diff --git a/src/asahi/layout/README b/src/asahi/layout/README new file mode 100644 index 00000000000..a544d9e7079 --- /dev/null +++ b/src/asahi/layout/README @@ -0,0 +1,9 @@ +# ail + +ail is a small library for working with the image (and buffer) layouts +encountered with AGX hardware. Its design is inspired by isl. In +particular, ail strives to use isl unit suffixes and to represent +quantities in a canonical, API-agnostic fashion. + +See the isl documentation for conventions in mesa/docs/isl for the conventions +that ail tries to adhere to, in particular mesa/docs/isl/units.rst. diff --git a/src/asahi/layout/layout.c b/src/asahi/layout/layout.c new file mode 100644 index 00000000000..500b0b75f4d --- /dev/null +++ b/src/asahi/layout/layout.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2022 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 "layout.h" + +static void +ail_initialize_linear(struct ail_layout *layout) +{ + /* Select the optimal stride if none is forced */ + if (layout->linear_stride_B == 0) { + uint32_t minimum_stride_B = + util_format_get_stride(layout->format, layout->width_px); + + layout->linear_stride_B = ALIGN_POT(minimum_stride_B, AIL_CACHELINE); + } + + assert((layout->linear_stride_B % 16) == 0 && "Strides must be aligned"); + + layout->size_B = layout->linear_stride_B * layout->height_px; +} + +/* + * Calculate the minimum integer l such that x 2^-l < y, where x is an integer + * and y is a power-of-two. + */ +static unsigned +ail_min_mip_below(unsigned x, unsigned y) +{ + assert(util_is_power_of_two_nonzero(y)); + + if (x < y) + return 0; + else if (util_is_power_of_two_or_zero(x)) + return util_logbase2(x) - util_logbase2(y) + 1; + else + return util_logbase2_ceil(x) - util_logbase2(y); +} + +/* + * Get the maximum tile size possible for a given block size. This satisfy + * width * height * blocksize = 16384 = page size, so each tile is one page. + */ +static inline struct ail_tile +ail_get_max_tile_size(unsigned blocksize_B) +{ + switch (blocksize_B) { + case 1: return (struct ail_tile) { 128, 128 }; + case 2: return (struct ail_tile) { 128, 64 }; + case 4: return (struct ail_tile) { 64, 64 }; + case 8: return (struct ail_tile) { 64, 32 }; + case 16: return (struct ail_tile) { 32, 32 }; + default: unreachable("Invalid blocksize"); + } +} + +static void +ail_initialize_twiddled(struct ail_layout *layout) +{ + unsigned offset_B = 0; + unsigned blocksize_B = util_format_get_blocksize(layout->format); + + unsigned w_el = util_format_get_nblocksx(layout->format, layout->width_px); + unsigned h_el = util_format_get_nblocksy(layout->format, layout->height_px); + + /* Calculate the tile size used for the large miptree, and the dimensions of + * level 0 given that tile size. + */ + struct ail_tile tilesize_el = ail_get_max_tile_size(blocksize_B); + unsigned stx_tiles = DIV_ROUND_UP(w_el, tilesize_el.width_el); + unsigned sty_tiles = DIV_ROUND_UP(h_el, tilesize_el.height_el); + unsigned sarea_tiles = stx_tiles * sty_tiles; + + /* Calculate which level the small power-of-two miptree begins at. The + * power-of-two miptree is used when either the width or the height is + * smaller than a single large tile. + */ + unsigned pot_level = + MIN2(ail_min_mip_below(w_el, tilesize_el.width_el), + ail_min_mip_below(h_el, tilesize_el.height_el)); + + /* First allocate the large miptree. All tiles in the large miptree are of + * size tilesize_el and have their dimensions given by stx/sty/sarea. + */ + for (unsigned l = 0; l < pot_level; ++l) { + unsigned tiles = (sarea_tiles >> (2 * l)); + + bool pad_left = (stx_tiles & BITFIELD_MASK(l)); + bool pad_bottom = (sty_tiles & BITFIELD_MASK(l)); + bool pad_corner = pad_left && pad_bottom; + + if (pad_left) + tiles += (sty_tiles >> l); + + if (pad_bottom) + tiles += (stx_tiles >> l); + + if (pad_corner) + tiles += 1; + + unsigned size_el = tiles * tilesize_el.width_el * tilesize_el.height_el; + layout->level_offsets_B[l] = offset_B; + offset_B = ALIGN_POT(offset_B + (blocksize_B * size_el), AIL_CACHELINE); + + layout->tilesize_el[l] = tilesize_el; + } + + /* Then begin the POT miptree. Note that we round up to a power-of-two + * outside the loop. That ensures correct handling of cases like 33x33 + * images, where the round-down error of right-shifting could cause incorrect + * tile size calculations. + */ + unsigned potw_el = util_next_power_of_two(u_minify(w_el, pot_level)); + unsigned poth_el = util_next_power_of_two(u_minify(h_el, pot_level)); + + /* Finally we allocate the POT miptree, starting at level pot_level. Each + * level uses the largest power-of-two tile that fits the level. + */ + for (unsigned l = pot_level; l < layout->levels; ++l) { + unsigned size_el = potw_el * poth_el; + layout->level_offsets_B[l] = offset_B; + offset_B = ALIGN_POT(offset_B + (blocksize_B * size_el), AIL_CACHELINE); + + unsigned tilesize_el = MIN2(potw_el, poth_el); + layout->tilesize_el[l] = (struct ail_tile) { tilesize_el, tilesize_el }; + + potw_el = u_minify(potw_el, 1); + poth_el = u_minify(poth_el, 1); + } + + /* Arrays and cubemaps have the entire miptree duplicated and page aligned */ + layout->layer_stride_B = ALIGN_POT(offset_B, AIL_PAGESIZE); + layout->size_B = layout->layer_stride_B * layout->depth_px; +} + +void +ail_make_miptree(struct ail_layout *layout) +{ + assert(layout->width_px >= 1 && "Invalid dimensions"); + assert(layout->height_px >= 1 && "Invalid dimensions"); + + if (layout->tiling == AIL_TILING_LINEAR) { + assert(layout->depth_px == 1 && "Invalid linear layout"); + assert(layout->levels == 1 && "Invalid linear layout"); + assert(util_format_get_blockwidth(layout->format) == 1 && + "Strided linear block formats unsupported"); + assert(util_format_get_blockheight(layout->format) == 1 && + "Strided linear block formats unsupported"); + } else { + assert(layout->linear_stride_B == 0 && "Invalid nonlinear layout"); + assert(layout->depth_px >= 1 && "Invalid dimensions"); + assert(layout->levels >= 1 && "Invalid dimensions"); + } + + assert(util_format_get_blockdepth(layout->format) == 1 && + "Deep formats unsupported"); + + if (layout->tiling == AIL_TILING_LINEAR) + ail_initialize_linear(layout); + else if (layout->tiling == AIL_TILING_TWIDDLED) + ail_initialize_twiddled(layout); + else + unreachable("Unsupported tiling"); + + layout->size_B = ALIGN_POT(layout->size_B, AIL_PAGESIZE); + assert(layout->size_B > 0 && "Invalid dimensions"); +} diff --git a/src/asahi/layout/layout.h b/src/asahi/layout/layout.h new file mode 100644 index 00000000000..8ef958f66bf --- /dev/null +++ b/src/asahi/layout/layout.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2022 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. + * + */ + +#ifndef __AIL_LAYOUT_H_ +#define __AIL_LAYOUT_H_ + +#include "util/format/u_format.h" +#include "util/u_math.h" +#include "util/macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AIL_CACHELINE 0x80 +#define AIL_PAGESIZE 0x4000 +#define AIL_MAX_MIP_LEVELS 16 + +enum ail_tiling { + /** + * Strided linear (raster order). Only allowed for 1D or 2D, without + * mipmapping, multisampling, block-compression, or arrays. + */ + AIL_TILING_LINEAR, + + /** + * Twiddled (Morton order). Always allowed. + */ + AIL_TILING_TWIDDLED, +}; + +/* + * Represents the dimensions of a single tile. Used to describe tiled layouts. + * Width and height are in units of elements, not pixels, to model compressed + * textures corrects. + * + * Invariant: width_el and height_el are powers of two. + */ +struct ail_tile { + unsigned width_el, height_el; +}; + +/* + * An AGX image layout. + */ +struct ail_layout { + /** Width, height, and depth in pixels at level 0 */ + uint32_t width_px, height_px, depth_px; + + /** Number of miplevels. 1 if no mipmapping is used. */ + uint8_t levels; + + /** Tiling mode used */ + enum ail_tiling tiling; + + /** Texture format */ + enum pipe_format format; + + /** + * If tiling is LINEAR, the number of bytes between adjacent rows of + * elements. Otherwise, this field is zero. + */ + uint32_t linear_stride_B; + + /** + * Stride between layers of an array texture, including a cube map. Layer i + * begins at offset (i * layer_stride_B) from the beginning of the texture. + * + * If depth_px = 1, the value of this field is UNDEFINED. + */ + uint32_t layer_stride_B; + + /** + * Offsets of mip levels within a layer. + */ + uint32_t level_offsets_B[AIL_MAX_MIP_LEVELS]; + + /** + * If tiling is TWIDDLED, the tile size used for each mip level within a + * layer. Calculating tile sizes is the sole responsibility of + * ail_initialized_twiddled. + */ + struct ail_tile tilesize_el[AIL_MAX_MIP_LEVELS]; + + /* Size of entire texture */ + uint32_t size_B; +}; + +static inline uint32_t +ail_get_linear_stride_B(struct ail_layout *layout, ASSERTED uint8_t level) +{ + assert(layout->tiling == AIL_TILING_LINEAR && "Invalid usage"); + assert(level == 0 && "Strided linear mipmapped textures are unsupported"); + + return layout->linear_stride_B; +} + +static inline uint32_t +ail_get_layer_offset_B(struct ail_layout *layout, unsigned z_px) +{ + return z_px * layout->layer_stride_B; +} + +static inline uint32_t +ail_get_level_offset_B(struct ail_layout *layout, unsigned level) +{ + return layout->level_offsets_B[level]; +} + +static inline uint32_t +ail_get_layer_level_B(struct ail_layout *layout, unsigned z_px, unsigned level) +{ + return ail_get_layer_offset_B(layout, z_px) + + ail_get_level_offset_B(layout, level); +} + +static inline uint32_t +ail_get_linear_pixel_B(struct ail_layout *layout, ASSERTED unsigned level, + uint32_t x_px, uint32_t y_px, uint32_t z_px) +{ + assert(level == 0 && "Strided linear mipmapped textures are unsupported"); + assert(z_px == 0 && "Strided linear 3D textures are unsupported"); + assert(util_format_get_blockwidth(layout->format) == 1 && + "Strided linear block formats unsupported"); + assert(util_format_get_blockheight(layout->format) == 1 && + "Strided linear block formats unsupported"); + + return (y_px * ail_get_linear_stride_B(layout, level)) + + (x_px * util_format_get_blocksize(layout->format)); +} + +void ail_make_miptree(struct ail_layout *layout); + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif diff --git a/src/asahi/layout/meson.build b/src/asahi/layout/meson.build new file mode 100644 index 00000000000..2b8e5af7edd --- /dev/null +++ b/src/asahi/layout/meson.build @@ -0,0 +1,32 @@ +# Copyright © 2022 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 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. + +libasahi_layout_files = files( + 'layout.c', +) + +libasahi_layout = static_library( + 'asahi_layout', + [libasahi_layout_files], + include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_asahi], + c_args : [no_override_init_args], + gnu_symbol_visibility : 'hidden', + build_by_default : false, +) diff --git a/src/asahi/meson.build b/src/asahi/meson.build index f272e926c1c..8b251fd2dbe 100644 --- a/src/asahi/meson.build +++ b/src/asahi/meson.build @@ -20,9 +20,10 @@ # SOFTWARE. inc_asahi = include_directories([ - '.', 'lib', 'compiler' + '.', 'layout', 'lib', 'compiler' ]) +subdir('layout') subdir('lib') subdir('compiler') diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 389b11f2150..cb639d5debb 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -167,35 +167,15 @@ agx_resource_create(struct pipe_screen *screen, nresource->mipmapped = (templ->last_level > 0); nresource->internal_format = nresource->base.format; - unsigned offset = 0; - unsigned blocksize = util_format_get_blocksize(templ->format); - - for (unsigned l = 0; l <= templ->last_level; ++l) { - unsigned width = u_minify(templ->width0, l); - unsigned height = u_minify(templ->height0, l); - - if (nresource->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER) { - unsigned tile = agx_select_tile_size(templ->width0, templ->height0, l, blocksize); - - width = ALIGN_POT(width, tile); - height = ALIGN_POT(height, tile); - } - - /* Align stride to presumed cache line */ - nresource->slices[l].line_stride = util_format_get_stride(templ->format, width); - if (nresource->modifier == DRM_FORMAT_MOD_LINEAR) { - nresource->slices[l].line_stride = ALIGN_POT(nresource->slices[l].line_stride, 64); - } - - nresource->slices[l].offset = offset; - nresource->slices[l].size = ALIGN_POT(nresource->slices[l].line_stride * height, 0x80); - - offset += nresource->slices[l].size; - } - - /* Arrays and cubemaps have the entire miptree duplicated and page aligned (16K) */ - nresource->array_stride = ALIGN_POT(offset, 0x4000); - unsigned size = nresource->array_stride * templ->array_size * templ->depth0; + nresource->layout = (struct ail_layout) { + .tiling = (nresource->modifier == DRM_FORMAT_MOD_LINEAR) ? + AIL_TILING_LINEAR : AIL_TILING_TWIDDLED, + .format = templ->format, + .width_px = templ->width0, + .height_px = templ->height0, + .depth_px = templ->depth0 * templ->array_size, + .levels = templ->last_level + 1 + }; pipe_reference_init(&nresource->base.reference, 1); @@ -204,26 +184,25 @@ agx_resource_create(struct pipe_screen *screen, if (templ->bind & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)) { - unsigned width0 = templ->width0, height0 = templ->height0; + unsigned width = templ->width0; + unsigned height = templ->height0; - if (nresource->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER) { - width0 = ALIGN_POT(width0, 64); - height0 = ALIGN_POT(height0, 64); + if (nresource->layout.tiling == AIL_TILING_TWIDDLED) { + width = ALIGN_POT(width, 64); + height = ALIGN_POT(height, 64); } nresource->dt = winsys->displaytarget_create(winsys, templ->bind, templ->format, - width0, - height0, + width, + height, 64, NULL /*map_front_private*/, &nresource->dt_stride); - nresource->slices[0].line_stride = nresource->dt_stride; - assert((nresource->dt_stride & 0xF) == 0); - - offset = nresource->slices[0].line_stride * ALIGN_POT(templ->height0, 64); + if (nresource->layout.tiling == AIL_TILING_LINEAR) + nresource->layout.linear_stride_B = nresource->dt_stride; if (nresource->dt == NULL) { FREE(nresource); @@ -231,7 +210,8 @@ agx_resource_create(struct pipe_screen *screen, } } - nresource->bo = agx_bo_create(dev, size, AGX_MEMORY_TYPE_FRAMEBUFFER); + ail_make_miptree(&nresource->layout); + nresource->bo = agx_bo_create(dev, nresource->layout.size_B, AGX_MEMORY_TYPE_FRAMEBUFFER); if (!nresource->bo) { FREE(nresource); @@ -322,17 +302,18 @@ agx_transfer_map(struct pipe_context *pctx, } else { assert (rsrc->modifier == DRM_FORMAT_MOD_LINEAR); - transfer->base.stride = rsrc->slices[level].line_stride; - transfer->base.layer_stride = rsrc->array_stride; + transfer->base.stride = ail_get_linear_stride_B(&rsrc->layout, level); + transfer->base.layer_stride = rsrc->layout.layer_stride_B; /* Be conservative for direct writes */ if ((usage & PIPE_MAP_WRITE) && (usage & PIPE_MAP_DIRECTLY)) BITSET_SET(rsrc->data_valid, level); - return (uint8_t *) agx_map_texture_cpu(rsrc, level, box->z) - + transfer->base.box.y * rsrc->slices[level].line_stride - + transfer->base.box.x * blocksize; + uint32_t offset = ail_get_linear_pixel_B(&rsrc->layout, level, box->x, + box->y, box->z); + + return ((uint8_t *) rsrc->bo->ptr.cpu) + offset; } } diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index b0612ba3c95..36296b544b9 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -483,9 +483,12 @@ agx_create_sampler_view(struct pipe_context *pctx, else cfg.depth = state->u.tex.last_layer - state->u.tex.first_layer + 1; - cfg.stride = (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) ? - (rsrc->slices[level].line_stride - 16) : - AGX_RT_STRIDE_TILED; + if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) { + cfg.stride = ail_get_linear_stride_B(&rsrc->layout, level) - 16; + } else { + assert(rsrc->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER); + cfg.stride = AGX_RT_STRIDE_TILED; + } } /* Initialize base object */ @@ -760,10 +763,12 @@ agx_set_framebuffer_state(struct pipe_context *pctx, if (tex->mipmapped) cfg.unk_55 = 0x8; - cfg.stride = (tex->modifier == DRM_FORMAT_MOD_LINEAR) ? - (tex->slices[level].line_stride - 4) : - tex->mipmapped ? AGX_RT_STRIDE_TILED_MIPMAPPED : - AGX_RT_STRIDE_TILED; + if (tex->modifier == DRM_FORMAT_MOD_LINEAR) { + cfg.stride = ail_get_linear_stride_B(&tex->layout, level) - 4; + } else { + cfg.stride = tex->mipmapped ? AGX_RT_STRIDE_TILED_MIPMAPPED : + AGX_RT_STRIDE_TILED; + } }; } } @@ -1353,7 +1358,7 @@ agx_build_reload_pipeline(struct agx_context *ctx, uint32_t code, struct pipe_su cfg.address = agx_map_texture_gpu(rsrc, level, layer); cfg.stride = (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) ? - (rsrc->slices[level].line_stride - 16) : + (ail_get_linear_stride_B(&rsrc->layout, level) - 16) : AGX_RT_STRIDE_TILED; } diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 94f4b2796b1..791c95b44c8 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -34,6 +34,7 @@ #include "asahi/lib/agx_device.h" #include "asahi/lib/pool.h" #include "asahi/compiler/agx_compile.h" +#include "asahi/layout/layout.h" #include "compiler/nir/nir_lower_blend.h" #include "util/hash_table.h" #include "util/bitset.h" @@ -248,14 +249,7 @@ struct agx_resource { BITSET_DECLARE(data_valid, PIPE_MAX_TEXTURE_LEVELS); - struct { - unsigned offset; - unsigned line_stride; - unsigned size; - } slices[PIPE_MAX_TEXTURE_LEVELS]; - - /* Bytes from one miptree to the next */ - unsigned array_stride; + struct ail_layout layout; /* Metal does not support packed depth/stencil formats; presumably AGX does * not either. Instead, we create separate depth and stencil resources, @@ -274,26 +268,18 @@ agx_resource(struct pipe_resource *pctx) return (struct agx_resource *) pctx; } -/* - * Within a resource containing multiple layers and multiple mip levels, - * returns the offset from the start of the backing BO of a given level/slice. - */ -static inline uint32_t -agx_texture_offset(struct agx_resource *rsrc, unsigned level, unsigned z) -{ - return rsrc->slices[level].offset + (z * rsrc->array_stride); -} - static inline void * agx_map_texture_cpu(struct agx_resource *rsrc, unsigned level, unsigned z) { - return ((uint8_t *) rsrc->bo->ptr.cpu) + agx_texture_offset(rsrc, level, z); + return ((uint8_t *) rsrc->bo->ptr.cpu) + + ail_get_layer_level_B(&rsrc->layout, z, level); } static inline uint64_t agx_map_texture_gpu(struct agx_resource *rsrc, unsigned level, unsigned z) { - return rsrc->bo->ptr.gpu + (uint64_t) agx_texture_offset(rsrc, level, z); + return rsrc->bo->ptr.gpu + + (uint64_t) ail_get_layer_level_B(&rsrc->layout, z, level); } struct agx_transfer { diff --git a/src/gallium/drivers/asahi/magic.c b/src/gallium/drivers/asahi/magic.c index d7307776c1e..dcf051bed95 100644 --- a/src/gallium/drivers/asahi/magic.c +++ b/src/gallium/drivers/asahi/magic.c @@ -54,7 +54,7 @@ static size_t asahi_size_resource(struct pipe_resource *prsrc, unsigned level) { struct agx_resource *rsrc = agx_resource(prsrc); - size_t size = rsrc->slices[level].size; + size_t size = rsrc->layout.size_B; if (rsrc->separate_stencil) size += asahi_size_resource(&rsrc->separate_stencil->base, level); @@ -118,7 +118,7 @@ asahi_pack_iogpu_attachment(void *out, struct agx_resource *rsrc, agx_pack(out, IOGPU_ATTACHMENT, cfg) { cfg.type = asahi_classify_attachment(rsrc->base.format); cfg.address = agx_map_surface_resource(surf, rsrc); - cfg.size = rsrc->slices[surf->u.tex.level].size; + cfg.size = rsrc->layout.size_B; cfg.percent = (100 * cfg.size) / total_size; } } diff --git a/src/gallium/drivers/asahi/meson.build b/src/gallium/drivers/asahi/meson.build index 24da3bc10cf..c19ae0f20bf 100644 --- a/src/gallium/drivers/asahi/meson.build +++ b/src/gallium/drivers/asahi/meson.build @@ -37,5 +37,5 @@ libasahi = static_library( driver_asahi = declare_dependency( compile_args : '-DGALLIUM_ASAHI', - link_with : [libasahi, libasahi_compiler, libasahi_lib, libasahi_decode] + link_with : [libasahi, libasahi_compiler, libasahi_lib, libasahi_layout, libasahi_decode] )