[Mesa-dev] [PATCH] llvmpipe: Implement TXQ.
Roland Scheidegger
sroland at vmware.com
Thu May 17 12:16:23 PDT 2012
Still have a comment, but it's really trivial and either way it's fine so:
Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Am 17.05.2012 16:48, 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 <galibert at 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 | 72 +++++++++++++++++
> 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, 225 insertions(+), 6 deletions(-)
>
> Addresses Roland's latest pertinent nitpicks.
>
> 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..f3023a0 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,74 @@ 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));
> +
> + 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;
Missed it last time I think you could start with bld_int_vec.undef for
slightly more optimized code but it doesn't really matter.
Also, not sure if variable name "slot" makes sense anymore?
> +
> + 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_extract_broadcast(gallivm, bld_int_vec.type, bld_int_vec.type,
> + slot,
> + lp_build_const_int32(gallivm, i));
> + }
> +}
> 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;
More information about the mesa-dev
mailing list