From ebd65d011faa751774808e0d70cc990ab9a08fbf Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 3 Nov 2022 09:15:20 +0100 Subject: [PATCH] v3dv: fix event synchronization MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Since we now implement events in the GPU we need to be more careful and insert barriers to honor the dependencies provided by the API as well as ensuring we are synchronizing these with the compute queue, since that is how we implement GPU event functionality. Fixes: ecb01d53fdb413121ce2 ("v3dv: refactor events") Reviewed-by: Alejandro Piñeiro Part-of: (cherry picked from commit e6884df088a1e172cd87956fe9afdac63069eb2c) --- .pick_status.json | 2 +- src/broadcom/vulkan/v3dv_event.c | 109 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 2b79581..4b4658f 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2299,7 +2299,7 @@ "description": "v3dv: fix event synchronization", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "ecb01d53fdb413121ce2a8f36ad67e51898eec00" }, diff --git a/src/broadcom/vulkan/v3dv_event.c b/src/broadcom/vulkan/v3dv_event.c index 529b88d..8d57849 100644 --- a/src/broadcom/vulkan/v3dv_event.c +++ b/src/broadcom/vulkan/v3dv_event.c @@ -591,8 +591,54 @@ v3dv_CmdSetEvent2(VkCommandBuffer commandBuffer, assert(cmd_buffer->state.pass == NULL); assert(cmd_buffer->state.job == NULL); - v3dv_CmdPipelineBarrier2(commandBuffer, pDependencyInfo); + /* We need to add the compute stage to the dstStageMask of all dependencies, + * so let's go ahead and patch the dependency info we receive. + */ + uint32_t memory_barrier_count = pDependencyInfo->memoryBarrierCount; + VkMemoryBarrier2 *memory_barriers = memory_barrier_count ? + malloc(memory_barrier_count * sizeof(memory_barriers[0])): NULL; + for (int i = 0; i < memory_barrier_count; i++) { + memory_barriers[i] = pDependencyInfo->pMemoryBarriers[i]; + memory_barriers[i].dstStageMask |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + } + + uint32_t buffer_barrier_count = pDependencyInfo->bufferMemoryBarrierCount; + VkBufferMemoryBarrier2 *buffer_barriers = buffer_barrier_count ? + malloc(buffer_barrier_count * sizeof(buffer_barriers[0])): NULL; + for (int i = 0; i < buffer_barrier_count; i++) { + buffer_barriers[i] = pDependencyInfo->pBufferMemoryBarriers[i]; + buffer_barriers[i].dstStageMask |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + } + + uint32_t image_barrier_count = pDependencyInfo->imageMemoryBarrierCount; + VkImageMemoryBarrier2 *image_barriers = image_barrier_count ? + malloc(image_barrier_count * sizeof(image_barriers[0])): NULL; + for (int i = 0; i < image_barrier_count; i++) { + image_barriers[i] = pDependencyInfo->pImageMemoryBarriers[i]; + image_barriers[i].dstStageMask |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + } + + VkDependencyInfo info = { + .sType = pDependencyInfo->sType, + .dependencyFlags = pDependencyInfo->dependencyFlags, + .memoryBarrierCount = memory_barrier_count, + .pMemoryBarriers = memory_barriers, + .bufferMemoryBarrierCount = buffer_barrier_count, + .pBufferMemoryBarriers = buffer_barriers, + .imageMemoryBarrierCount = image_barrier_count, + .pImageMemoryBarriers = image_barriers, + }; + + v3dv_cmd_buffer_emit_pipeline_barrier(cmd_buffer, &info); + cmd_buffer_emit_set_event(cmd_buffer, event, 1); + + if (memory_barriers) + free(memory_barriers); + if (buffer_barriers) + free(buffer_barriers); + if (image_barriers) + free(image_barriers); } VKAPI_ATTR void VKAPI_CALL @@ -609,6 +655,18 @@ v3dv_CmdResetEvent2(VkCommandBuffer commandBuffer, assert(cmd_buffer->state.pass == NULL); assert(cmd_buffer->state.job == NULL); + VkMemoryBarrier2 barrier = { + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + .srcStageMask = stageMask, + .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, + }; + VkDependencyInfo info = { + .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + .memoryBarrierCount = 1, + .pMemoryBarriers = &barrier, + }; + v3dv_cmd_buffer_emit_pipeline_barrier(cmd_buffer, &info); + cmd_buffer_emit_set_event(cmd_buffer, event, 0); } @@ -616,11 +674,58 @@ VKAPI_ATTR void VKAPI_CALL v3dv_CmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, - const VkDependencyInfo *pDependencyInfos) + const VkDependencyInfo *pDependencyInfo) { V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); for (uint32_t i = 0; i < eventCount; i++) { struct v3dv_event *event = v3dv_event_from_handle(pEvents[i]);; cmd_buffer_emit_wait_event(cmd_buffer, event); } + + /* We need to add the compute stage to the srcStageMask of all dependencies, + * so let's go ahead and patch the dependency info we receive. + */ + uint32_t memory_barrier_count = pDependencyInfo->memoryBarrierCount; + VkMemoryBarrier2 *memory_barriers = memory_barrier_count ? + malloc(memory_barrier_count * sizeof(memory_barriers[0])): NULL; + for (int i = 0; i < memory_barrier_count; i++) { + memory_barriers[i] = pDependencyInfo->pMemoryBarriers[i]; + memory_barriers[i].srcStageMask |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + } + + uint32_t buffer_barrier_count = pDependencyInfo->bufferMemoryBarrierCount; + VkBufferMemoryBarrier2 *buffer_barriers = buffer_barrier_count ? + malloc(buffer_barrier_count * sizeof(buffer_barriers[0])): NULL; + for (int i = 0; i < buffer_barrier_count; i++) { + buffer_barriers[i] = pDependencyInfo->pBufferMemoryBarriers[i]; + buffer_barriers[i].srcStageMask |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + } + + uint32_t image_barrier_count = pDependencyInfo->imageMemoryBarrierCount; + VkImageMemoryBarrier2 *image_barriers = image_barrier_count ? + malloc(image_barrier_count * sizeof(image_barriers[0])): NULL; + for (int i = 0; i < image_barrier_count; i++) { + image_barriers[i] = pDependencyInfo->pImageMemoryBarriers[i]; + image_barriers[i].srcStageMask |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + } + + VkDependencyInfo info = { + .sType = pDependencyInfo->sType, + .dependencyFlags = pDependencyInfo->dependencyFlags, + .memoryBarrierCount = memory_barrier_count, + .pMemoryBarriers = memory_barriers, + .bufferMemoryBarrierCount = buffer_barrier_count, + .pBufferMemoryBarriers = buffer_barriers, + .imageMemoryBarrierCount = image_barrier_count, + .pImageMemoryBarriers = image_barriers, + }; + + v3dv_cmd_buffer_emit_pipeline_barrier(cmd_buffer, &info); + + if (memory_barriers) + free(memory_barriers); + if (buffer_barriers) + free(buffer_barriers); + if (image_barriers) + free(image_barriers); } -- 2.7.4