Mesa (master): freedreno/a2xx: add missing vertex formats (SSCALE/USCALE/FIXED)

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Oct 30 18:04:48 UTC 2019


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

Author: Jonathan Marek <jonathan at marek.ca>
Date:   Fri Sep  6 12:59:15 2019 -0400

freedreno/a2xx: add missing vertex formats (SSCALE/USCALE/FIXED)

Mostly for vertex formats, but they are supported as texture formats too
(untested however).

Signed-off-by: Jonathan Marek <jonathan at marek.ca>
Reviewed-by: Rob Clark <robdclark at gmail.com>

---

 src/freedreno/registers/a2xx.xml                 |  2 +-
 src/gallium/drivers/freedreno/a2xx/fd2_gmem.c    |  3 +-
 src/gallium/drivers/freedreno/a2xx/fd2_program.c | 31 +++++-----------
 src/gallium/drivers/freedreno/a2xx/fd2_screen.c  | 14 ++++----
 src/gallium/drivers/freedreno/a2xx/fd2_texture.c | 23 ++++++------
 src/gallium/drivers/freedreno/a2xx/fd2_util.c    | 45 ++++++++++++++++++++++--
 src/gallium/drivers/freedreno/a2xx/fd2_util.h    | 11 +++++-
 src/gallium/drivers/freedreno/a2xx/instr-a2xx.h  |  4 +--
 8 files changed, 83 insertions(+), 50 deletions(-)

diff --git a/src/freedreno/registers/a2xx.xml b/src/freedreno/registers/a2xx.xml
index 4817ab31bb3..e486f804bc7 100644
--- a/src/freedreno/registers/a2xx.xml
+++ b/src/freedreno/registers/a2xx.xml
@@ -1620,7 +1620,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
 		<bitfield name="SWIZ_Y" low="4" high="6" type="sq_tex_swiz"/>
 		<bitfield name="SWIZ_Z" low="7" high="9" type="sq_tex_swiz"/>
 		<bitfield name="SWIZ_W" low="10" high="12" type="sq_tex_swiz"/>
-		<bitfield name="EXP_ADJUST" low="13" high="18" type="uint"/>
+		<bitfield name="EXP_ADJUST" low="13" high="18" type="int"/>
 		<bitfield name="XY_MAG_FILTER" low="19" high="20" type="sq_tex_filter"/>
 		<bitfield name="XY_MIN_FILTER" low="21" high="22" type="sq_tex_filter"/>
 		<bitfield name="MIP_FILTER" low="23" high="24" type="sq_tex_filter"/>
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c
index 6a78db5377e..bf112149b03 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c
@@ -52,6 +52,7 @@ static uint32_t fmt2swap(enum pipe_format format)
 	case PIPE_FORMAT_B5G5R5X1_UNORM:
 	case PIPE_FORMAT_B4G4R4A4_UNORM:
 	case PIPE_FORMAT_B4G4R4X4_UNORM:
+	case PIPE_FORMAT_B2G3R3_UNORM:
 		return 1;
 	default:
 		return 0;
@@ -248,7 +249,7 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base,
 			A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
 			A2XX_SQ_TEX_0_PITCH(slice->pitch));
 	OUT_RELOC(ring, rsc->bo, offset,
-			fd2_pipe2surface(format) |
+			A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(format).format) |
 			A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL), 0);
 	OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
 			A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_program.c b/src/gallium/drivers/freedreno/a2xx/fd2_program.c
index c4c23ff0d5b..9efc473b4a7 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_program.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_program.c
@@ -166,30 +166,15 @@ static void
 patch_vtx_fetch(struct fd_context *ctx, struct pipe_vertex_element *elem,
 	instr_fetch_vtx_t *instr, uint16_t dst_swiz)
 {
-	struct pipe_vertex_buffer *vb =
-				&ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index];
-	enum pipe_format format = elem->src_format;
-	const struct util_format_description *desc =
-			util_format_description(format);
-	unsigned j;
-
-	/* Find the first non-VOID channel. */
-	for (j = 0; j < 4; j++)
-		if (desc->channel[j].type != UTIL_FORMAT_TYPE_VOID)
-			break;
-
-	instr->format = fd2_pipe2surface(format);
-	instr->num_format_all = !desc->channel[j].normalized;
-	instr->format_comp_all = desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED;
-	instr->stride = vb->stride;
+	struct surface_format fmt = fd2_pipe2surface(elem->src_format);
+
+	instr->dst_swiz = fd2_vtx_swiz(elem->src_format, dst_swiz);
+	instr->format_comp_all = fmt.sign == SQ_TEX_SIGN_SIGNED;
+	instr->num_format_all = fmt.num_format;
+	instr->format = fmt.format;
+	instr->exp_adjust_all = fmt.exp_adjust;
+	instr->stride = ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index].stride;
 	instr->offset = elem->src_offset;
