From ae6e22e311d417ec0b50edb9b656c1c3de6df28a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 26 Oct 2016 11:51:27 +1000 Subject: vulkan/wsi/x11: handle timeouts properly in next image acquire (v1.1) For 0 timeout, just poll for an event, and if none, return For UINT64_MAX timeout, just wait for special event blocked For other timeouts get the xcb fd and block on it, decreasing the timeout if we get woken up for non-special events. v1.1: return VK_TIMEOUT for poll timeouts. handle timeout going negative. Reviewed-by: Edward O'Callaghan Signed-off-by: Dave Airlie (cherry picked from commit 787c172aed0ae88ca6a8c1a193d9dd744fbdc918) --- src/vulkan/wsi/wsi_common_x11.c | 62 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 09718eb..ae2d111 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -34,6 +34,7 @@ #include #include +#include #include "util/hash_table.h" #include "wsi_common.h" @@ -555,6 +556,26 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain, return VK_SUCCESS; } + +static uint64_t wsi_get_current_time(void) +{ + uint64_t current_time; + struct timespec tv; + + clock_gettime(CLOCK_MONOTONIC, &tv); + current_time = tv.tv_nsec + tv.tv_sec*1000000000ull; + return current_time; +} + +static uint64_t wsi_get_absolute_timeout(uint64_t timeout) +{ + uint64_t current_time = wsi_get_current_time(); + + timeout = MIN2(UINT64_MAX - current_time, timeout); + + return current_time + timeout; +} + static VkResult x11_acquire_next_image(struct wsi_swapchain *anv_chain, uint64_t timeout, @@ -562,7 +583,9 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain, uint32_t *image_index) { struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; - + xcb_generic_event_t *event; + struct pollfd pfds; + uint64_t atimeout; while (1) { for (uint32_t i = 0; i < chain->image_count; i++) { if (!chain->images[i].busy) { @@ -575,10 +598,39 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain, } xcb_flush(chain->conn); - xcb_generic_event_t *event = - xcb_wait_for_special_event(chain->conn, chain->special_event); - if (!event) - return VK_ERROR_OUT_OF_DATE_KHR; + + if (timeout == UINT64_MAX) { + event = xcb_wait_for_special_event(chain->conn, chain->special_event); + if (!event) + return VK_ERROR_OUT_OF_DATE_KHR; + } else { + event = xcb_poll_for_special_event(chain->conn, chain->special_event); + if (!event) { + int ret; + if (timeout == 0) + return VK_NOT_READY; + + 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 a non-special event happens, the fd will still + * poll. So recalculate the timeout now just in case. + */ + uint64_t current_time = wsi_get_current_time(); + if (atimeout > current_time) + timeout = atimeout - current_time; + else + timeout = 0; + continue; + } + } VkResult result = x11_handle_dri3_present_event(chain, (void *)event); free(event); -- cgit v1.1 From 2e3e5c0e73cf4e3156823367084fd6e2d8286be8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 26 Oct 2016 12:58:34 +1000 Subject: vulkan/wsi: store present mode in swapchain base class This just moves this up a level as x11 will need it to implement things properly. Reviewed-by: Jason Ekstrand Signed-off-by: Dave Airlie (cherry picked from commit 1cdca1eb16ab33da338dda076794efd4bf859f7b) --- src/vulkan/wsi/wsi_common.h | 1 + src/vulkan/wsi/wsi_common_wayland.c | 6 +++--- src/vulkan/wsi/wsi_common_x11.c | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index ee67511..a1f5a40 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -53,6 +53,7 @@ struct wsi_swapchain { VkAllocationCallbacks alloc; const struct wsi_image_fns *image_fns; VkFence fences[3]; + VkPresentModeKHR present_mode; VkResult (*destroy)(struct wsi_swapchain *swapchain, const VkAllocationCallbacks *pAllocator); diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index a8130ce..f6c218b 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -576,7 +576,7 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, { struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain; - if (chain->present_mode == VK_PRESENT_MODE_FIFO_KHR) { + if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) { while (!chain->fifo_ready) { int ret = wl_display_dispatch_queue(chain->display->display, chain->queue); @@ -589,7 +589,7 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, wl_surface_attach(chain->surface, chain->images[image_index].buffer, 0, 0); wl_surface_damage(chain->surface, 0, 0, INT32_MAX, INT32_MAX); - if (chain->present_mode == VK_PRESENT_MODE_FIFO_KHR) { + if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) { struct wl_callback *frame = wl_surface_frame(chain->surface); wl_proxy_set_queue((struct wl_proxy *)frame, chain->queue); wl_callback_add_listener(frame, &frame_listener, chain); @@ -717,12 +717,12 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.acquire_next_image = wsi_wl_swapchain_acquire_next_image; chain->base.queue_present = wsi_wl_swapchain_queue_present; chain->base.image_fns = image_fns; + chain->base.present_mode = pCreateInfo->presentMode; chain->surface = surface->surface; chain->extent = pCreateInfo->imageExtent; chain->vk_format = pCreateInfo->imageFormat; chain->drm_format = wl_drm_format_for_vk_format(chain->vk_format, alpha); - chain->present_mode = pCreateInfo->presentMode; chain->fifo_ready = true; chain->image_count = num_images; diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index ae2d111..9ce3842 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -825,6 +825,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.acquire_next_image = x11_acquire_next_image; chain->base.queue_present = x11_queue_present; chain->base.image_fns = image_fns; + chain->base.present_mode = pCreateInfo->presentMode; chain->conn = conn; chain->window = window; chain->depth = geometry->depth; -- cgit v1.1 From 6eceac3a029c86175c68e2759439ee070972ad79 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 26 Oct 2016 13:05:51 +1000 Subject: vulkan/wsi/x11: add support for IMMEDIATE present mode We shouldn't be using ASYNC here, that would be used for immediate mode, so let's implement that. Reviewed-by: Jason Ekstrand Signed-off-by: Dave Airlie (cherry picked from commit ca035006c86a5055c8e640f49c858f04770681eb) --- src/vulkan/wsi/wsi_common_x11.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 9ce3842..75eab6c 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -143,6 +143,7 @@ static const VkSurfaceFormatKHR formats[] = { }; static const VkPresentModeKHR present_modes[] = { + VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, }; @@ -654,7 +655,8 @@ x11_queue_present(struct wsi_swapchain *anv_chain, int64_t divisor = 0; int64_t remainder = 0; - options |= XCB_PRESENT_OPTION_ASYNC; + if (chain->base.present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) + options |= XCB_PRESENT_OPTION_ASYNC; xshmfence_reset(image->shm_fence); -- cgit v1.1 From 0aa527526c18ec630f532003eb01ae0bcf86aea3 Mon Sep 17 00:00:00 2001 From: Kevin Strasser Date: Wed, 2 Nov 2016 18:18:44 -0700 Subject: vulkan/wsi: Add a thread-safe queue implementation In order to support FIFO mode without blocking the application on calls to vkQueuePresentKHR it is necessary to enqueue the request and defer calling the server until the next vblank period. The xcb present api doesn't offer a way to register a callback, so we will have to spawn a worker thread that will wait for a request to be added to the queue, call to the server, and then make the image available for reuse. This commit introduces the queue data structure needed to implement this. Signed-off-by: Jason Ekstrand Reviewed-by: Eric Engestrom Reviewed-by: Dave Airlie Cc: "13.0" (cherry picked from commit 932bb3f0ddf22a9cbdf6d45089547765027b4397) --- src/vulkan/wsi/Makefile.sources | 3 +- src/vulkan/wsi/wsi_common_queue.h | 154 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/vulkan/wsi/wsi_common_queue.h diff --git a/src/vulkan/wsi/Makefile.sources b/src/vulkan/wsi/Makefile.sources index 3139e6d..50660f9 100644 --- a/src/vulkan/wsi/Makefile.sources +++ b/src/vulkan/wsi/Makefile.sources @@ -1,6 +1,7 @@ VULKAN_WSI_FILES := \ - wsi_common.h + wsi_common.h \ + wsi_common_queue.h VULKAN_WSI_WAYLAND_FILES := \ wsi_common_wayland.c \ diff --git a/src/vulkan/wsi/wsi_common_queue.h b/src/vulkan/wsi/wsi_common_queue.h new file mode 100644 index 0000000..0e72c8d --- /dev/null +++ b/src/vulkan/wsi/wsi_common_queue.h @@ -0,0 +1,154 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef VULKAN_WSI_COMMON_QUEUE_H +#define VULKAN_WSI_COMMON_QUEUE_H + +#include +#include +#include "util/u_vector.h" + +struct wsi_queue { + struct u_vector vector; + pthread_mutex_t mutex; + pthread_cond_t cond; +}; + +static inline int +wsi_queue_init(struct wsi_queue *queue, int length) +{ + int ret; + + uint32_t length_pow2 = 4; + while (length_pow2 < length) + length_pow2 *= 2; + + ret = u_vector_init(&queue->vector, sizeof(uint32_t), + sizeof(uint32_t) * length_pow2); + if (!ret) + return ENOMEM; + + pthread_condattr_t condattr; + ret = pthread_condattr_init(&condattr); + if (ret) + goto fail_vector; + + ret = pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC); + if (ret) + goto fail_condattr; + + ret = pthread_cond_init(&queue->cond, &condattr); + if (ret) + goto fail_condattr; + + ret = pthread_mutex_init(&queue->mutex, NULL); + if (ret) + goto fail_cond; + + return 0; + +fail_cond: + pthread_cond_destroy(&queue->cond); +fail_condattr: + pthread_condattr_destroy(&condattr); +fail_vector: + u_vector_finish(&queue->vector); + + return ret; +} + +static inline void +wsi_queue_destroy(struct wsi_queue *queue) +{ + u_vector_finish(&queue->vector); + pthread_mutex_destroy(&queue->mutex); + pthread_cond_destroy(&queue->cond); +} + +static inline void +wsi_queue_push(struct wsi_queue *queue, uint32_t index) +{ + uint32_t *elem; + + pthread_mutex_lock(&queue->mutex); + + if (u_vector_length(&queue->vector) == 0) + pthread_cond_signal(&queue->cond); + + elem = u_vector_add(&queue->vector); + *elem = index; + + pthread_mutex_unlock(&queue->mutex); +} + +#define NSEC_PER_SEC 1000000000 +#define INT_TYPE_MAX(type) ((1ull << (sizeof(type) * 8 - 1)) - 1) + +static inline VkResult +wsi_queue_pull(struct wsi_queue *queue, uint32_t *index, uint64_t timeout) +{ + VkResult result; + int32_t ret; + + pthread_mutex_lock(&queue->mutex); + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + uint32_t abs_nsec = now.tv_nsec + timeout % NSEC_PER_SEC; + uint64_t abs_sec = now.tv_sec + (abs_nsec / NSEC_PER_SEC) + + (timeout / NSEC_PER_SEC); + abs_nsec %= NSEC_PER_SEC; + + /* Avoid roll-over in tv_sec on 32-bit systems if the user provided timeout + * is UINT64_MAX + */ + struct timespec abstime; + abstime.tv_nsec = abs_nsec; + abstime.tv_sec = MIN2(abs_sec, INT_TYPE_MAX(abstime.tv_sec)); + + while (u_vector_length(&queue->vector) == 0) { + ret = pthread_cond_timedwait(&queue->cond, &queue->mutex, &abstime); + if (ret == 0) { + continue; + } else if (ret == ETIMEDOUT) { + result = VK_TIMEOUT; + goto end; + } else { + /* Something went badly wrong */ + result = VK_ERROR_OUT_OF_DATE_KHR; + goto end; + } + } + + uint32_t *elem = u_vector_remove(&queue->vector); + *index = *elem; + result = VK_SUCCESS; + +end: + pthread_mutex_unlock(&queue->mutex); + + return result; +} + +#endif /* VULKAN_WSI_COMMON_QUEUE_H */ -- cgit v1.1 From aa939d7d2a16ea3ea2da785859b96bfacf9d62d9 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 3 Nov 2016 16:59:08 -0700 Subject: vulkan/wsi/x11: Implement FIFO mode. This implements VK_PRESENT_MODE_FIFO_KHR for X11. Unfortunately, due to the way the present extension works, we have to manage the queue of presented images in a separate thread. Signed-off-by: Jason Ekstrand Reviewed-by: Eric Engestrom Reviewed-by: Dave Airlie Cc: "13.0" (cherry picked from commit e73d136a02308088cacab842790c7670e5d07b23) --- src/vulkan/wsi/wsi_common_x11.c | 174 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 164 insertions(+), 10 deletions(-) diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 75eab6c..8e0043f 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -39,6 +39,7 @@ #include "wsi_common.h" #include "wsi_common_x11.h" +#include "wsi_common_queue.h" #define typed_memcpy(dest, src, count) ({ \ static_assert(sizeof(*src) == sizeof(*dest), ""); \ @@ -145,6 +146,7 @@ static const VkSurfaceFormatKHR formats[] = { static const VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, + VK_PRESENT_MODE_FIFO_KHR, }; static xcb_screen_t * @@ -490,8 +492,15 @@ struct x11_swapchain { xcb_present_event_t event_id; xcb_special_event_t * special_event; uint64_t send_sbc; + uint64_t last_present_msc; uint32_t stamp; + bool threaded; + VkResult status; + struct wsi_queue present_queue; + struct wsi_queue acquire_queue; + pthread_t queue_manager; + struct x11_image images[0]; }; @@ -542,6 +551,8 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain, for (unsigned i = 0; i < chain->image_count; i++) { if (chain->images[i].pixmap == idle->pixmap) { chain->images[i].busy = false; + if (chain->threaded) + wsi_queue_push(&chain->acquire_queue, i); break; } } @@ -549,7 +560,13 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain, break; } - case XCB_PRESENT_COMPLETE_NOTIFY: + case XCB_PRESENT_EVENT_COMPLETE_NOTIFY: { + xcb_present_complete_notify_event_t *complete = (void *) event; + if (complete->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) + chain->last_present_msc = complete->msc; + break; + } + default: break; } @@ -578,12 +595,9 @@ static uint64_t wsi_get_absolute_timeout(uint64_t timeout) } static VkResult -x11_acquire_next_image(struct wsi_swapchain *anv_chain, - uint64_t timeout, - VkSemaphore semaphore, - uint32_t *image_index) +x11_acquire_next_image_poll_x11(struct x11_swapchain *chain, + uint32_t *image_index, uint64_t timeout) { - struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; xcb_generic_event_t *event; struct pollfd pfds; uint64_t atimeout; @@ -641,17 +655,38 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain, } static VkResult -x11_queue_present(struct wsi_swapchain *anv_chain, - uint32_t image_index) +x11_acquire_next_image_from_queue(struct x11_swapchain *chain, + uint32_t *image_index_out, uint64_t timeout) +{ + assert(chain->threaded); + + 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; + } + + assert(image_index < chain->image_count); + xshmfence_await(chain->images[image_index].shm_fence); + + *image_index_out = image_index; + + return VK_SUCCESS; +} + +static VkResult +x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index, + uint32_t target_msc) { - struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; struct x11_image *image = &chain->images[image_index]; assert(image_index < chain->image_count); uint32_t options = XCB_PRESENT_OPTION_NONE; - int64_t target_msc = 0; int64_t divisor = 0; int64_t remainder = 0; @@ -686,6 +721,82 @@ x11_queue_present(struct wsi_swapchain *anv_chain, } static VkResult +x11_acquire_next_image(struct wsi_swapchain *anv_chain, + uint64_t timeout, + VkSemaphore semaphore, + uint32_t *image_index) +{ + struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; + + if (chain->threaded) { + return x11_acquire_next_image_from_queue(chain, image_index, timeout); + } else { + return x11_acquire_next_image_poll_x11(chain, image_index, timeout); + } +} + +static VkResult +x11_queue_present(struct wsi_swapchain *anv_chain, + uint32_t image_index) +{ + struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; + + if (chain->threaded) { + wsi_queue_push(&chain->present_queue, image_index); + return chain->status; + } else { + return x11_present_to_x11(chain, image_index, 0); + } +} + +static void * +x11_manage_fifo_queues(void *state) +{ + struct x11_swapchain *chain = state; + VkResult result; + + assert(chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR); + + while (chain->status == VK_SUCCESS) { + /* 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 + * before that point so the client should be able to acquire any image + * other than the currently presented one. + */ + uint32_t image_index; + result = wsi_queue_pull(&chain->present_queue, &image_index, INT64_MAX); + if (result != VK_SUCCESS) { + goto fail; + } else if (chain->status != VK_SUCCESS) { + 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) + goto fail; + + while (chain->last_present_msc < target_msc) { + xcb_generic_event_t *event = + xcb_wait_for_special_event(chain->conn, chain->special_event); + if (!event) + goto fail; + + result = x11_handle_dri3_present_event(chain, (void *)event); + if (result != VK_SUCCESS) + goto fail; + } + } + +fail: + chain->status = result; + wsi_queue_push(&chain->acquire_queue, UINT32_MAX); + + return NULL; +} + +static VkResult x11_image_init(VkDevice device_h, struct x11_swapchain *chain, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -783,6 +894,15 @@ x11_swapchain_destroy(struct wsi_swapchain *anv_chain, for (uint32_t i = 0; i < chain->image_count; i++) x11_image_finish(chain, pAllocator, &chain->images[i]); + if (chain->threaded) { + chain->status = VK_ERROR_OUT_OF_DATE_KHR; + /* Push a UINT32_MAX to wake up the manager */ + wsi_queue_push(&chain->present_queue, UINT32_MAX); + pthread_join(chain->queue_manager, NULL); + wsi_queue_destroy(&chain->acquire_queue); + wsi_queue_destroy(&chain->present_queue); + } + xcb_unregister_for_special_event(chain->conn, chain->special_event); vk_free(pAllocator, chain); @@ -834,6 +954,9 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->extent = pCreateInfo->imageExtent; chain->image_count = num_images; chain->send_sbc = 0; + chain->last_present_msc = 0; + chain->threaded = false; + chain->status = VK_SUCCESS; free(geometry); @@ -872,6 +995,37 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, goto fail_init_images; } + if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) { + chain->threaded = true; + + /* Initialize our queues. We make them image_count + 1 because we will + * occasionally use UINT32_MAX to signal the other thread that an error + * has occurred and we don't want an overflow. + */ + int ret; + ret = wsi_queue_init(&chain->acquire_queue, chain->image_count + 1); + if (ret) { + goto fail_init_images; + } + + ret = wsi_queue_init(&chain->present_queue, chain->image_count + 1); + if (ret) { + wsi_queue_destroy(&chain->acquire_queue); + goto fail_init_images; + } + + for (unsigned i = 0; i < chain->image_count; i++) + wsi_queue_push(&chain->acquire_queue, i); + + ret = pthread_create(&chain->queue_manager, NULL, + x11_manage_fifo_queues, chain); + if (ret) { + wsi_queue_destroy(&chain->present_queue); + wsi_queue_destroy(&chain->acquire_queue); + goto fail_init_images; + } + } + *swapchain_out = &chain->base; return VK_SUCCESS; -- cgit v1.1 From 960a87fb174290f36ce0434a631b879d01397589 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Nov 2016 03:10:52 +0000 Subject: radv: fix texel fetch offset with 2d arrays. The code didn't limit the offsets to the number supplied, so if we expected 3 but only got 2 we were accessing undefined memory. This fixes random failures in: dEQP-VK.glsl.texture_functions.texelfetchoffset.sampler2darray_* Reviewed-by: Bas Nieuwenhuizen Cc: "13.0" Signed-off-by: Dave Airlie (cherry picked from commit bb8ac183404541ca8dee31563709d5aca8de0e73) --- src/amd/common/ac_nir_to_llvm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 31d7b6e..799eb34 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -3517,12 +3517,13 @@ static void visit_tex(struct nir_to_llvm_context *ctx, nir_tex_instr *instr) if (offsets && instr->op == nir_texop_txf) { nir_const_value *const_offset = nir_src_as_const_value(instr->src[const_src].src); - + int num_offsets = instr->src[const_src].src.ssa->num_components; assert(const_offset); - if (instr->coord_components > 2) + num_offsets = MIN2(num_offsets, instr->coord_components); + if (num_offsets > 2) address[2] = LLVMBuildAdd(ctx->builder, address[2], LLVMConstInt(ctx->i32, const_offset->i32[2], false), ""); - if (instr->coord_components > 1) + if (num_offsets > 1) address[1] = LLVMBuildAdd(ctx->builder, address[1], LLVMConstInt(ctx->i32, const_offset->i32[1], false), ""); address[0] = LLVMBuildAdd(ctx->builder, -- cgit v1.1 From d653c84a688d65b8b421c08fdbea6b22878a364d Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 24 Nov 2016 18:14:58 +0000 Subject: radv: honour the number of properties available Cap up-to the number of properties available while copying the data. Otherwise we might crash and/or leak data. Cc: Dave Airlie Cc: "13.0" Signed-off-by: Emil Velikov Reviewed-by: Bas Nieuwenhuizen Signed-off-by: Dave Airlie (cherry picked from commit a025c5b2c7c9c6862006b13c9b8ab46c3acf8e53) --- src/amd/vulkan/radv_device.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 4a924ea..94a2ef0 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -659,17 +659,15 @@ VkResult radv_EnumerateInstanceExtensionProperties( uint32_t* pPropertyCount, VkExtensionProperties* pProperties) { - unsigned i; if (pProperties == NULL) { *pPropertyCount = ARRAY_SIZE(global_extensions); return VK_SUCCESS; } - for (i = 0; i < *pPropertyCount; i++) - memcpy(&pProperties[i], &global_extensions[i], sizeof(VkExtensionProperties)); + *pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(global_extensions)); + typed_memcpy(pProperties, global_extensions, *pPropertyCount); - *pPropertyCount = i; - if (i < ARRAY_SIZE(global_extensions)) + if (*pPropertyCount < ARRAY_SIZE(global_extensions)) return VK_INCOMPLETE; return VK_SUCCESS; @@ -681,19 +679,17 @@ VkResult radv_EnumerateDeviceExtensionProperties( uint32_t* pPropertyCount, VkExtensionProperties* pProperties) { - unsigned i; - if (pProperties == NULL) { *pPropertyCount = ARRAY_SIZE(device_extensions); return VK_SUCCESS; } - for (i = 0; i < *pPropertyCount; i++) - memcpy(&pProperties[i], &device_extensions[i], sizeof(VkExtensionProperties)); + *pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(device_extensions)); + typed_memcpy(pProperties, device_extensions, *pPropertyCount); - *pPropertyCount = i; - if (i < ARRAY_SIZE(device_extensions)) + if (*pPropertyCount < ARRAY_SIZE(device_extensions)) return VK_INCOMPLETE; + return VK_SUCCESS; } -- cgit v1.1 From 17dee709a9b8ac358374d26c1f4efe5c7b09f5bd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Nov 2016 10:04:35 +1000 Subject: radv/si: fix optimal micro tile selection The same fix was posted for radeonsi, so port it here. Reviewed-by: Edward O'Callaghan Cc: "13.0" Signed-off-by: Dave Airlie (cherry picked from commit 9838db8f643354e485f74664b92b902fe0b95c4f) --- src/amd/vulkan/radv_image.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 3099d83..9649158 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -831,29 +831,29 @@ void radv_image_set_optimal_micro_tile_mode(struct radv_device *device, switch (micro_tile_mode) { case 0: /* displayable */ switch (image->surface.bpe) { - case 8: + case 1: image->surface.tiling_index[0] = 10; break; - case 16: + case 2: image->surface.tiling_index[0] = 11; break; - default: /* 32, 64 */ + default: /* 4, 8 */ image->surface.tiling_index[0] = 12; break; } break; case 1: /* thin */ switch (image->surface.bpe) { - case 8: + case 1: image->surface.tiling_index[0] = 14; break; - case 16: + case 2: image->surface.tiling_index[0] = 15; break; - case 32: + case 4: image->surface.tiling_index[0] = 16; break; - default: /* 64, 128 */ + default: /* 8, 16 */ image->surface.tiling_index[0] = 17; break; } -- cgit v1.1 From 87b76f0e058658ffe122b97e8dc7e7dc19d49265 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 25 Oct 2016 07:47:13 +1000 Subject: radv/ac/llvm: shadow samplers only return one value. The intrinsic engine asserts in llvm due to this. Reported-by: Christoph Haag Cc: "13.0" Signed-off-by: Dave Airlie (cherry picked from commit b56b54cbf1d8e70c87a434da5350d11533e5fed8) Squashed with commit: radv/ac/llvm: fix regression with shadow samplers fix This fixes b56b54cbf1d8e70c87a434da5350d11533e5fed8: radv/ac/llvm: shadow samplers only return one value It makes sure we only do that for shadow sampling, as opposed to sizing requests. Signed-off-by: Dave Airlie Cc: "13.0" (cherry picked from commit b2e217369e1ca4bf9d7741721559a4506b1f0ce8) Squashed with commit: radv: brown-paper bag for a forgotten else. This fixes the fix: radv/ac/llvm: fix regression with shadow samplers fix Signed-off-by: Dave Airlie Cc: "13.0" (cherry picked from commit 020978af12ef6d598bc5efeae3704c0eb8cdafd2) --- src/amd/common/ac_nir_to_llvm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 799eb34..0daef08 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -3545,6 +3545,8 @@ static void visit_tex(struct nir_to_llvm_context *ctx, nir_tex_instr *instr) if (instr->op == nir_texop_query_levels) result = LLVMBuildExtractElement(ctx->builder, result, LLVMConstInt(ctx->i32, 3, false), ""); + else if (instr->is_shadow && instr->op != nir_texop_txs && instr->op != nir_texop_lod) + result = LLVMBuildExtractElement(ctx->builder, result, ctx->i32zero, ""); else if (instr->op == nir_texop_txs && instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE && instr->is_array) { -- cgit v1.1 From 02fd5a19b7be6fe849b39e36d3b6e5f609927d2f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Nov 2016 07:03:11 +0000 Subject: radv: fix 3D clears with baseMiplevel This fixes: dEQP-VK.api.image_clearing.clear_color_image.3d* These were hitting an assert as the code wasn't taking the baseMipLevel into account when minify the image depth. Reviewed-by: Bas Nieuwenhuizen Signed-off-by: Dave Airlie Cc: "13.0" (cherry picked from commit 09c0c17bc3609a5f5d3ba1df26820406ff5449bf) --- src/amd/vulkan/radv_meta_clear.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index 7e3e5f4..a347703 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -998,7 +998,7 @@ radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer, const VkImageSubresourceRange *range = &ranges[r]; for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) { const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ? - radv_minify(image->extent.depth, l) : + radv_minify(image->extent.depth, range->baseMipLevel + l) : radv_get_layerCount(image, range); for (uint32_t s = 0; s < layer_count; ++s) { struct radv_image_view iview; -- cgit v1.1 From f92c2e3d2bc0bc44e53f42706ebce041a313246c Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 28 Nov 2016 15:02:48 +0000 Subject: Update version to 13.0.2 Signed-off-by: Emil Velikov --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5cb7d85..347caf3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -13.0.1 +13.0.2 -- cgit v1.1 From c9e993ba1301ac0380b86a3934f5c97ff0827594 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 28 Nov 2016 15:06:08 +0000 Subject: docs: add release notes for 13.0.2 Signed-off-by: Emil Velikov --- docs/relnotes/13.0.2.html | 188 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 docs/relnotes/13.0.2.html diff --git a/docs/relnotes/13.0.2.html b/docs/relnotes/13.0.2.html new file mode 100644 index 0000000..5125b61 --- /dev/null +++ b/docs/relnotes/13.0.2.html @@ -0,0 +1,188 @@ + + + + + Mesa Release Notes + + + + +
+

