diff options
author | Roland Scheidegger <[email protected]> | 2012-11-27 03:26:49 +0100 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2012-11-27 03:26:49 +0100 |
commit | 0b6554ba6f2aa8a771852566340c24205e406d02 (patch) | |
tree | 4860b057589b29b85a70fb8666537dfa51f10afa /src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | |
parent | 93c689a2dfa29cf3a4647432f0690bf76514b5bd (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.c | 115 |
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); |