summaryrefslogtreecommitdiff
path: root/src/mesa/vbo/vbo_exec_draw.c
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2009-03-03 10:46:12 +0000
committerKeith Whitwell <keithw@vmware.com>2009-03-03 10:46:12 +0000
commitc4d1f4607abf3dfbcfcffc5c67bb89d420d3381a (patch)
treecac8b185bf1508083360e7d4a204b4e1877a4f8d /src/mesa/vbo/vbo_exec_draw.c
parenteb8a1d96424cb732b0a723cb1fdba90958d24e16 (diff)
vbo: use MapBufferRange where available
Previously would have to allocate a new VBO after firing a draw command as subsequent call to Map() on old VBO might block if the driver had submitted the commands to hardware.
Diffstat (limited to 'src/mesa/vbo/vbo_exec_draw.c')
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c118
1 files changed, 101 insertions, 17 deletions
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index ae43857c8a..a89f150654 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -70,7 +70,7 @@ static GLuint vbo_copy_vertices( struct vbo_exec_context *exec )
GLuint ovf, i;
GLuint sz = exec->vtx.vertex_size;
GLfloat *dst = exec->vtx.copied.buffer;
- GLfloat *src = ((GLfloat *)exec->vtx.buffer_map +
+ GLfloat *src = (exec->vtx.buffer_map +
exec->vtx.prim[exec->vtx.prim_count-1].start *
exec->vtx.vertex_size);
@@ -147,7 +147,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
struct vbo_exec_context *exec = &vbo->exec;
struct gl_client_array *arrays = exec->vtx.arrays;
GLuint count = exec->vtx.vert_count;
- GLubyte *data = exec->vtx.buffer_map;
+ GLubyte *data = (GLubyte *)exec->vtx.buffer_map;
const GLuint *map;
GLuint attr;
GLbitfield varying_inputs = 0x0;
@@ -220,10 +220,78 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
}
+static void vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
+{
+ GLenum target = GL_ARRAY_BUFFER_ARB;
+
+ if (exec->vtx.bufferobj->Name) {
+ GLcontext *ctx = exec->ctx;
+
+ exec->vtx.buffer_used += (exec->vtx.buffer_ptr -
+ exec->vtx.buffer_map) * sizeof(float);
+
+ ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj);
+ exec->vtx.buffer_map = NULL;
+ exec->vtx.buffer_ptr = NULL;
+ exec->vtx.max_vert = 0;
+ }
+}
+
+void vbo_exec_vtx_map( struct vbo_exec_context *exec )
+{
+ GLcontext *ctx = exec->ctx;
+ GLenum target = GL_ARRAY_BUFFER_ARB;
+ GLenum access = GL_READ_WRITE_ARB;
+ GLenum usage = GL_STREAM_DRAW_ARB;
+
+ if (exec->vtx.bufferobj->Name == 0)
+ return;
+
+ if (exec->vtx.buffer_map != NULL) {
+ assert(0);
+ exec->vtx.buffer_map = NULL;
+ }
+
+ if (VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024 &&
+ ctx->Driver.MapBufferRange)
+ {
+ exec->vtx.buffer_map =
+ (GLfloat *)ctx->Driver.MapBufferRange(ctx,
+ target,
+ exec->vtx.buffer_used,
+ (VBO_VERT_BUFFER_SIZE -
+ exec->vtx.buffer_used),
+ (GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT |
+ GL_MAP_UNSYNCHRONIZED_BIT |
+ MESA_MAP_NOWAIT_BIT),
+ exec->vtx.bufferobj);
+ }
+
+ if (exec->vtx.buffer_map) {
+ exec->vtx.buffer_map += exec->vtx.buffer_used / sizeof(float);
+ }
+ else {
+ exec->vtx.buffer_used = 0;
+
+ ctx->Driver.BufferData(ctx, target,
+ VBO_VERT_BUFFER_SIZE,
+ NULL, usage, exec->vtx.bufferobj);
+
+ exec->vtx.buffer_map =
+ (GLfloat *)ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
+ }
+
+ if (0) _mesa_printf("map %d..\n", exec->vtx.buffer_used);
+}
+
+
+
/**
* Execute the buffer and save copied verts.
*/
-void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
+void vbo_exec_vtx_flush( struct vbo_exec_context *exec,
+ GLboolean unmap )
{
if (0)
vbo_exec_debug_verts( exec );
@@ -236,13 +304,9 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
if (exec->vtx.copied.nr != exec->vtx.vert_count) {
GLcontext *ctx = exec->ctx;
-
- 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);
- /* Before the unmap (why?)
+ /* Before the update_state() as this may raise _NEW_ARRAY
+ * from _mesa_set_varying_vp_inputs().
*/
vbo_exec_bind_arrays( ctx );
@@ -250,8 +314,12 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
_mesa_update_state( ctx );
- ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj);
- exec->vtx.buffer_map = NULL;
+ if (exec->vtx.bufferobj->Name) {
+ vbo_exec_vtx_unmap( exec );
+ }
+
+ if (0) _mesa_printf("%s %d %d\n", __FUNCTION__, exec->vtx.prim_count,
+ exec->vtx.vert_count);
vbo_context(ctx)->draw_prims( ctx,
exec->vtx.inputs,
@@ -261,15 +329,31 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
0,
exec->vtx.vert_count - 1);
- /* Get new data:
- */
- ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
- exec->vtx.buffer_map
- = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
+ /* If using a real VBO, get new storage -- unless asked not to.
+ */
+ if (exec->vtx.bufferobj->Name && !unmap) {
+ vbo_exec_vtx_map( exec );
+ }
}
}
+ /* May have to unmap explicitly if we didn't draw:
+ */
+ if (unmap &&
+ exec->vtx.bufferobj->Name &&
+ exec->vtx.buffer_map) {
+ vbo_exec_vtx_unmap( exec );
+ }
+
+
+ if (unmap)
+ exec->vtx.max_vert = 0;
+ else
+ exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
+ (exec->vtx.vertex_size * sizeof(GLfloat)));
+
+
+ exec->vtx.buffer_ptr = exec->vtx.buffer_map;
exec->vtx.prim_count = 0;
exec->vtx.vert_count = 0;
- exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
}