Mesa (master): freedreno: add screen->setup_slices() for tex layout

Rob Clark robclark at kemper.freedesktop.org
Sun Jan 14 21:15:29 UTC 2018


Module: Mesa
Branch: master
Commit: 16b91c2254b1287b135ee363f9f669c5595ebdaf
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=16b91c2254b1287b135ee363f9f669c5595ebdaf

Author: Rob Clark <robdclark at gmail.com>
Date:   Sun Jan 14 08:57:29 2018 -0500

freedreno: add screen->setup_slices() for tex layout

The rules are sufficiently different for a5xx with tiled textures, so
split this out into something that can be implemented per-generation.
The a5xx specific implementation will come in a later patch.

Signed-off-by: Rob Clark <robdclark at gmail.com>

---

 src/gallium/drivers/freedreno/freedreno_resource.c | 59 +++++++++++++++-------
 src/gallium/drivers/freedreno/freedreno_resource.h |  1 +
 src/gallium/drivers/freedreno/freedreno_screen.h   |  2 +
 3 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index daa162c166..eaaf2e8b22 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -656,12 +656,12 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format forma
 }
 
 static uint32_t
-slice_alignment(struct pipe_screen *pscreen, const struct pipe_resource *tmpl)
+slice_alignment(enum pipe_texture_target target)
 {
 	/* on a3xx, 2d array and 3d textures seem to want their
 	 * layers aligned to page boundaries:
 	 */
-	switch (tmpl->target) {
+	switch (target) {
 	case PIPE_TEXTURE_3D:
 	case PIPE_TEXTURE_1D_ARRAY:
 	case PIPE_TEXTURE_2D_ARRAY:
@@ -671,6 +671,36 @@ slice_alignment(struct pipe_screen *pscreen, const struct pipe_resource *tmpl)
 	}
 }
 
+/* cross generation texture layout to plug in to screen->setup_slices()..
+ * replace with generation specific one as-needed.
+ *
+ * TODO for a4xx probably can extract out the a4xx specific logic int
+ * a small fd4_setup_slices() wrapper that sets up layer_first, and then
+ * calls this.
+ */
+uint32_t
+fd_setup_slices(struct fd_resource *rsc)
+{
+	uint32_t alignment;
+
+	alignment = slice_alignment(rsc->base.target);
+
+	struct fd_screen *screen = fd_screen(rsc->base.screen);
+	if (is_a4xx(screen) || is_a5xx(screen)) {
+		switch (rsc->base.target) {
+		case PIPE_TEXTURE_3D:
+			rsc->layer_first = false;
+			break;
+		default:
+			rsc->layer_first = true;
+			alignment = 1;
+			break;
+		}
+	}
+
+	return setup_slices(rsc, alignment, rsc->base.format);
+}
+
 /* special case to resize query buf after allocated.. */
 void
 fd_resource_resize(struct pipe_resource *prsc, uint32_t sz)
@@ -682,7 +712,7 @@ fd_resource_resize(struct pipe_resource *prsc, uint32_t sz)
 	debug_assert(prsc->bind == PIPE_BIND_QUERY_BUFFER);
 
 	prsc->width0 = sz;
-	realloc_bo(rsc, setup_slices(rsc, 1, prsc->format));
+	realloc_bo(rsc, fd_screen(prsc->screen)->setup_slices(rsc));
 }
 
 // TODO common helper?
@@ -715,7 +745,7 @@ fd_resource_create(struct pipe_screen *pscreen,
 	struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
 	struct pipe_resource *prsc = &rsc->base;
 	enum pipe_format format = tmpl->format;
-	uint32_t size, alignment;
+	uint32_t size;
 
 	DBG("%p: target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
 			"nr_samples=%u, usage=%u, bind=%x, flags=%x", prsc,
@@ -756,20 +786,7 @@ fd_resource_create(struct pipe_screen *pscreen,
 		rsc->lrz = fd_bo_new(screen->dev, size, flags);
 	}
 
-	alignment = slice_alignment(pscreen, tmpl);
-	if (is_a4xx(screen) || is_a5xx(screen)) {
-		switch (tmpl->target) {
-		case PIPE_TEXTURE_3D:
-			rsc->layer_first = false;
-			break;
-		default:
-			rsc->layer_first = true;
-			alignment = 1;
-			break;
-		}
-	}
-
-	size = setup_slices(rsc, alignment, format);
+	size = screen->setup_slices(rsc);
 
 	/* special case for hw-query buffer, which we need to allocate before we
 	 * know the size:
@@ -1091,7 +1108,8 @@ static const struct u_transfer_vtbl transfer_vtbl = {
 void
 fd_resource_screen_init(struct pipe_screen *pscreen)
 {
-	bool fake_rgtc = fd_screen(pscreen)->gpu_id < 400;
+	struct fd_screen *screen = fd_screen(pscreen);
+	bool fake_rgtc = screen->gpu_id < 400;
 
 	pscreen->resource_create = u_transfer_helper_resource_create;
 	pscreen->resource_from_handle = fd_resource_from_handle;
@@ -1100,6 +1118,9 @@ fd_resource_screen_init(struct pipe_screen *pscreen)
 
 	pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl,
 			true, fake_rgtc, true);
+
+	if (!screen->setup_slices)
+		screen->setup_slices = fd_setup_slices;
 }
 
 void
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 5132c58a0d..0b41a13be3 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -171,6 +171,7 @@ void fd_blitter_pipe_end(struct fd_context *ctx);
 void fd_resource_screen_init(struct pipe_screen *pscreen);
 void fd_resource_context_init(struct pipe_context *pctx);
 
+uint32_t fd_setup_slices(struct fd_resource *rsc);
 void fd_resource_resize(struct pipe_resource *prsc, uint32_t sz);
 
 bool fd_render_condition_check(struct pipe_context *pctx);
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h
index d5e497d4f6..5a825763f2 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.h
+++ b/src/gallium/drivers/freedreno/freedreno_screen.h
@@ -80,6 +80,8 @@ struct fd_screen {
 	 */
 	struct fd_pipe *pipe;
 
+	uint32_t (*setup_slices)(struct fd_resource *rsc);
+
 	int64_t cpu_gpu_time_delta;
 
 	struct fd_batch_cache batch_cache;




More information about the mesa-commit mailing list