* Keith Whitwell <keith@tungstengraphics.com>
*/
-#include "glheader.h"
-#include "context.h"
-#include "macros.h"
-#include "vtxfmt.h"
-#include "dlist.h"
-#include "state.h"
-#include "light.h"
-#include "api_arrayelt.h"
-#include "api_noop.h"
-#include "dispatch.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/vtxfmt.h"
+#include "main/dlist.h"
+#include "main/state.h"
+#include "main/light.h"
+#include "main/api_arrayelt.h"
+#include "main/api_noop.h"
+#include "glapi/dispatch.h"
#include "vbo_context.h"
+#ifdef ERROR
+#undef ERROR
+#endif
+
+
static void reset_attrfv( struct vbo_exec_context *exec );
if (exec->eval.recalculate_maps)
vbo_exec_eval_update( exec );
- for (i = 0 ; i <= VBO_ATTRIB_INDEX ; i++) {
+ for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
if (exec->eval.map1[i].map)
if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz)
vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz );
if (exec->eval.recalculate_maps)
vbo_exec_eval_update( exec );
- for (i = 0 ; i <= VBO_ATTRIB_INDEX ; i++) {
+ for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
if (exec->eval.map2[i].map)
if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz)
vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz );
}
+/**
+ * Tell the VBO module to use a real OpenGL vertex buffer object to
+ * store accumulated immediate-mode vertex data.
+ * This replaces the malloced buffer which was created in
+ * vb_exec_vtx_init() below.
+ */
+void vbo_use_buffer_objects(GLcontext *ctx)
+{
+ struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
+ /* Any buffer name but 0 can be used here since this bufferobj won't
+ * go into the bufferobj hashtable.
+ */
+ GLuint bufName = 0xaabbccdd;
+ GLenum target = GL_ARRAY_BUFFER_ARB;
+ GLenum access = GL_READ_WRITE_ARB;
+ GLenum usage = GL_STREAM_DRAW_ARB;
+ GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat);
+
+ /* Make sure this func is only used once */
+ assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj);
+ if (exec->vtx.buffer_map) {
+ _mesa_align_free(exec->vtx.buffer_map);
+ }
+
+ /* Allocate a real buffer object now */
+ exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
+ ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
+
+ /* and map it */
+ exec->vtx.buffer_map
+ = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
+}
+
+
+
void vbo_exec_vtx_init( struct vbo_exec_context *exec )
{
GLcontext *ctx = exec->ctx;
GLuint i;
/* Allocate a buffer object. Will just reuse this object
- * continuously.
+ * continuously, unless vbo_use_buffer_objects() is called to enable
+ * use of real VBOs.
*/
exec->vtx.bufferobj = ctx->Array.NullBufferObj;
exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64);
void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
{
- if (exec->vtx.buffer_map) {
- ALIGN_FREE(exec->vtx.buffer_map);
- exec->vtx.buffer_map = NULL;
+ GLcontext *ctx = exec->ctx;
+ if (exec->vtx.bufferobj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, exec->vtx.bufferobj);
+ ctx->Driver.DeleteBuffer(ctx, exec->vtx.bufferobj);
+ exec->vtx.bufferobj = NULL;
+ }
+ else {
+ if (exec->vtx.buffer_map) {
+ ALIGN_FREE(exec->vtx.buffer_map);
+ exec->vtx.buffer_map = NULL;
+ }
}
}