Mesa (master): freedreno/a3xx: alpha render-target shenanigans

Rob Clark robclark at kemper.freedesktop.org
Fri Sep 12 20:26:54 UTC 2014


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

Author: Rob Clark <robclark at freedesktop.org>
Date:   Fri Sep 12 09:01:25 2014 -0400

freedreno/a3xx: alpha render-target shenanigans

We need the .w component to end up in .x, since the hw appears to fetch
gl_FragColor starting with the .x coordinate regardless of MRT format.
As long as we are doing this, we might as well throw out the remaining
unneeded components.

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

---

 src/gallium/drivers/freedreno/a3xx/fd3_draw.c    |    2 ++
 src/gallium/drivers/freedreno/ir3/ir3_compiler.c |   17 +++++++++++++++++
 src/gallium/drivers/freedreno/ir3/ir3_shader.c   |    1 +
 src/gallium/drivers/freedreno/ir3/ir3_shader.h   |   16 ++++++++++++++--
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index 394277c..15d2ce4 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -30,6 +30,7 @@
 #include "util/u_string.h"
 #include "util/u_memory.h"
 #include "util/u_prim.h"
+#include "util/u_format.h"
 
 #include "freedreno_state.h"
 #include "freedreno_resource.h"
@@ -103,6 +104,7 @@ fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
 			/* do binning pass first: */
 			.binning_pass = true,
 			.color_two_side = ctx->rasterizer ? ctx->rasterizer->light_twoside : false,
+			.alpha = util_format_is_alpha(pipe_surface_format(ctx->framebuffer.cbufs[0])),
 			// TODO set .half_precision based on render target format,
 			// ie. float16 and smaller use half, float32 use full..
 			.half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
index affb775..25211fe 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
@@ -2607,6 +2607,23 @@ ir3_compile_shader(struct ir3_shader_variant *so,
 		block->noutputs = j * 4;
 	}
 
+	/* for rendering to alpha format, we only need the .w component,
+	 * and we need it to be in the .x position:
+	 */
+	if (key.alpha) {
+		for (i = 0, j = 0; i < so->outputs_count; i++) {
+			unsigned name = sem2name(so->outputs[i].semantic);
+
+			/* move .w component to .x and discard others: */
+			if (name == TGSI_SEMANTIC_COLOR) {
+				block->outputs[(i*4)+0] = block->outputs[(i*4)+3];
+				block->outputs[(i*4)+1] = NULL;
+				block->outputs[(i*4)+2] = NULL;
+				block->outputs[(i*4)+3] = NULL;
+			}
+		}
+	}
+
 	/* at this point, we want the kill's in the outputs array too,
 	 * so that they get scheduled (since they have no dst).. we've
 	 * already ensured that the array is big enough in push_block():
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
index a170469..6d45597 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
@@ -189,6 +189,7 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key)
 	if (shader->type == SHADER_VERTEX) {
 		key.color_two_side = false;
 		key.half_precision = false;
+		key.alpha = false;
 	}
 
 	for (v = shader->variants; v; v = v->next)
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
index 1a91fcb..882893f 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
@@ -54,12 +54,24 @@ static inline uint16_t sem2idx(ir3_semantic sem)
  * in hw (two sided color), binning-pass vertex shader, etc.
  */
 struct ir3_shader_key {
-	/* vertex shader variant parameters: */
+	/*
+	 * Vertex shader variant parameters:
+	 */
 	unsigned binning_pass : 1;
 
-	/* fragment shader variant parameters: */
+	/*
+	 * Fragment shader variant parameters:
+	 */
 	unsigned color_two_side : 1;
 	unsigned half_precision : 1;
+	/* For rendering to alpha, we need a bit of special handling
+	 * since the hw always takes gl_FragColor starting from x
+	 * component, rather than figuring out to take the w component.
+	 * We could be more clever and generate variants for other
+	 * render target formats (ie. luminance formats are xxx1), but
+	 * let's start with this and see how it goes:
+	 */
+	unsigned alpha : 1;
 };
 
 struct ir3_shader_variant {




More information about the mesa-commit mailing list