From 0af7c1e385b94c4d3610c4bff4c3af8a1afb26c6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 9 Dec 2021 16:59:03 +1000 Subject: [PATCH] mesa/st: merge the syncobj code from st into mesa MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This merges all the syncobj code into the mesa from the state tracker. Acked-by: Marek Olšák Part-of: --- src/mesa/main/mtypes.h | 3 + src/mesa/main/syncobj.c | 107 ++++++++++++++++++++-- src/mesa/meson.build | 2 - src/mesa/state_tracker/st_cb_syncobj.c | 160 --------------------------------- src/mesa/state_tracker/st_cb_syncobj.h | 44 --------- 5 files changed, 103 insertions(+), 213 deletions(-) delete mode 100644 src/mesa/state_tracker/st_cb_syncobj.c delete mode 100644 src/mesa/state_tracker/st_cb_syncobj.h diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ab0db99..f4f9bfb 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2253,6 +2253,9 @@ struct gl_sync_object GLenum16 SyncCondition; GLbitfield Flags; /**< Flags passed to glFenceSync */ GLuint StatusFlag:1; /**< Has the sync object been signaled? */ + + struct pipe_fence_handle *fence; + simple_mtx_t mutex; /**< protects "fence" */ }; diff --git a/src/mesa/main/syncobj.c b/src/mesa/main/syncobj.c index 2c45ef6..968a1d5 100644 --- a/src/mesa/main/syncobj.c +++ b/src/mesa/main/syncobj.c @@ -71,6 +71,9 @@ #include "state_tracker/st_cb_syncobj.h" #include "api_exec_decl.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" + /** * Allocate/init the context state related to sync objects. */ @@ -90,6 +93,70 @@ _mesa_free_sync_data(struct gl_context *ctx) (void) ctx; } +static struct gl_sync_object * +new_sync_object(struct gl_context *ctx) +{ + struct gl_sync_object *so = CALLOC_STRUCT(gl_sync_object); + + simple_mtx_init(&so->mutex, mtx_plain); + return so; +} + +static void +delete_sync_object(struct gl_context *ctx, + struct gl_sync_object *obj) +{ + struct pipe_screen *screen = ctx->pipe->screen; + + screen->fence_reference(screen, &obj->fence, NULL); + simple_mtx_destroy(&obj->mutex); + free(obj->Label); + FREE(obj); +} + +static void +__client_wait_sync(struct gl_context *ctx, + struct gl_sync_object *obj, + GLbitfield flags, GLuint64 timeout) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_fence_handle *fence = NULL; + + /* If the fence doesn't exist, assume it's signalled. */ + simple_mtx_lock(&obj->mutex); + if (!obj->fence) { + simple_mtx_unlock(&obj->mutex); + obj->StatusFlag = GL_TRUE; + return; + } + + /* We need a local copy of the fence pointer, so that we can call + * fence_finish unlocked. + */ + screen->fence_reference(screen, &fence, obj->fence); + simple_mtx_unlock(&obj->mutex); + + /* Section 4.1.2 of OpenGL 4.5 (Compatibility Profile) says: + * [...] if ClientWaitSync is called and all of the following are true: + * - the SYNC_FLUSH_COMMANDS_BIT bit is set in flags, + * - sync is unsignaled when ClientWaitSync is called, + * - and the calls to ClientWaitSync and FenceSync were issued from + * the same context, + * then the GL will behave as if the equivalent of Flush were inserted + * immediately after the creation of sync. + * + * Assume GL_SYNC_FLUSH_COMMANDS_BIT is always set, because applications + * forget to set it. + */ + if (screen->fence_finish(screen, pipe, fence, timeout)) { + simple_mtx_lock(&obj->mutex); + screen->fence_reference(screen, &obj->fence, NULL); + simple_mtx_unlock(&obj->mutex); + obj->StatusFlag = GL_TRUE; + } + screen->fence_reference(screen, &fence, NULL); +} /** * Check if the given sync object is: @@ -137,7 +204,7 @@ _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj, _mesa_set_remove(ctx->Shared->SyncObjects, entry); simple_mtx_unlock(&ctx->Shared->Mutex); - st_delete_sync_object(ctx, syncObj); + delete_sync_object(ctx, syncObj); } else { simple_mtx_unlock(&ctx->Shared->Mutex); } @@ -207,7 +274,7 @@ fence_sync(struct gl_context *ctx, GLenum condition, GLbitfield flags) { struct gl_sync_object *syncObj; - syncObj = st_new_sync_object(ctx); + syncObj = new_sync_object(ctx); if (syncObj != NULL) { /* The name is not currently used, and it is never visible to * applications. If sync support is extended to provide support for @@ -221,7 +288,11 @@ fence_sync(struct gl_context *ctx, GLenum condition, GLbitfield flags) syncObj->Flags = flags; syncObj->StatusFlag = 0; - st_fence_sync(ctx, syncObj, condition, flags); + assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0); + assert(syncObj->fence == NULL); + + /* Deferred flush are only allowed when there's a single context. See issue 1430 */ + ctx->pipe->flush(ctx->pipe, &syncObj->fence, ctx->Shared->RefCount == 1 ? PIPE_FLUSH_DEFERRED : 0); simple_mtx_lock(&ctx->Shared->Mutex); _mesa_set_add(ctx->Shared->SyncObjects, syncObj); @@ -276,14 +347,14 @@ client_wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, * ClientWaitSync was called. ALREADY_SIGNALED will always be returned * if was signaled, even if the value of is zero. */ - st_check_sync(ctx, syncObj); + __client_wait_sync(ctx, syncObj, 0, 0); if (syncObj->StatusFlag) { ret = GL_ALREADY_SIGNALED; } else { if (timeout == 0) { ret = GL_TIMEOUT_EXPIRED; } else { - st_client_wait_sync(ctx, syncObj, flags, timeout); + __client_wait_sync(ctx, syncObj, flags, timeout); ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED; @@ -333,7 +404,29 @@ static void wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, GLbitfield flags, GLuint64 timeout) { - st_server_wait_sync(ctx, syncObj, flags, timeout); + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_fence_handle *fence = NULL; + + /* Nothing needs to be done here if the driver does not support async + * flushes. */ + if (!pipe->fence_server_sync) + return; + + /* If the fence doesn't exist, assume it's signalled. */ + simple_mtx_lock(&syncObj->mutex); + if (!syncObj->fence) { + simple_mtx_unlock(&syncObj->mutex); + syncObj->StatusFlag = GL_TRUE; + return; + } + + /* We need a local copy of the fence pointer. */ + screen->fence_reference(screen, &fence, syncObj->fence); + simple_mtx_unlock(&syncObj->mutex); + + pipe->fence_server_sync(pipe, fence); + screen->fence_reference(screen, &fence, NULL); _mesa_unref_sync_object(ctx, syncObj, 1); } @@ -408,7 +501,7 @@ _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, * this call won't block. It just updates state in the common object * data from the current driver state. */ - st_check_sync(ctx, syncObj); + __client_wait_sync(ctx, syncObj, 0, 0); v[0] = (syncObj->StatusFlag) ? GL_SIGNALED : GL_UNSIGNALED; size = 1; diff --git a/src/mesa/meson.build b/src/mesa/meson.build index 978a2fc..46a2d18 100644 --- a/src/mesa/meson.build +++ b/src/mesa/meson.build @@ -356,8 +356,6 @@ files_libmesa = files( 'state_tracker/st_cb_rasterpos.h', 'state_tracker/st_cb_readpixels.c', 'state_tracker/st_cb_readpixels.h', - 'state_tracker/st_cb_syncobj.c', - 'state_tracker/st_cb_syncobj.h', 'state_tracker/st_cb_texture.c', 'state_tracker/st_cb_texture.h', 'state_tracker/st_cb_viewport.c', diff --git a/src/mesa/state_tracker/st_cb_syncobj.c b/src/mesa/state_tracker/st_cb_syncobj.c deleted file mode 100644 index 25aaa52..0000000 --- a/src/mesa/state_tracker/st_cb_syncobj.c +++ /dev/null @@ -1,160 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Marek Olšák - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Marek Olšák - */ - -#include "main/glheader.h" -#include "main/macros.h" -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "util/u_memory.h" -#include "st_context.h" -#include "st_cb_syncobj.h" - -struct st_sync_object { - struct gl_sync_object b; - - struct pipe_fence_handle *fence; - simple_mtx_t mutex; /**< protects "fence" */ -}; - - -struct gl_sync_object *st_new_sync_object(struct gl_context *ctx) -{ - struct st_sync_object *so = CALLOC_STRUCT(st_sync_object); - - simple_mtx_init(&so->mutex, mtx_plain); - return &so->b; -} - -void st_delete_sync_object(struct gl_context *ctx, - struct gl_sync_object *obj) -{ - struct pipe_screen *screen = st_context(ctx)->screen; - struct st_sync_object *so = (struct st_sync_object*)obj; - - screen->fence_reference(screen, &so->fence, NULL); - simple_mtx_destroy(&so->mutex); - free(so->b.Label); - FREE(so); -} - -void st_fence_sync(struct gl_context *ctx, struct gl_sync_object *obj, - GLenum condition, GLbitfield flags) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct st_sync_object *so = (struct st_sync_object*)obj; - - assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0); - assert(so->fence == NULL); - - /* Deferred flush are only allowed when there's a single context. See issue 1430 */ - pipe->flush(pipe, &so->fence, ctx->Shared->RefCount == 1 ? PIPE_FLUSH_DEFERRED : 0); -} - -void st_client_wait_sync(struct gl_context *ctx, - struct gl_sync_object *obj, - GLbitfield flags, GLuint64 timeout) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct pipe_screen *screen = st_context(ctx)->screen; - struct st_sync_object *so = (struct st_sync_object*)obj; - struct pipe_fence_handle *fence = NULL; - - /* If the fence doesn't exist, assume it's signalled. */ - simple_mtx_lock(&so->mutex); - if (!so->fence) { - simple_mtx_unlock(&so->mutex); - so->b.StatusFlag = GL_TRUE; - return; - } - - /* We need a local copy of the fence pointer, so that we can call - * fence_finish unlocked. - */ - screen->fence_reference(screen, &fence, so->fence); - simple_mtx_unlock(&so->mutex); - - /* Section 4.1.2 of OpenGL 4.5 (Compatibility Profile) says: - * [...] if ClientWaitSync is called and all of the following are true: - * - the SYNC_FLUSH_COMMANDS_BIT bit is set in flags, - * - sync is unsignaled when ClientWaitSync is called, - * - and the calls to ClientWaitSync and FenceSync were issued from - * the same context, - * then the GL will behave as if the equivalent of Flush were inserted - * immediately after the creation of sync. - * - * Assume GL_SYNC_FLUSH_COMMANDS_BIT is always set, because applications - * forget to set it. - */ - if (screen->fence_finish(screen, pipe, fence, timeout)) { - simple_mtx_lock(&so->mutex); - screen->fence_reference(screen, &so->fence, NULL); - simple_mtx_unlock(&so->mutex); - so->b.StatusFlag = GL_TRUE; - } - screen->fence_reference(screen, &fence, NULL); -} - -void st_check_sync(struct gl_context *ctx, struct gl_sync_object *obj) -{ - st_client_wait_sync(ctx, obj, 0, 0); -} - -void st_server_wait_sync(struct gl_context *ctx, - struct gl_sync_object *obj, - GLbitfield flags, GLuint64 timeout) -{ - struct pipe_context *pipe = st_context(ctx)->pipe; - struct pipe_screen *screen = st_context(ctx)->screen; - struct st_sync_object *so = (struct st_sync_object*)obj; - struct pipe_fence_handle *fence = NULL; - - /* Nothing needs to be done here if the driver does not support async - * flushes. */ - if (!pipe->fence_server_sync) - return; - - /* If the fence doesn't exist, assume it's signalled. */ - simple_mtx_lock(&so->mutex); - if (!so->fence) { - simple_mtx_unlock(&so->mutex); - so->b.StatusFlag = GL_TRUE; - return; - } - - /* We need a local copy of the fence pointer. */ - screen->fence_reference(screen, &fence, so->fence); - simple_mtx_unlock(&so->mutex); - - pipe->fence_server_sync(pipe, fence); - screen->fence_reference(screen, &fence, NULL); -} - diff --git a/src/mesa/state_tracker/st_cb_syncobj.h b/src/mesa/state_tracker/st_cb_syncobj.h deleted file mode 100644 index b80541c..0000000 --- a/src/mesa/state_tracker/st_cb_syncobj.h +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Marek Olšák - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef ST_CB_SYNCOBJ_H -#define ST_CB_SYNCOBJ_H - -struct gl_sync_object *st_new_sync_object(struct gl_context *ctx); -void st_delete_sync_object(struct gl_context *ctx, - struct gl_sync_object *obj); -void st_fence_sync(struct gl_context *ctx, struct gl_sync_object *obj, - GLenum condition, GLbitfield flags); -void st_client_wait_sync(struct gl_context *ctx, - struct gl_sync_object *obj, - GLbitfield flags, GLuint64 timeout); - -void st_check_sync(struct gl_context *ctx, struct gl_sync_object *obj); -void st_server_wait_sync(struct gl_context *ctx, - struct gl_sync_object *obj, - GLbitfield flags, GLuint64 timeout); -#endif /* ST_CB_SYNCOBJ_H */ -- 2.7.4