summaryrefslogtreecommitdiffstats
path: root/src/mesa/vbo
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2014-02-06 19:24:23 +0100
committerMarek Olšák <[email protected]>2014-02-25 16:07:33 +0100
commitdca350201e00c7cf1cfb009158f4abf27fbc96d2 (patch)
tree8e331dfaa4ab2b623ee559f14fb1f678be6ba5df /src/mesa/vbo
parent86e68b0f1f7f5ff58b38653978acaa736ae3d01c (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/vbo')
-rw-r--r--src/mesa/vbo/vbo_exec_api.c4
-rw-r--r--src/mesa/vbo/vbo_exec_array.c36
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c22
-rw-r--r--src/mesa/vbo/vbo_primitive_restart.c17
-rw-r--r--src/mesa/vbo/vbo_rebase.c9
-rw-r--r--src/mesa/vbo/vbo_save_api.c15
-rw-r--r--src/mesa/vbo/vbo_save_draw.c6
-rw-r--r--src/mesa/vbo/vbo_split_copy.c28
8 files changed, 81 insertions, 56 deletions
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 9858badebf1..74aec127c5c 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -1118,8 +1118,8 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
/* Free the vertex buffer. Unmap first if needed.
*/
- if (_mesa_bufferobj_mapped(exec->vtx.bufferobj)) {
- ctx->Driver.UnmapBuffer(ctx, exec->vtx.bufferobj);
+ if (_mesa_bufferobj_mapped(exec->vtx.bufferobj, MAP_INTERNAL)) {
+ ctx->Driver.UnmapBuffer(ctx, exec->vtx.bufferobj, MAP_INTERNAL);
}
_mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
}
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 32e1458bd2b..07ce08feff9 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -101,7 +101,8 @@ vbo_get_minmax_index(struct gl_context *ctx,
if (_mesa_is_bufferobj(ib->obj)) {
GLsizeiptr size = MIN2(count * index_size, ib->obj->Size);
indices = ctx->Driver.MapBufferRange(ctx, (GLintptr) indices, size,
- GL_MAP_READ_BIT, ib->obj);
+ GL_MAP_READ_BIT, ib->obj,
+ MAP_INTERNAL);
}
switch (ib->type) {
@@ -177,7 +178,7 @@ vbo_get_minmax_index(struct gl_context *ctx,
}
if (_mesa_is_bufferobj(ib->obj)) {
- ctx->Driver.UnmapBuffer(ctx, ib->obj);
+ ctx->Driver.UnmapBuffer(ctx, ib->obj, MAP_INTERNAL);
}
}
@@ -229,13 +230,15 @@ check_array_data(struct gl_context *ctx, struct gl_client_array *array,
if (array->Enabled) {
const void *data = array->Ptr;
if (_mesa_is_bufferobj(array->BufferObj)) {
- if (!array->BufferObj->Pointer) {
+ if (!array->BufferObj->Mappings[MAP_INTERNAL].Pointer) {
/* need to map now */
- array->BufferObj->Pointer =
+ array->BufferObj->Mappings[MAP_INTERNAL].Pointer =
ctx->Driver.MapBufferRange(ctx, 0, array->BufferObj->Size,
- GL_MAP_READ_BIT, array->BufferObj);
+ GL_MAP_READ_BIT, array->BufferObj,
+ MAP_INTERNAL);
}
- data = ADD_POINTERS(data, array->BufferObj->Pointer);
+ data = ADD_POINTERS(data,
+ array->BufferObj->Mappings[MAP_INTERNAL].Pointer);
}
switch (array->Type) {
case GL_FLOAT:
@@ -273,8 +276,8 @@ unmap_array_buffer(struct gl_context *ctx, struct gl_client_array *array)
{
if (array->Enabled &&
_mesa_is_bufferobj(array->BufferObj) &&
- _mesa_bufferobj_mapped(array->BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, array->BufferObj);
+ _mesa_bufferobj_mapped(array->BufferObj, MAP_INTERNAL)) {
+ ctx->Driver.UnmapBuffer(ctx, array->BufferObj, MAP_INTERNAL);
}
}
@@ -295,7 +298,8 @@ check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType,
elemMap = ctx->Driver.MapBufferRange(ctx, 0,
ctx->Array.VAO->IndexBufferObj->Size,
GL_MAP_READ_BIT,
- ctx->Array.VAO->IndexBufferObj);
+ ctx->Array.VAO->IndexBufferObj,
+ MAP_INTERNAL);
elements = ADD_POINTERS(elements, elemMap);
}
@@ -324,7 +328,8 @@ check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType,
}
if (_mesa_is_bufferobj(vao->IndexBufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj);
+ ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj,
+ MAP_INTERNAL);
}
for (k = 0; k < Elements(vao->_VertexAttrib); k++) {
@@ -374,7 +379,8 @@ print_draw_arrays(struct gl_context *ctx,
if (bufName) {
GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size,
- GL_MAP_READ_BIT, bufObj);
+ GL_MAP_READ_BIT, bufObj,
+ MAP_INTERNAL);
int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr;
float *f = (float *) (p + offset);
int *k = (int *) f;
@@ -386,7 +392,7 @@ print_draw_arrays(struct gl_context *ctx,
for (i = 0; i < n; i++) {
printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]);
}
- ctx->Driver.UnmapBuffer(ctx, bufObj);
+ ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL);
}
}
}
@@ -885,7 +891,8 @@ dump_element_buffer(struct gl_context *ctx, GLenum type)
ctx->Driver.MapBufferRange(ctx, 0,
ctx->Array.VAO->IndexBufferObj->Size,
GL_MAP_READ_BIT,
- ctx->Array.VAO->IndexBufferObj);
+ ctx->Array.VAO->IndexBufferObj,
+ MAP_INTERNAL);
switch (type) {
case GL_UNSIGNED_BYTE:
{
@@ -927,7 +934,8 @@ dump_element_buffer(struct gl_context *ctx, GLenum type)
;
}
- ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj);
+ ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj,
+ MAP_INTERNAL);
}
#endif
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 46be65fc010..c454c6943b4 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -220,9 +220,10 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
/* a real buffer obj: Ptr is an offset, not a pointer*/
- assert(exec->vtx.bufferobj->Pointer); /* buf should be mapped */
+ assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer);
assert(offset >= 0);
- arrays[attr].Ptr = (GLubyte *)exec->vtx.bufferobj->Offset + offset;
+ arrays[attr].Ptr = (GLubyte *)
+ exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset + offset;
}
else {
/* Ptr into ordinary app memory */
@@ -261,12 +262,15 @@ vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
struct gl_context *ctx = exec->ctx;
if (ctx->Driver.FlushMappedBufferRange) {
- GLintptr offset = exec->vtx.buffer_used - exec->vtx.bufferobj->Offset;
- GLsizeiptr length = (exec->vtx.buffer_ptr - exec->vtx.buffer_map) * sizeof(float);
+ GLintptr offset = exec->vtx.buffer_used -
+ exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset;
+ GLsizeiptr length = (exec->vtx.buffer_ptr - exec->vtx.buffer_map) *
+ sizeof(float);
if (length)
ctx->Driver.FlushMappedBufferRange(ctx, offset, length,
- exec->vtx.bufferobj);
+ exec->vtx.bufferobj,
+ MAP_INTERNAL);
}
exec->vtx.buffer_used += (exec->vtx.buffer_ptr -
@@ -275,7 +279,7 @@ vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
assert(exec->vtx.buffer_used <= VBO_VERT_BUFFER_SIZE);
assert(exec->vtx.buffer_ptr != NULL);
- ctx->Driver.UnmapBuffer(ctx, exec->vtx.bufferobj);
+ ctx->Driver.UnmapBuffer(ctx, exec->vtx.bufferobj, MAP_INTERNAL);
exec->vtx.buffer_map = NULL;
exec->vtx.buffer_ptr = NULL;
exec->vtx.max_vert = 0;
@@ -312,7 +316,8 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec )
(VBO_VERT_BUFFER_SIZE -
exec->vtx.buffer_used),
accessRange,
- exec->vtx.bufferobj);
+ exec->vtx.bufferobj,
+ MAP_INTERNAL);
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
}
else {
@@ -336,7 +341,8 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec )
(GLfloat *)ctx->Driver.MapBufferRange(ctx,
0, VBO_VERT_BUFFER_SIZE,
accessRange,
- exec->vtx.bufferobj);
+ exec->vtx.bufferobj,
+ MAP_INTERNAL);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "VBO allocation");
diff --git a/src/mesa/vbo/vbo_primitive_restart.c b/src/mesa/vbo/vbo_primitive_restart.c
index 9c30554314c..25c89669ccf 100644
--- a/src/mesa/vbo/vbo_primitive_restart.c
+++ b/src/mesa/vbo/vbo_primitive_restart.c
@@ -177,7 +177,7 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
struct _mesa_prim temp_prim;
struct vbo_context *vbo = vbo_context(ctx);
vbo_draw_func draw_prims_func = vbo->draw_prims;
- GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;
+ GLboolean map_ib = ib->obj->Name && !ib->obj->Mappings[MAP_INTERNAL].Pointer;
void *ptr;
/* If there is an indirect buffer, map it and extract the draw params */
@@ -186,7 +186,7 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
struct _mesa_index_buffer new_ib = *ib;
const uint32_t *indirect_params;
if (!ctx->Driver.MapBufferRange(ctx, 0, indirect->Size, GL_MAP_READ_BIT,
- indirect)) {
+ indirect, MAP_INTERNAL)) {
/* something went wrong with mapping, give up */
_mesa_error(ctx, GL_OUT_OF_MEMORY,
@@ -195,8 +195,9 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
}
assert(nr_prims == 1);
- indirect_params = (const uint32_t *) ADD_POINTERS(indirect->Pointer,
- new_prim.indirect_offset);
+ indirect_params = (const uint32_t *)
+ ADD_POINTERS(indirect->Mappings[MAP_INTERNAL].Pointer,
+ new_prim.indirect_offset);
new_prim.is_indirect = 0;
new_prim.count = indirect_params[0];
@@ -210,7 +211,7 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
prims = &new_prim;
ib = &new_ib;
- ctx->Driver.UnmapBuffer(ctx, indirect);
+ ctx->Driver.UnmapBuffer(ctx, indirect, MAP_INTERNAL);
}
/* Find the sub-primitives. These are regions in the index buffer which
@@ -218,17 +219,17 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
*/
if (map_ib) {
ctx->Driver.MapBufferRange(ctx, 0, ib->obj->Size, GL_MAP_READ_BIT,
- ib->obj);
+ ib->obj, MAP_INTERNAL);
}
- ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
+ ptr = ADD_POINTERS(ib->obj->Mappings[MAP_INTERNAL].Pointer, ib->ptr);
sub_prims = find_sub_primitives(ptr, vbo_sizeof_ib_type(ib->type),
0, ib->count, restart_index,
&num_sub_prims);
if (map_ib) {
- ctx->Driver.UnmapBuffer(ctx, ib->obj);
+ ctx->Driver.UnmapBuffer(ctx, ib->obj, MAP_INTERNAL);
}
/* Loop over the primitives, and use the located sub-primitives to draw
diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c
index c700621cef2..f3fe5f75708 100644
--- a/src/mesa/vbo/vbo_rebase.c
+++ b/src/mesa/vbo/vbo_rebase.c
@@ -157,15 +157,16 @@ void vbo_rebase_prims( struct gl_context *ctx,
} else if (ib) {
/* Unfortunately need to adjust each index individually.
*/
- GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;
+ GLboolean map_ib = ib->obj->Name &&
+ !ib->obj->Mappings[MAP_INTERNAL].Pointer;
void *ptr;
if (map_ib)
ctx->Driver.MapBufferRange(ctx, 0, ib->obj->Size, GL_MAP_READ_BIT,
- ib->obj);
+ ib->obj, MAP_INTERNAL);
- ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
+ ptr = ADD_POINTERS(ib->obj->Mappings[MAP_INTERNAL].Pointer, ib->ptr);
/* Some users might prefer it if we translated elements to
* GLuints here. Others wouldn't...
@@ -183,7 +184,7 @@ void vbo_rebase_prims( struct gl_context *ctx,
}
if (map_ib)
- ctx->Driver.UnmapBuffer(ctx, ib->obj);
+ ctx->Driver.UnmapBuffer(ctx, ib->obj, MAP_INTERNAL);
tmp_ib.obj = ctx->Shared->NullBufferObj;
tmp_ib.ptr = tmp_indices;
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index b86ced5bf89..1c6b91942d5 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -253,7 +253,8 @@ vbo_save_map_vertex_store(struct gl_context *ctx,
GLsizeiptr size = vertex_store->bufferobj->Size - offset;
GLfloat *range = (GLfloat *)
ctx->Driver.MapBufferRange(ctx, offset, size, access,
- vertex_store->bufferobj);
+ vertex_store->bufferobj,
+ MAP_INTERNAL);
if (range) {
/* compute address of start of whole buffer (needed elsewhere) */
vertex_store->buffer = range - vertex_store->used;
@@ -279,13 +280,14 @@ vbo_save_unmap_vertex_store(struct gl_context *ctx,
if (vertex_store->bufferobj->Size > 0) {
GLintptr offset = 0;
GLsizeiptr length = vertex_store->used * sizeof(GLfloat)
- - vertex_store->bufferobj->Offset;
+ - vertex_store->bufferobj->Mappings[MAP_INTERNAL].Offset;
/* Explicitly flush the region we wrote to */
ctx->Driver.FlushMappedBufferRange(ctx, offset, length,
- vertex_store->bufferobj);
+ vertex_store->bufferobj,
+ MAP_INTERNAL);
- ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj);
+ ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj, MAP_INTERNAL);
}
vertex_store->buffer = NULL;
}
@@ -1118,6 +1120,7 @@ _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
{
GET_CURRENT_CONTEXT(ctx);
struct vbo_save_context *save = &vbo_context(ctx)->save;
+ struct gl_buffer_object *indexbuf = ctx->Array.VAO->IndexBufferObj;
GLint i;
if (!_mesa_is_valid_prim_mode(ctx, mode)) {
@@ -1140,9 +1143,9 @@ _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
_ae_map_vbos(ctx);
- if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj))
+ if (_mesa_is_bufferobj(indexbuf))
indices =
- ADD_POINTERS(ctx->Array.VAO->IndexBufferObj->Pointer, indices);
+ ADD_POINTERS(indexbuf->Mappings[MAP_INTERNAL].Pointer, indices);
vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK |
VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 4b13cc4e5d0..89fd30e0fb1 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -225,7 +225,8 @@ vbo_save_loopback_vertex_list(struct gl_context *ctx,
ctx->Driver.MapBufferRange(ctx, 0,
list->vertex_store->bufferobj->Size,
GL_MAP_READ_BIT, /* ? */
- list->vertex_store->bufferobj);
+ list->vertex_store->bufferobj,
+ MAP_INTERNAL);
vbo_loopback_vertex_list(ctx,
(const GLfloat *)(buffer + list->buffer_offset),
@@ -235,7 +236,8 @@ vbo_save_loopback_vertex_list(struct gl_context *ctx,
list->wrap_count,
list->vertex_size);
- ctx->Driver.UnmapBuffer(ctx, list->vertex_store->bufferobj);
+ ctx->Driver.UnmapBuffer(ctx, list->vertex_store->bufferobj,
+ MAP_INTERNAL);
}
diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c
index 4332ef2e6d7..719ad651a89 100644
--- a/src/mesa/vbo/vbo_split_copy.c
+++ b/src/mesa/vbo/vbo_split_copy.c
@@ -451,11 +451,14 @@ replay_init( struct copy_context *copy )
copy->varying[j].size = attr_size(copy->array[i]);
copy->vertex_size += attr_size(copy->array[i]);
- if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo))
- ctx->Driver.MapBufferRange(ctx, 0, vbo->Size, GL_MAP_READ_BIT, vbo);
+ if (_mesa_is_bufferobj(vbo) &&
+ !_mesa_bufferobj_mapped(vbo, MAP_INTERNAL))
+ ctx->Driver.MapBufferRange(ctx, 0, vbo->Size, GL_MAP_READ_BIT, vbo,
+ MAP_INTERNAL);
- copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer,
- copy->array[i]->Ptr);
+ copy->varying[j].src_ptr =
+ ADD_POINTERS(vbo->Mappings[MAP_INTERNAL].Pointer,
+ copy->array[i]->Ptr);
copy->dstarray_ptr[i] = &copy->varying[j].dstarray;
}
@@ -466,12 +469,13 @@ replay_init( struct copy_context *copy )
* do it internally.
*/
if (_mesa_is_bufferobj(copy->ib->obj) &&
- !_mesa_bufferobj_mapped(copy->ib->obj))
+ !_mesa_bufferobj_mapped(copy->ib->obj, MAP_INTERNAL))
ctx->Driver.MapBufferRange(ctx, 0, copy->ib->obj->Size, GL_MAP_READ_BIT,
- copy->ib->obj);
+ copy->ib->obj, MAP_INTERNAL);
- srcptr = (const GLubyte *) ADD_POINTERS(copy->ib->obj->Pointer,
- copy->ib->ptr);
+ srcptr = (const GLubyte *)
+ ADD_POINTERS(copy->ib->obj->Mappings[MAP_INTERNAL].Pointer,
+ copy->ib->ptr);
switch (copy->ib->type) {
case GL_UNSIGNED_BYTE:
@@ -572,15 +576,15 @@ replay_finish( struct copy_context *copy )
*/
for (i = 0; i < copy->nr_varying; i++) {
struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj;
- if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo))
- ctx->Driver.UnmapBuffer(ctx, vbo);
+ if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo, MAP_INTERNAL))
+ ctx->Driver.UnmapBuffer(ctx, vbo, MAP_INTERNAL);
}
/* Unmap index buffer:
*/
if (_mesa_is_bufferobj(copy->ib->obj) &&
- _mesa_bufferobj_mapped(copy->ib->obj)) {
- ctx->Driver.UnmapBuffer(ctx, copy->ib->obj);
+ _mesa_bufferobj_mapped(copy->ib->obj, MAP_INTERNAL)) {
+ ctx->Driver.UnmapBuffer(ctx, copy->ib->obj, MAP_INTERNAL);
}
}