<div dir="ltr">I'm going to squash this with the previous one and send review comments on the combined patch. It's terribly difficult to reason about the two individually.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 21, 2018 at 6:05 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">Use a helper function for updating the swapchain status. This will be<br>
used later to handle VK_SUBOPTIMAL_KHR, where we need to make a<br>
non-error status stick to the swapchain until recreation.<br>
<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 | 90 ++++++++++++++++++++++++++++++<wbr>++---------<br>
1 file changed, 72 insertions(+), 18 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 308b20c9f02..e84572810d3 100644<br>
--- a/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
+++ b/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
@@ -641,6 +641,36 @@ struct x11_swapchain {<br>
struct x11_image images[0];<br>
};<br>
<br>
+/**<br>
+ * Update the swapchain status with the result of an operation, and return<br>
+ * the combined status. The chain status will eventually be returned from<br>
+ * AcquireNextImage and QueuePresent.<br>
+ *<br>
+ * We make sure to 'stick' more pessimistic statuses: an out-of-date error<br>
+ * is permanent once seen, and every subsequent call will return this. If<br>
+ * this has not been seen, success will be returned.<br>
+ */<br>
+static VkResult<br>
+x11_swapchain_result(struct x11_swapchain *chain, VkResult result)<br>
+{<br>
+ /* Prioritise returning existing errors for consistency. */<br>
+ if (chain->status < 0)<br>
+ return chain->status;<br>
+<br>
+ /* If we have a new error, mark it as permanent on the chain and return. */<br>
+ if (result < 0) {<br>
+ chain->status = result;<br>
+ return result;<br>
+ }<br>
+<br>
+ /* Return temporary errors, but don't persist them. */<br>
+ if (result == VK_TIMEOUT || result == VK_NOT_READY)<br>
+ return result;<br>
+<br>
+ /* No changes, so return the last status. */<br>
+ return chain->status;<br>
+}<br>
+<br>
static struct wsi_image *<br>
x11_get_wsi_image(struct wsi_swapchain *wsi_chain, uint32_t image_index)<br>
{<br>
@@ -648,6 +678,9 @@ x11_get_wsi_image(struct wsi_swapchain *wsi_chain, uint32_t image_index)<br>
return &chain->images[image_index].<wbr>base;<br>
}<br>
<br>
+/**<br>
+ * Process an X11 Present event. Does not update chain->status.<br>
+ */<br>
static VkResult<br>
x11_handle_dri3_present_event(<wbr>struct x11_swapchain *chain,<br>
xcb_present_generic_event_t *event)<br>
@@ -719,6 +752,8 @@ x11_acquire_next_image_poll_<wbr>x11(struct x11_swapchain *chain,<br>
xcb_generic_event_t *event;<br>
struct pollfd pfds;<br>
uint64_t atimeout;<br>
+ VkResult result = VK_SUCCESS;<br>
+<br>
while (1) {<br>
for (uint32_t i = 0; i < chain->base.image_count; i++) {<br>
if (!chain->images[i].busy) {<br>
@@ -726,7 +761,8 @@ x11_acquire_next_image_poll_<wbr>x11(struct x11_swapchain *chain,<br>
xshmfence_await(chain->images[<wbr>i].shm_fence);<br>
*image_index = i;<br>
chain->images[i].busy = true;<br>
- return VK_SUCCESS;<br>
+ result = VK_SUCCESS;<br>
+ goto out;<br>
}<br>
}<br>
<br>
@@ -734,24 +770,31 @@ x11_acquire_next_image_poll_<wbr>x11(struct x11_swapchain *chain,<br>
<br>
if (timeout == UINT64_MAX) {<br>
event = xcb_wait_for_special_event(<wbr>chain->conn, chain->special_event);<br>
- if (!event)<br>
- return VK_ERROR_OUT_OF_DATE_KHR;<br>
+ if (!event) {<br>
+ result = VK_ERROR_OUT_OF_DATE_KHR;<br>
+ goto out;<br>
+ }<br>
} else {<br>
event = xcb_poll_for_special_event(<wbr>chain->conn, chain->special_event);<br>
if (!event) {<br>
int ret;<br>
- if (timeout == 0)<br>
- return VK_NOT_READY;<br>
+ if (timeout == 0) {<br>
+ result = VK_NOT_READY;<br>
+ goto out;<br>
+ }<br>
<br>
atimeout = wsi_get_absolute_timeout(<wbr>timeout);<br>
<br>
pfds.fd = xcb_get_file_descriptor(chain-<wbr>>conn);<br>
pfds.events = POLLIN;<br>
ret = poll(&pfds, 1, timeout / 1000 / 1000);<br>
- if (ret == 0)<br>
- return VK_TIMEOUT;<br>
- if (ret == -1)<br>
- return VK_ERROR_OUT_OF_DATE_KHR;<br>
+ if (ret == 0) {<br>
+ result = VK_TIMEOUT;<br>
+ goto out;<br>
+ } else if (ret == -1) {<br>
+ result = VK_ERROR_OUT_OF_DATE_KHR;<br>
+ goto out;<br>
+ }<br>
<br>
/* If a non-special event happens, the fd will still<br>
* poll. So recalculate the timeout now just in case.<br>
@@ -765,11 +808,18 @@ x11_acquire_next_image_poll_<wbr>x11(struct x11_swapchain *chain,<br>
}<br>
}<br>
<br>
+ /* Update the swapchain status here. We may catch non-fatal errors here,<br>
+ * in which case we need to update the status and continue.<br>
+ */<br>
VkResult result = x11_handle_dri3_present_event(<wbr>chain, (void *)event);<br>
+ result = x11_swapchain_result(chain, result);<br>
free(event);<br>
if (result < 0)<br>
- return result;<br>
+ goto out;<br>
}<br>
+<br>
+out:<br>
+ return x11_swapchain_result(chain, result);<br>
}<br>
<br>
static VkResult<br>
@@ -781,11 +831,9 @@ x11_acquire_next_image_from_<wbr>queue(struct x11_swapchain *chain,<br>
uint32_t image_index;<br>
VkResult result = wsi_queue_pull(&chain-><wbr>acquire_queue,<br>
&image_index, timeout);<br>
- if (result < 0) {<br>
- return result;<br>
- } else if (chain->status != VK_SUCCESS) {<br>
- return chain->status;<br>
- }<br>
+ /* On error, the thread has shut down, so safe to update chain->status */<br>
+ if (result < 0)<br>
+ return x11_swapchain_result(chain, result);<br>
<br>
assert(image_index < chain->base.image_count);<br>
xshmfence_await(chain->images[<wbr>image_index].shm_fence);<br>
@@ -859,13 +907,16 @@ 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>
+ return x11_swapchain_result(chain, result);<br>
}<br>
<br>
static void *<br>
@@ -888,6 +939,9 @@ x11_manage_fifo_queues(void *state)<br>
if (result < 0) {<br>
goto fail;<br>
} else if (chain->status < 0) {<br>
+ /* The status can change underneath us if the swapchain is destroyed<br>
+ * from another thread.<br>
+ */<br>
return NULL;<br>
}<br>
<br>
@@ -910,7 +964,7 @@ x11_manage_fifo_queues(void *state)<br>
}<br>
<br>
fail:<br>
- chain->status = result;<br>
+ result = x11_swapchain_result(chain, result);<br>
wsi_queue_push(&chain-><wbr>acquire_queue, UINT32_MAX);<br>
<br>
return NULL;<br>
<span class="HOEnZb"><font color="#888888">--<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>