For this one, I'm making live edits to see if I like the suggested changes. I'll send out the v2 with the comments incorporated when I'm done.
On Wed, Feb 21, 2018 at 11:32 AM, Jason Ekstrand <ja...@jlekstrand.net> wrote: > From: Daniel Stone <dani...@collabora.com> > > Use a helper function for updating the swapchain status. This will be > used later to handle VK_SUBOPTIMAL_KHR, where we need to make a > non-error status stick to the swapchain until recreation. Instead of > direct comparisons to VK_SUCCESS to check for error, test for negative > numbers meaning an error status, and positive numbers indicating > non-error statuses. > > Signed-off-by: Daniel Stone <dani...@collabora.com> > --- > src/vulkan/wsi/wsi_common_x11.c | 104 ++++++++++++++++++++++++++++++ > ---------- > 1 file changed, 79 insertions(+), 25 deletions(-) > > diff --git a/src/vulkan/wsi/wsi_common_x11.c > b/src/vulkan/wsi/wsi_common_x11.c > index 2cc7a67..e845728 100644 > --- a/src/vulkan/wsi/wsi_common_x11.c > +++ b/src/vulkan/wsi/wsi_common_x11.c > @@ -641,6 +641,36 @@ struct x11_swapchain { > struct x11_image images[0]; > }; > > +/** > + * Update the swapchain status with the result of an operation, and return > + * the combined status. The chain status will eventually be returned from > + * AcquireNextImage and QueuePresent. > + * > + * We make sure to 'stick' more pessimistic statuses: an out-of-date error > + * is permanent once seen, and every subsequent call will return this. If > + * this has not been seen, success will be returned. > + */ > +static VkResult > +x11_swapchain_result(struct x11_swapchain *chain, VkResult result) > +{ > + /* Prioritise returning existing errors for consistency. */ > + if (chain->status < 0) > + return chain->status; > + > + /* If we have a new error, mark it as permanent on the chain and > return. */ > + if (result < 0) { > + chain->status = result; > + return result; > + } > + > + /* Return temporary errors, but don't persist them. */ > + if (result == VK_TIMEOUT || result == VK_NOT_READY) > + return result; > + > + /* No changes, so return the last status. */ > + return chain->status; > +} > + > static struct wsi_image * > x11_get_wsi_image(struct wsi_swapchain *wsi_chain, uint32_t image_index) > { > @@ -648,6 +678,9 @@ x11_get_wsi_image(struct wsi_swapchain *wsi_chain, > uint32_t image_index) > return &chain->images[image_index].base; > } > > +/** > + * Process an X11 Present event. Does not update chain->status. > + */ > static VkResult > x11_handle_dri3_present_event(struct x11_swapchain *chain, > xcb_present_generic_event_t *event) > @@ -719,6 +752,8 @@ x11_acquire_next_image_poll_x11(struct x11_swapchain > *chain, > xcb_generic_event_t *event; > struct pollfd pfds; > uint64_t atimeout; > + VkResult result = VK_SUCCESS; > + > while (1) { > for (uint32_t i = 0; i < chain->base.image_count; i++) { > if (!chain->images[i].busy) { > @@ -726,7 +761,8 @@ x11_acquire_next_image_poll_x11(struct x11_swapchain > *chain, > xshmfence_await(chain->images[i].shm_fence); > *image_index = i; > chain->images[i].busy = true; > - return VK_SUCCESS; > + result = VK_SUCCESS; > Since our neat little helper returns the accumulated result, these can all be - return VK_WHATEVER; + return x11_swapchain_result(chain, VK_WHATEVER); That makes things quite a bit cleaner. > + goto out; > } > } > > @@ -734,24 +770,31 @@ x11_acquire_next_image_poll_x11(struct > x11_swapchain *chain, > > if (timeout == UINT64_MAX) { > event = xcb_wait_for_special_event(chain->conn, > chain->special_event); > - if (!event) > - return VK_ERROR_OUT_OF_DATE_KHR; > + if (!event) { > + result = VK_ERROR_OUT_OF_DATE_KHR; > + goto out; > + } > } else { > event = xcb_poll_for_special_event(chain->conn, > chain->special_event); > if (!event) { > int ret; > - if (timeout == 0) > - return VK_NOT_READY; > + if (timeout == 0) { > + result = VK_NOT_READY; > + goto out; > + } > > atimeout = wsi_get_absolute_timeout(timeout); > > pfds.fd = xcb_get_file_descriptor(chain->conn); > pfds.events = POLLIN; > ret = poll(&pfds, 1, timeout / 1000 / 1000); > - if (ret == 0) > - return VK_TIMEOUT; > - if (ret == -1) > - return VK_ERROR_OUT_OF_DATE_KHR; > + if (ret == 0) { > + result = VK_TIMEOUT; > + goto out; > + } else if (ret == -1) { > + result = VK_ERROR_OUT_OF_DATE_KHR; > + goto out; > + } > > /* If a non-special event happens, the fd will still > * poll. So recalculate the timeout now just in case. > @@ -765,11 +808,18 @@ x11_acquire_next_image_poll_x11(struct > x11_swapchain *chain, > } > } > > + /* Update the swapchain status here. We may catch non-fatal errors > here, > + * in which case we need to update the status and continue. > + */ > VkResult result = x11_handle_dri3_present_event(chain, (void > *)event); > This shadows the function-scope result variable. I don't think that's what you intended. > + result = x11_swapchain_result(chain, result); > free(event); > - if (result != VK_SUCCESS) > - return result; > + if (result < 0) > + goto out; > } > + > +out: > + return x11_swapchain_result(chain, result); > } > > static VkResult > @@ -781,11 +831,9 @@ x11_acquire_next_image_from_queue(struct > x11_swapchain *chain, > uint32_t image_index; > VkResult result = wsi_queue_pull(&chain->acquire_queue, > &image_index, timeout); > - if (result != VK_SUCCESS) { > - return result; > - } else if (chain->status != VK_SUCCESS) { > - return chain->status; > - } > + /* On error, the thread has shut down, so safe to update chain->status > */ > + if (result < 0) > + return x11_swapchain_result(chain, result); > I think we also want if (result == VK_TIMEOUT) return result; > > assert(image_index < chain->base.image_count); > xshmfence_await(chain->images[image_index].shm_fence); > @@ -859,13 +907,16 @@ x11_queue_present(struct wsi_swapchain *anv_chain, > const VkPresentRegionKHR *damage) > { > struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; > + VkResult result; > > if (chain->threaded) { > wsi_queue_push(&chain->present_queue, image_index); > - return chain->status; > + result = chain->status; > } else { > - return x11_present_to_x11(chain, image_index, 0); > + result = x11_present_to_x11(chain, image_index, 0); > Fun fact: x11_present_to_x11 always returns VK_SUCCESS. I don't think this function needs to be modified at all. > } > + > + return x11_swapchain_result(chain, result); > } > > static void * > @@ -876,7 +927,7 @@ x11_manage_fifo_queues(void *state) > > assert(chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR); > > - while (chain->status == VK_SUCCESS) { > + while (chain->status >= 0) { > /* It should be safe to unconditionally block here. Later in the > loop > * we blocks until the previous present has landed on-screen. At > that > * point, we should have received IDLE_NOTIFY on all images > presented > @@ -885,15 +936,18 @@ x11_manage_fifo_queues(void *state) > */ > uint32_t image_index; > result = wsi_queue_pull(&chain->present_queue, &image_index, > INT64_MAX); > - if (result != VK_SUCCESS) { > + if (result < 0) { > goto fail; > - } else if (chain->status != VK_SUCCESS) { > + } else if (chain->status < 0) { > + /* The status can change underneath us if the swapchain is > destroyed > + * from another thread. > + */ > return NULL; > } > > uint64_t target_msc = chain->last_present_msc + 1; > result = x11_present_to_x11(chain, image_index, target_msc); > - if (result != VK_SUCCESS) > + if (result < 0) > goto fail; > > while (chain->last_present_msc < target_msc) { > @@ -904,13 +958,13 @@ x11_manage_fifo_queues(void *state) > > result = x11_handle_dri3_present_event(chain, (void *)event); > free(event); > - if (result != VK_SUCCESS) > + if (result < 0) > goto fail; > } > } > > fail: > - chain->status = result; > + result = x11_swapchain_result(chain, result); > The "result =" does nothing here. I'm fine with leaving it though as it's also not hurting anything. > wsi_queue_push(&chain->acquire_queue, UINT32_MAX); > > return NULL; > @@ -932,7 +986,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain > *chain, > result = wsi_create_native_image(&chain->base, pCreateInfo, > 0, NULL, NULL, &image->base); > } > - if (result != VK_SUCCESS) > + if (result < 0) > return result; > > image->pixmap = xcb_generate_id(chain->conn); > -- > 2.5.0.400.gff86faf > >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev