summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2015-03-28 20:51:23 +0100
committerRoland Scheidegger <[email protected]>2015-03-31 17:23:51 +0200
commit1863ed21ffbb3ab7fd9875dc25e32ececea79d50 (patch)
treea121276df53929126c0a7065fb068710b87a168d
parent0fc5b80e7abae061dd5b0a17a0e775619a5245be (diff)
gallivm: simplify sampler interface
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. Reviewed-by: Jose Fonseca <[email protected]>
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm_sample.c31
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h48
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c227
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h17
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c133
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.c33
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(&params, 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,
+ &params);
}
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(&params, 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,
+ &params);
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(&params, 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,
+ &params);
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;