aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/main/arrayobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/arrayobj.c')
-rw-r--r--src/mesa/main/arrayobj.c108
1 files changed, 95 insertions, 13 deletions
diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c
index 0fa5f0de551..c03353b78f5 100644
--- a/src/mesa/main/arrayobj.c
+++ b/src/mesa/main/arrayobj.c
@@ -1,9 +1,10 @@
/*
* Mesa 3-D graphics library
- * Version: 7.2
+ * Version: 7.6
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* (C) Copyright IBM Corporation 2006
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -46,6 +47,7 @@
#include "bufferobj.h"
#endif
#include "arrayobj.h"
+#include "macros.h"
#include "glapi/dispatch.h"
@@ -79,6 +81,7 @@ unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj)
GLuint i;
_mesa_reference_buffer_object(ctx, &obj->Vertex.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->Weight.BufferObj, NULL);
_mesa_reference_buffer_object(ctx, &obj->Normal.BufferObj, NULL);
_mesa_reference_buffer_object(ctx, &obj->Color.BufferObj, NULL);
_mesa_reference_buffer_object(ctx, &obj->SecondaryColor.BufferObj, NULL);
@@ -86,10 +89,10 @@ unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj)
_mesa_reference_buffer_object(ctx, &obj->Index.BufferObj, NULL);
_mesa_reference_buffer_object(ctx, &obj->EdgeFlag.BufferObj, NULL);
- for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++)
+ for (i = 0; i < Elements(obj->TexCoord); i++)
_mesa_reference_buffer_object(ctx, &obj->TexCoord[i].BufferObj, NULL);
- for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ for (i = 0; i < Elements(obj->VertexAttrib); i++)
_mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL);
}
@@ -198,7 +201,8 @@ init_array(GLcontext *ctx,
array->Normalized = GL_FALSE;
#if FEATURE_ARB_vertex_buffer_object
/* Vertex array buffers */
- array->BufferObj = ctx->Array.NullBufferObj;
+ _mesa_reference_buffer_object(ctx, &array->BufferObj,
+ ctx->Shared->NullBufferObj);
#endif
}
@@ -220,16 +224,17 @@ _mesa_initialize_array_object( GLcontext *ctx,
/* Init the individual arrays */
init_array(ctx, &obj->Vertex, 4, GL_FLOAT);
+ init_array(ctx, &obj->Weight, 1, GL_FLOAT);
init_array(ctx, &obj->Normal, 3, GL_FLOAT);
init_array(ctx, &obj->Color, 4, GL_FLOAT);
init_array(ctx, &obj->SecondaryColor, 4, GL_FLOAT);
init_array(ctx, &obj->FogCoord, 1, GL_FLOAT);
init_array(ctx, &obj->Index, 1, GL_FLOAT);
- for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
+ for (i = 0; i < Elements(obj->TexCoord); i++) {
init_array(ctx, &obj->TexCoord[i], 4, GL_FLOAT);
}
init_array(ctx, &obj->EdgeFlag, 1, GL_BOOL);
- for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ for (i = 0; i < Elements(obj->VertexAttrib); i++) {
init_array(ctx, &obj->VertexAttrib[i], 4, GL_FLOAT);
}
@@ -242,8 +247,8 @@ _mesa_initialize_array_object( GLcontext *ctx,
/**
* Add the given array object to the array object pool.
*/
-void
-_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj )
+static void
+save_array_object( GLcontext *ctx, struct gl_array_object *obj )
{
if (obj->Name > 0) {
/* insert into hash table */
@@ -256,8 +261,8 @@ _mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj )
* Remove the given array object from the array object pool.
* Do not deallocate the array object though.
*/
-void
-_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj )
+static void
+remove_array_object( GLcontext *ctx, struct gl_array_object *obj )
{
if (obj->Name > 0) {
/* remove from hash table */
@@ -266,6 +271,83 @@ _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj )
}
+
+/**
+ * Compute the index of the last array element that can be safely accessed
+ * in a vertex array. We can really only do this when the array lives in
+ * a VBO.
+ * The array->_MaxElement field will be updated.
+ * Later in glDrawArrays/Elements/etc we can do some bounds checking.
+ */
+static void
+compute_max_element(struct gl_client_array *array)
+{
+ if (array->BufferObj->Name) {
+ /* Compute the max element we can access in the VBO without going
+ * out of bounds.
+ */
+ array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size
+ - (GLsizeiptrARB) array->Ptr + array->StrideB
+ - array->_ElementSize) / array->StrideB;
+ if (0)
+ _mesa_printf("%s Object %u Size %u MaxElement %u\n",
+ __FUNCTION__,
+ array->BufferObj->Name,
+ (GLuint) array->BufferObj->Size,
+ array->_MaxElement);
+ }
+ else {
+ /* user-space array, no idea how big it is */
+ array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
+ }
+}
+
+
+/**
+ * Helper for update_arrays().
+ * \return min(current min, array->_MaxElement).
+ */
+static GLuint
+update_min(GLuint min, struct gl_client_array *array)
+{
+ compute_max_element(array);
+ if (array->Enabled)
+ return MIN2(min, array->_MaxElement);
+ else
+ return min;
+}
+
+
+/**
+ * Examine vertex arrays to update the gl_array_object::_MaxElement field.
+ */
+void
+_mesa_update_array_object_max_element(GLcontext *ctx,
+ struct gl_array_object *arrayObj)
+{
+ GLuint i, min = ~0;
+
+ min = update_min(min, &arrayObj->Vertex);
+ min = update_min(min, &arrayObj->Weight);
+ min = update_min(min, &arrayObj->Normal);
+ min = update_min(min, &arrayObj->Color);
+ min = update_min(min, &arrayObj->SecondaryColor);
+ min = update_min(min, &arrayObj->FogCoord);
+ min = update_min(min, &arrayObj->Index);
+ min = update_min(min, &arrayObj->EdgeFlag);
+#if FEATURE_point_size_array
+ min = update_min(min, &arrayObj->PointSize);
+#endif
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
+ min = update_min(min, &arrayObj->TexCoord[i]);
+ for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
+ min = update_min(min, &arrayObj->VertexAttrib[i]);
+
+ /* _MaxElement is one past the last legal array element */
+ arrayObj->_MaxElement = min;
+}
+
+
/**********************************************************************/
/* API Functions */
/**********************************************************************/
@@ -311,7 +393,7 @@ _mesa_BindVertexArrayAPPLE( GLuint id )
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
return;
}
- _mesa_save_array_object(ctx, newObj);
+ save_array_object(ctx, newObj);
}
}
@@ -360,7 +442,7 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids)
}
/* The ID is immediately freed for re-use */
- _mesa_remove_array_object(ctx, obj);
+ remove_array_object(ctx, obj);
/* Unreference the array object.
* If refcount hits zero, the object will be deleted.
@@ -414,7 +496,7 @@ _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE");
return;
}
- _mesa_save_array_object(ctx, obj);
+ save_array_object(ctx, obj);
arrays[i] = first + i;
}