Mesa (master): freedreno: pitch alignment should match gmem alignment

Rob Clark robclark at kemper.freedesktop.org
Tue Dec 6 23:03:29 UTC 2016


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

Author: Rob Clark <robdclark at gmail.com>
Date:   Sat Dec  3 12:34:10 2016 -0500

freedreno: pitch alignment should match gmem alignment

Deal w/ differing gmem tile size alignment between generations, and make
sure texture pitch matches.

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

---

 src/gallium/drivers/freedreno/a5xx/fd5_gmem.c      |  1 +
 src/gallium/drivers/freedreno/freedreno_gmem.c     | 17 +++++++++--------
 src/gallium/drivers/freedreno/freedreno_resource.c | 11 +++++++----
 src/gallium/drivers/freedreno/freedreno_screen.c   |  6 ++++--
 src/gallium/drivers/freedreno/freedreno_screen.h   |  2 +-
 5 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
index d37c9d4..f505733 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
@@ -104,6 +104,7 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
 			OUT_RING(ring, base);           /* RB_MRT[i].BASE_LO */
 			OUT_RING(ring, 0x00000000);     /* RB_MRT[i].BASE_HI */
 		} else {
+			debug_assert((offset + size) <= fd_bo_size(rsc->bo));
 			OUT_RELOCW(ring, rsc->bo, offset, 0, 0);  /* BASE_LO/HI */
 		}
 
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c
index aeccebd..c7ac0a2 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.c
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.c
@@ -110,7 +110,8 @@ calculate_tiles(struct fd_batch *batch)
 	struct fd_gmem_stateobj *gmem = &ctx->gmem;
 	struct pipe_scissor_state *scissor = &batch->max_scissor;
 	struct pipe_framebuffer_state *pfb = &batch->framebuffer;
-	const uint32_t gmem_alignment = ctx->screen->gmem_alignment;
+	const uint32_t gmem_alignw = ctx->screen->gmem_alignw;
+	const uint32_t gmem_alignh = ctx->screen->gmem_alignh;
 	const uint32_t gmem_size = ctx->screen->gmemsize_bytes;
 	uint32_t minx, miny, width, height;
 	uint32_t nbins_x = 1, nbins_y = 1;
@@ -149,21 +150,21 @@ calculate_tiles(struct fd_batch *batch)
 		height = pfb->height;
 	} else {
 		/* round down to multiple of alignment: */
-		minx = scissor->minx & ~(gmem_alignment - 1);
-		miny = scissor->miny & ~(gmem_alignment - 1);
+		minx = scissor->minx & ~(gmem_alignw - 1);
+		miny = scissor->miny & ~(gmem_alignh - 1);
 		width = scissor->maxx - minx;
 		height = scissor->maxy - miny;
 	}
 
-	bin_w = align(width, gmem_alignment);
-	bin_h = align(height, gmem_alignment);
+	bin_w = align(width, gmem_alignw);
+	bin_h = align(height, gmem_alignh);
 
 	/* first, find a bin width that satisfies the maximum width
 	 * restrictions:
 	 */
 	while (bin_w > max_width) {
 		nbins_x++;
-		bin_w = align(width / nbins_x, gmem_alignment);
+		bin_w = align(width / nbins_x, gmem_alignw);
 	}
 
 	if (fd_mesa_debug & FD_DBG_MSGS) {
@@ -180,10 +181,10 @@ calculate_tiles(struct fd_batch *batch)
 	while (total_size(cbuf_cpp, zsbuf_cpp, bin_w, bin_h, gmem) > gmem_size) {
 		if (bin_w > bin_h) {
 			nbins_x++;
-			bin_w = align(width / nbins_x, gmem_alignment);
+			bin_w = align(width / nbins_x, gmem_alignw);
 		} else {
 			nbins_y++;
-			bin_h = align(height / nbins_y, gmem_alignment);
+			bin_h = align(height / nbins_y, gmem_alignh);
 		}
 	}
 
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index f1acf64..174c1d4 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -700,6 +700,7 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format forma
 {
 	struct pipe_resource *prsc = &rsc->base.b;
 	enum util_format_layout layout = util_format_description(format)->layout;
+	uint32_t pitchalign = fd_screen(prsc->screen)->gmem_alignw;
 	uint32_t level, size = 0;
 	uint32_t width = prsc->width0;
 	uint32_t height = prsc->height0;
@@ -715,9 +716,9 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format forma
 
 		if (layout == UTIL_FORMAT_LAYOUT_ASTC)
 			slice->pitch = width =
-				util_align_npot(width, 32 * util_format_get_blockwidth(format));
+				util_align_npot(width, pitchalign * util_format_get_blockwidth(format));
 		else
-			slice->pitch = width = align(width, 32);
+			slice->pitch = width = align(width, pitchalign);
 		slice->offset = size;
 		blocks = util_format_get_nblocks(format, width, height);
 		/* 1d array and 2d array textures must all have the same layer size
@@ -882,6 +883,7 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
 	struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
 	struct fd_resource_slice *slice = &rsc->slices[0];
 	struct pipe_resource *prsc = &rsc->base.b;
+	uint32_t pitchalign = fd_screen(pscreen)->gmem_alignw;
 
 	DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
 			"nr_samples=%u, usage=%u, bind=%x, flags=%x",
@@ -911,7 +913,8 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
 	slice->offset = handle->offset;
 	slice->size0 = handle->stride * prsc->height0;
 
-	if ((slice->pitch < align(prsc->width0, 32)) || (slice->pitch % 32))
+	if ((slice->pitch < align(prsc->width0, pitchalign)) ||
+			(slice->pitch & (pitchalign - 1)))
 		goto fail;
 
 	assert(rsc->cpp);
@@ -1125,7 +1128,7 @@ fd_resource_context_init(struct pipe_context *pctx)
 	pctx->transfer_flush_region = u_transfer_flush_region_vtbl;
 	pctx->transfer_unmap = u_transfer_unmap_vtbl;
 	pctx->buffer_subdata = u_default_buffer_subdata;
-        pctx->texture_subdata = u_default_texture_subdata;
+	pctx->texture_subdata = u_default_texture_subdata;
 	pctx->create_surface = fd_create_surface;
 	pctx->surface_destroy = fd_surface_destroy;
 	pctx->resource_copy_region = fd_resource_copy_region;
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 8ab0e37..8765d5c 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -679,9 +679,11 @@ fd_screen_create(struct fd_device *dev)
 	}
 
 	if (screen->gpu_id >= 500) {
-		screen->gmem_alignment = 64;
+		screen->gmem_alignw = 64;
+		screen->gmem_alignh = 32;
 	} else {
-		screen->gmem_alignment = 32;
+		screen->gmem_alignw = 32;
+		screen->gmem_alignh = 32;
 	}
 
 	/* NOTE: don't enable reordering on a2xx, since completely untested.
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h
index 6a7b2a8..8319539 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.h
+++ b/src/gallium/drivers/freedreno/freedreno_screen.h
@@ -64,7 +64,7 @@ struct fd_screen {
 	uint32_t chip_id;        /* coreid:8 majorrev:8 minorrev:8 patch:8 */
 	uint32_t max_freq;
 	uint32_t max_rts;        /* max # of render targets */
-	uint32_t gmem_alignment;
+	uint32_t gmem_alignw, gmem_alignh;
 	bool has_timestamp;
 
 	void *compiler;          /* currently unused for a2xx */




More information about the mesa-commit mailing list