diff options
author | Marek Olšák <[email protected]> | 2019-07-03 18:51:24 -0400 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2019-07-15 14:58:23 -0400 |
commit | ce04fbf67c9ded75a206c9560a3869df76a46839 (patch) | |
tree | 8fe3a9402b63361405a2380afddbc48db49f00f5 /src/mesa | |
parent | fc4302d1dfe4fe724df250d0de1fcf0f60953c99 (diff) |
st/mesa: don't invalidate a buffer range that is mapped
This is needed to fix an issue with OpenGL when a buffer is mapped and
BufferSubData is called. In this case, we can't invalidate the buffer range.
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/state_tracker/st_cb_bufferobjects.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 080dcccba0b..6b54aa67583 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -131,10 +131,16 @@ st_bufferobj_subdata(struct gl_context *ctx, * even if the buffer is currently referenced by hardware - they * just queue the upload as dma rather than mapping the underlying * buffer directly. + * + * If the buffer is mapped, suppress implicit buffer range invalidation + * by using PIPE_TRANSFER_MAP_DIRECTLY. */ - pipe_buffer_write(st_context(ctx)->pipe, - st_obj->buffer, - offset, size, data); + struct pipe_context *pipe = st_context(ctx)->pipe; + + pipe->buffer_subdata(pipe, st_obj->buffer, + _mesa_bufferobj_mapped(obj, MAP_USER) ? + PIPE_TRANSFER_MAP_DIRECTLY : 0, + offset, size, data); } @@ -283,6 +289,7 @@ bufferobj_data(struct gl_context *ctx, struct pipe_screen *screen = pipe->screen; struct st_buffer_object *st_obj = st_buffer_object(obj); struct st_memory_object *st_mem_obj = st_memory_object(memObj); + bool is_mapped = _mesa_bufferobj_mapped(obj, MAP_USER); if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD && size && st_obj->buffer && @@ -293,11 +300,19 @@ bufferobj_data(struct gl_context *ctx, /* Just discard the old contents and write new data. * This should be the same as creating a new buffer, but we avoid * a lot of validation in Mesa. + * + * If the buffer is mapped, we can't discard it. + * + * PIPE_TRANSFER_MAP_DIRECTLY supresses implicit buffer range + * invalidation. */ pipe->buffer_subdata(pipe, st_obj->buffer, - PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE, + is_mapped ? PIPE_TRANSFER_MAP_DIRECTLY : + PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE, 0, size, data); return GL_TRUE; + } else if (is_mapped) { + return GL_TRUE; /* can't reallocate, nothing to do */ } else if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER)) { pipe->invalidate_resource(pipe, st_obj->buffer); return GL_TRUE; @@ -422,8 +437,8 @@ st_bufferobj_invalidate(struct gl_context *ctx, if (offset != 0 || size != obj->Size) return; - /* Nothing to invalidate. */ - if (!st_obj->buffer) + /* If the buffer is mapped, we can't invalidate it. */ + if (!st_obj->buffer || _mesa_bufferobj_mapped(obj, MAP_USER)) return; pipe->invalidate_resource(pipe, st_obj->buffer); |