<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Feb 15, 2018 at 7:57 AM, Daniel Stone <span dir="ltr"><<a href="mailto:daniels@collabora.com" target="_blank">daniels@collabora.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Louis-Francis Ratté-Boulianne <<a href="mailto:lfrb@collabora.com">lfrb@collabora.com</a>><br>
<br>
When it is detected that a window could have been flipped<br>
but has been copied because of suboptimal format/modifier.<br>
The Vulkan client should then re-create the swapchain.<br>
<br>
Signed-off-by: Louis-Francis Ratté-Boulianne <<a href="mailto:lfrb@collabora.com">lfrb@collabora.com</a>><br>
Reviewed-by: Daniel Stone <<a href="mailto:daniels@collabora.com">daniels@collabora.com</a>><br>
Signed-off-by: Daniel Stone <<a href="mailto:daniels@collabora.com">daniels@collabora.com</a>><br>
---<br>
src/vulkan/wsi/wsi_common_x11.<wbr>c | 64 ++++++++++++++++++++++++++++++<wbr>+++++++----<br>
1 file changed, 58 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/src/vulkan/wsi/wsi_common_<wbr>x11.c b/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
index c569aa17187..a9929af338c 100644<br>
--- a/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
+++ b/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
@@ -130,6 +130,8 @@ wsi_x11_connection_create(<wbr>const VkAllocationCallbacks *alloc,<br>
{<br>
xcb_query_extension_cookie_t dri3_cookie, pres_cookie, amd_cookie, nv_cookie;<br>
xcb_query_extension_reply_t *dri3_reply, *pres_reply, *amd_reply, *nv_reply;<br>
+ bool has_dri3_v1_1 = false;<br>
+ bool has_present_v1_1 = false;<br>
<br>
struct wsi_x11_connection *wsi_conn =<br>
vk_alloc(alloc, sizeof(*wsi_conn), 8,<br>
@@ -138,7 +140,7 @@ wsi_x11_connection_create(<wbr>const VkAllocationCallbacks *alloc,<br>
return NULL;<br>
<br>
dri3_cookie = xcb_query_extension(conn, 4, "DRI3");<br>
- pres_cookie = xcb_query_extension(conn, 7, "PRESENT");<br>
+ pres_cookie = xcb_query_extension(conn, 7, "Present");<br></blockquote><div><br></div><div>This seems a bit odd. Did we just not use it before? Looking through things, it appears we didn't.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
/* We try to be nice to users and emit a warning if they try to use a<br>
* Vulkan application on a system without DRI3 enabled. However, this ends<br>
@@ -173,13 +175,27 @@ wsi_x11_connection_create(<wbr>const VkAllocationCallbacks *alloc,<br>
<br>
ver_cookie = xcb_dri3_query_version(conn, 1, 1);<br>
ver_reply = xcb_dri3_query_version_reply(<wbr>conn, ver_cookie, NULL);<br>
- wsi_conn->has_dri3_modifiers =<br>
+ has_dri3_v1_1 =<br>
(ver_reply->major_version > 1 || ver_reply->minor_version >= 1);<br>
free(ver_reply);<br>
}<br>
#endif<br>
<br>
wsi_conn->has_present = pres_reply->present != 0;<br>
+#if XCB_PRESENT_MAJOR_VERSION > 1 || XCB_PRESENT_MINOR_VERSION >= 1<br>
+ if (wsi_conn->has_present) {<br>
+ xcb_present_query_version_<wbr>cookie_t ver_cookie;<br>
+ xcb_present_query_version_<wbr>reply_t *ver_reply;<br>
+<br>
+ ver_cookie = xcb_present_query_version(<wbr>conn, 1, 1);<br>
+ ver_reply = xcb_present_query_version_<wbr>reply(conn, ver_cookie, NULL);<br>
+ has_present_v1_1 =<br>
+ (ver_reply->major_version > 1 || ver_reply->minor_version >= 1);<br>
+ free(ver_reply);<br>
+ }<br>
+#endif<br>
+<br>
+ wsi_conn->has_dri3_modifiers = has_dri3_v1_1 && has_present_v1_1;<br>
wsi_conn->is_proprietary_x11 = false;<br>
if (amd_reply && amd_reply->present)<br>
wsi_conn->is_proprietary_x11 = true;<br>
@@ -651,6 +667,8 @@ struct x11_swapchain {<br>
<br>
bool threaded;<br>
VkResult status;<br>
+ bool suboptimal;<br>
+ bool realloc_suboptimal;<br>
struct wsi_queue present_queue;<br>
struct wsi_queue acquire_queue;<br>
pthread_t queue_manager;<br>
@@ -699,6 +717,10 @@ x11_handle_dri3_present_event(<wbr>struct x11_swapchain *chain,<br>
xcb_present_complete_notify_<wbr>event_t *complete = (void *) event;<br>
if (complete->kind == XCB_PRESENT_COMPLETE_KIND_<wbr>PIXMAP)<br>
chain->last_present_msc = complete->msc;<br>
+#if XCB_PRESENT_MAJOR_VERSION > 1 || XCB_PRESENT_MINOR_VERSION >= 1<br>
+ if (complete->mode == XCB_PRESENT_COMPLETE_MODE_<wbr>SUBOPTIMAL_COPY)<br>
+ chain->suboptimal = true;<br></blockquote><div><br></div><div>I think I like the approach taken in GLX better. Here, we'll properly reallocate when we go from not flipping to flipping but, what happens if we stop flipping? In that case, we can do better if we reallocate again.<br><br></div><div>Also, I find "chain->suboptimal" and "chain->realloc_suboptimal" to be very confusing. chain->suboptimal has an obvious meaning but the other doesn't. At the very least we need better documentation as to what they mean.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+#endif<br>
break;<br>
}<br>
<br>
@@ -828,6 +850,11 @@ x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,<br>
if (chain->base.present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR)<br>
options |= XCB_PRESENT_OPTION_ASYNC;<br>
<br>
+#if XCB_PRESENT_MAJOR_VERSION > 1 || XCB_PRESENT_MINOR_VERSION >= 1<br>
+ if (chain->has_dri3_modifiers)<br>
+ options |= XCB_PRESENT_OPTION_SUBOPTIMAL;<br>
+#endif<br>
+<br>
xshmfence_reset(image->shm_<wbr>fence);<br>
<br>
++chain->send_sbc;<br>
@@ -862,11 +889,19 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,<br>
uint32_t *image_index)<br>
{<br>
struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;<br>
+ VkResult result;<br>
<br>
if (chain->threaded) {<br>
- return x11_acquire_next_image_from_<wbr>queue(chain, image_index, timeout);<br>
+ result = x11_acquire_next_image_from_<wbr>queue(chain, image_index, timeout);<br>
} else {<br>
- return x11_acquire_next_image_poll_<wbr>x11(chain, image_index, timeout);<br>
+ result = x11_acquire_next_image_poll_<wbr>x11(chain, image_index, timeout);<br>
+ }<br>
+<br>
+ if (result != VK_SUCCESS) {<br>
+ return result;<br>
+ } else {<br>
+ return (chain->realloc_suboptimal && chain->suboptimal) ? VK_SUBOPTIMAL_KHR<br>
+ : VK_SUCCESS;<br>
}<br>
}<br>
<br>
@@ -876,12 +911,20 @@ x11_queue_present(struct wsi_swapchain *anv_chain,<br>
const VkPresentRegionKHR *damage)<br>
{<br>
struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;<br>
+ VkResult result;<br>
<br>
if (chain->threaded) {<br>
wsi_queue_push(&chain-><wbr>present_queue, image_index);<br>
- return chain->status;<br>
+ result = chain->status;<br>
} else {<br>
- return x11_present_to_x11(chain, image_index, 0);<br>
+ result = x11_present_to_x11(chain, image_index, 0);<br>
+ }<br>
+<br>
+ if (result != VK_SUCCESS) {<br>
+ return result;<br>
+ } else {<br>
+ return (chain->realloc_suboptimal && chain->suboptimal) ? VK_SUBOPTIMAL_KHR<br>
+ : VK_SUCCESS;<br>
}<br>
}<br>
<br>
@@ -1220,6 +1263,15 @@ x11_surface_create_swapchain(<wbr>VkIcdSurfaceBase *icd_surface,<br>
chain->status = VK_SUCCESS;<br>
chain->has_dri3_modifiers = wsi_conn->has_dri3_modifiers;<br>
<br>
+ chain->suboptimal = false;<br>
+ chain->realloc_suboptimal = true;<br>
+ if (pCreateInfo->oldSwapchain) {<br>
+ struct x11_swapchain *old_chain = (void *)pCreateInfo->oldSwapchain;<br>
+<br>
+ if (old_chain->suboptimal)<br>
+ chain->realloc_suboptimal = false;<br>
+ }<br>
+<br>
if (!wsi_x11_check_dri3_<wbr>compatible(conn, local_fd))<br>
chain->base.use_prime_blit = true;<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>