The Mesa 3D Graphics Library

+
+ + +
+ +

Mesa 13.0.2 Release Notes / November 28, 2016

+ +

+Mesa 13.0.2 is a bug fix release which fixes bugs found since the 13.0.1 release. +

+

+Mesa 13.0.2 implements the OpenGL 4.4 API, but the version reported by +glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) / +glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used. +Some drivers don't support all the features required in OpenGL 4.4. OpenGL +4.4 is only available if requested at context creation +because compatibility contexts are not supported. +

+ + +

SHA256 checksums

+
+TBD
+
+ + +

New features

+

None

+ + +

Bug fixes

+ +
    + +
  • Bug 97321 - Query INFO_LOG_LENGTH for empty info log should return 0
  • + +
  • Bug 97420 - "#version 0" crashes glsl_compiler
  • + +
  • Bug 98632 - Fix build on Hurd without PATH_MAX
  • + +
+ + +

Changes

+ +

Ben Widawsky (3):

+
    +
  • i965: Add some APL and KBL SKU strings
  • +
  • i965: Reorder PCI ID list to match release order
  • +
  • i965/glk: Add basic Geminilake support
  • +
+ +

Dave Airlie (14):

+
    +
  • radv: fix texturesamples to handle single sample case
  • +
  • wsi: fix VK_INCOMPLETE for vkGetSwapchainImagesKHR
  • +
  • radv: don't crash on null swapchain destroy.
  • +
  • ac/nir/llvm: fix channel in texture gather lowering code.
  • +
  • radv: make sure to flush input attachments correctly.
  • +
  • radv: fix image view creation for depth and stencil only
  • +
  • radv: spir-v allows texture size query with and without lod.
  • +
  • vulkan/wsi/x11: handle timeouts properly in next image acquire (v1.1)
  • +
  • vulkan/wsi: store present mode in swapchain base class
  • +
  • vulkan/wsi/x11: add support for IMMEDIATE present mode
  • +
  • radv: fix texel fetch offset with 2d arrays.
  • +
  • radv/si: fix optimal micro tile selection
  • +
  • radv/ac/llvm: shadow samplers only return one value.
  • +
  • radv: fix 3D clears with baseMiplevel
  • +
