summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/r600/r600_shader.c96
1 files changed, 50 insertions, 46 deletions
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 0eb776c3358..b8a86b03143 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -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 */