diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index d7465b7..ccb28e5 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -3956,10 +3956,8 @@ _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset, return; } - /* We don't actually do anything for this yet. Just return after - * validating the parameters and generating the required errors. - */ - return; + if (ctx->Driver.InvalidateBufferSubData) + ctx->Driver.InvalidateBufferSubData(ctx, bufObj, offset, length); } void GLAPIENTRY @@ -3990,8 +3988,6 @@ _mesa_InvalidateBufferData(GLuint buffer) return; } - /* We don't actually do anything for this yet. Just return after - * validating the parameters and generating the required errors. - */ - return; + if (ctx->Driver.InvalidateBufferSubData) + ctx->Driver.InvalidateBufferSubData(ctx, bufObj, 0, bufObj->Size); } diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index e5281ce..70ed563 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -634,6 +634,11 @@ struct dd_function_table { GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size ); + void (*InvalidateBufferSubData)( struct gl_context *ctx, + struct gl_buffer_object *obj, + GLintptr offset, + GLsizeiptr length ); + /* Returns pointer to the start of the mapped range. * May return NULL if MESA_MAP_NOWAIT_BIT is set in access: */ diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 8ca7e4c..58c862d 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -328,6 +328,40 @@ st_bufferobj_data(struct gl_context *ctx, /** + * Called via glInvalidateBuffer[SubData]. + */ +static void +st_bufferobj_invalidate(struct gl_context *ctx, + struct gl_buffer_object *obj, + GLintptr offset, + GLsizeiptr size) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; + struct st_buffer_object *st_obj = st_buffer_object(obj); + struct pipe_resource *buffer; + + /* We ignore partial invalidates. */ + if (offset != 0 || size != obj->Size) + return; + + /* Nothing to invalidate. */ + if (!st_obj->buffer) + return; + + /* Allocate a new buffer. XXX this may be wasteful, is there a better way? */ + /* XXX - check interaction with GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD */ + buffer = screen->resource_create(screen, st_obj->buffer); + if (!buffer) + return; + + pipe_resource_reference(&st_obj->buffer, buffer); + pipe_resource_reference(&buffer, NULL); +} + + +/** * Called via glMapBufferRange(). */ static void * @@ -520,6 +554,7 @@ st_init_bufferobject_functions(struct dd_function_table *functions) functions->NewBufferObject = st_bufferobj_alloc; functions->DeleteBuffer = st_bufferobj_free; functions->BufferData = st_bufferobj_data; + functions->InvalidateBufferSubData = st_bufferobj_invalidate; functions->BufferSubData = st_bufferobj_subdata; functions->GetBufferSubData = st_bufferobj_get_subdata; functions->MapBufferRange = st_bufferobj_map_range;