panfrost: Add a pan_image_layout object
authorBoris Brezillon <boris.brezillon@collabora.com>
Thu, 17 Dec 2020 11:12:28 +0000 (12:12 +0100)
committerBoris Brezillon <boris.brezillon@collabora.com>
Mon, 4 Jan 2021 16:05:42 +0000 (17:05 +0100)
Group the slices, dimension, modifier and array stride in a an object
representing the image layout. This way we shrink the number of
arguments passed to various pan_texture helpers and simplifies some
of the logic along the way.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8125>

src/gallium/drivers/panfrost/pan_cmdstream.c
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/panfrost/pan_fragment.c
src/gallium/drivers/panfrost/pan_job.c
src/gallium/drivers/panfrost/pan_mfbd.c
src/gallium/drivers/panfrost/pan_resource.c
src/gallium/drivers/panfrost/pan_resource.h
src/gallium/drivers/panfrost/pan_sfbd.c
src/panfrost/lib/pan_blit.c
src/panfrost/lib/pan_texture.c
src/panfrost/lib/pan_texture.h

index 0cd5247..c7d558d 100644 (file)
@@ -1042,7 +1042,7 @@ panfrost_update_sampler_view(struct panfrost_sampler_view *view,
 {
         struct panfrost_resource *rsrc = pan_resource(view->base.texture);
         if (view->texture_bo != rsrc->bo->ptr.gpu ||
-            view->modifier != rsrc->modifier) {
+            view->modifier != rsrc->layout.modifier) {
                 panfrost_bo_unreference(view->bo);
                 panfrost_create_sampler_view_bo(view, pctx, &rsrc->base);
         }
index 04f048f..70dc76e 100644 (file)
@@ -1011,7 +1011,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
         }
 
         so->texture_bo = prsrc->bo->ptr.gpu;
-        so->modifier = prsrc->modifier;
+        so->modifier = prsrc->layout.modifier;
 
         unsigned char user_swizzle[4] = {
                 so->base.swizzle_r,
@@ -1048,7 +1048,8 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
                                                        so->base.u.tex.first_layer,
                                                        so->base.u.tex.last_layer,
                                                        texture->nr_samples,
-                                                       type, prsrc->modifier);
+                                                       type,
+                                                       prsrc->layout.modifier);
 
         so->bo = panfrost_bo_create(device, size, 0);
 
@@ -1060,20 +1061,17 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
                 payload.gpu += MALI_MIDGARD_TEXTURE_LENGTH;
         }
 
-        panfrost_new_texture(device, tex,
+        panfrost_new_texture(device, &prsrc->layout, tex,
                              texture->width0, texture->height0,
                              depth, array_size,
-                             format,
-                             type, prsrc->modifier,
+                             format, type,
                              so->base.u.tex.first_level,
                              so->base.u.tex.last_level,
                              so->base.u.tex.first_layer,
                              so->base.u.tex.last_layer,
                              texture->nr_samples,
-                             prsrc->cubemap_stride,
                              panfrost_translate_swizzle_4(user_swizzle),
-                             prsrc->bo->ptr.gpu,
-                             prsrc->slices, &payload);
+                             prsrc->bo->ptr.gpu, &payload);
 }
 
 static struct pipe_sampler_view *
index af97b18..0a6a026 100644 (file)
@@ -42,7 +42,7 @@ panfrost_initialize_surface(
         unsigned level = surf->u.tex.level;
         struct panfrost_resource *rsrc = pan_resource(surf->texture);
 
-        rsrc->slices[level].initialized = true;
+        rsrc->layout.slices[level].initialized = true;
 }
 
 /* Generate a fragment job. This should be called once per frame. (According to
index 3304c46..301ce45 100644 (file)
@@ -759,7 +759,7 @@ panfrost_load_surface(struct panfrost_batch *batch, struct pipe_surface *surf, u
         struct panfrost_resource *rsrc = pan_resource(surf->texture);
         unsigned level = surf->u.tex.level;
 
-        if (!rsrc->slices[level].initialized)
+        if (!rsrc->layout.slices[level].initialized)
                 return;
 
         if (!rsrc->damage.inverted_len)
@@ -808,16 +808,14 @@ panfrost_load_surface(struct panfrost_batch *batch, struct pipe_surface *surf, u
                 .depth0 = rsrc->base.depth0,
                 .format = format,
                 .dim = dim,
-                .modifier = rsrc->modifier,
                 .array_size = rsrc->base.array_size,
                 .first_level = level,
                 .last_level = level,
                 .first_layer = surf->u.tex.first_layer,
                 .last_layer = surf->u.tex.last_layer,
                 .nr_samples = rsrc->base.nr_samples,
-                .cubemap_stride = rsrc->cubemap_stride,
                 .bo = rsrc->bo,
-                .slices = rsrc->slices
+                .layout = &rsrc->layout,
         };
 
         mali_ptr blend_shader = 0;
index 5931025..83bd537 100644 (file)
@@ -134,12 +134,12 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
         unsigned level = surf->u.tex.level;
         unsigned first_layer = surf->u.tex.first_layer;
         assert(surf->u.tex.last_layer == first_layer);
-        int row_stride = rsrc->slices[level].row_stride;
+        int row_stride = rsrc->layout.slices[level].row_stride;
 
         /* Only set layer_stride for layered MSAA rendering  */
 
         unsigned nr_samples = surf->texture->nr_samples;
-        unsigned layer_stride = (nr_samples > 1) ? rsrc->slices[level].surface_stride : 0;
+        unsigned layer_stride = (nr_samples > 1) ? rsrc->layout.slices[level].surface_stride : 0;
         mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
 
         if (layer_stride)
@@ -151,7 +151,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
 
         panfrost_mfbd_rt_init_format(surf, rt);
 
-        if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) {
+        if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) {
                 if (version >= 7)
                         rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_LINEAR;
                 else
@@ -160,7 +160,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
                 rt->rgb.base = base;
                 rt->rgb.row_stride = row_stride;
                 rt->rgb.surface_stride = layer_stride;
-        } else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
+        } else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
                 if (version >= 7)
                         rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED;
                 else
@@ -169,13 +169,13 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
                 rt->rgb.base = base;
                 rt->rgb.row_stride = row_stride;
                 rt->rgb.surface_stride = layer_stride;
-        } else if (drm_is_afbc(rsrc->modifier)) {
+        } else if (drm_is_afbc(rsrc->layout.modifier)) {
                 if (version >= 7)
                         rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_AFBC;
                 else
                         rt->midgard.writeback_block_format = MALI_BLOCK_FORMAT_AFBC;
 
-                unsigned header_size = rsrc->slices[level].header_size;
+                unsigned header_size = rsrc->layout.slices[level].header_size;
 
                 rt->afbc.header = base;
                 rt->afbc.chunk_size = 9;
@@ -184,7 +184,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
                 if (!(dev->quirks & IS_BIFROST))
                         rt->midgard_afbc.sparse = true;
 
-                if (rsrc->modifier & AFBC_FORMAT_MOD_YTR)
+                if (rsrc->layout.modifier & AFBC_FORMAT_MOD_YTR)
                         rt->afbc.yuv_transform_enable = true;
 
                 /* TODO: The blob sets this to something nonzero, but it's not
@@ -254,7 +254,7 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
 
                 if (rsrc->checksummed) {
                         unsigned level = c_surf->u.tex.level;
-                        struct panfrost_slice *slice = &rsrc->slices[level];
+                        struct panfrost_slice *slice = &rsrc->layout.slices[level];
 
                         ext->crc_row_stride = slice->crc.stride;
                         if (rsrc->checksum_bo)
@@ -291,8 +291,8 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
         else
                 ext->zs_msaa_v7 = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE;
 
-        if (drm_is_afbc(rsrc->modifier)) {
-                unsigned header_size = rsrc->slices[level].header_size;
+        if (drm_is_afbc(rsrc->layout.modifier)) {
+                unsigned header_size = rsrc->layout.slices[level].header_size;
                 ext->zs_afbc_header = base;
                 ext->zs_afbc_body = base + header_size;
                 ext->zs_afbc_body_size = 0x1000;
@@ -304,19 +304,18 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
                 else
                         ext->zs_block_format = MALI_BLOCK_FORMAT_AFBC;
         } else {
-                assert(rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
-                       rsrc->modifier == DRM_FORMAT_MOD_LINEAR);
+                assert(rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
+                       rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR);
                 /* TODO: Z32F(S8) support, which is always linear */
 
-                int row_stride = rsrc->slices[level].row_stride;
-
-                unsigned layer_stride = (nr_samples > 1) ? rsrc->slices[level].surface_stride : 0;
-
                 ext->zs_writeback_base = base;
-                ext->zs_writeback_row_stride = row_stride;
-                ext->zs_writeback_surface_stride = layer_stride;
+                ext->zs_writeback_row_stride =
+                        rsrc->layout.slices[level].row_stride;
+                ext->zs_writeback_surface_stride =
+                        (nr_samples > 1) ?
+                        rsrc->layout.slices[level].surface_stride : 0;
 
-                if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) {
+                if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) {
                         if (version >= 7)
                                 ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_LINEAR;
                         else
@@ -358,12 +357,14 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
                 }
 
                 struct panfrost_resource *stencil = rsrc->separate_stencil;
-                struct panfrost_slice stencil_slice = stencil->slices[level];
-                unsigned stencil_layer_stride = (nr_samples > 1) ? stencil_slice.surface_stride : 0;
-
-                ext->s_writeback_base = panfrost_get_texture_address(stencil, level, first_layer, 0);
-                ext->s_writeback_row_stride = stencil_slice.row_stride;
-                ext->s_writeback_surface_stride = stencil_layer_stride;
+                struct panfrost_slice *stencil_slice =
+                       &stencil->layout.slices[level];
+
+                ext->s_writeback_base =
+                        panfrost_get_texture_address(stencil, level, first_layer, 0);
+                ext->s_writeback_row_stride = stencil_slice->row_stride;
+                ext->s_writeback_surface_stride =
+                        (nr_samples > 1) ? stencil_slice->surface_stride : 0;
                 break;
         default:
                 unreachable("Unsupported depth/stencil format.");
index b9a5fbf..be48365 100644 (file)
@@ -96,36 +96,39 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
 
         rsc->bo = panfrost_bo_import(dev, whandle->handle);
         rsc->internal_format = templat->format;
-        rsc->modifier = (whandle->modifier == DRM_FORMAT_MOD_INVALID) ?
-                DRM_FORMAT_MOD_LINEAR : whandle->modifier;
+        rsc->layout.modifier = (whandle->modifier == DRM_FORMAT_MOD_INVALID) ?
+                               DRM_FORMAT_MOD_LINEAR : whandle->modifier;
+        rsc->layout.dim = panfrost_translate_texture_dimension(templat->target);
         rsc->modifier_constant = true;
-        rsc->slices[0].line_stride = whandle->stride;
-        rsc->slices[0].row_stride = whandle->stride;
+        rsc->layout.slices[0].line_stride = whandle->stride;
+        rsc->layout.slices[0].row_stride = whandle->stride;
 
-        if (rsc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
-            drm_is_afbc(rsc->modifier)) {
-                unsigned tile_h = panfrost_block_dim(rsc->modifier, false, 0);
+        if (rsc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
+            drm_is_afbc(rsc->layout.modifier)) {
+                unsigned tile_h = panfrost_block_dim(rsc->layout.modifier, false, 0);
 
                 if (util_format_is_compressed(rsc->internal_format))
                         tile_h >>= 2;
 
-                rsc->slices[0].row_stride *= tile_h;
+                rsc->layout.slices[0].row_stride *= tile_h;
         }
 
-        rsc->slices[0].offset = whandle->offset;
-        rsc->slices[0].initialized = true;
+        rsc->layout.slices[0].offset = whandle->offset;
+        rsc->layout.slices[0].initialized = true;
         panfrost_resource_set_damage_region(NULL, &rsc->base, 0, NULL);
 
         if (dev->quirks & IS_BIFROST &&
             templat->bind & PIPE_BIND_RENDER_TARGET) {
-                unsigned size = panfrost_compute_checksum_size(
-                                        &rsc->slices[0], templat->width0, templat->height0);
+                unsigned size =
+                        panfrost_compute_checksum_size(&rsc->layout.slices[0],
+                                                       templat->width0,
+                                                       templat->height0);
                 rsc->checksum_bo = panfrost_bo_create(dev, size, 0);
                 rsc->checksummed = true;
         }
 
         if (drm_is_afbc(whandle->modifier)) {
-                rsc->slices[0].header_size =
+                rsc->layout.slices[0].header_size =
                         panfrost_afbc_header_size(templat->width0, templat->height0);
         }
 
@@ -149,7 +152,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
         struct panfrost_resource *rsrc = (struct panfrost_resource *) pt;
         struct renderonly_scanout *scanout = rsrc->scanout;
 
-        handle->modifier = rsrc->modifier;
+        handle->modifier = rsrc->layout.modifier;
         rsrc->modifier_constant = true;
 
         if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
@@ -159,8 +162,8 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
                         return true;
 
                 handle->handle = rsrc->bo->gem_handle;
-                handle->stride = rsrc->slices[0].line_stride;
-                handle->offset = rsrc->slices[0].offset;
+                handle->stride = rsrc->layout.slices[0].line_stride;
+                handle->offset = rsrc->layout.slices[0].offset;
                 return TRUE;
         } else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
                 if (scanout) {
@@ -184,8 +187,8 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
                                 return false;
 
                         handle->handle = fd;
-                        handle->stride = rsrc->slices[0].line_stride;
-                        handle->offset = rsrc->slices[0].offset;
+                        handle->stride = rsrc->layout.slices[0].line_stride;
+                        handle->offset = rsrc->layout.slices[0].offset;
                         return true;
                 }
         }
