From 3d993e63bb59a6a25cf15e72495c0ccbf2df453e Mon Sep 17 00:00:00 2001 From: Sagar Ghuge Date: Fri, 8 Sep 2023 14:15:22 -0700 Subject: [PATCH] anv: Enable barrier handling on video engines v1: (Lionel) - Don't check for the layout transition Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9776 Signed-off-by: Sagar Ghuge Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/vulkan/genX_cmd_buffer.c | 88 +++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 417d0ed9327..b79c5b99633 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3837,6 +3837,16 @@ stage_is_transfer(const VkPipelineStageFlags2 stage) VK_PIPELINE_STAGE_2_TRANSFER_BIT)); } +static inline bool +stage_is_video(const VkPipelineStageFlags2 stage) +{ + return (stage & (VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT | +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR | +#endif + VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR)); +} + static inline bool mask_is_shader_write(const VkAccessFlags2 access) { @@ -3867,11 +3877,86 @@ mask_is_write(const VkAccessFlags2 access) VK_ACCESS_2_OPTICAL_FLOW_WRITE_BIT_NV); } +static void +cmd_buffer_barrier_video(struct anv_cmd_buffer *cmd_buffer, + const VkDependencyInfo *dep_info) +{ + assert(anv_cmd_buffer_is_video_queue(cmd_buffer)); + + bool flush_llc = false; + bool flush_ccs = false; + for (uint32_t i = 0; i < dep_info->imageMemoryBarrierCount; i++) { + const VkImageMemoryBarrier2 *img_barrier = + &dep_info->pImageMemoryBarriers[i]; + + ANV_FROM_HANDLE(anv_image, image, img_barrier->image); + const VkImageSubresourceRange *range = &img_barrier->subresourceRange; + + /* If srcQueueFamilyIndex is not equal to dstQueueFamilyIndex, this + * memory barrier defines a queue family ownership transfer. + */ + if (img_barrier->srcQueueFamilyIndex != img_barrier->dstQueueFamilyIndex) + flush_llc = true; + + VkImageAspectFlags img_aspects = + vk_image_expand_aspect_mask(&image->vk, range->aspectMask); + anv_foreach_image_aspect_bit(aspect_bit, image, img_aspects) { + const uint32_t plane = + anv_image_aspect_to_plane(image, 1UL << aspect_bit); + if (isl_aux_usage_has_ccs(image->planes[plane].aux_usage)) { + flush_ccs = true; + } + } + } + + for (uint32_t i = 0; i < dep_info->bufferMemoryBarrierCount; i++) { + /* Flush the cache if something is written by the video operations and + * used by any other stages except video encode/decode stages or if + * srcQueueFamilyIndex is not equal to dstQueueFamilyIndex, this memory + * barrier defines a queue family ownership transfer. + */ + if ((stage_is_video(dep_info->pBufferMemoryBarriers[i].srcStageMask) && + mask_is_write(dep_info->pBufferMemoryBarriers[i].srcAccessMask) && + !stage_is_video(dep_info->pBufferMemoryBarriers[i].dstStageMask)) || + (dep_info->pBufferMemoryBarriers[i].srcQueueFamilyIndex != + dep_info->pBufferMemoryBarriers[i].dstQueueFamilyIndex)) { + flush_llc = true; + break; + } + } + + for (uint32_t i = 0; i < dep_info->memoryBarrierCount; i++) { + /* Flush the cache if something is written by the video operations and + * used by any other stages except video encode/decode stage. + */ + if (stage_is_video(dep_info->pMemoryBarriers[i].srcStageMask) && + mask_is_write(dep_info->pMemoryBarriers[i].srcAccessMask) && + !stage_is_video(dep_info->pMemoryBarriers[i].dstStageMask)) { + flush_llc = true; + break; + } + } + + if (flush_ccs || flush_llc) { + anv_batch_emit(&cmd_buffer->batch, GENX(MI_FLUSH_DW), fd) { +#if GFX_VERx10 >= 125 + fd.FlushCCS = flush_ccs; +#endif + fd.FlushLLC = flush_llc; + } + } +} + static void cmd_buffer_barrier(struct anv_cmd_buffer *cmd_buffer, const VkDependencyInfo *dep_info, const char *reason) { + if (anv_cmd_buffer_is_video_queue(cmd_buffer)) { + cmd_buffer_barrier_video(cmd_buffer, dep_info); + return; + } + struct anv_device *device = cmd_buffer->device; /* XXX: Right now, we're really dumb and just flush whatever categories @@ -3883,9 +3968,6 @@ cmd_buffer_barrier(struct anv_cmd_buffer *cmd_buffer, bool apply_sparse_flushes = false; - if (anv_cmd_buffer_is_video_queue(cmd_buffer)) - return; - for (uint32_t i = 0; i < dep_info->memoryBarrierCount; i++) { src_flags |= dep_info->pMemoryBarriers[i].srcAccessMask; dst_flags |= dep_info->pMemoryBarriers[i].dstAccessMask;