diff --git a/src/gallium/auxiliary/driver_noop/noop_pipe.c b/src/gallium/auxiliary/driver_noop/noop_pipe.c index c737b756ccb..4a20c735e9f 100644 --- a/src/gallium/auxiliary/driver_noop/noop_pipe.c +++ b/src/gallium/auxiliary/driver_noop/noop_pipe.c @@ -743,6 +743,15 @@ static void noop_vertex_state_destroy(struct pipe_screen *screen, FREE(state); } +static void noop_set_fence_timeline_value(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + uint64_t value) +{ + struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen *)screen; + struct pipe_screen *oscreen = noop_screen->oscreen; + oscreen->set_fence_timeline_value(oscreen, fence, value); +} + struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) { struct noop_pipe_screen *noop_screen; @@ -800,6 +809,8 @@ struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) screen->vertex_state_destroy = noop_vertex_state_destroy; if (oscreen->get_sparse_texture_virtual_page_size) screen->get_sparse_texture_virtual_page_size = noop_get_sparse_texture_virtual_page_size; + if (oscreen->set_fence_timeline_value) + screen->set_fence_timeline_value = noop_set_fence_timeline_value; slab_create_parent(&noop_screen->pool_transfers, sizeof(struct pipe_transfer), 64); diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.c b/src/gallium/auxiliary/driver_trace/tr_screen.c index b2f302ed477..d964b42b0ad 100644 --- a/src/gallium/auxiliary/driver_trace/tr_screen.c +++ b/src/gallium/auxiliary/driver_trace/tr_screen.c @@ -1332,6 +1332,22 @@ static void trace_screen_vertex_state_destroy(struct pipe_screen *_screen, screen->vertex_state_destroy(screen, state); } +static void trace_screen_set_fence_timeline_value(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + uint64_t value) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin("pipe_screen", "set_fence_timeline_value"); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, fence); + trace_dump_arg(uint, value); + trace_dump_call_end(); + + screen->set_fence_timeline_value(screen, fence, value); +} + bool trace_enabled(void) { @@ -1436,6 +1452,7 @@ trace_screen_create(struct pipe_screen *screen) SCR_INIT(vertex_state_destroy); tr_scr->base.transfer_helper = screen->transfer_helper; SCR_INIT(get_sparse_texture_virtual_page_size); + SCR_INIT(set_fence_timeline_value); tr_scr->screen = screen; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 5848183417b..596319426e2 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -724,6 +724,14 @@ struct pipe_screen { */ pipe_create_vertex_state_func create_vertex_state; pipe_vertex_state_destroy_func vertex_state_destroy; + + /** + * Update a timeline semaphore value stored within a driver fence object. + * Future waits and signals will use the new value. + */ + void (*set_fence_timeline_value)(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + uint64_t value); }; diff --git a/src/mesa/main/externalobjects.c b/src/mesa/main/externalobjects.c index 02ed37f4fb1..13dbbcf045b 100644 --- a/src/mesa/main/externalobjects.c +++ b/src/mesa/main/externalobjects.c @@ -855,15 +855,6 @@ _mesa_IsSemaphoreEXT(GLuint semaphore) static void semaphore_parameter_stub(const char* func, GLenum pname) { - GET_CURRENT_CONTEXT(ctx); - - if (!ctx->Extensions.EXT_semaphore) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); - return; - } - - /* EXT_semaphore and EXT_semaphore_fd define no parameters */ - _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); } void GLAPIENTRY @@ -871,9 +862,31 @@ _mesa_SemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, const GLuint64 *params) { + GET_CURRENT_CONTEXT(ctx); const char *func = "glSemaphoreParameterui64vEXT"; - semaphore_parameter_stub(func, pname); + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (pname != GL_D3D12_FENCE_VALUE_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); + return; + } + + struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, + semaphore); + if (!semObj) + return; + + if (semObj->type != PIPE_FD_TYPE_TIMELINE_SEMAPHORE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(Not a D3D12 fence)", func); + return; + } + + semObj->timeline_value = params[0]; + ctx->screen->set_fence_timeline_value(ctx->screen, semObj->fence, params[0]); } void GLAPIENTRY @@ -881,9 +894,30 @@ _mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params) { + GET_CURRENT_CONTEXT(ctx); const char *func = "glGetSemaphoreParameterui64vEXT"; - semaphore_parameter_stub(func, pname); + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (pname != GL_D3D12_FENCE_VALUE_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); + return; + } + + struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, + semaphore); + if (!semObj) + return; + + if (semObj->type != PIPE_FD_TYPE_TIMELINE_SEMAPHORE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(Not a D3D12 fence)", func); + return; + } + + params[0] = semObj->timeline_value; } void GLAPIENTRY diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index e99093d349e..ba43cea3009 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3070,6 +3070,7 @@ struct gl_semaphore_object GLuint Name; /**< hash table ID/name */ struct pipe_fence_handle *fence; enum pipe_fd_type type; + uint64_t timeline_value; }; /**