@@ -311,7 +314,7 @@ panfrost_create_scanout_res(struct pipe_screen *screen,
 /* Setup the mip tree given a particular modifier, possibly with checksumming */
 
 static void
-panfrost_setup_slices(struct panfrost_device *dev,
+panfrost_setup_layout(struct panfrost_device *dev,
                       struct panfrost_resource *pres,
                       size_t *bo_size)
 {
@@ -343,24 +346,23 @@ panfrost_setup_slices(struct panfrost_device *dev,
         bool renderable = res->bind &
                           (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL) &&
                           res->target != PIPE_BUFFER;
-        bool afbc = drm_is_afbc(pres->modifier);
-        bool tiled = pres->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED;
-        bool linear = pres->modifier == DRM_FORMAT_MOD_LINEAR;
+        bool afbc = drm_is_afbc(pres->layout.modifier);
+        bool tiled = pres->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED;
+        bool linear = pres->layout.modifier == DRM_FORMAT_MOD_LINEAR;
         bool should_align = renderable || tiled || afbc;
 
         unsigned offset = 0;
-        unsigned size_2d = 0;
         unsigned tile_h = 1, tile_w = 1, tile_shift = 0;
 
         if (tiled || afbc) {
-                tile_w = panfrost_block_dim(pres->modifier, true, 0);
-                tile_h = panfrost_block_dim(pres->modifier, false, 0);
+                tile_w = panfrost_block_dim(pres->layout.modifier, true, 0);
+                tile_h = panfrost_block_dim(pres->layout.modifier, false, 0);
                 if (util_format_is_compressed(pres->internal_format))
                         tile_shift = 2;
         }
 
         for (unsigned l = 0; l <= res->last_level; ++l) {
-                struct panfrost_slice *slice = &pres->slices[l];
+                struct panfrost_slice *slice = &pres->layout.slices[l];
 
                 unsigned effective_width = width;
                 unsigned effective_height = height;
@@ -399,11 +401,6 @@ panfrost_setup_slices(struct panfrost_device *dev,
 
                 slice->surface_stride = slice_one_size;
 
-                /* Report 2D size for 3D texturing */
-
-                if (l == 0)
-                        size_2d = slice_one_size;
-
                 /* Compute AFBC sizes if necessary */
                 if (afbc) {
                         slice->header_size =
@@ -431,20 +428,10 @@ panfrost_setup_slices(struct panfrost_device *dev,
 
         assert(res->array_size);
 
-        if (res->target != PIPE_TEXTURE_3D) {
-                /* Arrays and cubemaps have the entire miptree duplicated */
-
-                pres->cubemap_stride = ALIGN_POT(offset, 64);
-                if (bo_size)
-                        *bo_size = ALIGN_POT(pres->cubemap_stride * res->array_size, 4096);
-        } else {
-                /* 3D strides across the 2D layers */
-                assert(res->array_size == 1);
-
-                pres->cubemap_stride = size_2d;
-                if (bo_size)
-                        *bo_size = ALIGN_POT(offset, 4096);
-        }
+        /* Arrays and cubemaps have the entire miptree duplicated */
+        pres->layout.array_stride = ALIGN_POT(offset, 64);
+        if (bo_size)
+                *bo_size = ALIGN_POT(pres->layout.array_stride * res->array_size, 4096);
 }
 
 /* Based on the usage, determine if it makes sense to use u-inteleaved tiling.
@@ -550,16 +537,16 @@ static void
 panfrost_resource_setup(struct panfrost_device *dev, struct panfrost_resource *pres,
                         size_t *bo_size, uint64_t modifier)
 {
-        pres->modifier = (modifier != DRM_FORMAT_MOD_INVALID) ? modifier :
+        pres->layout.modifier = (modifier != DRM_FORMAT_MOD_INVALID) ? modifier :
                 panfrost_best_modifier(dev, pres);
         pres->checksummed = (pres->base.bind & PIPE_BIND_RENDER_TARGET);
 
         /* We can only switch tiled->linear if the resource isn't already
          * linear and if we control the modifier */
-        pres->modifier_constant = !((pres->modifier != DRM_FORMAT_MOD_LINEAR)
+        pres->modifier_constant = !((pres->layout.modifier != DRM_FORMAT_MOD_LINEAR)
                         && (modifier == DRM_FORMAT_MOD_INVALID));
 
-        panfrost_setup_slices(dev, pres, bo_size);
+        panfrost_setup_layout(dev, pres, bo_size);
 }
 
 void
@@ -639,6 +626,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
         so->base = *template;
         so->base.screen = screen;
         so->internal_format = template->format;
+        so->layout.dim = panfrost_translate_texture_dimension(template->target);
 
         pipe_reference_init(&so->base.reference, 1);
 
@@ -814,7 +802,7 @@ panfrost_ptr_map(struct pipe_context *pctx,
         struct panfrost_bo *bo = rsrc->bo;
 
         /* Can't map tiled/compressed directly */
-        if ((usage & PIPE_MAP_DIRECTLY) && rsrc->modifier != DRM_FORMAT_MOD_LINEAR)
+        if ((usage & PIPE_MAP_DIRECTLY) && rsrc->layout.modifier != DRM_FORMAT_MOD_LINEAR)
                 return NULL;
 
         struct panfrost_transfer *transfer = rzalloc(pctx, struct panfrost_transfer);
@@ -826,9 +814,9 @@ panfrost_ptr_map(struct pipe_context *pctx,
         *out_transfer = &transfer->base;
 
         /* We don't have s/w routines for AFBC, so use a staging texture */
-        if (drm_is_afbc(rsrc->modifier)) {
+        if (drm_is_afbc(rsrc->layout.modifier)) {
                 struct panfrost_resource *staging = pan_alloc_staging(ctx, rsrc, level, box);
-                transfer->base.stride = staging->slices[0].line_stride;
+                transfer->base.stride = staging->layout.slices[0].line_stride;
                 transfer->base.layer_stride = transfer->base.stride * box->height;
 
                 transfer->staging.rsrc = &staging->base;
@@ -845,7 +833,7 @@ panfrost_ptr_map(struct pipe_context *pctx,
                  * from a pending batch XXX */
                 panfrost_flush_batches_accessing_bo(ctx, rsrc->bo, true);
 
-                if ((usage & PIPE_MAP_READ) && rsrc->slices[level].initialized) {
+                if ((usage & PIPE_MAP_READ) && rsrc->layout.slices[level].initialized) {
                         pan_blit_to_staging(pctx, transfer);
                         panfrost_flush_batches_accessing_bo(ctx, staging->bo, true);
                         panfrost_bo_wait(staging->bo, INT64_MAX, false);
@@ -932,25 +920,25 @@ panfrost_ptr_map(struct pipe_context *pctx,
                 }
         }
 
-        if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
+        if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
                 transfer->base.stride = box->width * bytes_per_pixel;
                 transfer->base.layer_stride = transfer->base.stride * box->height;
                 transfer->map = ralloc_size(transfer, transfer->base.layer_stride * box->depth);
                 assert(box->depth == 1);
 
-                if ((usage & PIPE_MAP_READ) && rsrc->slices[level].initialized) {
+                if ((usage & PIPE_MAP_READ) && rsrc->layout.slices[level].initialized) {
                         panfrost_load_tiled_image(
                                         transfer->map,
-                                        bo->ptr.cpu + rsrc->slices[level].offset,
+                                        bo->ptr.cpu + rsrc->layout.slices[level].offset,
                                         box->x, box->y, box->width, box->height,
                                         transfer->base.stride,
-                                        rsrc->slices[level].line_stride,
+                                        rsrc->layout.slices[level].line_stride,
                                         rsrc->internal_format);
                 }
 
                 return transfer->map;
         } else {
-                assert (rsrc->modifier == DRM_FORMAT_MOD_LINEAR);
+                assert (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR);
 
                 /* Direct, persistent writes create holes in time for
                  * caching... I don't know if this is actually possible but we
@@ -961,23 +949,22 @@ panfrost_ptr_map(struct pipe_context *pctx,
                 if ((usage & dpw) == dpw && rsrc->index_cache)
                         return NULL;
 
-                transfer->base.stride = rsrc->slices[level].line_stride;
-                transfer->base.layer_stride = panfrost_get_layer_stride(
-                                rsrc->slices, rsrc->base.target == PIPE_TEXTURE_3D,
-                                rsrc->cubemap_stride, level);
+                transfer->base.stride = rsrc->layout.slices[level].line_stride;
+                transfer->base.layer_stride =
+                        panfrost_get_layer_stride(&rsrc->layout, level);
 
                 /* By mapping direct-write, we're implicitly already
                  * initialized (maybe), so be conservative */
 
                 if (usage & PIPE_MAP_WRITE) {
-                        rsrc->slices[level].initialized = true;
+                        rsrc->layout.slices[level].initialized = true;
                         panfrost_minmax_cache_invalidate(rsrc->index_cache, &transfer->base);
                 }
 
                 return bo->ptr.cpu
-                       + rsrc->slices[level].offset
+                       + rsrc->layout.slices[level].offset
                        + transfer->base.box.z * transfer->base.layer_stride
-                       + transfer->base.box.y * rsrc->slices[level].line_stride
+                       + transfer->base.box.y * rsrc->layout.slices[level].line_stride
                        + transfer->base.box.x * bytes_per_pixel;
         }
 }
@@ -1050,9 +1037,9 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
                 struct panfrost_bo *bo = prsrc->bo;
 
                 if (transfer->usage & PIPE_MAP_WRITE) {
-                        prsrc->slices[transfer->level].initialized = true;
+                        prsrc->layout.slices[transfer->level].initialized = true;
 
-                        if (prsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
+                        if (prsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
                                 assert(transfer->box.depth == 1);
 
                                 if (panfrost_should_linear_convert(prsrc, transfer)) {
@@ -1066,9 +1053,9 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
                                         }
 
                                         util_copy_rect(
-                                                bo->ptr.cpu + prsrc->slices[0].offset,
+                                                bo->ptr.cpu + prsrc->layout.slices[0].offset,
                                                 prsrc->base.format,
-                                                prsrc->slices[0].line_stride,
+                                                prsrc->layout.slices[0].line_stride,
                                                 0, 0,
                                                 transfer->box.width,
                                                 transfer->box.height,
@@ -1077,11 +1064,11 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
                                                 0, 0);
                                 } else {
                                         panfrost_store_tiled_image(
-                                                bo->ptr.cpu + prsrc->slices[transfer->level].offset,
+                                                bo->ptr.cpu + prsrc->layout.slices[transfer->level].offset,
                                                 trans->map,
                                                 transfer->box.x, transfer->box.y,
                                                 transfer->box.width, transfer->box.height,
-                                                prsrc->slices[transfer->level].line_stride,
+                                                prsrc->layout.slices[transfer->level].line_stride,
                                                 transfer->stride,
                                                 prsrc->internal_format);
                                 }
@@ -1116,7 +1103,7 @@ panfrost_ptr_flush_region(struct pipe_context *pctx,
                                transfer->box.x + box->x + box->width);
         } else {
                 unsigned level = transfer->level;
-                rsc->slices[level].initialized = true;
+                rsc->layout.slices[level].initialized = true;
         }
 }
 
@@ -1151,7 +1138,7 @@ panfrost_generate_mipmap(
 
         assert(rsrc->bo);
         for (unsigned l = base_level + 1; l <= last_level; ++l)
-                rsrc->slices[l].initialized = false;
+                rsrc->layout.slices[l].initialized = false;
 
         /* Beyond that, we just delegate the hard stuff. */
 
@@ -1167,15 +1154,16 @@ panfrost_generate_mipmap(
 /* Computes the address to a texture at a particular slice */
 
 mali_ptr
-panfrost_get_texture_address(
-        struct panfrost_resource *rsrc,
-        unsigned level, unsigned face, unsigned sample)
+panfrost_get_texture_address(struct panfrost_resource *rsrc,
+                             unsigned level, unsigned layer,
+                             unsigned sample)
 {
         bool is_3d = rsrc->base.target == PIPE_TEXTURE_3D;
+        unsigned array_idx = is_3d ? 0 : layer;
+        unsigned surface_idx = is_3d ? layer : sample;
         return rsrc->bo->ptr.gpu +
-               panfrost_texture_offset(rsrc->slices, is_3d,
-                                       rsrc->cubemap_stride,
-                                       level, face, sample);
+               panfrost_texture_offset(&rsrc->layout, level,
+                                       array_idx, surface_idx);
 }
 
 static void
index 183af68..6a8104d 100644 (file)
@@ -52,14 +52,8 @@ struct panfrost_resource {
 
         struct util_range valid_buffer_range;
 
-        /* Description of the mip levels */
-        struct panfrost_slice slices[MAX_MIP_LEVELS];
-
-        /* Distance from tree to tree */
-        unsigned cubemap_stride;
-
-        /* DRM fourcc code: linear, 16x16 u-interleaved, AFBC */
-        uint64_t modifier;
+        /* Description of the resource layout */
+        struct pan_image_layout layout;
 
         /* Whether the modifier can be changed */
         bool modifier_constant;
@@ -101,9 +95,9 @@ pan_transfer(struct pipe_transfer *p)
 }
 
 mali_ptr
-panfrost_get_texture_address(
-        struct panfrost_resource *rsrc,
-        unsigned level, unsigned face, unsigned sample);
+panfrost_get_texture_address(struct panfrost_resource *rsrc,
+                             unsigned level, unsigned layer,
+                             unsigned sample);
 
 void panfrost_resource_screen_init(struct pipe_screen *screen);
 
index 3fcaf3c..3d378f3 100644 (file)
@@ -84,7 +84,7 @@ panfrost_sfbd_set_cbuf(
         unsigned level = surf->u.tex.level;
         unsigned first_layer = surf->u.tex.first_layer;
         assert(surf->u.tex.last_layer == first_layer);
-        signed row_stride = rsrc->slices[level].row_stride;
+        signed row_stride = rsrc->layout.slices[level].row_stride;
 
         mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
 
@@ -94,9 +94,9 @@ panfrost_sfbd_set_cbuf(
         fb->color_writeback.base = base;
         fb->color_writeback.row_stride = row_stride;
 
-        if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR)
+        if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR)
                 fb->color_block_format = MALI_BLOCK_FORMAT_LINEAR;
-        else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
+        else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
                 fb->color_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
         } else {
                 fprintf(stderr, "Invalid render modifier\n");
@@ -114,12 +114,12 @@ panfrost_sfbd_set_zsbuf(
         unsigned level = surf->u.tex.level;
         assert(surf->u.tex.first_layer == 0);
 
-        fb->zs_writeback.base = rsrc->bo->ptr.gpu + rsrc->slices[level].offset;
-        fb->zs_writeback.row_stride = rsrc->slices[level].row_stride;
+        fb->zs_writeback.base = rsrc->bo->ptr.gpu + rsrc->layout.slices[level].offset;
+        fb->zs_writeback.row_stride = rsrc->layout.slices[level].row_stride;
 
-        if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR)
+        if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR)
                 fb->zs_block_format = MALI_BLOCK_FORMAT_LINEAR;
-        else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
+        else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
                 fb->zs_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
         } else {
                 fprintf(stderr, "Invalid render modifier\n");
@@ -230,7 +230,7 @@ panfrost_sfbd_fragment(struct panfrost_batch *batch, bool has_draws)
 
                         if (rsrc->checksummed) {
                                 unsigned level = surf->u.tex.level;
-                                struct panfrost_slice *slice = &rsrc->slices[level];
+                                struct panfrost_slice *slice = &rsrc->layout.slices[level];
 
                                 params.crc_buffer.row_stride = slice->crc.stride;
                                 params.crc_buffer.base = bo->ptr.gpu + slice->crc.offset;
index e796d95..e3c7c2b 100644 (file)
@@ -316,21 +316,20 @@ midgard_load_emit_texture(struct pan_pool *pool, struct MALI_DRAW *draw,
          * itself is for a 2D texture with array size 1 even for 3D/array
          * textures, removing the need to separately key the blit shaders for
          * 2D and 3D variants */
-         panfrost_new_texture(pool->dev, texture.cpu,
-                              image->width0, image->height0,
-                              MAX2(image->nr_samples, 1), 1,
-                              image->format, MALI_TEXTURE_DIMENSION_2D,
-                              image->modifier,
-                              image->first_level, image->last_level,
-                              0, 0,
-                              image->nr_samples,
-                              0,
-                              PAN_V6_SWIZZLE(R, G, B, A),
-                              image->bo->ptr.gpu + image->first_layer *
-                              panfrost_get_layer_stride(image->slices,
-                                                        image->dim == MALI_TEXTURE_DIMENSION_3D,
-                                                        image->cubemap_stride, image->first_level),
-                              image->slices, &payload);
+
+        unsigned offset =
+                image->first_layer *
+                panfrost_get_layer_stride(image->layout, image->first_level);
+
+        panfrost_new_texture(pool->dev, image->layout, texture.cpu,
+                             image->width0, image->height0,
+                             MAX2(image->nr_samples, 1), 1,
+                             image->format, MALI_TEXTURE_DIMENSION_2D,
+                             image->first_level, image->last_level,
+                             0, 0,
+                             image->nr_samples,
+                             PAN_V6_SWIZZLE(R, G, B, A),
+                             image->bo->ptr.gpu + offset, &payload);
 
         pan_pack(sampler.cpu, MIDGARD_SAMPLER, cfg)
                 cfg.normalized_coordinates = false;
@@ -492,21 +491,19 @@ bifrost_load_emit_texture(struct pan_pool *pool, struct MALI_DRAW *draw,
                  .gpu = texture.gpu + MALI_BIFROST_TEXTURE_LENGTH,
         };
 
-        panfrost_new_texture(pool->dev, (void *)texture.cpu,
+        unsigned offset =
+                image->first_layer *
+                panfrost_get_layer_stride(image->layout, image->first_level);
+
+        panfrost_new_texture(pool->dev, image->layout, texture.cpu,
                              image->width0, image->height0,
                              MAX2(image->nr_samples, 1), 1,
                              image->format, MALI_TEXTURE_DIMENSION_2D,
-                             image->modifier,
                              image->first_level, image->last_level,
                              0, 0,
                              image->nr_samples,
-                             0,
                              PAN_V6_SWIZZLE(R, G, B, A),
-                             image->bo->ptr.gpu + image->first_layer *
-                             panfrost_get_layer_stride(image->slices,
-                                                       image->dim == MALI_TEXTURE_DIMENSION_3D,
-                                                       image->cubemap_stride, image->first_level),
-                             image->slices, &payload);
+                             image->bo->ptr.gpu + offset, &payload);
 
         pan_pack(sampler.cpu, BIFROST_SAMPLER, cfg) {
                 cfg.seamless_cube_map = false;
index be487f2..3e39050 100644 (file)
@@ -79,9 +79,8 @@ panfrost_modifier_to_layout(uint64_t modifier)
 
 static bool
 panfrost_needs_explicit_stride(const struct panfrost_device *dev,
-                               uint64_t modifier,
+                               const struct pan_image_layout *layout,
                                enum pipe_format format,
-                               struct panfrost_slice *slices,
                                uint16_t width,
                                unsigned first_level,
                                unsigned last_level)
@@ -90,14 +89,14 @@ panfrost_needs_explicit_stride(const struct panfrost_device *dev,
         if (dev->quirks & IS_BIFROST)
                 return true;
 
-        if (modifier != DRM_FORMAT_MOD_LINEAR)
+        if (layout->modifier != DRM_FORMAT_MOD_LINEAR)
                 return false;
 
         unsigned bytes_per_block = util_format_get_blocksize(format);
         unsigned block_w = util_format_get_blockwidth(format);
 
         for (unsigned l = first_level; l <= last_level; ++l) {
-                unsigned actual = slices[l].line_stride;
+                unsigned actual = layout->slices[l].line_stride;
                 unsigned expected =
                         DIV_ROUND_UP(u_minify(width, l), block_w) *
                         bytes_per_block;
@@ -269,34 +268,22 @@ panfrost_block_dim(uint64_t modifier, bool width, unsigned plane)
 }
 
 static uint64_t
-panfrost_get_surface_strides(struct panfrost_slice *slices,
-                             const struct util_format_description *desc,
-                             enum mali_texture_dimension dim,
-                             uint64_t modifier,
-                             unsigned width, unsigned height,
-                             unsigned l, unsigned cube_stride)
+panfrost_get_surface_strides(const struct pan_image_layout *layout,
+                             unsigned l)
 {
-        bool is_3d = dim == MALI_TEXTURE_DIMENSION_3D;
-
-        unsigned line_stride = slices[l].row_stride;
-        unsigned layer_stride =
-                panfrost_get_layer_stride(slices, is_3d, cube_stride, l);
-
-        return ((uint64_t)layer_stride << 32) | line_stride;
+        return ((uint64_t)layout->slices[l].surface_stride << 32) |
+               layout->slices[l].row_stride;
 }
 
 static mali_ptr
-panfrost_get_surface_pointer(mali_ptr base, struct panfrost_slice *slices,
+panfrost_get_surface_pointer(const struct pan_image_layout *layout,
                              enum mali_texture_dimension dim,
-                             unsigned l, unsigned w, unsigned f, unsigned s,
-                             unsigned cube_stride)
+                             mali_ptr base,
+                             unsigned l, unsigned w, unsigned f, unsigned s)
 {
         unsigned face_mult = dim == MALI_TEXTURE_DIMENSION_CUBE ? 6 : 1;
-        bool is_3d = dim == MALI_TEXTURE_DIMENSION_3D;
 
-        return base +
-               panfrost_texture_offset(slices, is_3d, cube_stride,
-                                       l, w * face_mult + f, s);
+        return base + panfrost_texture_offset(layout, l, w * face_mult + f, s);
 }
 
 struct panfrost_surface_iter {
@@ -357,28 +344,27 @@ panfrost_surface_iter_next(const struct panfrost_device *dev,
 
 static void
 panfrost_emit_texture_payload(const struct panfrost_device *dev,
+                              const struct pan_image_layout *layout,
                               mali_ptr *payload,
                               const struct util_format_description *desc,
                               enum mali_texture_dimension dim,
-                              uint64_t modifier,
-                              unsigned width, unsigned height,
                               unsigned first_level, unsigned last_level,
                               unsigned first_layer, unsigned last_layer,
                               unsigned nr_samples,
-                              unsigned cube_stride,
                               bool manual_stride,
-                              mali_ptr base,
-                              struct panfrost_slice *slices)
+                              mali_ptr base)
 {
-        base |= panfrost_compression_tag(dev, desc, dim, modifier);
+        base |= panfrost_compression_tag(dev, desc, dim, layout->modifier);
 
         /* Inject the addresses in, interleaving array indices, mip levels,
          * cube faces, and strides in that order */
 
         unsigned first_face  = 0, last_face = 0;
 
-        if (dim == MALI_TEXTURE_DIMENSION_CUBE)
-                panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer);
+        if (dim == MALI_TEXTURE_DIMENSION_CUBE) {
+                panfrost_adjust_cube_dimensions(&first_face, &last_face,
+                                                &first_layer, &last_layer);
+        }
 
         nr_samples = MAX2(nr_samples, 1);
 
@@ -391,36 +377,31 @@ panfrost_emit_texture_payload(const struct panfrost_device *dev,
              !panfrost_surface_iter_end(&iter);
              panfrost_surface_iter_next(dev, &iter)) {
                 payload[idx++] =
-                        panfrost_get_surface_pointer(base, slices, dim,
+                        panfrost_get_surface_pointer(layout, dim, base,
                                                      iter.level, iter.layer,
-                                                     iter.face, iter.sample,
-                                                     cube_stride);
+                                                     iter.face, iter.sample);
 
                 if (!manual_stride)
                         continue;
 
                 payload[idx++] =
-                        panfrost_get_surface_strides(slices, desc, dim,
-                                                     modifier, width, height,
-                                                     iter.level, cube_stride);
+                        panfrost_get_surface_strides(layout, iter.level);
         }
 }
 
 void
 panfrost_new_texture(const struct panfrost_device *dev,
+                     const struct pan_image_layout *layout,
                      void *out,
                      uint16_t width, uint16_t height,
                      uint16_t depth, uint16_t array_size,
                      enum pipe_format format,
                      enum mali_texture_dimension dim,
-                     uint64_t modifier,
                      unsigned first_level, unsigned last_level,
                      unsigned first_layer, unsigned last_layer,
                      unsigned nr_samples,
-                     unsigned cube_stride,
                      unsigned swizzle,
                      mali_ptr base,
-                     struct panfrost_slice *slices,
                      const struct panfrost_ptr *payload)
 {
         const struct util_format_description *desc =
@@ -428,22 +409,17 @@ panfrost_new_texture(const struct panfrost_device *dev,
 
         bool is_bifrost = dev->quirks & IS_BIFROST;
         bool manual_stride =
-                panfrost_needs_explicit_stride(dev, modifier, format, slices,
-                                               width, first_level, last_level);
+                panfrost_needs_explicit_stride(dev, layout, format, width,
+                                               first_level, last_level);
 
-        panfrost_emit_texture_payload(dev,
+        panfrost_emit_texture_payload(dev, layout,
                                       payload->cpu,
-                                      desc,
-                                      dim,
-                                      modifier,
-                                      width, height,
+                                      desc, dim,
                                       first_level, last_level,
                                       first_layer, last_layer,
                                       nr_samples,
-                                      cube_stride,
                                       manual_stride,
-                                      base,
-                                      slices);
+                                      base);
 
         if (is_bifrost) {
                 pan_pack(out, BIFROST_TEXTURE, cfg) {
@@ -456,7 +432,8 @@ panfrost_new_texture(const struct panfrost_device *dev,
                         else
                                 cfg.sample_count = MAX2(nr_samples, 1);
                         cfg.swizzle = swizzle;
-                        cfg.texel_ordering = panfrost_modifier_to_layout(modifier);
+                        cfg.texel_ordering =
+                                panfrost_modifier_to_layout(layout->modifier);
                         cfg.levels = last_level - first_level + 1;
                         cfg.array_size = array_size;
                         cfg.surfaces = payload->gpu;
@@ -477,7 +454,8 @@ panfrost_new_texture(const struct panfrost_device *dev,
                         cfg.array_size = array_size;
                         cfg.format = panfrost_pipe_format_v6[format].hw;
                         cfg.dimension = dim;
-                        cfg.texel_ordering = panfrost_modifier_to_layout(modifier);
+                        cfg.texel_ordering =
+                                panfrost_modifier_to_layout(layout->modifier);
                         cfg.manual_stride = manual_stride;
                         cfg.levels = last_level - first_level + 1;
                         cfg.swizzle = swizzle;
@@ -511,17 +489,24 @@ panfrost_compute_checksum_size(
 }
 
 unsigned
-panfrost_get_layer_stride(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level)
+panfrost_get_layer_stride(const struct pan_image_layout *layout,
+                          unsigned level)
 {
-        return is_3d ? slices[level].surface_stride : cube_stride;
+        if (layout->dim == MALI_TEXTURE_DIMENSION_3D)
+                return layout->slices[level].surface_stride;
+
+        return layout->array_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(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level, unsigned face, unsigned sample)
+panfrost_texture_offset(const struct pan_image_layout *layout,
+                        unsigned level, unsigned array_idx,
+                        unsigned surface_idx)
 {
-        unsigned layer_stride = panfrost_get_layer_stride(slices, is_3d, cube_stride, level);
-        return slices[level].offset + (face * layer_stride) + (sample * slices[level].surface_stride);
+        return layout->slices[level].offset +
+               (array_idx * layout->array_stride) +
+               (surface_idx * layout->slices[level].surface_stride);
 }
index 9507e23..7def961 100644 (file)
@@ -59,6 +59,13 @@ struct panfrost_slice {
         bool initialized;
 };
 
+struct pan_image_layout {
+        uint64_t modifier;
+        enum mali_texture_dimension dim;
+        struct panfrost_slice slices[MAX_MIP_LEVELS];
+        unsigned array_stride;
+};
+
 struct pan_image {
         /* Format and size */
         uint16_t width0, height0, depth0, array_size;
@@ -68,9 +75,7 @@ struct pan_image {
         unsigned first_layer, last_layer;
         unsigned nr_samples;
         struct panfrost_bo *bo;
-        struct panfrost_slice *slices;
-        unsigned cubemap_stride;
-        uint64_t modifier;
+        const struct pan_image_layout *layout;
 };
 
 unsigned
@@ -102,26 +107,27 @@ panfrost_estimate_texture_payload_size(
 
 void
 panfrost_new_texture(const struct panfrost_device *dev,
+                     const struct pan_image_layout *layout,
                      void *out,
                      uint16_t width, uint16_t height,
                      uint16_t depth, uint16_t array_size,
                      enum pipe_format format,
                      enum mali_texture_dimension dim,
-                     uint64_t modifier,
                      unsigned first_level, unsigned last_level,
                      unsigned first_layer, unsigned last_layer,
                      unsigned nr_samples,
-                     unsigned cube_stride,
                      unsigned swizzle,
                      mali_ptr base,
-                     struct panfrost_slice *slices,
                      const struct panfrost_ptr *payload);
 
 unsigned
-panfrost_get_layer_stride(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level);
+panfrost_get_layer_stride(const struct pan_image_layout *layout,
+                          unsigned level);
 
 unsigned
-panfrost_texture_offset(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level, unsigned face, unsigned sample);
+panfrost_texture_offset(const struct pan_image_layout *layout,
+                        unsigned level, unsigned array_idx,
+                        unsigned surface_idx);
 
 /* Formats */