+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)
+{
+ 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);