+ +

Eduardo Lima Mitev (2):

+
    +
  • vulkan/wsi/x11: Fix behavior of vkGetPhysicalDeviceSurfaceFormatsKHR
  • +
  • vulkan/wsi/x11: Fix behavior of vkGetPhysicalDeviceSurfacePresentModesKHR
  • +
+ +

Emil Velikov (5):

+
    +
  • docs: add sha256 checksums for 13.0.1
  • +
  • cherry-ignore: add reverted LLVM_LIBDIR patch
  • +
  • anv: fix enumeration of properties
  • +
  • radv: honour the number of properties available
  • +
  • Update version to 13.0.2
  • +
+ +

Eric Anholt (3):

+
    +
  • vc4: Don't abort when a shader compile fails.
  • +
  • vc4: Clamp the shadow comparison value.
  • +
  • vc4: Fix register class handling of DDX/DDY arguments.
  • +
+ +

Gwan-gyeong Mun (2):

+
    +
  • util/disk_cache: close a previously opened handle in disk_cache_put (v2)
  • +
  • anv: Fix unintentional integer overflow in anv_CreateDmaBufImageINTEL
  • +
+ +

Iago Toral Quiroga (1):

+
    +
  • anv/format: handle unsupported formats properly
  • +
+ +

Ian Romanick (2):

