aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2012-11-27 03:26:49 +0100
committerRoland Scheidegger <[email protected]>2012-11-27 03:26:49 +0100
commit0b6554ba6f2aa8a771852566340c24205e406d02 (patch)
tree4860b057589b29b85a70fb8666537dfa51f10afa /src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
parent93c689a2dfa29cf3a4647432f0690bf76514b5bd (diff)
gallivm,llvmpipe: handle TXF (texelFetch) instruction, including offsets
This also adds some code to handle per-quad lods for more than 4-wide fetches, because otherwise I'd have to integrate the texelFetch function into the splitting stuff... (but it is not used yet outside texelFetch). passes piglit fs-texelFetch-2D, fails fs-texelFetchOffset-2D due to I believe a test error (results are undefined for out-of-bounds fetches, we return whatever is at offset 0, whereas the test expects [0,0,0,1]). Texel offsets are only handled by texelFetch for now, though the interface can handle it for everything. Reviewed-by: José Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c115
1 files changed, 112 insertions, 3 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 85a4401b534..2afdd3027e0 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -1146,7 +1146,8 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
unsigned unit;
LLVMValueRef lod_bias, explicit_lod;
LLVMValueRef oow = NULL;
- LLVMValueRef coords[3];
+ LLVMValueRef coords[4];
+ LLVMValueRef offsets[3] = { NULL };
struct lp_derivatives derivs;
unsigned num_coords;
unsigned dims;
@@ -1225,7 +1226,7 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED)
coords[i] = lp_build_mul(&bld->bld_base.base, coords[i], oow);
}
- for (i = num_coords; i < 3; i++) {
+ for (i = num_coords; i < 4; i++) {
coords[i] = bld->bld_base.base.undef;
}
@@ -1285,16 +1286,112 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
unit = inst->Src[1].Register.Index;
}
+ /* some advanced gather instructions (txgo) would require 4 offsets */
+ if (inst->Texture.NumOffsets == 1) {
+ unsigned dim;
+ for (dim = 0; dim < dims; dim++) {
+ offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim );
+ }
+ }
+
bld->sampler->emit_fetch_texel(bld->sampler,
bld->bld_base.base.gallivm,
bld->bld_base.base.type,
- unit, num_coords, coords,
+ FALSE,
+ unit, coords,
+ offsets,
&derivs,
lod_bias, explicit_lod,
texel);
}
static void
+emit_txf( struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_instruction *inst,
+ LLVMValueRef *texel)
+{
+ unsigned unit;
+ LLVMValueRef coord_undef = LLVMGetUndef(bld->bld_base.base.int_vec_type);
+ LLVMValueRef explicit_lod = NULL;
+ LLVMValueRef coords[3];
+ LLVMValueRef offsets[3] = { NULL };
+ struct lp_derivatives derivs;
+ unsigned num_coords;
+ unsigned dims;
+ unsigned i;
+
+ if (!bld->sampler) {
+ _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
+ for (i = 0; i < 4; i++) {
+ texel[i] = coord_undef;
+ }
+ return;
+ }
+
+ derivs.ddx_ddy[0] = coord_undef;
+ derivs.ddx_ddy[1] = coord_undef;
+
+ switch (inst->Texture.Texture) {
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_BUFFER:
+ num_coords = 1;
+ dims = 1;
+ break;
+ case TGSI_TEXTURE_1D_ARRAY:
+ num_coords = 2;
+ dims = 1;
+ break;
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_RECT:
+ num_coords = 2;
+ dims = 2;
+ break;
+ case TGSI_TEXTURE_2D_ARRAY:
+ num_coords = 3;
+ dims = 2;
+ break;
+ case TGSI_TEXTURE_3D:
+ num_coords = 3;
+ dims = 3;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ /* always have lod except for buffers ? */
+ if (inst->Texture.Texture != TGSI_TEXTURE_BUFFER) {
+ explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 );
+ }
+
+ for (i = 0; i < num_coords; i++) {
+ coords[i] = lp_build_emit_fetch( &bld->bld_base, inst, 0, i );
+ }
+ for (i = num_coords; i < 3; i++) {
+ coords[i] = coord_undef;
+ }
+
+ unit = inst->Src[1].Register.Index;
+
+ if (inst->Texture.NumOffsets == 1) {
+ unsigned dim;
+ for (dim = 0; dim < dims; dim++) {
+ offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim );
+ }
+ }
+
+ bld->sampler->emit_fetch_texel(bld->sampler,
+ bld->bld_base.base.gallivm,
+ bld->bld_base.base.type,
+ TRUE,
+ unit, coords,
+ offsets,
+ &derivs,
+ NULL, explicit_lod,
+ texel);
+}
+
+static void
emit_txq( struct lp_build_tgsi_soa_context *bld,
const struct tgsi_full_instruction *inst,
LLVMValueRef *sizes_out)
@@ -1756,6 +1853,17 @@ txq_emit(
}
static void
+txf_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
+
+ emit_txf(bld, emit_data->inst, emit_data->output);
+}
+
+static void
cal_emit(
const struct lp_build_tgsi_action * action,
struct lp_build_tgsi_context * bld_base,
@@ -2126,6 +2234,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
bld.bld_base.op_actions[TGSI_OPCODE_TXL].emit = txl_emit;
bld.bld_base.op_actions[TGSI_OPCODE_TXP].emit = txp_emit;
bld.bld_base.op_actions[TGSI_OPCODE_TXQ].emit = txq_emit;
+ bld.bld_base.op_actions[TGSI_OPCODE_TXF].emit = txf_emit;
lp_exec_mask_init(&bld.exec_mask, &bld.bld_base.base);