Mesa (main): panfrost: Implement tiled 3D resource access
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Sat Apr 16 14:13:59 UTC 2022
Module: Mesa
Branch: main
Commit: cd2aa776cfc2e07cb20e4e4942c3776576f7d781
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=cd2aa776cfc2e07cb20e4e4942c3776576f7d781
Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date: Thu Apr 7 14:48:05 2022 -0400
panfrost: Implement tiled 3D resource access
We need to access each layer separately. This is a simple generalization of the
existing tiled 2D resource access code.
Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15803>
---
src/gallium/drivers/panfrost/pan_resource.c | 84 +++++++++++++++++++++--------
1 file changed, 63 insertions(+), 21 deletions(-)
diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index 8d23bf74a87..dde07e6c3bd 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -828,6 +828,65 @@ pan_blit_to_staging(struct pipe_context *pctx, struct panfrost_transfer *trans)
panfrost_blit(pctx, &blit);
}
+static void
+panfrost_load_tiled_images(struct panfrost_transfer *transfer,
+ struct panfrost_resource *rsrc)
+{
+ struct pipe_transfer *ptrans = &transfer->base;
+ unsigned level = ptrans->level;
+
+ /* If the requested level of the image is uninitialized, it's not
+ * necessary to copy it. Leave the result unintiialized too.
+ */
+ if (!BITSET_TEST(rsrc->valid.data, level))
+ return;
+
+ struct panfrost_bo *bo = rsrc->image.data.bo;
+ unsigned stride = panfrost_get_layer_stride(&rsrc->image.layout, level);
+
+ /* Otherwise, load each layer separately, required to load from 3D and
+ * array textures.
+ */
+ for (unsigned z = 0; z < ptrans->box.depth; ++z) {
+ void *dst = transfer->map + (ptrans->layer_stride * z);
+ uint8_t *map = bo->ptr.cpu +
+ rsrc->image.layout.slices[level].offset +
+ (z + ptrans->box.z) * stride;
+
+ panfrost_load_tiled_image(dst, map, ptrans->box.x,
+ ptrans->box.y, ptrans->box.width,
+ ptrans->box.height, ptrans->stride,
+ rsrc->image.layout.slices[level].line_stride,
+ rsrc->image.layout.format);
+ }
+}
+
+static void
+panfrost_store_tiled_images(struct panfrost_transfer *transfer,
+ struct panfrost_resource *rsrc)
+{
+ struct panfrost_bo *bo = rsrc->image.data.bo;
+ struct pipe_transfer *ptrans = &transfer->base;
+ unsigned level = ptrans->level;
+ unsigned stride = panfrost_get_layer_stride(&rsrc->image.layout, level);
+
+ /* Otherwise, store each layer separately, required to store to 3D and
+ * array textures.
+ */
+ for (unsigned z = 0; z < ptrans->box.depth; ++z) {
+ void *src = transfer->map + (ptrans->layer_stride * z);
+ uint8_t *map = bo->ptr.cpu +
+ rsrc->image.layout.slices[level].offset +
+ (z + ptrans->box.z) * stride;
+
+ panfrost_store_tiled_image(map, src,
+ ptrans->box.x, ptrans->box.y,
+ ptrans->box.width, ptrans->box.height,
+ rsrc->image.layout.slices[level].line_stride,
+ ptrans->stride, rsrc->image.layout.format);
+ }
+}
+
static void *
panfrost_ptr_map(struct pipe_context *pctx,
struct pipe_resource *resource,
@@ -992,17 +1051,9 @@ panfrost_ptr_map(struct pipe_context *pctx,
transfer->base.stride = box_blocks.width * bytes_per_block;
transfer->base.layer_stride = transfer->base.stride * box_blocks.height;
transfer->map = ralloc_size(transfer, transfer->base.layer_stride * box->depth);
- assert(box->depth == 1);
-
- if ((usage & PIPE_MAP_READ) && BITSET_TEST(rsrc->valid.data, level)) {
- panfrost_load_tiled_image(
- transfer->map,
- bo->ptr.cpu + rsrc->image.layout.slices[level].offset,
- box->x, box->y, box->width, box->height,
- transfer->base.stride,
- rsrc->image.layout.slices[level].line_stride,
- rsrc->image.layout.format);
- }
+
+ if (usage & PIPE_MAP_READ)
+ panfrost_load_tiled_images(transfer, rsrc);
return transfer->map;
} else {
@@ -1199,8 +1250,6 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
BITSET_SET(prsrc->valid.data, transfer->level);
if (prsrc->image.layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
- assert(transfer->box.depth == 1);
-
if (panfrost_should_linear_convert(dev, prsrc, transfer)) {
panfrost_resource_setup(dev, prsrc, DRM_FORMAT_MOD_LINEAR,
prsrc->image.layout.format);
@@ -1223,14 +1272,7 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
transfer->stride,
0, 0);
} else {
- panfrost_store_tiled_image(
- bo->ptr.cpu + prsrc->image.layout.slices[transfer->level].offset,
- trans->map,
- transfer->box.x, transfer->box.y,
- transfer->box.width, transfer->box.height,
- prsrc->image.layout.slices[transfer->level].line_stride,
- transfer->stride,
- prsrc->image.layout.format);
+ panfrost_store_tiled_images(trans, prsrc);
}
}
}
More information about the mesa-commit
mailing list