From: Jason Ekstrand Date: Tue, 8 Sep 2015 18:51:47 +0000 (-0700) Subject: vk/wsi/x11: Actually block on X so we don't re-use busy buffers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=060720f0c9fc5333ba481315e63ba697c868f44c;p=mesa.git vk/wsi/x11: Actually block on X so we don't re-use busy buffers --- diff --git a/src/vulkan/anv_wsi_x11.c b/src/vulkan/anv_wsi_x11.c index b412a2bab32..be4677ae7ed 100644 --- a/src/vulkan/anv_wsi_x11.c +++ b/src/vulkan/anv_wsi_x11.c @@ -50,7 +50,7 @@ x11_get_window_supported(struct anv_wsi_implementation *impl, static VkResult x11_get_surface_info(struct anv_wsi_implementation *impl, struct anv_device *device, - VkSurfaceDescriptionWindowWSI *window, + VkSurfaceDescriptionWindowWSI *vk_window, VkSurfaceInfoTypeWSI infoType, size_t* pDataSize, void* pData) { @@ -68,11 +68,21 @@ x11_get_surface_info(struct anv_wsi_implementation *impl, assert(*pDataSize >= sizeof(*props)); + VkPlatformHandleXcbWSI *vk_xcb_handle = vk_window->pPlatformHandle; + xcb_connection_t *conn = vk_xcb_handle->connection; + xcb_window_t win = (xcb_window_t)(uintptr_t)vk_window->pPlatformWindow; + + xcb_get_geometry_cookie_t cookie = xcb_get_geometry(conn, win); + xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, cookie, + NULL); + VkExtent2D extent = { geom->width, geom->height }; + free(geom); + props->minImageCount = 2; props->maxImageCount = 4; - props->currentExtent = (VkExtent2D) { -1, -1 }; - props->minImageExtent = (VkExtent2D) { 1, 1 }; - props->maxImageExtent = (VkExtent2D) { INT16_MAX, INT16_MAX }; + props->currentExtent = extent; + props->minImageExtent = extent; + props->maxImageExtent = extent; props->supportedTransforms = VK_SURFACE_TRANSFORM_NONE_BIT_WSI; props->currentTransform = VK_SURFACE_TRANSFORM_NONE_WSI; props->maxImageArraySize = 1; @@ -109,6 +119,14 @@ x11_get_surface_info(struct anv_wsi_implementation *impl, } } +struct x11_image { + struct anv_image * image; + struct anv_device_memory * memory; + xcb_pixmap_t pixmap; + xcb_get_geometry_cookie_t geom_cookie; + bool busy; +}; + struct x11_swap_chain { struct anv_swap_chain base; @@ -118,11 +136,7 @@ struct x11_swap_chain { VkExtent2D extent; uint32_t image_count; uint32_t next_image; - struct { - struct anv_image * image; - struct anv_device_memory * memory; - xcb_pixmap_t pixmap; - } images[0]; + struct x11_image images[0]; }; static VkResult @@ -165,8 +179,21 @@ x11_acquire_next_image(struct anv_swap_chain *anv_chain, uint32_t *image_index) { struct x11_swap_chain *chain = (struct x11_swap_chain *)anv_chain; + struct x11_image *image = &chain->images[chain->next_image]; + + if (image->busy) { + xcb_get_geometry_reply_t *geom = + xcb_get_geometry_reply(chain->conn, image->geom_cookie, NULL); + image->busy = false; + + if (geom->width != chain->extent.width || + geom->height != chain->extent.height) { + free(geom); + return VK_ERROR_OUT_OF_DATE_WSI; + } + free(geom); + } - anv_finishme("Implement real blocking AcquireNextImage"); *image_index = chain->next_image; chain->next_image = (chain->next_image + 1) % chain->image_count; return VK_SUCCESS; @@ -178,16 +205,14 @@ x11_queue_present(struct anv_swap_chain *anv_chain, uint32_t image_index) { struct x11_swap_chain *chain = (struct x11_swap_chain *)anv_chain; + struct x11_image *image = &chain->images[image_index]; - xcb_void_cookie_t cookie; - - xcb_pixmap_t pixmap = chain->images[image_index].pixmap; + assert(image_index < chain->image_count); - if (pixmap == XCB_NONE) - return vk_error(VK_ERROR_INVALID_VALUE); + xcb_void_cookie_t cookie; cookie = xcb_copy_area(chain->conn, - pixmap, + image->pixmap, chain->window, chain->gc, 0, 0, @@ -196,15 +221,33 @@ x11_queue_present(struct anv_swap_chain *anv_chain, chain->extent.height); xcb_discard_reply(chain->conn, cookie.sequence); + image->geom_cookie = xcb_get_geometry(chain->conn, chain->window); + image->busy = true; + xcb_flush(chain->conn); return VK_SUCCESS; } static VkResult -x11_destroy_swap_chain(struct anv_swap_chain *chain) +x11_destroy_swap_chain(struct anv_swap_chain *anv_chain) { - anv_device_free(chain->device, chain); + struct x11_swap_chain *chain = (struct x11_swap_chain *)anv_chain; + xcb_void_cookie_t cookie; + + for (uint32_t i = 0; i < chain->image_count; i++) { + struct x11_image *image = &chain->images[i]; + + if (image->busy) + xcb_discard_reply(chain->conn, image->geom_cookie.sequence); + + cookie = xcb_free_pixmap(chain->conn, image->pixmap); + xcb_discard_reply(chain->conn, cookie.sequence); + + /* TODO: Delete images and free memory */ + } + + anv_device_free(chain->base.device, chain); return VK_SUCCESS; } @@ -329,6 +372,7 @@ x11_create_swap_chain(struct anv_wsi_implementation *impl, chain->images[i].image = image; chain->images[i].memory = memory; chain->images[i].pixmap = pixmap; + chain->images[i].busy = false; xcb_discard_reply(chain->conn, cookie.sequence); }