Mesa (master): freedreno: helper for a3xx/a4xx border-colors

Rob Clark robclark at kemper.freedesktop.org
Tue Sep 15 21:35:37 UTC 2015


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

Author: Rob Clark <robclark at freedesktop.org>
Date:   Tue Sep 15 09:23:21 2015 -0400

freedreno: helper for a3xx/a4xx border-colors

Both use the same layout for the buffer containing border-color values,
so rather than duplicating the logic in a4xx, split it out into a
helper.

Signed-off-by: Rob Clark <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/a3xx/fd3_context.h  |   16 -----
 src/gallium/drivers/freedreno/a3xx/fd3_emit.c     |   53 +----------------
 src/gallium/drivers/freedreno/freedreno_texture.c |   66 +++++++++++++++++++++
 src/gallium/drivers/freedreno/freedreno_texture.h |   31 ++++++++++
 4 files changed, 99 insertions(+), 67 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.h b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
index 250bcf8..b4c2ebe5 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_context.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
@@ -73,22 +73,6 @@ struct fd3_context {
 	 */
 	struct fd_vertex_state blit_vbuf_state;
 
-
-	/*
-	 * Border color layout *appears* to be as arrays of 0x40 byte
-	 * elements, with frag shader elements starting at (16 x 0x40).
-	 * But at some point I should probably experiment more with
-	 * samplers in vertex shaders to be sure.  Unclear about why
-	 * there is this offset when there are separate VS and FS base
-	 * addr regs.
-	 *
-	 * The first 8 bytes of each entry are the requested border
-	 * color in fp16.  Unclear about the rest.. could be used for
-	 * other formats, or could simply be for aligning the pitch
-	 * to 32 pixels.
-	 */
-#define BORDERCOLOR_SIZE 0x40
-
 	struct u_upload_mgr *border_color_uploader;
 	struct pipe_resource *border_color_buf;
 
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 6f514ed..b81bc5a 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -149,6 +149,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
 			&fd3_ctx->border_color_buf,
 			&ptr);
 
+	fd_setup_border_colors(tex, ptr, tex_off[sb]);
+
 	if (tex->num_samplers > 0) {
 		/* output sampler state: */
 		OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * tex->num_samplers));
@@ -163,57 +165,6 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
 			const struct fd3_sampler_stateobj *sampler = tex->samplers[i] ?
 					fd3_sampler_stateobj(tex->samplers[i]) :
 					&dummy_sampler;
-			uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
-					(BORDERCOLOR_SIZE * tex_off[sb]) +
-					(BORDERCOLOR_SIZE * i));
-			uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
-
-			/*
-			 * XXX HACK ALERT XXX
-			 *
-			 * The border colors need to be swizzled in a particular
-			 * format-dependent order. Even though samplers don't know about
-			 * formats, we can assume that with a GL state tracker, there's a
-			 * 1:1 correspondence between sampler and texture. Take advantage
-			 * of that knowledge.
-			 */
-			if (i < tex->num_textures && tex->textures[i]) {
-				const struct util_format_description *desc =
-					util_format_description(tex->textures[i]->format);
-				for (j = 0; j < 4; j++) {
-					if (desc->swizzle[j] >= 4)
-						continue;
-
-					const struct util_format_channel_description *chan =
-						&desc->channel[desc->swizzle[j]];
-					int size = chan->size;
-
-					/* The Z16 texture format we use seems to look in the
-					 * 32-bit border color slots
-					 */
-					if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
-						size = 32;
-
-					/* Formats like R11G11B10 or RGB9_E5 don't specify
-					 * per-channel sizes properly.
-					 */
-					if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
-						size = 16;
-
-					if (chan->pure_integer && size > 16)
-						bcolor32[desc->swizzle[j] + 4] =
-							sampler->base.border_color.i[j];
-					else if (size > 16)
-						bcolor32[desc->swizzle[j]] =
-							fui(sampler->base.border_color.f[j]);
-					else if (chan->pure_integer)
-						bcolor[desc->swizzle[j] + 8] =
-							sampler->base.border_color.i[j];
-					else
-						bcolor[desc->swizzle[j]] =
-							util_float_to_half(sampler->base.border_color.f[j]);
-				}
-			}
 
 			OUT_RING(ring, sampler->texsamp0);
 			OUT_RING(ring, sampler->texsamp1);
