diff --git a/.pick_status.json b/.pick_status.json index 8d29a58c2ad..824a208e71e 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2065,7 +2065,7 @@ "description": "vulkan/wsi/x11: do not inherit last_present_mode", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "61309c2a727d52d543207d6ae79fcb3e68b5cff3" }, diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 54769b81ccc..8476819bc97 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -810,7 +810,7 @@ struct x11_swapchain { bool has_present_queue; bool has_acquire_queue; VkResult status; - xcb_present_complete_mode_t last_present_mode; + bool copy_is_suboptimal; struct wsi_queue present_queue; struct wsi_queue acquire_queue; pthread_t queue_manager; @@ -919,25 +919,30 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain, chain->last_present_msc = complete->msc; VkResult result = VK_SUCCESS; - - /* The winsys is now trying to flip directly and cannot due to our - * configuration. Request the user reallocate. - */ + switch (complete->mode) { + case XCB_PRESENT_COMPLETE_MODE_COPY: + if (chain->copy_is_suboptimal) + result = VK_SUBOPTIMAL_KHR; + break; + case XCB_PRESENT_COMPLETE_MODE_FLIP: + /* If we ever go from flipping to copying, the odds are very likely + * that we could reallocate in a more optimal way if we didn't have + * to care about scanout, so we always do this. + */ + chain->copy_is_suboptimal = true; + break; #ifdef HAVE_DRI3_MODIFIERS - if (complete->mode == XCB_PRESENT_COMPLETE_MODE_SUBOPTIMAL_COPY && - chain->last_present_mode != XCB_PRESENT_COMPLETE_MODE_SUBOPTIMAL_COPY) + case XCB_PRESENT_COMPLETE_MODE_SUBOPTIMAL_COPY: + /* The winsys is now trying to flip directly and cannot due to our + * configuration. Request the user reallocate. + */ result = VK_SUBOPTIMAL_KHR; + break; #endif + default: + break; + } - /* When we go from flipping to copying, the odds are very likely that - * we could reallocate in a more optimal way if we didn't have to care - * about scanout, so we always do this. - */ - if (complete->mode == XCB_PRESENT_COMPLETE_MODE_COPY && - chain->last_present_mode == XCB_PRESENT_COMPLETE_MODE_FLIP) - result = VK_SUBOPTIMAL_KHR; - - chain->last_present_mode = complete->mode; return result; } @@ -1611,17 +1616,15 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->status = VK_SUCCESS; chain->has_dri3_modifiers = wsi_conn->has_dri3_modifiers; - /* If we are reallocating from an old swapchain, then we inherit its - * last completion mode, to ensure we don't get into reallocation - * cycles. If we are starting anew, we set 'COPY', as that is the only - * mode which provokes reallocation when anything changes, to make - * sure we have the most optimal allocation. + /* We used to inherit copy_is_suboptimal from pCreateInfo->oldSwapchain. + * When it 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. */ - VK_FROM_HANDLE(x11_swapchain, old_chain, pCreateInfo->oldSwapchain); - if (old_chain) - chain->last_present_mode = old_chain->last_present_mode; - else - chain->last_present_mode = XCB_PRESENT_COMPLETE_MODE_COPY; + chain->copy_is_suboptimal = false; if (!wsi_device->sw) if (!wsi_x11_check_dri3_compatible(wsi_device, conn))