Mesa (main): panfrost: Split pan_layout.c from pan_texture.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 26 18:19:26 UTC 2022


Module: Mesa
Branch: main
Commit: 644611010e2877f67893846938847bb8095efa41
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=644611010e2877f67893846938847bb8095efa41

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Sat Apr 16 10:02:51 2022 -0400

panfrost: Split pan_layout.c from pan_texture.c

Before we used GenXML, pan_texture mixed layout code with texture descriptor
packing code. For the most part, the layout code is generation-independent; the
pack code is not. We introduced an anti-pattern where the file was compiled N+1
times: N times for each PAN_ARCH value, and an extra time with no PAN_ARCH
value. And then the contents of the file changed completely depending on
PAN_ARCH. This is a pretty weird construction.

Let's instead split off the layout file from the descriptor file, compile the
layout file once, and compile the descriptor file per-gen.

Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15991>

---

 src/panfrost/lib/meson.build   |   2 +-
 src/panfrost/lib/pan_layout.c  | 333 +++++++++++++++++++++++++++++++++++++++++
 src/panfrost/lib/pan_texture.c | 332 ++--------------------------------------
 3 files changed, 345 insertions(+), 322 deletions(-)

diff --git a/src/panfrost/lib/meson.build b/src/panfrost/lib/meson.build
index ae6709e19e3..2c27d429fa6 100644
--- a/src/panfrost/lib/meson.build
+++ b/src/panfrost/lib/meson.build
@@ -80,7 +80,7 @@ libpanfrost_lib_files = files(
   'pan_clear.c',
   'pan_samples.c',
   'pan_tiler.c',
-  'pan_texture.c',
+  'pan_layout.c',
   'pan_scratch.c',
   'pan_props.c',
   'pan_util.c',
diff --git a/src/panfrost/lib/pan_layout.c b/src/panfrost/lib/pan_layout.c
new file mode 100644
index 00000000000..7dfec7bb827
--- /dev/null
+++ b/src/panfrost/lib/pan_layout.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2019-2022 Collabora, Ltd.
+ * Copyright (C) 2018-2019 Alyssa Rosenzweig
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include "util/macros.h"
+#include "util/u_math.h"
+#include "pan_texture.h"
+
+/* List of supported modifiers, in descending order of preference. AFBC is
+ * faster than u-interleaved tiling which is faster than linear. Within AFBC,
+ * enabling the YUV-like transform is typically a win where possible. */
+
+uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT] = {
+        DRM_FORMAT_MOD_ARM_AFBC(
+                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
+                AFBC_FORMAT_MOD_SPARSE |
+                AFBC_FORMAT_MOD_YTR),
+
+        DRM_FORMAT_MOD_ARM_AFBC(
+                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
+                AFBC_FORMAT_MOD_SPARSE),
+
+        DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
+        DRM_FORMAT_MOD_LINEAR
+};
+
+/* If not explicitly, line stride is calculated for block-based formats as
+ * (ceil(width / block_width) * block_size). As a special case, this is left
+ * zero if there is only a single block vertically. So, we have a helper to
+ * extract the dimensions of a block-based format and use that to calculate the
+ * line stride as such.
+ */
+
+unsigned
+panfrost_block_dim(uint64_t modifier, bool width, unsigned plane)
+{
+        if (!drm_is_afbc(modifier)) {
+                assert(modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED);
+                return 16;
+        }
+
+        switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
+        case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
+                return 16;
+        case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
+                return width ? 32 : 8;
+        case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
+                return width ? 64 : 4;
+        case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
+                return plane ? (width ? 64 : 4) : (width ? 32 : 8);
+        default:
+                unreachable("Invalid AFBC block size");
+        }
+}
+
+/* Computes sizes for checksumming, which is 8 bytes per 16x16 tile.
+ * Checksumming is believed to be a CRC variant (CRC64 based on the size?).
+ * This feature is also known as "transaction elimination". */
+
+#define CHECKSUM_TILE_WIDTH 16
+#define CHECKSUM_TILE_HEIGHT 16
+#define CHECKSUM_BYTES_PER_TILE 8
+
+unsigned
+panfrost_compute_checksum_size(
+        struct pan_image_slice_layout *slice,
+        unsigned width,
+        unsigned height)
+{
+        unsigned tile_count_x = DIV_ROUND_UP(width, CHECKSUM_TILE_WIDTH);
+        unsigned tile_count_y = DIV_ROUND_UP(height, CHECKSUM_TILE_HEIGHT);
+
+        slice->crc.stride = tile_count_x * CHECKSUM_BYTES_PER_TILE;
+
+        return slice->crc.stride * tile_count_y;
+}
+
+unsigned
+panfrost_get_layer_stride(const struct pan_image_layout *layout,
+                          unsigned level)
+{
+        if (layout->dim != MALI_TEXTURE_DIMENSION_3D)
+                return layout->array_stride;
+        else if (drm_is_afbc(layout->modifier))
+                return layout->slices[level].afbc.surface_stride;
+        else
+                return layout->slices[level].surface_stride;
+}
+
+/* Computes the offset into a texture at a particular level/face. Add to
+ * the base address of a texture to get the address to that level/face */
+
+unsigned
+panfrost_texture_offset(const struct pan_image_layout *layout,
+                        unsigned level, unsigned array_idx,
+                        unsigned surface_idx)
+{
+        return layout->slices[level].offset +
+               (array_idx * layout->array_stride) +
+               (surface_idx * layout->slices[level].surface_stride);
+}
+
+bool
+pan_image_layout_init(const struct panfrost_device *dev,
+                      struct pan_image_layout *layout,
+                      uint64_t modifier,
+                      enum pipe_format format,
+                      enum mali_texture_dimension dim,
+                      unsigned width, unsigned height, unsigned depth,
+                      unsigned array_size, unsigned nr_samples,
+                      unsigned nr_slices, enum pan_image_crc_mode crc_mode,
+                      const struct pan_image_explicit_layout *explicit_layout)
+{
+        /* Explicit stride only work with non-mipmap, non-array; single-sample
+         * 2D image, and in-band CRC can't be used.
+         */
+        if (explicit_layout &&
+	    (depth > 1 || nr_samples > 1 || array_size > 1 ||
+             dim != MALI_TEXTURE_DIMENSION_2D || nr_slices > 1 ||
+             crc_mode == PAN_IMAGE_CRC_INBAND))
+                return false;
+
+        /* Mandate 64 byte alignement */
+        if (explicit_layout && (explicit_layout->offset & 63))
+                return false;
+
+        layout->crc_mode = crc_mode;
+        layout->modifier = modifier;
+        layout->format = format;
+        layout->dim = dim;
+        layout->width = width;
+        layout->height = height;
+        layout->depth = depth;
+        layout->array_size = array_size;
+        layout->nr_samples = nr_samples;
+        layout->nr_slices = nr_slices;
+
+        unsigned bytes_per_pixel = util_format_get_blocksize(format);
+
+        /* MSAA is implemented as a 3D texture with z corresponding to the
+         * sample #, horrifyingly enough */
+
+        assert(depth == 1 || nr_samples == 1);
+
+        bool afbc = drm_is_afbc(layout->modifier);
+        bool tiled = layout->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED;
+        bool linear = layout->modifier == DRM_FORMAT_MOD_LINEAR;
+        bool should_align = tiled || afbc;
+        bool is_3d = layout->dim == MALI_TEXTURE_DIMENSION_3D;
+
+        unsigned oob_crc_offset = 0;
+        unsigned offset = explicit_layout ? explicit_layout->offset : 0;
+        unsigned tile_h = 1, tile_w = 1, tile_shift = 0;
+
+        if (tiled || afbc) {
+                tile_w = panfrost_block_dim(layout->modifier, true, 0);
+                tile_h = panfrost_block_dim(layout->modifier, false, 0);
+                if (util_format_is_compressed(format))
+                        tile_shift = 2;
+        }
+
+        for (unsigned l = 0; l < nr_slices; ++l) {
+                struct pan_image_slice_layout *slice = &layout->slices[l];
+
+                unsigned effective_width = width;
+                unsigned effective_height = height;
+                unsigned effective_depth = depth;
+
+                if (should_align) {
+                        effective_width = ALIGN_POT(effective_width, tile_w) >> tile_shift;
+                        effective_height = ALIGN_POT(effective_height, tile_h) >> tile_shift;
+
+                        /* We don't need to align depth */
+                }
+
+                /* Align levels to cache-line as a performance improvement for
+                 * linear/tiled and as a requirement for AFBC */
+
+                offset = ALIGN_POT(offset, 64);
+
+                slice->offset = offset;
+
+                /* Compute the would-be stride */
+                unsigned stride = bytes_per_pixel * effective_width;
+
+                if (explicit_layout) {
+                        /* Make sure the explicit stride is valid */
+                        if (explicit_layout->line_stride < stride)
+                                return false;
+
+                        stride = explicit_layout->line_stride;
+                } else if (linear) {
+                        /* Keep lines alignment on 64 byte for performance */
+                        stride = ALIGN_POT(stride, 64);
+                }
+
+                slice->line_stride = stride;
+                slice->row_stride = stride * (tile_h >> tile_shift);
+
+                unsigned slice_one_size = slice->line_stride * effective_height;
+
+                /* Compute AFBC sizes if necessary */
+                if (afbc) {
+                        slice->afbc.header_size =
+                                panfrost_afbc_header_size(width, height);
+
+                        /* Stride between two rows of AFBC headers */
+                        slice->afbc.row_stride =
+                                (effective_width / tile_w) *
+                                AFBC_HEADER_BYTES_PER_TILE;
+
+                        /* AFBC body size */
+                        slice->afbc.body_size = slice_one_size;
+
+                        /* 3D AFBC resources have all headers placed at the
+                         * beginning instead of having them split per depth
+                         * level
+                         */
+                        if (is_3d) {
+                                slice->afbc.surface_stride =
+                                        slice->afbc.header_size;
+                                slice->afbc.header_size *= effective_depth;
+                                slice->afbc.body_size *= effective_depth;
+                                offset += slice->afbc.header_size;
+                        } else {
+                                slice_one_size += slice->afbc.header_size;
+                                slice->afbc.surface_stride = slice_one_size;
+                        }
+                }
+
+                unsigned slice_full_size =
+                        slice_one_size * effective_depth * nr_samples;
+
+                slice->surface_stride = slice_one_size;
+
+                /* Compute AFBC sizes if necessary */
+
+                offset += slice_full_size;
+                slice->size = slice_full_size;
+
+                /* Add a checksum region if necessary */
+                if (crc_mode != PAN_IMAGE_CRC_NONE) {
+                        slice->crc.size =
+                                panfrost_compute_checksum_size(slice, width, height);
+
+                        if (crc_mode == PAN_IMAGE_CRC_INBAND) {
+                                slice->crc.offset = offset;
+                                offset += slice->crc.size;
+                                slice->size += slice->crc.size;
+                        } else {
+                                slice->crc.offset = oob_crc_offset;
+                                oob_crc_offset += slice->crc.size;
+                        }
+                }
+
+                width = u_minify(width, 1);
+                height = u_minify(height, 1);
+                depth = u_minify(depth, 1);
+        }
+
+        /* Arrays and cubemaps have the entire miptree duplicated */
+        layout->array_stride = ALIGN_POT(offset, 64);
+        if (explicit_layout)
+                layout->data_size = offset;
+        else
+                layout->data_size = ALIGN_POT(layout->array_stride * array_size, 4096);
+        layout->crc_size = oob_crc_offset;
+
+        return true;
+}
+
+void
+pan_iview_get_surface(const struct pan_image_view *iview,
+                      unsigned level, unsigned layer, unsigned sample,
+                      struct pan_surface *surf)
+{
+        level += iview->first_level;
+        assert(level < iview->image->layout.nr_slices);
+
+       layer += iview->first_layer;
+
+        bool is_3d = iview->image->layout.dim == MALI_TEXTURE_DIMENSION_3D;
+        const struct pan_image_slice_layout *slice = &iview->image->layout.slices[level];
+        mali_ptr base = iview->image->data.bo->ptr.gpu + iview->image->data.offset;
+
+        if (drm_is_afbc(iview->image->layout.modifier)) {
+                assert(!sample);
+
+                if (is_3d) {
+                        ASSERTED unsigned depth = u_minify(iview->image->layout.depth, level);
+                        assert(layer < depth);
+                        surf->afbc.header = base + slice->offset +
+                                           (layer * slice->afbc.surface_stride);
+                        surf->afbc.body = base + slice->offset +
+                                          slice->afbc.header_size +
+                                          (slice->surface_stride * layer);
+                } else {
+                        assert(layer < iview->image->layout.array_size);
+                        surf->afbc.header = base +
+                                            panfrost_texture_offset(&iview->image->layout,
+                                                                    level, layer, 0);
+                        surf->afbc.body = surf->afbc.header + slice->afbc.header_size;
+                }
+        } else {
+                unsigned array_idx = is_3d ? 0 : layer;
+                unsigned surface_idx = is_3d ? layer : sample;
+
+                surf->data = base +
+                             panfrost_texture_offset(&iview->image->layout, level,
+                                                     array_idx, surface_idx);
+        }
+}
diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c
index c5a4e1cecbf..5eeb2430e1c 100644
--- a/src/panfrost/lib/pan_texture.c
+++ b/src/panfrost/lib/pan_texture.c
@@ -29,330 +29,12 @@
 #include "util/u_math.h"
 #include "pan_texture.h"
 
