From d660e28c9cc52e55963532939ef383eac983a44b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 5 Mar 2010 13:21:56 -0700 Subject: gallivm: implement non-normalized texture wrap modes Note that only the PIPE_TEX_WRAP_CLAMP,CLAMP_TO_EDGE,CLAMP_TO_BORDER modes work with non-normalized texcoords. --- src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 107 ++++++++++++++-------- 1 file changed, 68 insertions(+), 39 deletions(-) (limited to 'src/gallium/auxiliary') diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index fe41d5ee49..50dd1a57c9 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -361,15 +361,10 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0); LLVMValueRef half = lp_build_const_scalar(coord_bld->type, 0.5); LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length); - LLVMValueRef length_minus_one; - LLVMValueRef length_f_minus_one; + LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one); + LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one); LLVMValueRef coord0, coord1, weight; - /* XXX check for normalized vs. unnormalized coords */ - - length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one); - length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one); - switch(wrap_mode) { case PIPE_TEX_WRAP_REPEAT: /* mul by size and subtract 0.5 */ @@ -394,7 +389,9 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, break; case PIPE_TEX_WRAP_CLAMP: - coord = lp_build_mul(coord_bld, coord, length_f); + if (bld->static_state->normalized_coords) { + coord = lp_build_mul(coord_bld, coord, length_f); + } weight = lp_build_fract(coord_bld, coord); coord0 = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f_minus_one); @@ -406,11 +403,20 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, break; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - /* clamp to [0,1] */ - coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, coord_bld->one); - /* mul by tex size and subtract 0.5 */ - coord = lp_build_mul(coord_bld, coord, length_f); - coord = lp_build_sub(coord_bld, coord, half); + if (bld->static_state->normalized_coords) { + /* clamp to [0,1] */ + coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, coord_bld->one); + /* mul by tex size and subtract 0.5 */ + coord = lp_build_mul(coord_bld, coord, length_f); + coord = lp_build_sub(coord_bld, coord, half); + } + else { + LLVMValueRef min, max; + /* clamp to [0.5, length - 0.5] */ + min = lp_build_const_scalar(coord_bld->type, 0.5F); + max = lp_build_sub(coord_bld, length_f, min); + coord = lp_build_clamp(coord_bld, coord, min, max); + } /* compute lerp weight */ weight = lp_build_fract(coord_bld, coord); /* coord0 = floor(coord); */ @@ -425,16 +431,25 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_CLAMP_TO_BORDER: { LLVMValueRef min, max; - /* min = -1.0 / (2 * length) */ - min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f)); - min = lp_build_negate(coord_bld, min); - /* max = 1.0 - min */ - max = lp_build_sub(coord_bld, coord_bld->one, min); - /* coord = clamp(coord, min, max) */ - coord = lp_build_clamp(coord_bld, coord, min, max); - /* scale coord to length (and sub 0.5?) */ - coord = lp_build_mul(coord_bld, coord, length_f); - coord = lp_build_sub(coord_bld, coord, half); + if (bld->static_state->normalized_coords) { + /* min = -1.0 / (2 * length) */ + min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f)); + min = lp_build_negate(coord_bld, min); + /* max = 1.0 - min */ + max = lp_build_sub(coord_bld, coord_bld->one, min); + /* coord = clamp(coord, min, max) */ + coord = lp_build_clamp(coord_bld, coord, min, max); + /* scale coord to length (and sub 0.5?) */ + coord = lp_build_mul(coord_bld, coord, length_f); + coord = lp_build_sub(coord_bld, coord, half); + } + else { + /* clamp to [-0.5, length + 0.5] */ + min = lp_build_const_scalar(coord_bld->type, -0.5F); + max = lp_build_sub(coord_bld, length_f, min); + coord = lp_build_clamp(coord_bld, coord, min, max); + coord = lp_build_sub(coord_bld, coord, half); + } /* compute lerp weight */ weight = lp_build_fract(coord_bld, coord); /* convert to int */ @@ -552,8 +567,6 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one); LLVMValueRef icoord; - /* XXX check for normalized vs. unnormalized coords */ - switch(wrap_mode) { case PIPE_TEX_WRAP_REPEAT: coord = lp_build_mul(coord_bld, coord, length_f); @@ -568,7 +581,9 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_CLAMP: /* mul by size */ - coord = lp_build_mul(coord_bld, coord, length_f); + if (bld->static_state->normalized_coords) { + coord = lp_build_mul(coord_bld, coord, length_f); + } /* floor */ icoord = lp_build_ifloor(coord_bld, coord); /* clamp to [0, size-1]. Note: int coord builder type */ @@ -579,12 +594,19 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_CLAMP_TO_EDGE: { LLVMValueRef min, max; - /* min = 1.0 / (2 * length) */ - min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f)); - /* max = length - min */ - max = lp_build_sub(coord_bld, length_f, min); - /* scale coord to length */ - coord = lp_build_mul(coord_bld, coord, length_f); + if (bld->static_state->normalized_coords) { + /* min = 1.0 / (2 * length) */ + min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f)); + /* max = length - min */ + max = lp_build_sub(coord_bld, length_f, min); + /* scale coord to length */ + coord = lp_build_mul(coord_bld, coord, length_f); + } + else { + /* clamp to [0.5, length - 0.5] */ + min = lp_build_const_scalar(coord_bld->type, 0.5F); + max = lp_build_sub(coord_bld, length_f, min); + } /* coord = clamp(coord, min, max) */ coord = lp_build_clamp(coord_bld, coord, min, max); icoord = lp_build_ifloor(coord_bld, coord); @@ -595,13 +617,20 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, /* Note: this is the same as CLAMP_TO_EDGE, except min = -min */ { LLVMValueRef min, max; - /* min = -1.0 / (2 * length) */ - min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f)); - min = lp_build_negate(coord_bld, min); - /* max = length - min */ - max = lp_build_sub(coord_bld, length_f, min); - /* scale coord to length */ - coord = lp_build_mul(coord_bld, coord, length_f); + if (bld->static_state->normalized_coords) { + /* min = -1.0 / (2 * length) */ + min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f)); + min = lp_build_negate(coord_bld, min); + /* max = length - min */ + max = lp_build_sub(coord_bld, length_f, min); + /* scale coord to length */ + coord = lp_build_mul(coord_bld, coord, length_f); + } + else { + /* clamp to [-0.5, length + 0.5] */ + min = lp_build_const_scalar(coord_bld->type, -0.5F); + max = lp_build_sub(coord_bld, length_f, min); + } /* coord = clamp(coord, min, max) */ coord = lp_build_clamp(coord_bld, coord, min, max); icoord = lp_build_ifloor(coord_bld, coord); -- cgit v1.2.3