[Mesa-dev] [PATCH] gallivm: simplify sampler interface
Jose Fonseca
jfonseca at vmware.com
Mon Mar 30 06:10:45 PDT 2015
On 28/03/15 19:53, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> This has got a bit out of control with more and more parameters added.
> Worse, whenever something in there changes all callees have to be updated
> for that, even though they don't really do much with any parameter in there
> except pass it on to the actual sampling function.
> Hence simply put almost everything into a struct. Also instead of relying
> on some arguments being NULL, be explicit and set this in a key (which is
> just reused for function generation for simplicity). (The code still relies
> on them being NULL in the end for now.)
> Technically there is a minimal functional change here for shadow sampling:
> if shadow sampling is done is now determined explicitly by the texture
> function (either sample_c or the gl-style tex func inherit this from target)
> instead of the static texture state. These two should always match, however.
> Otherwise, it should generate all the same code.
> ---
> src/gallium/auxiliary/draw/draw_llvm_sample.c | 31 +--
> src/gallium/auxiliary/gallivm/lp_bld_sample.h | 48 +++--
> src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 227 +++++++++-------------
> src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 17 +-
> src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 133 +++++++------
> src/gallium/drivers/llvmpipe/lp_tex_sample.c | 33 +---
> 6 files changed, 218 insertions(+), 271 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> index 16d075c..32cad59 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> @@ -229,38 +229,19 @@ draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
> static void
> draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
> struct gallivm_state *gallivm,
> - struct lp_type type,
> - boolean is_fetch,
> - unsigned texture_index,
> - unsigned sampler_index,
> - LLVMValueRef context_ptr,
> - const LLVMValueRef *coords,
> - const LLVMValueRef *offsets,
> - const struct lp_derivatives *derivs,
> - LLVMValueRef lod_bias, /* optional */
> - LLVMValueRef explicit_lod, /* optional */
> - enum lp_sampler_lod_property lod_property,
> - LLVMValueRef *texel)
> + const struct lp_sampler_params *params)
> {
> struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;
> + unsigned texture_index = params->texture_index;
> + unsigned sampler_index = params->sampler_index;
>
> assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
> assert(sampler_index < PIPE_MAX_SAMPLERS);
>
> - lp_build_sample_soa(gallivm,
> - &sampler->dynamic_state.static_state[texture_index].texture_state,
> + lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
> &sampler->dynamic_state.static_state[sampler_index].sampler_state,
> &sampler->dynamic_state.base,
> - type,
> - is_fetch,
> - texture_index,
> - sampler_index,
> - context_ptr,
> - coords,
> - offsets,
> - derivs,
> - lod_bias, explicit_lod, lod_property,
> - texel);
> + gallivm, params);
> }
>
>
> @@ -306,7 +287,7 @@ draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_stat
> return NULL;
>
> sampler->base.destroy = draw_llvm_sampler_soa_destroy;
> - sampler->base.emit_fetch_texel = draw_llvm_sampler_soa_emit_fetch_texel;
> + sampler->base.emit_tex_sample = 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;
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> index be41ca0..b95ee6f 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> @@ -68,6 +68,37 @@ enum lp_sampler_lod_property {
> };
>
>
> +enum lp_sampler_lod_control {
> + LP_SAMPLER_LOD_IMPLICIT,
> + LP_SAMPLER_LOD_BIAS,
> + LP_SAMPLER_LOD_EXPLICIT,
> + LP_SAMPLER_LOD_DERIVATIVES,
> +};
> +
> +
> +#define LP_SAMPLER_SHADOW (1 << 0)
> +#define LP_SAMPLER_OFFSETS (1 << 1)
> +#define LP_SAMPLER_FETCH (1 << 2)
> +#define LP_SAMPLER_LOD_CONTROL_SHIFT 3
> +#define LP_SAMPLER_LOD_CONTROL_MASK (3 << 3)
> +#define LP_SAMPLER_LOD_PROPERTY_SHIFT 5
> +#define LP_SAMPLER_LOD_PROPERTY_MASK (3 << 5)
> +
> +struct lp_sampler_params
> +{
> + struct lp_type type;
> + unsigned texture_index;
> + unsigned sampler_index;
> + unsigned sample_key;
> + LLVMValueRef context_ptr;
> + const LLVMValueRef *coords;
> + const LLVMValueRef *offsets;
> + LLVMValueRef lod;
> + const struct lp_derivatives *derivs;
> + LLVMValueRef *texel;
> +};
> +
> +
> /**
> * Texture static state.
> *
> @@ -531,22 +562,11 @@ lp_build_sample_offset(struct lp_build_context *bld,
>
>
> void
> -lp_build_sample_soa(struct gallivm_state *gallivm,
> - const struct lp_static_texture_state *static_texture_state,
> +lp_build_sample_soa(const struct lp_static_texture_state *static_texture_state,
> const struct lp_static_sampler_state *static_sampler_state,
> struct lp_sampler_dynamic_state *dynamic_texture_state,
> - struct lp_type fp_type,
> - boolean is_fetch,
> - unsigned texture_index,
> - unsigned sampler_index,
> - LLVMValueRef context_ptr,
> - const LLVMValueRef *coords,
> - const LLVMValueRef *offsets,
> - const struct lp_derivatives *derivs,
> - LLVMValueRef lod_bias,
> - LLVMValueRef explicit_lod,
> - enum lp_sampler_lod_property lod_property,
> - LLVMValueRef texel_out[4]);
> + struct gallivm_state *gallivm,
> + const struct lp_sampler_params *params);
>
>
> void
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> index 598d5fc..82ef359 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> @@ -2361,7 +2361,7 @@ lp_build_sample_nop(struct gallivm_state *gallivm,
> * 'texel' will return a vector of four LLVMValueRefs corresponding to
> * R, G, B, A.
> * \param type vector float type to use for coords, etc.
> - * \param is_fetch if this is a texel fetch instruction.
> + * \param sample_key
> * \param derivs partial derivatives of (s,t,r,q) with respect to x and y
> */
> static void
> @@ -2370,16 +2370,14 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
> const struct lp_static_sampler_state *static_sampler_state,
> struct lp_sampler_dynamic_state *dynamic_state,
> struct lp_type type,
> - boolean is_fetch,
> + unsigned sample_key,
> unsigned texture_index,
> unsigned sampler_index,
> LLVMValueRef context_ptr,
> const LLVMValueRef *coords,
> const LLVMValueRef *offsets,
> const struct lp_derivatives *derivs, /* optional */
> - LLVMValueRef lod_bias, /* optional */
> - LLVMValueRef explicit_lod, /* optional */
> - enum lp_sampler_lod_property lod_property,
> + LLVMValueRef lod, /* optional */
> LLVMValueRef texel_out[4])
> {
> unsigned target = static_texture_state->target;
> @@ -2391,12 +2389,41 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
> LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
> LLVMBuilderRef builder = gallivm->builder;
> LLVMValueRef tex_width, newcoords[5];
> + enum lp_sampler_lod_property lod_property;
> + enum lp_sampler_lod_control lod_control;
> + LLVMValueRef lod_bias = NULL;
> + LLVMValueRef explicit_lod = NULL;
> + boolean is_fetch = !!(sample_key & LP_SAMPLER_FETCH);
>
> if (0) {
> enum pipe_format fmt = static_texture_state->format;
> debug_printf("Sample from %s\n", util_format_name(fmt));
> }
>
> + lod_property = (sample_key & LP_SAMPLER_LOD_PROPERTY_MASK) >>
> + LP_SAMPLER_LOD_PROPERTY_SHIFT;
> + lod_control = (sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >>
> + LP_SAMPLER_LOD_CONTROL_SHIFT;
> +
> + if (lod_control == LP_SAMPLER_LOD_BIAS) {
> + lod_bias = lod;
> + assert(lod);
> + assert(derivs == NULL);
> + }
> + else if (lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> + explicit_lod = lod;
> + assert(lod);
> + assert(derivs == NULL);
> + }
> + else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
> + assert(derivs);
> + assert(lod == NULL);
> + }
> + else {
> + assert(derivs == NULL);
> + assert(lod == NULL);
> + }
> +
> if (static_texture_state->format == PIPE_FORMAT_NONE) {
> /*
> * If there's nothing bound, format is NONE, and we must return
> @@ -2633,7 +2660,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>
> else if (is_fetch) {
> lp_build_fetch_texel(&bld, texture_index, newcoords,
> - explicit_lod, offsets,
> + lod, offsets,
> texel_out);
> }
>
> @@ -2895,15 +2922,6 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>
> #define LP_MAX_TEX_FUNC_ARGS 32
>
> -#define LP_SAMPLER_FUNC_LOD_BIAS (1 << 0)
> -#define LP_SAMPLER_FUNC_LOD_EXPLICIT (1 << 1)
> -#define LP_SAMPLER_FUNC_EXPLICITDERIVS (1 << 2)
> -#define LP_SAMPLER_FUNC_SHADOW (1 << 3)
> -#define LP_SAMPLER_FUNC_OFFSETS (1 << 4)
> -#define LP_SAMPLER_FUNC_FETCH (1 << 5)
> -#define LP_SAMPLER_FUNC_LOD_PROPERTY_SHIFT 6
> -
> -
> static inline void
> get_target_info(enum pipe_texture_target target,
> unsigned *num_coords, unsigned *num_derivs,
> @@ -2935,27 +2953,27 @@ lp_build_sample_gen_func(struct gallivm_state *gallivm,
> const struct lp_static_sampler_state *static_sampler_state,
> struct lp_sampler_dynamic_state *dynamic_state,
> struct lp_type type,
> - boolean is_fetch,
> unsigned texture_index,
> unsigned sampler_index,
> LLVMValueRef function,
> unsigned num_args,
> - unsigned sampler_bits,
> - enum lp_sampler_lod_property lod_property)
> + unsigned sample_key)
> {
> -
> LLVMBuilderRef old_builder;
> LLVMBasicBlockRef block;
> LLVMValueRef coords[5];
> LLVMValueRef offsets[3] = { NULL };
> - LLVMValueRef lod_bias = NULL;
> - LLVMValueRef explicit_lod = NULL;
> + LLVMValueRef lod = NULL;
> LLVMValueRef context_ptr;
> LLVMValueRef texel_out[4];
> struct lp_derivatives derivs;
> struct lp_derivatives *deriv_ptr = NULL;
> unsigned num_param = 0;
> unsigned i, num_coords, num_derivs, num_offsets, layer;
> + enum lp_sampler_lod_control lod_control;
> +
> + lod_control = (sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >>
> + LP_SAMPLER_LOD_CONTROL_SHIFT;
>
> get_target_info(static_texture_state->target,
> &num_coords, &num_derivs, &num_offsets, &layer);
> @@ -2972,21 +2990,19 @@ lp_build_sample_gen_func(struct gallivm_state *gallivm,
> if (layer) {
> coords[layer] = LLVMGetParam(function, num_param++);
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_SHADOW) {
> + if (sample_key & LP_SAMPLER_SHADOW) {
> coords[4] = LLVMGetParam(function, num_param++);
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_OFFSETS) {
> + if (sample_key & LP_SAMPLER_OFFSETS) {
> for (i = 0; i < num_offsets; i++) {
> offsets[i] = LLVMGetParam(function, num_param++);
> }
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_LOD_BIAS) {
> - lod_bias = LLVMGetParam(function, num_param++);
> - }
> - else if (sampler_bits & LP_SAMPLER_FUNC_LOD_EXPLICIT) {
> - explicit_lod = LLVMGetParam(function, num_param++);
> + if (lod_control == LP_SAMPLER_LOD_BIAS ||
> + lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> + lod = LLVMGetParam(function, num_param++);
> }
> - else if (sampler_bits & LP_SAMPLER_FUNC_EXPLICITDERIVS) {
> + else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
> for (i = 0; i < num_derivs; i++) {
> derivs.ddx[i] = LLVMGetParam(function, num_param++);
> derivs.ddy[i] = LLVMGetParam(function, num_param++);
> @@ -3010,16 +3026,14 @@ lp_build_sample_gen_func(struct gallivm_state *gallivm,
> static_sampler_state,
> dynamic_state,
> type,
> - is_fetch,
> + sample_key,
> texture_index,
> sampler_index,
> context_ptr,
> coords,
> offsets,
> deriv_ptr,
> - lod_bias,
> - explicit_lod,
> - lod_property,
> + lod,
> texel_out);
>
> LLVMBuildAggregateRet(gallivm->builder, texel_out, 4);
> @@ -3040,18 +3054,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> const struct lp_static_texture_state *static_texture_state,
> const struct lp_static_sampler_state *static_sampler_state,
> struct lp_sampler_dynamic_state *dynamic_state,
> - struct lp_type type,
> - boolean is_fetch,
> - unsigned texture_index,
> - unsigned sampler_index,
> - LLVMValueRef context_ptr,
> - const LLVMValueRef *coords,
> - const LLVMValueRef *offsets,
> - const struct lp_derivatives *derivs, /* optional */
> - LLVMValueRef lod_bias, /* optional */
> - LLVMValueRef explicit_lod, /* optional */
> - enum lp_sampler_lod_property lod_property,
> - LLVMValueRef texel_out[4])
> + const struct lp_sampler_params *params)
> {
> LLVMBuilderRef builder = gallivm->builder;
> LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(
> @@ -3061,9 +3064,18 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> LLVMBasicBlockRef bb;
> LLVMValueRef tex_ret;
> unsigned num_args = 0;
> - unsigned sampler_bits = 0;
> char func_name[64];
> unsigned i, num_coords, num_derivs, num_offsets, layer;
> + unsigned texture_index = params->texture_index;
> + unsigned sampler_index = params->sampler_index;
> + unsigned sample_key = params->sample_key;
> + const LLVMValueRef *coords = params->coords;
> + const LLVMValueRef *offsets = params->offsets;
> + const struct lp_derivatives *derivs = params->derivs;
> + enum lp_sampler_lod_control lod_control;
> +
> + lod_control = (sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >>
> + LP_SAMPLER_LOD_CONTROL_SHIFT;
>
> get_target_info(static_texture_state->target,
> &num_coords, &num_derivs, &num_offsets, &layer);
> @@ -3071,34 +3083,13 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> /*
> * texture function matches are found by name.
> * Thus the name has to include both the texture and sampler unit
> - * (which covers all static state) plus the actual texture functions
> - * (which is determined here somewhat awkwardly by presence of the
> - * corresponding LLVMValueRefs). Additionally, lod_property also
> - * has to be included (it could change if the lod for instance comes
> - * from a shader uniform or a temp reg).
> + * (which covers all static state) plus the actual texture function
> + * (including things like offsets, shadow coord, lod control).
> + * Additionally lod_property has to be included too.
> */
> - if (static_sampler_state->compare_mode != PIPE_TEX_COMPARE_NONE) {
> - sampler_bits |= LP_SAMPLER_FUNC_SHADOW;
> - }
> - if (offsets[0]) {
> - sampler_bits |= LP_SAMPLER_FUNC_OFFSETS;
> - }
> - if (lod_bias) {
> - sampler_bits |= LP_SAMPLER_FUNC_LOD_BIAS;
> - }
> - else if (explicit_lod) {
> - sampler_bits |= LP_SAMPLER_FUNC_LOD_EXPLICIT;
> - }
> - else if (derivs) {
> - sampler_bits |= LP_SAMPLER_FUNC_EXPLICITDERIVS;
> - }
> - if (is_fetch) {
> - sampler_bits |= LP_SAMPLER_FUNC_FETCH;
> - }
> - sampler_bits |= lod_property << LP_SAMPLER_FUNC_LOD_PROPERTY_SHIFT;
>
> util_snprintf(func_name, sizeof(func_name), "texfunc_res_%d_sam_%d_%x",
> - texture_index, sampler_index, sampler_bits);
> + texture_index, sampler_index, sample_key);
>
> function = LLVMGetNamedFunction(module, func_name);
>
> @@ -3113,7 +3104,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> * Generate the function prototype.
> */
>
> - arg_types[num_param++] = LLVMTypeOf(context_ptr);
> + arg_types[num_param++] = LLVMTypeOf(params->context_ptr);
> for (i = 0; i < num_coords; i++) {
> arg_types[num_param++] = LLVMTypeOf(coords[0]);
> assert(LLVMTypeOf(coords[0]) == LLVMTypeOf(coords[i]));
> @@ -3122,22 +3113,20 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> arg_types[num_param++] = LLVMTypeOf(coords[layer]);
> assert(LLVMTypeOf(coords[0]) == LLVMTypeOf(coords[layer]));
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_SHADOW) {
> + if (sample_key & LP_SAMPLER_SHADOW) {
> arg_types[num_param++] = LLVMTypeOf(coords[0]);
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_OFFSETS) {
> + if (sample_key & LP_SAMPLER_OFFSETS) {
> for (i = 0; i < num_offsets; i++) {
> arg_types[num_param++] = LLVMTypeOf(offsets[0]);
> assert(LLVMTypeOf(offsets[0]) == LLVMTypeOf(offsets[i]));
> }
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_LOD_BIAS) {
> - arg_types[num_param++] = LLVMTypeOf(lod_bias);
> - }
> - else if (sampler_bits & LP_SAMPLER_FUNC_LOD_EXPLICIT) {
> - arg_types[num_param++] = LLVMTypeOf(explicit_lod);
> + if (lod_control == LP_SAMPLER_LOD_BIAS ||
> + lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> + arg_types[num_param++] = LLVMTypeOf(params->lod);
> }
> - else if (sampler_bits & LP_SAMPLER_FUNC_EXPLICITDERIVS) {
> + else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
> for (i = 0; i < num_derivs; i++) {
> arg_types[num_param++] = LLVMTypeOf(derivs->ddx[i]);
> arg_types[num_param++] = LLVMTypeOf(derivs->ddy[i]);
> @@ -3147,7 +3136,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> }
>
> val_type[0] = val_type[1] = val_type[2] = val_type[3] =
> - lp_build_vec_type(gallivm, type);
> + lp_build_vec_type(gallivm, params->type);
> ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 4, 0);
> function_type = LLVMFunctionType(ret_type, arg_types, num_param, 0);
> function = LLVMAddFunction(module, func_name, function_type);
> @@ -3165,39 +3154,35 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> static_texture_state,
> static_sampler_state,
> dynamic_state,
> - type,
> - is_fetch,
> + params->type,
> texture_index,
> sampler_index,
> function,
> num_param,
> - sampler_bits,
> - lod_property);
> + sample_key);
> }
>
> num_args = 0;
> - args[num_args++] = context_ptr;
> + args[num_args++] = params->context_ptr;
> for (i = 0; i < num_coords; i++) {
> args[num_args++] = coords[i];
> }
> if (layer) {
> args[num_args++] = coords[layer];
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_SHADOW) {
> + if (sample_key & LP_SAMPLER_SHADOW) {
> args[num_args++] = coords[4];
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_OFFSETS) {
> + if (sample_key & LP_SAMPLER_OFFSETS) {
> for (i = 0; i < num_offsets; i++) {
> args[num_args++] = offsets[i];
> }
> }
> - if (sampler_bits & LP_SAMPLER_FUNC_LOD_BIAS) {
> - args[num_args++] = lod_bias;
> - }
> - else if (sampler_bits & LP_SAMPLER_FUNC_LOD_EXPLICIT) {
> - args[num_args++] = explicit_lod;
> + if (lod_control == LP_SAMPLER_LOD_BIAS ||
> + lod_control == LP_SAMPLER_LOD_EXPLICIT) {
> + args[num_args++] = params->lod;
> }
> - else if (sampler_bits & LP_SAMPLER_FUNC_EXPLICITDERIVS) {
> + else if (lod_control == LP_SAMPLER_LOD_DERIVATIVES) {
> for (i = 0; i < num_derivs; i++) {
> args[num_args++] = derivs->ddx[i];
> args[num_args++] = derivs->ddy[i];
> @@ -3212,7 +3197,7 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> LLVMSetInstructionCallConv(inst, LLVMFastCallConv);
>
> for (i = 0; i < 4; i++) {
> - texel_out[i] = LLVMBuildExtractValue(gallivm->builder, tex_ret, i, "");
> + params->texel[i] = LLVMBuildExtractValue(gallivm->builder, tex_ret, i, "");
> }
> }
>
> @@ -3222,58 +3207,34 @@ lp_build_sample_soa_func(struct gallivm_state *gallivm,
> * Either via a function call or inline it directly.
> */
> void
> -lp_build_sample_soa(struct gallivm_state *gallivm,
> - const struct lp_static_texture_state *static_texture_state,
> +lp_build_sample_soa(const struct lp_static_texture_state *static_texture_state,
> const struct lp_static_sampler_state *static_sampler_state,
> struct lp_sampler_dynamic_state *dynamic_state,
> - struct lp_type type,
> - boolean is_fetch,
> - unsigned texture_index,
> - unsigned sampler_index,
> - LLVMValueRef context_ptr,
> - const LLVMValueRef *coords,
> - const LLVMValueRef *offsets,
> - const struct lp_derivatives *derivs, /* optional */
> - LLVMValueRef lod_bias, /* optional */
> - LLVMValueRef explicit_lod, /* optional */
> - enum lp_sampler_lod_property lod_property,
> - LLVMValueRef texel_out[4])
> + struct gallivm_state *gallivm,
> + const struct lp_sampler_params *params)
> {
> if (USE_TEX_FUNC_CALL) {
> lp_build_sample_soa_func(gallivm,
> static_texture_state,
> static_sampler_state,
> dynamic_state,
> - type,
> - is_fetch,
> - texture_index,
> - sampler_index,
> - context_ptr,
> - coords,
> - offsets,
> - derivs,
> - lod_bias,
> - explicit_lod,
> - lod_property,
> - texel_out);
> + params);
> }
> else {
> lp_build_sample_soa_code(gallivm,
> static_texture_state,
> static_sampler_state,
> dynamic_state,
> - type,
> - is_fetch,
> - texture_index,
> - sampler_index,
> - context_ptr,
> - coords,
> - offsets,
> - derivs,
> - lod_bias,
> - explicit_lod,
> - lod_property,
> - texel_out);
> + params->type,
> + params->sample_key,
> + params->texture_index,
> + params->sampler_index,
> + params->context_ptr,
> + params->coords,
> + params->offsets,
> + params->derivs,
> + params->lod,
> + params->texel);
> }
> }
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> index 8d53607..3f76b79 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> @@ -182,20 +182,9 @@ struct lp_build_sampler_soa
> (*destroy)( struct lp_build_sampler_soa *sampler );
>
> void
> - (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler,
> - struct gallivm_state *gallivm,
> - struct lp_type type,
> - boolean is_fetch,
> - unsigned texture_index,
> - unsigned sampler_index,
> - LLVMValueRef context_ptr,
> - const LLVMValueRef *coords,
> - const LLVMValueRef *offsets,
> - const struct lp_derivatives *derivs,
> - LLVMValueRef lod_bias, /* optional */
> - LLVMValueRef explicit_lod, /* optional */
> - enum lp_sampler_lod_property,
> - LLVMValueRef *texel);
> + (*emit_tex_sample)(const struct lp_build_sampler_soa *sampler,
> + struct gallivm_state *gallivm,
> + const struct lp_sampler_params *params);
>
> void
> (*emit_size_query)( const struct lp_build_sampler_soa *sampler,
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 3e82036..6a71da6 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -1964,16 +1964,19 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
> unsigned sampler_reg)
> {
> unsigned unit = inst->Src[sampler_reg].Register.Index;
> - LLVMValueRef lod_bias, explicit_lod;
> LLVMValueRef oow = NULL;
> + LLVMValueRef lod = NULL;
> LLVMValueRef coords[5];
> LLVMValueRef offsets[3] = { NULL };
> struct lp_derivatives derivs;
> - struct lp_derivatives *deriv_ptr = NULL;
> + struct lp_sampler_params params;
> enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
> unsigned num_derivs, num_offsets, i;
> unsigned shadow_coord = 0;
> unsigned layer_coord = 0;
> + unsigned sample_key = 0;
> +
> + memset(¶ms, 0, sizeof(params));
>
> if (!bld->sampler) {
> _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
> @@ -2053,7 +2056,6 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
> /* Note lod and especially projected are illegal in a LOT of cases */
> if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS ||
> modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> - LLVMValueRef lod;
> if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
> inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY) {
> /* note that shadow cube array with bias/explicit lod does not exist */
> @@ -2063,19 +2065,13 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
> lod = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3);
> }
> if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
> - lod_bias = lod;
> - explicit_lod = NULL;
> + sample_key |= LP_SAMPLER_LOD_BIAS << LP_SAMPLER_LOD_CONTROL_SHIFT;
> }
> else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> - lod_bias = NULL;
> - explicit_lod = lod;
> + sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
> }
> lod_property = lp_build_lod_property(&bld->bld_base, inst, 0);
> }
> - else {
> - lod_bias = NULL;
> - explicit_lod = NULL;
> - }
>
> if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) {
> oow = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3);
> @@ -2104,6 +2100,7 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
> }
> /* Shadow coord occupies always 5th slot. */
> if (shadow_coord) {
> + sample_key |= LP_SAMPLER_SHADOW;
> if (shadow_coord == 4) {
> coords[4] = lp_build_emit_fetch(&bld->bld_base, inst, 1, 0);
> }
> @@ -2116,11 +2113,12 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
>
> if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
> unsigned dim;
> + sample_key |= LP_SAMPLER_LOD_DERIVATIVES << LP_SAMPLER_LOD_CONTROL_SHIFT;
> for (dim = 0; dim < num_derivs; ++dim) {
> derivs.ddx[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 1, dim);
> derivs.ddy[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 2, dim);
> }
> - deriv_ptr = &derivs;
> + params.derivs = &derivs;
> /*
> * could also check all src regs if constant but I doubt such
> * cases exist in practice.
> @@ -2137,26 +2135,30 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
> lod_property = LP_SAMPLER_LOD_PER_ELEMENT;
> }
> }
> + sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
>
> /* some advanced gather instructions (txgo) would require 4 offsets */
> if (inst->Texture.NumOffsets == 1) {
> unsigned dim;
> + sample_key |= LP_SAMPLER_OFFSETS;
> for (dim = 0; dim < num_offsets; dim++) {
> offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim);
> }
> }
>
> - bld->sampler->emit_fetch_texel(bld->sampler,
> - bld->bld_base.base.gallivm,
> - bld->bld_base.base.type,
> - FALSE,
> - unit, unit,
> - bld->context_ptr,
> - coords,
> - offsets,
> - deriv_ptr,
> - lod_bias, explicit_lod, lod_property,
> - texel);
> + params.type = bld->bld_base.base.type;
> + params.sample_key = sample_key;
> + params.texture_index = unit;
> + params.sampler_index = unit;
> + params.context_ptr = bld->context_ptr;
> + params.coords = coords;
> + params.offsets = offsets;
> + params.lod = lod;
> + params.texel = texel;
> +
> + bld->sampler->emit_tex_sample(bld->sampler,
> + bld->bld_base.base.gallivm,
> + ¶ms);
> }
>
> static void
> @@ -2168,15 +2170,18 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
> {
> struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> unsigned texture_unit, sampler_unit;
> - LLVMValueRef lod_bias, explicit_lod;
> + LLVMValueRef lod = NULL;
> LLVMValueRef coords[5];
> LLVMValueRef offsets[3] = { NULL };
> struct lp_derivatives derivs;
> - struct lp_derivatives *deriv_ptr = NULL;
> + struct lp_sampler_params params;
> enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
>
> unsigned num_offsets, num_derivs, i;
> unsigned layer_coord = 0;
> + unsigned sample_key = 0;
> +
> + memset(¶ms, 0, sizeof(params));
>
> if (!bld->sampler) {
> _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
> @@ -2238,25 +2243,19 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
>
> if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS ||
> modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> - LLVMValueRef lod = lp_build_emit_fetch(&bld->bld_base, inst, 3, 0);
> + lod = lp_build_emit_fetch(&bld->bld_base, inst, 3, 0);
> if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
> - lod_bias = lod;
> - explicit_lod = NULL;
> + sample_key |= LP_SAMPLER_LOD_BIAS << LP_SAMPLER_LOD_CONTROL_SHIFT;
> }
> else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
> - lod_bias = NULL;
> - explicit_lod = lod;
> + sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
> }
> lod_property = lp_build_lod_property(&bld->bld_base, inst, 0);
> }
> else if (modifier == LP_BLD_TEX_MODIFIER_LOD_ZERO) {
> - lod_bias = NULL;
> /* XXX might be better to explicitly pass the level zero information */
> - explicit_lod = lp_build_const_vec(gallivm, bld->bld_base.base.type, 0.0F);
> - }
> - else {
> - lod_bias = NULL;
> - explicit_lod = NULL;
> + sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
> + lod = lp_build_const_vec(gallivm, bld->bld_base.base.type, 0.0F);
> }
>
> for (i = 0; i < num_derivs; i++) {
> @@ -2275,16 +2274,18 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
> }
> /* Shadow coord occupies always 5th slot. */
> if (compare) {
> + sample_key |= LP_SAMPLER_SHADOW;
> coords[4] = lp_build_emit_fetch(&bld->bld_base, inst, 3, 0);
> }
>
> if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
> unsigned dim;
> + sample_key |= LP_SAMPLER_LOD_DERIVATIVES << LP_SAMPLER_LOD_CONTROL_SHIFT;
> for (dim = 0; dim < num_derivs; ++dim) {
> derivs.ddx[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 3, dim);
> derivs.ddy[dim] = lp_build_emit_fetch(&bld->bld_base, inst, 4, dim);
> }
> - deriv_ptr = &derivs;
> + params.derivs = &derivs;
> /*
> * could also check all src regs if constant but I doubt such
> * cases exist in practice.
> @@ -2305,22 +2306,26 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
> /* some advanced gather instructions (txgo) would require 4 offsets */
> if (inst->Texture.NumOffsets == 1) {
> unsigned dim;
> + sample_key |= LP_SAMPLER_OFFSETS;
> for (dim = 0; dim < num_offsets; dim++) {
> offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim);
> }
> }
> + sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
>
> - bld->sampler->emit_fetch_texel(bld->sampler,
> - bld->bld_base.base.gallivm,
> - bld->bld_base.base.type,
> - FALSE,
> - texture_unit, sampler_unit,
> - bld->context_ptr,
> - coords,
> - offsets,
> - deriv_ptr,
> - lod_bias, explicit_lod, lod_property,
> - texel);
> + params.type = bld->bld_base.base.type;
> + params.sample_key = sample_key;
> + params.texture_index = texture_unit;
> + params.sampler_index = sampler_unit;
> + params.context_ptr = bld->context_ptr;
> + params.coords = coords;
> + params.offsets = offsets;
> + params.lod = lod;
> + params.texel = texel;
> +
> + bld->sampler->emit_tex_sample(bld->sampler,
> + bld->bld_base.base.gallivm,
> + ¶ms);
>
> if (inst->Src[1].Register.SwizzleX != PIPE_SWIZZLE_RED ||
> inst->Src[1].Register.SwizzleY != PIPE_SWIZZLE_GREEN ||
> @@ -2347,9 +2352,13 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
> LLVMValueRef explicit_lod = NULL;
> LLVMValueRef coords[5];
> LLVMValueRef offsets[3] = { NULL };
> + struct lp_sampler_params params;
> enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
> unsigned dims, i;
> unsigned layer_coord = 0;
> + unsigned sample_key = LP_SAMPLER_FETCH;
> +
> + memset(¶ms, 0, sizeof(params));
>
> if (!bld->sampler) {
> _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
> @@ -2399,6 +2408,7 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
> if (target != TGSI_TEXTURE_BUFFER &&
> target != TGSI_TEXTURE_2D_MSAA &&
> target != TGSI_TEXTURE_2D_ARRAY_MSAA) {
> + sample_key |= LP_SAMPLER_LOD_EXPLICIT << LP_SAMPLER_LOD_CONTROL_SHIFT;
> explicit_lod = lp_build_emit_fetch(&bld->bld_base, inst, 0, 3);
> lod_property = lp_build_lod_property(&bld->bld_base, inst, 0);
> }
> @@ -2416,22 +2426,27 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
>
> if (inst->Texture.NumOffsets == 1) {
> unsigned dim;
> + sample_key |= LP_SAMPLER_OFFSETS;
> for (dim = 0; dim < dims; dim++) {
> offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim);
> }
> }
> + sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
>
> - bld->sampler->emit_fetch_texel(bld->sampler,
> - bld->bld_base.base.gallivm,
> - bld->bld_base.base.type,
> - TRUE,
> - unit, unit,
> - bld->context_ptr,
> - coords,
> - offsets,
> - NULL,
> - NULL, explicit_lod, lod_property,
> - texel);
> + params.type = bld->bld_base.base.type;
> + params.sample_key = sample_key;
> + params.texture_index = unit;
> + params.sampler_index = unit;
> + params.context_ptr = bld->context_ptr;
> + params.coords = coords;
> + params.offsets = offsets;
> + params.derivs = NULL;
> + params.lod = explicit_lod;
> + params.texel = texel;
> +
> + bld->sampler->emit_tex_sample(bld->sampler,
> + bld->bld_base.base.gallivm,
> + ¶ms);
>
> if (is_samplei &&
> (inst->Src[1].Register.SwizzleX != PIPE_SWIZZLE_RED ||
> diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> index 1828069..316d1c5 100644
> --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> @@ -235,43 +235,24 @@ lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
> static void
> lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
> struct gallivm_state *gallivm,
> - struct lp_type type,
> - boolean is_fetch,
> - unsigned texture_index,
> - unsigned sampler_index,
> - LLVMValueRef context_ptr,
> - const LLVMValueRef *coords,
> - const LLVMValueRef *offsets,
> - const struct lp_derivatives *derivs,
> - LLVMValueRef lod_bias, /* optional */
> - LLVMValueRef explicit_lod, /* optional */
> - enum lp_sampler_lod_property lod_property,
> - LLVMValueRef *texel)
> + const struct lp_sampler_params *params)
> {
> struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
> + unsigned texture_index = params->texture_index;
> + unsigned sampler_index = params->sampler_index;
>
> assert(sampler_index < PIPE_MAX_SAMPLERS);
> assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
>
> if (LP_PERF & PERF_NO_TEX) {
> - lp_build_sample_nop(gallivm, type, coords, texel);
> + lp_build_sample_nop(gallivm, params->type, params->coords, params->texel);
> return;
> }
>
> - lp_build_sample_soa(gallivm,
> - &sampler->dynamic_state.static_state[texture_index].texture_state,
> + lp_build_sample_soa(&sampler->dynamic_state.static_state[texture_index].texture_state,
> &sampler->dynamic_state.static_state[sampler_index].sampler_state,
> &sampler->dynamic_state.base,
> - type,
> - is_fetch,
> - texture_index,
> - sampler_index,
> - context_ptr,
> - coords,
> - offsets,
> - derivs,
> - lod_bias, explicit_lod, lod_property,
> - texel);
> + gallivm, params);
> }
>
> /**
> @@ -317,7 +298,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state)
> return NULL;
>
> sampler->base.destroy = lp_llvm_sampler_soa_destroy;
> - sampler->base.emit_fetch_texel = lp_llvm_sampler_soa_emit_fetch_texel;
> + sampler->base.emit_tex_sample = 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;
>
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>
More information about the mesa-dev
mailing list