Before, changing any of these sampler values triggered generation of new JIT code. Added a new flag for the special case of min_lod == max_lod which is hit during auto mipmap generation.tags/snb-magic
@@ -99,21 +99,21 @@ lp_sampler_static_state(struct lp_sampler_static_state *state, | |||
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]; | |||
@@ -140,6 +140,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state, | |||
*/ | |||
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 */ | |||
@@ -149,20 +150,20 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, | |||
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; | |||
@@ -82,8 +82,9 @@ struct lp_sampler_static_state | |||
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; | |||
@@ -143,6 +144,20 @@ struct lp_sampler_dynamic_state | |||
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); | |||
}; | |||
@@ -248,6 +263,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state, | |||
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 */ |
@@ -970,7 +970,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, | |||
/* 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); | |||
} |
@@ -937,7 +937,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld, | |||
/* 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); | |||
} |
@@ -65,6 +65,11 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) | |||
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, | |||
@@ -88,6 +93,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) | |||
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); | |||
@@ -54,6 +54,10 @@ struct lp_jit_texture | |||
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; | |||
}; | |||
@@ -65,6 +69,9 @@ enum { | |||
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 */ | |||
}; | |||
@@ -617,7 +617,8 @@ lp_setup_set_vertex_info( struct lp_setup_context *setup, | |||
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; | |||
@@ -638,6 +639,11 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, | |||
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. | |||
*/ |
@@ -143,7 +143,8 @@ lp_setup_set_scissor( struct lp_setup_context *setup, | |||
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, |
@@ -208,10 +208,12 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) | |||
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; | |||
} |
@@ -151,6 +151,9 @@ LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE) | |||
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 | |||
@@ -217,6 +220,10 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state, | |||
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; | |||