r600g: fix TXD src regs needing fetching.
authorMike Kaplinskiy <mike.kaplinskiy@gmail.com>
Wed, 15 Jun 2011 06:56:10 +0000 (16:56 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 15 Jun 2011 06:58:40 +0000 (16:58 +1000)
[airlied: final chunk of Mike's patch from bug 37476
this uses a loop to emit the GRADIENTS and does a check to
see if we need to fetch to a temporary register. It also
increases the context src gpr to 4 which is needed here.]

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/r600_shader.c

index 0eb776c33586ffbc8779f7904c11b19d1ba22eb8..b8a86b031438a697a0e7ef9fc3818b40b904d521 100644 (file)
@@ -186,7 +186,7 @@ struct r600_shader_ctx {
        struct r600_shader_tgsi_instruction     *inst_info;
        struct r600_bc                          *bc;
        struct r600_shader                      *shader;
-       struct r600_shader_src                  src[3];
+       struct r600_shader_src                  src[4];
        u32                                     *literals;
        u32                                     nliterals;
        u32                                     max_driver_temp_used;
@@ -1768,7 +1768,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
        struct r600_bc_tex tex;
        struct r600_bc_alu alu;
        unsigned src_gpr;
-       int r, i;
+       int r, i, j;
        int opcode;
        /* Texture fetch instructions can only use gprs as source.
         * Also they cannot negate the source or take the absolute value */
@@ -1782,51 +1782,55 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
                /* TGSI moves the sampler to src reg 3 for TXD */
                sampler_src_reg = 3;
 
-               /* set gradients h/v */
-               memset(&tex, 0, sizeof(struct r600_bc_tex));
-               tex.inst = SQ_TEX_INST_SET_GRADIENTS_H;
-               tex.sampler_id = tgsi_tex_get_src_gpr(ctx, sampler_src_reg);
-               tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
-               tex.src_gpr = tgsi_tex_get_src_gpr(ctx, 1);
-               tex.src_sel_x = ctx->src[1].swizzle[0];
-               tex.src_sel_y = ctx->src[1].swizzle[1];
-               tex.src_sel_z = ctx->src[1].swizzle[2];
-               tex.src_sel_w = ctx->src[1].swizzle[3];
-               tex.src_rel = ctx->src[1].rel;
-               tex.dst_gpr = ctx->temp_reg; /* just to avoid confusing the asm scheduler */
-               tex.dst_sel_x = tex.dst_sel_y = tex.dst_sel_z = tex.dst_sel_w = 7;
-               if (inst->Texture.Texture != TGSI_TEXTURE_RECT) {
-                       tex.coord_type_x = 1;
-                       tex.coord_type_y = 1;
-                       tex.coord_type_z = 1;
-                       tex.coord_type_w = 1;
-               }
-               r = r600_bc_add_tex(ctx->bc, &tex);
-               if (r)
-                       return r;
+               for (i = 1; i < 3; i++) {
+                       /* set gradients h/v */
+                       memset(&tex, 0, sizeof(struct r600_bc_tex));
+                       tex.inst = (i == 1) ? SQ_TEX_INST_SET_GRADIENTS_H :
+                               SQ_TEX_INST_SET_GRADIENTS_V;
+                       tex.sampler_id = tgsi_tex_get_src_gpr(ctx, sampler_src_reg);
+                       tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
+
+                       if (tgsi_tex_src_requires_loading(ctx, i)) {
+                               tex.src_gpr = r600_get_temp(ctx);
+                               tex.src_sel_x = 0;
+                               tex.src_sel_y = 1;
+                               tex.src_sel_z = 2;
+                               tex.src_sel_w = 3;
+
+                               for (j = 0; j < 4; j++) {
+                                       memset(&alu, 0, sizeof(struct r600_bc_alu));
+                                       alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
+                                        r600_bc_src(&alu.src[0], &ctx->src[i], j);
+                                        alu.dst.sel = tex.src_gpr;
+                                        alu.dst.chan = j;
+                                        if (j == 3)
+                                                alu.last = 1;
+                                        alu.dst.write = 1;
+                                        r = r600_bc_add_alu(ctx->bc, &alu);
+                                        if (r)
+                                                return r;
+                               }
 
-               /* set gradients h/v */
-               memset(&tex, 0, sizeof(struct r600_bc_tex));
-               tex.inst = SQ_TEX_INST_SET_GRADIENTS_V;
-               tex.sampler_id = tgsi_tex_get_src_gpr(ctx, sampler_src_reg);
-               tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
-               tex.src_gpr = tgsi_tex_get_src_gpr(ctx, 2);
-               tex.src_sel_x = ctx->src[2].swizzle[0];
-               tex.src_sel_y = ctx->src[2].swizzle[1];
-               tex.src_sel_z = ctx->src[2].swizzle[2];
-               tex.src_sel_w = ctx->src[2].swizzle[3];
-               tex.src_rel = ctx->src[2].rel;
-               tex.dst_gpr = ctx->temp_reg; /* just to avoid confusing the asm scheduler */
-               tex.dst_sel_x = tex.dst_sel_y = tex.dst_sel_z = tex.dst_sel_w = 7;
-               if (inst->Texture.Texture != TGSI_TEXTURE_RECT) {
-                       tex.coord_type_x = 1;
-                       tex.coord_type_y = 1;
-                       tex.coord_type_z = 1;
-                       tex.coord_type_w = 1;
-               }
-               r = r600_bc_add_tex(ctx->bc, &tex);
-               if (r)
-                       return r;
+                       } else {
+                               tex.src_gpr = tgsi_tex_get_src_gpr(ctx, i);
+                               tex.src_sel_x = ctx->src[i].swizzle[0];
+                               tex.src_sel_y = ctx->src[i].swizzle[1];
+                               tex.src_sel_z = ctx->src[i].swizzle[2];
+                               tex.src_sel_w = ctx->src[i].swizzle[3];
+                               tex.src_rel = ctx->src[i].rel;
+                       }
+                       tex.dst_gpr = ctx->temp_reg; /* just to avoid confusing the asm scheduler */
+                       tex.dst_sel_x = tex.dst_sel_y = tex.dst_sel_z = tex.dst_sel_w = 7;
+                       if (inst->Texture.Texture != TGSI_TEXTURE_RECT) {
+                               tex.coord_type_x = 1;
+                               tex.coord_type_y = 1;
+                               tex.coord_type_z = 1;
+                               tex.coord_type_w = 1;
+                       }
+                       r = r600_bc_add_tex(ctx->bc, &tex);
+                       if (r)
+                               return r;
+               }
        } else if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
                int out_chan;
                /* Add perspective divide */