llvmpipe: fix race between draw and setting fragment shader.
[mesa.git] / src / gallium / drivers / llvmpipe / lp_test_main.c
index f07fa256f16d3d4a199d525a6e699253ff54aaad..5ec0dd347bd3edb1938718ea674ad5866dbf449e 100644 (file)
  */
 
 
-#include "lp_bld_const.h"
+#include "util/u_cpu_detect.h"
+#include "util/u_math.h"
+
+#include "gallivm/lp_bld_const.h"
+#include "gallivm/lp_bld_init.h"
+#include "gallivm/lp_bld_debug.h"
 #include "lp_test.h"
 
 
@@ -142,6 +147,7 @@ write_elem(struct lp_type type, void *dst, unsigned index, double value)
       if(type.sign) {
          long long lvalue = (long long)value;
          lvalue = MIN2(lvalue, ((long long)1 << (type.width - 1)) - 1);
+         lvalue = MAX2(lvalue, -((long long)1 << (type.width - 1)));
          switch(type.width) {
          case 8:
             *((int8_t *)dst + index) = (int8_t)lvalue;
@@ -190,18 +196,29 @@ random_elem(struct lp_type type, void *dst, unsigned index)
    assert(index < type.length);
    value = (double)rand()/(double)RAND_MAX;
    if(!type.norm) {
-      unsigned long long mask;
-      if (type.floating)
-         mask = ~(unsigned long long)0;
-      else if (type.fixed)
-         mask = ((unsigned long long)1 << (type.width / 2)) - 1;
-      else if (type.sign)
-         mask = ((unsigned long long)1 << (type.width - 1)) - 1;
-      else
-         mask = ((unsigned long long)1 << type.width) - 1;
-      value += (double)(mask & rand());
+      if (type.floating) {
+         value *= 2.0;
+      }
+      else {
+         unsigned long long mask;
+         if (type.fixed)
+            mask = ((unsigned long long)1 << (type.width / 2)) - 1;
+         else if (type.sign)
+            mask = ((unsigned long long)1 << (type.width - 1)) - 1;
+         else
+            mask = ((unsigned long long)1 << type.width) - 1;
+         value += (double)(mask & rand());
+         if (!type.fixed && !type.sign && type.width == 32) {
+            /*
+             * rand only returns half the possible range
+             * XXX 64bit values...
+             */
+            if(rand() & 1)
+               value += (double)0x80000000;
+         }
+      }
    }
-   if(!type.sign)
+   if(type.sign)
       if(rand() & 1)
          value = -value;
    write_elem(type, dst, index, value);
@@ -246,12 +263,18 @@ boolean
 compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps)
 {
    unsigned i;
+   eps *= type.floating ? 8.0 : 2.0;
    for (i = 0; i < type.length; ++i) {
       double res_elem = read_elem(type, res, i);
       double ref_elem = read_elem(type, ref, i);
-      double delta = fabs(res_elem - ref_elem);
-      if(delta >= 2.0*eps)
+      double delta = res_elem - ref_elem;
+      if (ref_elem < -1.0 || ref_elem > 1.0) {
+        delta /= ref_elem;
+      }
+      delta = fabs(delta);
+      if (delta >= eps) {
          return FALSE;
+      }
    }
 
    return TRUE;
@@ -355,35 +378,52 @@ int main(int argc, char **argv)
    unsigned long n = 1000;
    unsigned i;
    boolean success;
+   boolean single = FALSE;
+   unsigned fpstate;
+
+   util_cpu_detect();
+   fpstate = util_fpstate_get();
+   util_fpstate_set_denorms_to_zero(fpstate);
+
+   if (!lp_build_init())
+      return 1;
 
    for(i = 1; i < argc; ++i) {
       if(strcmp(argv[i], "-v") == 0)
          ++verbose;
+      else if(strcmp(argv[i], "-s") == 0)
+         single = TRUE;
       else if(strcmp(argv[i], "-o") == 0)
          fp = fopen(argv[++i], "wt");
       else
          n = atoi(argv[i]);
    }
 
-#ifdef LLVM_NATIVE_ARCH
-   LLVMLinkInJIT();
-   LLVMInitializeNativeTarget();
+#ifdef DEBUG
+   if (verbose >= 2) {
+      gallivm_debug |= GALLIVM_DEBUG_IR;
+      gallivm_debug |= GALLIVM_DEBUG_ASM;
+   }
 #endif
 
-   if(fp) {
+   if (fp) {
       /* Warm up the caches */
       test_some(0, NULL, 100);
 
       write_tsv_header(fp);
    }
       
-   if(n)
+   if (single)
+      success = test_single(verbose, fp);
+   else if (n)
       success = test_some(verbose, fp, n);
    else
       success = test_all(verbose, fp);
 
-   if(fp)
+   if (fp)
       fclose(fp);
 
+   LLVMShutdown();
+
    return success ? 0 : 1;
 }