From fe5a483328907776f05b3653421fa565bc07b7ac Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 20 Apr 2010 15:09:02 +0200 Subject: [PATCH] gallivm: Cleanups and bugfixes to aos format translation. --- src/gallium/auxiliary/gallivm/lp_bld_format.h | 8 - .../auxiliary/gallivm/lp_bld_format_aos.c | 156 +++---------- src/gallium/drivers/llvmpipe/lp_test_format.c | 221 +++++++----------- 3 files changed, 126 insertions(+), 259 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h index 13d0de875d7..ecf2cfd62c0 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h @@ -51,14 +51,6 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, const struct util_format_description *desc, LLVMValueRef packed); - -LLVMValueRef -lp_build_unpack_rgba8_aos(LLVMBuilderRef builder, - const struct util_format_description *desc, - struct lp_type type, - LLVMValueRef packed); - - LLVMValueRef lp_build_pack_rgba_aos(LLVMBuilderRef builder, const struct util_format_description *desc, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c index 4cf285efb89..191562d460d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c @@ -33,8 +33,8 @@ */ -#include "util/u_cpu_detect.h" #include "util/u_format.h" +#include "util/u_math.h" #include "lp_bld_type.h" #include "lp_bld_const.h" @@ -63,10 +63,11 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, LLVMValueRef aux[4]; bool normalized; int empty_channel; + bool needs_uitofp; unsigned shift; unsigned i; - /* FIXME: Support more formats */ + /* TODO: Support more formats */ assert(desc->layout == UTIL_FORMAT_LAYOUT_PLAIN); assert(desc->block.width == 1); assert(desc->block.height == 1); @@ -93,6 +94,7 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, /* Initialize vector constants */ normalized = FALSE; + needs_uitofp = FALSE; empty_channel = -1; shift = 0; for (i = 0; i < 4; ++i) { @@ -105,10 +107,13 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, empty_channel = i; } else { - unsigned mask = (1 << bits) - 1; + unsigned long long mask = (1ULL << bits) - 1; assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED); - assert(bits < 32); + + if (bits == 32) { + needs_uitofp = TRUE; + } shifts[i] = LLVMConstInt(LLVMInt32Type(), shift, 0); masks[i] = LLVMConstInt(LLVMInt32Type(), mask, 0); @@ -126,8 +131,12 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), ""); masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), ""); - /* UIToFP can't be expressed in SSE2 */ - casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), ""); + if (!needs_uitofp) { + /* UIToFP can't be expressed in SSE2 */ + casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), ""); + } else { + casted = LLVMBuildUIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), ""); + } if (normalized) scaled = LLVMBuildMul(builder, casted, LLVMConstVector(scales, 4), ""); @@ -138,7 +147,22 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, aux[i] = LLVMGetUndef(LLVMFloatType()); for (i = 0; i < 4; ++i) { - enum util_format_swizzle swizzle = desc->swizzle[i]; + enum util_format_swizzle swizzle; + + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + /* + * For ZS formats do RGBA = ZZZ1 + */ + if (i == 3) { + swizzle = UTIL_FORMAT_SWIZZLE_1; + } else if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) { + swizzle = UTIL_FORMAT_SWIZZLE_0; + } else { + swizzle = desc->swizzle[0]; + } + } else { + swizzle = desc->swizzle[i]; + } switch (swizzle) { case UTIL_FORMAT_SWIZZLE_X: @@ -166,117 +190,6 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder, } -/** - * Take a vector with packed pixels and unpack into a rgba8 vector. - * - * Formats with bit depth smaller than 32bits are accepted, but they must be - * padded to 32bits. - */ -LLVMValueRef -lp_build_unpack_rgba8_aos(LLVMBuilderRef builder, - const struct util_format_description *desc, - struct lp_type type, - LLVMValueRef packed) -{ - struct lp_build_context bld; - bool rgba8; - LLVMValueRef res; - unsigned i; - - lp_build_context_init(&bld, builder, type); - - /* FIXME: Support more formats */ - assert(desc->layout == UTIL_FORMAT_LAYOUT_PLAIN); - assert(desc->block.width == 1); - assert(desc->block.height == 1); - assert(desc->block.bits <= 32); - - assert(!type.floating); - assert(!type.fixed); - assert(type.norm); - assert(type.width == 8); - assert(type.length % 4 == 0); - - rgba8 = TRUE; - for(i = 0; i < 4; ++i) { - assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED || - desc->channel[i].type == UTIL_FORMAT_TYPE_VOID); - if(desc->channel[0].size != 8) - rgba8 = FALSE; - } - - if(rgba8) { - /* - * The pixel is already in a rgba8 format variant. All it is necessary - * is to swizzle the channels. - */ - - unsigned char swizzles[4]; - boolean zeros[4]; /* bitwise AND mask */ - boolean ones[4]; /* bitwise OR mask */ - boolean swizzles_needed = FALSE; - boolean zeros_needed = FALSE; - boolean ones_needed = FALSE; - - for(i = 0; i < 4; ++i) { - enum util_format_swizzle swizzle = desc->swizzle[i]; - - /* Initialize with the no-op case */ - swizzles[i] = util_cpu_caps.little_endian ? 3 - i : i; - zeros[i] = TRUE; - ones[i] = FALSE; - - switch (swizzle) { - case UTIL_FORMAT_SWIZZLE_X: - case UTIL_FORMAT_SWIZZLE_Y: - case UTIL_FORMAT_SWIZZLE_Z: - case UTIL_FORMAT_SWIZZLE_W: - if(swizzle != swizzles[i]) { - swizzles[i] = swizzle; - swizzles_needed = TRUE; - } - break; - case UTIL_FORMAT_SWIZZLE_0: - zeros[i] = FALSE; - zeros_needed = TRUE; - break; - case UTIL_FORMAT_SWIZZLE_1: - ones[i] = TRUE; - ones_needed = TRUE; - break; - case UTIL_FORMAT_SWIZZLE_NONE: - assert(0); - break; - } - } - - res = packed; - - if(swizzles_needed) - res = lp_build_swizzle1_aos(&bld, res, swizzles); - - if(zeros_needed) { - /* Mask out zero channels */ - LLVMValueRef mask = lp_build_const_mask_aos(type, zeros); - res = LLVMBuildAnd(builder, res, mask, ""); - } - - if(ones_needed) { - /* Or one channels */ - LLVMValueRef mask = lp_build_const_mask_aos(type, ones); - res = LLVMBuildOr(builder, res, mask, ""); - } - } - else { - /* FIXME */ - assert(0); - res = lp_build_undef(type); - } - - return res; -} - - /** * Pack a single pixel. * @@ -393,13 +306,16 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder, format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) && format_desc->block.width == 1 && format_desc->block.height == 1 && + util_is_pot(format_desc->block.bits) && format_desc->block.bits <= 32 && - format_desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT) + format_desc->is_bitmask && + !format_desc->is_mixed) { LLVMValueRef packed; ptr = LLVMBuildBitCast(builder, ptr, - LLVMPointerType(LLVMIntType(format_desc->block.bits), 0) , ""); + LLVMPointerType(LLVMIntType(format_desc->block.bits), 0) , + ""); packed = LLVMBuildLoad(builder, ptr, "packed"); diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c index fb595893bd0..13c3c3572d6 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_format.c +++ b/src/gallium/drivers/llvmpipe/lp_test_format.c @@ -37,59 +37,13 @@ #include "util/u_cpu_detect.h" #include "util/u_format.h" +#include "util/u_format_tests.h" +#include "util/u_format_s3tc.h" #include "gallivm/lp_bld_format.h" #include "lp_test.h" -struct pixel_test_case -{ - enum pipe_format format; - uint32_t packed; - double unpacked[4]; -}; - - -struct pixel_test_case test_cases[] = -{ - {PIPE_FORMAT_B5G6R5_UNORM, 0x0000, {0.0, 0.0, 0.0, 1.0}}, - {PIPE_FORMAT_B5G6R5_UNORM, 0x001f, {0.0, 0.0, 1.0, 1.0}}, - {PIPE_FORMAT_B5G6R5_UNORM, 0x07e0, {0.0, 1.0, 0.0, 1.0}}, - {PIPE_FORMAT_B5G6R5_UNORM, 0xf800, {1.0, 0.0, 0.0, 1.0}}, - {PIPE_FORMAT_B5G6R5_UNORM, 0xffff, {1.0, 1.0, 1.0, 1.0}}, - - {PIPE_FORMAT_B5G5R5A1_UNORM, 0x0000, {0.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_B5G5R5A1_UNORM, 0x001f, {0.0, 0.0, 1.0, 0.0}}, - {PIPE_FORMAT_B5G5R5A1_UNORM, 0x03e0, {0.0, 1.0, 0.0, 0.0}}, - {PIPE_FORMAT_B5G5R5A1_UNORM, 0x7c00, {1.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_B5G5R5A1_UNORM, 0x8000, {0.0, 0.0, 0.0, 1.0}}, - {PIPE_FORMAT_B5G5R5A1_UNORM, 0xffff, {1.0, 1.0, 1.0, 1.0}}, - - {PIPE_FORMAT_B8G8R8A8_UNORM, 0x00000000, {0.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_B8G8R8A8_UNORM, 0x000000ff, {0.0, 0.0, 1.0, 0.0}}, - {PIPE_FORMAT_B8G8R8A8_UNORM, 0x0000ff00, {0.0, 1.0, 0.0, 0.0}}, - {PIPE_FORMAT_B8G8R8A8_UNORM, 0x00ff0000, {1.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_B8G8R8A8_UNORM, 0xff000000, {0.0, 0.0, 0.0, 1.0}}, - {PIPE_FORMAT_B8G8R8A8_UNORM, 0xffffffff, {1.0, 1.0, 1.0, 1.0}}, - -#if 0 - {PIPE_FORMAT_R8G8B8A8_UNORM, 0x00000000, {0.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_R8G8B8A8_UNORM, 0x000000ff, {0.0, 0.0, 0.0, 1.0}}, - {PIPE_FORMAT_R8G8B8A8_UNORM, 0x0000ff00, {0.0, 0.0, 1.0, 0.0}}, - {PIPE_FORMAT_R8G8B8A8_UNORM, 0x00ff0000, {0.0, 1.0, 0.0, 0.0}}, - {PIPE_FORMAT_R8G8B8A8_UNORM, 0xff000000, {1.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_R8G8B8A8_UNORM, 0xffffffff, {1.0, 1.0, 1.0, 1.0}}, -#endif - - {PIPE_FORMAT_A8R8G8B8_UNORM, 0x00000000, {0.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_A8R8G8B8_UNORM, 0x000000ff, {0.0, 0.0, 0.0, 1.0}}, - {PIPE_FORMAT_A8R8G8B8_UNORM, 0x0000ff00, {1.0, 0.0, 0.0, 0.0}}, - {PIPE_FORMAT_A8R8G8B8_UNORM, 0x00ff0000, {0.0, 1.0, 0.0, 0.0}}, - {PIPE_FORMAT_A8R8G8B8_UNORM, 0xff000000, {0.0, 0.0, 1.0, 0.0}}, - {PIPE_FORMAT_A8R8G8B8_UNORM, 0xffffffff, {1.0, 1.0, 1.0, 1.0}}, -}; - - void write_tsv_header(FILE *fp) { @@ -114,52 +68,11 @@ write_tsv_row(FILE *fp, } -typedef void (*load_ptr_t)(const uint32_t packed, float *); +typedef void (*fetch_ptr_t)(const void *packed, float *); static LLVMValueRef -add_load_rgba_test(LLVMModuleRef module, - const struct util_format_description *desc) -{ - LLVMTypeRef args[2]; - LLVMValueRef func; - LLVMValueRef packed; - LLVMValueRef rgba_ptr; - LLVMBasicBlockRef block; - LLVMBuilderRef builder; - LLVMValueRef rgba; - - args[0] = LLVMInt32Type(); - args[1] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0); - - func = LLVMAddFunction(module, "load", LLVMFunctionType(LLVMVoidType(), args, 2, 0)); - LLVMSetFunctionCallConv(func, LLVMCCallConv); - packed = LLVMGetParam(func, 0); - rgba_ptr = LLVMGetParam(func, 1); - - block = LLVMAppendBasicBlock(func, "entry"); - builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(builder, block); - - if(desc->block.bits < 32) - packed = LLVMBuildTrunc(builder, packed, LLVMIntType(desc->block.bits), ""); - - rgba = lp_build_unpack_rgba_aos(builder, desc, packed); - - LLVMBuildStore(builder, rgba, rgba_ptr); - - LLVMBuildRetVoid(builder); - - LLVMDisposeBuilder(builder); - return func; -} - - -typedef void (*store_ptr_t)(uint32_t *, const float *); - - -static LLVMValueRef -add_store_rgba_test(LLVMModuleRef module, +add_fetch_rgba_test(LLVMModuleRef module, const struct util_format_description *desc) { LLVMTypeRef args[2]; @@ -169,12 +82,11 @@ add_store_rgba_test(LLVMModuleRef module, LLVMBasicBlockRef block; LLVMBuilderRef builder; LLVMValueRef rgba; - LLVMValueRef packed; - args[0] = LLVMPointerType(LLVMInt32Type(), 0); + args[0] = LLVMPointerType(LLVMInt8Type(), 0); args[1] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0); - func = LLVMAddFunction(module, "store", LLVMFunctionType(LLVMVoidType(), args, 2, 0)); + func = LLVMAddFunction(module, "fetch", LLVMFunctionType(LLVMVoidType(), args, 2, 0)); LLVMSetFunctionCallConv(func, LLVMCCallConv); packed_ptr = LLVMGetParam(func, 0); rgba_ptr = LLVMGetParam(func, 1); @@ -183,14 +95,9 @@ add_store_rgba_test(LLVMModuleRef module, builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, block); - rgba = LLVMBuildLoad(builder, rgba_ptr, ""); - - packed = lp_build_pack_rgba_aos(builder, desc, rgba); + rgba = lp_build_fetch_rgba_aos(builder, desc, packed_ptr); - if(desc->block.bits < 32) - packed = LLVMBuildZExt(builder, packed, LLVMInt32Type(), ""); - - LLVMBuildStore(builder, packed, packed_ptr); + LLVMBuildStore(builder, rgba, rgba_ptr); LLVMBuildRetVoid(builder); @@ -201,30 +108,24 @@ add_store_rgba_test(LLVMModuleRef module, PIPE_ALIGN_STACK static boolean -test_format(unsigned verbose, FILE *fp, const struct pixel_test_case *test) +test_format(unsigned verbose, FILE *fp, + const struct util_format_description *desc, + const struct util_format_test_case *test) { LLVMModuleRef module = NULL; - LLVMValueRef load = NULL; - LLVMValueRef store = NULL; + LLVMValueRef fetch = NULL; LLVMExecutionEngineRef engine = NULL; LLVMModuleProviderRef provider = NULL; LLVMPassManagerRef pass = NULL; char *error = NULL; - const struct util_format_description *desc; - load_ptr_t load_ptr; - store_ptr_t store_ptr; + fetch_ptr_t fetch_ptr; float unpacked[4]; - unsigned packed; boolean success; unsigned i; - desc = util_format_description(test->format); - fprintf(stderr, "%s\n", desc->name); - module = LLVMModuleCreateWithName("test"); - load = add_load_rgba_test(module, desc); - store = add_store_rgba_test(module, desc); + fetch = add_fetch_rgba_test(module, desc); if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) { LLVMDumpModule(module); @@ -254,33 +155,32 @@ test_format(unsigned verbose, FILE *fp, const struct pixel_test_case *test) (void)pass; #endif - load_ptr = (load_ptr_t) LLVMGetPointerToGlobal(engine, load); - store_ptr = (store_ptr_t)LLVMGetPointerToGlobal(engine, store); + fetch_ptr = (fetch_ptr_t) LLVMGetPointerToGlobal(engine, fetch); memset(unpacked, 0, sizeof unpacked); - packed = 0; - load_ptr(test->packed, unpacked); - store_ptr(&packed, unpacked); + fetch_ptr(test->packed, unpacked); success = TRUE; - if(test->packed != packed) - success = FALSE; for(i = 0; i < 4; ++i) - if(test->unpacked[i] != unpacked[i]) + if(test->unpacked[0][0][i] != unpacked[i]) success = FALSE; if (!success) { printf("FAILED\n"); - printf(" Packed: %08x\n", test->packed); - printf(" %08x\n", packed); - printf(" Unpacked: %f %f %f %f\n", unpacked[0], unpacked[1], unpacked[2], unpacked[3]); - printf(" %f %f %f %f\n", test->unpacked[0], test->unpacked[1], test->unpacked[2], test->unpacked[3]); + printf(" Packed: %02x %02x %02x %02x\n", + test->packed[0], test->packed[1], test->packed[2], test->packed[3]); + printf(" Unpacked: %f %f %f %f obtained\n", + unpacked[0], unpacked[1], unpacked[2], unpacked[3]); + printf(" %f %f %f %f expected\n", + test->unpacked[0][0][0], + test->unpacked[0][0][1], + test->unpacked[0][0][2], + test->unpacked[0][0][3]); LLVMDumpModule(module); } - LLVMFreeMachineCodeForFunction(engine, store); - LLVMFreeMachineCodeForFunction(engine, load); + LLVMFreeMachineCodeForFunction(engine, fetch); LLVMDisposeExecutionEngine(engine); if(pass) @@ -293,15 +193,74 @@ test_format(unsigned verbose, FILE *fp, const struct pixel_test_case *test) } + +static boolean +test_one(unsigned verbose, FILE *fp, + const struct util_format_description *format_desc) +{ + unsigned i; + bool success = TRUE; + + printf("Testing %s ...\n", + format_desc->name); + + for (i = 0; i < util_format_nr_test_cases; ++i) { + const struct util_format_test_case *test = &util_format_test_cases[i]; + + if (test->format == format_desc->format) { + + if (!test_format(verbose, fp, format_desc, test)) { + success = FALSE; + } + + } + } + + return success; +} + + boolean test_all(unsigned verbose, FILE *fp) { - unsigned i; + enum pipe_format format; bool success = TRUE; - for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) - if(!test_format(verbose, fp, &test_cases[i])) - success = FALSE; + for (format = 1; format < PIPE_FORMAT_COUNT; ++format) { + const struct util_format_description *format_desc; + + format_desc = util_format_description(format); + if (!format_desc) { + continue; + } + + /* + * XXX: copied from lp_build_fetch_rgba_aos() + * TODO: test more + */ + + if (!(format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && + format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB && + format_desc->block.width == 1 && + format_desc->block.height == 1 && + util_is_pot(format_desc->block.bits) && + format_desc->block.bits <= 32 && + format_desc->is_bitmask && + !format_desc->is_mixed && + (format_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED || + format_desc->channel[1].type == UTIL_FORMAT_TYPE_UNSIGNED))) { + continue; + } + + if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC && + !util_format_s3tc_enabled) { + continue; + } + + if (!test_one(verbose, fp, format_desc)) { + success = FALSE; + } + } return success; } -- 2.30.2