-#ifndef PAN_ARCH
-
-/* Generates a texture descriptor. Ideally, descriptors are immutable after the
- * texture is created, so we can keep these hanging around in GPU memory in a
- * dedicated BO and not have to worry. In practice there are some minor gotchas
- * with this (the driver sometimes will change the format of a texture on the
- * fly for compression) but it's fast enough to just regenerate the descriptor
- * in those cases, rather than monkeypatching at drawtime. A texture descriptor
- * consists of a 32-byte header followed by pointers. 
- */
-
-/* List of supported modifiers, in descending order of preference. AFBC is
- * faster than u-interleaved tiling which is faster than linear. Within AFBC,
- * enabling the YUV-like transform is typically a win where possible. */
-
-uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT] = {
-        DRM_FORMAT_MOD_ARM_AFBC(
-                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
-                AFBC_FORMAT_MOD_SPARSE |
-                AFBC_FORMAT_MOD_YTR),
-
-        DRM_FORMAT_MOD_ARM_AFBC(
-                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
-                AFBC_FORMAT_MOD_SPARSE),
-
-        DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
-        DRM_FORMAT_MOD_LINEAR
-};
-
-/* If not explicitly, line stride is calculated for block-based formats as
- * (ceil(width / block_width) * block_size). As a special case, this is left
- * zero if there is only a single block vertically. So, we have a helper to
- * extract the dimensions of a block-based format and use that to calculate the
- * line stride as such.
- */
-
-unsigned
-panfrost_block_dim(uint64_t modifier, bool width, unsigned plane)
-{
-        if (!drm_is_afbc(modifier)) {
-                assert(modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED);
-                return 16;
-        }
-
-        switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
-        case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
-                return 16;
-        case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
-                return width ? 32 : 8;
-        case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
-                return width ? 64 : 4;
-        case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
-                return plane ? (width ? 64 : 4) : (width ? 32 : 8);
-        default:
-                unreachable("Invalid AFBC block size");
-        }
-}
-
-/* Computes sizes for checksumming, which is 8 bytes per 16x16 tile.
- * Checksumming is believed to be a CRC variant (CRC64 based on the size?).
- * This feature is also known as "transaction elimination". */
-
-#define CHECKSUM_TILE_WIDTH 16
-#define CHECKSUM_TILE_HEIGHT 16
-#define CHECKSUM_BYTES_PER_TILE 8
-
-unsigned
-panfrost_compute_checksum_size(
-        struct pan_image_slice_layout *slice,
-        unsigned width,
-        unsigned height)
-{
-        unsigned tile_count_x = DIV_ROUND_UP(width, CHECKSUM_TILE_WIDTH);
-        unsigned tile_count_y = DIV_ROUND_UP(height, CHECKSUM_TILE_HEIGHT);
-
-        slice->crc.stride = tile_count_x * CHECKSUM_BYTES_PER_TILE;
-
-        return slice->crc.stride * tile_count_y;
-}
-
-unsigned
-panfrost_get_layer_stride(const struct pan_image_layout *layout,
-                          unsigned level)
-{
-        if (layout->dim != MALI_TEXTURE_DIMENSION_3D)
-                return layout->array_stride;
-        else if (drm_is_afbc(layout->modifier))
-                return layout->slices[level].afbc.surface_stride;
-        else
-                return layout->slices[level].surface_stride;
-}
-
-/* Computes the offset into a texture at a particular level/face. Add to
- * the base address of a texture to get the address to that level/face */
-
-unsigned
-panfrost_texture_offset(const struct pan_image_layout *layout,
-                        unsigned level, unsigned array_idx,
-                        unsigned surface_idx)
-{
-        return layout->slices[level].offset +
-               (array_idx * layout->array_stride) +
-               (surface_idx * layout->slices[level].surface_stride);
-}
-
-bool
-pan_image_layout_init(const struct panfrost_device *dev,
-                      struct pan_image_layout *layout,
-                      uint64_t modifier,
-                      enum pipe_format format,
-                      enum mali_texture_dimension dim,
-                      unsigned width, unsigned height, unsigned depth,
-                      unsigned array_size, unsigned nr_samples,
-                      unsigned nr_slices, enum pan_image_crc_mode crc_mode,
-                      const struct pan_image_explicit_layout *explicit_layout)
-{
-        /* Explicit stride only work with non-mipmap, non-array; single-sample
-         * 2D image, and in-band CRC can't be used.
-         */
-        if (explicit_layout &&
-	    (depth > 1 || nr_samples > 1 || array_size > 1 ||
-             dim != MALI_TEXTURE_DIMENSION_2D || nr_slices > 1 ||
-             crc_mode == PAN_IMAGE_CRC_INBAND))
-                return false;
-
-        /* Mandate 64 byte alignement */
-        if (explicit_layout && (explicit_layout->offset & 63))
-                return false;
-
-        layout->crc_mode = crc_mode;
-        layout->modifier = modifier;
-        layout->format = format;
-        layout->dim = dim;
-        layout->width = width;
-        layout->height = height;
-        layout->depth = depth;
-        layout->array_size = array_size;
-        layout->nr_samples = nr_samples;
-        layout->nr_slices = nr_slices;
-
-        unsigned bytes_per_pixel = util_format_get_blocksize(format);
-
-        /* MSAA is implemented as a 3D texture with z corresponding to the
-         * sample #, horrifyingly enough */
-
-        assert(depth == 1 || nr_samples == 1);
-
-        bool afbc = drm_is_afbc(layout->modifier);
-        bool tiled = layout->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED;
-        bool linear = layout->modifier == DRM_FORMAT_MOD_LINEAR;
-        bool should_align = tiled || afbc;
-        bool is_3d = layout->dim == MALI_TEXTURE_DIMENSION_3D;
-
-        unsigned oob_crc_offset = 0;
-        unsigned offset = explicit_layout ? explicit_layout->offset : 0;
-        unsigned tile_h = 1, tile_w = 1, tile_shift = 0;
-
-        if (tiled || afbc) {
-                tile_w = panfrost_block_dim(layout->modifier, true, 0);
-                tile_h = panfrost_block_dim(layout->modifier, false, 0);
-                if (util_format_is_compressed(format))
-                        tile_shift = 2;
-        }
-
-        for (unsigned l = 0; l < nr_slices; ++l) {
-                struct pan_image_slice_layout *slice = &layout->slices[l];
-
-                unsigned effective_width = width;
-                unsigned effective_height = height;
-                unsigned effective_depth = depth;
-
-                if (should_align) {
-                        effective_width = ALIGN_POT(effective_width, tile_w) >> tile_shift;
-                        effective_height = ALIGN_POT(effective_height, tile_h) >> tile_shift;
-
-                        /* We don't need to align depth */
-                }
-
-                /* Align levels to cache-line as a performance improvement for
-                 * linear/tiled and as a requirement for AFBC */
-
-                offset = ALIGN_POT(offset, 64);
-
-                slice->offset = offset;
-
-                /* Compute the would-be stride */
-                unsigned stride = bytes_per_pixel * effective_width;
-
-                if (explicit_layout) {
-                        /* Make sure the explicit stride is valid */
-                        if (explicit_layout->line_stride < stride)
-                                return false;
-
-                        stride = explicit_layout->line_stride;
-                } else if (linear) {
-                        /* Keep lines alignment on 64 byte for performance */
-                        stride = ALIGN_POT(stride, 64);
-                }
-
-                slice->line_stride = stride;
-                slice->row_stride = stride * (tile_h >> tile_shift);
-
-                unsigned slice_one_size = slice->line_stride * effective_height;
-
-                /* Compute AFBC sizes if necessary */
-                if (afbc) {
-                        slice->afbc.header_size =
-                                panfrost_afbc_header_size(width, height);
-
-                        /* Stride between two rows of AFBC headers */
-                        slice->afbc.row_stride =
-                                (effective_width / tile_w) *
-                                AFBC_HEADER_BYTES_PER_TILE;
-
-                        /* AFBC body size */
-                        slice->afbc.body_size = slice_one_size;
-
-                        /* 3D AFBC resources have all headers placed at the
-                         * beginning instead of having them split per depth
-                         * level
-                         */
-                        if (is_3d) {
-                                slice->afbc.surface_stride =
-                                        slice->afbc.header_size;
-                                slice->afbc.header_size *= effective_depth;
-                                slice->afbc.body_size *= effective_depth;
-                                offset += slice->afbc.header_size;
-                        } else {
-                                slice_one_size += slice->afbc.header_size;
-                                slice->afbc.surface_stride = slice_one_size;
-                        }
-                }
-
-                unsigned slice_full_size =
-                        slice_one_size * effective_depth * nr_samples;
-
-                slice->surface_stride = slice_one_size;
-
-                /* Compute AFBC sizes if necessary */
-
-                offset += slice_full_size;
-                slice->size = slice_full_size;
-
-                /* Add a checksum region if necessary */
-                if (crc_mode != PAN_IMAGE_CRC_NONE) {
-                        slice->crc.size =
-                                panfrost_compute_checksum_size(slice, width, height);
-
-                        if (crc_mode == PAN_IMAGE_CRC_INBAND) {
-                                slice->crc.offset = offset;
-                                offset += slice->crc.size;
-                                slice->size += slice->crc.size;
-                        } else {
-                                slice->crc.offset = oob_crc_offset;
-                                oob_crc_offset += slice->crc.size;
-                        }
-                }
-
-                width = u_minify(width, 1);
-                height = u_minify(height, 1);
-                depth = u_minify(depth, 1);
-        }
-
-        /* Arrays and cubemaps have the entire miptree duplicated */
-        layout->array_stride = ALIGN_POT(offset, 64);
-        if (explicit_layout)
-                layout->data_size = offset;
-        else
-                layout->data_size = ALIGN_POT(layout->array_stride * array_size, 4096);
-        layout->crc_size = oob_crc_offset;
-
-        return true;
-}
-
-void
-pan_iview_get_surface(const struct pan_image_view *iview,
-                      unsigned level, unsigned layer, unsigned sample,
-                      struct pan_surface *surf)
-{
-        level += iview->first_level;
-        assert(level < iview->image->layout.nr_slices);
-
-       layer += iview->first_layer;
-
-        bool is_3d = iview->image->layout.dim == MALI_TEXTURE_DIMENSION_3D;
-        const struct pan_image_slice_layout *slice = &iview->image->layout.slices[level];
-        mali_ptr base = iview->image->data.bo->ptr.gpu + iview->image->data.offset;
-
-        if (drm_is_afbc(iview->image->layout.modifier)) {
-                assert(!sample);
-
-                if (is_3d) {
-                        ASSERTED unsigned depth = u_minify(iview->image->layout.depth, level);
-                        assert(layer < depth);
-                        surf->afbc.header = base + slice->offset +
-                                           (layer * slice->afbc.surface_stride);
-                        surf->afbc.body = base + slice->offset +
-                                          slice->afbc.header_size +
-                                          (slice->surface_stride * layer);
-                } else {
-                        assert(layer < iview->image->layout.array_size);
-                        surf->afbc.header = base +
-                                            panfrost_texture_offset(&iview->image->layout,
-                                                                    level, layer, 0);
-                        surf->afbc.body = surf->afbc.header + slice->afbc.header_size;
-                }
-        } else {
-                unsigned array_idx = is_3d ? 0 : layer;
-                unsigned surface_idx = is_3d ? layer : sample;
-
-                surf->data = base +
-                             panfrost_texture_offset(&iview->image->layout, level,
-                                                     array_idx, surface_idx);
-        }
-}
-
-#else /* ifndef PAN_ARCH */
-
 #if PAN_ARCH >= 5