diff --git a/src/gallium/drivers/freedreno/freedreno_texture.c b/src/gallium/drivers/freedreno/freedreno_texture.c
index eaa6629..04e4643 100644
--- a/src/gallium/drivers/freedreno/freedreno_texture.c
+++ b/src/gallium/drivers/freedreno/freedreno_texture.c
@@ -162,3 +162,69 @@ fd_texture_init(struct pipe_context *pctx)
 
 	pctx->sampler_view_destroy = fd_sampler_view_destroy;
 }
+
+/* helper for setting up border-color buffer for a3xx/a4xx: */
+void
+fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
+		unsigned offset)
+{
+	unsigned i, j;
+
+	for (i = 0; i < tex->num_samplers; i++) {
+		struct pipe_sampler_state *sampler = tex->samplers[i];
+		uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
+				(BORDERCOLOR_SIZE * offset) +
+				(BORDERCOLOR_SIZE * i));
+		uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
+
+		if (!sampler)
+			continue;
+
+		/*
+		 * XXX HACK ALERT XXX
+		 *
+		 * The border colors need to be swizzled in a particular
+		 * format-dependent order. Even though samplers don't know about
+		 * formats, we can assume that with a GL state tracker, there's a
+		 * 1:1 correspondence between sampler and texture. Take advantage
+		 * of that knowledge.
+		 */
+		if (i < tex->num_textures && tex->textures[i]) {
+			const struct util_format_description *desc =
+					util_format_description(tex->textures[i]->format);
+			for (j = 0; j < 4; j++) {
+				if (desc->swizzle[j] >= 4)
+					continue;
+
+				const struct util_format_channel_description *chan =
+						&desc->channel[desc->swizzle[j]];
+				int size = chan->size;
+
+				/* The Z16 texture format we use seems to look in the
+				 * 32-bit border color slots
+				 */
+				if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
+					size = 32;
+
+				/* Formats like R11G11B10 or RGB9_E5 don't specify
+				 * per-channel sizes properly.
+				 */
+				if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
+					size = 16;
+
+				if (chan->pure_integer && size > 16)
+					bcolor32[desc->swizzle[j] + 4] =
+							sampler->border_color.i[j];
+				else if (size > 16)
+					bcolor32[desc->swizzle[j]] =
+							fui(sampler->border_color.f[j]);
+				else if (chan->pure_integer)
+					bcolor[desc->swizzle[j] + 8] =
+							sampler->border_color.i[j];
+				else
+					bcolor[desc->swizzle[j]] =
+							util_float_to_half(sampler->border_color.f[j]);
+			}
+		}
+	}
+}
diff --git a/src/gallium/drivers/freedreno/freedreno_texture.h b/src/gallium/drivers/freedreno/freedreno_texture.h
index 43571a9..fa27d1c 100644
--- a/src/gallium/drivers/freedreno/freedreno_texture.h
+++ b/src/gallium/drivers/freedreno/freedreno_texture.h
@@ -41,4 +41,35 @@ void fd_set_sampler_views(struct pipe_context *pctx, unsigned shader,
 
 void fd_texture_init(struct pipe_context *pctx);
 
+struct fd_texture_stateobj;
+
+/* Both a3xx/a4xx share the same layout for the border-color buffer,
+ * which contains the pre-swizzled (based on texture format) border
+ * color value, with the following layout (per sampler):
+ *
+ *  offset | description
+ *  -------+-------------
+ *  0x00:  | fp16[0]   \
+ *         | fp16[1]   |___ swizzled fp16 channel values for "small float"
+ *         | fp16[2]   |    formats (<= 16 bits per component, !integer)
+ *         | fp16[3]   /
+ *  0x08:  | padding
+ *  0x10:  | int16[0]  \
+ *         | int16[1]  |___ swizzled int16 channels for for "small integer"
+ *         | int16[2]  |    formats (<= 16 bits per component, integer)
+ *         | int16[3]  /
+ *  0x18:  | padding
+ *  0x20:  | fp32[0]   \
+ *         | fp32[1]   |___ swizzled fp32 channel values for "large float"
+ *         | fp32[2]   |    formats (> 16 bits per component, !integer)
+ *         | fp32[3]   /
+ *  0x30:  | int32[0]  \
+ *         | int32[1]  |___ swizzled int32 channel values for "large int"
+ *         | int32[2]  |    formats (> 16 bits per component, integer)
+ *         | int32[3]  /
+ */
+#define BORDERCOLOR_SIZE 0x40
+void fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
+		unsigned offset);
+
 #endif /* FREEDRENO_TEXTURE_H_ */




More information about the mesa-commit mailing list