Reviewed-by: Jose Fonseca <jfons...@vmware.com>
----- Original Message ----- > From: Roland Scheidegger <srol...@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 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev