[Mesa-dev,v3] Fixing an x86 FPU bug.

Submitted by marius.predut@intel.com on Feb. 12, 2015, 6 p.m.

Details

Message ID 1423764046-29060-1-git-send-email-marius.predut@intel.com
State New, archived
Headers show

Not browsing as part of any series.

Commit Message

marius.predut@intel.com Feb. 12, 2015, 6 p.m.
From: Marius Predut <marius.predut@intel.com>

On 32-bit, for floating point operations is used x86 FPU registers
instead SSE, reason for  when reinterprets an integer as a float
result is unexpected (modify floats when they are written to memory).
The defect was checked with and without -O3 compiler flag

This patch is based Neil Roberts review.
This patch is more complete - it include changes on all places that are storing attribute values to use gl_constant_value.
This patch fix 2 piglit tests.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82668
Signed-off-by: Marius Predut <marius.predut@intel.com>
---
 src/mesa/main/context.c       |    3 ++-
 src/mesa/main/macros.h        |   41 +++++++++++++++++++++--------------------
 src/mesa/vbo/vbo_attrib_tmp.h |   20 ++++++++++++++++----
 src/mesa/vbo/vbo_context.h    |   16 ++++++++--------
 src/mesa/vbo/vbo_exec.h       |   11 ++++++-----
 src/mesa/vbo/vbo_exec_api.c   |   39 +++++++++++++++++++--------------------
 src/mesa/vbo/vbo_exec_draw.c  |    6 +++---
 src/mesa/vbo/vbo_exec_eval.c  |   22 +++++++++++-----------
 src/mesa/vbo/vbo_save.h       |   16 ++++++++--------
 src/mesa/vbo/vbo_save_api.c   |   34 +++++++++++++++++-----------------
 src/mesa/vbo/vbo_save_draw.c  |    6 +++---
 11 files changed, 114 insertions(+), 100 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 63d30a2..f0597e2 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -134,6 +134,7 @@ 
 #include "math/m_matrix.h"
 #include "main/dispatch.h" /* for _gloffset_COUNT */
 #include "uniforms.h"
+#include "macros.h"
 
 #ifdef USE_SPARC_ASM
 #include "sparc/sparc.h"
@@ -656,7 +657,7 @@  _mesa_init_constants(struct gl_constants *consts, gl_api api)
    consts->MaxSamples = 0;
 
    /* GLSL default if NativeIntegers == FALSE */
-   consts->UniformBooleanTrue = FLT_AS_UINT(1.0f);
+   consts->UniformBooleanTrue = FLOAT_AS_UNION(1.0f).u;
 
    /* GL_ARB_sync */
    consts->MaxServerWaitTimeout = 0x1fff7fffffffULL;
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index cd5f2d6..2af15de 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -32,6 +32,7 @@ 
 #define MACROS_H
 
 #include "imports.h"
+#include "program/prog_parameter.h"
 
 
 /**
@@ -170,27 +171,26 @@  extern GLfloat _mesa_ubyte_to_float_color_tab[256];
 	ub = ((GLubyte) F_TO_I((f) * 255.0F))
 #endif
 
-static inline GLfloat INT_AS_FLT(GLint i)
+static union gl_constant_value UINT_AS_UNION(GLuint u)
 {
-   fi_type tmp;
-   tmp.i = i;
-   return tmp.f;
+   union gl_constant_value tmp;
+   tmp.u = u;
+   return tmp;
 }
 
-static inline GLfloat UINT_AS_FLT(GLuint u)
+static inline union gl_constant_value INT_AS_UNION(GLint i)
 {
-   fi_type tmp;
-   tmp.u = u;
-   return tmp.f;
+   union gl_constant_value tmp;
+   tmp.i = i;
+   return tmp;
 }
 
-static inline unsigned FLT_AS_UINT(float f)
+static inline union gl_constant_value FLOAT_AS_UNION(GLfloat f)
 {
-   fi_type tmp;
+   union gl_constant_value tmp;
    tmp.f = f;
-   return tmp.u;
+   return tmp;
 }
-
 /**
  * Convert a floating point value to an unsigned fixed point value.
  *
@@ -382,6 +382,7 @@  do {                                    \
     V[3] = V3;                          \
 } while(0)
 
+
 /*@}*/
 
 
@@ -620,24 +621,24 @@  do {				\
  * The default values are chosen based on \p type.
  */
 static inline void
-COPY_CLEAN_4V_TYPE_AS_FLOAT(GLfloat dst[4], int sz, const GLfloat src[4],
+COPY_CLEAN_4V_TYPE_AS_UNION(gl_constant_value dst[4], int sz, const gl_constant_value src[4],
                             GLenum type)
 {
    switch (type) {
    case GL_FLOAT:
-      ASSIGN_4V(dst, 0, 0, 0, 1);
+      ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));
       break;
    case GL_INT:
-      ASSIGN_4V(dst, INT_AS_FLT(0), INT_AS_FLT(0),
-                     INT_AS_FLT(0), INT_AS_FLT(1));
+      ASSIGN_4V(dst, INT_AS_UNION(0), INT_AS_UNION(0),
+                INT_AS_UNION(0), INT_AS_UNION(1));
       break;
    case GL_UNSIGNED_INT:
-      ASSIGN_4V(dst, UINT_AS_FLT(0), UINT_AS_FLT(0),
-                     UINT_AS_FLT(0), UINT_AS_FLT(1));
+      ASSIGN_4V(dst, UINT_AS_UNION(0), UINT_AS_UNION(0),
+                UINT_AS_UNION(0), UINT_AS_UNION(1));
       break;
    default:
-      ASSIGN_4V(dst, 0.0f, 0.0f, 0.0f, 1.0f); /* silence warnings */
-      ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_FLOAT macro");
+      ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1)); /* silence warnings */
+      ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_UNION macro");
    }
    COPY_SZ_4V(dst, sz, src);
 }
diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h
index ec66934..17a0a10 100644
--- a/src/mesa/vbo/vbo_attrib_tmp.h
+++ b/src/mesa/vbo/vbo_attrib_tmp.h
@@ -28,6 +28,18 @@  USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "util/u_format_r11g11b10f.h"
 #include "main/varray.h"
 
+
+/* ATTR */
+#define ATTR( A, N, T, V0, V1, V2, V3 )	  ATTR_##T((A), (N), (T), (V0), (V1), (V2), (V3))
+
+#define ATTR_GL_UNSIGNED_INT( A, N, T, V0, V1, V2, V3 ) \
+    ATTR_UNION(A, N, T, UINT_AS_UNION(V0), UINT_AS_UNION(V1), UINT_AS_UNION(V2), UINT_AS_UNION(V3))
+#define ATTR_GL_INT( A, N, T, V0, V1, V2, V3 ) \
+    ATTR_UNION(A, N, T, INT_AS_UNION(V0), INT_AS_UNION(V1), INT_AS_UNION(V2), INT_AS_UNION(V3))
+#define ATTR_GL_FLOAT( A, N, T, V0, V1, V2, V3 )	\
+    ATTR_UNION(A, N, T, FLOAT_AS_UNION(V0), FLOAT_AS_UNION(V1), FLOAT_AS_UNION(V2), FLOAT_AS_UNION(V3))
+
+
 /* float */
 #define ATTR1FV( A, V ) ATTR( A, 1, GL_FLOAT, (V)[0], 0, 0, 1 )
 #define ATTR2FV( A, V ) ATTR( A, 2, GL_FLOAT, (V)[0], (V)[1], 0, 1 )
@@ -41,8 +53,8 @@  USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /* int */
 #define ATTRI( A, N, X, Y, Z, W) ATTR( A, N, GL_INT, \
-                                       INT_AS_FLT(X), INT_AS_FLT(Y), \
-                                       INT_AS_FLT(Z), INT_AS_FLT(W) )
+                                       X, Y, \
+                                       Z, W )
 
 #define ATTR2IV( A, V ) ATTRI( A, 2, (V)[0], (V)[1], 0, 1 )
 #define ATTR3IV( A, V ) ATTRI( A, 3, (V)[0], (V)[1], (V)[2], 1 )
@@ -56,8 +68,8 @@  USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /* uint */
 #define ATTRUI( A, N, X, Y, Z, W) ATTR( A, N, GL_UNSIGNED_INT, \
-                                        UINT_AS_FLT(X), UINT_AS_FLT(Y), \
-                                        UINT_AS_FLT(Z), UINT_AS_FLT(W) )
+                                        X, Y, \
+                                        Z, W )
 
 #define ATTR2UIV( A, V ) ATTRUI( A, 2, (V)[0], (V)[1], 0, 1 )
 #define ATTR3UIV( A, V ) ATTRUI( A, 3, (V)[0], (V)[1], (V)[2], 1 )
diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h
index e224513..8857ad6 100644
--- a/src/mesa/vbo/vbo_context.h
+++ b/src/mesa/vbo/vbo_context.h
@@ -56,6 +56,7 @@ 
 #include "vbo_exec.h"
 #include "vbo_save.h"
 
+#include "main/macros.h"
 
 struct vbo_context {
    struct gl_client_array currval[VBO_ATTRIB_MAX];
@@ -151,24 +152,23 @@  vbo_attrtype_to_integer_flag(GLenum format)
    }
 }
 
-
 /**
  * Return default component values for the given format.
- * The return type is an array of floats, because that's how we declare
- * the vertex storage despite the fact we sometimes store integers in there.
+ * The return type is an array of gl_constant_values, because that's how we declare
+ * the vertex storage : floats , integers or unsigned integers.
  */
