summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-03-03 11:51:14 +0000
committerKeith Whitwell <[email protected]>2009-03-03 11:51:14 +0000
commit916de35d677ca5238e9515840fa5aa9f81302c5b (patch)
tree73a8a2443c3de43d253a38528335e39b40b391dc /src
parent72cf6e8e92e49753472e760b1cf4575327b48f43 (diff)
parent2785af803f7d6d64ff17c10645e5f10499289ed0 (diff)
Merge commit 'origin/gallium-0.1'
Conflicts: scons/gallium.py src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c src/gallium/include/pipe/p_defines.h src/mesa/vbo/vbo_exec_api.c src/mesa/vbo/vbo_exec_draw.c
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c73
-rw-r--r--src/gallium/include/pipe/p_defines.h1
-rw-r--r--src/mesa/main/dd.h32
-rw-r--r--src/mesa/main/vtxfmt.c9
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c35
-rw-r--r--src/mesa/vbo/vbo_exec.c1
-rw-r--r--src/mesa/vbo/vbo_exec.h15
-rw-r--r--src/mesa/vbo/vbo_exec_api.c73
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c118
-rw-r--r--src/mesa/vbo/vbo_save.h2
-rw-r--r--src/mesa/vbo/vbo_save_api.c16
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 );