state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
}
+ /* If min_lod == max_lod we can greatly simplify mipmap selection.
+ * This is a case that occurs during automatic mipmap generation.
+ */
+ if (sampler->min_lod == sampler->max_lod) {
+ state->min_max_lod_equal = 1;
+ state->min_max_lod = sampler->min_lod;
+ }
+
state->compare_mode = sampler->compare_mode;
if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
state->compare_func = sampler->compare_func;
}
state->normalized_coords = sampler->normalized_coords;
- state->lod_bias = sampler->lod_bias;
- if (!view->last_level &&
- sampler->min_img_filter == sampler->mag_img_filter) {
- state->min_lod = 0.0f;
- state->max_lod = 0.0f;
- } else {
- state->min_lod = MAX2(sampler->min_lod, 0.0f);
- state->max_lod = sampler->max_lod;
- }
+
state->border_color[0] = sampler->border_color[0];
state->border_color[1] = sampler->border_color[1];
state->border_color[2] = sampler->border_color[2];
*/
LLVMValueRef
lp_build_lod_selector(struct lp_build_sample_context *bld,
+ unsigned unit,
const LLVMValueRef ddx[4],
const LLVMValueRef ddy[4],
LLVMValueRef lod_bias, /* optional */
LLVMValueRef depth)
{
- if (bld->static_state->min_lod == bld->static_state->max_lod) {
+ if (bld->static_state->min_max_lod_equal) {
/* User is forcing sampling from a particular mipmap level.
* This is hit during mipmap generation.
*/
- return LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
+ return LLVMConstReal(LLVMFloatType(), bld->static_state->min_max_lod);
}
else {
struct lp_build_context *float_bld = &bld->float_bld;
- LLVMValueRef sampler_lod_bias = LLVMConstReal(LLVMFloatType(),
- bld->static_state->lod_bias);
- LLVMValueRef min_lod = LLVMConstReal(LLVMFloatType(),
- bld->static_state->min_lod);
- LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(),
- bld->static_state->max_lod);
+ LLVMValueRef sampler_lod_bias =
+ bld->dynamic_state->lod_bias(bld->dynamic_state, bld->builder, unit);
+ LLVMValueRef min_lod =
+ bld->dynamic_state->min_lod(bld->dynamic_state, bld->builder, unit);
+ LLVMValueRef max_lod =
+ bld->dynamic_state->max_lod(bld->dynamic_state, bld->builder, unit);
LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
LLVMValueRef lod;
unsigned compare_mode:1;
unsigned compare_func:3;
unsigned normalized_coords:1;
- float lod_bias, min_lod, max_lod;
float border_color[4];
+ unsigned min_max_lod_equal:1; /**< min_lod == max_lod ? */
+ float min_max_lod; /**< only valid when min_max_lod_equal=1 */
/* Aero hacks */
unsigned force_nearest_s:1;
LLVMBuilderRef builder,
unsigned unit);
+ /** Obtain texture min lod */
+ LLVMValueRef
+ (*min_lod)(const struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder, unsigned unit);
+
+ /** Obtain texture max lod */
+ LLVMValueRef
+ (*max_lod)(const struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder, unsigned unit);
+
+ /** Obtain texture lod bias */
+ LLVMValueRef
+ (*lod_bias)(const struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder, unsigned unit);
};
LLVMValueRef
lp_build_lod_selector(struct lp_build_sample_context *bld,
+ unsigned unit,
const LLVMValueRef ddx[4],
const LLVMValueRef ddy[4],
LLVMValueRef lod_bias, /* optional */
/* Need to compute lod either to choose mipmap levels or to
* distinguish between minification/magnification with one mipmap level.
*/
- lod = lp_build_lod_selector(bld, ddx, ddy,
+ lod = lp_build_lod_selector(bld, unit, ddx, ddy,
lod_bias, explicit_lod,
width, height, depth);
}
/* Need to compute lod either to choose mipmap levels or to
* distinguish between minification/magnification with one mipmap level.
*/
- lod = lp_build_lod_selector(bld, ddx, ddy,
+ lod = lp_build_lod_selector(bld, unit, ddx, ddy,
lod_bias, explicit_lod,
width, height, depth);
}
LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
LP_MAX_TEXTURE_LEVELS);
+ elem_types[LP_JIT_TEXTURE_MIN_LOD] = LLVMFloatType();
+ elem_types[LP_JIT_TEXTURE_MAX_LOD] = LLVMFloatType();
+ elem_types[LP_JIT_TEXTURE_LOD_BIAS] = LLVMFloatType();
+
+
texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width,
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
screen->target, texture_type,
LP_JIT_TEXTURE_DATA);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, min_lod,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_MIN_LOD);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, max_lod,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_MAX_LOD);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, lod_bias,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_LOD_BIAS);
+
LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
screen->target, texture_type);
uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
const void *data[LP_MAX_TEXTURE_LEVELS];
+ /* sampler state, actually */
+ float min_lod;
+ float max_lod;
+ float lod_bias;
};
LP_JIT_TEXTURE_ROW_STRIDE,
LP_JIT_TEXTURE_IMG_STRIDE,
LP_JIT_TEXTURE_DATA,
+ LP_JIT_TEXTURE_MIN_LOD,
+ LP_JIT_TEXTURE_MAX_LOD,
+ LP_JIT_TEXTURE_LOD_BIAS,
LP_JIT_TEXTURE_NUM_FIELDS /* number of fields above */
};
void
lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
unsigned num,
- struct pipe_sampler_view **views)
+ struct pipe_sampler_view **views,
+ const struct pipe_sampler_state **samplers)
{
unsigned i;
jit_tex->depth = tex->depth0;
jit_tex->last_level = tex->last_level;
+ /* sampler state */
+ jit_tex->min_lod = samplers[i]->min_lod;
+ jit_tex->max_lod = samplers[i]->max_lod;
+ jit_tex->lod_bias = samplers[i]->lod_bias;
+
/* We're referencing the texture's internal data, so save a
* reference to it.
*/
void
lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
unsigned num,
- struct pipe_sampler_view **views);
+ struct pipe_sampler_view **views,
+ const struct pipe_sampler_state **samplers);
unsigned
lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
lp_setup_set_fs_constants(llvmpipe->setup,
llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);
- if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
+ if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW |
+ LP_NEW_SAMPLER))
lp_setup_set_fragment_sampler_views(llvmpipe->setup,
llvmpipe->num_fragment_sampler_views,
- llvmpipe->fragment_sampler_views);
+ llvmpipe->fragment_sampler_views,
+ llvmpipe->sampler);
llvmpipe->dirty = 0;
}
LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
LP_LLVM_TEXTURE_MEMBER(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE)
LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA, FALSE)
+LP_LLVM_TEXTURE_MEMBER(min_lod, LP_JIT_TEXTURE_MIN_LOD, TRUE)
+LP_LLVM_TEXTURE_MEMBER(max_lod, LP_JIT_TEXTURE_MAX_LOD, TRUE)
+LP_LLVM_TEXTURE_MEMBER(lod_bias, LP_JIT_TEXTURE_LOD_BIAS, TRUE)
static void
sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride;
sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
+ sampler->dynamic_state.base.min_lod = lp_llvm_texture_min_lod;
+ sampler->dynamic_state.base.max_lod = lp_llvm_texture_max_lod;
+ sampler->dynamic_state.base.lod_bias = lp_llvm_texture_lod_bias;
+
sampler->dynamic_state.static_state = static_state;
sampler->dynamic_state.context_ptr = context_ptr;