[Mesa-dev] [PATCH] gallivm: fix up size queries for dx10 sviewinfo opcode
Jose Fonseca
jfonseca at vmware.com
Wed Feb 6 02:26:56 PST 2013
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>
----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
>
> 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.
> ---
> src/gallium/auxiliary/draw/draw_llvm_sample.c | 2 +
> src/gallium/auxiliary/gallivm/lp_bld_sample.h | 1 +
> src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 64
> +++++++++++++-------
> src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 1 +
> src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 66
> +++++----------------
> src/gallium/auxiliary/tgsi/tgsi_info.c | 4 ++
> src/gallium/docs/source/tgsi.rst | 2 +-
> src/gallium/drivers/llvmpipe/lp_tex_sample.c | 2 +
> 8 files changed, 67 insertions(+), 75 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c
> b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> index 03a2592..e51e011 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> @@ -269,6 +269,7 @@ draw_llvm_sampler_soa_emit_size_query(const
> struct lp_build_sampler_soa *base,
> struct gallivm_state *gallivm,
> struct lp_type type,
> unsigned texture_unit,
> + boolean need_nr_mips,
> LLVMValueRef explicit_lod, /*
> optional */
> LLVMValueRef *sizes_out)
> {
> @@ -281,6 +282,7 @@ draw_llvm_sampler_soa_emit_size_query(const
> struct lp_build_sampler_soa *base,
> &sampler->dynamic_state.base,
> type,
> texture_unit,
> + need_nr_mips,
> explicit_lod,
> sizes_out);
> }
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> index 77ce008..f502216 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 778400a..c5b48b5 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 adc63ef..407e968 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 5eeaaf4..52a60dd 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
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c
> b/src/gallium/auxiliary/tgsi/tgsi_info.c
> index 458bc69..f87cf4c 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_info.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
> @@ -293,7 +293,10 @@ tgsi_opcode_infer_src_type( uint opcode )
> case TGSI_OPCODE_USHR:
> case TGSI_OPCODE_SHL:
> case TGSI_OPCODE_TXQ:
> + case TGSI_OPCODE_SVIEWINFO:
> case TGSI_OPCODE_TXF:
> + case TGSI_OPCODE_SAMPLE_I:
> + case TGSI_OPCODE_SAMPLE_I_MS:
> return TGSI_TYPE_UNSIGNED;
> case TGSI_OPCODE_MOD:
> case TGSI_OPCODE_I2F:
> @@ -343,6 +346,7 @@ tgsi_opcode_infer_dst_type( uint opcode )
> case TGSI_OPCODE_SHL:
> case TGSI_OPCODE_TXQ:
> case TGSI_OPCODE_TXQ_LZ:
> + case TGSI_OPCODE_SVIEWINFO:
> return TGSI_TYPE_UNSIGNED;
> case TGSI_OPCODE_F2I:
> case TGSI_OPCODE_IDIV:
> diff --git a/src/gallium/docs/source/tgsi.rst
> b/src/gallium/docs/source/tgsi.rst
> index 548a9a3..e0a65f7 100644
> --- a/src/gallium/docs/source/tgsi.rst
> +++ b/src/gallium/docs/source/tgsi.rst
> @@ -1435,7 +1435,7 @@ instructions. If in doubt double check Direct3D
> documentation.
>
> .. opcode:: SVIEWINFO - query the dimensions of a given sampler
> view.
> dst receives width, height, depth or array size and
> - number of mipmap levels. The dst can have a writemask
> + number of mipmap levels as int4. The dst can have a
> writemask
> which will specify what info is the caller interested
> in.
> SVIEWINFO dst, src_mip_level, sampler_view
> diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> index 69ac888..df2a610 100644
> --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> @@ -279,6 +279,7 @@ lp_llvm_sampler_soa_emit_size_query(const struct
> lp_build_sampler_soa *base,
> struct gallivm_state *gallivm,
> struct lp_type type,
> unsigned texture_unit,
> + boolean need_nr_mips,
> LLVMValueRef explicit_lod, /*
> optional */
> LLVMValueRef *sizes_out)
> {
> @@ -291,6 +292,7 @@ lp_llvm_sampler_soa_emit_size_query(const struct
> lp_build_sampler_soa *base,
> &sampler->dynamic_state.base,
> type,
> texture_unit,
> + need_nr_mips,
> explicit_lod,
> sizes_out);
> }
> --
> 1.7.9.5
>
More information about the mesa-dev
mailing list