diff options
author | Marek Olšák <[email protected]> | 2014-02-06 19:24:23 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2014-02-25 16:07:33 +0100 |
commit | dca350201e00c7cf1cfb009158f4abf27fbc96d2 (patch) | |
tree | 8e331dfaa4ab2b623ee559f14fb1f678be6ba5df /src/mesa/state_tracker | |
parent | 86e68b0f1f7f5ff58b38653978acaa736ae3d01c (diff) |
mesa: allow buffers to be mapped multiple times
OpenGL allows a buffer to be mapped only once, but we also map buffers
internally, e.g. in the software primitive restart fallback, for PBOs,
vbo_get_minmax_index, etc. This has always been a problem, but it will
be a bigger problem with persistent buffer mappings, which will prevent
all Mesa functions from mapping buffers for internal purposes.
This adds a driver interface to core Mesa which supports multiple buffer
mappings and allows 2 mappings: one for the GL user and one for Mesa.
Note that Gallium supports an unlimited number of buffer and texture
mappings, so it's not really an issue for Gallium.
v2: fix unmapping in xm_dd.c, remove the GL errors there
v3: fix the intel driver (by Fredrik)
Reviewed-by: Fredrik Höglund <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_cb_bufferobjects.c | 48 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_bufferobjects.h | 2 |
2 files changed, 27 insertions, 23 deletions
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index bf4c71f721e..49c4b903e59 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -76,7 +76,7 @@ st_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj) struct st_buffer_object *st_obj = st_buffer_object(obj); assert(obj->RefCount == 0); - assert(st_obj->transfer == NULL); + _mesa_buffer_unmap_all_mappings(ctx, obj); if (st_obj->buffer) pipe_resource_reference(&st_obj->buffer, NULL); @@ -310,7 +310,8 @@ st_bufferobj_data(struct gl_context *ctx, static void * st_bufferobj_map_range(struct gl_context *ctx, GLintptr offset, GLsizeiptr length, GLbitfield access, - struct gl_buffer_object *obj) + struct gl_buffer_object *obj, + gl_map_buffer_index index) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); @@ -355,28 +356,29 @@ st_bufferobj_map_range(struct gl_context *ctx, assert(offset < obj->Size); assert(offset + length <= obj->Size); - obj->Pointer = pipe_buffer_map_range(pipe, + obj->Mappings[index].Pointer = pipe_buffer_map_range(pipe, st_obj->buffer, offset, length, flags, - &st_obj->transfer); - if (obj->Pointer) { - obj->Offset = offset; - obj->Length = length; - obj->AccessFlags = access; + &st_obj->transfer[index]); + if (obj->Mappings[index].Pointer) { + obj->Mappings[index].Offset = offset; + obj->Mappings[index].Length = length; + obj->Mappings[index].AccessFlags = access; } else { - st_obj->transfer = NULL; + st_obj->transfer[index] = NULL; } - return obj->Pointer; + return obj->Mappings[index].Pointer; } static void st_bufferobj_flush_mapped_range(struct gl_context *ctx, GLintptr offset, GLsizeiptr length, - struct gl_buffer_object *obj) + struct gl_buffer_object *obj, + gl_map_buffer_index index) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); @@ -384,14 +386,15 @@ st_bufferobj_flush_mapped_range(struct gl_context *ctx, /* Subrange is relative to mapped range */ assert(offset >= 0); assert(length >= 0); - assert(offset + length <= obj->Length); - assert(obj->Pointer); + assert(offset + length <= obj->Mappings[index].Length); + assert(obj->Mappings[index].Pointer); if (!length) return; - pipe_buffer_flush_mapped_range(pipe, st_obj->transfer, - obj->Offset + offset, length); + pipe_buffer_flush_mapped_range(pipe, st_obj->transfer[index], + obj->Mappings[index].Offset + offset, + length); } @@ -399,18 +402,19 @@ st_bufferobj_flush_mapped_range(struct gl_context *ctx, * Called via glUnmapBufferARB(). */ static GLboolean -st_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj) +st_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj, + gl_map_buffer_index index) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); - if (obj->Length) - pipe_buffer_unmap(pipe, st_obj->transfer); + if (obj->Mappings[index].Length) + pipe_buffer_unmap(pipe, st_obj->transfer[index]); - st_obj->transfer = NULL; - obj->Pointer = NULL; - obj->Offset = 0; - obj->Length = 0; + st_obj->transfer[index] = NULL; + obj->Mappings[index].Pointer = NULL; + obj->Mappings[index].Offset = 0; + obj->Mappings[index].Length = 0; return GL_TRUE; } diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.h b/src/mesa/state_tracker/st_cb_bufferobjects.h index a039c0a5059..a5ab122190a 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.h +++ b/src/mesa/state_tracker/st_cb_bufferobjects.h @@ -43,7 +43,7 @@ struct st_buffer_object { struct gl_buffer_object Base; struct pipe_resource *buffer; /* GPU storage */ - struct pipe_transfer *transfer; /* In-progress map information */ + struct pipe_transfer *transfer[MAP_COUNT]; }; |