diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 8216752ccaf..7a39f939c97 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1156,14 +1156,24 @@ struct dd_function_table { * server's command stream */ void (*ServerWaitSemaphoreObject)(struct gl_context *ctx, - struct gl_semaphore_object *semObj); + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *srcLayouts); /** * Introduce an operation to signal the semaphore object in the GL * server's command stream */ void (*ServerSignalSemaphoreObject)(struct gl_context *ctx, - struct gl_semaphore_object *semObj); + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *dstLayouts); /*@}*/ /** diff --git a/src/mesa/main/externalobjects.c b/src/mesa/main/externalobjects.c index 9ba70c8e7f8..8f31ba4c354 100644 --- a/src/mesa/main/externalobjects.c +++ b/src/mesa/main/externalobjects.c @@ -23,6 +23,7 @@ #include "macros.h" #include "mtypes.h" +#include "bufferobj.h" #include "context.h" #include "externalobjects.h" #include "teximage.h" @@ -716,7 +717,8 @@ _mesa_WaitSemaphoreEXT(GLuint semaphore, { GET_CURRENT_CONTEXT(ctx); struct gl_semaphore_object *semObj; - + struct gl_buffer_object **bufObjs; + struct gl_texture_object **texObjs; if (!ctx->Extensions.EXT_semaphore) { _mesa_error(ctx, GL_INVALID_OPERATION, "glWaitSemaphoreEXT(unsupported)"); @@ -732,8 +734,20 @@ _mesa_WaitSemaphoreEXT(GLuint semaphore, FLUSH_VERTICES(ctx, 0); FLUSH_CURRENT(ctx, 0); - /* TODO: memory barriers and layout transitions */ - ctx->Driver.ServerWaitSemaphoreObject(ctx, semObj); + bufObjs = alloca(sizeof(struct gl_buffer_object **) * numBufferBarriers); + for (unsigned i = 0; i < numBufferBarriers; i++) { + bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]); + } + + texObjs = alloca(sizeof(struct gl_texture_object **) * numTextureBarriers); + for (unsigned i = 0; i < numTextureBarriers; i++) { + texObjs[i] = _mesa_lookup_texture(ctx, textures[i]); + } + + ctx->Driver.ServerWaitSemaphoreObject(ctx, semObj, + numBufferBarriers, bufObjs, + numTextureBarriers, texObjs, + srcLayouts); } void GLAPIENTRY @@ -746,6 +760,8 @@ _mesa_SignalSemaphoreEXT(GLuint semaphore, { GET_CURRENT_CONTEXT(ctx); struct gl_semaphore_object *semObj; + struct gl_buffer_object **bufObjs; + struct gl_texture_object **texObjs; if (!ctx->Extensions.EXT_semaphore) { _mesa_error(ctx, GL_INVALID_OPERATION, "glSignalSemaphoreEXT(unsupported)"); @@ -761,8 +777,20 @@ _mesa_SignalSemaphoreEXT(GLuint semaphore, FLUSH_VERTICES(ctx, 0); FLUSH_CURRENT(ctx, 0); - /* TODO: memory barriers and layout transitions */ - ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj); + bufObjs = alloca(sizeof(struct gl_buffer_object **) * numBufferBarriers); + for (unsigned i = 0; i < numBufferBarriers; i++) { + bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]); + } + + texObjs = alloca(sizeof(struct gl_texture_object **) * numTextureBarriers); + for (unsigned i = 0; i < numTextureBarriers; i++) { + texObjs[i] = _mesa_lookup_texture(ctx, textures[i]); + } + + ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj, + numBufferBarriers, bufObjs, + numTextureBarriers, texObjs, + dstLayouts); } void GLAPIENTRY diff --git a/src/mesa/state_tracker/st_cb_semaphoreobjects.c b/src/mesa/state_tracker/st_cb_semaphoreobjects.c index 0661e65eff8..4a3faf57538 100644 --- a/src/mesa/state_tracker/st_cb_semaphoreobjects.c +++ b/src/mesa/state_tracker/st_cb_semaphoreobjects.c @@ -23,10 +23,14 @@ #include "main/imports.h" #include "main/mtypes.h" +#include "main/context.h" #include "main/externalobjects.h" #include "st_context.h" +#include "st_texture.h" +#include "st_cb_bitmap.h" +#include "st_cb_bufferobjects.h" #include "st_cb_semaphoreobjects.h" #include "state_tracker/drm_driver.h" @@ -69,10 +73,95 @@ st_import_semaphoreobj_fd(struct gl_context *ctx, #endif } +static void +st_server_wait_semaphore(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *srcLayouts) +{ + struct st_semaphore_object *st_obj = st_semaphore_object(semObj); + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + struct st_buffer_object *bufObj; + struct st_texture_object *texObj; + + /* The driver is allowed to flush during fence_server_sync, be prepared */ + st_flush_bitmap_cache(st); + pipe->fence_server_sync(pipe, st_obj->fence); + + /** + * According to the EXT_external_objects spec, the memory operations must + * follow the wait. This is to make sure the flush is executed after the + * other party is done modifying the memory. + * + * Relevant excerpt from section "4.2.3 Waiting for Semaphores": + * + * Following completion of the semaphore wait operation, memory will also be + * made visible in the specified buffer and texture objects. + * + */ + for (unsigned i = 0; i < numBufferBarriers; i++) { + if (!bufObjs[i]) + continue; + + bufObj = st_buffer_object(bufObjs[i]); + pipe->flush_resource(pipe, bufObj->buffer); + } + + for (unsigned i = 0; i < numTextureBarriers; i++) { + if (!texObjs[i]) + continue; + + texObj = st_texture_object(texObjs[i]); + pipe->flush_resource(pipe, texObj->pt); + } +} + +static void +st_server_signal_semaphore(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *dstLayouts) +{ + struct st_semaphore_object *st_obj = st_semaphore_object(semObj); + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + struct st_buffer_object *bufObj; + struct st_texture_object *texObj; + + for (unsigned i = 0; i < numBufferBarriers; i++) { + if (!bufObjs[i]) + continue; + + bufObj = st_buffer_object(bufObjs[i]); + pipe->flush_resource(pipe, bufObj->buffer); + } + + for (unsigned i = 0; i < numTextureBarriers; i++) { + if (!texObjs[i]) + continue; + + texObj = st_texture_object(texObjs[i]); + pipe->flush_resource(pipe, texObj->pt); + } + + /* The driver is allowed to flush during fence_server_signal, be prepared */ + st_flush_bitmap_cache(st); + pipe->fence_server_signal(pipe, st_obj->fence); +} + void st_init_semaphoreobject_functions(struct dd_function_table *functions) { functions->NewSemaphoreObject = st_semaphoreobj_alloc; functions->DeleteSemaphoreObject = st_semaphoreobj_free; functions->ImportSemaphoreFd = st_import_semaphoreobj_fd; + functions->ServerWaitSemaphoreObject = st_server_wait_semaphore; + functions->ServerSignalSemaphoreObject = st_server_signal_semaphore; }