llvmpipe, draw: improve shader cache debugging
[mesa.git] / src / gallium / drivers / llvmpipe / lp_test_conv.c
index f4a2f360c75522f11a066aec0e34b3acb00ce5de..6e58a031515fac37978e6421fafa8399807e8eb3 100644 (file)
@@ -140,7 +140,9 @@ add_conv_test(struct gallivm_state *gallivm,
       LLVMBuildStore(builder, dst[i], ptr);
    }
 
-   LLVMBuildRetVoid(builder);;
+   LLVMBuildRetVoid(builder);
+
+   gallivm_verify_function(gallivm, func);
 
    return func;
 }
@@ -148,15 +150,14 @@ add_conv_test(struct gallivm_state *gallivm,
 
 PIPE_ALIGN_STACK
 static boolean
-test_one(struct gallivm_state *gallivm, unsigned verbose,
+test_one(unsigned verbose,
          FILE *fp,
          struct lp_type src_type,
          struct lp_type dst_type)
 {
-   LLVMModuleRef module = gallivm->module;
-   LLVMExecutionEngineRef engine = gallivm->engine;
+   LLVMContextRef context;
+   struct gallivm_state *gallivm;
    LLVMValueRef func = NULL;
-   char *error = NULL;
    conv_test_ptr_t conv_test_ptr;
    boolean success;
    const unsigned n = LP_TEST_NUM_SAMPLES;
@@ -166,15 +167,32 @@ test_one(struct gallivm_state *gallivm, unsigned verbose,
    unsigned num_dsts;
    double eps;
    unsigned i, j;
-   void *code;
 
-   if (src_type.width * src_type.length != dst_type.width * dst_type.length &&
-       src_type.length != dst_type.length) {
+   if ((src_type.width >= dst_type.width && src_type.length > dst_type.length) ||
+       (src_type.width <= dst_type.width && src_type.length < dst_type.length)) {
+      return TRUE;
+   }
+
+   /* Known failures
+    * - fixed point 32 -> float 32
+    * - float 32 -> signed normalised integer 32
+    */
+   if ((src_type.floating && !dst_type.floating && dst_type.sign && dst_type.norm && src_type.width == dst_type.width) ||
+       (!src_type.floating && dst_type.floating && src_type.fixed && src_type.width == dst_type.width)) {
+      return TRUE;
+   }
+
+   /* Known failures
+    * - fixed point 32 -> float 32
+    * - float 32 -> signed normalised integer 32
+    */
+   if ((src_type.floating && !dst_type.floating && dst_type.sign && dst_type.norm && src_type.width == dst_type.width) ||
+       (!src_type.floating && dst_type.floating && src_type.fixed && src_type.width == dst_type.width)) {
       return TRUE;
    }
 
    if(verbose >= 1)
-      dump_conv_types(stdout, src_type, dst_type);
+      dump_conv_types(stderr, src_type, dst_type);
 
    if (src_type.length > dst_type.length) {
       num_srcs = 1;
@@ -194,29 +212,23 @@ test_one(struct gallivm_state *gallivm, unsigned verbose,
 
    eps = MAX2(lp_const_eps(src_type), lp_const_eps(dst_type));
 
-   func = add_conv_test(gallivm, src_type, num_srcs, dst_type, num_dsts);
+   context = LLVMContextCreate();
+   gallivm = gallivm_create("test_module", context);
 
-   if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
-      LLVMDumpModule(module);
-      abort();
-   }
-   LLVMDisposeMessage(error);
+   func = add_conv_test(gallivm, src_type, num_srcs, dst_type, num_dsts);
 
-   if(verbose >= 2)
-      LLVMDumpModule(module);
+   gallivm_compile_module(gallivm);
 
-   code = LLVMGetPointerToGlobal(engine, func);
-   conv_test_ptr = (conv_test_ptr_t)pointer_to_func(code);
+   conv_test_ptr = (conv_test_ptr_t)gallivm_jit_function(gallivm, func);
 
-   if(verbose >= 2)
-      lp_disassemble(code);
+   gallivm_free_ir(gallivm);
 
    success = TRUE;
    for(i = 0; i < n && success; ++i) {
       unsigned src_stride = src_type.length*src_type.width/8;
       unsigned dst_stride = dst_type.length*dst_type.width/8;
-      PIPE_ALIGN_VAR(16) uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
-      PIPE_ALIGN_VAR(16) uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+      PIPE_ALIGN_VAR(LP_MIN_VECTOR_ALIGN) uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+      PIPE_ALIGN_VAR(LP_MIN_VECTOR_ALIGN) uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
       double fref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
       uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
       int64_t start_counter = 0;
@@ -311,20 +323,8 @@ test_one(struct gallivm_state *gallivm, unsigned verbose,
    if(fp)
       write_tsv_row(fp, src_type, dst_type, cycles_avg, success);
 
-   if (!success) {
-      static boolean firsttime = TRUE;
-      if(firsttime) {
-         if(verbose < 2)
-            LLVMDumpModule(module);
-         LLVMWriteBitcodeToFile(module, "conv.bc");
-         fprintf(stderr, "conv.bc written\n");
-         fprintf(stderr, "Invoke as \"llc -o - conv.bc\"\n");
-         firsttime = FALSE;
-         /* abort(); */
-      }
-   }
-
-   LLVMFreeMachineCodeForFunction(engine, func);
+   gallivm_destroy(gallivm);
+   LLVMContextDispose(context);
 
    return success;
 }
@@ -333,23 +333,39 @@ test_one(struct gallivm_state *gallivm, unsigned verbose,
 const struct lp_type conv_types[] = {
    /* float, fixed,  sign,  norm, width, len */
 
+   /* Float */
    {   TRUE, FALSE,  TRUE,  TRUE,    32,   4 },
    {   TRUE, FALSE,  TRUE, FALSE,    32,   4 },
    {   TRUE, FALSE, FALSE,  TRUE,    32,   4 },
    {   TRUE, FALSE, FALSE, FALSE,    32,   4 },
 
-   /* TODO: test fixed formats too */
+   {   TRUE, FALSE,  TRUE,  TRUE,    32,   8 },
+   {   TRUE, FALSE,  TRUE, FALSE,    32,   8 },
+   {   TRUE, FALSE, FALSE,  TRUE,    32,   8 },
+   {   TRUE, FALSE, FALSE, FALSE,    32,   8 },
 
-   {  FALSE, FALSE,  TRUE,  TRUE,    16,   8 },
-   {  FALSE, FALSE,  TRUE, FALSE,    16,   8 },
-   {  FALSE, FALSE, FALSE,  TRUE,    16,   8 },
-   {  FALSE, FALSE, FALSE, FALSE,    16,   8 },
+   /* Fixed */
+   {  FALSE,  TRUE,  TRUE,  TRUE,    32,   4 },
+   {  FALSE,  TRUE,  TRUE, FALSE,    32,   4 },
+   {  FALSE,  TRUE, FALSE,  TRUE,    32,   4 },
+   {  FALSE,  TRUE, FALSE, FALSE,    32,   4 },
+
+   {  FALSE,  TRUE,  TRUE,  TRUE,    32,   8 },
+   {  FALSE,  TRUE,  TRUE, FALSE,    32,   8 },
+   {  FALSE,  TRUE, FALSE,  TRUE,    32,   8 },
+   {  FALSE,  TRUE, FALSE, FALSE,    32,   8 },
 
+   /* Integer */
    {  FALSE, FALSE,  TRUE,  TRUE,    32,   4 },
    {  FALSE, FALSE,  TRUE, FALSE,    32,   4 },
    {  FALSE, FALSE, FALSE,  TRUE,    32,   4 },
    {  FALSE, FALSE, FALSE, FALSE,    32,   4 },
 
+   {  FALSE, FALSE,  TRUE,  TRUE,    32,   8 },
+   {  FALSE, FALSE,  TRUE, FALSE,    32,   8 },
+   {  FALSE, FALSE, FALSE,  TRUE,    32,   8 },
+   {  FALSE, FALSE, FALSE, FALSE,    32,   8 },
+
    {  FALSE, FALSE,  TRUE,  TRUE,    16,   8 },
    {  FALSE, FALSE,  TRUE, FALSE,    16,   8 },
    {  FALSE, FALSE, FALSE,  TRUE,    16,   8 },
@@ -364,18 +380,21 @@ const struct lp_type conv_types[] = {
    {  FALSE, FALSE,  TRUE, FALSE,     8,   4 },
    {  FALSE, FALSE, FALSE,  TRUE,     8,   4 },
    {  FALSE, FALSE, FALSE, FALSE,     8,   4 },
+
+   {  FALSE, FALSE,  FALSE,  TRUE,    8,   8 },
 };
 
 
-const unsigned num_types = sizeof(conv_types)/sizeof(conv_types[0]);
+const unsigned num_types = ARRAY_SIZE(conv_types);
 
 
 boolean
-test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
+test_all(unsigned verbose, FILE *fp)
 {
    const struct lp_type *src_type;
    const struct lp_type *dst_type;
    boolean success = TRUE;
+   int error_count = 0;
 
    for(src_type = conv_types; src_type < &conv_types[num_types]; ++src_type) {
       for(dst_type = conv_types; dst_type < &conv_types[num_types]; ++dst_type) {
@@ -383,21 +402,21 @@ test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
          if(src_type == dst_type)
             continue;
 
-         if(src_type->norm != dst_type->norm)
-            continue;
-
-         if(!test_one(gallivm, verbose, fp, *src_type, *dst_type))
-           success = FALSE;
-
+         if(!test_one(verbose, fp, *src_type, *dst_type)){
+            success = FALSE;
+            ++error_count;
+         }
       }
    }
 
+   fprintf(stderr, "%d failures\n", error_count);
+
    return success;
 }
 
 
 boolean
-test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+test_some(unsigned verbose, FILE *fp,
           unsigned long n)
 {
    const struct lp_type *src_type;
@@ -412,7 +431,7 @@ test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
          dst_type = &conv_types[rand() % num_types];
       } while (src_type == dst_type || src_type->norm != dst_type->norm);
 
-      if(!test_one(gallivm, verbose, fp, *src_type, *dst_type))
+      if(!test_one(verbose, fp, *src_type, *dst_type))
         success = FALSE;
    }
 
@@ -421,7 +440,7 @@ test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
 
 
 boolean
-test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
+test_single(unsigned verbose, FILE *fp)
 {
    /*    float, fixed,  sign,  norm, width, len */
    struct lp_type f32x4_type =
@@ -431,7 +450,7 @@ test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
 
    boolean success;
 
-   success = test_one(gallivm, verbose, fp, f32x4_type, ub8x4_type);
+   success = test_one(verbose, fp, f32x4_type, ub8x4_type);
 
    return success;
 }