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 <sagar.ghuge@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25131>
This commit is contained in:
Sagar Ghuge 2023-09-08 14:15:22 -07:00 committed by Marge Bot
parent 8e97d291a8
commit 3d993e63bb

View file

@ -3837,6 +3837,16 @@ stage_is_transfer(const VkPipelineStageFlags2 stage)
VK_PIPELINE_STAGE_2_TRANSFER_BIT)); 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 static inline bool
mask_is_shader_write(const VkAccessFlags2 access) 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); 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 static void
cmd_buffer_barrier(struct anv_cmd_buffer *cmd_buffer, cmd_buffer_barrier(struct anv_cmd_buffer *cmd_buffer,
const VkDependencyInfo *dep_info, const VkDependencyInfo *dep_info,
const char *reason) 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; struct anv_device *device = cmd_buffer->device;
/* XXX: Right now, we're really dumb and just flush whatever categories /* 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; 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++) { for (uint32_t i = 0; i < dep_info->memoryBarrierCount; i++) {
src_flags |= dep_info->pMemoryBarriers[i].srcAccessMask; src_flags |= dep_info->pMemoryBarriers[i].srcAccessMask;
dst_flags |= dep_info->pMemoryBarriers[i].dstAccessMask; dst_flags |= dep_info->pMemoryBarriers[i].dstAccessMask;