[Mesa-dev] [PATCH] freedreno/a4xx: use hardware RGTC texture samplers

Ilia Mirkin imirkin at alum.mit.edu
Fri Nov 20 15:35:16 PST 2015


a4xx hardware has real support for RGTC so there's no need to fake it
like we do on a3xx. Undo the hacks, and keep track of an "internal
format" of a resource, which on a3xx will be different, triggering the
transfer-time conversions to take place.

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
 src/gallium/drivers/freedreno/a4xx/a4xx.xml.h      |  4 ++++
 src/gallium/drivers/freedreno/a4xx/fd4_format.c    | 27 +++++++---------------
 src/gallium/drivers/freedreno/a4xx/fd4_format.h    |  1 -
 src/gallium/drivers/freedreno/a4xx/fd4_texture.c   |  2 +-
 src/gallium/drivers/freedreno/freedreno_resource.c |  9 +++++---
 src/gallium/drivers/freedreno/freedreno_resource.h |  1 +
 6 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a4xx/a4xx.xml.h b/src/gallium/drivers/freedreno/a4xx/a4xx.xml.h
index e46a11e..4436697 100644
--- a/src/gallium/drivers/freedreno/a4xx/a4xx.xml.h
+++ b/src/gallium/drivers/freedreno/a4xx/a4xx.xml.h
@@ -207,6 +207,10 @@ enum a4xx_tex_fmt {
 	TFMT4_DXT1 = 86,
 	TFMT4_DXT3 = 87,
 	TFMT4_DXT5 = 88,
+	TFMT4_RGTC1_UNORM = 90,
+	TFMT4_RGTC1_SNORM = 91,
+	TFMT4_RGTC2_UNORM = 94,
+	TFMT4_RGTC2_SNORM = 95,
 	TFMT4_BPTC_UFLOAT = 97,
 	TFMT4_BPTC_FLOAT = 98,
 	TFMT4_BPTC = 99,
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_format.c b/src/gallium/drivers/freedreno/a4xx/fd4_format.c
index d2a1aee..a97e01a 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_format.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_format.c
@@ -291,15 +291,14 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
 	_T(BPTC_RGB_FLOAT,  BPTC_FLOAT,  NONE, WZYX),
 	_T(BPTC_RGB_UFLOAT, BPTC_UFLOAT, NONE, WZYX),
 
-	/* faked */
-	_T(RGTC1_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
-	_T(RGTC1_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
-	_T(RGTC2_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
-	_T(RGTC2_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
-	_T(LATC1_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
-	_T(LATC1_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
-	_T(LATC2_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
-	_T(LATC2_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
+	_T(RGTC1_UNORM, RGTC1_UNORM, NONE, WZYX),
+	_T(RGTC1_SNORM, RGTC1_SNORM, NONE, WZYX),
+	_T(RGTC2_UNORM, RGTC2_UNORM, NONE, WZYX),
+	_T(RGTC2_SNORM, RGTC2_SNORM, NONE, WZYX),
+	_T(LATC1_UNORM, RGTC1_UNORM, NONE, WZYX),
+	_T(LATC1_SNORM, RGTC1_SNORM, NONE, WZYX),
+	_T(LATC2_UNORM, RGTC2_UNORM, NONE, WZYX),
+	_T(LATC2_SNORM, RGTC2_SNORM, NONE, WZYX),
 };
 
 /* convert pipe format to vertex buffer format: */
@@ -342,8 +341,6 @@ fd4_pipe2fetchsize(enum pipe_format format)
 {
 	if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
 		format = PIPE_FORMAT_Z32_FLOAT;
-	else if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
-		format = PIPE_FORMAT_R8G8B8A8_UNORM;
 
 	switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) {
 	case 8:   return TFETCH4_1_BYTE;
@@ -359,14 +356,6 @@ fd4_pipe2fetchsize(enum pipe_format format)
 	}
 }
 
-unsigned
-fd4_pipe2nblocksx(enum pipe_format format, unsigned width)
-{
-	if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
-		format = PIPE_FORMAT_R8G8B8A8_UNORM;
-	return util_format_get_nblocksx(format, width);
-}
-
 /* we need to special case a bit the depth/stencil restore, because we are
  * using the texture sampler to blit into the depth/stencil buffer, *not*
  * into a color buffer.  Otherwise fd4_tex_swiz() will do the wrong thing,
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_format.h b/src/gallium/drivers/freedreno/a4xx/fd4_format.h
index 8c365f0..04837da 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_format.h
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_format.h
@@ -38,7 +38,6 @@ enum a4xx_tex_fmt fd4_pipe2tex(enum pipe_format format);
 enum a4xx_color_fmt fd4_pipe2color(enum pipe_format format);
 enum pipe_format fd4_gmem_restore_format(enum pipe_format format);
 enum a3xx_color_swap fd4_pipe2swap(enum pipe_format format);
-unsigned fd4_pipe2nblocksx(enum pipe_format format, unsigned width);
 enum a4xx_tex_fetchsize fd4_pipe2fetchsize(enum pipe_format format);
 enum a4xx_depth_format fd4_pipe2depth(enum pipe_format format);
 
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
index 00c257b..75b083b 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
@@ -240,7 +240,7 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 	so->texconst2 =
 		A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
 		A4XX_TEX_CONST_2_PITCH(
-			fd4_pipe2nblocksx(
+			util_format_get_nblocksx(
 				cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
 
 	switch (prsc->target) {
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 5b1cee8..75b6771 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -388,7 +388,8 @@ fd_resource_transfer_map(struct pipe_context *pctx,
 
 		buf = trans->staging;
 		offset = 0;
-	} else if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC) {
+	} else if (rsc->internal_format != format &&
+			   util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC) {
 		assert(trans->base.box.depth == 1);
 
 		trans->base.stride = util_format_get_stride(
@@ -547,6 +548,7 @@ static struct pipe_resource *
 fd_resource_create(struct pipe_screen *pscreen,
 		const struct pipe_resource *tmpl)
 {
+	struct fd_screen *screen = fd_screen(pscreen);
 	struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
 	struct pipe_resource *prsc = &rsc->base.b;
 	enum pipe_format format = tmpl->format;
@@ -574,9 +576,10 @@ fd_resource_create(struct pipe_screen *pscreen,
 
 	if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
 		format = PIPE_FORMAT_Z32_FLOAT;
-	else if (util_format_description(format)->layout ==
-			 UTIL_FORMAT_LAYOUT_RGTC)
+	else if (fd_screen(pscreen)->gpu_id < 400 &&
+			 util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
 		format = PIPE_FORMAT_R8G8B8A8_UNORM;
+	rsc->internal_format = format;
 	rsc->cpp = util_format_get_blocksize(format);
 
 	assert(rsc->cpp);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 10f5242..9a9b0d0 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -73,6 +73,7 @@ struct fd_resource {
 	struct u_resource base;
 	struct fd_bo *bo;
 	uint32_t cpp;
+	enum pipe_format internal_format;
 	bool layer_first;        /* see above description */
 	uint32_t layer_size;
 	struct fd_resource_slice slices[MAX_MIP_LEVELS];
-- 
2.4.10



More information about the mesa-dev mailing list