r600g: fix TXD src regs needing fetching.

[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>
This commit is contained in:
Mike Kaplinskiy
2011-06-15 16:56:10 +10:00
committed by Dave Airlie
parent 6415f25663
commit 40aec11b75
+49 -45
View 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;
/* 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;
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;
}
} 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;
}
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 */