[Mesa-dev] [PATCH] vbo: fix glVertexAttribI* functions

Brian Paul brianp at vmware.com
Wed Oct 31 08:09:52 PDT 2012


On 10/30/2012 04:32 PM, Marek Olšák wrote:
> 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 likely a candidate for the stable branches.

Looks good.  Just some minor things below.

Reviewed-by: Brian Paul <brianp at vmware.com>


> ---
>   docs/GL3.txt                  |    3 +-
>   src/mesa/main/macros.h        |   44 +++++++++++++++++++++
>   src/mesa/vbo/vbo_attrib_tmp.h |   86 ++++++++++++++++++++++-------------------
>   src/mesa/vbo/vbo_context.h    |   42 ++++++++++++++++++++
>   src/mesa/vbo/vbo_exec.h       |    1 +
>   src/mesa/vbo/vbo_exec_api.c   |   29 +++++++++-----
>   src/mesa/vbo/vbo_exec_draw.c  |    7 ++--
>   src/mesa/vbo/vbo_save.h       |    2 +
>   src/mesa/vbo/vbo_save_api.c   |   12 ++++--
>   src/mesa/vbo/vbo_save_draw.c  |   21 +++++++---
>   10 files changed, 183 insertions(+), 64 deletions(-)
>
> diff --git a/docs/GL3.txt b/docs/GL3.txt
> index 4f44764..28f6ae6 100644
> --- a/docs/GL3.txt
> +++ b/docs/GL3.txt
> @@ -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
>
> diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
> index 7b7fd1b..f89533f 100644
> --- a/src/mesa/main/macros.h
> +++ b/src/mesa/main/macros.h
> @@ -171,6 +171,26 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
>   	ub = ((GLubyte) F_TO_I((f) * 255.0F))
>   #endif
>
> +static inline float INT_AS_FLT(int i)
> +{
> +   union {
> +      int i;
> +      float f;
> +   } tmp;
> +   tmp.i = i;
> +   return tmp.f;
> +}

We have an fi_type union in imports.h, so:

static inline float
INT_AS_FLT(int i)
{
    fi_type tmp;
    tmp.i = i;
    return tmp.f;
}


> +
> +static inline float UINT_AS_FLT(unsigned u)
> +{
> +   union {
> +      unsigned u;
> +      float f;
> +   } tmp;
> +   tmp.u = u;
> +   return tmp.f;
> +}

You could add an unsigned field to the fi_type union and use it here 
too, if you want.



> +
>   /*@}*/
>
>
> @@ -573,6 +593,30 @@ 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. */

Closing */ on it's own line, please.


> +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 */
>   /*@{*/
> diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h
> index 8848445..6bc53ba 100644
> --- a/src/mesa/vbo/vbo_attrib_tmp.h
> +++ b/src/mesa/vbo/vbo_attrib_tmp.h
> @@ -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), \
> diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h
> index 491b597..74d61cc 100644
> --- a/src/mesa/vbo/vbo_context.h
> +++ b/src/mesa/vbo/vbo_context.h
> @@ -162,4 +162,46 @@ 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)

Break the declaration so the function name is on the next line, as above.


> +{
> +   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
> diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
> index ef57a81..96cf4c8 100644
> --- a/src/mesa/vbo/vbo_exec.h
> +++ b/src/mesa/vbo/vbo_exec.h
> @@ -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];
> diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
> index 44b9475..51a981b 100644
> --- a/src/mesa/vbo/vbo_exec_api.c
> +++ b/src/mesa/vbo/vbo_exec_api.c
> @@ -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).
> @@ -325,7 +329,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;
> @@ -366,8 +372,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.
> @@ -391,7 +398,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;		\
>   									\
> @@ -407,6 +414,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) {							\
> @@ -1120,6 +1128,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;
>      }
> @@ -1256,6 +1266,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;
>      }
>
> @@ -1310,7 +1321,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);
>   }
> diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
> index 817af4d..9529ce0 100644
> --- a/src/mesa/vbo/vbo_exec_draw.c
> +++ b/src/mesa/vbo/vbo_exec_draw.c
> @@ -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);
> diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h
> index f336696..750117b 100644
> --- a/src/mesa/vbo/vbo_save.h
> +++ b/src/mesa/vbo/vbo_save.h
> @@ -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;
>
> diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
> index 89f09a8..75b8ca3 100644
> --- a/src/mesa/vbo/vbo_save_api.c
> +++ b/src/mesa/vbo/vbo_save_api.c
> @@ -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) {						\
> diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
> index 30c1d3c..54fcf9e 100644
> --- a/src/mesa/vbo/vbo_save_draw.c
> +++ b/src/mesa/vbo/vbo_save_draw.c
> @@ -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)
> @@ -135,9 +139,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.
> @@ -171,6 +177,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;
> @@ -189,7 +196,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);



More information about the mesa-dev mailing list