r600g: add TXD support.
authorDave Airlie <airlied@redhat.com>
Wed, 15 Jun 2011 05:15:41 +0000 (15:15 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 15 Jun 2011 05:18:42 +0000 (15:18 +1000)
This at least passes the piglit arb_shader_texture_lod-texgrad test,
the AMD shader analyzer seems to multiply the V component by an unspecified
constant value no idea why.

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

index aeb1175958c2370a91307d0f5f164a9144fc303e..c447a03106326b9b59b39e207f085f852eacbf43 100644 (file)
@@ -1383,6 +1383,9 @@ int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex)
                                break;
                        }
                }
+               /* slight hack to make gradients always go into same cf */
+               if (ntex->inst == SQ_TEX_INST_SET_GRADIENTS_H)
+                       bc->force_add_cf = 1;
        }
 
        /* cf can contains only alu or only vtx or only tex */
index 4cf11dc9ff2f86f926ef86ddb9026a42bfa3d4ed..16fe6c54a15380312fe693440b3954f4b15c4186 100644 (file)
@@ -375,6 +375,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+       case PIPE_CAP_SM3:
                return 1;
 
        /* Supported except the original R600. */
@@ -395,7 +396,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_TGSI_INSTANCEID:
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
-       case PIPE_CAP_SM3:
                return 0;
 
        case PIPE_CAP_ARRAY_TEXTURES:
index 1b9f66318e14363bdd4478e43fe3b5521be87b89..9a0df2305b9128606d7f624cfceb59c271f42d28 100644 (file)
@@ -1761,10 +1761,60 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
                inst->Src[0].Register.File != TGSI_FILE_INPUT) ||
                ctx->src[0].neg || ctx->src[0].abs;
        boolean src_loaded = FALSE;
+       unsigned sampler_src_reg = 1;
 
        src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index;
 
-       if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
+       if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
+               /* 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 = ctx->file_offset[inst->Src[sampler_src_reg].Register.File] + inst->Src[sampler_src_reg].Register.Index;
+               tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
+               tex.src_gpr = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index;
+               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;
+
+               /* set gradients h/v */
+               memset(&tex, 0, sizeof(struct r600_bc_tex));
+               tex.inst = SQ_TEX_INST_SET_GRADIENTS_V;
+               tex.sampler_id = ctx->file_offset[inst->Src[sampler_src_reg].Register.File] + inst->Src[sampler_src_reg].Register.Index;
+               tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
+               tex.src_gpr = ctx->file_offset[inst->Src[2].Register.File] + inst->Src[2].Register.Index;
+               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 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
                int out_chan;
                /* Add perspective divide */
                if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
@@ -1957,7 +2007,8 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 
        memset(&tex, 0, sizeof(struct r600_bc_tex));
        tex.inst = opcode;
-       tex.sampler_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index;
+       
+       tex.sampler_id = ctx->file_offset[inst->Src[sampler_src_reg].Register.File] + inst->Src[sampler_src_reg].Register.Index;
        tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS;
        tex.src_gpr = src_gpr;
        tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index;
@@ -3082,7 +3133,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
        {TGSI_OPCODE_SNE,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2},
        {TGSI_OPCODE_STR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
        {TGSI_OPCODE_TEX,       0, SQ_TEX_INST_SAMPLE, tgsi_tex},
-       {TGSI_OPCODE_TXD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXD,       0, SQ_TEX_INST_SAMPLE_G, tgsi_tex},
        {TGSI_OPCODE_TXP,       0, SQ_TEX_INST_SAMPLE, tgsi_tex},
        {TGSI_OPCODE_UP2H,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
        {TGSI_OPCODE_UP2US,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
@@ -3240,7 +3291,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = {
        {TGSI_OPCODE_SNE,       0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2},
        {TGSI_OPCODE_STR,       0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
        {TGSI_OPCODE_TEX,       0, SQ_TEX_INST_SAMPLE, tgsi_tex},
-       {TGSI_OPCODE_TXD,       0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXD,       0, SQ_TEX_INST_SAMPLE_G, tgsi_tex},
        {TGSI_OPCODE_TXP,       0, SQ_TEX_INST_SAMPLE, tgsi_tex},
        {TGSI_OPCODE_UP2H,      0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
        {TGSI_OPCODE_UP2US,     0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
@@ -3398,7 +3449,7 @@ static struct r600_shader_tgsi_instruction cm_shader_tgsi_instruction[] = {
        {TGSI_OPCODE_SNE,       0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2},
        {TGSI_OPCODE_STR,       0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
        {TGSI_OPCODE_TEX,       0, SQ_TEX_INST_SAMPLE, tgsi_tex},
-       {TGSI_OPCODE_TXD,       0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXD,       0, SQ_TEX_INST_SAMPLE_G, tgsi_tex},
        {TGSI_OPCODE_TXP,       0, SQ_TEX_INST_SAMPLE, tgsi_tex},
        {TGSI_OPCODE_UP2H,      0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
        {TGSI_OPCODE_UP2US,     0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
index 9281b08bd82073996a269fb421af90e6cf730c5a..95672b13ba02e33781a48810e155e6f3d5d05128 100644 (file)
 
 #define SQ_TEX_INST_SAMPLE 0x10
 #define SQ_TEX_INST_SAMPLE_L 0x11
+#define SQ_TEX_INST_SAMPLE_G 0x14
 #define SQ_TEX_INST_SAMPLE_C 0x18
 
+#define SQ_TEX_INST_SET_GRADIENTS_H 0xB
+#define SQ_TEX_INST_SET_GRADIENTS_V 0xC
+
 #endif