Merge branch '7.8'
[mesa.git] / src / gallium / auxiliary / translate / translate_generic.c
index 3fec89b36e9798a2e7ead97ab0205495a1a4442a..c3ec9ae3f4b611b9d048432c2557bff6c01e0f68 100644 (file)
@@ -30,7 +30,7 @@
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
 
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
 #include "pipe/p_state.h"
 #include "translate.h"
 
@@ -46,9 +46,12 @@ struct translate_generic {
    struct translate translate;
 
    struct {
+      enum translate_element_type type;
+
       fetch_func fetch;
       unsigned buffer;
       unsigned input_offset;
+      unsigned instance_divisor;
 
       emit_func emit;
       unsigned output_offset;
@@ -121,6 +124,8 @@ emit_##NAME(const float *attrib, void *ptr)         \
 #define FROM_16_SNORM(i)   ((float) ((short *) ptr)[i] / 32767.0f)
 #define FROM_32_SNORM(i)   ((float) ((int *) ptr)[i] / 2147483647.0f)
 
+#define FROM_32_FIXED(i)   (((int *) ptr)[i] / 65536.0f)
+
 #define TO_64_FLOAT(x)   ((double) x)
 #define TO_32_FLOAT(x)   (x)
 
@@ -140,6 +145,8 @@ emit_##NAME(const float *attrib, void *ptr)         \
 #define TO_16_SNORM(x)   ((short) (x * 32767.0f))
 #define TO_32_SNORM(x)   ((int) (x * 2147483647.0f))
 
+#define TO_32_FIXED(x)   ((int) (x * 65536.0f))
+
 
 
 ATTRIB( R64G64B64A64_FLOAT,   4, double, FROM_64_FLOAT, TO_64_FLOAT )
@@ -213,7 +220,12 @@ ATTRIB( R8G8_SNORM,      2, char, FROM_8_SNORM, TO_8_SNORM )
 ATTRIB( R8_SNORM,        1, char, FROM_8_SNORM, TO_8_SNORM )
 
 ATTRIB( A8R8G8B8_UNORM,       4, ubyte, FROM_8_UNORM, TO_8_UNORM )
-//ATTRIB( R8G8B8A8_UNORM,       4, ubyte, FROM_8_UNORM, TO_8_UNORM )
+/*ATTRIB( R8G8B8A8_UNORM,       4, ubyte, FROM_8_UNORM, TO_8_UNORM )*/
+
+ATTRIB( R32G32B32A32_FIXED,   4, int, FROM_32_FIXED, TO_32_FIXED )
+ATTRIB( R32G32B32_FIXED,      3, int, FROM_32_FIXED, TO_32_FIXED )
+ATTRIB( R32G32_FIXED,         2, int, FROM_32_FIXED, TO_32_FIXED )
+ATTRIB( R32_FIXED,            1, int, FROM_32_FIXED, TO_32_FIXED )
 
 
 
@@ -380,11 +392,20 @@ static fetch_func get_fetch_func( enum pipe_format format )
    case PIPE_FORMAT_R8G8B8A8_SSCALED:
       return &fetch_R8G8B8A8_SSCALED;
 
+   case PIPE_FORMAT_B8G8R8A8_UNORM:
+      return &fetch_B8G8R8A8_UNORM;
+
    case PIPE_FORMAT_A8R8G8B8_UNORM:
       return &fetch_A8R8G8B8_UNORM;
 
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
-      return &fetch_B8G8R8A8_UNORM;
+   case PIPE_FORMAT_R32_FIXED:
+      return &fetch_R32_FIXED;
+   case PIPE_FORMAT_R32G32_FIXED:
+      return &fetch_R32G32_FIXED;
+   case PIPE_FORMAT_R32G32B32_FIXED:
+      return &fetch_R32G32B32_FIXED;
+   case PIPE_FORMAT_R32G32B32A32_FIXED:
+      return &fetch_R32G32B32A32_FIXED;
 
    default:
       assert(0); 
@@ -397,6 +418,12 @@ static fetch_func get_fetch_func( enum pipe_format format )
 
 static emit_func get_emit_func( enum pipe_format format )
 {
+   /* silence warnings */
+   (void) emit_R32G32B32A32_FIXED;
+   (void) emit_R32G32B32_FIXED;
+   (void) emit_R32G32_FIXED;
+   (void) emit_R32_FIXED;
+
    switch (format) {
    case PIPE_FORMAT_R64_FLOAT:
       return &emit_R64_FLOAT;
@@ -524,12 +551,12 @@ static emit_func get_emit_func( enum pipe_format format )
    case PIPE_FORMAT_R8G8B8A8_SSCALED:
       return &emit_R8G8B8A8_SSCALED;
 
-   case PIPE_FORMAT_A8R8G8B8_UNORM:
-      return &emit_A8R8G8B8_UNORM;
-
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       return &emit_B8G8R8A8_UNORM;
 
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
+      return &emit_A8R8G8B8_UNORM;
+
    default:
       assert(0); 
       return &emit_NULL;
@@ -544,6 +571,7 @@ static emit_func get_emit_func( enum pipe_format format )
 static void PIPE_CDECL generic_run_elts( struct translate *translate,
                                          const unsigned *elts,
                                          unsigned count,
+                                         unsigned instance_id,
                                          void *output_buffer )
 {
    struct translate_generic *tg = translate_generic(translate);
@@ -559,13 +587,20 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
 
       for (attr = 0; attr < nr_attrs; attr++) {
         float data[4];
-
-        const char *src = (tg->attrib[attr].input_ptr + 
-                           tg->attrib[attr].input_stride * elt);
+         const char *src;
 
         char *dst = (vert + 
                      tg->attrib[attr].output_offset);
 
+         if (tg->attrib[attr].instance_divisor) {
+            src = tg->attrib[attr].input_ptr +
+                  tg->attrib[attr].input_stride *
+                  (instance_id / tg->attrib[attr].instance_divisor);
+         } else {
+            src = tg->attrib[attr].input_ptr +
+                  tg->attrib[attr].input_stride * elt;
+         }
+
         tg->attrib[attr].fetch( src, data );
 
          if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n",
@@ -583,6 +618,7 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
 static void PIPE_CDECL generic_run( struct translate *translate,
                                     unsigned start,
                                     unsigned count,
+                                    unsigned instance_id,
                                     void *output_buffer )
 {
    struct translate_generic *tg = translate_generic(translate);
@@ -599,13 +635,25 @@ static void PIPE_CDECL generic_run( struct translate *translate,
       for (attr = 0; attr < nr_attrs; attr++) {
         float data[4];
 
-        const char *src = (tg->attrib[attr].input_ptr + 
-                           tg->attrib[attr].input_stride * elt);
-
         char *dst = (vert + 
                      tg->attrib[attr].output_offset);
 
-        tg->attrib[attr].fetch( src, data );
+         if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
+            const char *src;
+
+            if (tg->attrib[attr].instance_divisor) {
+               src = tg->attrib[attr].input_ptr +
+                     tg->attrib[attr].input_stride *
+                     (instance_id / tg->attrib[attr].instance_divisor);
+            } else {
+               src = tg->attrib[attr].input_ptr +
+                     tg->attrib[attr].input_stride * elt;
+            }
+
+            tg->attrib[attr].fetch( src, data );
+         } else {
+            data[0] = (float)instance_id;
+         }
 
          if (0) debug_printf("vert %d attr %d: %f %f %f %f\n",
                              i, attr, data[0], data[1], data[2], data[3]);
@@ -659,10 +707,12 @@ struct translate *translate_generic_create( const struct translate_key *key )
    tg->translate.run = generic_run;
 
    for (i = 0; i < key->nr_elements; i++) {
+      tg->attrib[i].type = key->element[i].type;
 
       tg->attrib[i].fetch = get_fetch_func(key->element[i].input_format);
       tg->attrib[i].buffer = key->element[i].input_buffer;
       tg->attrib[i].input_offset = key->element[i].input_offset;
+      tg->attrib[i].instance_divisor = key->element[i].instance_divisor;
 
       tg->attrib[i].emit = get_emit_func(key->element[i].output_format);
       tg->attrib[i].output_offset = key->element[i].output_offset;