vbo: fix glVertexAttribI* functions
authorMarek Olšák <maraeo@gmail.com>
Tue, 30 Oct 2012 13:44:22 +0000 (14:44 +0100)
committerMarek Olšák <maraeo@gmail.com>
Tue, 6 Nov 2012 00:13:48 +0000 (01:13 +0100)
The functions were broken, because they converted ints to floats.
Now we can finally advertise OpenGL 3.0. ;)

In this commit, the vbo module also tracks the type for each attrib
in addition to the size. It can be one of FLOAT, INT, UNSIGNED_INT.

The little ugliness is the vertex attribs are declared as floats even though
there may be integer values. The code just copies integer values into them
without any conversion.

This implementation passes the glVertexAttribI piglit test which I am going
to commit in piglit soon. The test covers vertex arrays, immediate mode and
display lists.

NOTE: This is a candidate for the stable branches.

Reviewed-by: Brian Paul <brianp@vmware.com>
v2: cosmetic changes as suggested by Brian

docs/GL3.txt
src/mesa/main/imports.h
src/mesa/main/macros.h
src/mesa/vbo/vbo_attrib_tmp.h
src/mesa/vbo/vbo_context.h
src/mesa/vbo/vbo_exec.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_draw.c
src/mesa/vbo/vbo_save.h
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_save_draw.c

index 4f44764c2c58a631f997e643290fd91c00a1f8dc..28f6ae603aebaf6b30770903ad4743c5e90f7235 100644 (file)
@@ -34,8 +34,7 @@ sRGB framebuffer format (GL_EXT_framebuffer_sRGB)     DONE (i965, r600)
 glClearBuffer commands                                DONE
 glGetStringi command                                  DONE
 glTexParameterI, glGetTexParameterI commands          DONE
-glVertexAttribI commands                              ~50% done (converts int
-                                                                 values to floats)
+glVertexAttribI commands                              DONE
 Depth format cube textures                            DONE
 GLX_ARB_create_context (GLX 1.4 is required)          DONE
 
index a78d67966f890de867348fabc985d48c437b0b07..40ba75785fc4095390ce8fce8254ca0acffd4335 100644 (file)
@@ -81,7 +81,7 @@ extern "C" {
  * these casts generate warnings.
  * The following union typedef is used to solve that.
  */
-typedef union { GLfloat f; GLint i; } fi_type;
+typedef union { GLfloat f; GLint i; GLuint u; } fi_type;
 
 
 
index 7b7fd1b6d760f04691b5345ab0315676cd4d8780..14a5d5fe16efbc09e9763ba5a148e5d4b05a6db4 100644 (file)
@@ -171,6 +171,20 @@ 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)
+{
+   fi_type tmp;
+   tmp.i = i;
+   return tmp.f;
+}
+
+static inline GLfloat UINT_AS_FLT(GLuint u)
+{
+   fi_type tmp;
+   tmp.u = u;
+   return tmp.f;
+}
+
 /*@}*/
 
 
