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:
Mike Blumenkrantz 2022-06-10 13:24:20 -04:00
parent 2ef6b0aab1
commit ea9e30f9d2
3 changed files with 51 additions and 1 deletions

View File

@ -606,10 +606,39 @@ kopper_present(void *data, void *gdata, int thread_idx)
struct kopper_displaytarget *cdt = cpi->res->obj->dt;
struct kopper_swapchain *swapchain = cpi->swapchain;
struct zink_screen *screen = gdata;
VkResult error;
VkResult error = VK_SUCCESS;
cpi->info.pResults = &error;
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);
simple_mtx_unlock(&screen->queue_lock);
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);
}
util_dynarray_append(arr, VkSemaphore, cpi->sem);
out:
if (thread_idx != -1)
p_atomic_dec(&swapchain->async_presents);
free(cpi);

View File

@ -1262,6 +1262,9 @@ zink_destroy_screen(struct pipe_screen *pscreen)
if (screen->prev_sem)
VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
if (screen->fence)
VKSCR(DestroyFence)(screen->dev, screen->fence, NULL);
if (screen->threaded)
util_queue_destroy(&screen->flush_queue);
@ -2064,6 +2067,21 @@ zink_get_sample_pixel_grid(struct pipe_screen *pscreen, unsigned sample_count,
static void
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.depth_clip_control_missing = !screen->info.have_EXT_depth_clip_control;
if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY)

View File

@ -103,6 +103,7 @@ struct zink_screen {
uint32_t last_finished; //this is racy but ultimately doesn't matter
VkSemaphore sem;
VkSemaphore prev_sem;
VkFence fence;
struct util_queue flush_queue;
struct zink_context *copy_context;
@ -201,6 +202,7 @@ struct zink_screen {
struct {
bool color_write_missing;
bool depth_clip_control_missing;
bool implicit_sync;
} driver_workarounds;
};