diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 73 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_defines.h | 1 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 32 | ||||
-rw-r--r-- | src/mesa/main/vtxfmt.c | 9 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_bufferobjects.c | 35 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec.c | 1 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec.h | 15 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec_api.c | 73 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec_draw.c | 118 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save.h | 2 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_api.c | 16 |
11 files changed, 303 insertions, 72 deletions
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 533c0a15f39..a0a483ecaad 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -284,16 +284,26 @@ fenced_buffer_map(struct pb_buffer *buf, unsigned flags) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct pipe_winsys *winsys = fenced_list->winsys; void *map; - assert(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE); - assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE)); - flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE; - - /* Check for GPU read/write access */ - if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) { - /* Wait for the GPU to finish writing */ - _fenced_buffer_finish(fenced_buf); + assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE)); + + /* Serialize writes */ + if((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) || + ((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) { + if(flags & PIPE_BUFFER_USAGE_DONTBLOCK) { + /* Don't wait for the GPU to finish writing */ + if(winsys->fence_finish(winsys, fenced_buf->fence, 0) == 0) + _fenced_buffer_remove(fenced_list, fenced_buf); + else + return NULL; + } + else { + /* Wait for the GPU to finish writing */ + _fenced_buffer_finish(fenced_buf); + } } #if 0 @@ -307,7 +317,7 @@ fenced_buffer_map(struct pb_buffer *buf, map = pb_map(fenced_buf->buffer, flags); if(map) { ++fenced_buf->mapcount; - fenced_buf->flags |= flags; + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE; } return map; @@ -471,6 +481,51 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list, } +<<<<<<< HEAD:src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +======= +void +buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence) +{ + struct fenced_buffer *fenced_buf; + struct fenced_buffer_list *fenced_list; + struct pipe_winsys *winsys; + /* FIXME: receive this as a parameter */ + unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0; + + /* This is a public function, so be extra cautious with the buffer passed, + * as happens frequently to receive null buffers, or pointer to buffers + * other than fenced buffers. */ + assert(buf); + if(!buf) + return; + assert(buf->vtbl == &fenced_buffer_vtbl); + if(buf->vtbl != &fenced_buffer_vtbl) + return; + + if(!fence) + return; + + fenced_buf = fenced_buffer(buf); + fenced_list = fenced_buf->list; + winsys = fenced_list->winsys; + + if(fence == fenced_buf->fence) { + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; + return; + } + + pipe_mutex_lock(fenced_list->mutex); + if (fenced_buf->fence) + _fenced_buffer_remove(fenced_list, fenced_buf); + winsys->fence_reference(winsys, &fenced_buf->fence, fence); + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; + _fenced_buffer_add(fenced_buf); + pipe_mutex_unlock(fenced_list->mutex); +} + + +>>>>>>> origin/gallium-0.1:src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c struct fenced_buffer_list * fenced_buffer_list_create(struct pb_fence_ops *ops) { diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 3cbc93d12bc..52d443970b0 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -215,6 +215,7 @@ enum pipe_transfer_usage { #define PIPE_BUFFER_USAGE_INDEX (1 << 6) #define PIPE_BUFFER_USAGE_CONSTANT (1 << 7) #define PIPE_BUFFER_USAGE_DISCARD (1 << 8) +#define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9) /** Pipe driver custom usage flags should be greater or equal to this value */ #define PIPE_BUFFER_USAGE_CUSTOM (1 << 16) diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 411b6a7b21f..a335f77479d 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -36,6 +36,22 @@ struct gl_pixelstore_attrib; struct gl_display_list; +#if FEATURE_ARB_vertex_buffer_object +/* Modifies GL_MAP_UNSYNCHRONIZED_BIT to allow driver to fail (return + * NULL) if buffer is unavailable for immediate mapping. + * + * Does GL_MAP_INVALIDATE_RANGE_BIT do this? It seems so, but it + * would require more book-keeping in the driver than seems necessary + * at this point. + * + * Does GL_MAP_INVALDIATE_BUFFER_BIT do this? Not really -- we don't + * want to provoke the driver to throw away the old storage, we will + * respect the contents of already referenced data. + */ +#define MESA_MAP_NOWAIT_BIT 0x0040 +#endif + + /** * Device driver function table. * Core Mesa uses these function pointers to call into device drivers. @@ -785,6 +801,16 @@ struct dd_function_table { void * (*MapBuffer)( GLcontext *ctx, GLenum target, GLenum access, struct gl_buffer_object *obj ); + /* May return NULL if MESA_MAP_NOWAIT_BIT is set in access: + */ + void * (*MapBufferRange)( GLcontext *ctx, GLenum target, + GLintptr offset, GLsizeiptr length, GLbitfield access, + struct gl_buffer_object *obj); + + void (*FlushMappedBufferRange) (GLcontext *ctx, GLenum target, + GLintptr offset, GLsizeiptr length, + struct gl_buffer_object *obj); + GLboolean (*UnmapBuffer)( GLcontext *ctx, GLenum target, struct gl_buffer_object *obj ); /*@}*/ @@ -954,6 +980,12 @@ struct dd_function_table { GLuint NeedFlush; GLuint SaveNeedFlush; + + /* Called prior to any of the GLvertexformat functions being + * called. Paired with Driver.FlushVertices(). + */ + void (*BeginVertices)( GLcontext *ctx ); + /** * If inside glBegin()/glEnd(), it should ASSERT(0). Otherwise, if * FLUSH_STORED_VERTICES bit in \p flags is set flushes any buffered diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c index 0204979003e..1f807dc3dc3 100644 --- a/src/mesa/main/vtxfmt.c +++ b/src/mesa/main/vtxfmt.c @@ -54,9 +54,12 @@ ASSERT( tnl->Current ); \ ASSERT( tnl->SwapCount < NUM_VERTEX_FORMAT_ENTRIES ); \ ASSERT( tmp_offset >= 0 ); \ - \ - /* Save the swapped function's dispatch entry so it can be */ \ - /* restored later. */ \ + \ + if (tnl->SwapCount == 0) \ + ctx->Driver.BeginVertices( ctx ); \ + \ + /* Save the swapped function's dispatch entry so it can be */ \ + /* restored later. */ \ tnl->Swapped[tnl->SwapCount].location = & (((_glapi_proc *)ctx->Exec)[tmp_offset]); \ tnl->Swapped[tnl->SwapCount].function = (_glapi_proc)TAG(FUNC); \ tnl->SwapCount++; \ diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 562ac6c65c5..28e387c399d 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -206,8 +206,40 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, } + /** - * Called via glMapBufferARB(). + * Called via glMapBufferRange(). + */ +static void * +st_bufferobj_map_range(GLcontext *ctx, GLenum target, + GLintptr offset, GLsizeiptr length, GLbitfield access, + struct gl_buffer_object *obj) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + struct st_buffer_object *st_obj = st_buffer_object(obj); + GLuint flags = 0; + + if (access & GL_MAP_WRITE_BIT) + flags |= PIPE_BUFFER_USAGE_CPU_WRITE; + + if (access & GL_MAP_READ_BIT) + flags |= PIPE_BUFFER_USAGE_CPU_READ; + + /* ... other flags ... + */ + + if (access & MESA_MAP_NOWAIT_BIT) + flags |= PIPE_BUFFER_USAGE_DONTBLOCK; + + obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags); + return obj->Pointer; +} + + + + +/** + * Called via glUnmapBufferARB(). */ static GLboolean st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) @@ -230,5 +262,6 @@ st_init_bufferobject_functions(struct dd_function_table *functions) functions->BufferSubData = st_bufferobj_subdata; functions->GetBufferSubData = st_bufferobj_get_subdata; functions->MapBuffer = st_bufferobj_map; + functions->MapBufferRange = st_bufferobj_map_range; functions->UnmapBuffer = st_bufferobj_unmap; } diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c index 635f239acc8..e168a89ea5e 100644 --- a/src/mesa/vbo/vbo_exec.c +++ b/src/mesa/vbo/vbo_exec.c @@ -57,6 +57,7 @@ void vbo_exec_init( GLcontext *ctx ) ctx->Driver.NeedFlush = 0; ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; + ctx->Driver.BeginVertices = vbo_exec_BeginVertices; ctx->Driver.FlushVertices = vbo_exec_FlushVertices; vbo_exec_invalidate_state( ctx, ~0 ); diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index ddbcbe11814..100bb8a5dec 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -43,7 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Wierd implementation stuff: */ -#define VBO_VERT_BUFFER_SIZE (1024*16) /* dwords == 64k */ +#define VBO_VERT_BUFFER_SIZE (1024*64) /* bytes */ #define VBO_MAX_ATTR_CODEGEN 16 #define ERROR_ATTRIB 16 @@ -78,14 +78,15 @@ struct vbo_exec_context struct { struct gl_buffer_object *bufferobj; - GLubyte *buffer_map; - GLuint vertex_size; + GLuint vertex_size; /* in dwords */ struct _mesa_prim prim[VBO_MAX_PRIM]; GLuint prim_count; - GLfloat *vbptr; /* cursor, points into buffer */ + GLfloat *buffer_map; + GLfloat *buffer_ptr; /* cursor, points into buffer */ + GLuint buffer_used; /* in bytes */ GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */ GLuint vert_count; @@ -140,6 +141,9 @@ struct vbo_exec_context void vbo_exec_init( GLcontext *ctx ); void vbo_exec_destroy( GLcontext *ctx ); void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state ); +void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap ); + +void vbo_exec_BeginVertices( GLcontext *ctx ); void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ); @@ -151,7 +155,8 @@ void vbo_exec_array_destroy( struct vbo_exec_context *exec ); void vbo_exec_vtx_init( struct vbo_exec_context *exec ); void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ); -void vbo_exec_vtx_flush( struct vbo_exec_context *exec ); +void vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ); +void vbo_exec_vtx_map( struct vbo_exec_context *exec ); void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ); void vbo_exec_eval_update( struct vbo_exec_context *exec ); diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 2743bf6b55c..c0ffdb55e47 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -62,7 +62,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec ) if (exec->vtx.prim_count == 0) { exec->vtx.copied.nr = 0; exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; + exec->vtx.buffer_ptr = exec->vtx.buffer_map; } else { GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin; @@ -80,7 +80,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec ) /* Execute the buffer and save copied vertices. */ if (exec->vtx.vert_count) - vbo_exec_vtx_flush( exec ); + vbo_exec_vtx_flush( exec, GL_FALSE ); else { exec->vtx.prim_count = 0; exec->vtx.copied.nr = 0; @@ -121,9 +121,9 @@ void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ) assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - _mesa_memcpy( exec->vtx.vbptr, data, + _mesa_memcpy( exec->vtx.buffer_ptr, data, exec->vtx.vertex_size * sizeof(GLfloat)); - exec->vtx.vbptr += exec->vtx.vertex_size; + exec->vtx.buffer_ptr += exec->vtx.vertex_size; data += exec->vtx.vertex_size; exec->vtx.vert_count++; } @@ -251,9 +251,10 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, exec->vtx.attrsz[attr] = newsz; exec->vtx.vertex_size += newsz - oldsz; - exec->vtx.max_vert = VBO_VERT_BUFFER_SIZE / exec->vtx.vertex_size; + exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) / + (exec->vtx.vertex_size * sizeof(GLfloat))); exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; + exec->vtx.buffer_ptr = exec->vtx.buffer_map; /* Recalculate all the attrptr[] values @@ -279,10 +280,10 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, if (exec->vtx.copied.nr) { GLfloat *data = exec->vtx.copied.buffer; - GLfloat *dest = exec->vtx.vbptr; + GLfloat *dest = exec->vtx.buffer_ptr; GLuint j; - assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map); + assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map); for (i = 0 ; i < exec->vtx.copied.nr ; i++) { for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) { @@ -308,7 +309,7 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, } } - exec->vtx.vbptr = dest; + exec->vtx.buffer_ptr = dest; exec->vtx.vert_count += exec->vtx.copied.nr; exec->vtx.copied.nr = 0; } @@ -373,9 +374,9 @@ do { \ GLuint i; \ \ for (i = 0; i < exec->vtx.vertex_size; i++) \ - exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \ + exec->vtx.buffer_ptr[i] = exec->vtx.vertex[i]; \ \ - exec->vtx.vbptr += exec->vtx.vertex_size; \ + exec->vtx.buffer_ptr += exec->vtx.vertex_size; \ exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \ \ if (++exec->vtx.vert_count >= exec->vtx.max_vert) \ @@ -532,7 +533,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) * begin/end pairs. */ if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) - vbo_exec_FlushVertices( ctx, ~0 ); + vbo_exec_FlushVertices_internal( ctx, GL_FALSE ); i = exec->vtx.prim_count++; exec->vtx.prim[i].mode = mode; @@ -566,7 +567,7 @@ static void GLAPIENTRY vbo_exec_End( void ) ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; if (exec->vtx.prim_count == VBO_MAX_PRIM) - vbo_exec_vtx_flush( exec ); + vbo_exec_vtx_flush( exec, GL_FALSE ); } else _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); @@ -672,23 +673,19 @@ void vbo_use_buffer_objects(GLcontext *ctx) */ 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); + GLsizei size = VBO_VERT_BUFFER_SIZE; /* 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); + exec->vtx.buffer_map = NULL; } /* 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); } @@ -708,7 +705,8 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) ctx->Array.NullBufferObj); ASSERT(!exec->vtx.buffer_map); - exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); + exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64); + vbo_exec_vtxfmt_init( exec ); /* Hook our functions into the dispatch table. @@ -747,22 +745,45 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ) } } - -void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) +void vbo_exec_BeginVertices( GLcontext *ctx ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + if (0) _mesa_printf("%s\n", __FUNCTION__); + vbo_exec_vtx_map( exec ); +} - if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) - return; +void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; - if (exec->vtx.vert_count) { - vbo_exec_vtx_flush( exec ); + if (exec->vtx.vert_count || unmap) { + vbo_exec_vtx_flush( exec, unmap ); } if (exec->vtx.vertex_size) { vbo_exec_copy_to_current( exec ); reset_attrfv( exec ); } +} + + + +void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + if (0) _mesa_printf("%s\n", __FUNCTION__); + + if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { + if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__); + return; + } + + vbo_exec_FlushVertices_internal( ctx, GL_TRUE ); + + /* Need to do this to ensure BeginVertices gets called again: + */ + _mesa_restore_exec_vtxfmt( ctx ); exec->ctx->Driver.NeedFlush = 0; } diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 45133fa4f32..38b6c56f479 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; @@ -234,10 +234,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 ); @@ -250,25 +318,22 @@ 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 ); if (ctx->NewState) _mesa_update_state( ctx ); - /* if using a real VBO, unmap it before drawing */ if (exec->vtx.bufferobj->Name) { - ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj); - exec->vtx.buffer_map = NULL; + 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, exec->vtx.prim, @@ -277,16 +342,31 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec ) 0, exec->vtx.vert_count - 1); - /* If using a real VBO, get new storage */ - if (exec->vtx.bufferobj->Name) { - 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; } diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 7dda54af48b..9558f838837 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -130,7 +130,7 @@ struct vbo_save_context { struct vbo_save_vertex_store *vertex_store; struct vbo_save_primitive_store *prim_store; - GLfloat *vbptr; /* cursor, points into buffer */ + GLfloat *buffer_ptr; /* cursor, points into buffer */ GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current values */ GLfloat *attrptr[VBO_ATTRIB_MAX]; GLuint vert_count; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index ddfd2765774..52b6f1884ee 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -241,7 +241,7 @@ static void _save_reset_counters( GLcontext *ctx ) save->buffer = (save->vertex_store->buffer + save->vertex_store->used); - assert(save->buffer == save->vbptr); + assert(save->buffer == save->buffer_ptr); if (save->vertex_size) save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / @@ -343,7 +343,7 @@ static void _save_compile_vertex_list( GLcontext *ctx ) /* Allocate and map new store: */ save->vertex_store = alloc_vertex_store( ctx ); - save->vbptr = map_vertex_store( ctx, save->vertex_store ); + save->buffer_ptr = map_vertex_store( ctx, save->vertex_store ); } if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) { @@ -414,9 +414,9 @@ static void _save_wrap_filled_vertex( GLcontext *ctx ) assert(save->max_vert - save->vert_count > save->copied.nr); for (i = 0 ; i < save->copied.nr ; i++) { - _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); + _mesa_memcpy( save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat)); data += save->vertex_size; - save->vbptr += save->vertex_size; + save->buffer_ptr += save->vertex_size; save->vert_count++; } } @@ -550,7 +550,7 @@ static void _save_upgrade_vertex( GLcontext *ctx, } } - save->vbptr = dest; + save->buffer_ptr = dest; save->vert_count += save->copied.nr; } } @@ -622,9 +622,9 @@ do { \ GLuint i; \ \ for (i = 0; i < save->vertex_size; i++) \ - save->vbptr[i] = save->vertex[i]; \ + save->buffer_ptr[i] = save->vertex[i]; \ \ - save->vbptr += save->vertex_size; \ + save->buffer_ptr += save->vertex_size; \ \ if (++save->vert_count >= save->max_vert) \ _save_wrap_filled_vertex( ctx ); \ @@ -1035,7 +1035,7 @@ void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ) if (!save->vertex_store) save->vertex_store = alloc_vertex_store( ctx ); - save->vbptr = map_vertex_store( ctx, save->vertex_store ); + save->buffer_ptr = map_vertex_store( ctx, save->vertex_store ); _save_reset_vertex( ctx ); _save_reset_counters( ctx ); |