From 409568b8d401ef8f6dee06441bb66959494a0c87 Mon Sep 17 00:00:00 2001 From: dancingmirrors Date: Sat, 11 Jul 2026 03:28:43 -0600 Subject: [PATCH] hasvk: We can use ARYSPC_LOD0 for layered DPB. --- src/intel/isl/isl.c | 13 ++++++++++--- src/intel/vulkan_hasvk/anv_image.c | 21 +++++++-------------- src/intel/vulkan_hasvk/anv_private.h | 2 ++ src/intel/vulkan_hasvk/genX_cmd_video.c | 5 +++-- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 59e33da..d881953 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -2359,7 +2359,10 @@ isl_calc_array_pitch_el_rows_gfx4_2d( * image size to accomodate that pitch. */ if (info->array_pitch_B) { - assert(ISL_GFX_VER(dev) >= 8); + /* GFX 7 can use ARYSPC_LOD0 for video decode. */ + assert(ISL_GFX_VER(dev) >= 8 || + (ISL_GFX_VER(dev) >= 7 && + (info->usage & ISL_SURF_USAGE_VIDEO_DECODE_BIT))); uint32_t tiled_aligned_row_pitch_B = align((fmtl->bpb / 8) * phys_slice0_sa->w, tile_info->phys_extent_B.width); assert(info->array_pitch_B % tiled_aligned_row_pitch_B == 0); @@ -3781,8 +3784,12 @@ isl_surf_init_interleaved_arrays(const struct isl_device *dev, uint32_t *surfs_offsets, const struct isl_surf_init_info *infos) { - /* Adjusting the array pitch is only supported on GFX 8+ */ - assert(ISL_GFX_VER(dev) >= 8); + /* Adjusting the array pitch is only supported on GFX 8+. + * However, GFX 7 can use ARYSPC_LOD0 here for layered DPB. + */ + assert(ISL_GFX_VER(dev) >= 8 || + (ISL_GFX_VER(dev) >= 7 && total_surf > 0 && + (infos[0].usage & ISL_SURF_USAGE_VIDEO_DECODE_BIT))); assert(total_surf <= ISL_SURF_MAX_INTERLEAVED_ARRAYS); /* Do a first pass to gather uninterleave surface layouts */ diff --git a/src/intel/vulkan_hasvk/anv_image.c b/src/intel/vulkan_hasvk/anv_image.c index 6d55e56..2516198 100644 --- a/src/intel/vulkan_hasvk/anv_image.c +++ b/src/intel/vulkan_hasvk/anv_image.c @@ -137,20 +137,11 @@ image_binding_grow(const struct anv_device *device, "VkImageDrmFormatModifierExplicitCreateInfoEXT::" "pPlaneLayouts[]::offset is misaligned"); } - - /* We require that surfaces be added in memory-order. This simplifies the - * layout validation required by - * VkImageDrmFormatModifierExplicitCreateInfoEXT, - */ - if (unlikely(offset < container->size)) { - return vk_errorf(device, - VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT, - "VkImageDrmFormatModifierExplicitCreateInfoEXT::" - "pPlaneLayouts[]::offset is too small"); - } } - if (__builtin_add_overflow(offset, size, &container->size)) { + /* Track the end of each memory plane instead of assuming an append order. */ + uint64_t memory_range_end; + if (__builtin_add_overflow(offset, size, &memory_range_end)) { if (has_implicit_offset) { assert(!"overflow"); return vk_errorf(device, VK_ERROR_UNKNOWN, @@ -163,6 +154,7 @@ image_binding_grow(const struct anv_device *device, } } + container->size = MAX2(container->size, memory_range_end); container->alignment = MAX2(container->alignment, alignment); *out_range = (struct anv_image_memory_range) { @@ -1102,6 +1094,8 @@ add_all_surfaces_implicit_interleaved_arrays_layout( return result; } + image->vid_layered_interleaved = true; + return VK_SUCCESS; } @@ -1121,8 +1115,7 @@ add_all_surfaces_implicit_layout( const struct intel_device_info *devinfo = device->info; VkResult result; - /* XXX: Based on what I could glean from !35651. */ - if (devinfo->ver == 8 && image->n_planes > 1 && !image->disjoint && + if (devinfo->ver >= 7 && image->n_planes > 1 && !image->disjoint && image->vk.array_layers > 1 && (image->vk.usage & (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))) { diff --git a/src/intel/vulkan_hasvk/anv_private.h b/src/intel/vulkan_hasvk/anv_private.h index 9e82245..aa4d11b 100644 --- a/src/intel/vulkan_hasvk/anv_private.h +++ b/src/intel/vulkan_hasvk/anv_private.h @@ -3227,6 +3227,8 @@ struct anv_image { bool vid_neutral_chroma_init; + bool vid_layered_interleaved; + /** * The memory bindings created by vkCreateImage and vkBindImageMemory. * diff --git a/src/intel/vulkan_hasvk/genX_cmd_video.c b/src/intel/vulkan_hasvk/genX_cmd_video.c index 505439b..e24c33b 100644 --- a/src/intel/vulkan_hasvk/genX_cmd_video.c +++ b/src/intel/vulkan_hasvk/genX_cmd_video.c @@ -251,9 +251,10 @@ anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *img = iv->image; #if GFX_VER < 8 - const bool gen7_layered_clamp = img->vk.array_layers > 1; + const bool gen7_layered_clamp = + img->vk.array_layers > 1 && !img->vid_layered_interleaved; if (gen7_layered_clamp) - mesa_logw_once("Layered DPB is broken on gen7 when the array pitch is not tile aligned."); + mesa_logw_once("Layered DPB is broken on GFX 7 when the array pitch is not tile aligned."); #else const bool gen7_layered_clamp = false; #endif