X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_test_format.c;h=31d965de59725089064203996ec307d43e0992a7;hb=dffeaa55dd1155d7a1e8feb5ecfc54fff688fcd8;hp=4152ca6cf6370e41e8b551cd0162c20c6008cb3b;hpb=0f68236a2487dbeb0396b996debcda595b0b54a1;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c index 4152ca6cf63..31d965de597 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_format.c +++ b/src/gallium/drivers/llvmpipe/lp_test_format.c @@ -44,6 +44,7 @@ #include "lp_test.h" +static struct lp_build_format_cache *cache_ptr; void write_tsv_header(FILE *fp) @@ -71,20 +72,20 @@ write_tsv_row(FILE *fp, typedef void (*fetch_ptr_t)(void *unpacked, const void *packed, - unsigned i, unsigned j); + unsigned i, unsigned j, struct lp_build_format_cache *cache); static LLVMValueRef add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose, const struct util_format_description *desc, - struct lp_type type) + struct lp_type type, + unsigned use_cache) { char name[256]; LLVMContextRef context = gallivm->context; LLVMModuleRef module = gallivm->module; LLVMBuilderRef builder = gallivm->builder; - LLVMPassManagerRef passmgr = gallivm->passmgr; - LLVMTypeRef args[4]; + LLVMTypeRef args[5]; LLVMValueRef func; LLVMValueRef packed_ptr; LLVMValueRef offset = LLVMConstNull(LLVMInt32TypeInContext(context)); @@ -93,43 +94,40 @@ add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose, LLVMValueRef j; LLVMBasicBlockRef block; LLVMValueRef rgba; + LLVMValueRef cache = NULL; - util_snprintf(name, sizeof name, "fetch_%s_%s", desc->short_name, - type.floating ? "float" : "unorm8"); + snprintf(name, sizeof name, "fetch_%s_%s", desc->short_name, + type.floating ? "float" : "unorm8"); args[0] = LLVMPointerType(lp_build_vec_type(gallivm, type), 0); args[1] = LLVMPointerType(LLVMInt8TypeInContext(context), 0); args[3] = args[2] = LLVMInt32TypeInContext(context); + args[4] = LLVMPointerType(lp_build_format_cache_type(gallivm), 0); func = LLVMAddFunction(module, name, LLVMFunctionType(LLVMVoidTypeInContext(context), - args, Elements(args), 0)); + args, ARRAY_SIZE(args), 0)); LLVMSetFunctionCallConv(func, LLVMCCallConv); rgba_ptr = LLVMGetParam(func, 0); packed_ptr = LLVMGetParam(func, 1); i = LLVMGetParam(func, 2); j = LLVMGetParam(func, 3); + if (use_cache) { + cache = LLVMGetParam(func, 4); + } + block = LLVMAppendBasicBlockInContext(context, func, "entry"); LLVMPositionBuilderAtEnd(builder, block); - rgba = lp_build_fetch_rgba_aos(gallivm, desc, type, - packed_ptr, offset, i, j); + rgba = lp_build_fetch_rgba_aos(gallivm, desc, type, TRUE, + packed_ptr, offset, i, j, cache); LLVMBuildStore(builder, rgba, rgba_ptr); LLVMBuildRetVoid(builder); - if (LLVMVerifyFunction(func, LLVMPrintMessageAction)) { - LLVMDumpValue(func); - abort(); - } - - LLVMRunFunctionPassManager(passmgr, func); - - if (verbose >= 1) { - LLVMDumpValue(func); - } + gallivm_verify_function(gallivm, func); return func; } @@ -137,26 +135,31 @@ add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose, PIPE_ALIGN_STACK static boolean -test_format_float(struct gallivm_state *gallivm, unsigned verbose, FILE *fp, - const struct util_format_description *desc) +test_format_float(unsigned verbose, FILE *fp, + const struct util_format_description *desc, + unsigned use_cache) { + LLVMContextRef context; + struct gallivm_state *gallivm; LLVMValueRef fetch = NULL; - LLVMExecutionEngineRef engine = gallivm->engine; fetch_ptr_t fetch_ptr; + PIPE_ALIGN_VAR(16) uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; PIPE_ALIGN_VAR(16) float unpacked[4]; boolean first = TRUE; boolean success = TRUE; unsigned i, j, k, l; - void *f; - fetch = add_fetch_rgba_test(gallivm, verbose, desc, lp_float32_vec4_type()); + context = LLVMContextCreate(); + gallivm = gallivm_create("test_module_float", context); - f = LLVMGetPointerToGlobal(engine, fetch); - fetch_ptr = (fetch_ptr_t) pointer_to_func(f); + fetch = add_fetch_rgba_test(gallivm, verbose, desc, + lp_float32_vec4_type(), use_cache); - if (verbose >= 2) { - lp_disassemble(f); - } + gallivm_compile_module(gallivm); + + fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch); + + gallivm_free_ir(gallivm); for (l = 0; l < util_format_nr_test_cases; ++l) { const struct util_format_test_case *test = &util_format_test_cases[l]; @@ -166,34 +169,54 @@ test_format_float(struct gallivm_state *gallivm, unsigned verbose, FILE *fp, if (first) { printf("Testing %s (float) ...\n", desc->name); + fflush(stdout); first = FALSE; } + /* To ensure it's 16-byte aligned */ + memcpy(packed, test->packed, sizeof packed); + for (i = 0; i < desc->block.height; ++i) { for (j = 0; j < desc->block.width; ++j) { - boolean match; + boolean match = TRUE; memset(unpacked, 0, sizeof unpacked); - fetch_ptr(unpacked, test->packed, j, i); + fetch_ptr(unpacked, packed, j, i, use_cache ? cache_ptr : NULL); - match = TRUE; - for(k = 0; k < 4; ++k) - if (fabs((float)test->unpacked[i][j][k] - unpacked[k]) > FLT_EPSILON) + for(k = 0; k < 4; ++k) { + if (util_double_inf_sign(test->unpacked[i][j][k]) != util_inf_sign(unpacked[k])) { + match = FALSE; + } + + if (util_is_double_nan(test->unpacked[i][j][k]) != util_is_nan(unpacked[k])) { match = FALSE; + } + + if (!util_is_double_inf_or_nan(test->unpacked[i][j][k]) && + fabs((float)test->unpacked[i][j][k] - unpacked[k]) > FLT_EPSILON) { + match = FALSE; + } + } + + /* Ignore errors in S3TC for now */ + if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { + match = TRUE; + } if (!match) { printf("FAILED\n"); printf(" Packed: %02x %02x %02x %02x\n", test->packed[0], test->packed[1], test->packed[2], test->packed[3]); - printf(" Unpacked (%u,%u): %f %f %f %f obtained\n", + printf(" Unpacked (%u,%u): %.9g %.9g %.9g %.9g obtained\n", j, i, unpacked[0], unpacked[1], unpacked[2], unpacked[3]); - printf(" %f %f %f %f expected\n", + printf(" %.9g %.9g %.9g %.9g expected\n", test->unpacked[i][j][0], test->unpacked[i][j][1], test->unpacked[i][j][2], test->unpacked[i][j][3]); + fflush(stdout); success = FALSE; } } @@ -201,14 +224,8 @@ test_format_float(struct gallivm_state *gallivm, unsigned verbose, FILE *fp, } } - if (!success) { - if (verbose < 1) { - LLVMDumpValue(fetch); - } - } - - LLVMFreeMachineCodeForFunction(engine, fetch); - LLVMDeleteFunction(fetch); + gallivm_destroy(gallivm); + LLVMContextDispose(context); if(fp) write_tsv_row(fp, desc, success); @@ -219,26 +236,31 @@ test_format_float(struct gallivm_state *gallivm, unsigned verbose, FILE *fp, PIPE_ALIGN_STACK static boolean -test_format_unorm8(struct gallivm_state *gallivm, - unsigned verbose, FILE *fp, - const struct util_format_description *desc) +test_format_unorm8(unsigned verbose, FILE *fp, + const struct util_format_description *desc, + unsigned use_cache) { + LLVMContextRef context; + struct gallivm_state *gallivm; LLVMValueRef fetch = NULL; fetch_ptr_t fetch_ptr; + PIPE_ALIGN_VAR(16) uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; uint8_t unpacked[4]; boolean first = TRUE; boolean success = TRUE; unsigned i, j, k, l; - void *f; - fetch = add_fetch_rgba_test(gallivm, verbose, desc, lp_unorm8_vec4_type()); + context = LLVMContextCreate(); + gallivm = gallivm_create("test_module_unorm8", context); - f = LLVMGetPointerToGlobal(gallivm->engine, fetch); - fetch_ptr = (fetch_ptr_t) pointer_to_func(f); + fetch = add_fetch_rgba_test(gallivm, verbose, desc, + lp_unorm8_vec4_type(), use_cache); - if (verbose >= 2) { - lp_disassemble(f); - } + gallivm_compile_module(gallivm); + + fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch); + + gallivm_free_ir(gallivm); for (l = 0; l < util_format_nr_test_cases; ++l) { const struct util_format_test_case *test = &util_format_test_cases[l]; @@ -251,23 +273,37 @@ test_format_unorm8(struct gallivm_state *gallivm, first = FALSE; } + /* To ensure it's 16-byte aligned */ + /* Could skip this and use unaligned lp_build_fetch_rgba_aos */ + memcpy(packed, test->packed, sizeof packed); + for (i = 0; i < desc->block.height; ++i) { for (j = 0; j < desc->block.width; ++j) { boolean match; memset(unpacked, 0, sizeof unpacked); - fetch_ptr(unpacked, test->packed, j, i); + fetch_ptr(unpacked, packed, j, i, use_cache ? cache_ptr : NULL); match = TRUE; for(k = 0; k < 4; ++k) { int error = float_to_ubyte(test->unpacked[i][j][k]) - unpacked[k]; + + if (util_is_double_nan(test->unpacked[i][j][k])) + continue; + if (error < 0) error = -error; + if (error > 1) match = FALSE; } + /* Ignore errors in S3TC as we only implement a poor man approach */ + if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { + match = TRUE; + } + if (!match) { printf("FAILED\n"); printf(" Packed: %02x %02x %02x %02x\n", @@ -280,6 +316,7 @@ test_format_unorm8(struct gallivm_state *gallivm, float_to_ubyte(test->unpacked[i][j][1]), float_to_ubyte(test->unpacked[i][j][2]), float_to_ubyte(test->unpacked[i][j][3])); + success = FALSE; } } @@ -287,11 +324,8 @@ test_format_unorm8(struct gallivm_state *gallivm, } } - if (!success) - LLVMDumpValue(fetch); - - LLVMFreeMachineCodeForFunction(gallivm->engine, fetch); - LLVMDeleteFunction(fetch); + gallivm_destroy(gallivm); + LLVMContextDispose(context); if(fp) write_tsv_row(fp, desc, success); @@ -303,17 +337,17 @@ test_format_unorm8(struct gallivm_state *gallivm, static boolean -test_one(struct gallivm_state *gallivm, - unsigned verbose, FILE *fp, - const struct util_format_description *format_desc) +test_one(unsigned verbose, FILE *fp, + const struct util_format_description *format_desc, + unsigned use_cache) { boolean success = TRUE; - if (!test_format_float(gallivm, verbose, fp, format_desc)) { + if (!test_format_float(verbose, fp, format_desc, use_cache)) { success = FALSE; } - if (!test_format_unorm8(gallivm, verbose, fp, format_desc)) { + if (!test_format_unorm8(verbose, fp, format_desc, use_cache)) { success = FALSE; } @@ -322,53 +356,72 @@ test_one(struct gallivm_state *gallivm, boolean -test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp) +test_all(unsigned verbose, FILE *fp) { enum pipe_format format; boolean success = TRUE; + unsigned use_cache; - util_format_s3tc_init(); + cache_ptr = align_malloc(sizeof(struct lp_build_format_cache), 16); - for (format = 1; format < PIPE_FORMAT_COUNT; ++format) { - const struct util_format_description *format_desc; + for (use_cache = 0; use_cache < 2; use_cache++) { + 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; - } + format_desc = util_format_description(format); + if (!format_desc) { + continue; + } - /* - * TODO: test more - */ + /* + * TODO: test more + */ - if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { - continue; - } + if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + continue; + } - if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC && - !util_format_s3tc_enabled) { - continue; - } + if (util_format_is_pure_integer(format)) + continue; + + /* only have util fetch func for etc1 */ + if (format_desc->layout == UTIL_FORMAT_LAYOUT_ETC && + format != PIPE_FORMAT_ETC1_RGB8) { + continue; + } - if (!test_one(gallivm, verbose, fp, format_desc)) { - success = FALSE; + /* missing fetch funcs */ + if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC || + format_desc->layout == UTIL_FORMAT_LAYOUT_ATC) { + continue; + } + + /* only test twice with formats which can use cache */ + if (format_desc->layout != UTIL_FORMAT_LAYOUT_S3TC && use_cache) { + continue; + } + + if (!test_one(verbose, fp, format_desc, use_cache)) { + success = FALSE; + } } } + align_free(cache_ptr); return success; } boolean -test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp, +test_some(unsigned verbose, FILE *fp, unsigned long n) { - return test_all(gallivm, verbose, fp); + return test_all(verbose, fp); } boolean -test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp) +test_single(unsigned verbose, FILE *fp) { printf("no test_single()"); return TRUE;