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

Author: Alex Deucher <alexdeuc...@gmail.com>
Date:   Fri Jun 24 18:05:53 2011 -0400

r600g: eg+ support for FS_COLOR0_WRITES_ALL_CBUFS

Evergreen+ don't support multi-writes so we need to emulate
it in the shader. Fixes the following piglit tests:
fbo-drawbuffers-fragcolor
ati_draw_buffers-arbfp-no-option

Signed-off-by: Alex Deucher <alexdeuc...@gmail.com>

---

 src/gallium/drivers/r600/evergreen_state.c   |    6 ++-
 src/gallium/drivers/r600/r600_asm.c          |    2 +
 src/gallium/drivers/r600/r600_pipe.h         |    1 +
 src/gallium/drivers/r600/r600_shader.c       |   77 ++++++++++++++++---------
 src/gallium/drivers/r600/r600_shader.h       |    1 +
 src/gallium/drivers/r600/r600_state_common.c |    4 +-
 6 files changed, 61 insertions(+), 30 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index dfe7896..dc18261 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -885,6 +885,7 @@ static void evergreen_set_framebuffer_state(struct 
pipe_context *ctx,
 
        /* build states */
        rctx->have_depth_fb = 0;
+       rctx->nr_cbufs = state->nr_cbufs;
        for (int i = 0; i < state->nr_cbufs; i++) {
                evergreen_cb(rctx, rstate, state, i);
        }
@@ -1631,7 +1632,10 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, 
struct r600_pipe_shader
                    rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
                        exports_ps |= 1;
                else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) {
-                       num_cout++;
+                       if (rshader->fs_write_all)
+                               num_cout = rshader->nr_cbufs;
+                       else
+                               num_cout++;
                }
        }
        exports_ps |= S_02884C_EXPORT_COLORS(num_cout);
diff --git a/src/gallium/drivers/r600/r600_asm.c 
b/src/gallium/drivers/r600/r600_asm.c
index c447a03..065f955 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -1863,6 +1863,8 @@ void r600_bc_dump(struct r600_bc *bc)
                        break;
                case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
                case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+               case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+               case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
                        fprintf(stderr, "%04d %08X EXPORT ", id, 
bc->bytecode[id]);
                        fprintf(stderr, "GPR:%X ", cf->output.gpr);
                        fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size);
diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index dc9aad0..2667c80 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -213,6 +213,7 @@ struct r600_pipe_context {
        boolean                         export_16bpc;
        unsigned                        alpha_ref;
        boolean                         alpha_ref_dirty;
+       unsigned                        nr_cbufs;
        struct r600_textures_info       ps_samplers;
 
        struct r600_pipe_fences         fences;
diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 2e5d4a6..f83d707 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -606,7 +606,7 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * 
rctx, struct r600_pi
        struct r600_bc_output output[32];
        unsigned output_done, noutput;
        unsigned opcode;
-       int i, r = 0, pos0;
+       int i, j, r = 0, pos0;
 
        ctx.bc = &shader->bc;
        ctx.shader = shader;
@@ -623,6 +623,8 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * 
rctx, struct r600_pi
        shader->clamp_color = (((ctx.type == TGSI_PROCESSOR_FRAGMENT) && 
rctx->clamp_fragment_color) ||
                ((ctx.type == TGSI_PROCESSOR_VERTEX) && 
rctx->clamp_vertex_color));
 
+       shader->nr_cbufs = rctx->nr_cbufs;
+
        /* register allocations */
        /* Values [0,127] correspond to GPR[0..127].
         * Values [128,159] correspond to constant buffer bank 0
@@ -767,50 +769,68 @@ static int r600_shader_from_tgsi(struct r600_pipe_context 
* rctx, struct r600_pi
        }
 
        /* export output */
+       j = 0;
        for (i = 0, pos0 = 0; i < noutput; i++) {
                memset(&output[i], 0, sizeof(struct r600_bc_output));
-               output[i].gpr = shader->output[i].gpr;
-               output[i].elem_size = 3;
-               output[i].swizzle_x = 0;
-               output[i].swizzle_y = 1;
-               output[i].swizzle_z = 2;
-               output[i].swizzle_w = 3;
-               output[i].burst_count = 1;
-               output[i].barrier = 1;
-               output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
-               output[i].array_base = i - pos0;
-               output[i].inst = BC_INST(ctx.bc, 
V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
+               output[i + j].gpr = shader->output[i].gpr;
+               output[i + j].elem_size = 3;
+               output[i + j].swizzle_x = 0;
+               output[i + j].swizzle_y = 1;
+               output[i + j].swizzle_z = 2;
+               output[i + j].swizzle_w = 3;
+               output[i + j].burst_count = 1;
+               output[i + j].barrier = 1;
+               output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+               output[i + j].array_base = i - pos0;
+               output[i + j].inst = BC_INST(ctx.bc, 
V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
                switch (ctx.type) {
                case TGSI_PROCESSOR_VERTEX:
                        if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
-                               output[i].array_base = 60;
-                               output[i].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+                               output[i + j].array_base = 60;
+                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
                                /* position doesn't count in array_base */
                                pos0++;
                        }
                        if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) {
-                               output[i].array_base = 61;
-                               output[i].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+                               output[i + j].array_base = 61;
+                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
                                /* position doesn't count in array_base */
                                pos0++;
                        }
                        break;
                case TGSI_PROCESSOR_FRAGMENT:
                        if (shader->output[i].name == TGSI_SEMANTIC_COLOR) {
-                               output[i].array_base = shader->output[i].sid;
-                               output[i].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+                               output[i + j].array_base = 
shader->output[i].sid;
+                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+                               if (shader->fs_write_all && (shader->family >= 
CHIP_CEDAR)) {
+                                       for (j = 1; j < shader->nr_cbufs; j++) {
+                                               memset(&output[i + j], 0, 
sizeof(struct r600_bc_output));
+                                               output[i + j].gpr = 
shader->output[i].gpr;
+                                               output[i + j].elem_size = 3;
+                                               output[i + j].swizzle_x = 0;
+                                               output[i + j].swizzle_y = 1;
+                                               output[i + j].swizzle_z = 2;
+                                               output[i + j].swizzle_w = 3;
+                                               output[i + j].burst_count = 1;
+                                               output[i + j].barrier = 1;
+                                               output[i + j].array_base = 
shader->output[i].sid + j;
+                                               output[i + j].inst = 
BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
+                                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+                                       }
+                                       j--;
+                               }
                        } else if (shader->output[i].name == 
TGSI_SEMANTIC_POSITION) {
-                               output[i].array_base = 61;
-                               output[i].swizzle_x = 2;
-                               output[i].swizzle_y = 7;
-                               output[i].swizzle_z = output[i].swizzle_w = 7;
-                               output[i].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+                               output[i + j].array_base = 61;
+                               output[i + j].swizzle_x = 2;
+                               output[i + j].swizzle_y = 7;
+                               output[i + j].swizzle_z = output[i + 
j].swizzle_w = 7;
+                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
                        } else if (shader->output[i].name == 
TGSI_SEMANTIC_STENCIL) {
-                               output[i].array_base = 61;
-                               output[i].swizzle_x = 7;
-                               output[i].swizzle_y = 1;
-                               output[i].swizzle_z = output[i].swizzle_w = 7;
-                               output[i].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+                               output[i + j].array_base = 61;
+                               output[i + j].swizzle_x = 7;
+                               output[i + j].swizzle_y = 1;
+                               output[i + j].swizzle_z = output[i + 
j].swizzle_w = 7;
+                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
                        } else {
                                R600_ERR("unsupported fragment output name 
%d\n", shader->output[i].name);
                                r = -EINVAL;
@@ -823,6 +843,7 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * 
rctx, struct r600_pi
                        goto out_err;
                }
        }
+       noutput += j;
        /* add fake param output for vertex shader if no param is exported */
        if (ctx.type == TGSI_PROCESSOR_VERTEX) {
                for (i = 0, pos0 = 0; i < noutput; i++) {
diff --git a/src/gallium/drivers/r600/r600_shader.h 
b/src/gallium/drivers/r600/r600_shader.h
index c1e00f3..76aebf2 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -47,6 +47,7 @@ struct r600_shader {
        boolean                 uses_kill;
        boolean                 fs_write_all;
        boolean                 clamp_color;
+       unsigned                nr_cbufs;
 };
 
 #endif
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index f1b0fc3..bf4e90e 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -599,7 +599,9 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct 
pipe_draw_info *info)
        if (rctx->vs_shader->shader.clamp_color != rctx->clamp_vertex_color)
                r600_shader_rebuild(ctx, rctx->vs_shader);
 
-       if (rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color)
+       if ((rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color) 
||
+           (rctx->ps_shader->shader.fs_write_all &&
+            (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs)))
                r600_shader_rebuild(ctx, rctx->ps_shader);
 
        if (rctx->spi_dirty)

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to