-
-	unsigned swiz = 0;
-	for (int i = 0; i < 4; i++) {
-		unsigned s = dst_swiz >> i*3 & 7;
-		swiz |= (s >= 4 ? s : desc->swizzle[s]) << i*3;
-	}
-	instr->dst_swiz = swiz;
 }
 
 static void
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_screen.c b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c
index 42c0c024e61..361660857ee 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_screen.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c
@@ -59,13 +59,13 @@ fd2_screen_is_format_supported(struct pipe_screen *pscreen,
 	}
 
 	if ((usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_VERTEX_BUFFER)) &&
-	    !util_format_is_srgb(format)) {
-		enum a2xx_sq_surfaceformat fmt = fd2_pipe2surface(format);
-		unsigned block_size = util_format_get_blocksize(format);
-		if (fmt != ~0)
-			retval |= usage & PIPE_BIND_VERTEX_BUFFER;
-		if (fmt != ~0 && block_size != 3 && block_size != 6 &&
-		    (block_size != 12 || format == PIPE_FORMAT_R32G32B32_FLOAT))
+			!util_format_is_srgb(format) &&
+			!util_format_is_pure_integer(format) &&
+			fd2_pipe2surface(format).format != FMT_INVALID) {
+		retval |= usage & PIPE_BIND_VERTEX_BUFFER;
+		/* the only npot blocksize supported texture format is R32G32B32_FLOAT */
+		if (util_is_power_of_two_or_zero(util_format_get_blocksize(format)) ||
+				format == PIPE_FORMAT_R32G32B32_FLOAT)
 			retval |= usage & PIPE_BIND_SAMPLER_VIEW;
 	}
 
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c
index 7aa26ca5673..b6ceb323f0b 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c
@@ -170,6 +170,7 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
 	struct fd2_pipe_sampler_view *so = CALLOC_STRUCT(fd2_pipe_sampler_view);
 	struct fd_resource *rsc = fd_resource(prsc);
+	struct surface_format fmt = fd2_pipe2surface(cso->format);
 
 	if (!so)
 		return NULL;
@@ -180,26 +181,24 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 	so->base.reference.count = 1;
 	so->base.context = pctx;
 
-	enum sq_tex_sign sign = SQ_TEX_SIGN_UNSIGNED;
-	if (util_format_is_snorm(cso->format))
-		sign = SQ_TEX_SIGN_SIGNED;
-	/* note: SQ_TEX_SIGN_GAMMA same as SQ_TEX_SIGN_UNSIGNED (a200) */
-
 	so->tex0 =
-		A2XX_SQ_TEX_0_SIGN_X(sign) |
-		A2XX_SQ_TEX_0_SIGN_Y(sign) |
-		A2XX_SQ_TEX_0_SIGN_Z(sign) |
-		A2XX_SQ_TEX_0_SIGN_W(sign) |
+		A2XX_SQ_TEX_0_SIGN_X(fmt.sign) |
+		A2XX_SQ_TEX_0_SIGN_Y(fmt.sign) |
+		A2XX_SQ_TEX_0_SIGN_Z(fmt.sign) |
+		A2XX_SQ_TEX_0_SIGN_W(fmt.sign) |
 		A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch) |
 		COND(rsc->tile_mode, A2XX_SQ_TEX_0_TILED);
 	so->tex1 =
-		A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(cso->format)) |
+		A2XX_SQ_TEX_1_FORMAT(fmt.format) |
 		A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL);
 	so->tex2 =
 		A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) |
 		A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1);
-	so->tex3 = fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
-			cso->swizzle_b, cso->swizzle_a);
+	so->tex3 =
+		A2XX_SQ_TEX_3_NUM_FORMAT(fmt.num_format) |
+		fd2_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
+		             cso->swizzle_b, cso->swizzle_a) |
+		A2XX_SQ_TEX_3_EXP_ADJUST(fmt.exp_adjust);
 
 	so->tex4 =
 		A2XX_SQ_TEX_4_MIP_MIN_LEVEL(fd_sampler_first_level(cso)) |
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_util.c b/src/gallium/drivers/freedreno/a2xx/fd2_util.c
index af570701e54..ed1bbb1368d 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_util.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_util.c
@@ -29,8 +29,8 @@
 
 #include "fd2_util.h"
 
