llvmpipe: Make lerping work for 8.8 fixed point values.

This commit is contained in:
José Fonseca 2009-10-25 09:16:38 +00:00
parent bfd7a9ca96
commit f3893ca9c8

View file

@ -361,6 +361,8 @@ lp_build_mul(struct lp_build_context *bld,
LLVMValueRef b)
{
const struct lp_type type = bld->type;
LLVMValueRef shift;
LLVMValueRef res;
if(a == bld->zero)
return bld->zero;
@ -394,10 +396,31 @@ lp_build_mul(struct lp_build_context *bld,
assert(0);
}
if(LLVMIsConstant(a) && LLVMIsConstant(b))
return LLVMConstMul(a, b);
if(type.fixed)
shift = lp_build_int_const_scalar(type, type.width/2);
else
shift = NULL;
return LLVMBuildMul(bld->builder, a, b, "");
if(LLVMIsConstant(a) && LLVMIsConstant(b)) {
res = LLVMConstMul(a, b);
if(shift) {
if(type.sign)
res = LLVMConstAShr(res, shift);
else
res = LLVMConstLShr(res, shift);
}
}
else {
res = LLVMBuildMul(bld->builder, a, b, "");
if(shift) {
if(type.sign)
res = LLVMBuildAShr(bld->builder, res, shift, "");
else
res = LLVMBuildLShr(bld->builder, res, shift, "");
}
}
return res;
}
@ -432,13 +455,36 @@ lp_build_div(struct lp_build_context *bld,
}
/**
* Linear interpolation.
*
* This also works for integer values with a few caveats.
*
* @sa http://www.stereopsis.com/doubleblend.html
*/
LLVMValueRef
lp_build_lerp(struct lp_build_context *bld,
LLVMValueRef x,
LLVMValueRef v0,
LLVMValueRef v1)
{
return lp_build_add(bld, v0, lp_build_mul(bld, x, lp_build_sub(bld, v1, v0)));
LLVMValueRef delta;
LLVMValueRef res;
delta = lp_build_sub(bld, v1, v0);
res = lp_build_mul(bld, x, delta);
res = lp_build_add(bld, v0, res);
if(bld->type.fixed)
/* XXX: This step is necessary for lerping 8bit colors stored on 16bits,
* but it will be wrong for other uses. Basically we need a more
* powerful lp_type, capable of further distinguishing the values
* interpretation from the value storage. */
res = LLVMBuildAnd(bld->builder, res, lp_build_int_const_scalar(bld->type, (1 << bld->type.width/2) - 1), "");
return res;
}