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;
}
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;
}
if (chain->extent.width != cur_width || chain->extent.height != cur_height)
chain->status = VK_SUBOPTIMAL_KHR;
- /* 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))