From 61b7da074e2faebf03d3dfc30e910ee1367bcd5a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 23 Sep 2010 18:18:40 -0600 Subject: [PATCH] llvmpipe: make min/max lod and lod bias dynamic state 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. --- src/gallium/auxiliary/gallivm/lp_bld_sample.c | 35 ++++++++++--------- src/gallium/auxiliary/gallivm/lp_bld_sample.h | 18 +++++++++- .../auxiliary/gallivm/lp_bld_sample_aos.c | 2 +- .../auxiliary/gallivm/lp_bld_sample_soa.c | 2 +- src/gallium/drivers/llvmpipe/lp_jit.c | 15 ++++++++ src/gallium/drivers/llvmpipe/lp_jit.h | 7 ++++ src/gallium/drivers/llvmpipe/lp_setup.c | 8 ++++- src/gallium/drivers/llvmpipe/lp_setup.h | 3 +- .../drivers/llvmpipe/lp_state_derived.c | 6 ++-- src/gallium/drivers/llvmpipe/lp_tex_sample.c | 7 ++++ 10 files changed, 79 insertions(+), 24 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c index e89ee7c2302..caf1c7e8656 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c @@ -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; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 8b042d5242e..661f35f6deb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -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 */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c index 7e064900e77..000d4938a03 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c @@ -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); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 91fab18e4e6..cbae1188a59 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -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); } diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 8e6dfb293d0..4c7089892ef 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -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); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index c94189413ab..e94d758e200 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -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 */ }; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index ea7002aafcf..28d202bd655 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -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. */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 81ff43f8adc..868bd3ad2f1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -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, diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index edd723f65f2..d2be22d7fc5 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -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; } diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index 4e026cc8ffb..151fe93cfbb 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -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; -- 2.30.2