diff options
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm_sample.c | 31 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample.h | 48 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 227 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 17 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 133 | ||||
-rw-r--r-- | 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 16d075cec0a..32cad59d604 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 be41ca02ae8..b95ee6fb56f 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 598d5fcdb3c..82ef359ed30 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 8d53607b934..3f76b79b8d1 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 3e82036150b..6a71da68acd 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 1828069bf1a..316d1c55082 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; |