Mesa (master): freedreno/a4xx: add ARB_texture_buffer_range support

Ilia Mirkin imirkin at kemper.freedesktop.org
Mon Nov 23 16:21:18 UTC 2015


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

Author: Ilia Mirkin <imirkin at alum.mit.edu>
Date:   Sat Nov 21 10:02:05 2015 -0500

freedreno/a4xx: add ARB_texture_buffer_range support

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>

---

 src/gallium/drivers/freedreno/a4xx/fd4_emit.c    |   14 ++++++--
 src/gallium/drivers/freedreno/a4xx/fd4_texture.c |   38 +++++++++++++++-------
 src/gallium/drivers/freedreno/freedreno_screen.c |    4 ++-
 3 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
index ec454b2..e488450 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
@@ -181,11 +181,12 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
 		OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
 				CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
 		for (i = 0; i < tex->num_textures; i++) {
-			static const struct fd4_pipe_sampler_view dummy_view = {};
+			static const struct fd4_pipe_sampler_view dummy_view = {
+				.base.target = PIPE_TEXTURE_1D,
+			};
 			const struct fd4_pipe_sampler_view *view = tex->textures[i] ?
 					fd4_pipe_sampler_view(tex->textures[i]) :
 					&dummy_view;
-			unsigned start = fd_sampler_first_level(&view->base);
 
 			OUT_RING(ring, view->texconst0);
 			OUT_RING(ring, view->texconst1);
@@ -193,7 +194,14 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
 			OUT_RING(ring, view->texconst3);
 			if (view->base.texture) {
 				struct fd_resource *rsc = fd_resource(view->base.texture);
-				uint32_t offset = fd_resource_offset(rsc, start, 0);
+				unsigned start = fd_sampler_first_level(&view->base);
+				uint32_t offset;
+				if (rsc->base.b.target == PIPE_BUFFER) {
+					offset = view->base.u.buf.first_element *
+						util_format_get_blocksize(view->base.format);
+				} else {
+					offset = fd_resource_offset(rsc, start, 0);
+				}
 				OUT_RELOC(ring, rsc->bo, offset, view->texconst4, 0);
 			} else {
 				OUT_RING(ring, 0x00000000);
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
index 598f1e1..a37c644 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
@@ -212,8 +212,7 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
 	struct fd4_pipe_sampler_view *so = CALLOC_STRUCT(fd4_pipe_sampler_view);
 	struct fd_resource *rsc = fd_resource(prsc);
-	unsigned lvl = fd_sampler_first_level(cso);
-	unsigned miplevels = fd_sampler_last_level(cso) - lvl;
+	unsigned lvl;
 	uint32_t sz2 = 0;
 
 	if (!so)
@@ -228,21 +227,38 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 	so->texconst0 =
 		A4XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) |
 		A4XX_TEX_CONST_0_FMT(fd4_pipe2tex(cso->format)) |
-		A4XX_TEX_CONST_0_MIPLVLS(miplevels) |
 		fd4_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
 				cso->swizzle_b, cso->swizzle_a);
 
 	if (util_format_is_srgb(cso->format))
 		so->texconst0 |= A4XX_TEX_CONST_0_SRGB;
 
-	so->texconst1 =
-		A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
-		A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
-	so->texconst2 =
-		A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
-		A4XX_TEX_CONST_2_PITCH(
-			util_format_get_nblocksx(
-				cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
+	if (prsc->target == PIPE_BUFFER) {
+		unsigned elements = cso->u.buf.last_element -
+			cso->u.buf.first_element + 1;
+		lvl = 0;
+		so->texconst1 =
+			A4XX_TEX_CONST_1_WIDTH(elements) |
+			A4XX_TEX_CONST_1_HEIGHT(1);
+		so->texconst2 =
+			A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
+			A4XX_TEX_CONST_2_PITCH(elements * rsc->cpp);
+	} else {
+		unsigned miplevels;
+
+		lvl = fd_sampler_first_level(cso);
+		miplevels = fd_sampler_last_level(cso) - lvl;
+
+		so->texconst0 |= A4XX_TEX_CONST_0_MIPLVLS(miplevels);
+		so->texconst1 =
+			A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
+			A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
+		so->texconst2 =
+			A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
+			A4XX_TEX_CONST_2_PITCH(
+					util_format_get_nblocksx(
+							cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
+	}
 
 	switch (prsc->target) {
 	case PIPE_TEXTURE_1D_ARRAY:
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 7bffc8f..0c494d4 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -183,7 +183,9 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 		return is_a3xx(screen) || is_a4xx(screen);
 
 	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
-		return is_a3xx(screen) ? 16 : 0;
+		if (is_a3xx(screen)) return 16;
+		if (is_a4xx(screen)) return 32;
+		return 0;
 	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
 		/* I think 32k on a4xx.. and we could possibly emulate more
 		 * by pretending 2d/rect textures and splitting high bits




More information about the mesa-commit mailing list