This looks good to me. Minor nitpicks below. Am 17.05.2012 10:34, 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.c | 7 +- > src/gallium/auxiliary/gallivm/lp_bld_sample.h | 13 ++++ > src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 75 ++++++++++++++++++ > 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 ++++++ > 7 files changed, 228 insertions(+), 6 deletions(-) > > To my delight, reshaping it works out well. This should be the final > version, unless something else is problematic. > > > 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.c > b/src/gallium/auxiliary/gallivm/lp_bld_sample.c > index c6d4f1b..2ffd9b8 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c > +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c > @@ -51,11 +51,6 @@ > */ > #define BRILINEAR_FACTOR 2 > > -static LLVMValueRef > -lp_build_minify(struct lp_build_context *bld, > - LLVMValueRef base_size, > - LLVMValueRef level); > - > /** > * Does the given texture wrap mode allow sampling the texture border color? > * XXX maybe move this into gallium util code. > @@ -670,7 +665,7 @@ lp_build_get_const_mipmap_level(struct > lp_build_sample_context *bld, > * Codegen equivalent for u_minify(). > * Return max(1, base_size >> level); > */ > -static LLVMValueRef > +LLVMValueRef > lp_build_minify(struct lp_build_context *bld, > LLVMValueRef base_size, > LLVMValueRef level) > diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h > b/src/gallium/auxiliary/gallivm/lp_bld_sample.h > index a71e656..e59a70d 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h > +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h > @@ -405,8 +405,21 @@ 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]); > > > +LLVMValueRef > +lp_build_minify(struct lp_build_context *bld, > + LLVMValueRef base_size, > + LLVMValueRef level); > + > #endif /* LP_BLD_SAMPLE_H */ > diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c > b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c > index 4ea7b4b..7515f72 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,77 @@ 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) > +{ > + LLVMValueRef lod, slot; > + int dims, i; > + struct lp_build_context bld_int_vec; > + > + switch (static_state->target) { > + case PIPE_TEXTURE_1D: > + case PIPE_BUFFER: > + dims = 1; > + break; > + case PIPE_TEXTURE_2D: > + case PIPE_TEXTURE_CUBE: > + case PIPE_TEXTURE_RECT: > +// case PIPE_TEXTURE_2D_MS: > + dims = 2; > + break; > + case PIPE_TEXTURE_3D: > + dims = 3; > + break; > + > + default: > + assert(0); > + return; > + } > + > + lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32)); > + > + bld_int_vec.zero = lp_build_zero(gallivm, bld_int_vec.type); > + bld_int_vec.one = lp_build_one (gallivm, bld_int_vec.type); This is unnecessary. build_context_init() will take care of initializing the zero/one values.
Though this always will use a vector, even for 1d case. I guess though this is ok, if llvm is smart enough it could make it scalar itself. > + > + 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, unit); > + lod = lp_build_broadcast_scalar(&bld_int_vec, > + LLVMBuildAdd(gallivm->builder, lod, > first_level, "lod")); > + > + } else > + lod = bld_int_vec.zero; > + > + slot = bld_int_vec.zero; > + > + slot = LLVMBuildInsertElement(gallivm->builder, slot, > + dynamic_state->width(dynamic_state, > gallivm, unit), > + lp_build_const_int32(gallivm, 0), ""); > + > + if (dims >= 2) { > + slot = LLVMBuildInsertElement(gallivm->builder, slot, > + dynamic_state->height(dynamic_state, > gallivm, unit), > + lp_build_const_int32(gallivm, 1), ""); > + } > + > + if (dims >= 3) { > + slot = LLVMBuildInsertElement(gallivm->builder, slot, > + dynamic_state->depth(dynamic_state, > gallivm, unit), > + lp_build_const_int32(gallivm, 2), ""); > + } > + > + slot = lp_build_minify(&bld_int_vec, slot, lod); > + > + for(i=0; i<dims; i++) { > + sizes_out[i] = lp_build_broadcast_scalar(&bld_int_vec, > + > LLVMBuildExtractElement(gallivm->builder, slot, > + > lp_build_const_int32(gallivm, i), "")); I think you could use the lp_build_extract_broadcast() helper instead for even better readability. > + } > +} > 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..a9d69a3 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; Roland _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev