From b2a1a3c79181a1a843d7bc772b4e9c751a93c86e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 27 Nov 2024 20:15:51 +0900 Subject: [PATCH] [vulkan] Add source barrier to packet scatter and image copy I got a sync validation error on a scatter command (I think) thus the setting was probably wrong. Most of the parameters are still what they were, but I'll be able to tweak the barriers as necessary. Unfortunately, it didn't help with the hang on fetching the light cull query data when starting in fisheye mode (no hang when enabling fisheye after startup). I'm not sure what's going on there other than the queries aren't getting updated: the counts seem to be fine so maybe the commands aren't running. I've probably got a tangled mess of pseudo-parallel command buffers: I need to go through my system and clean everything up. --- include/QF/Vulkan/barrier.h | 1 + include/QF/Vulkan/staging.h | 2 + libs/models/alias/vulkan_model_alias.c | 9 ++-- libs/models/iqm/vulkan_model_iqm.c | 3 +- libs/video/renderer/vulkan/barrier.c | 19 +++++++-- libs/video/renderer/vulkan/staging.c | 6 ++- libs/video/renderer/vulkan/vulkan_draw.c | 2 + libs/video/renderer/vulkan/vulkan_lighting.c | 44 ++++++++++++++++---- 8 files changed, 69 insertions(+), 17 deletions(-) diff --git a/include/QF/Vulkan/barrier.h b/include/QF/Vulkan/barrier.h index fe3fbb41e..b1c7a9cc5 100644 --- a/include/QF/Vulkan/barrier.h +++ b/include/QF/Vulkan/barrier.h @@ -37,6 +37,7 @@ enum { enum { qfv_BB_Unknown_to_TransferWrite, qfv_BB_UniformRead_to_TransferWrite, + qfv_BB_VertexAttrRead_to_TransferWrite, qfv_BB_TransferWrite_to_VertexAttrRead, qfv_BB_TransferWrite_to_IndexRead, qfv_BB_TransferWrite_to_UniformRead, diff --git a/include/QF/Vulkan/staging.h b/include/QF/Vulkan/staging.h index 295d8a7ba..be0f3cf0f 100644 --- a/include/QF/Vulkan/staging.h +++ b/include/QF/Vulkan/staging.h @@ -48,10 +48,12 @@ void QFV_PacketCopyBuffer (qfv_packet_t *packet, const struct qfv_bufferbarrier_s *dstBarrier); void QFV_PacketScatterBuffer (qfv_packet_t *packet, VkBuffer dstBuffer, uint32_t count, qfv_scatter_t *scatter, + const struct qfv_bufferbarrier_s *srcBarrier, const struct qfv_bufferbarrier_s *dstBarrier); struct qfv_imagebarrier_s; void QFV_PacketCopyImage (qfv_packet_t *packet, VkImage dstImage, int width, int height, + const struct qfv_imagebarrier_s *srcBarrier, const struct qfv_imagebarrier_s *dstBarrier); #endif//__QF_Vulkan_staging_h diff --git a/libs/models/alias/vulkan_model_alias.c b/libs/models/alias/vulkan_model_alias.c index b93855397..e9e7ba12b 100644 --- a/libs/models/alias/vulkan_model_alias.c +++ b/libs/models/alias/vulkan_model_alias.c @@ -442,12 +442,15 @@ Vulkan_Mod_FinalizeAliasModel (mod_alias_ctx_t *alias_ctx, vulkan_ctx_t *ctx) packet_data += ind_scatter.length; build_inds (indices, hdr->mdl.numtris, indexmap, alias_ctx); + auto sb = &bufferBarriers[qfv_BB_Unknown_to_TransferWrite]; + auto var = &bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead]; + auto ir = &bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]; QFV_PacketScatterBuffer (packet, mesh->vertex_buffer, 1, &vert_scatter, - &bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead]); + sb, var); QFV_PacketScatterBuffer (packet, mesh->uv_buffer, 1, &uv_scatter, - &bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead]); + sb, var); QFV_PacketScatterBuffer (packet, mesh->index_buffer, 1, &ind_scatter, - &bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]); + sb, ir); QFV_PacketSubmit (packet); } diff --git a/libs/models/iqm/vulkan_model_iqm.c b/libs/models/iqm/vulkan_model_iqm.c index 7c7085a2f..f9da1ad10 100644 --- a/libs/models/iqm/vulkan_model_iqm.c +++ b/libs/models/iqm/vulkan_model_iqm.c @@ -132,10 +132,11 @@ iqm_transfer_texture (tex_t *tex, VkImage image, qfv_stagebuf_t *stage, memset (dst + layer_size, 0, 2 * layer_size); int mipLevels = QFV_MipLevels (tex->width, tex->height); + auto sb = &imageBarriers[qfv_LT_Undefined_to_TransferDst]; auto ib = mipLevels == 1 ? &imageBarriers[qfv_LT_TransferDst_to_ShaderReadOnly] : nullptr; - QFV_PacketCopyImage (packet, image, tex->width, tex->height, ib); + QFV_PacketCopyImage (packet, image, tex->width, tex->height, sb, ib); if (mipLevels != 1) { QFV_GenerateMipMaps (device, packet->cmd, image, mipLevels, diff --git a/libs/video/renderer/vulkan/barrier.c b/libs/video/renderer/vulkan/barrier.c index 4e66f3fee..e509fa8fb 100644 --- a/libs/video/renderer/vulkan/barrier.c +++ b/libs/video/renderer/vulkan/barrier.c @@ -199,13 +199,26 @@ const qfv_bufferbarrier_t bufferBarriers[] = { .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, }, }, + [qfv_BB_VertexAttrRead_to_TransferWrite] = { + .srcStages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + .dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + }, + }, [qfv_BB_TransferWrite_to_VertexAttrRead] = { .srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT, .dstStages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, .barrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, }, }, [qfv_BB_TransferWrite_to_IndexRead] = { diff --git a/libs/video/renderer/vulkan/staging.c b/libs/video/renderer/vulkan/staging.c index 6782f0ff5..483f2a03e 100644 --- a/libs/video/renderer/vulkan/staging.c +++ b/libs/video/renderer/vulkan/staging.c @@ -365,10 +365,11 @@ QFV_PacketCopyBuffer (qfv_packet_t *packet, void QFV_PacketScatterBuffer (qfv_packet_t *packet, VkBuffer dstBuffer, uint32_t count, qfv_scatter_t *scatter, + const qfv_bufferbarrier_t *srcBarrier, const qfv_bufferbarrier_t *dstBarrier) { qfv_devfuncs_t *dfunc = packet->stage->device->funcs; - qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite]; + qfv_bufferbarrier_t bb = *srcBarrier; VkBufferCopy copy_regions[count]; VkBufferMemoryBarrier barriers[count] = {};//FIXME arm gcc sees as uninit for (uint32_t i = 0; i < count; i++) { @@ -401,10 +402,11 @@ QFV_PacketScatterBuffer (qfv_packet_t *packet, VkBuffer dstBuffer, void QFV_PacketCopyImage (qfv_packet_t *packet, VkImage dstImage, int width, int height, + const qfv_imagebarrier_t *srcBarrier, const qfv_imagebarrier_t *dstBarrier) { qfv_devfuncs_t *dfunc = packet->stage->device->funcs; - qfv_imagebarrier_t ib = imageBarriers[qfv_LT_Undefined_to_TransferDst]; + qfv_imagebarrier_t ib = *srcBarrier; ib.barrier.image = dstImage; ib.barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; ib.barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 1db9b5bb2..6764747fd 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -767,6 +767,7 @@ load_lmp (const char *path, vulkan_ctx_t *ctx) Vulkan_ExpandPalette (texels, tex.data, palette, 2, count); QFV_PacketCopyImage (packet, cache_image->image.image, tex.width, tex.height, + &imageBarriers[qfv_LT_Undefined_to_TransferDst], &imageBarriers[qfv_LT_TransferDst_to_ShaderReadOnly]); QFV_PacketSubmit (packet); @@ -1814,6 +1815,7 @@ Vulkan_Draw_AddFont (font_t *rfont, vulkan_ctx_t *ctx) memcpy (texels, tex.data, tex.width * tex.height); QFV_PacketCopyImage (packet, glyph_image->image.image, tex.width, tex.height, + &imageBarriers[qfv_LT_Undefined_to_TransferDst], &imageBarriers[qfv_LT_TransferDst_to_ShaderReadOnly]); QFV_PacketSubmit (packet); diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index 662563082..c429eef34 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -623,6 +623,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, return; } + auto sb = &bufferBarriers[qfv_BB_UniformRead_to_TransferWrite]; auto bb = &bufferBarriers[qfv_BB_TransferWrite_to_UniformRead]; uint32_t light_ids[ST_COUNT][MaxLights]; @@ -703,7 +704,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, styles[i] = (vec4f_t) { 1, 1, 1, d_lightstylevalue[i] / 65536.0}; } QFV_PacketScatterBuffer (packet, lframe->style_buffer, - 1, &style_scatter, bb); + 1, &style_scatter, sb, bb); if (queue[ST_CASCADE].count) { uint32_t mat_count = queue[ST_CASCADE].count * num_cascade; @@ -722,7 +723,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, }; } QFV_PacketScatterBuffer (packet, lframe->shadowmat_buffer, - queue[ST_CASCADE].count, scatter, bb); + queue[ST_CASCADE].count, scatter, sb, bb); } if (ndlight) { @@ -739,7 +740,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, cube_mats (&mats[i * 6], dynamic_lights[i]->origin); } QFV_PacketScatterBuffer (packet, lframe->shadowmat_buffer, - 1, &mat_scatter, bb); + 1, &mat_scatter, sb, bb); auto lights = (light_t *) packet_data; qfv_scatter_t light_scatter = { @@ -773,7 +774,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, lights[i] = light; } QFV_PacketScatterBuffer (packet, lframe->light_buffer, - 1, &light_scatter, bb); + 1, &light_scatter, sb, bb); auto render = (qfv_light_render_t *) packet_data; qfv_scatter_t render_scatter = { @@ -789,7 +790,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, }; } QFV_PacketScatterBuffer (packet, lframe->render_buffer, - 1, &render_scatter, bb); + 1, &render_scatter, sb, bb); } if (developer & SYS_lighting) { Vulkan_Draw_String (vid.width - 32, 8, @@ -815,6 +816,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, } QFV_PacketScatterBuffer (packet, lframe->id_buffer, 1, &lid_scatter, + &bufferBarriers[qfv_BB_VertexAttrRead_to_TransferWrite], &bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead]); auto lradii = (float *) packet_data; @@ -830,6 +832,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, } QFV_PacketScatterBuffer (packet, lframe->radius_buffer, 1, &lradius_scatter, + &bufferBarriers[qfv_BB_VertexAttrRead_to_TransferWrite], &bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead]); auto eids = (uint32_t *) packet_data; @@ -844,6 +847,17 @@ lighting_update_lights (const exprval_t **params, exprval_t *result, sizeof (uint32_t[queue[i].count])); } QFV_PacketScatterBuffer (packet, lframe->entid_buffer, 1, &eid_scatter, + &(qfv_bufferbarrier_t) { + .srcStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, + .dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_SHADER_READ_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + }, + }, &(qfv_bufferbarrier_t) { .srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT, .dstStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, @@ -1121,6 +1135,19 @@ lighting_rewrite_ids (lightingframe_t *lframe, vulkan_ctx_t *ctx) enqueue_map (matrix_ids, lframe, r); } + static qfv_bufferbarrier_t transfer_dst = { + .srcStages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT + | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT + | VK_ACCESS_SHADER_READ_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + }, + }; static qfv_bufferbarrier_t vtxattr_read = { .srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT, .dstStages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT @@ -1148,11 +1175,12 @@ lighting_rewrite_ids (lightingframe_t *lframe, vulkan_ctx_t *ctx) }; QFV_PacketScatterBuffer (packet, lframe->id_buffer, 1, &id_scatter, - &vtxattr_read); + &transfer_dst, &vtxattr_read); QFV_PacketScatterBuffer (packet, lframe->radius_buffer, 1, &radius_scatter, - &vtxattr_read); + &transfer_dst, &vtxattr_read); QFV_PacketScatterBuffer (packet, lframe->shadowmat_id_buffer, - 1, &matrix_id_scater, &storage_read); + 1, &matrix_id_scater, + &transfer_dst, &storage_read); QFV_PacketSubmit (packet); transition_shadow_targets (lframe, ctx);