Module: Mesa Branch: main Commit: 644611010e2877f67893846938847bb8095efa41 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=644611010e2877f67893846938847bb8095efa41
Author: Alyssa Rosenzweig <[email protected]> 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 <[email protected]> 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 */
