ac/surface: introduce umd metadata v2
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Tue, 21 Mar 2023 09:46:39 +0000 (10:46 +0100)
committerMarge Bot <emma+marge@anholt.net>
Tue, 28 Mar 2023 15:17:28 +0000 (15:17 +0000)
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 <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21984>

src/amd/common/ac_surface.c
src/amd/common/ac_surface.h
src/amd/vulkan/radv_image.c
src/gallium/drivers/radeonsi/si_texture.c

index eff1431..783b854 100644 (file)
@@ -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;
+      }
    }
 }
 
index 164695f..f96283a 100644 (file)
@@ -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);
index ec3e99f..734d8e4 100644 (file)
@@ -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
index b320553..f7ef69d 100644 (file)
@@ -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);
 }