From ce04fbf67c9ded75a206c9560a3869df76a46839 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 3 Jul 2019 18:51:24 -0400 Subject: [PATCH] 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. --- src/mesa/state_tracker/st_cb_bufferobjects.c | 27 +++++++++++++++----- 1 file 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); -- 2.30.2