From 7f94b8000156069f5e05aff89edf25ba4cf47935 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 21 Mar 2023 10:46:39 +0100 Subject: [PATCH] ac/surface: introduce umd metadata v2 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Update the metadata format. For gfx8- chips nothing change. For gfx9 chips: * for textures without a valid modifier a dw is added at index=10 containing the stride * for textures with a valid modifier the modifier is stored at index 10 and 11. Then the number of planes is stored at 12. Then for each plane the offset and the stride are stored. The goal here is to be able to create textures from dmabuf from umr - without these changes this is impossible because these values can't be guessed. The new layout is compatible with version=1 so old/new UMD can be used together without issues and isn't used by default. For radeonsi, it will be possible to use it with a AMD_DEBUG=... option. Reviewed-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Marek Olšák Part-of: --- src/amd/common/ac_surface.c | 42 +++++++++++++++++++++++++------ src/amd/common/ac_surface.h | 3 ++- src/amd/vulkan/radv_image.c | 3 ++- src/gallium/drivers/radeonsi/si_texture.c | 3 ++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index eff1431..783b854 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -2747,7 +2747,7 @@ bool ac_surface_apply_umd_metadata(const struct radeon_info *info, struct radeon if (offset || /* Non-zero planes ignore metadata. */ size_metadata < 10 * 4 || /* at least 2(header) + 8(desc) dwords */ - metadata[0] == 0 || /* invalid version number */ + metadata[0] == 0 || /* invalid version number (1 and 2 layouts are compatible) */ metadata[1] != ac_get_umd_metadata_word1(info)) /* invalid PCI ID */ { /* Disable DCC because it might not be enabled. */ ac_surface_zero_dcc_fields(surf); @@ -2824,7 +2824,8 @@ bool ac_surface_apply_umd_metadata(const struct radeon_info *info, struct radeon void ac_surface_compute_umd_metadata(const struct radeon_info *info, struct radeon_surf *surf, unsigned num_mipmap_levels, uint32_t desc[8], - unsigned *size_metadata, uint32_t metadata[64]) + unsigned *size_metadata, uint32_t metadata[64], + bool include_tool_md) { /* Clear the base address and set the relative DCC offset. */ desc[0] = 0; @@ -2853,17 +2854,23 @@ void ac_surface_compute_umd_metadata(const struct radeon_info *info, struct rade assert(0); } - /* Metadata image format format version 1: - * [0] = 1 (metadata format identifier) + /* Metadata image format format version 1 and 2. Version 2 uses the same layout as + * version 1 with some additional fields (used if include_tool_md=true). + * [0] = metadata_format_identifier * [1] = (VENDOR_ID << 16) | PCI_ID * [2:9] = image descriptor for the whole resource * [2] is always 0, because the base address is cleared * [9] is the DCC offset bits [39:8] from the beginning of * the buffer - * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level + * gfx8-: [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level (gfx8-) + * ---- The data below is only set in version=2. + * It shouldn't be used by the driver as it's only present to help + * tools (eg: umr) that would want to access this buffer. + * gfx9+ if valid modifier: [10:11] = modifier + * [12:12+3*nplane] = [offset, stride] + * else: [10]: stride */ - - metadata[0] = 1; /* metadata image format version 1 */ + metadata[0] = include_tool_md ? 2 : 1; /* metadata image format version */ /* Tiling modes are ambiguous without a PCI ID. */ metadata[1] = ac_get_umd_metadata_word1(info); @@ -2878,6 +2885,27 @@ void ac_surface_compute_umd_metadata(const struct radeon_info *info, struct rade metadata[10 + i] = surf->u.legacy.level[i].offset_256B; *size_metadata += num_mipmap_levels * 4; + } else if (include_tool_md) { + if (surf->modifier != DRM_FORMAT_MOD_INVALID) { + /* Modifier */ + metadata[10] = surf->modifier; + metadata[11] = surf->modifier >> 32; + /* Num planes */ + int nplanes = ac_surface_get_nplanes(surf); + metadata[12] = nplanes; + int ndw = 13; + for (int i = 0; i < nplanes; i++) { + metadata[ndw++] = ac_surface_get_plane_offset(info->gfx_level, + surf, i, 0); + metadata[ndw++] = ac_surface_get_plane_stride(info->gfx_level, + surf, i, 0); + } + *size_metadata = ndw * 4; + } else { + metadata[10] = ac_surface_get_plane_stride(info->gfx_level, + surf, 0, 0); + *size_metadata = 11 * 4; + } } } diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h index 164695f..f96283a 100644 --- a/src/amd/common/ac_surface.h +++ b/src/amd/common/ac_surface.h @@ -451,7 +451,8 @@ bool ac_surface_apply_umd_metadata(const struct radeon_info *info, struct radeon unsigned size_metadata, const uint32_t metadata[64]); void ac_surface_compute_umd_metadata(const struct radeon_info *info, struct radeon_surf *surf, unsigned num_mipmap_levels, uint32_t desc[8], - unsigned *size_metadata, uint32_t metadata[64]); + unsigned *size_metadata, uint32_t metadata[64], + bool include_tool_md); bool ac_surface_override_offset_stride(const struct radeon_info *info, struct radeon_surf *surf, unsigned num_mipmap_levels, uint64_t offset, unsigned pitch); diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index ec3e99f..734d8e4 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -1442,7 +1442,8 @@ radv_query_opaque_metadata(struct radv_device *device, struct radv_image *image, desc, NULL); ac_surface_compute_umd_metadata(&device->physical_device->rad_info, &image->planes[0].surface, - image->info.levels, desc, &md->size_metadata, md->metadata); + image->info.levels, desc, &md->size_metadata, md->metadata, + false); } void diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index b320553..f7ef69d 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -555,7 +555,8 @@ static void si_set_tex_bo_metadata(struct si_screen *sscreen, struct si_texture ac_surface_compute_umd_metadata(&sscreen->info, &tex->surface, tex->buffer.b.b.last_level + 1, - desc, &md.size_metadata, md.metadata); + desc, &md.size_metadata, md.metadata, + false); sscreen->ws->buffer_set_metadata(sscreen->ws, tex->buffer.buf, &md, &tex->surface); } -- 2.7.4