summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/ir3
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-09-12 09:01:25 -0400
committerRob Clark <[email protected]>2014-09-12 16:23:52 -0400
commit80058c0f08ea94d3de96909027a792e397fa9262 (patch)
tree8276c035f6fc8ef2bc86718518f2b03142966731 /src/gallium/drivers/freedreno/ir3
parent3e0a82b52ebbf306adb0dd0f0990f7a8e8b271c5 (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/ir3')
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler.c17
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.c1
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.h16
3 files changed, 32 insertions, 2 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
index affb775f75b..25211feb024 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 a170469b573..6d45597886b 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 1a91fcbcb13..882893fdde5 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 {