mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 07:08:04 +02:00
vulkan/wsi/win32: respect acquire timeout for sw wsi
When DXGI is not supported, win32 falls back to sw wsi without acquire
timeout ignored.
This change:
1. adds the needed acquire mutex and cond
- the fail path is intentionally left untouched so that mutex and
cond are both valid when wsi_win32_swapchain_destroy is called
2. adds wsi_win32_acquire_idle_cpu_image helper to respect timeout
3. adds wsi_win32_set_image_idle helper to properly signal acquire_cond
for sw wsi case
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/15122
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40557>
This commit is contained in:
parent
8ff24c7db3
commit
af42f0c80f
1 changed files with 83 additions and 2 deletions
|
|
@ -26,6 +26,9 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util/cnd_monotonic.h"
|
||||
#include "util/timespec.h"
|
||||
#include "util/u_thread.h"
|
||||
#include "vk_format.h"
|
||||
#include "vk_instance.h"
|
||||
#include "vk_physical_device.h"
|
||||
|
|
@ -100,6 +103,8 @@ struct wsi_win32_swapchain {
|
|||
IDXGISwapChain3 *dxgi;
|
||||
struct wsi_win32 *wsi;
|
||||
wsi_win32_surface *surface;
|
||||
mtx_t acquire_mutex;
|
||||
struct u_cnd_monotonic acquire_cond;
|
||||
uint64_t flip_sequence;
|
||||
VkResult status;
|
||||
VkExtent2D extent;
|
||||
|
|
@ -602,6 +607,10 @@ wsi_win32_swapchain_destroy(struct wsi_swapchain *drv_chain,
|
|||
chain->dxgi->Release();
|
||||
|
||||
wsi_swapchain_finish(&chain->base);
|
||||
|
||||
u_cnd_monotonic_destroy(&chain->acquire_cond);
|
||||
mtx_destroy(&chain->acquire_mutex);
|
||||
|
||||
vk_free(allocator, chain);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
@ -616,6 +625,21 @@ wsi_win32_get_wsi_image(struct wsi_swapchain *drv_chain,
|
|||
return &chain->images[image_index].base;
|
||||
}
|
||||
|
||||
static void
|
||||
wsi_win32_set_image_idle(struct wsi_win32_swapchain *chain,
|
||||
struct wsi_win32_image *image)
|
||||
{
|
||||
if (!chain->dxgi)
|
||||
mtx_lock(&chain->acquire_mutex);
|
||||
|
||||
image->state = WSI_IMAGE_IDLE;
|
||||
|
||||
if (!chain->dxgi) {
|
||||
u_cnd_monotonic_broadcast(&chain->acquire_cond);
|
||||
mtx_unlock(&chain->acquire_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult
|
||||
wsi_win32_release_images(struct wsi_swapchain *drv_chain,
|
||||
uint32_t count, const uint32_t *indices)
|
||||
|
|
@ -630,7 +654,7 @@ wsi_win32_release_images(struct wsi_swapchain *drv_chain,
|
|||
uint32_t index = indices[i];
|
||||
assert(index < chain->base.image_count);
|
||||
assert(chain->images[index].state == WSI_IMAGE_DRAWING);
|
||||
chain->images[index].state = WSI_IMAGE_IDLE;
|
||||
wsi_win32_set_image_idle(chain, &chain->images[index]);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
|
@ -650,6 +674,44 @@ wsi_win32_find_idle_image(struct wsi_win32_swapchain *chain,
|
|||
return false;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
wsi_win32_acquire_idle_cpu_image_locked(struct wsi_win32_swapchain *chain,
|
||||
const VkAcquireNextImageInfoKHR *info,
|
||||
uint32_t *out_image_index)
|
||||
{
|
||||
if (wsi_win32_find_idle_image(chain, out_image_index))
|
||||
return VK_SUCCESS;
|
||||
|
||||
if (info->timeout == 0)
|
||||
return VK_NOT_READY;
|
||||
|
||||
const uint64_t abs_timeout = os_time_get_absolute_timeout(info->timeout);
|
||||
struct timespec abs_timespec;
|
||||
timespec_from_nsec(&abs_timespec, abs_timeout);
|
||||
do {
|
||||
int ret = u_cnd_monotonic_timedwait(
|
||||
&chain->acquire_cond, &chain->acquire_mutex, &abs_timespec);
|
||||
if (ret == thrd_timedout)
|
||||
return VK_TIMEOUT;
|
||||
else if (ret != thrd_success)
|
||||
return VK_ERROR_OUT_OF_DATE_KHR;
|
||||
} while (!wsi_win32_find_idle_image(chain, out_image_index));
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static inline VkResult
|
||||
wsi_win32_acquire_idle_cpu_image(struct wsi_win32_swapchain *chain,
|
||||
const VkAcquireNextImageInfoKHR *info,
|
||||
uint32_t *out_image_index)
|
||||
{
|
||||
mtx_lock(&chain->acquire_mutex);
|
||||
VkResult result = wsi_win32_acquire_idle_cpu_image_locked(chain, info,
|
||||
out_image_index);
|
||||
mtx_unlock(&chain->acquire_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
wsi_win32_acquire_next_image(struct wsi_swapchain *drv_chain,
|
||||
const VkAcquireNextImageInfoKHR *info,
|
||||
|
|
@ -662,6 +724,10 @@ wsi_win32_acquire_next_image(struct wsi_swapchain *drv_chain,
|
|||
if (chain->status != VK_SUCCESS)
|
||||
return chain->status;
|
||||
|
||||
/* acquire timeout has to be explicitly handled for sw wsi */
|
||||
if (!chain->dxgi)
|
||||
return wsi_win32_acquire_idle_cpu_image(chain, info, image_index);
|
||||
|
||||
if (wsi_win32_find_idle_image(chain, image_index))
|
||||
return VK_SUCCESS;
|
||||
|
||||
|
|
@ -753,7 +819,7 @@ wsi_win32_queue_present(struct wsi_swapchain *drv_chain,
|
|||
if (!StretchBlt(chain->chain_dc, 0, 0, chain->extent.width, chain->extent.height, image->sw.dc, 0, 0, chain->extent.width, chain->extent.height, SRCCOPY))
|
||||
chain->status = VK_ERROR_MEMORY_MAP_FAILED;
|
||||
|
||||
image->state = WSI_IMAGE_IDLE;
|
||||
wsi_win32_set_image_idle(chain, image);
|
||||
|
||||
return chain->status;
|
||||
}
|
||||
|
|
@ -857,6 +923,19 @@ wsi_win32_surface_create_swapchain(
|
|||
if (chain == NULL)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
int ret = mtx_init(&chain->acquire_mutex, mtx_plain);
|
||||
if (ret != thrd_success) {
|
||||
vk_free(allocator, chain);
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
ret = u_cnd_monotonic_init(&chain->acquire_cond);
|
||||
if (ret != thrd_success) {
|
||||
mtx_destroy(&chain->acquire_mutex);
|
||||
vk_free(allocator, chain);
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
struct wsi_dxgi_image_params dxgi_image_params = {
|
||||
{ WSI_IMAGE_TYPE_DXGI },
|
||||
};
|
||||
|
|
@ -876,6 +955,8 @@ wsi_win32_surface_create_swapchain(
|
|||
create_info, image_params,
|
||||
allocator);
|
||||
if (result != VK_SUCCESS) {
|
||||
u_cnd_monotonic_destroy(&chain->acquire_cond);
|
||||
mtx_destroy(&chain->acquire_mutex);
|
||||
vk_free(allocator, chain);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue