summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/imports.h2
-rw-r--r--src/mesa/main/macros.h39
-rw-r--r--src/mesa/vbo/vbo_attrib_tmp.h86
-rw-r--r--src/mesa/vbo/vbo_context.h43
-rw-r--r--src/mesa/vbo/vbo_exec.h1
-rw-r--r--src/mesa/vbo/vbo_exec_api.c29
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c7
-rw-r--r--src/mesa/vbo/vbo_save.h2
-rw-r--r--src/mesa/vbo/vbo_save_api.c12
-rw-r--r--src/mesa/vbo/vbo_save_draw.c21
10 files changed, 179 insertions, 63 deletions
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index a78d67966f8..40ba75785fc 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -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;
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index 7b7fd1b6d76..14a5d5fe16e 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -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 */
/*@{*/
diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h
index 88484453570..6bc53bab3d2 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 c896f1196f7..1ff6ec0004e 100644
--- a/src/mesa/vbo/vbo_context.h
+++ b/src/mesa/vbo/vbo_context.h
@@ -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
diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
index ef57a81992f..96cf4c82bf9 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 2ddb715889e..75e549fc419 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).
@@ -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);
}
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 817af4dd52b..9529ce0698e 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 f33669670c4..750117b1239 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 89f09a8d83c..75b8ca3385f 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 09b8b8ab2b8..efb386e5c93 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)
@@ -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);