diff options
author | Brian Paul <brianp@vmware.com> | 2010-03-05 13:21:56 -0700 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2010-03-05 13:29:25 -0700 |
commit | d660e28c9cc52e55963532939ef383eac983a44b (patch) | |
tree | 2f1c074c052432e919c8f51a4af7427f93b526b6 | |
parent | b5b128b26841e7f947edd8f0cbcc91a530d6bb8f (diff) |
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.
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 107 |
1 files changed, 68 insertions, 39 deletions
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); |