+
    +
  • glcpp: Handle '#version 0' and other invalid values
  • +
  • glsl: Parse 0 as a preprocessor INTCONSTANT
  • +
+ +

Jason Ekstrand (15):

+
    +
  • anv/gen8: Stall when needed in Cmd(Set|Reset)Event
  • +
  • anv/wsi: Set the fence to signaled in AcquireNextImageKHR
  • +
  • anv: Rework fences
  • +
  • vulkan/wsi/wayland: Include pthread.h
  • +
  • vulkan/wsi/wayland: Clean up some error handling paths
  • +
  • vulkan/wsi: Report the correct min/maxImageCount
  • +
  • i965/gs: Allow primitive id to be a system value
  • +
  • anv: Handle null in all destructors
  • +
  • anv/fence: Handle ANV_FENCE_CREATE_SIGNALED_BIT
  • +
  • nir/spirv: Fix handling of gl_PrimitiveId
  • +
  • anv/blorp: Ignore clears for attachments first used as resolve destinations
  • +
  • anv: Implement a depth stall restriction on gen7
  • +
  • anv/cmd_buffer: Handle running out of binding tables in compute shaders
  • +
  • anv/cmd_buffer: Emit a CS stall before setting a CS pipeline
  • +
  • vulkan/wsi/x11: Implement FIFO mode.
  • +