@@ -573,6 +587,31 @@ do {                               \
 
 /*@}*/
 
+/** Copy \p sz elements into a homegeneous (4-element) vector, giving
+ * default values to the remaining components.
+ * 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],
+                            GLenum type)
+{
+   switch (type) {
+   case GL_FLOAT:
+      ASSIGN_4V(dst, 0, 0, 0, 1);
+      break;
+   case GL_INT:
+      ASSIGN_4V(dst, INT_AS_FLT(0), INT_AS_FLT(0),
+                     INT_AS_FLT(0), INT_AS_FLT(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));
+      break;
+   default:
+      ASSERT(0);
+   }
+   COPY_SZ_4V(dst, sz, src);
+}
 
 /** \name Linear interpolation functions */
 /*@{*/
index 884844535708a453d964ae990c6256bd7bba4319..6bc53bab3d2f5d1ae7e8c9012c67d582c1784db0 100644 (file)
@@ -26,38 +26,46 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 **************************************************************************/
 
 /* float */
-#define ATTR1FV( A, V ) ATTR( A, 1, (V)[0], 0, 0, 1 )
-#define ATTR2FV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 )
-#define ATTR3FV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 )
-#define ATTR4FV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
+#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 )
+#define ATTR3FV( A, V ) ATTR( A, 3, GL_FLOAT, (V)[0], (V)[1], (V)[2], 1 )
+#define ATTR4FV( A, V ) ATTR( A, 4, GL_FLOAT, (V)[0], (V)[1], (V)[2], (V)[3] )
 
-#define ATTR1F( A, X )          ATTR( A, 1, X, 0, 0, 1 )
-#define ATTR2F( A, X, Y )       ATTR( A, 2, X, Y, 0, 1 )
-#define ATTR3F( A, X, Y, Z )    ATTR( A, 3, X, Y, Z, 1 )
-#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W )
+#define ATTR1F( A, X )          ATTR( A, 1, GL_FLOAT, X, 0, 0, 1 )
+#define ATTR2F( A, X, Y )       ATTR( A, 2, GL_FLOAT, X, Y, 0, 1 )
+#define ATTR3F( A, X, Y, Z )    ATTR( A, 3, GL_FLOAT, X, Y, Z, 1 )
+#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, GL_FLOAT, X, Y, Z, W )
 
 /* int */
-#define ATTR2IV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 )
-#define ATTR3IV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 )
-#define ATTR4IV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
+#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) )
 
-#define ATTR1I( A, X )          ATTR( A, 1, X, 0, 0, 1 )
-#define ATTR2I( A, X, Y )       ATTR( A, 2, X, Y, 0, 1 )
-#define ATTR3I( A, X, Y, Z )    ATTR( A, 3, X, Y, Z, 1 )
-#define ATTR4I( A, X, Y, Z, W ) ATTR( A, 4, 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 )
+#define ATTR4IV( A, V ) ATTRI( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
+
+#define ATTR1I( A, X )          ATTRI( A, 1, X, 0, 0, 1 )
+#define ATTR2I( A, X, Y )       ATTRI( A, 2, X, Y, 0, 1 )
+#define ATTR3I( A, X, Y, Z )    ATTRI( A, 3, X, Y, Z, 1 )
+#define ATTR4I( A, X, Y, Z, W ) ATTRI( A, 4, X, Y, Z, W )
 
 
 /* uint */
-#define ATTR2UIV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 )
-#define ATTR3UIV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 )
-#define ATTR4UIV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
+#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) )
+
+#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 )
+#define ATTR4UIV( A, V ) ATTRUI( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
 
-#define ATTR1UI( A, X )          ATTR( A, 1, X, 0, 0, 1 )
-#define ATTR2UI( A, X, Y )       ATTR( A, 2, X, Y, 0, 1 )
-#define ATTR3UI( A, X, Y, Z )    ATTR( A, 3, X, Y, Z, 1 )
-#define ATTR4UI( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W )
+#define ATTR1UI( A, X )          ATTRUI( A, 1, X, 0, 0, 1 )
+#define ATTR2UI( A, X, Y )       ATTRUI( A, 2, X, Y, 0, 1 )
+#define ATTR3UI( A, X, Y, Z )    ATTRUI( A, 3, X, Y, Z, 1 )
+#define ATTR4UI( A, X, Y, Z, W ) ATTRUI( A, 4, X, Y, Z, W )
 
-#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] )
+#define MAT_ATTR( A, N, V ) ATTR( A, N, GL_FLOAT, (V)[0], (V)[1], (V)[2], (V)[3] )
 
 static inline float conv_ui10_to_norm_float(unsigned ui10)
 {
@@ -69,20 +77,20 @@ static inline float conv_ui2_to_norm_float(unsigned ui2)
    return ui2 / 3.0f;
 }
 
-#define ATTRUI10_1( A, UI ) ATTR( A, 1, (UI) & 0x3ff, 0, 0, 1 )
-#define ATTRUI10_2( A, UI ) ATTR( A, 2, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, 0, 1 )
-#define ATTRUI10_3( A, UI ) ATTR( A, 3, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, 1 )
-#define ATTRUI10_4( A, UI ) ATTR( A, 4, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, ((UI) >> 30) & 0x3 )
+#define ATTRUI10_1( A, UI ) ATTR( A, 1, GL_FLOAT, (UI) & 0x3ff, 0, 0, 1 )
+#define ATTRUI10_2( A, UI ) ATTR( A, 2, GL_FLOAT, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, 0, 1 )
+#define ATTRUI10_3( A, UI ) ATTR( A, 3, GL_FLOAT, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, 1 )
+#define ATTRUI10_4( A, UI ) ATTR( A, 4, GL_FLOAT, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, ((UI) >> 30) & 0x3 )
 
-#define ATTRUI10N_1( A, UI ) ATTR( A, 1, conv_ui10_to_norm_float((UI) & 0x3ff), 0, 0, 1 )
-#define ATTRUI10N_2( A, UI ) ATTR( A, 2, \
+#define ATTRUI10N_1( A, UI ) ATTR( A, 1, GL_FLOAT, conv_ui10_to_norm_float((UI) & 0x3ff), 0, 0, 1 )
+#define ATTRUI10N_2( A, UI ) ATTR( A, 2, GL_FLOAT, \
                                   conv_ui10_to_norm_float((UI) & 0x3ff), \
                                   conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), 0, 1 )
-#define ATTRUI10N_3( A, UI ) ATTR( A, 3, \
+#define ATTRUI10N_3( A, UI ) ATTR( A, 3, GL_FLOAT, \
                                   conv_ui10_to_norm_float((UI) & 0x3ff), \
                                   conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), \
                                   conv_ui10_to_norm_float(((UI) >> 20) & 0x3ff), 1 )
-#define ATTRUI10N_4( A, UI ) ATTR( A, 4, \
+#define ATTRUI10N_4( A, UI ) ATTR( A, 4, GL_FLOAT, \
                                   conv_ui10_to_norm_float((UI) & 0x3ff), \
                                   conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), \
                                   conv_ui10_to_norm_float(((UI) >> 20) & 0x3ff), \
@@ -119,30 +127,30 @@ static inline float conv_i2_to_norm_float(int i2)
    return (float)val.x;
 }
 
-#define ATTRI10_1( A, I10 ) ATTR( A, 1, conv_i10_to_i((I10) & 0x3ff), 0, 0, 1 )
-#define ATTRI10_2( A, I10 ) ATTR( A, 2, \
+#define ATTRI10_1( A, I10 ) ATTR( A, 1, GL_FLOAT, conv_i10_to_i((I10) & 0x3ff), 0, 0, 1 )
+#define ATTRI10_2( A, I10 ) ATTR( A, 2, GL_FLOAT, \
                                conv_i10_to_i((I10) & 0x3ff),           \
                                conv_i10_to_i(((I10) >> 10) & 0x3ff), 0, 1 )
-#define ATTRI10_3( A, I10 ) ATTR( A, 3, \
+#define ATTRI10_3( A, I10 ) ATTR( A, 3, GL_FLOAT, \
                                conv_i10_to_i((I10) & 0x3ff),       \
                                conv_i10_to_i(((I10) >> 10) & 0x3ff), \
                                conv_i10_to_i(((I10) >> 20) & 0x3ff), 1 )
-#define ATTRI10_4( A, I10 ) ATTR( A, 4, \
+#define ATTRI10_4( A, I10 ) ATTR( A, 4, GL_FLOAT, \
                                conv_i10_to_i((I10) & 0x3ff),           \
                                conv_i10_to_i(((I10) >> 10) & 0x3ff), \
                                conv_i10_to_i(((I10) >> 20) & 0x3ff), \
                                conv_i2_to_i(((I10) >> 30) & 0x3))
 
 
-#define ATTRI10N_1( A, I10 ) ATTR( A, 1, conv_i10_to_norm_float((I10) & 0x3ff), 0, 0, 1 )
-#define ATTRI10N_2( A, I10 ) ATTR( A, 2, \
+#define ATTRI10N_1( A, I10 ) ATTR( A, 1, GL_FLOAT, conv_i10_to_norm_float((I10) & 0x3ff), 0, 0, 1 )
+#define ATTRI10N_2( A, I10 ) ATTR( A, 2, GL_FLOAT, \
                                conv_i10_to_norm_float((I10) & 0x3ff),          \
                                conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), 0, 1 )
-#define ATTRI10N_3( A, I10 ) ATTR( A, 3, \
+#define ATTRI10N_3( A, I10 ) ATTR( A, 3, GL_FLOAT, \
                                conv_i10_to_norm_float((I10) & 0x3ff),      \
                                conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), \
                                conv_i10_to_norm_float(((I10) >> 20) & 0x3ff), 1 )
-#define ATTRI10N_4( A, I10 ) ATTR( A, 4, \
+#define ATTRI10N_4( A, I10 ) ATTR( A, 4, GL_FLOAT, \
                                conv_i10_to_norm_float((I10) & 0x3ff),          \
                                conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), \
                                conv_i10_to_norm_float(((I10) >> 20) & 0x3ff), \
index c896f1196f79099d785ac8032606e39190bc3874..1ff6ec0004eb382c7dd7a24884de1cd0958adfde 100644 (file)
@@ -147,4 +147,47 @@ vbo_draw_method(struct vbo_context *vbo, enum draw_method method)
    }
 }
 
+/**
+ * Return if format is integer. The immediate mode commands only emit floats
+ * for non-integer types, thus everything else is integer.
+ */
+static inline GLboolean
+vbo_attrtype_to_integer_flag(GLenum format)
+{
+   switch (format) {
+   case GL_FLOAT:
+      return GL_FALSE;
+   case GL_INT:
+   case GL_UNSIGNED_INT:
+      return GL_TRUE;
+   default:
+      ASSERT(0);
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * 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.
+ */
+static inline const GLfloat *
+vbo_get_default_vals_as_float(GLenum format)
+{
+   static const GLfloat default_float[4] = { 0, 0, 0, 1 };
+   static const GLint default_int[4] = { 0, 0, 0, 1 };
+
+   switch (format) {
+   case GL_FLOAT:
+      return default_float;
+   case GL_INT:
+   case GL_UNSIGNED_INT:
+      return (const GLfloat*)default_int;
+   default:
+      ASSERT(0);
+      return NULL;
+   }
+}
+
 #endif
index ef57a81992f890c4a070785f64417da06820e5fb..96cf4c82bf96201afbf6a63b187f739e132e5c99 100644 (file)
@@ -101,6 +101,7 @@ struct vbo_exec_context
       struct vbo_exec_copied_vtx copied;
 
       GLubyte attrsz[VBO_ATTRIB_MAX];
+      GLenum attrtype[VBO_ATTRIB_MAX];
       GLubyte active_sz[VBO_ATTRIB_MAX];
 
       GLfloat *attrptr[VBO_ATTRIB_MAX]; 
index 2ddb715889e27336f5034abdd785b71d85bfc404..75e549fc41920000fd0c6c570270398ad2dea072 100644 (file)
@@ -157,11 +157,13 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
         GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
          GLfloat tmp[4];
 
-         COPY_CLEAN_4V(tmp, 
-                       exec->vtx.attrsz[i], 
-                       exec->vtx.attrptr[i]);
+         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
+                                     exec->vtx.attrsz[i],
+                                     exec->vtx.attrptr[i],
+                                     exec->vtx.attrtype[i]);
          
-         if (memcmp(current, tmp, sizeof(tmp)) != 0) { 
+         if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
+             memcmp(current, tmp, sizeof(tmp)) != 0) {
             memcpy(current, tmp, sizeof(tmp));
         
             /* Given that we explicitly state size here, there is no need
@@ -170,8 +172,10 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
              * directly.
              */
             vbo->currval[i].Size = exec->vtx.attrsz[i];
-            assert(vbo->currval[i].Type == GL_FLOAT);
             vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
+            vbo->currval[i].Type = exec->vtx.attrtype[i];
+            vbo->currval[i].Integer =
+                  vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
 
             /* This triggers rather too much recalculation of Mesa state
              * that doesn't get used (eg light positions).
@@ -324,7 +328,9 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
               if (j == attr) {
                  if (oldSize) {
                     GLfloat tmp[4];
-                    COPY_CLEAN_4V(tmp, oldSize, data + old_offset);
+                     COPY_CLEAN_4V_TYPE_AS_FLOAT(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;
@@ -365,8 +371,9 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
       vbo_exec_wrap_upgrade_vertex( exec, attr, newSize );
    }
    else if (newSize < exec->vtx.active_sz[attr]) {
-      static const GLfloat id[4] = { 0, 0, 0, 1 };
       GLuint i;
+      const GLfloat *id =
+            vbo_get_default_vals_as_float(exec->vtx.attrtype[attr]);
 
       /* New size is smaller - just need to fill in some
        * zeros.  Don't need to flush or wrap.
@@ -390,7 +397,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, V0, V1, V2, V3 )                                   \
+#define ATTR( A, N, T, V0, V1, V2, V3 )                                        \
 do {                                                                   \
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;            \
                                                                        \
@@ -406,6 +413,7 @@ do {                                                                        \
       if (N>1) dest[1] = V1;                                           \
       if (N>2) dest[2] = V2;                                           \
       if (N>3) dest[3] = V3;                                           \
+      exec->vtx.attrtype[A] = T;                                        \
    }                                                                   \
                                                                        \
    if ((A) == 0) {                                                     \
@@ -1119,6 +1127,8 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
    for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
       ASSERT(i < Elements(exec->vtx.attrsz));
       exec->vtx.attrsz[i] = 0;
+      ASSERT(i < Elements(exec->vtx.attrtype));
+      exec->vtx.attrtype[i] = GL_FLOAT;
       ASSERT(i < Elements(exec->vtx.active_sz));
       exec->vtx.active_sz[i] = 0;
    }
@@ -1255,6 +1265,7 @@ static void reset_attrfv( struct vbo_exec_context *exec )
 
    for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
       exec->vtx.attrsz[i] = 0;
+      exec->vtx.attrtype[i] = GL_FLOAT;
       exec->vtx.active_sz[i] = 0;
    }
 
@@ -1309,7 +1320,7 @@ VertexAttrib4f_nopos(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
    GET_CURRENT_CONTEXT(ctx);
    if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      ATTR(VBO_ATTRIB_GENERIC0 + index, 4, x, y, z, w);
+      ATTR(VBO_ATTRIB_GENERIC0 + index, 4, GL_FLOAT, x, y, z, w);
    else
       ERROR(GL_INVALID_VALUE);
 }
index 817af4dd52b9039f3b3ae11044eee17f318f2df4..9529ce0698e560bf3289d5462326a401b27e0fbe 100644 (file)
@@ -207,9 +207,6 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
       assert(0);
    }
 
-   /* Make all active attributes (including edgeflag) available as
-    * arrays of floats.
-    */
    for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) {
       const GLuint src = map[attr];
 
@@ -235,7 +232,9 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
         arrays[attr].Size = exec->vtx.attrsz[src];
         arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat);
         arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat);
