zink: add implicit sync workaround for non-mesa drivers
implicit sync is hard, and many drivers get it wrong, so assume that anyone who isn't mesa might need some hand-holding cc: mesa-stable Reviewed-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17009>
This commit is contained in:
@@ -606,10 +606,39 @@ kopper_present(void *data, void *gdata, int thread_idx)
|
|||||||
struct kopper_displaytarget *cdt = cpi->res->obj->dt;
|
struct kopper_displaytarget *cdt = cpi->res->obj->dt;
|
||||||
struct kopper_swapchain *swapchain = cpi->swapchain;
|
struct kopper_swapchain *swapchain = cpi->swapchain;
|
||||||
struct zink_screen *screen = gdata;
|
struct zink_screen *screen = gdata;
|
||||||
VkResult error;
|
VkResult error = VK_SUCCESS;
|
||||||
cpi->info.pResults = &error;
|
cpi->info.pResults = &error;
|
||||||
|
|
||||||
simple_mtx_lock(&screen->queue_lock);
|
simple_mtx_lock(&screen->queue_lock);
|
||||||
|
if (screen->driver_workarounds.implicit_sync && cdt->type != KOPPER_WIN32) {
|
||||||
|
if (!screen->fence) {
|
||||||
|
VkFenceCreateInfo fci = {0};
|
||||||
|
fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
VKSCR(CreateFence)(screen->dev, &fci, NULL, &screen->fence);
|
||||||
|
}
|
||||||
|
VKSCR(ResetFences)(screen->dev, 1, &screen->fence);
|
||||||
|
VkSubmitInfo si = {0};
|
||||||
|
si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
si.waitSemaphoreCount = 1;
|
||||||
|
si.pWaitSemaphores = cpi->info.pWaitSemaphores;
|
||||||
|
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||||
|
si.pWaitDstStageMask = &stages;
|
||||||
|
|
||||||
|
error = VKSCR(QueueSubmit)(screen->queue, 1, &si, screen->fence);
|
||||||
|
if (!zink_screen_handle_vkresult(screen, error)) {
|
||||||
|
simple_mtx_unlock(&screen->queue_lock);
|
||||||
|
VKSCR(DestroySemaphore)(screen->dev, cpi->sem, NULL);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
error = VKSCR(WaitForFences)(screen->dev, 1, &screen->fence, VK_TRUE, UINT64_MAX);
|
||||||
|
if (!zink_screen_handle_vkresult(screen, error)) {
|
||||||
|
simple_mtx_unlock(&screen->queue_lock);
|
||||||
|
VKSCR(DestroySemaphore)(screen->dev, cpi->sem, NULL);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cpi->info.pWaitSemaphores = NULL;
|
||||||
|
cpi->info.waitSemaphoreCount = 0;
|
||||||
|
}
|
||||||
VkResult error2 = VKSCR(QueuePresentKHR)(screen->thread_queue, &cpi->info);
|
VkResult error2 = VKSCR(QueuePresentKHR)(screen->thread_queue, &cpi->info);
|
||||||
simple_mtx_unlock(&screen->queue_lock);
|
simple_mtx_unlock(&screen->queue_lock);
|
||||||
swapchain->last_present = cpi->image;
|
swapchain->last_present = cpi->image;
|
||||||
@@ -652,6 +681,7 @@ kopper_present(void *data, void *gdata, int thread_idx)
|
|||||||
_mesa_hash_table_insert(swapchain->presents, (void*)(uintptr_t)next, arr);
|
_mesa_hash_table_insert(swapchain->presents, (void*)(uintptr_t)next, arr);
|
||||||
}
|
}
|
||||||
util_dynarray_append(arr, VkSemaphore, cpi->sem);
|
util_dynarray_append(arr, VkSemaphore, cpi->sem);
|
||||||
|
out:
|
||||||
if (thread_idx != -1)
|
if (thread_idx != -1)
|
||||||
p_atomic_dec(&swapchain->async_presents);
|
p_atomic_dec(&swapchain->async_presents);
|
||||||
free(cpi);
|
free(cpi);
|
||||||
|
@@ -1262,6 +1262,9 @@ zink_destroy_screen(struct pipe_screen *pscreen)
|
|||||||
if (screen->prev_sem)
|
if (screen->prev_sem)
|
||||||
VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
|
VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
|
||||||
|
|
||||||
|
if (screen->fence)
|
||||||
|
VKSCR(DestroyFence)(screen->dev, screen->fence, NULL);
|
||||||
|
|
||||||
if (screen->threaded)
|
if (screen->threaded)
|
||||||
util_queue_destroy(&screen->flush_queue);
|
util_queue_destroy(&screen->flush_queue);
|
||||||
|
|
||||||
@@ -2064,6 +2067,21 @@ zink_get_sample_pixel_grid(struct pipe_screen *pscreen, unsigned sample_count,
|
|||||||
static void
|
static void
|
||||||
init_driver_workarounds(struct zink_screen *screen)
|
init_driver_workarounds(struct zink_screen *screen)
|
||||||
{
|
{
|
||||||
|
/* enable implicit sync for all non-mesa drivers */
|
||||||
|
screen->driver_workarounds.implicit_sync = true;
|
||||||
|
switch (screen->info.driver_props.driverID) {
|
||||||
|
case VK_DRIVER_ID_MESA_RADV:
|
||||||
|
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
|
||||||
|
case VK_DRIVER_ID_MESA_LLVMPIPE:
|
||||||
|
case VK_DRIVER_ID_MESA_TURNIP:
|
||||||
|
case VK_DRIVER_ID_MESA_V3DV:
|
||||||
|
case VK_DRIVER_ID_MESA_PANVK:
|
||||||
|
case VK_DRIVER_ID_MESA_VENUS:
|
||||||
|
screen->driver_workarounds.implicit_sync = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
screen->driver_workarounds.color_write_missing = !screen->info.have_EXT_color_write_enable;
|
screen->driver_workarounds.color_write_missing = !screen->info.have_EXT_color_write_enable;
|
||||||
screen->driver_workarounds.depth_clip_control_missing = !screen->info.have_EXT_depth_clip_control;
|
screen->driver_workarounds.depth_clip_control_missing = !screen->info.have_EXT_depth_clip_control;
|
||||||
if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY)
|
if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY)
|
||||||
|
@@ -103,6 +103,7 @@ struct zink_screen {
|
|||||||
uint32_t last_finished; //this is racy but ultimately doesn't matter
|
uint32_t last_finished; //this is racy but ultimately doesn't matter
|
||||||
VkSemaphore sem;
|
VkSemaphore sem;
|
||||||
VkSemaphore prev_sem;
|
VkSemaphore prev_sem;
|
||||||
|
VkFence fence;
|
||||||
struct util_queue flush_queue;
|
struct util_queue flush_queue;
|
||||||
struct zink_context *copy_context;
|
struct zink_context *copy_context;
|
||||||
|
|
||||||
@@ -201,6 +202,7 @@ struct zink_screen {
|
|||||||
struct {
|
struct {
|
||||||
bool color_write_missing;
|
bool color_write_missing;
|
||||||
bool depth_clip_control_missing;
|
bool depth_clip_control_missing;
|
||||||
|
bool implicit_sync;
|
||||||
} driver_workarounds;
|
} driver_workarounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user