+ +

Jordan Justen (2):

+
    +
  • isl: Fix height calculation in isl_msaa_interleaved_scale_px_to_sa
  • +
  • i965/hsw: Set integer mode in sampling state for stencil texturing
  • +
+ +

Kenneth Graunke (4):

+
    +
  • intel: Set min_ds_entries on Broxton.
  • +
  • i965: Fix compute shader crash.
  • +
  • mesa: Drop PATH_MAX usage.
  • +
  • i965: Fix GS push inputs with enhanced layouts.
  • +
+ +

Kevin Strasser (1):

+
    +
  • vulkan/wsi: Add a thread-safe queue implementation
  • +
+ +

Lionel Landwerlin (1):

+
    +
  • anv: fix multi level clears with VK_REMAINING_MIP_LEVELS
  • +
+ +

Lucas Stach (1):

+
    +
  • gbm: request correct version of the DRI2_FENCE extension
  • +
+ +

Nicolai Hähnle (2):

+
    +
  • radeonsi: store group_size_variable in struct si_compute
  • +
  • glsl/lower_output_reads: fix geometry shader output handling with conditional emit
  • +
+ +

Steinar H. Gunderson (1):

+
    +
  • Fix races during _mesa_HashWalk().
  • +
+ +

Tapani Pälli (1):

+
    +
  • mesa: fix empty program log length
  • +
+ + +
+ + -- cgit v1.1 From 2722144beddac0aa7065b478502c7c3a1f2a5451 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 28 Nov 2016 15:28:01 +0000 Subject: docs: add sha256 checksums for 13.0.2 Signed-off-by: Emil Velikov --- docs/relnotes/13.0.2.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/relnotes/13.0.2.html b/docs/relnotes/13.0.2.html index 5125b61..2f50199 100644 --- a/docs/relnotes/13.0.2.html +++ b/docs/relnotes/13.0.2.html @@ -31,7 +31,8 @@ because compatibility contexts are not supported.

SHA256 checksums

-TBD
+6014233a5db6032ab8de4881384871bbe029de684502707794ce7b3e6beec308  mesa-13.0.2.tar.gz
+a6ed622645f4ed61da418bf65adde5bcc4bb79023c36ba7d6b45b389da4416d5  mesa-13.0.2.tar.xz
 
-- cgit v1.1