[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