zink: hook up timeline semaphore signalling during batch submission

just basic parts, no waiting on semaphores yet

Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9963>
This commit is contained in:
Mike Blumenkrantz
2021-02-12 14:15:27 -05:00
committed by Marge Bot
parent 2d38fb7e61
commit 9a13add12e
7 changed files with 62 additions and 1 deletions

View File

@@ -154,6 +154,9 @@ create_batch_state(struct zink_context *ctx)
{ {
struct zink_screen *screen = zink_screen(ctx->base.screen); struct zink_screen *screen = zink_screen(ctx->base.screen);
struct zink_batch_state *bs = rzalloc(NULL, struct zink_batch_state); struct zink_batch_state *bs = rzalloc(NULL, struct zink_batch_state);
bs->have_timelines = ctx->have_timelines;
if (ctx->have_timelines)
bs->sem = ctx->batch.sem;
VkCommandPoolCreateInfo cpci = {}; VkCommandPoolCreateInfo cpci = {};
cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cpci.queueFamilyIndex = screen->gfx_queue; cpci.queueFamilyIndex = screen->gfx_queue;
@@ -244,12 +247,41 @@ get_batch_state(struct zink_context *ctx, struct zink_batch *batch)
return bs; return bs;
} }
static void
init_semaphore(struct zink_context *ctx, struct zink_batch *batch)
{
struct zink_screen *screen = zink_screen(ctx->base.screen);
VkSemaphoreCreateInfo sci = {};
VkSemaphoreTypeCreateInfo tci = {};
sci.pNext = &tci;
sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
if (vkCreateSemaphore(screen->dev, &sci, NULL, &batch->sem) != VK_SUCCESS)
ctx->have_timelines = false;
}
void void
zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch) zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
{ {
struct zink_screen *screen = zink_screen(ctx->base.screen); struct zink_screen *screen = zink_screen(ctx->base.screen);
bool fresh = !batch->state; bool fresh = !batch->state;
if (ctx->have_timelines) {
bool do_reset = false;
if (screen->last_finished > ctx->curr_batch && ctx->curr_batch == 1) {
do_reset = true;
/* semaphore signal values can never decrease,
* so we need a new semaphore anytime we overflow
*/
if (ctx->batch.prev_sem)
vkDestroySemaphore(screen->dev, ctx->batch.prev_sem, NULL);
ctx->batch.prev_sem = ctx->batch.sem;
}
if (fresh || do_reset)
init_semaphore(ctx, batch);
}
batch->state = get_batch_state(ctx, batch); batch->state = get_batch_state(ctx, batch);
assert(batch->state); assert(batch->state);
@@ -298,6 +330,7 @@ submit_queue(void *data, int thread_index)
{ {
struct zink_batch_state *bs = data; struct zink_batch_state *bs = data;
VkSubmitInfo si = {}; VkSubmitInfo si = {};
uint64_t batch_id = bs->fence.batch_id;
si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
si.waitSemaphoreCount = 0; si.waitSemaphoreCount = 0;
si.pWaitSemaphores = NULL; si.pWaitSemaphores = NULL;
@@ -307,6 +340,16 @@ submit_queue(void *data, int thread_index)
si.commandBufferCount = 1; si.commandBufferCount = 1;
si.pCommandBuffers = &bs->cmdbuf; si.pCommandBuffers = &bs->cmdbuf;
VkTimelineSemaphoreSubmitInfo tsi = {};
if (bs->have_timelines) {
tsi.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
si.pNext = &tsi;
tsi.signalSemaphoreValueCount = 1;
tsi.pSignalSemaphoreValues = &batch_id;
si.signalSemaphoreCount = 1;
si.pSignalSemaphores = &bs->sem;
}
struct wsi_memory_signal_submit_info mem_signal = { struct wsi_memory_signal_submit_info mem_signal = {
.sType = VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA, .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA,
.pNext = si.pNext, .pNext = si.pNext,

View File

@@ -55,7 +55,9 @@ struct zink_batch_state {
struct zink_context *ctx; struct zink_context *ctx;
VkCommandPool cmdpool; VkCommandPool cmdpool;
VkCommandBuffer cmdbuf; VkCommandBuffer cmdbuf;
VkQueue queue; //duplicated from batch for threading VkQueue queue; //duplicated from batch for threading
VkSemaphore sem;
struct util_queue_fence flush_completed; struct util_queue_fence flush_completed;
@@ -78,6 +80,7 @@ struct zink_batch_state {
VkDeviceSize resource_size; VkDeviceSize resource_size;
bool is_device_lost; bool is_device_lost;
bool have_timelines;
}; };
struct zink_batch { struct zink_batch {
@@ -86,6 +89,8 @@ struct zink_batch {
uint32_t last_batch_id; uint32_t last_batch_id;
VkQueue queue; //gfx+compute VkQueue queue; //gfx+compute
VkQueue thread_queue; //gfx+compute VkQueue thread_queue; //gfx+compute
VkSemaphore sem;
VkSemaphore prev_sem;
struct util_queue flush_queue; //TODO: move to wsi struct util_queue flush_queue; //TODO: move to wsi
bool has_work; bool has_work;

View File

@@ -301,6 +301,11 @@ zink_context_destroy(struct pipe_context *pctx)
pipe_resource_reference(&ctx->dummy_vertex_buffer, NULL); pipe_resource_reference(&ctx->dummy_vertex_buffer, NULL);
pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL); pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL);
if (ctx->batch.sem)
vkDestroySemaphore(screen->dev, ctx->batch.sem, NULL);
if (ctx->batch.prev_sem)
vkDestroySemaphore(screen->dev, ctx->batch.prev_sem, NULL);
if (ctx->tc) if (ctx->tc)
util_queue_destroy(&ctx->batch.flush_queue); util_queue_destroy(&ctx->batch.flush_queue);
@@ -2692,11 +2697,12 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
else else
ctx->batch.thread_queue = ctx->batch.queue; ctx->batch.thread_queue = ctx->batch.queue;
ctx->have_timelines = screen->info.have_KHR_timeline_semaphore;
simple_mtx_init(&ctx->batch_mtx, mtx_plain);
incr_curr_batch(ctx); incr_curr_batch(ctx);
zink_start_batch(ctx, &ctx->batch); zink_start_batch(ctx, &ctx->batch);
if (!ctx->batch.state) if (!ctx->batch.state)
goto fail; goto fail;
simple_mtx_init(&ctx->batch_mtx, mtx_plain);
ctx->program_cache = _mesa_hash_table_create(NULL, ctx->program_cache = _mesa_hash_table_create(NULL,
hash_gfx_program, hash_gfx_program,

View File

@@ -222,6 +222,7 @@ struct zink_context {
bool dirty_so_targets; bool dirty_so_targets;
bool xfb_barrier; bool xfb_barrier;
bool first_frame_done; bool first_frame_done;
bool have_timelines;
}; };
static inline struct zink_context * static inline struct zink_context *

View File

@@ -123,6 +123,7 @@ EXTENSIONS = [
properties=True, properties=True,
features=True, features=True,
guard=True), guard=True),
Extension("VK_KHR_timeline_semaphore"),
Extension("VK_EXT_4444_formats", Extension("VK_EXT_4444_formats",
alias="format_4444", alias="format_4444",
features=True), features=True),

View File

@@ -1174,6 +1174,9 @@ load_device_extensions(struct zink_screen *screen)
GET_PROC_ADDR(CmdBindVertexBuffers2EXT); GET_PROC_ADDR(CmdBindVertexBuffers2EXT);
} }
if (screen->info.have_KHR_timeline_semaphore)
GET_PROC_ADDR_KHR(WaitSemaphores);
screen->have_triangle_fans = true; screen->have_triangle_fans = true;
#if defined(VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME) #if defined(VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME)
if (screen->info.have_EXTX_portability_subset) { if (screen->info.have_EXTX_portability_subset) {

View File

@@ -107,6 +107,8 @@ struct zink_screen {
PFN_vkCmdDrawIndirectCount vk_CmdDrawIndirectCount; PFN_vkCmdDrawIndirectCount vk_CmdDrawIndirectCount;
PFN_vkCmdDrawIndexedIndirectCount vk_CmdDrawIndexedIndirectCount; PFN_vkCmdDrawIndexedIndirectCount vk_CmdDrawIndexedIndirectCount;
PFN_vkWaitSemaphores vk_WaitSemaphores;
PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR; PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR;
PFN_vkCmdBeginConditionalRenderingEXT vk_CmdBeginConditionalRenderingEXT; PFN_vkCmdBeginConditionalRenderingEXT vk_CmdBeginConditionalRenderingEXT;
PFN_vkCmdEndConditionalRenderingEXT vk_CmdEndConditionalRenderingEXT; PFN_vkCmdEndConditionalRenderingEXT vk_CmdEndConditionalRenderingEXT;