-/* Arm Scalable Texture Compression (ASTC) corresponds to just a few formats.
+/*
+ * Arm Scalable Texture Compression (ASTC) corresponds to just a few formats.
  * The block dimension is not part of the format. Instead, it is encoded as a
  * 6-bit tag on the payload pointer. Map the block size for a single dimension.
  */
-
 static inline enum mali_astc_2d_dimension
 panfrost_astc_dim_2d(unsigned dim)
 {
@@ -849,6 +531,15 @@ panfrost_modifier_to_layout(uint64_t modifier)
 }
 #endif
 
+/*
+ * Generates a texture descriptor. Ideally, descriptors are immutable after the
+ * texture is created, so we can keep these hanging around in GPU memory in a
+ * dedicated BO and not have to worry. In practice there are some minor gotchas
+ * with this (the driver sometimes will change the format of a texture on the
+ * fly for compression) but it's fast enough to just regenerate the descriptor
+ * in those cases, rather than monkeypatching at drawtime. A texture descriptor
+ * consists of a 32-byte header followed by pointers.
+ */
 void
 GENX(panfrost_new_texture)(const struct panfrost_device *dev,
                            const struct pan_image_view *iview,
@@ -938,4 +629,3 @@ GENX(panfrost_new_texture)(const struct panfrost_device *dev,
 #endif
         }
 }
-#endif /* ifdef PAN_ARCH */



More information about the mesa-commit mailing list