-        arrays[attr].Type = GL_FLOAT;
+        arrays[attr].Type = exec->vtx.attrtype[src];
+        arrays[attr].Integer =
+               vbo_attrtype_to_integer_flag(exec->vtx.attrtype[src]);
          arrays[attr].Format = GL_RGBA;
         arrays[attr].Enabled = 1;
          arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);
index f33669670c49fefca4caa0323289d76bda90c2e7..750117b12398f64a74d256fab5ea1f4a6248d1fd 100644 (file)
@@ -63,6 +63,7 @@ struct vbo_save_copied_vtx {
  */
 struct vbo_save_vertex_list {
    GLubyte attrsz[VBO_ATTRIB_MAX];
+   GLenum attrtype[VBO_ATTRIB_MAX];
    GLuint vertex_size;
 
    /* Copy of the final vertex from node->vertex_store->bufferobj.
@@ -127,6 +128,7 @@ struct vbo_save_context {
    const struct gl_client_array *inputs[VBO_ATTRIB_MAX];
 
    GLubyte attrsz[VBO_ATTRIB_MAX];
+   GLenum attrtype[VBO_ATTRIB_MAX];
    GLubyte active_sz[VBO_ATTRIB_MAX];
    GLuint vertex_size;
 
index 89f09a8d83ca867f002078cc3d15e70aaa47edf7..75b8ca3385f35e26a3a941bb242c0996b27fd4c1 100644 (file)
@@ -324,6 +324,7 @@ _save_compile_vertex_list(struct gl_context *ctx)
    /* Duplicate our template, increment refcounts to the storage structs:
     */
    memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
+   memcpy(node->attrtype, save->attrtype, sizeof(node->attrtype));
    node->vertex_size = save->vertex_size;
    node->buffer_offset =
       (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
@@ -510,7 +511,8 @@ _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(save->current[i], save->attrsz[i], save->attrptr[i]);
+         COPY_CLEAN_4V_TYPE_AS_FLOAT(save->current[i], save->attrsz[i],
+                                     save->attrptr[i], save->attrtype[i]);
       }
    }
 }
