summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2014-03-03 18:29:39 +0100
committerMarek Olšák <[email protected]>2014-03-07 18:07:05 +0100
commit8a08051e2a7227061300e344a4e41a1cdf2d6145 (patch)
tree585b2cd437383e6bd27248708ade0b5200a38d61 /src/gallium/drivers
parent67aef6dafa29fed008ea6065c425a6a92a651be9 (diff)
r600g: fix texelFetchOffset GLSL functions
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/r600_shader.c87
1 files changed, 77 insertions, 10 deletions
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index fabadd80e62..0016d29a2a8 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -4402,11 +4402,16 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
(inst->Texture.Texture == TGSI_TEXTURE_2D_MSAA ||
inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA);
+ bool txf_add_offsets = inst->Texture.NumOffsets &&
+ inst->Instruction.Opcode == TGSI_OPCODE_TXF &&
+ inst->Texture.Texture != TGSI_TEXTURE_BUFFER;
+
/* Texture fetch instructions can only use gprs as source.
* Also they cannot negate the source or take the absolute value */
const boolean src_requires_loading = (inst->Instruction.Opcode != TGSI_OPCODE_TXQ_LZ &&
tgsi_tex_src_requires_loading(ctx, 0)) ||
- read_compressed_msaa;
+ read_compressed_msaa || txf_add_offsets;
+
boolean src_loaded = FALSE;
unsigned sampler_src_reg = inst->Instruction.Opcode == TGSI_OPCODE_TXQ_LZ ? 0 : 1;
int8_t offset_x = 0, offset_y = 0, offset_z = 0;
@@ -4439,15 +4444,6 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
}
}
- /* get offset values */
- if (inst->Texture.NumOffsets) {
- assert(inst->Texture.NumOffsets == 1);
-
- offset_x = ctx->literals[4 * inst->TexOffsets[0].Index + inst->TexOffsets[0].SwizzleX] << 1;
- offset_y = ctx->literals[4 * inst->TexOffsets[0].Index + inst->TexOffsets[0].SwizzleY] << 1;
- offset_z = ctx->literals[4 * inst->TexOffsets[0].Index + inst->TexOffsets[0].SwizzleZ] << 1;
- }
-
if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
/* TGSI moves the sampler to src reg 3 for TXD */
sampler_src_reg = 3;
@@ -4800,6 +4796,77 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
src_gpr = ctx->temp_reg;
}
+ /* get offset values */
+ if (inst->Texture.NumOffsets) {
+ assert(inst->Texture.NumOffsets == 1);
+
+ if (txf_add_offsets) {
+ /* Add the offsets for texelFetch manually. */
+ const struct tgsi_texture_offset *off = inst->TexOffsets;
+
+ switch (inst->Texture.Texture) {
+ case TGSI_TEXTURE_3D:
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP2_ADD_INT;
+ alu.src[0].sel = src_gpr;
+ alu.src[0].chan = 2;
+ alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.src[1].value = ctx->literals[4 * off[0].Index + off[0].SwizzleZ];
+ alu.dst.sel = src_gpr;
+ alu.dst.chan = 2;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ /* fall through */
+
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOWRECT:
+ case TGSI_TEXTURE_2D_ARRAY:
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP2_ADD_INT;
+ alu.src[0].sel = src_gpr;
+ alu.src[0].chan = 1;
+ alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.src[1].value = ctx->literals[4 * off[0].Index + off[0].SwizzleY];
+ alu.dst.sel = src_gpr;
+ alu.dst.chan = 1;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ /* fall through */
+
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_1D_ARRAY:
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP2_ADD_INT;
+ alu.src[0].sel = src_gpr;
+ alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.src[1].value = ctx->literals[4 * off[0].Index + off[0].SwizzleX];
+ alu.dst.sel = src_gpr;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ break;
+ /* texture offsets do not apply to other texture targets */
+ }
+ } else {
+ offset_x = ctx->literals[4 * inst->TexOffsets[0].Index + inst->TexOffsets[0].SwizzleX] << 1;
+ offset_y = ctx->literals[4 * inst->TexOffsets[0].Index + inst->TexOffsets[0].SwizzleY] << 1;
+ offset_z = ctx->literals[4 * inst->TexOffsets[0].Index + inst->TexOffsets[0].SwizzleZ] << 1;
+ }
+ }
+
/* Obtain the sample index for reading a compressed MSAA color texture.
* To read the FMASK, we use the ldfptr instruction, which tells us
* where the samples are stored.