llvmpipe: Get blending of normalized 8bit unsigned integers working.
This commit is contained in:
parent
a6622e6c54
commit
ede73258a7
|
@ -184,7 +184,7 @@ lp_build_one(union lp_type type)
|
|||
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
|
||||
unsigned i;
|
||||
|
||||
assert(type.length < LP_MAX_VECTOR_LENGTH);
|
||||
assert(type.length <= LP_MAX_VECTOR_LENGTH);
|
||||
|
||||
elem_type = lp_build_elem_type(type);
|
||||
|
||||
|
@ -224,7 +224,7 @@ lp_build_const_aos(union lp_type type,
|
|||
unsigned i;
|
||||
|
||||
assert(type.length % 4 == 0);
|
||||
assert(type.length < LP_MAX_VECTOR_LENGTH);
|
||||
assert(type.length <= LP_MAX_VECTOR_LENGTH);
|
||||
|
||||
elem_type = lp_build_elem_type(type);
|
||||
|
||||
|
@ -421,9 +421,9 @@ lp_build_add(struct lp_build_context *bld,
|
|||
if(type.width * type.length == 128 &&
|
||||
!type.floating && !type.fixed) {
|
||||
if(type.width == 8)
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.adds.b" : "llvm.x86.sse2.addus.b";
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.padds.b" : "llvm.x86.sse2.paddus.b";
|
||||
if(type.width == 16)
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.adds.w" : "llvm.x86.sse2.addus.w";
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.padds.w" : "llvm.x86.sse2.paddus.w";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -468,9 +468,9 @@ lp_build_sub(struct lp_build_context *bld,
|
|||
if(type.width * type.length == 128 &&
|
||||
!type.floating && !type.fixed) {
|
||||
if(type.width == 8)
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.subs.b" : "llvm.x86.sse2.subus.b";
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.psubs.b" : "llvm.x86.sse2.psubus.b";
|
||||
if(type.width == 16)
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.subs.w" : "llvm.x86.sse2.subus.w";
|
||||
intrinsic = type.sign ? "llvm.x86.sse2.psubs.w" : "llvm.x86.sse2.psubus.w";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -490,11 +490,124 @@ lp_build_sub(struct lp_build_context *bld,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build shuffle vectors that match PUNPCKLxx and PUNPCKHxx instructions.
|
||||
*/
|
||||
static LLVMValueRef
|
||||
lp_build_unpack_shuffle(unsigned n, unsigned lo_hi)
|
||||
{
|
||||
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
|
||||
unsigned i, j;
|
||||
|
||||
assert(n <= LP_MAX_VECTOR_LENGTH);
|
||||
assert(lo_hi < 2);
|
||||
|
||||
for(i = 0, j = lo_hi*n/2; i < n; i += 2, ++j) {
|
||||
elems[i + 0] = LLVMConstInt(LLVMInt32Type(), 0 + j, 0);
|
||||
elems[i + 1] = LLVMConstInt(LLVMInt32Type(), n + j, 0);
|
||||
}
|
||||
|
||||
return LLVMConstVector(elems, n);
|
||||
}
|
||||
|
||||
|
||||
static LLVMValueRef
|
||||
lp_build_const_vec(LLVMTypeRef type, unsigned n, long long c)
|
||||
{
|
||||
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
|
||||
unsigned i;
|
||||
|
||||
assert(n <= LP_MAX_VECTOR_LENGTH);
|
||||
|
||||
for(i = 0; i < n; ++i)
|
||||
elems[i] = LLVMConstInt(type, c, 0);
|
||||
|
||||
return LLVMConstVector(elems, n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalized 8bit multiplication.
|
||||
*
|
||||
* - alpha plus one
|
||||
*
|
||||
* makes the following approximation to the division (Sree)
|
||||
*
|
||||
* a*b/255 ~= (a*(b + 1)) >> 256
|
||||
*
|
||||
* which is the fastest method that satisfies the following OpenGL criteria
|
||||
*
|
||||
* 0*0 = 0 and 255*255 = 255
|
||||
*
|
||||
* - geometric series
|
||||
*
|
||||
* takes the geometric series approximation to the division
|
||||
*
|
||||
* t/255 = (t >> 8) + (t >> 16) + (t >> 24) ..
|
||||
*
|
||||
* in this case just the first two terms to fit in 16bit arithmetic
|
||||
*
|
||||
* t/255 ~= (t + (t >> 8)) >> 8
|
||||
*
|
||||
* note that just by itself it doesn't satisfies the OpenGL criteria, as
|
||||
* 255*255 = 254, so the special case b = 255 must be accounted or roundoff
|
||||
* must be used
|
||||
*
|
||||
* - geometric series plus rounding
|
||||
*
|
||||
* when using a geometric series division instead of truncating the result
|
||||
* use roundoff in the approximation (Jim Blinn)
|
||||
*
|
||||
* t/255 ~= (t + (t >> 8) + 0x80) >> 8
|
||||
*
|
||||
* achieving the exact results
|
||||
*
|
||||
* @sa Alvy Ray Smith, Image Compositing Fundamentals, Tech Memo 4, Aug 15, 1995,
|
||||
* ftp://ftp.alvyray.com/Acrobat/4_Comp.pdf
|
||||
* @sa Michael Herf, The "double blend trick", May 2000,
|
||||
* http://www.stereopsis.com/doubleblend.html
|
||||
*/
|
||||
static LLVMValueRef
|
||||
lp_build_mul_u8n(LLVMBuilderRef builder,
|
||||
LLVMValueRef a, LLVMValueRef b)
|
||||
{
|
||||
static LLVMValueRef c01 = NULL;
|
||||
static LLVMValueRef c08 = NULL;
|
||||
static LLVMValueRef c80 = NULL;
|
||||
LLVMValueRef ab;
|
||||
|
||||
if(!c01) c01 = lp_build_const_vec(LLVMInt16Type(), 8, 0x01);
|
||||
if(!c08) c08 = lp_build_const_vec(LLVMInt16Type(), 8, 0x08);
|
||||
if(!c80) c80 = lp_build_const_vec(LLVMInt16Type(), 8, 0x80);
|
||||
|
||||
#if 0
|
||||
|
||||
/* a*b/255 ~= (a*(b + 1)) >> 256 */
|
||||
b = LLVMBuildAdd(builder, b, c01, "");
|
||||
ab = LLVMBuildMul(builder, a, b, "");
|
||||
|
||||
#else
|
||||
|
||||
/* t/255 ~= (t + (t >> 8) + 0x80) >> 8 */
|
||||
ab = LLVMBuildMul(builder, a, b, "");
|
||||
ab = LLVMBuildAdd(builder, ab, LLVMBuildLShr(builder, ab, c08, ""), "");
|
||||
ab = LLVMBuildAdd(builder, ab, c80, "");
|
||||
|
||||
#endif
|
||||
|
||||
ab = LLVMBuildLShr(builder, ab, c08, "");
|
||||
|
||||
return ab;
|
||||
}
|
||||
|
||||
|
||||
LLVMValueRef
|
||||
lp_build_mul(struct lp_build_context *bld,
|
||||
LLVMValueRef a,
|
||||
LLVMValueRef b)
|
||||
{
|
||||
const union lp_type type = bld->type;
|
||||
|
||||
if(a == bld->zero)
|
||||
return bld->zero;
|
||||
if(a == bld->one)
|
||||
|
@ -506,6 +619,50 @@ lp_build_mul(struct lp_build_context *bld,
|
|||
if(a == bld->undef || b == bld->undef)
|
||||
return bld->undef;
|
||||
|
||||
if(!type.floating && !type.fixed && type.norm) {
|
||||
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
|
||||
if(type.width == 8 && type.length == 16) {
|
||||
LLVMTypeRef i16x8 = LLVMVectorType(LLVMInt16Type(), 8);
|
||||
LLVMTypeRef i8x16 = LLVMVectorType(LLVMInt8Type(), 16);
|
||||
static LLVMValueRef ml = NULL;
|
||||
static LLVMValueRef mh = NULL;
|
||||
LLVMValueRef al, ah, bl, bh;
|
||||
LLVMValueRef abl, abh;
|
||||
LLVMValueRef ab;
|
||||
|
||||
if(!ml) ml = lp_build_unpack_shuffle(16, 0);
|
||||
if(!mh) mh = lp_build_unpack_shuffle(16, 1);
|
||||
|
||||
/* PUNPCKLBW, PUNPCKHBW */
|
||||
al = LLVMBuildShuffleVector(bld->builder, a, bld->zero, ml, "");
|
||||
bl = LLVMBuildShuffleVector(bld->builder, b, bld->zero, ml, "");
|
||||
ah = LLVMBuildShuffleVector(bld->builder, a, bld->zero, mh, "");
|
||||
bh = LLVMBuildShuffleVector(bld->builder, b, bld->zero, mh, "");
|
||||
|
||||
/* NOP */
|
||||
al = LLVMBuildBitCast(bld->builder, al, i16x8, "");
|
||||
bl = LLVMBuildBitCast(bld->builder, bl, i16x8, "");
|
||||
ah = LLVMBuildBitCast(bld->builder, ah, i16x8, "");
|
||||
bh = LLVMBuildBitCast(bld->builder, bh, i16x8, "");
|
||||
|
||||
/* PMULLW, PSRLW, PADDW */
|
||||
abl = lp_build_mul_u8n(bld->builder, al, bl);
|
||||
abh = lp_build_mul_u8n(bld->builder, ah, bh);
|
||||
|
||||
/* PACKUSWB */
|
||||
ab = lp_build_intrinsic_binary(bld->builder, "llvm.x86.sse2.packuswb.128" , abl, abh);
|
||||
|
||||
/* NOP */
|
||||
ab = LLVMBuildBitCast(bld->builder, ab, i8x16, "");
|
||||
|
||||
return ab;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FIXME */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if(LLVMIsConstant(a) && LLVMIsConstant(b))
|
||||
return LLVMConstMul(a, b);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
|
@ -58,15 +59,15 @@
|
|||
unsigned verbose = 0;
|
||||
|
||||
|
||||
typedef void (*blend_test_ptr_t)(const float *src, const float *dst, const float *const_, float *res);
|
||||
typedef void (*blend_test_ptr_t)(const void *src, const void *dst, const void *con, void *res);
|
||||
|
||||
|
||||
static LLVMValueRef
|
||||
add_blend_test(LLVMModuleRef module,
|
||||
const struct pipe_blend_state *blend)
|
||||
const struct pipe_blend_state *blend,
|
||||
union lp_type type)
|
||||
{
|
||||
union lp_type type;
|
||||
|
||||
LLVMTypeRef vec_type;
|
||||
LLVMTypeRef args[4];
|
||||
LLVMValueRef func;
|
||||
LLVMValueRef src_ptr;
|
||||
|
@ -77,20 +78,12 @@ add_blend_test(LLVMModuleRef module,
|
|||
LLVMBuilderRef builder;
|
||||
LLVMValueRef src;
|
||||
LLVMValueRef dst;
|
||||
LLVMValueRef const_;
|
||||
LLVMValueRef con;
|
||||
LLVMValueRef res;
|
||||
|
||||
type.value = 0;
|
||||
type.floating = TRUE;
|
||||
type.sign = TRUE;
|
||||
type.norm = TRUE;
|
||||
type.width = 32;
|
||||
type.length = 4;
|
||||
vec_type = lp_build_vec_type(type);
|
||||
|
||||
args[0] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
|
||||
args[1] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
|
||||
args[2] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
|
||||
args[3] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
|
||||
args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
|
||||
func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidType(), args, 4, 0));
|
||||
LLVMSetFunctionCallConv(func, LLVMCCallConv);
|
||||
src_ptr = LLVMGetParam(func, 0);
|
||||
|
@ -104,9 +97,9 @@ add_blend_test(LLVMModuleRef module,
|
|||
|
||||
src = LLVMBuildLoad(builder, src_ptr, "src");
|
||||
dst = LLVMBuildLoad(builder, dst_ptr, "dst");
|
||||
const_ = LLVMBuildLoad(builder, const_ptr, "const");
|
||||
con = LLVMBuildLoad(builder, const_ptr, "const");
|
||||
|
||||
res = lp_build_blend(builder, blend, type, src, dst, const_, 3);
|
||||
res = lp_build_blend(builder, blend, type, src, dst, con, 3);
|
||||
|
||||
LLVMSetValueName(res, "res");
|
||||
|
||||
|
@ -119,13 +112,10 @@ add_blend_test(LLVMModuleRef module,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
random_color(float *color)
|
||||
static float
|
||||
random_float(void)
|
||||
{
|
||||
color[0] = (float)((double)random()/(double)RAND_MAX);
|
||||
color[1] = (float)((double)random()/(double)RAND_MAX);
|
||||
color[2] = (float)((double)random()/(double)RAND_MAX);
|
||||
color[3] = (float)((double)random()/(double)RAND_MAX);
|
||||
return (float)((double)random()/(double)RAND_MAX);
|
||||
}
|
||||
|
||||
|
||||
|
@ -148,7 +138,7 @@ compute_blend_ref_term(unsigned rgb_factor,
|
|||
const float *factor,
|
||||
const float *src,
|
||||
const float *dst,
|
||||
const float *const_,
|
||||
const float *con,
|
||||
float *term)
|
||||
{
|
||||
float temp;
|
||||
|
@ -186,14 +176,14 @@ compute_blend_ref_term(unsigned rgb_factor,
|
|||
term[2] = factor[2] * temp; /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
term[0] = factor[0] * const_[0]; /* R */
|
||||
term[1] = factor[1] * const_[1]; /* G */
|
||||
term[2] = factor[2] * const_[2]; /* B */
|
||||
term[0] = factor[0] * con[0]; /* R */
|
||||
term[1] = factor[1] * con[1]; /* G */
|
||||
term[2] = factor[2] * con[2]; /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
term[0] = factor[0] * const_[3]; /* R */
|
||||
term[1] = factor[1] * const_[3]; /* G */
|
||||
term[2] = factor[2] * const_[3]; /* B */
|
||||
term[0] = factor[0] * con[3]; /* R */
|
||||
term[1] = factor[1] * con[3]; /* G */
|
||||
term[2] = factor[2] * con[3]; /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC1_COLOR:
|
||||
assert(0); /* to do */
|
||||
|
@ -227,14 +217,14 @@ compute_blend_ref_term(unsigned rgb_factor,
|
|||
term[2] = factor[2] * (1.0f - dst[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
term[0] = factor[0] * (1.0f - const_[0]); /* R */
|
||||
term[1] = factor[1] * (1.0f - const_[1]); /* G */
|
||||
term[2] = factor[2] * (1.0f - const_[2]); /* B */
|
||||
term[0] = factor[0] * (1.0f - con[0]); /* R */
|
||||
term[1] = factor[1] * (1.0f - con[1]); /* G */
|
||||
term[2] = factor[2] * (1.0f - con[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
term[0] = factor[0] * (1.0f - const_[3]); /* R */
|
||||
term[1] = factor[1] * (1.0f - const_[3]); /* G */
|
||||
term[2] = factor[2] * (1.0f - const_[3]); /* B */
|
||||
term[0] = factor[0] * (1.0f - con[3]); /* R */
|
||||
term[1] = factor[1] * (1.0f - con[3]); /* G */
|
||||
term[2] = factor[2] * (1.0f - con[3]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
|
||||
assert(0); /* to do */
|
||||
|
@ -266,7 +256,7 @@ compute_blend_ref_term(unsigned rgb_factor,
|
|||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
term[3] = factor[3] * const_[3]; /* A */
|
||||
term[3] = factor[3] * con[3]; /* A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_ZERO:
|
||||
term[3] = 0.0f; /* A */
|
||||
|
@ -281,7 +271,7 @@ compute_blend_ref_term(unsigned rgb_factor,
|
|||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
term[3] = factor[3] * (1.0f - const_[3]);
|
||||
term[3] = factor[3] * (1.0f - con[3]);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
@ -293,14 +283,14 @@ static void
|
|||
compute_blend_ref(const struct pipe_blend_state *blend,
|
||||
const float *src,
|
||||
const float *dst,
|
||||
const float *const_,
|
||||
const float *con,
|
||||
float *res)
|
||||
{
|
||||
float src_term[4];
|
||||
float dst_term[4];
|
||||
|
||||
compute_blend_ref_term(blend->rgb_src_factor, blend->alpha_src_factor, src, src, dst, const_, src_term);
|
||||
compute_blend_ref_term(blend->rgb_dst_factor, blend->alpha_dst_factor, dst, src, dst, const_, dst_term);
|
||||
compute_blend_ref_term(blend->rgb_src_factor, blend->alpha_src_factor, src, src, dst, con, src_term);
|
||||
compute_blend_ref_term(blend->rgb_dst_factor, blend->alpha_dst_factor, dst, src, dst, con, dst_term);
|
||||
|
||||
/*
|
||||
* Combine RGB terms
|
||||
|
@ -361,7 +351,8 @@ compute_blend_ref(const struct pipe_blend_state *blend,
|
|||
|
||||
|
||||
static boolean
|
||||
test_one(const struct pipe_blend_state *blend)
|
||||
test_one(const struct pipe_blend_state *blend,
|
||||
union lp_type type)
|
||||
{
|
||||
LLVMModuleRef module = NULL;
|
||||
LLVMValueRef func = NULL;
|
||||
|
@ -371,11 +362,11 @@ test_one(const struct pipe_blend_state *blend)
|
|||
char *error = NULL;
|
||||
blend_test_ptr_t blend_test_ptr;
|
||||
boolean success;
|
||||
unsigned i, j;
|
||||
unsigned i, j, k;
|
||||
|
||||
module = LLVMModuleCreateWithName("test");
|
||||
|
||||
func = add_blend_test(module, blend);
|
||||
func = add_blend_test(module, blend, type);
|
||||
|
||||
if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
|
||||
LLVMDumpModule(module);
|
||||
|
@ -412,28 +403,97 @@ test_one(const struct pipe_blend_state *blend)
|
|||
|
||||
success = TRUE;
|
||||
for(i = 0; i < 10; ++i) {
|
||||
float src[4];
|
||||
float dst[4];
|
||||
float const_[4];
|
||||
float ref[4];
|
||||
float res[4];
|
||||
if(type.floating && type.width == 32) {
|
||||
float src[LP_MAX_VECTOR_LENGTH];
|
||||
float dst[LP_MAX_VECTOR_LENGTH];
|
||||
float con[LP_MAX_VECTOR_LENGTH];
|
||||
float ref[LP_MAX_VECTOR_LENGTH];
|
||||
float res[LP_MAX_VECTOR_LENGTH];
|
||||
|
||||
random_color(src);
|
||||
random_color(dst);
|
||||
random_color(const_);
|
||||
for(j = 0; j < type.length; ++j) {
|
||||
src[j] = random_float();
|
||||
dst[j] = random_float();
|
||||
con[j] = random_float();
|
||||
}
|
||||
|
||||
compute_blend_ref(blend, src, dst, const_, ref);
|
||||
for(j = 0; j < type.length; j += 4)
|
||||
compute_blend_ref(blend, src + j, dst + j, con + j, ref + j);
|
||||
|
||||
blend_test_ptr(src, dst, const_, res);
|
||||
blend_test_ptr(src, dst, con, res);
|
||||
|
||||
for(j = 0; j < 4; ++j)
|
||||
if(res[j] != ref[j])
|
||||
success = FALSE;
|
||||
for(j = 0; j < type.length; ++j)
|
||||
if(fabs(res[j] - ref[j]) > FLT_EPSILON)
|
||||
success = FALSE;
|
||||
|
||||
if (!success) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
fprintf(stderr, " Result: ");
|
||||
for(j = 0; j < type.length; ++j)
|
||||
fprintf(stderr, " %f", res[j]);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " Expected: ");
|
||||
for(j = 0; j < type.length; ++j)
|
||||
fprintf(stderr, " %f", ref[j]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
else if(!type.floating && !type.fixed && !type.sign && type.norm && type.width == 8) {
|
||||
uint8_t src[LP_MAX_VECTOR_LENGTH];
|
||||
uint8_t dst[LP_MAX_VECTOR_LENGTH];
|
||||
uint8_t con[LP_MAX_VECTOR_LENGTH];
|
||||
uint8_t ref[LP_MAX_VECTOR_LENGTH];
|
||||
uint8_t res[LP_MAX_VECTOR_LENGTH];
|
||||
|
||||
for(j = 0; j < type.length; ++j) {
|
||||
src[j] = random() & 0xff;
|
||||
dst[j] = random() & 0xff;
|
||||
con[j] = random() & 0xff;
|
||||
}
|
||||
|
||||
for(j = 0; j < type.length; j += 4) {
|
||||
float srcf[4];
|
||||
float dstf[4];
|
||||
float conf[4];
|
||||
float reff[4];
|
||||
|
||||
for(k = 0; k < 4; ++k) {
|
||||
srcf[k] = (1.0f/255.0f)*src[j + k];
|
||||
dstf[k] = (1.0f/255.0f)*dst[j + k];
|
||||
conf[k] = (1.0f/255.0f)*con[j + k];
|
||||
}
|
||||
|
||||
compute_blend_ref(blend, srcf, dstf, conf, reff);
|
||||
|
||||
for(k = 0; k < 4; ++k)
|
||||
ref[j + k] = (uint8_t)(reff[k]*255.0f + 0.5f);
|
||||
}
|
||||
|
||||
blend_test_ptr(src, dst, con, res);
|
||||
|
||||
for(j = 0; j < type.length; ++j) {
|
||||
int delta = (int)res[j] - (int)ref[j];
|
||||
if (delta < 0)
|
||||
delta = -delta;
|
||||
if(delta > 1)
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
fprintf(stderr, " Result: ");
|
||||
for(j = 0; j < type.length; ++j)
|
||||
fprintf(stderr, " %3u", res[j]);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " Expected: ");
|
||||
for(j = 0; j < type.length; ++j)
|
||||
fprintf(stderr, " %3u", ref[j]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
if (!success) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
fprintf(stderr, " Result: %f %f %f %f\n", res[0], res[1], res[2], res[3]);
|
||||
fprintf(stderr, " %f %f %f %f\n", ref[0], ref[1], ref[2], ref[3]);
|
||||
LLVMDumpModule(module);
|
||||
LLVMWriteBitcodeToFile(module, "blend.bc");
|
||||
fprintf(stderr, "blend.bc written\n");
|
||||
|
@ -497,8 +557,16 @@ blend_funcs[] = {
|
|||
};
|
||||
|
||||
|
||||
const union lp_type blend_types[] = {
|
||||
/* float, fixed, sign, norm, width, len */
|
||||
{{ TRUE, FALSE, TRUE, TRUE, 32, 4 }}, /* f32 x 4 */
|
||||
{{ FALSE, FALSE, FALSE, TRUE, 8, 16 }}, /* u8n x 16 */
|
||||
};
|
||||
|
||||
|
||||
const unsigned num_funcs = sizeof(blend_funcs)/sizeof(blend_funcs[0]);
|
||||
const unsigned num_factors = sizeof(blend_factors)/sizeof(blend_factors[0]);
|
||||
const unsigned num_types = sizeof(blend_types)/sizeof(blend_types[0]);
|
||||
|
||||
|
||||
static boolean
|
||||
|
@ -511,6 +579,7 @@ test_all(void)
|
|||
const struct value_name_pair *alpha_src_factor;
|
||||
const struct value_name_pair *alpha_dst_factor;
|
||||
struct pipe_blend_state blend;
|
||||
const union lp_type *type;
|
||||
bool success = TRUE;
|
||||
|
||||
for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) {
|
||||
|
@ -519,33 +588,35 @@ test_all(void)
|
|||
for(rgb_dst_factor = blend_factors; rgb_dst_factor <= rgb_src_factor; ++rgb_dst_factor) {
|
||||
for(alpha_src_factor = blend_factors; alpha_src_factor < &blend_factors[num_factors]; ++alpha_src_factor) {
|
||||
for(alpha_dst_factor = blend_factors; alpha_dst_factor <= alpha_src_factor; ++alpha_dst_factor) {
|
||||
for(type = blend_types; type < &blend_types[num_types]; ++type) {
|
||||
|
||||
if(rgb_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
|
||||
alpha_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
|
||||
continue;
|
||||
if(rgb_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
|
||||
alpha_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
|
||||
continue;
|
||||
|
||||
if(verbose >= 1)
|
||||
fprintf(stderr,
|
||||
"%s=%s %s=%s %s=%s %s=%s %s=%s %s=%s ...\n",
|
||||
"rgb_func", rgb_func->name,
|
||||
"rgb_src_factor", rgb_src_factor->name,
|
||||
"rgb_dst_factor", rgb_dst_factor->name,
|
||||
"alpha_func", alpha_func->name,
|
||||
"alpha_src_factor", alpha_src_factor->name,
|
||||
"alpha_dst_factor", alpha_dst_factor->name);
|
||||
if(verbose >= 1)
|
||||
fprintf(stderr,
|
||||
"%s=%s %s=%s %s=%s %s=%s %s=%s %s=%s ...\n",
|
||||
"rgb_func", rgb_func->name,
|
||||
"rgb_src_factor", rgb_src_factor->name,
|
||||
"rgb_dst_factor", rgb_dst_factor->name,
|
||||
"alpha_func", alpha_func->name,
|
||||
"alpha_src_factor", alpha_src_factor->name,
|
||||
"alpha_dst_factor", alpha_dst_factor->name);
|
||||
|
||||
memset(&blend, 0, sizeof blend);
|
||||
blend.blend_enable = 1;
|
||||
blend.rgb_func = rgb_func->value;
|
||||
blend.rgb_src_factor = rgb_src_factor->value;
|
||||
blend.rgb_dst_factor = rgb_dst_factor->value;
|
||||
blend.alpha_func = alpha_func->value;
|
||||
blend.alpha_src_factor = alpha_src_factor->value;
|
||||
blend.alpha_dst_factor = alpha_dst_factor->value;
|
||||
memset(&blend, 0, sizeof blend);
|
||||
blend.blend_enable = 1;
|
||||
blend.rgb_func = rgb_func->value;
|
||||
blend.rgb_src_factor = rgb_src_factor->value;
|
||||
blend.rgb_dst_factor = rgb_dst_factor->value;
|
||||
blend.alpha_func = alpha_func->value;
|
||||
blend.alpha_src_factor = alpha_src_factor->value;
|
||||
blend.alpha_dst_factor = alpha_dst_factor->value;
|
||||
|
||||
if(!test_one(&blend))
|
||||
success = FALSE;
|
||||
if(!test_one(&blend, *type))
|
||||
success = FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -567,6 +638,7 @@ test_some(unsigned long n)
|
|||
const struct value_name_pair *alpha_src_factor;
|
||||
const struct value_name_pair *alpha_dst_factor;
|
||||
struct pipe_blend_state blend;
|
||||
const union lp_type *type;
|
||||
unsigned long i;
|
||||
bool success = TRUE;
|
||||
|
||||
|
@ -584,28 +656,31 @@ test_some(unsigned long n)
|
|||
alpha_dst_factor = &blend_factors[random() % num_factors];
|
||||
} while(alpha_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
|
||||
|
||||
if(verbose >= 1)
|
||||
fprintf(stderr,
|
||||
"%s=%s %s=%s %s=%s %s=%s %s=%s %s=%s ...\n",
|
||||
"rgb_func", rgb_func->name,
|
||||
"rgb_src_factor", rgb_src_factor->name,
|
||||
"rgb_dst_factor", rgb_dst_factor->name,
|
||||
"alpha_func", alpha_func->name,
|
||||
"alpha_src_factor", alpha_src_factor->name,
|
||||
"alpha_dst_factor", alpha_dst_factor->name);
|
||||
for(type = blend_types; type < &blend_types[num_types]; ++type) {
|
||||
|
||||
memset(&blend, 0, sizeof blend);
|
||||
blend.blend_enable = 1;
|
||||
blend.rgb_func = rgb_func->value;
|
||||
blend.rgb_src_factor = rgb_src_factor->value;
|
||||
blend.rgb_dst_factor = rgb_dst_factor->value;
|
||||
blend.alpha_func = alpha_func->value;
|
||||
blend.alpha_src_factor = alpha_src_factor->value;
|
||||
blend.alpha_dst_factor = alpha_dst_factor->value;
|
||||
if(verbose >= 1)
|
||||
fprintf(stderr,
|
||||
"%s=%s %s=%s %s=%s %s=%s %s=%s %s=%s ...\n",
|
||||
"rgb_func", rgb_func->name,
|
||||
"rgb_src_factor", rgb_src_factor->name,
|
||||
"rgb_dst_factor", rgb_dst_factor->name,
|
||||
"alpha_func", alpha_func->name,
|
||||
"alpha_src_factor", alpha_src_factor->name,
|
||||
"alpha_dst_factor", alpha_dst_factor->name);
|
||||
|
||||
if(!test_one(&blend))
|
||||
success = FALSE;
|
||||
memset(&blend, 0, sizeof blend);
|
||||
blend.blend_enable = 1;
|
||||
blend.rgb_func = rgb_func->value;
|
||||
blend.rgb_src_factor = rgb_src_factor->value;
|
||||
blend.rgb_dst_factor = rgb_dst_factor->value;
|
||||
blend.alpha_func = alpha_func->value;
|
||||
blend.alpha_src_factor = alpha_src_factor->value;
|
||||
blend.alpha_dst_factor = alpha_dst_factor->value;
|
||||
|
||||
if(!test_one(&blend, *type))
|
||||
success = FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
Loading…
Reference in New Issue