Wouldn't it be easier (and more efficient) if you could just reuse the sampler code which does mipmap minification, i.e. get the texture sizes from bld.int_size and do a lp_build_minify (followed by extract shuffles)? Also, is it on purpose that the non-explicit lod path doesn't handle all cases (using lp_build_minify would handle both cases equally if you pass zero as the level)? Otherwise looks like a good idea to me (well ok I'm not too sure why this opcode is terribly useful in the first place but it exists...).
Roland Am 15.05.2012 22:09, schrieb Olivier Galibert: > Piglits test for fragment shaders pass, vertex shaders fail. The > actual failure seems to be in the interpolators, and not the > textureSize query. > > Signed-off-by: Olivier Galibert <galib...@pobox.com> > --- > src/gallium/auxiliary/draw/draw_llvm_sample.c | 23 +++++ > src/gallium/auxiliary/gallivm/lp_bld_sample.h | 10 +- > src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 112 > +++++++++++++++++++++ > src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 7 ++ > src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 86 ++++++++++++++++ > src/gallium/drivers/llvmpipe/lp_tex_sample.c | 23 +++++ > 6 files changed, 260 insertions(+), 1 deletion(-) > > diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c > b/src/gallium/auxiliary/draw/draw_llvm_sample.c > index 8af3461..a3f5197 100644 > --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c > +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c > @@ -195,6 +195,28 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct > lp_build_sampler_soa *base, > } > > > +/** > + * Fetch the texture size. > + */ > +static void > +draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa > *base, > + struct gallivm_state *gallivm, > + unsigned unit, > + LLVMValueRef explicit_lod, /* optional > */ > + LLVMValueRef *sizes_out) > +{ > + struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa > *)base; > + > + assert(unit < PIPE_MAX_VERTEX_SAMPLERS); > + > + lp_build_size_query_soa(gallivm, > + &sampler->dynamic_state.static_state[unit], > + &sampler->dynamic_state.base, > + unit, > + explicit_lod, > + sizes_out); > +} > + > struct lp_build_sampler_soa * > draw_llvm_sampler_soa_create(const struct lp_sampler_static_state > *static_state, > LLVMValueRef context_ptr) > @@ -207,6 +229,7 @@ draw_llvm_sampler_soa_create(const struct > lp_sampler_static_state *static_state, > > sampler->base.destroy = draw_llvm_sampler_soa_destroy; > sampler->base.emit_fetch_texel = draw_llvm_sampler_soa_emit_fetch_texel; > + sampler->base.emit_size_query = draw_llvm_sampler_soa_emit_size_query; > sampler->dynamic_state.base.width = draw_llvm_texture_width; > sampler->dynamic_state.base.height = draw_llvm_texture_height; > sampler->dynamic_state.base.depth = draw_llvm_texture_depth; > diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h > b/src/gallium/auxiliary/gallivm/lp_bld_sample.h > index a71e656..ec8aaf4 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h > +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h > @@ -67,7 +67,7 @@ struct lp_sampler_static_state > unsigned swizzle_a:3; > > /* pipe_texture's state */ > - unsigned target:3; /**< PIPE_TEXTURE_* */ > + unsigned target:4; /**< PIPE_TEXTURE_* */ > unsigned pot_width:1; /**< is the width a power of two? */ > unsigned pot_height:1; > unsigned pot_depth:1; > @@ -405,6 +405,14 @@ lp_build_sample_soa(struct gallivm_state *gallivm, > LLVMValueRef texel_out[4]); > > void > +lp_build_size_query_soa(struct gallivm_state *gallivm, > + const struct lp_sampler_static_state *static_state, > + struct lp_sampler_dynamic_state *dynamic_state, > + unsigned unit, > + LLVMValueRef explicit_lod, > + LLVMValueRef *sizes_out); > + > +void > lp_build_sample_nop(struct gallivm_state *gallivm, struct lp_type type, > LLVMValueRef texel_out[4]); > > diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c > b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c > index 4ea7b4b..926b626 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c > +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c > @@ -35,6 +35,7 @@ > > #include "pipe/p_defines.h" > #include "pipe/p_state.h" > +#include "pipe/p_shader_tokens.h" > #include "util/u_debug.h" > #include "util/u_dump.h" > #include "util/u_memory.h" > @@ -1277,3 +1278,114 @@ lp_build_sample_soa(struct gallivm_state *gallivm, > > apply_sampler_swizzle(&bld, texel_out); > } > + > +void > +lp_build_size_query_soa(struct gallivm_state *gallivm, > + const struct lp_sampler_static_state *static_state, > + struct lp_sampler_dynamic_state *dynamic_state, > + unsigned unit, > + LLVMValueRef explicit_lod, > + LLVMValueRef *sizes_out) > +{ > + if (explicit_lod) { > + LLVMValueRef first_level, zero, all_ones, lod, slot, shifter; > + int dims, array_size; > + struct lp_build_context bld_int_vec; > + > + switch (static_state->target) { > + case TGSI_TEXTURE_1D: > + case TGSI_TEXTURE_SHADOW1D: > + case TGSI_TEXTURE_SHADOW2D: > + case TGSI_TEXTURE_SHADOWCUBE: > + dims = 1; > + array_size = 0; > + break; > + case TGSI_TEXTURE_1D_ARRAY: > + case TGSI_TEXTURE_SHADOW1D_ARRAY: > + dims = 1; > + array_size = 1; > + break; > + case TGSI_TEXTURE_2D: > + case TGSI_TEXTURE_CUBE: > + dims = 2; > + array_size = 0; > + break; > +// case TGSI_TEXTURE_CUBE_ARRAY: > +// case TGSI_TEXTURE_SHADOWCUBE_ARRAY: > + case TGSI_TEXTURE_2D_ARRAY: > + case TGSI_TEXTURE_SHADOW2D_ARRAY: > + dims = 2; > + array_size = 1; > + break; > + case TGSI_TEXTURE_3D: > + dims = 3; > + array_size = 0; > + break; > + > + default: > + assert(0); > + return; > + } > + > + lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32)); > + > + zero = lp_build_const_int32(gallivm, 0); > + all_ones = lp_build_one(gallivm, lp_type_int_vec(32)); > + lod = LLVMBuildExtractElement(gallivm->builder, explicit_lod, zero, > ""); > + first_level = dynamic_state->first_level(dynamic_state, gallivm, unit); > + lod = LLVMBuildAdd(gallivm->builder, lod, first_level, "lod"); > + shifter = lp_build_broadcast_scalar(&bld_int_vec, lod); > + > + slot = dynamic_state->width(dynamic_state, gallivm, unit); > + slot = lp_build_broadcast_scalar(&bld_int_vec, slot); > + slot = LLVMBuildLShr(gallivm->builder, slot, shifter, "minify_width"); > + sizes_out[0] = lp_build_max(&bld_int_vec, slot, all_ones); > + > + if (dims >= 2) { > + slot = dynamic_state->height(dynamic_state, gallivm, unit); > + slot = lp_build_broadcast_scalar(&bld_int_vec, slot); > + slot = LLVMBuildLShr(gallivm->builder, slot, shifter, > "minify_height"); > + sizes_out[1] = lp_build_max(&bld_int_vec, slot, all_ones); > + } > + > + if (dims >= 3) { > + slot = dynamic_state->depth(dynamic_state, gallivm, unit); > + slot = lp_build_broadcast_scalar(&bld_int_vec, slot); > + slot = LLVMBuildLShr(gallivm->builder, slot, shifter, > "minify_depth"); > + sizes_out[2] = lp_build_max(&bld_int_vec, slot, all_ones); > + } > + > +// GL_ext_texture_array not supported yet > +// if (array_size) ??? > + > + } else { > + int dims; > + LLVMValueRef slot; > + struct lp_build_context bld_int_vec; > + switch (static_state->target) { > +// case TGSI_TEXTURE_BUFFER: > +// dims = 1; > +// break; > + > + case TGSI_TEXTURE_RECT: > + case TGSI_TEXTURE_SHADOWRECT: > +// case TGSI_TEXTURE_2D_MS: > + dims = 2; > + break; > + > + default: > + assert(0); > + return; > + } > + > + lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32)); > + > + slot = dynamic_state->width(dynamic_state, gallivm, unit); > + sizes_out[0] = lp_build_broadcast_scalar(&bld_int_vec, slot); > + > + if (dims >= 2) { > + slot = dynamic_state->height(dynamic_state, gallivm, unit); > + sizes_out[1] = lp_build_broadcast_scalar(&bld_int_vec, slot); > + } > + } > +} > diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > index 773c679..141e799 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > @@ -170,6 +170,13 @@ struct lp_build_sampler_soa > LLVMValueRef lod_bias, /* optional */ > LLVMValueRef explicit_lod, /* optional */ > LLVMValueRef *texel); > + > + void > + (*emit_size_query)( const struct lp_build_sampler_soa *sampler, > + struct gallivm_state *gallivm, > + unsigned unit, > + 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 cca7ef5..516ef08 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c > +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c > @@ -1209,6 +1209,80 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, > texel); > } > > +static void > +emit_txq( struct lp_build_tgsi_soa_context *bld, > + const struct tgsi_full_instruction *inst, > + LLVMValueRef *sizes_out) > +{ > + LLVMValueRef explicit_lod; > + unsigned num_coords, has_lod; > + unsigned i; > + > + switch (inst->Texture.Texture) { > + case TGSI_TEXTURE_1D: > + case TGSI_TEXTURE_SHADOW1D: > + case TGSI_TEXTURE_SHADOW2D: > + case TGSI_TEXTURE_SHADOWCUBE: > + num_coords = 1; > + has_lod = 1; > + break; > + case TGSI_TEXTURE_2D: > + case TGSI_TEXTURE_CUBE: > + 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; > + } > + > + 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; > + return; > + } > + > + if (has_lod) > + explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 2 ); > + else > + explicit_lod = NULL; > + > + bld->sampler->emit_size_query(bld->sampler, > + bld->bld_base.base.gallivm, > + inst->Src[1].Register.Index, > + explicit_lod, > + sizes_out); > +} > + > static boolean > near_end_of_shader(struct lp_build_tgsi_soa_context *bld, > int pc) > @@ -1585,6 +1659,17 @@ txp_emit( > } > > static void > +txq_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_txq(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, > @@ -1954,6 +2039,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, > bld.bld_base.op_actions[TGSI_OPCODE_TXD].emit = txd_emit; > 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; > > lp_exec_mask_init(&bld.exec_mask, &bld.bld_base.base); > > diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c > b/src/gallium/drivers/llvmpipe/lp_tex_sample.c > index ccc1396..daa96f2 100644 > --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c > +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c > @@ -204,6 +204,28 @@ lp_llvm_sampler_soa_emit_fetch_texel(const struct > lp_build_sampler_soa *base, > texel); > } > > +/** > + * Fetch the texture size. > + */ > +static void > +lp_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base, > + struct gallivm_state *gallivm, > + unsigned unit, > + LLVMValueRef explicit_lod, /* optional */ > + LLVMValueRef *sizes_out) > +{ > + struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base; > + > + assert(unit < PIPE_MAX_SAMPLERS); > + > + lp_build_size_query_soa(gallivm, > + &sampler->dynamic_state.static_state[unit], > + &sampler->dynamic_state.base, > + unit, > + explicit_lod, > + sizes_out); > +} > + > > struct lp_build_sampler_soa * > lp_llvm_sampler_soa_create(const struct lp_sampler_static_state > *static_state, > @@ -217,6 +239,7 @@ lp_llvm_sampler_soa_create(const struct > lp_sampler_static_state *static_state, > > sampler->base.destroy = lp_llvm_sampler_soa_destroy; > sampler->base.emit_fetch_texel = lp_llvm_sampler_soa_emit_fetch_texel; > + sampler->base.emit_size_query = lp_llvm_sampler_soa_emit_size_query; > sampler->dynamic_state.base.width = lp_llvm_texture_width; > sampler->dynamic_state.base.height = lp_llvm_texture_height; > sampler->dynamic_state.base.depth = lp_llvm_texture_depth; _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev