freedreno/a3xx: alpha render-target shenanigans
authorRob Clark <robclark@freedesktop.org>
Fri, 12 Sep 2014 13:01:25 +0000 (09:01 -0400)
committerRob Clark <robclark@freedesktop.org>
Fri, 12 Sep 2014 20:23:52 +0000 (16:23 -0400)
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@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/ir3/ir3_compiler.c
src/gallium/drivers/freedreno/ir3/ir3_shader.c
src/gallium/drivers/freedreno/ir3/ir3_shader.h

index 394277cf6b91b0a694282d15f35ad12c0a481a9b..15d2ce4a943d39a8dd3a12bdbeddea794a81f79a 100644 (file)
@@ -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),
index affb775f75ba57667c2d555b9fb634b8173276b4..25211feb02478b62406c551841d8e2c7200981a7 100644 (file)
@@ -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():
index a170469b573c67c2ab2d32079754248c5ad266ac..6d45597886baadc4140669dad13f23cf71e78b8d 100644 (file)
@@ -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)
index 1a91fcbcb1345361a06b800a4acb8e783b5efae0..882893fdde55a3a51a5114ce9a035955c67e58ab 100644 (file)
@@ -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 {