-enum a2xx_sq_surfaceformat
-fd2_pipe2surface(enum pipe_format format)
+static enum a2xx_sq_surfaceformat
+pipe2surface(enum pipe_format format, struct surface_format *fmt)
 {
 	const struct util_format_description *desc = util_format_description(format);
 
@@ -66,6 +66,15 @@ fd2_pipe2surface(enum pipe_format format)
 	for (unsigned i = 0; i < 4; i++)
 		channel_size |= desc->channel[i].size << i*8;
 
+	unsigned i = util_format_get_first_non_void_channel(format);
+	if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
+		desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
+		fmt->sign = SQ_TEX_SIGN_SIGNED;
+	if (!desc->channel[i].normalized)
+		fmt->num_format = SQ_TEX_NUM_FORMAT_INT;
+	if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
+		fmt->exp_adjust = -16;
+
 	/* Note: the 3 channel 24bpp/48bpp/96bpp formats are only for vertex fetch
 	 * we can use the 4 channel format and ignore the 4th component just isn't used
 	 * XXX: is it possible for the extra loaded component to cause a MMU fault?
@@ -83,7 +92,7 @@ fd2_pipe2surface(enum pipe_format format)
 		CASE(32, 32, 32,  0): return FMT_32_32_32_FLOAT;
 		CASE(32, 32, 32, 32): return FMT_32_32_32_32_FLOAT;
 		}
-	} else if (desc->is_unorm || desc->is_snorm) {
+	} else {
 		switch (channel_size) {
 		CASE( 8,  0,  0,  0): return FMT_8;
 		CASE( 8,  8,  0,  0): return FMT_8_8;
@@ -102,6 +111,7 @@ fd2_pipe2surface(enum pipe_format format)
 		CASE( 5,  6,  5,  0): return FMT_5_6_5;
 		CASE(10, 10, 10,  2): return FMT_2_10_10_10;
 		CASE( 8, 24,  0,  0): return FMT_24_8;
+		CASE( 2,  3,  3,  0): return FMT_2_3_3; /* Note: R/B swapped */
 		}
 	}
 #undef CASE
@@ -109,6 +119,18 @@ fd2_pipe2surface(enum pipe_format format)
 	return ~0;
 }
 
+struct surface_format
+fd2_pipe2surface(enum pipe_format format)
+{
+	struct surface_format fmt = {
+		.sign = SQ_TEX_SIGN_UNSIGNED,
+		.num_format = SQ_TEX_NUM_FORMAT_FRAC,
+		.exp_adjust = 0,
+	};
+	fmt.format = pipe2surface(format, &fmt);
+	return fmt;
+}
+
 enum a2xx_colorformatx
 fd2_pipe2color(enum pipe_format format)
 {
@@ -116,6 +138,8 @@ fd2_pipe2color(enum pipe_format format)
 	/* 8-bit buffers. */
 	case PIPE_FORMAT_R8_UNORM:
 		return COLORX_8;
+	case PIPE_FORMAT_B2G3R3_UNORM:
+		return COLORX_2_3_3; /* note: untested */
 
 	/* 16-bit buffers. */
 	case PIPE_FORMAT_B5G6R5_UNORM:
@@ -190,3 +214,18 @@ fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
 			A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(rswiz[2])) |
 			A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(rswiz[3]));
 }
+
+uint32_t
+fd2_vtx_swiz(enum pipe_format format, unsigned swizzle)
+{
+	const struct util_format_description *desc =
+			util_format_description(format);
+	unsigned char swiz[4], rswiz[4];
+
+	for (unsigned i = 0; i < 4; i++)
+		swiz[i] = (swizzle >> i * 3) & 7;
+
+	util_format_compose_swizzles(desc->swizzle, swiz, rswiz);
+
+	return rswiz[0] | rswiz[1] << 3 | rswiz[2] << 6 | rswiz[3] << 9;
+}
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_util.h b/src/gallium/drivers/freedreno/a2xx/fd2_util.h
index d2758f3f0b2..cf945b14475 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_util.h
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_util.h
@@ -31,10 +31,19 @@
 
 #include "a2xx.xml.h"
 
-enum a2xx_sq_surfaceformat fd2_pipe2surface(enum pipe_format format);
+struct surface_format {
+#define FMT_INVALID 0x7f
+	enum a2xx_sq_surfaceformat format : 7;
+	enum sq_tex_sign sign : 2;
+	enum sq_tex_num_format num_format : 1;
+	int exp_adjust : 6;
+};
+
+struct surface_format fd2_pipe2surface(enum pipe_format format);
 enum a2xx_colorformatx fd2_pipe2color(enum pipe_format format);
 uint32_t fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r,
 		unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
+uint32_t fd2_vtx_swiz(enum pipe_format format, unsigned swizzle);
 
 /* convert x,y to dword */
 static inline uint32_t xy2d(uint16_t x, uint16_t y)
diff --git a/src/gallium/drivers/freedreno/a2xx/instr-a2xx.h b/src/gallium/drivers/freedreno/a2xx/instr-a2xx.h
index 2591062ee3c..0078b24b509 100644
--- a/src/gallium/drivers/freedreno/a2xx/instr-a2xx.h
+++ b/src/gallium/drivers/freedreno/a2xx/instr-a2xx.h
@@ -372,8 +372,8 @@ typedef struct PACKED {
 	uint8_t             signed_rf_mode_all       : 1;
 	uint8_t             reserved1                : 1;
 	instr_surf_fmt_t    format                   : 6;
-	uint8_t             reserved2                : 1;
-	uint8_t             exp_adjust_all           : 7;
+	uint8_t             reserved2                : 2;
+	uint8_t             exp_adjust_all           : 6;
 	uint8_t             reserved3                : 1;
 	uint8_t             pred_select              : 1;
 	/* dword2: */




More information about the mesa-commit mailing list