@@ -612,7 +614,8 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
             if (save->attrsz[j]) {
                if (j == attr) {
                   if (oldsz) {
-                     COPY_CLEAN_4V(dest, oldsz, data);
+                     COPY_CLEAN_4V_TYPE_AS_FLOAT(dest, oldsz, data,
+                                                 save->attrtype[j]);
                      data += oldsz;
                      dest += newsz;
                   }
@@ -649,8 +652,8 @@ save_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
       _save_upgrade_vertex(ctx, attr, sz);
    }
    else if (sz < save->active_sz[attr]) {
-      static GLfloat id[4] = { 0, 0, 0, 1 };
       GLuint i;
+      const GLfloat *id = vbo_get_default_vals_as_float(save->attrtype[attr]);
 
       /* New size is equal or smaller - just need to fill in some
        * zeros.
@@ -688,7 +691,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, V0, V1, V2, V3)                             \
+#define ATTR(A, N, T, V0, V1, V2, V3)                          \
 do {                                                           \
    struct vbo_save_context *save = &vbo_context(ctx)->save;    \
                                                                \
@@ -701,6 +704,7 @@ do {                                                                \
       if (N>1) dest[1] = V1;                                   \
       if (N>2) dest[2] = V2;                                   \
       if (N>3) dest[3] = V3;                                   \
+      save->attrtype[A] = T;                                    \
    }                                                           \
                                                                \
    if ((A) == 0) {                                             \
index 09b8b8ab2b89ffa7b67a0669b3a01fe22b175836..efb386e5c93e7544079d0ea29c5b3cccc9b86f77 100644 (file)
@@ -79,16 +79,20 @@ _playback_copy_to_current(struct gl_context *ctx,
         GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
          GLfloat tmp[4];
 
-         COPY_CLEAN_4V(tmp, 
-                       node->attrsz[i], 
-                       data);
+         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
+                                     node->attrsz[i],
+                                     data,
+                                     node->attrtype[i]);
          
-         if (memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
+         if (node->attrtype[i] != vbo->currval[i].Type ||
+             memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
             memcpy(current, tmp, 4 * sizeof(GLfloat));
 
             vbo->currval[i].Size = node->attrsz[i];
-            assert(vbo->currval[i].Type == GL_FLOAT);
             vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
+            vbo->currval[i].Type = node->attrtype[i];
+            vbo->currval[i].Integer =
+                  vbo_attrtype_to_integer_flag(node->attrtype[i]);
 
             if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
                 i <= VBO_ATTRIB_LAST_MATERIAL)
@@ -134,9 +138,11 @@ static void vbo_bind_vertex_list(struct gl_context *ctx,
    const GLuint *map;
    GLuint attr;
    GLubyte node_attrsz[VBO_ATTRIB_MAX];  /* copy of node->attrsz[] */
+   GLenum node_attrtype[VBO_ATTRIB_MAX];  /* copy of node->attrtype[] */
    GLbitfield64 varying_inputs = 0x0;
 
    memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
+   memcpy(node_attrtype, node->attrtype, sizeof(node->attrtype));
 
    /* Install the default (ie Current) attributes first, then overlay
     * all active ones.
@@ -170,6 +176,7 @@ static void vbo_bind_vertex_list(struct gl_context *ctx,
           (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) {
          save->inputs[VERT_ATTRIB_GENERIC0] = save->inputs[0];
          node_attrsz[VERT_ATTRIB_GENERIC0] = node_attrsz[0];
+         node_attrtype[VERT_ATTRIB_GENERIC0] = node_attrtype[0];
          node_attrsz[0] = 0;
       }
       break;
@@ -188,7 +195,9 @@ static void vbo_bind_vertex_list(struct gl_context *ctx,
         arrays[attr].Size = node_attrsz[src];
         arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat);
         arrays[attr].Stride = node->vertex_size * sizeof(GLfloat);
-        arrays[attr].Type = GL_FLOAT;
+         arrays[attr].Type = node_attrtype[src];
+         arrays[attr].Integer =
+               vbo_attrtype_to_integer_flag(node_attrtype[src]);
          arrays[attr].Format = GL_RGBA;
         arrays[attr].Enabled = 1;
          arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);