diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 96 |
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 */ |