diff --git a/src/intel/vulkan_hasvk/anv_private.h b/src/intel/vulkan_hasvk/anv_private.h index 680be5a..55f0234 100644 --- a/src/intel/vulkan_hasvk/anv_private.h +++ b/src/intel/vulkan_hasvk/anv_private.h @@ -3619,9 +3619,6 @@ anv_image_dpb_address(const struct anv_image_view *iv, &x_offset_sa, &y_offset_sa); - if (x_offset_sa || y_offset_sa) - mesa_logw_once("QPitch restrictions on gen7 can result in corruption."); - return anv_address_add(addr, offset_B); } diff --git a/src/intel/vulkan_hasvk/genX_cmd_video.c b/src/intel/vulkan_hasvk/genX_cmd_video.c index 61a6011..24942c2 100644 --- a/src/intel/vulkan_hasvk/genX_cmd_video.c +++ b/src/intel/vulkan_hasvk/genX_cmd_video.c @@ -163,6 +163,31 @@ anv_h264_sane_field_pocs(const int32_t poc[2], int32_t *top, int32_t *bottom) *top = t; *bottom = b; } +static inline struct anv_address +anv_h264_dpb_addr(const struct anv_image_view *iv, uint32_t layer, bool clamp0) +{ + if (clamp0) + return anv_image_address(iv->image, + &iv->image->planes[0].primary_surface.memory_range); + return anv_image_dpb_address(iv, layer); +} + +static inline struct anv_address +anv_h264_dmv_top(const struct anv_image_view *iv, uint32_t layer, bool clamp0) +{ + if (clamp0) + return anv_image_address(iv->image, &iv->image->vid_dmv_top_surface); + return anv_image_dmv_top_address(iv, layer); +} + +static inline struct anv_address +anv_h264_dmv_bottom(const struct anv_image_view *iv, uint32_t layer, bool clamp0) +{ + if (clamp0) + return anv_image_address(iv->image, &iv->image->vid_dmv_bottom_surface); + return anv_image_dmv_bottom_address(iv, layer); +} + static void anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, const VkVideoDecodeInfoKHR *frame_info) @@ -225,6 +250,14 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, const struct anv_image_view *iv = anv_image_view_from_handle(frame_info->dstPictureResource.imageViewBinding); const struct anv_image *img = iv->image; +#if GFX_VER < 8 + const bool gen7_layered_clamp = img->vk.array_layers > 1; + if (gen7_layered_clamp) + mesa_logw_once("hasvk/video: Layered DPB is broken on gen7 when the array pitch is not tile aligned."); +#else + const bool gen7_layered_clamp = false; +#endif + if (INTEL_DEBUG(DEBUG_PERF)) { const StdVideoDecodeH264PictureInfo *p = h264_pic_info->pStdPictureInfo; mesa_logw("hasvk/video: VID f_num=%d poc=%d/%d field=%u bot=%u idr=%u ref=%u " @@ -308,7 +341,7 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, buf.CommandType = 3; struct anv_address dst_addr = - anv_image_dpb_address(iv, frame_info->dstPictureResource.baseArrayLayer); + anv_h264_dpb_addr(iv, frame_info->dstPictureResource.baseArrayLayer, gen7_layered_clamp); #if GFX_VERx10 == 70 buf.PostDeblockingDestinationAddress = dst_addr; buf.PostDeblockingDestinationCacheabilityControl = 2; @@ -360,8 +393,9 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, continue; const struct anv_image_view *ref_iv = anv_image_view_from_handle(frame_info->pReferenceSlots[i].pPictureResource->imageViewBinding); struct anv_address ref_addr = - anv_image_dpb_address(ref_iv, - frame_info->pReferenceSlots[i].pPictureResource->baseArrayLayer); + anv_h264_dpb_addr(ref_iv, + frame_info->pReferenceSlots[i].pPictureResource->baseArrayLayer, + gen7_layered_clamp); buf.ReferencePictureAddress[hw] = ref_addr; #if GFX_VERx10 == 70 @@ -640,7 +674,7 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, uint32_t ref_layer = frame_info->pReferenceSlots[i].pPictureResource->baseArrayLayer; if (i == 0) - dmv_bo = anv_image_dmv_top_address(ref_iv, ref_layer).bo; + dmv_bo = anv_h264_dmv_top(ref_iv, ref_layer, gen7_layered_clamp).bo; #if GFX_VERx10 == 70 { bool ref_is_field = ref_info && @@ -648,16 +682,16 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, bool ref_dmv_bottom = ref_is_field && !sps->flags.direct_8x8_inference_flag; avc_directmode.DirectMVBufferAddress[hw * 2] = - anv_image_dmv_top_address(ref_iv, ref_layer); + anv_h264_dmv_top(ref_iv, ref_layer, gen7_layered_clamp); avc_directmode.DirectMVBufferAddress[hw * 2 + 1] = ref_dmv_bottom ? - anv_image_dmv_bottom_address(ref_iv, ref_layer) : - anv_image_dmv_top_address(ref_iv, ref_layer); + anv_h264_dmv_bottom(ref_iv, ref_layer, gen7_layered_clamp) : + anv_h264_dmv_top(ref_iv, ref_layer, gen7_layered_clamp); } avc_directmode.DirectMVBufferCacheabilityControl[hw * 2] = 2; avc_directmode.DirectMVBufferCacheabilityControl[hw * 2 + 1] = 2; #elif GFX_VERx10 == 75 { - struct anv_address dmv_addr = anv_image_dmv_top_address(ref_iv, ref_layer); + struct anv_address dmv_addr = anv_h264_dmv_top(ref_iv, ref_layer, gen7_layered_clamp); if (hw == 0) { avc_directmode.DirectMVBuffer0Address = dmv_addr; avc_directmode.DirectMVBufferMOCS = anv_mocs(cmd_buffer->device, dmv_addr.bo, 0); @@ -667,7 +701,7 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, } } #elif GFX_VERx10 == 80 - avc_directmode.DirectMVBufferAddress[hw] = anv_image_dmv_top_address(ref_iv, ref_layer); + avc_directmode.DirectMVBufferAddress[hw] = anv_h264_dmv_top(ref_iv, ref_layer, gen7_layered_clamp); #endif { int32_t ref_top, ref_bot; @@ -681,21 +715,21 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, { bool cur_dmv_bottom = field_pic && !sps->flags.direct_8x8_inference_flag; avc_directmode.DirectMVBufferWriteAddress[0] = - anv_image_dmv_top_address(iv, dst_layer); + anv_h264_dmv_top(iv, dst_layer, gen7_layered_clamp); avc_directmode.DirectMVBufferWriteAddress[1] = cur_dmv_bottom ? - anv_image_dmv_bottom_address(iv, dst_layer) : - anv_image_dmv_top_address(iv, dst_layer); + anv_h264_dmv_bottom(iv, dst_layer, gen7_layered_clamp) : + anv_h264_dmv_top(iv, dst_layer, gen7_layered_clamp); } avc_directmode.DirectMVBufferWriteCacheabilityControl[0] = 2; avc_directmode.DirectMVBufferWriteCacheabilityControl[1] = 2; #elif GFX_VERx10 == 75 - avc_directmode.DirectMVBufferWriteAddress = anv_image_dmv_top_address(iv, dst_layer); + avc_directmode.DirectMVBufferWriteAddress = anv_h264_dmv_top(iv, dst_layer, gen7_layered_clamp); avc_directmode.DirectMVBufferWriteMOCS = anv_mocs(cmd_buffer->device, avc_directmode.DirectMVBufferWriteAddress.bo, 0); if (!avc_directmode.DirectMVBufferMOCS) avc_directmode.DirectMVBufferMOCS = anv_mocs(cmd_buffer->device, avc_directmode.DirectMVBufferWriteAddress.bo, 0); #elif GFX_VERx10 == 80 avc_directmode.DirectMVBufferAttributes.TargetCache = 2; /* LLC/eLLC */ - avc_directmode.DirectMVBufferWriteAddress = anv_image_dmv_top_address(iv, dst_layer); + avc_directmode.DirectMVBufferWriteAddress = anv_h264_dmv_top(iv, dst_layer, gen7_layered_clamp); avc_directmode.DirectMVBufferWriteAttributes.TargetCache = 2; #endif {