-static inline const GLfloat *
-vbo_get_default_vals_as_float(GLenum format)
+static inline const gl_constant_value *
+vbo_get_default_vals_as_union(GLenum format)
 {
-   static const GLfloat default_float[4] = { 0, 0, 0, 1 };
-   static const GLint default_int[4] = { 0, 0, 0, 1 };
+   static const gl_constant_value default_float[4] = { {.f = 0}, {.f = 0}, {.f = 0}, {.f = 1} };
+   static const gl_constant_value default_int[4]   = { {.i = 0}, {.i = 0}, {.i = 0}, {.i = 1} };
 
    switch (format) {
    case GL_FLOAT:
       return default_float;
    case GL_INT:
    case GL_UNSIGNED_INT:
-      return (const GLfloat*)default_int;
+      return default_int;
    default:
       ASSERT(0);
       return NULL;
diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
index bb265de..1020afe 100644
--- a/src/mesa/vbo/vbo_exec.h
+++ b/src/mesa/vbo/vbo_exec.h
@@ -38,6 +38,7 @@  USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "vbo.h"
 #include "vbo_attrib.h"
 
+#include "program/prog_parameter.h"
 
 /**
  * Max number of primitives (number of glBegin/End pairs) per VBO.
@@ -71,7 +72,7 @@  struct vbo_exec_eval2_map {
 
 
 struct vbo_exec_copied_vtx {
-   GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
+   gl_constant_value buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
    GLuint nr;
 };
 
@@ -91,10 +92,10 @@  struct vbo_exec_context
       struct _mesa_prim prim[VBO_MAX_PRIM];
       GLuint prim_count;
 
-      GLfloat *buffer_map;
-      GLfloat *buffer_ptr;              /* cursor, points into buffer */
+      gl_constant_value *buffer_map;
+      gl_constant_value *buffer_ptr;              /* cursor, points into buffer */
       GLuint   buffer_used;             /* in bytes */
-      GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */
+      gl_constant_value vertex[VBO_ATTRIB_MAX*4]; /* current vertex */
 
       GLuint vert_count;
       GLuint max_vert;
@@ -104,7 +105,7 @@  struct vbo_exec_context
       GLenum attrtype[VBO_ATTRIB_MAX];
       GLubyte active_sz[VBO_ATTRIB_MAX];
 
-      GLfloat *attrptr[VBO_ATTRIB_MAX]; 
+      gl_constant_value *attrptr[VBO_ATTRIB_MAX];
       struct gl_client_array arrays[VERT_ATTRIB_MAX];
 
       /* According to program mode, the values above plus current
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 5f8250e..1dfc6a4 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -46,7 +46,6 @@  USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "vbo_context.h"
 #include "vbo_noop.h"
 
-
 #ifdef ERROR
 #undef ERROR
 #endif
@@ -115,7 +114,7 @@  static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
  */
 void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )
 {
-   GLfloat *data = exec->vtx.copied.buffer;
+   gl_constant_value *data = exec->vtx.copied.buffer;
    GLuint i;
 
    /* Run pipeline on current vertices, copy wrapped vertices
@@ -158,10 +157,10 @@  static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
          /* Note: the exec->vtx.current[i] pointers point into the
           * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
           */
-	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
-         GLfloat tmp[4];
+	 gl_constant_value *current = (gl_constant_value *)vbo->currval[i].Ptr;
+         gl_constant_value tmp[4];
 
-         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
+         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
                                      exec->vtx.attrsz[i],
                                      exec->vtx.attrptr[i],
                                      exec->vtx.attrtype[i]);
@@ -214,7 +213,7 @@  vbo_exec_copy_from_current(struct vbo_exec_context *exec)
    GLint i;
 
    for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
-      const GLfloat *current = (GLfloat *) vbo->currval[i].Ptr;
+      const gl_constant_value *current = (gl_constant_value *) vbo->currval[i].Ptr;
       switch (exec->vtx.attrsz[i]) {
       case 4: exec->vtx.attrptr[i][3] = current[3];
       case 3: exec->vtx.attrptr[i][2] = current[2];
@@ -240,7 +239,7 @@  vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    struct gl_context *ctx = exec->ctx;
    struct vbo_context *vbo = vbo_context(ctx);
    const GLint lastcount = exec->vtx.vert_count;
-   GLfloat *old_attrptr[VBO_ATTRIB_MAX];
+   gl_constant_value *old_attrptr[VBO_ATTRIB_MAX];
    const GLuint old_vtx_size = exec->vtx.vertex_size; /* floats per vertex */
    const GLuint oldSize = exec->vtx.attrsz[attr];
    GLuint i;
@@ -287,7 +286,7 @@  vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    if (unlikely(oldSize)) {
       /* Size changed, recalculate all the attrptr[] values
        */
-      GLfloat *tmp = exec->vtx.vertex;
+      gl_constant_value *tmp = exec->vtx.vertex;
 
       for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
 	 if (exec->vtx.attrsz[i]) {
@@ -306,7 +305,7 @@  vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    else {
       /* Just have to append the new attribute at the end */
       exec->vtx.attrptr[attr] = exec->vtx.vertex +
-	 exec->vtx.vertex_size - newSize;
+        exec->vtx.vertex_size - newSize;
    }
 
    /* Replay stored vertices to translate them
@@ -315,8 +314,8 @@  vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
     * -- No need to replay - just copy piecewise
     */
    if (unlikely(exec->vtx.copied.nr)) {
-      GLfloat *data = exec->vtx.copied.buffer;
-      GLfloat *dest = exec->vtx.buffer_ptr;
+      gl_constant_value *data = exec->vtx.copied.buffer;
+      gl_constant_value *dest = exec->vtx.buffer_ptr;
       GLuint j;
 
       assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);
@@ -331,13 +330,13 @@  vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
 
 	       if (j == attr) {
 		  if (oldSize) {
-		     GLfloat tmp[4];
-                     COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp, oldSize,
+		     gl_constant_value tmp[4];
+		     COPY_CLEAN_4V_TYPE_AS_UNION(tmp, oldSize,
                                                  data + old_offset,
                                                  exec->vtx.attrtype[j]);
 		     COPY_SZ_4V(dest + new_offset, newSize, tmp);
 		  } else {
-		     GLfloat *current = (GLfloat *)vbo->currval[j].Ptr;
+		     gl_constant_value *current = (gl_constant_value *)vbo->currval[j].Ptr;
 		     COPY_SZ_4V(dest + new_offset, sz, current);
 		  }
 	       }
@@ -376,14 +375,14 @@  vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
    }
    else if (newSize < exec->vtx.active_sz[attr]) {
       GLuint i;
-      const GLfloat *id =
-            vbo_get_default_vals_as_float(exec->vtx.attrtype[attr]);
+      const gl_constant_value *id =
+            vbo_get_default_vals_as_union(exec->vtx.attrtype[attr]);
 
       /* New size is smaller - just need to fill in some
        * zeros.  Don't need to flush or wrap.
        */
       for (i = newSize; i <= exec->vtx.attrsz[attr]; i++)
-	 exec->vtx.attrptr[attr][i-1] = id[i-1];
+        exec->vtx.attrptr[attr][i-1] = id[i-1];
    }
 
    exec->vtx.active_sz[attr] = newSize;
@@ -401,7 +400,7 @@  vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
  * This macro is used to implement all the glVertex, glColor, glTexCoord,
  * glVertexAttrib, etc functions.
  */
-#define ATTR( A, N, T, V0, V1, V2, V3 )					\
+#define ATTR_UNION( A, N, T, V0, V1, V2, V3 )				\
 do {									\
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;		\
 									\
@@ -412,12 +411,12 @@  do {									\
       vbo_exec_fixup_vertex(ctx, A, N);					\
    									\
    {									\
-      GLfloat *dest = exec->vtx.attrptr[A];				\
+      gl_constant_value *dest = exec->vtx.attrptr[A];			\
       if (N>0) dest[0] = V0;						\
       if (N>1) dest[1] = V1;						\
       if (N>2) dest[2] = V2;						\
       if (N>3) dest[3] = V3;						\
-      exec->vtx.attrtype[A] = T;                                        \
+      exec->vtx.attrtype[A] = T;					\
    }									\
 									\
    if ((A) == 0) {							\
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 362cc10..47072f1 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -73,8 +73,8 @@  vbo_copy_vertices( struct vbo_exec_context *exec )
    GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count;
    GLuint ovf, i;
    GLuint sz = exec->vtx.vertex_size;
-   GLfloat *dst = exec->vtx.copied.buffer;
-   const GLfloat *src = (exec->vtx.buffer_map + 
+   gl_constant_value *dst = exec->vtx.copied.buffer;
+   const gl_constant_value *src = (exec->vtx.buffer_map +
                          exec->vtx.prim[exec->vtx.prim_count-1].start * 
                          exec->vtx.vertex_size);
 
@@ -336,7 +336,7 @@  vbo_exec_vtx_map( struct vbo_exec_context *exec )
                                  exec->vtx.bufferobj)) {
          /* buffer allocation worked, now map the buffer */
          exec->vtx.buffer_map =
-            (GLfloat *)ctx->Driver.MapBufferRange(ctx,
+            (gl_constant_value *)ctx->Driver.MapBufferRange(ctx,
                                                   0, VBO_VERT_BUFFER_SIZE,
                                                   accessRange,
                                                   exec->vtx.bufferobj,
diff --git a/src/mesa/vbo/vbo_exec_eval.c b/src/mesa/vbo/vbo_exec_eval.c
index 82f89b9..3360511 100644
--- a/src/mesa/vbo/vbo_exec_eval.c
+++ b/src/mesa/vbo/vbo_exec_eval.c
@@ -130,11 +130,11 @@  void vbo_exec_do_EvalCoord1f(struct vbo_exec_context *exec, GLfloat u)
       struct gl_1d_map *map = exec->eval.map1[attr].map;
       if (map) {
 	 GLfloat uu = (u - map->u1) * map->du;
-	 GLfloat data[4];
+	 gl_constant_value data[4];
 
-	 ASSIGN_4V(data, 0, 0, 0, 1);
+	 ASSIGN_4V(data, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));
 
-	 _math_horner_bezier_curve(map->Points, data, uu, 
+	 _math_horner_bezier_curve(map->Points, &data[0].f, uu,
 				   exec->eval.map1[attr].sz, 
 				   map->Order);
 
@@ -176,12 +176,12 @@  void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
       if (map) {
 	 GLfloat uu = (u - map->u1) * map->du;
 	 GLfloat vv = (v - map->v1) * map->dv;
-	 GLfloat data[4];
+	 gl_constant_value data[4];
 
-	 ASSIGN_4V(data, 0, 0, 0, 1);
+	 ASSIGN_4V(data, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));
 
 	 _math_horner_bezier_surf(map->Points, 
-				  data, 
+				  &data[0].f,
 				  uu, vv, 
 				  exec->eval.map2[attr].sz, 
 				  map->Uorder, map->Vorder);
@@ -203,7 +203,7 @@  void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
       ASSIGN_4V(vertex, 0, 0, 0, 1);
 
       if (exec->ctx->Eval.AutoNormal) {
-	 GLfloat normal[4];
+	 gl_constant_value normal[4];
          GLfloat du[4], dv[4];
 
          _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 
@@ -221,11 +221,11 @@  void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
 	 }
 
 
-         CROSS3(normal, du, dv);
-         NORMALIZE_3FV(normal);
-	 normal[3] = 1.0;
+         CROSS3(&normal[0].f, du, dv);
+         NORMALIZE_3FV(&normal[0].f);
+	 normal[3] = FLOAT_AS_UNION(1.0);
 
-	 COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],
+ 	 COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],
 		     exec->vtx.attrsz[VBO_ATTRIB_NORMAL],
 		     normal );
 
diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h
index fd26b5f..6d2ad277 100644
--- a/src/mesa/vbo/vbo_save.h
+++ b/src/mesa/vbo/vbo_save.h
@@ -40,7 +40,7 @@  USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 struct vbo_save_copied_vtx {
-   GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
+   gl_constant_value buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
    GLuint nr;
 };
 
@@ -107,7 +107,7 @@  struct vbo_save_vertex_list {
  */
 struct vbo_save_vertex_store {
    struct gl_buffer_object *bufferobj;
-   GLfloat *buffer;
+   gl_constant_value *buffer;
    GLuint used;
    GLuint refcount;
 };
@@ -133,7 +133,7 @@  struct vbo_save_context {
 
    GLboolean out_of_memory;  /**< True if last VBO allocation failed */
 
-   GLfloat *buffer;
+   gl_constant_value *buffer;
    GLuint count;
    GLuint wrap_count;
    GLuint replay_flags;
@@ -144,9 +144,9 @@  struct vbo_save_context {
    struct vbo_save_vertex_store *vertex_store;
    struct vbo_save_primitive_store *prim_store;
 
-   GLfloat *buffer_ptr;		   /* cursor, points into buffer */
-   GLfloat vertex[VBO_ATTRIB_MAX*4];	   /* current values */
-   GLfloat *attrptr[VBO_ATTRIB_MAX];
+   gl_constant_value *buffer_ptr;		   /* cursor, points into buffer */
+   gl_constant_value vertex[VBO_ATTRIB_MAX*4];	   /* current values */
+   gl_constant_value *attrptr[VBO_ATTRIB_MAX];
    GLuint vert_count;
    GLuint max_vert;
    GLboolean dangling_attr_ref;
@@ -155,7 +155,7 @@  struct vbo_save_context {
 
    struct vbo_save_copied_vtx copied;
    
-   GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->ListState */
+   gl_constant_value *current[VBO_ATTRIB_MAX]; /* points into ctx->ListState */
    GLubyte *currentsz[VBO_ATTRIB_MAX];
 };
 
@@ -186,7 +186,7 @@  void vbo_save_playback_vertex_list( struct gl_context *ctx, void *data );
 
 void vbo_save_api_init( struct vbo_save_context *save );
 
-GLfloat *
+gl_constant_value *
 vbo_save_map_vertex_store(struct gl_context *ctx,
                           struct vbo_save_vertex_store *vertex_store);
 
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index beef342..775be51 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -99,14 +99,14 @@  USE OR OTHER DEALINGS IN THE SOFTWARE.
 static GLuint
 _save_copy_vertices(struct gl_context *ctx,
                     const struct vbo_save_vertex_list *node,
-                    const GLfloat * src_buffer)
+                    const gl_constant_value * src_buffer)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
    GLuint nr = prim->count;
    GLuint sz = save->vertex_size;
-   const GLfloat *src = src_buffer + prim->start * sz;
-   GLfloat *dst = save->copied.buffer;
+   const gl_constant_value *src = src_buffer + prim->start * sz;
+   gl_constant_value *dst = save->copied.buffer;
    GLuint ovf, i;
 
    if (prim->end)
@@ -233,7 +233,7 @@  free_vertex_store(struct gl_context *ctx,
 }
 
 
-GLfloat *
+gl_constant_value *
 vbo_save_map_vertex_store(struct gl_context *ctx,
                           struct vbo_save_vertex_store *vertex_store)
 {
@@ -249,7 +249,7 @@  vbo_save_map_vertex_store(struct gl_context *ctx,
       /* Map the remaining free space in the VBO */
       GLintptr offset = vertex_store->used * sizeof(GLfloat);
       GLsizeiptr size = vertex_store->bufferobj->Size - offset;
-      GLfloat *range = (GLfloat *)
+      gl_constant_value *range = (gl_constant_value *)
          ctx->Driver.MapBufferRange(ctx, offset, size, access,
                                     vertex_store->bufferobj,
                                     MAP_INTERNAL);
@@ -549,7 +549,7 @@  static void
 _save_wrap_filled_vertex(struct gl_context *ctx)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
-   GLfloat *data = save->copied.buffer;
+   gl_constant_value *data = save->copied.buffer;
    GLuint i;
 
    /* Emit a glEnd to close off the last vertex list.
@@ -578,7 +578,7 @@  _save_copy_to_current(struct gl_context *ctx)
    for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
       if (save->attrsz[i]) {
          save->currentsz[i][0] = save->attrsz[i];
-         COPY_CLEAN_4V_TYPE_AS_FLOAT(save->current[i], save->attrsz[i],
+         COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
                                      save->attrptr[i], save->attrtype[i]);
       }
    }
@@ -620,7 +620,7 @@  _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLuint oldsz;
    GLuint i;
-   GLfloat *tmp;
+   gl_constant_value *tmp;
 
    /* Store the current run of vertices, and emit a GL_END.  Emit a
     * BEGIN in the new buffer.
@@ -669,8 +669,8 @@  _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
     * and will need fixup at runtime.
     */
    if (save->copied.nr) {
-      const GLfloat *data = save->copied.buffer;
-      GLfloat *dest = save->buffer;
+      const gl_constant_value *data = save->copied.buffer;
+      gl_constant_value *dest = save->buffer;
       GLuint j;
 
       /* Need to note this and fix up at runtime (or loopback):
@@ -685,7 +685,7 @@  _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
             if (save->attrsz[j]) {
                if (j == attr) {
                   if (oldsz) {
-                     COPY_CLEAN_4V_TYPE_AS_FLOAT(dest, oldsz, data,
+                     COPY_CLEAN_4V_TYPE_AS_UNION(dest, oldsz, data,
                                                  save->attrtype[j]);
                      data += oldsz;
                      dest += newsz;
@@ -729,7 +729,7 @@  save_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
    }
    else if (sz < save->active_sz[attr]) {
       GLuint i;
-      const GLfloat *id = vbo_get_default_vals_as_float(save->attrtype[attr]);
+      const gl_constant_value *id = vbo_get_default_vals_as_union(save->attrtype[attr]);
 
       /* New size is equal or smaller - just need to fill in some
        * zeros.
@@ -772,7 +772,7 @@  _save_reset_vertex(struct gl_context *ctx)
  * 3f version won't otherwise set color[3] to 1.0 -- this is the job
  * of the chooser function when switching between Color4f and Color3f.
  */
-#define ATTR(A, N, T, V0, V1, V2, V3)				\
+#define ATTR_UNION(A, N, T, V0, V1, V2, V3)			\
 do {								\
    struct vbo_save_context *save = &vbo_context(ctx)->save;	\
 								\
@@ -780,12 +780,12 @@  do {								\
       save_fixup_vertex(ctx, A, N);				\
 								\
    {								\
-      GLfloat *dest = save->attrptr[A];				\
+      gl_constant_value *dest = save->attrptr[A];		\
       if (N>0) dest[0] = V0;					\
       if (N>1) dest[1] = V1;					\
       if (N>2) dest[2] = V2;					\
       if (N>3) dest[3] = V3;					\
-      save->attrtype[A] = T;                                    \
+      save->attrtype[A] = T;					\
    }								\
 								\
    if ((A) == 0) {						\
@@ -1566,14 +1566,14 @@  _save_current_init(struct gl_context *ctx)
       const GLuint j = i - VBO_ATTRIB_POS;
       ASSERT(j < VERT_ATTRIB_MAX);
       save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
-      save->current[i] = ctx->ListState.CurrentAttrib[j];
+      save->current[i] = (gl_constant_value*)(ctx->ListState.CurrentAttrib[j]);
    }
 
    for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
       const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
       ASSERT(j < MAT_ATTRIB_MAX);
       save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
-      save->current[i] = ctx->ListState.CurrentMaterial[j];
+      save->current[i] = (gl_constant_value*)ctx->ListState.CurrentMaterial[j];
    }
 }
 
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index d0521d7..01a0ec5 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -76,11 +76,11 @@  _playback_copy_to_current(struct gl_context *ctx,
    for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
       if (node->attrsz[i]) {
 	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
-         GLfloat tmp[4];
+         gl_constant_value tmp[4];
 
-         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
+         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
                                      node->attrsz[i],
-                                     data,
+                                     (gl_constant_value*)data,
                                      node->attrtype[i]);
          
          if (node->attrtype[i] != vbo->currval[i].Type ||

Comments

I have a few concerns about this patch.

Firstly, including prog_parameter.h from macros.h feels wrong.  Macros 
are a lower-level concept than program parameters so the "lower" thing 
shouldn't be including the "higher" thing.

Instead of using gl_constant_value everywhere, why not use the fi_type 
which is basically the same thing?

more below...


On 02/12/2015 11:00 AM, marius.predut@intel.com wrote:
> From: Marius Predut <marius.predut@intel.com>
>
> On 32-bit, for floating point operations is used x86 FPU registers
> instead SSE, reason for  when reinterprets an integer as a float
> result is unexpected (modify floats when they are written to memory).
> The defect was checked with and without -O3 compiler flag
>
> This patch is based Neil Roberts review.
> This patch is more complete - it include changes on all places that are storing attribute values to use gl_constant_value.
> This patch fix 2 piglit tests.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82668
> Signed-off-by: Marius Predut <marius.predut@intel.com>
> ---
>   src/mesa/main/context.c       |    3 ++-
>   src/mesa/main/macros.h        |   41 +++++++++++++++++++++--------------------
>   src/mesa/vbo/vbo_attrib_tmp.h |   20 ++++++++++++++++----
>   src/mesa/vbo/vbo_context.h    |   16 ++++++++--------
>   src/mesa/vbo/vbo_exec.h       |   11 ++++++-----
>   src/mesa/vbo/vbo_exec_api.c   |   39 +++++++++++++++++++--------------------
>   src/mesa/vbo/vbo_exec_draw.c  |    6 +++---
>   src/mesa/vbo/vbo_exec_eval.c  |   22 +++++++++++-----------
>   src/mesa/vbo/vbo_save.h       |   16 ++++++++--------
>   src/mesa/vbo/vbo_save_api.c   |   34 +++++++++++++++++-----------------
>   src/mesa/vbo/vbo_save_draw.c  |    6 +++---
>   11 files changed, 114 insertions(+), 100 deletions(-)
>
> diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
> index 63d30a2..f0597e2 100644
> --- a/src/mesa/main/context.c
> +++ b/src/mesa/main/context.c
> @@ -134,6 +134,7 @@
>   #include "math/m_matrix.h"
>   #include "main/dispatch.h" /* for _gloffset_COUNT */
>   #include "uniforms.h"
> +#include "macros.h"
>
>   #ifdef USE_SPARC_ASM
>   #include "sparc/sparc.h"
> @@ -656,7 +657,7 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api)
>      consts->MaxSamples = 0;
>
>      /* GLSL default if NativeIntegers == FALSE */
> -   consts->UniformBooleanTrue = FLT_AS_UINT(1.0f);
> +   consts->UniformBooleanTrue = FLOAT_AS_UNION(1.0f).u;

I don't think this has to change if we just keep FLT_AS_UINT().


>
>      /* GL_ARB_sync */
>      consts->MaxServerWaitTimeout = 0x1fff7fffffffULL;
> diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
> index cd5f2d6..2af15de 100644
> --- a/src/mesa/main/macros.h
> +++ b/src/mesa/main/macros.h
> @@ -32,6 +32,7 @@
>   #define MACROS_H
>
>   #include "imports.h"
> +#include "program/prog_parameter.h"

See above.


>
>
>   /**
> @@ -170,27 +171,26 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
>   	ub = ((GLubyte) F_TO_I((f) * 255.0F))
>   #endif
>
> -static inline GLfloat INT_AS_FLT(GLint i)
> +static union gl_constant_value UINT_AS_UNION(GLuint u)
>   {
> -   fi_type tmp;
> -   tmp.i = i;
> -   return tmp.f;
> +   union gl_constant_value tmp;
> +   tmp.u = u;
> +   return tmp;
>   }
>
> -static inline GLfloat UINT_AS_FLT(GLuint u)
> +static inline union gl_constant_value INT_AS_UNION(GLint i)
>   {
> -   fi_type tmp;
> -   tmp.u = u;
> -   return tmp.f;
> +   union gl_constant_value tmp;
> +   tmp.i = i;
> +   return tmp;
>   }
>
> -static inline unsigned FLT_AS_UINT(float f)
> +static inline union gl_constant_value FLOAT_AS_UNION(GLfloat f)
>   {
> -   fi_type tmp;
> +   union gl_constant_value tmp;
>      tmp.f = f;
> -   return tmp.u;
> +   return tmp;
>   }
> -
>   /**
>    * Convert a floating point value to an unsigned fixed point value.
>    *
> @@ -382,6 +382,7 @@ do {                                    \
>       V[3] = V3;                          \
>   } while(0)
>
> +

Seems to be a few cases of unrelated whitespace changes.


>   /*@}*/
>
>
> @@ -620,24 +621,24 @@ do {				\
>    * The default values are chosen based on \p type.
>    */
>   static inline void
> -COPY_CLEAN_4V_TYPE_AS_FLOAT(GLfloat dst[4], int sz, const GLfloat src[4],
> +COPY_CLEAN_4V_TYPE_AS_UNION(gl_constant_value dst[4], int sz, const gl_constant_value src[4],
>                               GLenum type)
>   {
>      switch (type) {
>      case GL_FLOAT:
> -      ASSIGN_4V(dst, 0, 0, 0, 1);
> +      ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));
>         break;
>      case GL_INT:
> -      ASSIGN_4V(dst, INT_AS_FLT(0), INT_AS_FLT(0),
> -                     INT_AS_FLT(0), INT_AS_FLT(1));
> +      ASSIGN_4V(dst, INT_AS_UNION(0), INT_AS_UNION(0),
> +                INT_AS_UNION(0), INT_AS_UNION(1));
>         break;
>      case GL_UNSIGNED_INT:
> -      ASSIGN_4V(dst, UINT_AS_FLT(0), UINT_AS_FLT(0),
> -                     UINT_AS_FLT(0), UINT_AS_FLT(1));
> +      ASSIGN_4V(dst, UINT_AS_UNION(0), UINT_AS_UNION(0),
> +                UINT_AS_UNION(0), UINT_AS_UNION(1));
>         break;
>      default:
> -      ASSIGN_4V(dst, 0.0f, 0.0f, 0.0f, 1.0f); /* silence warnings */
> -      ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_FLOAT macro");
> +      ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1)); /* silence warnings */
> +      ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_UNION macro");
>      }
>      COPY_SZ_4V(dst, sz, src);
>   }
> diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h
> index ec66934..17a0a10 100644
> --- a/src/mesa/vbo/vbo_attrib_tmp.h
> +++ b/src/mesa/vbo/vbo_attrib_tmp.h
> @@ -28,6 +28,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>   #include "util/u_format_r11g11b10f.h"
>   #include "main/varray.h"
>
> +
> +/* ATTR */
> +#define ATTR( A, N, T, V0, V1, V2, V3 )	  ATTR_##T((A), (N), (T), (V0), (V1), (V2), (V3))
> +
> +#define ATTR_GL_UNSIGNED_INT( A, N, T, V0, V1, V2, V3 ) \
> +    ATTR_UNION(A, N, T, UINT_AS_UNION(V0), UINT_AS_UNION(V1), UINT_AS_UNION(V2), UINT_AS_UNION(V3))

Why does 'T' need to be an argument to this macro?  Isn't it always 
GL_UNSIGNED_INT?


> +#define ATTR_GL_INT( A, N, T, V0, V1, V2, V3 ) \
> +    ATTR_UNION(A, N, T, INT_AS_UNION(V0), INT_AS_UNION(V1), INT_AS_UNION(V2), INT_AS_UNION(V3))
> +#define ATTR_GL_FLOAT( A, N, T, V0, V1, V2, V3 )	\
> +    ATTR_UNION(A, N, T, FLOAT_AS_UNION(V0), FLOAT_AS_UNION(V1), FLOAT_AS_UNION(V2), FLOAT_AS_UNION(V3))
> +
> +

I think there's more macro use here than necessary...


>   /* float */
>   #define ATTR1FV( A, V ) ATTR( A, 1, GL_FLOAT, (V)[0], 0, 0, 1 )
>   #define ATTR2FV( A, V ) ATTR( A, 2, GL_FLOAT, (V)[0], (V)[1], 0, 1 )
> @@ -41,8 +53,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>
>   /* int */
>   #define ATTRI( A, N, X, Y, Z, W) ATTR( A, N, GL_INT, \
> -                                       INT_AS_FLT(X), INT_AS_FLT(Y), \
> -                                       INT_AS_FLT(Z), INT_AS_FLT(W) )
> +                                       X, Y, \
> +                                       Z, W )

For example, couldn't this be:
#define ATTRI( A, N, X, Y, Z, W)  ATTR_GL_INT( A, N, X, Y, Z, W )

Or even:
#define ATTRI( A, N, X, Y, Z, W)  ATTR_UNION(A, N, GL_INT,     \
                                              INT_AS_UNION(V0), \
                                              INT_AS_UNION(V1), \
                                              INT_AS_UNION(V2), \
                                              INT_AS_UNION(V3))

Then get rid of ATTR().  Or keep it instead of introducing ATTR_UNION().


>
>   #define ATTR2IV( A, V ) ATTRI( A, 2, (V)[0], (V)[1], 0, 1 )
>   #define ATTR3IV( A, V ) ATTRI( A, 3, (V)[0], (V)[1], (V)[2], 1 )
> @@ -56,8 +68,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>
>   /* uint */
>   #define ATTRUI( A, N, X, Y, Z, W) ATTR( A, N, GL_UNSIGNED_INT, \
> -                                        UINT_AS_FLT(X), UINT_AS_FLT(Y), \
> -                                        UINT_AS_FLT(Z), UINT_AS_FLT(W) )
> +                                        X, Y, \
> +                                        Z, W )
>
>   #define ATTR2UIV( A, V ) ATTRUI( A, 2, (V)[0], (V)[1], 0, 1 )
>   #define ATTR3UIV( A, V ) ATTRUI( A, 3, (V)[0], (V)[1], (V)[2], 1 )
> diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h
> index e224513..8857ad6 100644
> --- a/src/mesa/vbo/vbo_context.h
> +++ b/src/mesa/vbo/vbo_context.h
> @@ -56,6 +56,7 @@
>   #include "vbo_exec.h"
>   #include "vbo_save.h"
>
> +#include "main/macros.h"
>
>   struct vbo_context {
>      struct gl_client_array currval[VBO_ATTRIB_MAX];
> @@ -151,24 +152,23 @@ vbo_attrtype_to_integer_flag(GLenum format)
>      }
>   }
>
> -
>   /**
>    * Return default component values for the given format.
> - * The return type is an array of floats, because that's how we declare
> - * the vertex storage despite the fact we sometimes store integers in there.
> + * The return type is an array of gl_constant_values, because that's how we declare
> + * the vertex storage : floats , integers or unsigned integers.
>    */
> -static inline const GLfloat *
> -vbo_get_default_vals_as_float(GLenum format)
> +static inline const gl_constant_value *
> +vbo_get_default_vals_as_union(GLenum format)
>   {
> -   static const GLfloat default_float[4] = { 0, 0, 0, 1 };
> -   static const GLint default_int[4] = { 0, 0, 0, 1 };
> +   static const gl_constant_value default_float[4] = { {.f = 0}, {.f = 0}, {.f = 0}, {.f = 1} };
> +   static const gl_constant_value default_int[4]   = { {.i = 0}, {.i = 0}, {.i = 0}, {.i = 1} };

I don't recall if this will be accepted by MSVC 2013.  It won't work 
with older versions.


>
>      switch (format) {
>      case GL_FLOAT:
>         return default_float;
>      case GL_INT:
>      case GL_UNSIGNED_INT:
> -      return (const GLfloat*)default_int;
> +      return default_int;
>      default:
>         ASSERT(0);
>         return NULL;
> diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
> index bb265de..1020afe 100644
> --- a/src/mesa/vbo/vbo_exec.h
> +++ b/src/mesa/vbo/vbo_exec.h
> @@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>   #include "vbo.h"
>   #include "vbo_attrib.h"
>
> +#include "program/prog_parameter.h"
>
>   /**
>    * Max number of primitives (number of glBegin/End pairs) per VBO.
> @@ -71,7 +72,7 @@ struct vbo_exec_eval2_map {
>
>
>   struct vbo_exec_copied_vtx {
> -   GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
> +   gl_constant_value buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
>      GLuint nr;
>   };
>
> @@ -91,10 +92,10 @@ struct vbo_exec_context
>         struct _mesa_prim prim[VBO_MAX_PRIM];
>         GLuint prim_count;
>
> -      GLfloat *buffer_map;
> -      GLfloat *buffer_ptr;              /* cursor, points into buffer */
> +      gl_constant_value *buffer_map;
> +      gl_constant_value *buffer_ptr;              /* cursor, points into buffer */
>         GLuint   buffer_used;             /* in bytes */
> -      GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */
> +      gl_constant_value vertex[VBO_ATTRIB_MAX*4]; /* current vertex */
>
>         GLuint vert_count;
>         GLuint max_vert;
> @@ -104,7 +105,7 @@ struct vbo_exec_context
>         GLenum attrtype[VBO_ATTRIB_MAX];
>         GLubyte active_sz[VBO_ATTRIB_MAX];
>
> -      GLfloat *attrptr[VBO_ATTRIB_MAX];
> +      gl_constant_value *attrptr[VBO_ATTRIB_MAX];
>         struct gl_client_array arrays[VERT_ATTRIB_MAX];
>
>         /* According to program mode, the values above plus current
> diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
> index 5f8250e..1dfc6a4 100644
> --- a/src/mesa/vbo/vbo_exec_api.c
> +++ b/src/mesa/vbo/vbo_exec_api.c
> @@ -46,7 +46,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>   #include "vbo_context.h"
>   #include "vbo_noop.h"
>
> -
>   #ifdef ERROR
>   #undef ERROR
>   #endif
> @@ -115,7 +114,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
>    */
>   void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )
>   {
> -   GLfloat *data = exec->vtx.copied.buffer;
> +   gl_constant_value *data = exec->vtx.copied.buffer;
>      GLuint i;
>
>      /* Run pipeline on current vertices, copy wrapped vertices
> @@ -158,10 +157,10 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
>            /* Note: the exec->vtx.current[i] pointers point into the
>             * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
>             */
> -	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
> -         GLfloat tmp[4];
> +	 gl_constant_value *current = (gl_constant_value *)vbo->currval[i].Ptr;
> +         gl_constant_value tmp[4];
>
> -         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
> +         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
>                                        exec->vtx.attrsz[i],
>                                        exec->vtx.attrptr[i],
>                                        exec->vtx.attrtype[i]);
> @@ -214,7 +213,7 @@ vbo_exec_copy_from_current(struct vbo_exec_context *exec)
>      GLint i;
>
>      for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
> -      const GLfloat *current = (GLfloat *) vbo->currval[i].Ptr;
> +      const gl_constant_value *current = (gl_constant_value *) vbo->currval[i].Ptr;
>         switch (exec->vtx.attrsz[i]) {
>         case 4: exec->vtx.attrptr[i][3] = current[3];
>         case 3: exec->vtx.attrptr[i][2] = current[2];
> @@ -240,7 +239,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
>      struct gl_context *ctx = exec->ctx;
>      struct vbo_context *vbo = vbo_context(ctx);
>      const GLint lastcount = exec->vtx.vert_count;
> -   GLfloat *old_attrptr[VBO_ATTRIB_MAX];
> +   gl_constant_value *old_attrptr[VBO_ATTRIB_MAX];
>      const GLuint old_vtx_size = exec->vtx.vertex_size; /* floats per vertex */
>      const GLuint oldSize = exec->vtx.attrsz[attr];
>      GLuint i;
> @@ -287,7 +286,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
>      if (unlikely(oldSize)) {
>         /* Size changed, recalculate all the attrptr[] values
>          */
> -      GLfloat *tmp = exec->vtx.vertex;
> +      gl_constant_value *tmp = exec->vtx.vertex;
>
>         for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
>   	 if (exec->vtx.attrsz[i]) {
> @@ -306,7 +305,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
>      else {
>         /* Just have to append the new attribute at the end */
>         exec->vtx.attrptr[attr] = exec->vtx.vertex +
> -	 exec->vtx.vertex_size - newSize;
> +        exec->vtx.vertex_size - newSize;
>      }
>
>      /* Replay stored vertices to translate them
> @@ -315,8 +314,8 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
>       * -- No need to replay - just copy piecewise
>       */
>      if (unlikely(exec->vtx.copied.nr)) {
> -      GLfloat *data = exec->vtx.copied.buffer;
> -      GLfloat *dest = exec->vtx.buffer_ptr;
> +      gl_constant_value *data = exec->vtx.copied.buffer;
> +      gl_constant_value *dest = exec->vtx.buffer_ptr;
>         GLuint j;
>
>         assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);
> @@ -331,13 +330,13 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
>
>   	       if (j == attr) {
>   		  if (oldSize) {
> -		     GLfloat tmp[4];
> -                     COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp, oldSize,
> +		     gl_constant_value tmp[4];
> +		     COPY_CLEAN_4V_TYPE_AS_UNION(tmp, oldSize,
>                                                    data + old_offset,
>                                                    exec->vtx.attrtype[j]);
>   		     COPY_SZ_4V(dest + new_offset, newSize, tmp);
>   		  } else {
> -		     GLfloat *current = (GLfloat *)vbo->currval[j].Ptr;
> +		     gl_constant_value *current = (gl_constant_value *)vbo->currval[j].Ptr;
>   		     COPY_SZ_4V(dest + new_offset, sz, current);
>   		  }
>   	       }
> @@ -376,14 +375,14 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
>      }
>      else if (newSize < exec->vtx.active_sz[attr]) {
>         GLuint i;
> -      const GLfloat *id =
> -            vbo_get_default_vals_as_float(exec->vtx.attrtype[attr]);
> +      const gl_constant_value *id =
> +            vbo_get_default_vals_as_union(exec->vtx.attrtype[attr]);
>
>         /* New size is smaller - just need to fill in some
>          * zeros.  Don't need to flush or wrap.
>          */
>         for (i = newSize; i <= exec->vtx.attrsz[attr]; i++)
> -	 exec->vtx.attrptr[attr][i-1] = id[i-1];
> +        exec->vtx.attrptr[attr][i-1] = id[i-1];
>      }
>
>      exec->vtx.active_sz[attr] = newSize;
> @@ -401,7 +400,7 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
>    * This macro is used to implement all the glVertex, glColor, glTexCoord,
>    * glVertexAttrib, etc functions.
>    */
> -#define ATTR( A, N, T, V0, V1, V2, V3 )					\
> +#define ATTR_UNION( A, N, T, V0, V1, V2, V3 )				\
>   do {									\
>      struct vbo_exec_context *exec = &vbo_context(ctx)->exec;		\
>   									\
> @@ -412,12 +411,12 @@ do {									\
>         vbo_exec_fixup_vertex(ctx, A, N);					\
>      									\
>      {									\
> -      GLfloat *dest = exec->vtx.attrptr[A];				\
> +      gl_constant_value *dest = exec->vtx.attrptr[A];			\
>         if (N>0) dest[0] = V0;						\
>         if (N>1) dest[1] = V1;						\
>         if (N>2) dest[2] = V2;						\
>         if (N>3) dest[3] = V3;						\
> -      exec->vtx.attrtype[A] = T;                                        \
> +      exec->vtx.attrtype[A] = T;					\
>      }									\
>   									\
>      if ((A) == 0) {							\
> diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
> index 362cc10..47072f1 100644
> --- a/src/mesa/vbo/vbo_exec_draw.c
> +++ b/src/mesa/vbo/vbo_exec_draw.c
> @@ -73,8 +73,8 @@ vbo_copy_vertices( struct vbo_exec_context *exec )
>      GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count;
>      GLuint ovf, i;
>      GLuint sz = exec->vtx.vertex_size;
> -   GLfloat *dst = exec->vtx.copied.buffer;
> -   const GLfloat *src = (exec->vtx.buffer_map +
> +   gl_constant_value *dst = exec->vtx.copied.buffer;
> +   const gl_constant_value *src = (exec->vtx.buffer_map +
>                            exec->vtx.prim[exec->vtx.prim_count-1].start *
>                            exec->vtx.vertex_size);
>
> @@ -336,7 +336,7 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec )
>                                    exec->vtx.bufferobj)) {
>            /* buffer allocation worked, now map the buffer */
>            exec->vtx.buffer_map =
> -            (GLfloat *)ctx->Driver.MapBufferRange(ctx,
> +            (gl_constant_value *)ctx->Driver.MapBufferRange(ctx,
>                                                     0, VBO_VERT_BUFFER_SIZE,
>                                                     accessRange,
>                                                     exec->vtx.bufferobj,
> diff --git a/src/mesa/vbo/vbo_exec_eval.c b/src/mesa/vbo/vbo_exec_eval.c
> index 82f89b9..3360511 100644
> --- a/src/mesa/vbo/vbo_exec_eval.c
> +++ b/src/mesa/vbo/vbo_exec_eval.c
> @@ -130,11 +130,11 @@ void vbo_exec_do_EvalCoord1f(struct vbo_exec_context *exec, GLfloat u)
>         struct gl_1d_map *map = exec->eval.map1[attr].map;
>         if (map) {
>   	 GLfloat uu = (u - map->u1) * map->du;
> -	 GLfloat data[4];
> +	 gl_constant_value data[4];
>
> -	 ASSIGN_4V(data, 0, 0, 0, 1);
> +	 ASSIGN_4V(data, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));
>
> -	 _math_horner_bezier_curve(map->Points, data, uu,
> +	 _math_horner_bezier_curve(map->Points, &data[0].f, uu,
>   				   exec->eval.map1[attr].sz,
>   				   map->Order);
>
> @@ -176,12 +176,12 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
>         if (map) {
>   	 GLfloat uu = (u - map->u1) * map->du;
>   	 GLfloat vv = (v - map->v1) * map->dv;
> -	 GLfloat data[4];
> +	 gl_constant_value data[4];
>
> -	 ASSIGN_4V(data, 0, 0, 0, 1);
> +	 ASSIGN_4V(data, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));
>
>   	 _math_horner_bezier_surf(map->Points,
> -				  data,
> +				  &data[0].f,
>   				  uu, vv,
>   				  exec->eval.map2[attr].sz,
>   				  map->Uorder, map->Vorder);
> @@ -203,7 +203,7 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
>         ASSIGN_4V(vertex, 0, 0, 0, 1);
>
>         if (exec->ctx->Eval.AutoNormal) {
> -	 GLfloat normal[4];
> +	 gl_constant_value normal[4];
>            GLfloat du[4], dv[4];
>
>            _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv,
> @@ -221,11 +221,11 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
>   	 }
>
>
> -         CROSS3(normal, du, dv);
> -         NORMALIZE_3FV(normal);
> -	 normal[3] = 1.0;
> +         CROSS3(&normal[0].f, du, dv);
> +         NORMALIZE_3FV(&normal[0].f);
> +	 normal[3] = FLOAT_AS_UNION(1.0);

Indentation looks funny.


>
> -	 COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],
> + 	 COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],
>   		     exec->vtx.attrsz[VBO_ATTRIB_NORMAL],
>   		     normal );
>
> diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h
> index fd26b5f..6d2ad277 100644
> --- a/src/mesa/vbo/vbo_save.h
> +++ b/src/mesa/vbo/vbo_save.h
> @@ -40,7 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>
>
>   struct vbo_save_copied_vtx {
> -   GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
> +   gl_constant_value buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];
>      GLuint nr;
>   };
>
> @@ -107,7 +107,7 @@ struct vbo_save_vertex_list {
>    */
>   struct vbo_save_vertex_store {
>      struct gl_buffer_object *bufferobj;
> -   GLfloat *buffer;
> +   gl_constant_value *buffer;
>      GLuint used;
>      GLuint refcount;
>   };
> @@ -133,7 +133,7 @@ struct vbo_save_context {
>
>      GLboolean out_of_memory;  /**< True if last VBO allocation failed */
>
> -   GLfloat *buffer;
> +   gl_constant_value *buffer;
>      GLuint count;
>      GLuint wrap_count;
>      GLuint replay_flags;
> @@ -144,9 +144,9 @@ struct vbo_save_context {
>      struct vbo_save_vertex_store *vertex_store;
>      struct vbo_save_primitive_store *prim_store;
>
> -   GLfloat *buffer_ptr;		   /* cursor, points into buffer */
> -   GLfloat vertex[VBO_ATTRIB_MAX*4];	   /* current values */
> -   GLfloat *attrptr[VBO_ATTRIB_MAX];
> +   gl_constant_value *buffer_ptr;		   /* cursor, points into buffer */
> +   gl_constant_value vertex[VBO_ATTRIB_MAX*4];	   /* current values */
> +   gl_constant_value *attrptr[VBO_ATTRIB_MAX];
>      GLuint vert_count;
>      GLuint max_vert;
>      GLboolean dangling_attr_ref;
> @@ -155,7 +155,7 @@ struct vbo_save_context {
>
>      struct vbo_save_copied_vtx copied;
>
> -   GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->ListState */
> +   gl_constant_value *current[VBO_ATTRIB_MAX]; /* points into ctx->ListState */
>      GLubyte *currentsz[VBO_ATTRIB_MAX];
>   };
>
> @@ -186,7 +186,7 @@ void vbo_save_playback_vertex_list( struct gl_context *ctx, void *data );
>
>   void vbo_save_api_init( struct vbo_save_context *save );
>
> -GLfloat *
> +gl_constant_value *
>   vbo_save_map_vertex_store(struct gl_context *ctx,
>                             struct vbo_save_vertex_store *vertex_store);
>
> diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
> index beef342..775be51 100644
> --- a/src/mesa/vbo/vbo_save_api.c
> +++ b/src/mesa/vbo/vbo_save_api.c
> @@ -99,14 +99,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>   static GLuint
>   _save_copy_vertices(struct gl_context *ctx,
>                       const struct vbo_save_vertex_list *node,
> -                    const GLfloat * src_buffer)
> +                    const gl_constant_value * src_buffer)
>   {
>      struct vbo_save_context *save = &vbo_context(ctx)->save;
>      const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
>      GLuint nr = prim->count;
>      GLuint sz = save->vertex_size;
> -   const GLfloat *src = src_buffer + prim->start * sz;
> -   GLfloat *dst = save->copied.buffer;
> +   const gl_constant_value *src = src_buffer + prim->start * sz;
> +   gl_constant_value *dst = save->copied.buffer;
>      GLuint ovf, i;
>
>      if (prim->end)
> @@ -233,7 +233,7 @@ free_vertex_store(struct gl_context *ctx,
>   }
>
>
> -GLfloat *
> +gl_constant_value *
>   vbo_save_map_vertex_store(struct gl_context *ctx,
>                             struct vbo_save_vertex_store *vertex_store)
>   {
> @@ -249,7 +249,7 @@ vbo_save_map_vertex_store(struct gl_context *ctx,
>         /* Map the remaining free space in the VBO */
>         GLintptr offset = vertex_store->used * sizeof(GLfloat);
>         GLsizeiptr size = vertex_store->bufferobj->Size - offset;
> -      GLfloat *range = (GLfloat *)
> +      gl_constant_value *range = (gl_constant_value *)
>            ctx->Driver.MapBufferRange(ctx, offset, size, access,
>                                       vertex_store->bufferobj,
>                                       MAP_INTERNAL);
> @@ -549,7 +549,7 @@ static void
>   _save_wrap_filled_vertex(struct gl_context *ctx)
>   {
>      struct vbo_save_context *save = &vbo_context(ctx)->save;
> -   GLfloat *data = save->copied.buffer;
> +   gl_constant_value *data = save->copied.buffer;
>      GLuint i;
>
>      /* Emit a glEnd to close off the last vertex list.
> @@ -578,7 +578,7 @@ _save_copy_to_current(struct gl_context *ctx)
>      for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
>         if (save->attrsz[i]) {
>            save->currentsz[i][0] = save->attrsz[i];
> -         COPY_CLEAN_4V_TYPE_AS_FLOAT(save->current[i], save->attrsz[i],
> +         COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
>                                        save->attrptr[i], save->attrtype[i]);
>         }
>      }
> @@ -620,7 +620,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
>      struct vbo_save_context *save = &vbo_context(ctx)->save;
>      GLuint oldsz;
>      GLuint i;
> -   GLfloat *tmp;
> +   gl_constant_value *tmp;
>
>      /* Store the current run of vertices, and emit a GL_END.  Emit a
>       * BEGIN in the new buffer.
> @@ -669,8 +669,8 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
>       * and will need fixup at runtime.
>       */
>      if (save->copied.nr) {
> -      const GLfloat *data = save->copied.buffer;
> -      GLfloat *dest = save->buffer;
> +      const gl_constant_value *data = save->copied.buffer;
> +      gl_constant_value *dest = save->buffer;
>         GLuint j;
>
>         /* Need to note this and fix up at runtime (or loopback):
> @@ -685,7 +685,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
>               if (save->attrsz[j]) {
>                  if (j == attr) {
>                     if (oldsz) {
> -                     COPY_CLEAN_4V_TYPE_AS_FLOAT(dest, oldsz, data,
> +                     COPY_CLEAN_4V_TYPE_AS_UNION(dest, oldsz, data,
>                                                    save->attrtype[j]);
>                        data += oldsz;
>                        dest += newsz;
> @@ -729,7 +729,7 @@ save_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
>      }
>      else if (sz < save->active_sz[attr]) {
>         GLuint i;
> -      const GLfloat *id = vbo_get_default_vals_as_float(save->attrtype[attr]);
> +      const gl_constant_value *id = vbo_get_default_vals_as_union(save->attrtype[attr]);
>
>         /* New size is equal or smaller - just need to fill in some
>          * zeros.
> @@ -772,7 +772,7 @@ _save_reset_vertex(struct gl_context *ctx)
>    * 3f version won't otherwise set color[3] to 1.0 -- this is the job
>    * of the chooser function when switching between Color4f and Color3f.
>    */
> -#define ATTR(A, N, T, V0, V1, V2, V3)				\
> +#define ATTR_UNION(A, N, T, V0, V1, V2, V3)			\
>   do {								\
>      struct vbo_save_context *save = &vbo_context(ctx)->save;	\
>   								\
> @@ -780,12 +780,12 @@ do {								\
>         save_fixup_vertex(ctx, A, N);				\
>   								\
>      {								\
> -      GLfloat *dest = save->attrptr[A];				\
> +      gl_constant_value *dest = save->attrptr[A];		\
>         if (N>0) dest[0] = V0;					\
>         if (N>1) dest[1] = V1;					\
>         if (N>2) dest[2] = V2;					\
>         if (N>3) dest[3] = V3;					\
> -      save->attrtype[A] = T;                                    \
> +      save->attrtype[A] = T;					\
>      }								\
>   								\
>      if ((A) == 0) {						\
> @@ -1566,14 +1566,14 @@ _save_current_init(struct gl_context *ctx)
>         const GLuint j = i - VBO_ATTRIB_POS;
>         ASSERT(j < VERT_ATTRIB_MAX);
>         save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
> -      save->current[i] = ctx->ListState.CurrentAttrib[j];
> +      save->current[i] = (gl_constant_value*)(ctx->ListState.CurrentAttrib[j]);
>      }
>
>      for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
>         const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
>         ASSERT(j < MAT_ATTRIB_MAX);
>         save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
> -      save->current[i] = ctx->ListState.CurrentMaterial[j];
> +      save->current[i] = (gl_constant_value*)ctx->ListState.CurrentMaterial[j];
>      }
>   }
>
> diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
> index d0521d7..01a0ec5 100644
> --- a/src/mesa/vbo/vbo_save_draw.c
> +++ b/src/mesa/vbo/vbo_save_draw.c
> @@ -76,11 +76,11 @@ _playback_copy_to_current(struct gl_context *ctx,
>      for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
>         if (node->attrsz[i]) {
>   	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
> -         GLfloat tmp[4];
> +         gl_constant_value tmp[4];
>
> -         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
> +         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
>                                        node->attrsz[i],
> -                                     data,
> +                                     (gl_constant_value*)data,
>                                        node->attrtype[i]);
>
>            if (node->attrtype[i] != vbo->currval[i].Type ||
>
> -----Original Message-----

> From: Brian Paul [mailto:brianp@vmware.com]

> Sent: Thursday, February 12, 2015 10:24 PM

> To: Predut, Marius; mesa-dev@lists.freedesktop.org

> Subject: Re: [Mesa-dev] [PATCH v3] Fixing an x86 FPU bug.

> 

> I have a few concerns about this patch.

> 

> Firstly, including prog_parameter.h from macros.h feels wrong.  Macros are a

> lower-level concept than program parameters so the "lower" thing shouldn't be

> including the "higher" thing.

> 

> Instead of using gl_constant_value everywhere, why not use the fi_type which

> is basically the same thing?


if there are no more comments , I will take it in consideration.

> 

> more below...

> 

> 

> On 02/12/2015 11:00 AM, marius.predut@intel.com wrote:

> > From: Marius Predut <marius.predut@intel.com>

> >

> > On 32-bit, for floating point operations is used x86 FPU registers

> > instead SSE, reason for  when reinterprets an integer as a float

> > result is unexpected (modify floats when they are written to memory).

> > The defect was checked with and without -O3 compiler flag

> >

> > This patch is based Neil Roberts review.

> > This patch is more complete - it include changes on all places that are

> storing attribute values to use gl_constant_value.

> > This patch fix 2 piglit tests.

> >

> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82668

> > Signed-off-by: Marius Predut <marius.predut@intel.com>

> > ---

> >   src/mesa/main/context.c       |    3 ++-

> >   src/mesa/main/macros.h        |   41 +++++++++++++++++++++----------------

> ----

> >   src/mesa/vbo/vbo_attrib_tmp.h |   20 ++++++++++++++++----

> >   src/mesa/vbo/vbo_context.h    |   16 ++++++++--------

> >   src/mesa/vbo/vbo_exec.h       |   11 ++++++-----

> >   src/mesa/vbo/vbo_exec_api.c   |   39 +++++++++++++++++++------------------

> --

> >   src/mesa/vbo/vbo_exec_draw.c  |    6 +++---

> >   src/mesa/vbo/vbo_exec_eval.c  |   22 +++++++++++-----------

> >   src/mesa/vbo/vbo_save.h       |   16 ++++++++--------

> >   src/mesa/vbo/vbo_save_api.c   |   34 +++++++++++++++++-----------------

> >   src/mesa/vbo/vbo_save_draw.c  |    6 +++---

> >   11 files changed, 114 insertions(+), 100 deletions(-)

> >

> > diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index

> > 63d30a2..f0597e2 100644

> > --- a/src/mesa/main/context.c

> > +++ b/src/mesa/main/context.c

> > @@ -134,6 +134,7 @@

> >   #include "math/m_matrix.h"

> >   #include "main/dispatch.h" /* for _gloffset_COUNT */

> >   #include "uniforms.h"

> > +#include "macros.h"

> >

> >   #ifdef USE_SPARC_ASM

> >   #include "sparc/sparc.h"

> > @@ -656,7 +657,7 @@ _mesa_init_constants(struct gl_constants *consts, gl_api

> api)

> >      consts->MaxSamples = 0;

> >

> >      /* GLSL default if NativeIntegers == FALSE */

> > -   consts->UniformBooleanTrue = FLT_AS_UINT(1.0f);

> > +   consts->UniformBooleanTrue = FLOAT_AS_UNION(1.0f).u;

> 

> I don't think this has to change if we just keep FLT_AS_UINT().

> 


May be, but in this case not matter  (FLT_AS_UINT was removed)

> 

> >

> >      /* GL_ARB_sync */

> >      consts->MaxServerWaitTimeout = 0x1fff7fffffffULL; diff --git

> > a/src/mesa/main/macros.h b/src/mesa/main/macros.h index

> > cd5f2d6..2af15de 100644

> > --- a/src/mesa/main/macros.h

> > +++ b/src/mesa/main/macros.h

> > @@ -32,6 +32,7 @@

> >   #define MACROS_H

> >

> >   #include "imports.h"

> > +#include "program/prog_parameter.h"

> 

> See above.

> 

> 

> >

> >

> >   /**

> > @@ -170,27 +171,26 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];

> >   	ub = ((GLubyte) F_TO_I((f) * 255.0F))

> >   #endif

> >

> > -static inline GLfloat INT_AS_FLT(GLint i)

> > +static union gl_constant_value UINT_AS_UNION(GLuint u)

> >   {

> > -   fi_type tmp;

> > -   tmp.i = i;

> > -   return tmp.f;

> > +   union gl_constant_value tmp;

> > +   tmp.u = u;

> > +   return tmp;

> >   }

> >

> > -static inline GLfloat UINT_AS_FLT(GLuint u)

> > +static inline union gl_constant_value INT_AS_UNION(GLint i)

> >   {

> > -   fi_type tmp;

> > -   tmp.u = u;

> > -   return tmp.f;

> > +   union gl_constant_value tmp;

> > +   tmp.i = i;

> > +   return tmp;

> >   }

> >

> > -static inline unsigned FLT_AS_UINT(float f)

> > +static inline union gl_constant_value FLOAT_AS_UNION(GLfloat f)

> >   {

> > -   fi_type tmp;

> > +   union gl_constant_value tmp;

> >      tmp.f = f;

> > -   return tmp.u;

> > +   return tmp;

> >   }

> > -

> >   /**

> >    * Convert a floating point value to an unsigned fixed point value.

> >    *

> > @@ -382,6 +382,7 @@ do {                                    \

> >       V[3] = V3;                          \

> >   } while(0)

> >

> > +

> 

> Seems to be a few cases of unrelated whitespace changes.

> 

ok
> 

> >   /*@}*/

> >

> >

> > @@ -620,24 +621,24 @@ do {				\

> >    * The default values are chosen based on \p type.

> >    */

> >   static inline void

> > -COPY_CLEAN_4V_TYPE_AS_FLOAT(GLfloat dst[4], int sz, const GLfloat

> > src[4],

> > +COPY_CLEAN_4V_TYPE_AS_UNION(gl_constant_value dst[4], int sz, const

> > +gl_constant_value src[4],

> >                               GLenum type)

> >   {

> >      switch (type) {

> >      case GL_FLOAT:

> > -      ASSIGN_4V(dst, 0, 0, 0, 1);

> > +      ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0),

> > + FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));

> >         break;

> >      case GL_INT:

> > -      ASSIGN_4V(dst, INT_AS_FLT(0), INT_AS_FLT(0),

> > -                     INT_AS_FLT(0), INT_AS_FLT(1));

> > +      ASSIGN_4V(dst, INT_AS_UNION(0), INT_AS_UNION(0),

> > +                INT_AS_UNION(0), INT_AS_UNION(1));

> >         break;

> >      case GL_UNSIGNED_INT:

> > -      ASSIGN_4V(dst, UINT_AS_FLT(0), UINT_AS_FLT(0),

> > -                     UINT_AS_FLT(0), UINT_AS_FLT(1));

> > +      ASSIGN_4V(dst, UINT_AS_UNION(0), UINT_AS_UNION(0),

> > +                UINT_AS_UNION(0), UINT_AS_UNION(1));

> >         break;

> >      default:

> > -      ASSIGN_4V(dst, 0.0f, 0.0f, 0.0f, 1.0f); /* silence warnings */

> > -      ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_FLOAT macro");

> > +      ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0),

> FLOAT_AS_UNION(0), FLOAT_AS_UNION(1)); /* silence warnings */

> > +      ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_UNION

> > + macro");

> >      }

> >      COPY_SZ_4V(dst, sz, src);

> >   }

> > diff --git a/src/mesa/vbo/vbo_attrib_tmp.h

> > b/src/mesa/vbo/vbo_attrib_tmp.h index ec66934..17a0a10 100644

> > --- a/src/mesa/vbo/vbo_attrib_tmp.h

> > +++ b/src/mesa/vbo/vbo_attrib_tmp.h

> > @@ -28,6 +28,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

> >   #include "util/u_format_r11g11b10f.h"

> >   #include "main/varray.h"

> >

> > +

> > +/* ATTR */

> > +#define ATTR( A, N, T, V0, V1, V2, V3 )	  ATTR_##T((A), (N), (T), (V0),

> (V1), (V2), (V3))

> > +

> > +#define ATTR_GL_UNSIGNED_INT( A, N, T, V0, V1, V2, V3 ) \

> > +    ATTR_UNION(A, N, T, UINT_AS_UNION(V0), UINT_AS_UNION(V1),

> > +UINT_AS_UNION(V2), UINT_AS_UNION(V3))

> 

> Why does 'T' need to be an argument to this macro?  Isn't it always

> GL_UNSIGNED_INT?


No

> 

> 

> > +#define ATTR_GL_INT( A, N, T, V0, V1, V2, V3 ) \

> > +    ATTR_UNION(A, N, T, INT_AS_UNION(V0), INT_AS_UNION(V1),

> INT_AS_UNION(V2), INT_AS_UNION(V3))

> > +#define ATTR_GL_FLOAT( A, N, T, V0, V1, V2, V3 )	\

> > +    ATTR_UNION(A, N, T, FLOAT_AS_UNION(V0), FLOAT_AS_UNION(V1),

> FLOAT_AS_UNION(V2), FLOAT_AS_UNION(V3))

> > +

> > +

> 

> I think there's more macro use here than necessary...

> 


To avoid too many changes in the macros.h I prefer to preserve the initial macros.h design file.
(also the patch is too big for this small defect!)
The initial design is more generic and this let as add easily new functionalists.
Also to change those macros should be action of a new patch.

> 

> >   /* float */

> >   #define ATTR1FV( A, V ) ATTR( A, 1, GL_FLOAT, (V)[0], 0, 0, 1 )

> >   #define ATTR2FV( A, V ) ATTR( A, 2, GL_FLOAT, (V)[0], (V)[1], 0, 1 )

> > @@ -41,8 +53,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

> >

> >   /* int */

> >   #define ATTRI( A, N, X, Y, Z, W) ATTR( A, N, GL_INT, \

> > -                                       INT_AS_FLT(X), INT_AS_FLT(Y), \

> > -                                       INT_AS_FLT(Z), INT_AS_FLT(W) )

> > +                                       X, Y, \

> > +                                       Z, W )

> 

> For example, couldn't this be:

> #define ATTRI( A, N, X, Y, Z, W)  ATTR_GL_INT( A, N, X, Y, Z, W )

> 

> Or even:

> #define ATTRI( A, N, X, Y, Z, W)  ATTR_UNION(A, N, GL_INT,     \

>                                               INT_AS_UNION(V0), \

>                                               INT_AS_UNION(V1), \

>                                               INT_AS_UNION(V2), \

>                                               INT_AS_UNION(V3))

> 

> Then get rid of ATTR().  Or keep it instead of introducing ATTR_UNION().

> 


See below comment.

> 

> >

> >   #define ATTR2IV( A, V ) ATTRI( A, 2, (V)[0], (V)[1], 0, 1 )

> >   #define ATTR3IV( A, V ) ATTRI( A, 3, (V)[0], (V)[1], (V)[2], 1 )

> > @@ -56,8 +68,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

> >

> >   /* uint */

> >   #define ATTRUI( A, N, X, Y, Z, W) ATTR( A, N, GL_UNSIGNED_INT, \

> > -                                        UINT_AS_FLT(X), UINT_AS_FLT(Y), \

> > -                                        UINT_AS_FLT(Z), UINT_AS_FLT(W) )

> > +                                        X, Y, \

> > +                                        Z, W )

> >

> >   #define ATTR2UIV( A, V ) ATTRUI( A, 2, (V)[0], (V)[1], 0, 1 )

> >   #define ATTR3UIV( A, V ) ATTRUI( A, 3, (V)[0], (V)[1], (V)[2], 1 )

> > diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h

> > index e224513..8857ad6 100644

> > --- a/src/mesa/vbo/vbo_context.h

> > +++ b/src/mesa/vbo/vbo_context.h

> > @@ -56,6 +56,7 @@

> >   #include "vbo_exec.h"

> >   #include "vbo_save.h"

> >

> > +#include "main/macros.h"

> >

> >   struct vbo_context {

> >      struct gl_client_array currval[VBO_ATTRIB_MAX];

> > @@ -151,24 +152,23 @@ vbo_attrtype_to_integer_flag(GLenum format)

> >      }

> >   }

> >

> > -

> >   /**

> >    * Return default component values for the given format.

> > - * The return type is an array of floats, because that's how we declare

> > - * the vertex storage despite the fact we sometimes store integers in

> there.

> > + * The return type is an array of gl_constant_values, because that's how we

> declare

> > + * the vertex storage : floats , integers or unsigned integers.

> >    */

> > -static inline const GLfloat *

> > -vbo_get_default_vals_as_float(GLenum format)

> > +static inline const gl_constant_value *

> > +vbo_get_default_vals_as_union(GLenum format)

> >   {

> > -   static const GLfloat default_float[4] = { 0, 0, 0, 1 };

> > -   static const GLint default_int[4] = { 0, 0, 0, 1 };

> > +   static const gl_constant_value default_float[4] = { {.f = 0}, {.f = 0},

> {.f = 0}, {.f = 1} };

> > +   static const gl_constant_value default_int[4]   = { {.i = 0}, {.i = 0},

> {.i = 0}, {.i = 1} };

> 

> I don't recall if this will be accepted by MSVC 2013.  It won't work

> with older versions.


Agree , but we need this back compatibility?


> 

> 

> >

> >      switch (format) {

> >      case GL_FLOAT:

> >         return default_float;

> >      case GL_INT:

> >      case GL_UNSIGNED_INT:

> > -      return (const GLfloat*)default_int;

> > +      return default_int;

> >      default:

> >         ASSERT(0);

> >         return NULL;

> > diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h

> > index bb265de..1020afe 100644

> > --- a/src/mesa/vbo/vbo_exec.h

> > +++ b/src/mesa/vbo/vbo_exec.h

> > @@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

> >   #include "vbo.h"

> >   #include "vbo_attrib.h"

> >

> > +#include "program/prog_parameter.h"

> >

> >   /**

> >    * Max number of primitives (number of glBegin/End pairs) per VBO.

> > @@ -71,7 +72,7 @@ struct vbo_exec_eval2_map {

> >

> >

> >   struct vbo_exec_copied_vtx {

> > -   GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];

> > +   gl_constant_value buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];

> >      GLuint nr;

> >   };

> >

> > @@ -91,10 +92,10 @@ struct vbo_exec_context

> >         struct _mesa_prim prim[VBO_MAX_PRIM];

> >         GLuint prim_count;

> >

> > -      GLfloat *buffer_map;

> > -      GLfloat *buffer_ptr;              /* cursor, points into buffer */

> > +      gl_constant_value *buffer_map;

> > +      gl_constant_value *buffer_ptr;              /* cursor, points into

> buffer */

> >         GLuint   buffer_used;             /* in bytes */

> > -      GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */

> > +      gl_constant_value vertex[VBO_ATTRIB_MAX*4]; /* current vertex */

> >

> >         GLuint vert_count;

> >         GLuint max_vert;

> > @@ -104,7 +105,7 @@ struct vbo_exec_context

> >         GLenum attrtype[VBO_ATTRIB_MAX];

> >         GLubyte active_sz[VBO_ATTRIB_MAX];

> >

> > -      GLfloat *attrptr[VBO_ATTRIB_MAX];

> > +      gl_constant_value *attrptr[VBO_ATTRIB_MAX];

> >         struct gl_client_array arrays[VERT_ATTRIB_MAX];

> >

> >         /* According to program mode, the values above plus current

> > diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c

> > index 5f8250e..1dfc6a4 100644

> > --- a/src/mesa/vbo/vbo_exec_api.c

> > +++ b/src/mesa/vbo/vbo_exec_api.c

> > @@ -46,7 +46,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

> >   #include "vbo_context.h"

> >   #include "vbo_noop.h"

> >

> > -

> >   #ifdef ERROR

> >   #undef ERROR

> >   #endif

> > @@ -115,7 +114,7 @@ static void vbo_exec_wrap_buffers( struct

> vbo_exec_context *exec )

> >    */

> >   void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )

> >   {

> > -   GLfloat *data = exec->vtx.copied.buffer;

> > +   gl_constant_value *data = exec->vtx.copied.buffer;

> >      GLuint i;

> >

> >      /* Run pipeline on current vertices, copy wrapped vertices

> > @@ -158,10 +157,10 @@ static void vbo_exec_copy_to_current( struct

> vbo_exec_context *exec )

> >            /* Note: the exec->vtx.current[i] pointers point into the

> >             * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.

> >             */

> > -	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;

> > -         GLfloat tmp[4];

> > +	 gl_constant_value *current = (gl_constant_value *)vbo->currval[i].Ptr;

> > +         gl_constant_value tmp[4];

> >

> > -         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,

> > +         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,

> >                                        exec->vtx.attrsz[i],

> >                                        exec->vtx.attrptr[i],

> >                                        exec->vtx.attrtype[i]);

> > @@ -214,7 +213,7 @@ vbo_exec_copy_from_current(struct vbo_exec_context

> *exec)

> >      GLint i;

> >

> >      for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {

> > -      const GLfloat *current = (GLfloat *) vbo->currval[i].Ptr;

> > +      const gl_constant_value *current = (gl_constant_value *) vbo-

> >currval[i].Ptr;

> >         switch (exec->vtx.attrsz[i]) {

> >         case 4: exec->vtx.attrptr[i][3] = current[3];

> >         case 3: exec->vtx.attrptr[i][2] = current[2];

> > @@ -240,7 +239,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context

> *exec,

> >      struct gl_context *ctx = exec->ctx;

> >      struct vbo_context *vbo = vbo_context(ctx);

> >      const GLint lastcount = exec->vtx.vert_count;

> > -   GLfloat *old_attrptr[VBO_ATTRIB_MAX];

> > +   gl_constant_value *old_attrptr[VBO_ATTRIB_MAX];

> >      const GLuint old_vtx_size = exec->vtx.vertex_size; /* floats per vertex

> */

> >      const GLuint oldSize = exec->vtx.attrsz[attr];

> >      GLuint i;

> > @@ -287,7 +286,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context

> *exec,

> >      if (unlikely(oldSize)) {

> >         /* Size changed, recalculate all the attrptr[] values

> >          */

> > -      GLfloat *tmp = exec->vtx.vertex;

> > +      gl_constant_value *tmp = exec->vtx.vertex;

> >

> >         for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {

> >   	 if (exec->vtx.attrsz[i]) {

> > @@ -306,7 +305,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context

> *exec,

> >      else {

> >         /* Just have to append the new attribute at the end */

> >         exec->vtx.attrptr[attr] = exec->vtx.vertex +

> > -	 exec->vtx.vertex_size - newSize;

> > +        exec->vtx.vertex_size - newSize;

> >      }

> >

> >      /* Replay stored vertices to translate them

> > @@ -315,8 +314,8 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context

> *exec,

> >       * -- No need to replay - just copy piecewise

> >       */

> >      if (unlikely(exec->vtx.copied.nr)) {

> > -      GLfloat *data = exec->vtx.copied.buffer;

> > -      GLfloat *dest = exec->vtx.buffer_ptr;

> > +      gl_constant_value *data = exec->vtx.copied.buffer;

> > +      gl_constant_value *dest = exec->vtx.buffer_ptr;

> >         GLuint j;

> >

> >         assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);

> > @@ -331,13 +330,13 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context

> *exec,

> >

> >   	       if (j == attr) {

> >   		  if (oldSize) {

> > -		     GLfloat tmp[4];

> > -                     COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp, oldSize,

> > +		     gl_constant_value tmp[4];

> > +		     COPY_CLEAN_4V_TYPE_AS_UNION(tmp, oldSize,

> >                                                    data + old_offset,

> >                                                    exec->vtx.attrtype[j]);

> >   		     COPY_SZ_4V(dest + new_offset, newSize, tmp);

> >   		  } else {

> > -		     GLfloat *current = (GLfloat *)vbo->currval[j].Ptr;

> > +		     gl_constant_value *current = (gl_constant_value *)vbo-

> >currval[j].Ptr;

> >   		     COPY_SZ_4V(dest + new_offset, sz, current);

> >   		  }

> >   	       }

> > @@ -376,14 +375,14 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint

> attr, GLuint newSize)

> >      }

> >      else if (newSize < exec->vtx.active_sz[attr]) {

> >         GLuint i;

> > -      const GLfloat *id =

> > -            vbo_get_default_vals_as_float(exec->vtx.attrtype[attr]);

> > +      const gl_constant_value *id =

> > +            vbo_get_default_vals_as_union(exec->vtx.attrtype[attr]);

> >

> >         /* New size is smaller - just need to fill in some

> >          * zeros.  Don't need to flush or wrap.

> >          */

> >         for (i = newSize; i <= exec->vtx.attrsz[attr]; i++)

> > -	 exec->vtx.attrptr[attr][i-1] = id[i-1];

> > +        exec->vtx.attrptr[attr][i-1] = id[i-1];

> >      }

> >

> >      exec->vtx.active_sz[attr] = newSize;

> > @@ -401,7 +400,7 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint

> attr, GLuint newSize)

> >    * This macro is used to implement all the glVertex, glColor, glTexCoord,

> >    * glVertexAttrib, etc functions.

> >    */

> > -#define ATTR( A, N, T, V0, V1, V2, V3 )					\

> > +#define ATTR_UNION( A, N, T, V0, V1, V2, V3 )				\

> >   do {									\

> >      struct vbo_exec_context *exec = &vbo_context(ctx)->exec;		\

> >   									\

> > @@ -412,12 +411,12 @@ do {

> 		\

> >         vbo_exec_fixup_vertex(ctx, A, N);					\

> >      									\

> >      {									\

> > -      GLfloat *dest = exec->vtx.attrptr[A];				\

> > +      gl_constant_value *dest = exec->vtx.attrptr[A];			\

> >         if (N>0) dest[0] = V0;						\

> >         if (N>1) dest[1] = V1;						\

> >         if (N>2) dest[2] = V2;						\

> >         if (N>3) dest[3] = V3;						\

> > -      exec->vtx.attrtype[A] = T;                                        \

> > +      exec->vtx.attrtype[A] = T;					\

> >      }									\

> >   									\

> >      if ((A) == 0) {							\

> > diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c

> > index 362cc10..47072f1 100644

> > --- a/src/mesa/vbo/vbo_exec_draw.c

> > +++ b/src/mesa/vbo/vbo_exec_draw.c

> > @@ -73,8 +73,8 @@ vbo_copy_vertices( struct vbo_exec_context *exec )

> >      GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count;

> >      GLuint ovf, i;

> >      GLuint sz = exec->vtx.vertex_size;

> > -   GLfloat *dst = exec->vtx.copied.buffer;

> > -   const GLfloat *src = (exec->vtx.buffer_map +

> > +   gl_constant_value *dst = exec->vtx.copied.buffer;

> > +   const gl_constant_value *src = (exec->vtx.buffer_map +

> >                            exec->vtx.prim[exec->vtx.prim_count-1].start *

> >                            exec->vtx.vertex_size);

> >

> > @@ -336,7 +336,7 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec )

> >                                    exec->vtx.bufferobj)) {

> >            /* buffer allocation worked, now map the buffer */

> >            exec->vtx.buffer_map =

> > -            (GLfloat *)ctx->Driver.MapBufferRange(ctx,

> > +            (gl_constant_value *)ctx->Driver.MapBufferRange(ctx,

> >                                                     0, VBO_VERT_BUFFER_SIZE,

> >                                                     accessRange,

> >                                                     exec->vtx.bufferobj,

> > diff --git a/src/mesa/vbo/vbo_exec_eval.c b/src/mesa/vbo/vbo_exec_eval.c

> > index 82f89b9..3360511 100644

> > --- a/src/mesa/vbo/vbo_exec_eval.c

> > +++ b/src/mesa/vbo/vbo_exec_eval.c

> > @@ -130,11 +130,11 @@ void vbo_exec_do_EvalCoord1f(struct vbo_exec_context

> *exec, GLfloat u)

> >         struct gl_1d_map *map = exec->eval.map1[attr].map;

> >         if (map) {

> >   	 GLfloat uu = (u - map->u1) * map->du;

> > -	 GLfloat data[4];

> > +	 gl_constant_value data[4];

> >

> > -	 ASSIGN_4V(data, 0, 0, 0, 1);

> > +	 ASSIGN_4V(data, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0),

> FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));

> >

> > -	 _math_horner_bezier_curve(map->Points, data, uu,

> > +	 _math_horner_bezier_curve(map->Points, &data[0].f, uu,

> >   				   exec->eval.map1[attr].sz,

> >   				   map->Order);

> >

> > @@ -176,12 +176,12 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context

> *exec,

> >         if (map) {

> >   	 GLfloat uu = (u - map->u1) * map->du;

> >   	 GLfloat vv = (v - map->v1) * map->dv;

> > -	 GLfloat data[4];

> > +	 gl_constant_value data[4];

> >

> > -	 ASSIGN_4V(data, 0, 0, 0, 1);

> > +	 ASSIGN_4V(data, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0),

> FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));

> >

> >   	 _math_horner_bezier_surf(map->Points,

> > -				  data,

> > +				  &data[0].f,

> >   				  uu, vv,

> >   				  exec->eval.map2[attr].sz,

> >   				  map->Uorder, map->Vorder);

> > @@ -203,7 +203,7 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context

> *exec,

> >         ASSIGN_4V(vertex, 0, 0, 0, 1);

> >

> >         if (exec->ctx->Eval.AutoNormal) {

> > -	 GLfloat normal[4];

> > +	 gl_constant_value normal[4];

> >            GLfloat du[4], dv[4];

> >

> >            _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv,

> > @@ -221,11 +221,11 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context

> *exec,

> >   	 }

> >

> >

> > -         CROSS3(normal, du, dv);

> > -         NORMALIZE_3FV(normal);

> > -	 normal[3] = 1.0;

> > +         CROSS3(&normal[0].f, du, dv);

> > +         NORMALIZE_3FV(&normal[0].f);

> > +	 normal[3] = FLOAT_AS_UNION(1.0);

> 

> Indentation looks funny.


Uniform things.

> 

> 

> >

> > -	 COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],

> > + 	 COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],

> >   		     exec->vtx.attrsz[VBO_ATTRIB_NORMAL],

> >   		     normal );

> >

> > diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h

> > index fd26b5f..6d2ad277 100644

> > --- a/src/mesa/vbo/vbo_save.h

> > +++ b/src/mesa/vbo/vbo_save.h

> > @@ -40,7 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

> >

> >

> >   struct vbo_save_copied_vtx {

> > -   GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];

> > +   gl_constant_value buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS];

> >      GLuint nr;

> >   };

> >

> > @@ -107,7 +107,7 @@ struct vbo_save_vertex_list {

> >    */

> >   struct vbo_save_vertex_store {

> >      struct gl_buffer_object *bufferobj;

> > -   GLfloat *buffer;

> > +   gl_constant_value *buffer;

> >      GLuint used;

> >      GLuint refcount;

> >   };

> > @@ -133,7 +133,7 @@ struct vbo_save_context {

> >

> >      GLboolean out_of_memory;  /**< True if last VBO allocation failed */

> >

> > -   GLfloat *buffer;

> > +   gl_constant_value *buffer;

> >      GLuint count;

> >      GLuint wrap_count;

> >      GLuint replay_flags;

> > @@ -144,9 +144,9 @@ struct vbo_save_context {

> >      struct vbo_save_vertex_store *vertex_store;

> >      struct vbo_save_primitive_store *prim_store;

> >

> > -   GLfloat *buffer_ptr;		   /* cursor, points into buffer */

> > -   GLfloat vertex[VBO_ATTRIB_MAX*4];	   /* current values */

> > -   GLfloat *attrptr[VBO_ATTRIB_MAX];

> > +   gl_constant_value *buffer_ptr;		   /* cursor, points into buffer

> */

> > +   gl_constant_value vertex[VBO_ATTRIB_MAX*4];	   /* current values */

> > +   gl_constant_value *attrptr[VBO_ATTRIB_MAX];

> >      GLuint vert_count;

> >      GLuint max_vert;

> >      GLboolean dangling_attr_ref;

> > @@ -155,7 +155,7 @@ struct vbo_save_context {

> >

> >      struct vbo_save_copied_vtx copied;

> >

> > -   GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->ListState */

> > +   gl_constant_value *current[VBO_ATTRIB_MAX]; /* points into ctx-

> >ListState */

> >      GLubyte *currentsz[VBO_ATTRIB_MAX];

> >   };

> >

> > @@ -186,7 +186,7 @@ void vbo_save_playback_vertex_list( struct gl_context

> *ctx, void *data );

> >

> >   void vbo_save_api_init( struct vbo_save_context *save );

> >

> > -GLfloat *

> > +gl_constant_value *

> >   vbo_save_map_vertex_store(struct gl_context *ctx,

> >                             struct vbo_save_vertex_store *vertex_store);

> >

> > diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c

> > index beef342..775be51 100644

> > --- a/src/mesa/vbo/vbo_save_api.c

> > +++ b/src/mesa/vbo/vbo_save_api.c

> > @@ -99,14 +99,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

> >   static GLuint

> >   _save_copy_vertices(struct gl_context *ctx,

> >                       const struct vbo_save_vertex_list *node,

> > -                    const GLfloat * src_buffer)

> > +                    const gl_constant_value * src_buffer)

> >   {

> >      struct vbo_save_context *save = &vbo_context(ctx)->save;

> >      const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];

> >      GLuint nr = prim->count;

> >      GLuint sz = save->vertex_size;

> > -   const GLfloat *src = src_buffer + prim->start * sz;

> > -   GLfloat *dst = save->copied.buffer;

> > +   const gl_constant_value *src = src_buffer + prim->start * sz;

> > +   gl_constant_value *dst = save->copied.buffer;

> >      GLuint ovf, i;

> >

> >      if (prim->end)

> > @@ -233,7 +233,7 @@ free_vertex_store(struct gl_context *ctx,

> >   }

> >

> >

> > -GLfloat *

> > +gl_constant_value *

> >   vbo_save_map_vertex_store(struct gl_context *ctx,

> >                             struct vbo_save_vertex_store *vertex_store)

> >   {

> > @@ -249,7 +249,7 @@ vbo_save_map_vertex_store(struct gl_context *ctx,

> >         /* Map the remaining free space in the VBO */

> >         GLintptr offset = vertex_store->used * sizeof(GLfloat);

> >         GLsizeiptr size = vertex_store->bufferobj->Size - offset;

> > -      GLfloat *range = (GLfloat *)

> > +      gl_constant_value *range = (gl_constant_value *)

> >            ctx->Driver.MapBufferRange(ctx, offset, size, access,

> >                                       vertex_store->bufferobj,

> >                                       MAP_INTERNAL);

> > @@ -549,7 +549,7 @@ static void

> >   _save_wrap_filled_vertex(struct gl_context *ctx)

> >   {

> >      struct vbo_save_context *save = &vbo_context(ctx)->save;

> > -   GLfloat *data = save->copied.buffer;

> > +   gl_constant_value *data = save->copied.buffer;

> >      GLuint i;

> >

> >      /* Emit a glEnd to close off the last vertex list.

> > @@ -578,7 +578,7 @@ _save_copy_to_current(struct gl_context *ctx)

> >      for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {

> >         if (save->attrsz[i]) {

> >            save->currentsz[i][0] = save->attrsz[i];

> > -         COPY_CLEAN_4V_TYPE_AS_FLOAT(save->current[i], save->attrsz[i],

> > +         COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],

> >                                        save->attrptr[i], save->attrtype[i]);

> >         }

> >      }

> > @@ -620,7 +620,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint

> attr, GLuint newsz)

> >      struct vbo_save_context *save = &vbo_context(ctx)->save;

> >      GLuint oldsz;

> >      GLuint i;

> > -   GLfloat *tmp;

> > +   gl_constant_value *tmp;

> >

> >      /* Store the current run of vertices, and emit a GL_END.  Emit a

> >       * BEGIN in the new buffer.

> > @@ -669,8 +669,8 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint

> attr, GLuint newsz)

> >       * and will need fixup at runtime.

> >       */

> >      if (save->copied.nr) {

> > -      const GLfloat *data = save->copied.buffer;

> > -      GLfloat *dest = save->buffer;

> > +      const gl_constant_value *data = save->copied.buffer;

> > +      gl_constant_value *dest = save->buffer;

> >         GLuint j;

> >

> >         /* Need to note this and fix up at runtime (or loopback):

> > @@ -685,7 +685,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint

> attr, GLuint newsz)

> >               if (save->attrsz[j]) {

> >                  if (j == attr) {

> >                     if (oldsz) {

> > -                     COPY_CLEAN_4V_TYPE_AS_FLOAT(dest, oldsz, data,

> > +                     COPY_CLEAN_4V_TYPE_AS_UNION(dest, oldsz, data,

> >                                                    save->attrtype[j]);

> >                        data += oldsz;

> >                        dest += newsz;

> > @@ -729,7 +729,7 @@ save_fixup_vertex(struct gl_context *ctx, GLuint attr,

> GLuint sz)

> >      }

> >      else if (sz < save->active_sz[attr]) {

> >         GLuint i;

> > -      const GLfloat *id = vbo_get_default_vals_as_float(save-

> >attrtype[attr]);

> > +      const gl_constant_value *id = vbo_get_default_vals_as_union(save-

> >attrtype[attr]);

> >

> >         /* New size is equal or smaller - just need to fill in some

> >          * zeros.

> > @@ -772,7 +772,7 @@ _save_reset_vertex(struct gl_context *ctx)

> >    * 3f version won't otherwise set color[3] to 1.0 -- this is the job

> >    * of the chooser function when switching between Color4f and Color3f.

> >    */

> > -#define ATTR(A, N, T, V0, V1, V2, V3)				\

> > +#define ATTR_UNION(A, N, T, V0, V1, V2, V3)			\

> >   do {								\

> >      struct vbo_save_context *save = &vbo_context(ctx)->save;	\

> >   								\

> > @@ -780,12 +780,12 @@ do {

> 	\

> >         save_fixup_vertex(ctx, A, N);				\

> >   								\

> >      {								\

> > -      GLfloat *dest = save->attrptr[A];				\

> > +      gl_constant_value *dest = save->attrptr[A];		\

> >         if (N>0) dest[0] = V0;					\

> >         if (N>1) dest[1] = V1;					\

> >         if (N>2) dest[2] = V2;					\

> >         if (N>3) dest[3] = V3;					\

> > -      save->attrtype[A] = T;                                    \

> > +      save->attrtype[A] = T;					\

> >      }								\

> >   								\

> >      if ((A) == 0) {						\

> > @@ -1566,14 +1566,14 @@ _save_current_init(struct gl_context *ctx)

> >         const GLuint j = i - VBO_ATTRIB_POS;

> >         ASSERT(j < VERT_ATTRIB_MAX);

> >         save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];

> > -      save->current[i] = ctx->ListState.CurrentAttrib[j];

> > +      save->current[i] = (gl_constant_value*)(ctx-

> >ListState.CurrentAttrib[j]);

> >      }

> >

> >      for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++)

> {

> >         const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;

> >         ASSERT(j < MAT_ATTRIB_MAX);

> >         save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];

> > -      save->current[i] = ctx->ListState.CurrentMaterial[j];

> > +      save->current[i] = (gl_constant_value*)ctx-

> >ListState.CurrentMaterial[j];

> >      }

> >   }

> >

> > diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c

> > index d0521d7..01a0ec5 100644

> > --- a/src/mesa/vbo/vbo_save_draw.c

> > +++ b/src/mesa/vbo/vbo_save_draw.c

> > @@ -76,11 +76,11 @@ _playback_copy_to_current(struct gl_context *ctx,

> >      for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {

> >         if (node->attrsz[i]) {

> >   	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;

> > -         GLfloat tmp[4];

> > +         gl_constant_value tmp[4];

> >

> > -         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,

> > +         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,

> >                                        node->attrsz[i],

> > -                                     data,

> > +                                     (gl_constant_value*)data,

> >                                        node->attrtype[i]);

> >

> >            if (node->attrtype[i] != vbo->currval[i].Type ||

> >