diff options
author | Roland Scheidegger <[email protected]> | 2013-02-05 13:37:57 -0800 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2013-02-08 18:54:40 -0800 |
commit | 614982d320985c04e247293b54b66d7df5c19004 (patch) | |
tree | 53a17cb7593ba82d1140bd218a7f192606cf332a /src/gallium/auxiliary/gallivm | |
parent | 0a8043bb766f9c38af559438b646c3659614b103 (diff) |
gallivm: fix up size queries for dx10 sviewinfo opcode
Need to calculate the number of mip levels (if it would be worthwile could
store it in dynamic state).
While here, the query code also used chan 2 for the lod value.
This worked with mesa state tracker but it seems safer to use chan 0.
Still passes piglit textureSize (with some handwaving), though the non-GL
parts are (largely) untested.
v2: clarify and expect the sviewinfo opcode to return ints, not floats,
just like the OpenGL textureSize (dx10 supports dst modifiers with resinfo).
Also simplify some code.
Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/gallivm')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 64 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 66 |
4 files changed, 58 insertions, 74 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 77ce00869be..f5022167123 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -487,6 +487,7 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, struct lp_sampler_dynamic_state *dynamic_state, struct lp_type int_type, unsigned texture_unit, + boolean need_nr_mips, LLVMValueRef explicit_lod, LLVMValueRef *sizes_out); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 778400af5f0..c5b48b52da3 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -1742,39 +1742,27 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, struct lp_sampler_dynamic_state *dynamic_state, struct lp_type int_type, unsigned texture_unit, + boolean need_nr_mips, LLVMValueRef explicit_lod, LLVMValueRef *sizes_out) { LLVMValueRef lod; LLVMValueRef size; + LLVMValueRef first_level = NULL; int dims, i; - boolean has_array = FALSE; + boolean has_array; struct lp_build_context bld_int_vec; + dims = texture_dims(static_state->target); + switch (static_state->target) { - case PIPE_TEXTURE_1D: - case PIPE_BUFFER: - dims = 1; - break; case PIPE_TEXTURE_1D_ARRAY: - dims = 1; - has_array = TRUE; - break; - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_CUBE: - case PIPE_TEXTURE_RECT: - dims = 2; - break; - case PIPE_TEXTURE_3D: - dims = 3; - break; case PIPE_TEXTURE_2D_ARRAY: - dims = 2; has_array = TRUE; break; default: - assert(0); - return; + has_array = FALSE; + break; } assert(!int_type.floating); @@ -1782,7 +1770,6 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32, 128)); if (explicit_lod) { - LLVMValueRef first_level; lod = LLVMBuildExtractElement(gallivm->builder, explicit_lod, lp_build_const_int32(gallivm, 0), ""); first_level = dynamic_state->first_level(dynamic_state, gallivm, texture_unit); lod = lp_build_broadcast_scalar(&bld_int_vec, @@ -1792,7 +1779,12 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, lod = bld_int_vec.zero; } - size = bld_int_vec.undef; + if (need_nr_mips) { + size = bld_int_vec.zero; + } + else { + size = bld_int_vec.undef; + } size = LLVMBuildInsertElement(gallivm->builder, size, dynamic_state->width(dynamic_state, gallivm, texture_unit), @@ -1811,15 +1803,43 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, } size = lp_build_minify(&bld_int_vec, size, lod); - + if (has_array) size = LLVMBuildInsertElement(gallivm->builder, size, dynamic_state->depth(dynamic_state, gallivm, texture_unit), lp_build_const_int32(gallivm, dims), ""); + /* + * XXX for out-of-bounds lod, should set size to zero vector here + * (for dx10-style only, i.e. need_nr_mips) + */ + for (i = 0; i < dims + (has_array ? 1 : 0); i++) { sizes_out[i] = lp_build_extract_broadcast(gallivm, bld_int_vec.type, int_type, size, lp_build_const_int32(gallivm, i)); } + + /* + * if there's no explicit_lod (buffers, rects) queries requiring nr of + * mips would be illegal. + */ + if (need_nr_mips && explicit_lod) { + struct lp_build_context bld_int_scalar; + LLVMValueRef num_levels; + lp_build_context_init(&bld_int_scalar, gallivm, lp_type_int(32)); + + if (static_state->level_zero_only) { + num_levels = bld_int_scalar.one; + } + else { + LLVMValueRef last_level; + + last_level = dynamic_state->last_level(dynamic_state, gallivm, texture_unit); + num_levels = lp_build_sub(&bld_int_scalar, last_level, first_level); + num_levels = lp_build_add(&bld_int_scalar, num_levels, bld_int_scalar.one); + } + sizes_out[3] = lp_build_broadcast(gallivm, lp_build_vec_type(gallivm, int_type), + num_levels); + } } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 837394fb890..3446a8fd46d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -189,6 +189,7 @@ struct lp_build_sampler_soa struct gallivm_state *gallivm, struct lp_type type, unsigned unit, + boolean need_nr_mips, LLVMValueRef explicit_lod, /* optional */ LLVMValueRef *sizes_out); }; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 5eeaaf4ed98..52a60dd43b6 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -1621,69 +1621,35 @@ emit_txf( struct lp_build_tgsi_soa_context *bld, } static void -emit_txq( struct lp_build_tgsi_soa_context *bld, - const struct tgsi_full_instruction *inst, - LLVMValueRef *sizes_out) +emit_size_query( struct lp_build_tgsi_soa_context *bld, + const struct tgsi_full_instruction *inst, + LLVMValueRef *sizes_out, + boolean is_sviewinfo) { LLVMValueRef explicit_lod; - unsigned num_coords, has_lod; + unsigned has_lod; unsigned i; switch (inst->Texture.Texture) { - case TGSI_TEXTURE_1D: - case TGSI_TEXTURE_SHADOW1D: - num_coords = 1; - has_lod = 1; - break; - case TGSI_TEXTURE_2D: - case TGSI_TEXTURE_SHADOW2D: - case TGSI_TEXTURE_CUBE: - case TGSI_TEXTURE_SHADOWCUBE: - case TGSI_TEXTURE_1D_ARRAY: - case TGSI_TEXTURE_SHADOW1D_ARRAY: - num_coords = 2; - has_lod = 1; - break; - case TGSI_TEXTURE_3D: -// case TGSI_TEXTURE_CUBE_ARRAY: -// case TGSI_TEXTURE_SHADOWCUBE_ARRAY: - case TGSI_TEXTURE_2D_ARRAY: - case TGSI_TEXTURE_SHADOW2D_ARRAY: - num_coords = 3; - has_lod = 1; - break; - case TGSI_TEXTURE_BUFFER: - num_coords = 1; - has_lod = 0; - break; - case TGSI_TEXTURE_RECT: case TGSI_TEXTURE_SHADOWRECT: -// case TGSI_TEXTURE_2D_MS: - num_coords = 2; has_lod = 0; break; - -// case TGSI_TEXTURE_2D_MS_ARRAY: -// num_coords = 3; -// has_lod = 0; -// break; - default: - assert(0); - return; + has_lod = 1; + break; } if (!bld->sampler) { _debug_printf("warning: found texture query instruction but no sampler generator supplied\n"); - for (i = 0; i < num_coords; i++) - sizes_out[i] = bld->bld_base.base.undef; + for (i = 0; i < 4; i++) + sizes_out[i] = bld->bld_base.int_bld.undef; return; } if (has_lod) - explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 2 ); + explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 0 ); else explicit_lod = NULL; @@ -1691,6 +1657,7 @@ emit_txq( struct lp_build_tgsi_soa_context *bld, bld->bld_base.base.gallivm, bld->bld_base.int_bld.type, inst->Src[1].Register.Index, + is_sviewinfo, explicit_lod, sizes_out); } @@ -2078,7 +2045,7 @@ txq_emit( { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); - emit_txq(bld, emit_data->inst, emit_data->output); + emit_size_query(bld, emit_data->inst, emit_data->output, FALSE); } static void @@ -2174,13 +2141,8 @@ sviewinfo_emit( struct lp_build_emit_data * emit_data) { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); - /* - * FIXME: unlike txq we are required to return number of mipmap levels - * too, and the unused channels are defined to be zero. - * Either always do that (and hope llvm can optimize it away?) - * or pass a parameter all the way down. - */ - emit_txq(bld, emit_data->inst, emit_data->output); + + emit_size_query(bld, emit_data->inst, emit_data->output, TRUE); } static void |