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);