vulkan/wsi/x11: document implementation
To extend the shared understanding of our code base and ease contributing document purpose and flow for many of our internal functions. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6536>
This commit is contained in:
parent
978ea32acf
commit
6018d5c44a
|
@ -75,9 +75,8 @@ struct wsi_x11 {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** wsi_dri3_open
|
/**
|
||||||
*
|
* Wrapper around xcb_dri3_open. Returns the opened fd or -1 on error.
|
||||||
* Wrapper around xcb_dri3_open
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
wsi_dri3_open(xcb_connection_t *conn,
|
wsi_dri3_open(xcb_connection_t *conn,
|
||||||
|
@ -96,6 +95,7 @@ wsi_dri3_open(xcb_connection_t *conn,
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* According to DRI3 extension nfd must equal one. */
|
||||||
if (reply->nfd != 1) {
|
if (reply->nfd != 1) {
|
||||||
free(reply);
|
free(reply);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -108,6 +108,13 @@ wsi_dri3_open(xcb_connection_t *conn,
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks compatibility of the device wsi_dev with the device the X server
|
||||||
|
* provides via DRI3.
|
||||||
|
*
|
||||||
|
* This returns true when no device could be retrieved from the X server or when
|
||||||
|
* the information for the X server device indicate that it is the same device.
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
wsi_x11_check_dri3_compatible(const struct wsi_device *wsi_dev,
|
wsi_x11_check_dri3_compatible(const struct wsi_device *wsi_dev,
|
||||||
xcb_connection_t *conn)
|
xcb_connection_t *conn)
|
||||||
|
@ -116,6 +123,9 @@ wsi_x11_check_dri3_compatible(const struct wsi_device *wsi_dev,
|
||||||
xcb_setup_roots_iterator(xcb_get_setup(conn));
|
xcb_setup_roots_iterator(xcb_get_setup(conn));
|
||||||
xcb_screen_t *screen = screen_iter.data;
|
xcb_screen_t *screen = screen_iter.data;
|
||||||
|
|
||||||
|
/* Open the DRI3 device from the X server. If we do not retrieve one we
|
||||||
|
* assume our local device is compatible.
|
||||||
|
*/
|
||||||
int dri3_fd = wsi_dri3_open(conn, screen->root, None);
|
int dri3_fd = wsi_dri3_open(conn, screen->root, None);
|
||||||
if (dri3_fd == -1)
|
if (dri3_fd == -1)
|
||||||
return true;
|
return true;
|
||||||
|
@ -322,6 +332,14 @@ wsi_x11_check_for_dri3(struct wsi_x11_connection *wsi_conn)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get internal struct representing an xcb_connection_t.
|
||||||
|
*
|
||||||
|
* This can allocate the struct but the caller does not own the struct. It is
|
||||||
|
* deleted on wsi_x11_finish_wsi by the hash table it is inserted.
|
||||||
|
*
|
||||||
|
* If the allocation fails NULL is returned.
|
||||||
|
*/
|
||||||
static struct wsi_x11_connection *
|
static struct wsi_x11_connection *
|
||||||
wsi_x11_get_connection(struct wsi_device *wsi_dev,
|
wsi_x11_get_connection(struct wsi_device *wsi_dev,
|
||||||
xcb_connection_t *conn)
|
xcb_connection_t *conn)
|
||||||
|
@ -1059,6 +1077,10 @@ static uint64_t wsi_get_absolute_timeout(uint64_t timeout)
|
||||||
return current_time + timeout;
|
return current_time + timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire a ready-to-use image directly from our swapchain. If all images are
|
||||||
|
* busy wait until one is not anymore or till timeout.
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_acquire_next_image_poll_x11(struct x11_swapchain *chain,
|
x11_acquire_next_image_poll_x11(struct x11_swapchain *chain,
|
||||||
uint32_t *image_index, uint64_t timeout)
|
uint32_t *image_index, uint64_t timeout)
|
||||||
|
@ -1124,6 +1146,10 @@ x11_acquire_next_image_poll_x11(struct x11_swapchain *chain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire a ready-to-use image from the acquire-queue. Only relevant in fifo
|
||||||
|
* presentation mode.
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_acquire_next_image_from_queue(struct x11_swapchain *chain,
|
x11_acquire_next_image_from_queue(struct x11_swapchain *chain,
|
||||||
uint32_t *image_index_out, uint64_t timeout)
|
uint32_t *image_index_out, uint64_t timeout)
|
||||||
|
@ -1151,6 +1177,9 @@ x11_acquire_next_image_from_queue(struct x11_swapchain *chain,
|
||||||
return chain->status;
|
return chain->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send image to X server via Present extension.
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_present_to_x11_dri3(struct x11_swapchain *chain, uint32_t image_index,
|
x11_present_to_x11_dri3(struct x11_swapchain *chain, uint32_t image_index,
|
||||||
uint64_t target_msc)
|
uint64_t target_msc)
|
||||||
|
@ -1226,6 +1255,9 @@ x11_present_to_x11_dri3(struct x11_swapchain *chain, uint32_t image_index,
|
||||||
return x11_swapchain_result(chain, VK_SUCCESS);
|
return x11_swapchain_result(chain, VK_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send image to X server unaccelerated (software drivers).
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_present_to_x11_sw(struct x11_swapchain *chain, uint32_t image_index,
|
x11_present_to_x11_sw(struct x11_swapchain *chain, uint32_t image_index,
|
||||||
uint64_t target_msc)
|
uint64_t target_msc)
|
||||||
|
@ -1252,6 +1284,10 @@ x11_present_to_x11_sw(struct x11_swapchain *chain, uint32_t image_index,
|
||||||
xcb_flush(chain->conn);
|
xcb_flush(chain->conn);
|
||||||
return x11_swapchain_result(chain, VK_SUCCESS);
|
return x11_swapchain_result(chain, VK_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send image to the X server for presentation at target_msc.
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
|
x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
|
||||||
uint64_t target_msc)
|
uint64_t target_msc)
|
||||||
|
@ -1261,6 +1297,12 @@ x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
|
||||||
return x11_present_to_x11_dri3(chain, image_index, target_msc);
|
return x11_present_to_x11_dri3(chain, image_index, target_msc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire a ready-to-use image from the swapchain.
|
||||||
|
*
|
||||||
|
* This means usually that the image is not waiting on presentation and that the
|
||||||
|
* image has been released by the X server to be used again by the consumer.
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_acquire_next_image(struct wsi_swapchain *anv_chain,
|
x11_acquire_next_image(struct wsi_swapchain *anv_chain,
|
||||||
const VkAcquireNextImageInfoKHR *info,
|
const VkAcquireNextImageInfoKHR *info,
|
||||||
|
@ -1273,10 +1315,12 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
|
||||||
if (chain->status < 0)
|
if (chain->status < 0)
|
||||||
return chain->status;
|
return chain->status;
|
||||||
|
|
||||||
|
/* For software drivers and without shared memory we only render to a single image. */
|
||||||
if (chain->base.wsi->sw && !chain->has_mit_shm) {
|
if (chain->base.wsi->sw && !chain->has_mit_shm) {
|
||||||
*image_index = 0;
|
*image_index = 0;
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain->has_acquire_queue) {
|
if (chain->has_acquire_queue) {
|
||||||
return x11_acquire_next_image_from_queue(chain, image_index, timeout);
|
return x11_acquire_next_image_from_queue(chain, image_index, timeout);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1284,6 +1328,13 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a new presentation of an image that was previously acquired by the
|
||||||
|
* consumer.
|
||||||
|
*
|
||||||
|
* Note that in immediate presentation mode this does not really queue the
|
||||||
|
* presentation but directly asks the X server to show it.
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_queue_present(struct wsi_swapchain *anv_chain,
|
x11_queue_present(struct wsi_swapchain *anv_chain,
|
||||||
uint32_t image_index,
|
uint32_t image_index,
|
||||||
|
@ -1300,10 +1351,22 @@ x11_queue_present(struct wsi_swapchain *anv_chain,
|
||||||
wsi_queue_push(&chain->present_queue, image_index);
|
wsi_queue_push(&chain->present_queue, image_index);
|
||||||
return chain->status;
|
return chain->status;
|
||||||
} else {
|
} else {
|
||||||
|
/* No present queue means immedate mode, so we present immediately. */
|
||||||
return x11_present_to_x11(chain, image_index, 0);
|
return x11_present_to_x11(chain, image_index, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decides if an early wait on buffer fences before buffer submission is required. That is for:
|
||||||
|
* - Mailbox mode, as otherwise the latest image in the queue might not be fully rendered at
|
||||||
|
* present time, what could lead to missing a frame.
|
||||||
|
* - Immediate mode under Xwayland, as it works practically the same as mailbox mode using the
|
||||||
|
* mailbox mechanism of Wayland. Sending a buffer with fences not yet signalled can make the
|
||||||
|
* compositor miss a frame when compositing the final image with this buffer.
|
||||||
|
*
|
||||||
|
* Note though that early waits can be disabled in general on Xwayland by setting the
|
||||||
|
* 'vk_xwayland_wait_ready' DRIConf option to false.
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
x11_needs_wait_for_fences(const struct wsi_device *wsi_device,
|
x11_needs_wait_for_fences(const struct wsi_device *wsi_device,
|
||||||
struct wsi_x11_connection *wsi_conn,
|
struct wsi_x11_connection *wsi_conn,
|
||||||
|
@ -1323,6 +1386,21 @@ x11_needs_wait_for_fences(const struct wsi_device *wsi_device,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our queue manager. Albeit called x11_manage_fifo_queues only directly
|
||||||
|
* manages the present-queue and does this in general in fifo and mailbox presentation
|
||||||
|
* modes (there is no present-queue in immediate mode with the exception of Xwayland).
|
||||||
|
*
|
||||||
|
* Runs in a separate thread, blocks and reacts to queued images on the
|
||||||
|
* present-queue
|
||||||
|
*
|
||||||
|
* In mailbox mode the queue management is simplified since we only need to
|
||||||
|
* pull new images from the present queue and can directly present them.
|
||||||
|
*
|
||||||
|
* In fifo mode images can only be presented one after the other. For that after
|
||||||
|
* sending the image to the X server we wait until the image either has been
|
||||||
|
* presented or released and only then pull a new image from the present-queue.
|
||||||
|
*/
|
||||||
static void *
|
static void *
|
||||||
x11_manage_fifo_queues(void *state)
|
x11_manage_fifo_queues(void *state)
|
||||||
{
|
{
|
||||||
|
@ -1343,6 +1421,7 @@ x11_manage_fifo_queues(void *state)
|
||||||
uint32_t image_index = 0;
|
uint32_t image_index = 0;
|
||||||
result = wsi_queue_pull(&chain->present_queue, &image_index, INT64_MAX);
|
result = wsi_queue_pull(&chain->present_queue, &image_index, INT64_MAX);
|
||||||
assert(result != VK_TIMEOUT);
|
assert(result != VK_TIMEOUT);
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (chain->status < 0) {
|
} else if (chain->status < 0) {
|
||||||
|
@ -1352,6 +1431,9 @@ x11_manage_fifo_queues(void *state)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Waiting for the GPU work to finish at this point in time is required in certain usage
|
||||||
|
* scenarios. Otherwise we wait as usual in wsi_common_queue_present.
|
||||||
|
*/
|
||||||
if (x11_needs_wait_for_fences(chain->base.wsi, wsi_conn,
|
if (x11_needs_wait_for_fences(chain->base.wsi, wsi_conn,
|
||||||
chain->base.present_mode)) {
|
chain->base.present_mode)) {
|
||||||
result = chain->base.wsi->WaitForFences(chain->base.device, 1,
|
result = chain->base.wsi->WaitForFences(chain->base.device, 1,
|
||||||
|
@ -1716,7 +1798,12 @@ wsi_x11_set_adaptive_sync_property(xcb_connection_t *conn,
|
||||||
free(reply);
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the swapchain.
|
||||||
|
*
|
||||||
|
* Supports immediate, fifo and mailbox presentation mode.
|
||||||
|
*
|
||||||
|
*/
|
||||||
static VkResult
|
static VkResult
|
||||||
x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
VkDevice device,
|
VkDevice device,
|
||||||
|
@ -1732,12 +1819,20 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
|
|
||||||
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
||||||
|
|
||||||
|
/* Get xcb connection from the icd_surface and from that our internal struct
|
||||||
|
* representing it.
|
||||||
|
*/
|
||||||
xcb_connection_t *conn = x11_surface_get_connection(icd_surface);
|
xcb_connection_t *conn = x11_surface_get_connection(icd_surface);
|
||||||
struct wsi_x11_connection *wsi_conn =
|
struct wsi_x11_connection *wsi_conn =
|
||||||
wsi_x11_get_connection(wsi_device, conn);
|
wsi_x11_get_connection(wsi_device, conn);
|
||||||
if (!wsi_conn)
|
if (!wsi_conn)
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
|
||||||
|
/* Get number of images in our swapchain. This count depends on:
|
||||||
|
* - requested minimal image count
|
||||||
|
* - device characteristics
|
||||||
|
* - presentation mode.
|
||||||
|
*/
|
||||||
unsigned num_images = pCreateInfo->minImageCount;
|
unsigned num_images = pCreateInfo->minImageCount;
|
||||||
if (wsi_device->x11.strict_imageCount)
|
if (wsi_device->x11.strict_imageCount)
|
||||||
num_images = pCreateInfo->minImageCount;
|
num_images = pCreateInfo->minImageCount;
|
||||||
|
@ -1746,8 +1841,12 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
else if (wsi_device->x11.ensure_minImageCount)
|
else if (wsi_device->x11.ensure_minImageCount)
|
||||||
num_images = MAX2(num_images, x11_get_min_image_count(wsi_device));
|
num_images = MAX2(num_images, x11_get_min_image_count(wsi_device));
|
||||||
|
|
||||||
/* Check for whether or not we have a window up-front */
|
/* Check that we have a window up-front. It is an error to not have one. */
|
||||||
xcb_window_t window = x11_surface_get_window(icd_surface);
|
xcb_window_t window = x11_surface_get_window(icd_surface);
|
||||||
|
|
||||||
|
/* Get the geometry of that window. The bit depth of the swapchain will be fitted and the
|
||||||
|
* chain's images extents should fit it for performance-optimizing flips.
|
||||||
|
*/
|
||||||
xcb_get_geometry_reply_t *geometry =
|
xcb_get_geometry_reply_t *geometry =
|
||||||
xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), NULL);
|
xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), NULL);
|
||||||
if (geometry == NULL)
|
if (geometry == NULL)
|
||||||
|
@ -1757,12 +1856,16 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
const uint16_t cur_height = geometry->height;
|
const uint16_t cur_height = geometry->height;
|
||||||
free(geometry);
|
free(geometry);
|
||||||
|
|
||||||
|
/* Allocate the actual swapchain. The size depends on image count. */
|
||||||
size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
|
size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
|
||||||
chain = vk_zalloc(pAllocator, size, 8,
|
chain = vk_zalloc(pAllocator, size, 8,
|
||||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||||
if (chain == NULL)
|
if (chain == NULL)
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
|
||||||
|
/* When our local device is not compatible with the DRI3 device provided by
|
||||||
|
* the X server we assume this is a PRIME system.
|
||||||
|
*/
|
||||||
bool use_prime_blit = false;
|
bool use_prime_blit = false;
|
||||||
if (!wsi_device->sw)
|
if (!wsi_device->sw)
|
||||||
if (!wsi_x11_check_dri3_compatible(wsi_device, conn))
|
if (!wsi_x11_check_dri3_compatible(wsi_device, conn))
|
||||||
|
@ -1792,19 +1895,39 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
chain->has_dri3_modifiers = wsi_conn->has_dri3_modifiers;
|
chain->has_dri3_modifiers = wsi_conn->has_dri3_modifiers;
|
||||||
chain->has_mit_shm = wsi_conn->has_mit_shm;
|
chain->has_mit_shm = wsi_conn->has_mit_shm;
|
||||||
|
|
||||||
|
/* When images in the swapchain don't fit the window, X can still present them, but it won't
|
||||||
|
* happen by flip, only by copy. So this is a suboptimal copy, because if the client would change
|
||||||
|
* the chain extents X may be able to flip
|
||||||
|
*/
|
||||||
if (chain->extent.width != cur_width || chain->extent.height != cur_height)
|
if (chain->extent.width != cur_width || chain->extent.height != cur_height)
|
||||||
chain->status = VK_SUBOPTIMAL_KHR;
|
chain->status = VK_SUBOPTIMAL_KHR;
|
||||||
|
|
||||||
/* We used to inherit copy_is_suboptimal from pCreateInfo->oldSwapchain.
|
/* On a new swapchain this helper variable is set to false. Once we present it will have an
|
||||||
* When it was true, and when the next present was completed with copying,
|
* impact once we ever do at least one flip and go back to copying afterwards. It is presumed
|
||||||
* we would return VK_SUBOPTIMAL_KHR and hint the app to reallocate again
|
* that in this case here is a high likelihood X could do flips again if the client reallocates a
|
||||||
* for no good reason. If all following presents on the surface were
|
* new swapchain.
|
||||||
* completed with copying because of some surface state change, we would
|
*
|
||||||
* always return VK_SUBOPTIMAL_KHR no matter how many times the app had
|
* Note that we used to inheritted this property from 'pCreateInfo->oldSwapchain'. But when it
|
||||||
* reallocated.
|
* was true, and when the next present was completed with copying, we would return
|
||||||
|
* VK_SUBOPTIMAL_KHR and hint the app to reallocate again for no good reason. If all following
|
||||||
|
* presents on the surface were completed with copying because of some surface state change, we
|
||||||
|
* would always return VK_SUBOPTIMAL_KHR no matter how many times the app had reallocated.
|
||||||
|
*
|
||||||
|
* Note also that is is questionable in general if that mechanism is really useful. It ist not
|
||||||
|
* clear why on a change from flipping to copying we can assume a reallocation has a high chance
|
||||||
|
* of making flips work again per se. In other words it is not clear why there is need for
|
||||||
|
* another way to inform clients about suboptimal copies besides forwarding the
|
||||||
|
* 'PresentOptionSuboptimal' complete mode.
|
||||||
*/
|
*/
|
||||||
chain->copy_is_suboptimal = false;
|
chain->copy_is_suboptimal = false;
|
||||||
|
|
||||||
|
/* For our swapchain we need to listen to following Present extension events:
|
||||||
|
* - Configure: Window dimensions changed. Images in the swapchain might need
|
||||||
|
* to be reallocated.
|
||||||
|
* - Complete: An image from our swapchain was presented on the output.
|
||||||
|
* - Idle: An image from our swapchain is not anymore accessed by the X
|
||||||
|
* server and can be reused.
|
||||||
|
*/
|
||||||
chain->event_id = xcb_generate_id(chain->conn);
|
chain->event_id = xcb_generate_id(chain->conn);
|
||||||
xcb_present_select_input(chain->conn, chain->event_id, chain->window,
|
xcb_present_select_input(chain->conn, chain->event_id, chain->window,
|
||||||
XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
|
XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
|
||||||
|
@ -1818,6 +1941,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
xcb_register_for_special_xge(chain->conn, &xcb_present_id,
|
xcb_register_for_special_xge(chain->conn, &xcb_present_id,
|
||||||
chain->event_id, NULL);
|
chain->event_id, NULL);
|
||||||
|
|
||||||
|
/* Create the graphics context. */
|
||||||
chain->gc = xcb_generate_id(chain->conn);
|
chain->gc = xcb_generate_id(chain->conn);
|
||||||
if (!chain->gc) {
|
if (!chain->gc) {
|
||||||
/* FINISHME: Choose a better error. */
|
/* FINISHME: Choose a better error. */
|
||||||
|
@ -1851,6 +1975,17 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
goto fail_init_images;
|
goto fail_init_images;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize queues for images in our swapchain. Possible queues are:
|
||||||
|
* - Present queue: for images sent to the X server but not yet presented.
|
||||||
|
* - Acquire queue: for images already presented but not yet released by the
|
||||||
|
* X server.
|
||||||
|
*
|
||||||
|
* In general queues are not used on software drivers, otherwise which queues
|
||||||
|
* are used depends on our presentation mode:
|
||||||
|
* - Fifo: present and acquire
|
||||||
|
* - Mailbox: present only
|
||||||
|
* - Immediate: present when we wait on fences before buffer submission (Xwayland)
|
||||||
|
*/
|
||||||
if ((chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR ||
|
if ((chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR ||
|
||||||
chain->base.present_mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR ||
|
chain->base.present_mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR ||
|
||||||
x11_needs_wait_for_fences(wsi_device, wsi_conn,
|
x11_needs_wait_for_fences(wsi_device, wsi_conn,
|
||||||
|
@ -1858,7 +1993,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||||
!chain->base.wsi->sw) {
|
!chain->base.wsi->sw) {
|
||||||
chain->has_present_queue = true;
|
chain->has_present_queue = true;
|
||||||
|
|
||||||
/* Initialize our queues. We make them base.image_count + 1 because we will
|
/* The queues have a length of base.image_count + 1 because we will
|
||||||
* occasionally use UINT32_MAX to signal the other thread that an error
|
* occasionally use UINT32_MAX to signal the other thread that an error
|
||||||
* has occurred and we don't want an overflow.
|
* has occurred and we don't want an overflow.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue