From: Dave Airlie <airl...@redhat.com>

This writes the VS shaders outputs to the LDS memory in
the correct places.

Signed-off-by: Dave Airlie <airl...@redhat.com>
---
 src/gallium/drivers/r600/r600_shader.c | 76 +++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 69675b2..ee83114 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -2385,6 +2385,71 @@ static int r600_fetch_tess_io_info(struct 
r600_shader_ctx *ctx)
        return 0;
 }
 
+static int emit_lds_vs_writes(struct r600_shader_ctx *ctx)
+{
+       int i, j, r;
+       int temp_reg;
+
+       /* fetch tcs input values into input_vals */
+       ctx->tess_input_info = r600_get_temp(ctx);
+       ctx->tess_output_info = 0;
+       r = r600_fetch_tess_io_info(ctx);
+       if (r)
+               return r;
+
+       temp_reg = r600_get_temp(ctx);
+       /* dst reg contains LDS address stride * idx */
+       /* MUL vertexID, vertex_dw_stride */
+       r = single_alu_op2(ctx, ALU_OP2_MULLO_INT,
+                          temp_reg, 0,
+                          ctx->tess_input_info, 1,
+                          0, 1); /* rel id in r0.y? */
+       if (r)
+               return r;
+
+       for (i = 0; i < ctx->shader->noutput; i++) {
+               struct r600_bytecode_alu alu;
+               int param = 
r600_get_lds_unique_index(ctx->shader->output[i].name, 
ctx->shader->output[i].sid);
+
+               if (param) {
+                       r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+                                          temp_reg, 1,
+                                          temp_reg, 0,
+                                          V_SQ_ALU_SRC_LITERAL, param * 16);
+                       if (r)
+                               return r;
+               }
+
+               r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+                                  temp_reg, 2,
+                                  temp_reg, param ? 1 : 0,
+                                  V_SQ_ALU_SRC_LITERAL, 8);
+               if (r)
+                       return r;
+
+
+               for (j = 0; j < 2; j++) {
+                       int chan = (j == 1) ? 2 : (param ? 1 : 0);
+                       memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+                       alu.op = LDS_OP3_LDS_WRITE_REL;
+                       alu.src[0].sel = temp_reg;
+                       alu.src[0].chan = chan;
+                       alu.src[1].sel = ctx->shader->output[i].gpr;
+                       alu.src[1].chan = j * 2;
+                       alu.src[2].sel = ctx->shader->output[i].gpr;
+                       alu.src[2].chan = (j * 2) + 1;
+                       alu.last = 1;
+                       alu.dst.chan = 0;
+                       alu.lds_idx = 1;
+                       alu.is_lds_idx_op = true;
+                       r = r600_bytecode_add_alu(ctx->bc, &alu);
+                       if (r)
+                               return r;
+               }
+       }
+       return 0;
+}
+
 static int r600_shader_from_tgsi(struct r600_context *rctx,
                                 struct r600_pipe_shader *pipeshader,
                                 union r600_shader_key key)
@@ -2405,6 +2470,7 @@ static int r600_shader_from_tgsi(struct r600_context 
*rctx,
        bool use_llvm = false;
        bool indirect_gprs;
        bool ring_outputs = false;
+       bool lds_outputs = false;
        bool lds_inputs = false;
        bool pos_emitted = false;
 
@@ -2437,12 +2503,15 @@ static int r600_shader_from_tgsi(struct r600_context 
*rctx,
                shader->vs_as_ls = key.vs.as_ls;
                if (shader->vs_as_es)
                        ring_outputs = true;
+               if (shader->vs_as_ls)
+                       lds_outputs = true;
                break;
        case TGSI_PROCESSOR_GEOMETRY:
                ring_outputs = true;
                break;
        case TGSI_PROCESSOR_TESS_CTRL:
                shader->tcs_prim_mode = key.tcs.prim_mode;
+               lds_outputs = true;
                lds_inputs = true;
                break;
        case TGSI_PROCESSOR_TESS_EVAL:
@@ -2882,7 +2951,12 @@ static int r600_shader_from_tgsi(struct r600_context 
*rctx,
        pipeshader->enabled_stream_buffers_mask = 
ctx.enabled_stream_buffers_mask;
        convert_edgeflag_to_int(&ctx);
 
-       if (ring_outputs) {
+       if (lds_outputs) {
+               if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+                       if (ctx.shader->noutput)
+                               emit_lds_vs_writes(&ctx);
+               }
+       } else if (ring_outputs) {
                if (shader->vs_as_es || shader->tes_as_es) {
                        ctx.gs_export_gpr_tregs[0] = r600_get_temp(&ctx);
                        ctx.gs_export_gpr_tregs[1] = -1;
-- 
2.5.0

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

Reply via email to