1
0
Fork 0

cogl: Store latest GPU work completed sync fd

This keeps an internal sync_fd for the latest work submitted to
the GPU. This can then be fetched with cogl_context_get_latest_sync_fd
for use. This is intended for use with linux-drm-syncobj-v1

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3300>
This commit is contained in:
Austin Shafer 2023-10-26 13:33:34 -04:00
parent 3f5bf42ab6
commit 99209958b9
9 changed files with 98 additions and 0 deletions

View file

@ -311,3 +311,6 @@ _cogl_context_set_current_projection_entry (CoglContext *context,
void void
_cogl_context_set_current_modelview_entry (CoglContext *context, _cogl_context_set_current_modelview_entry (CoglContext *context,
CoglMatrixEntry *entry); CoglMatrixEntry *entry);
void
_cogl_context_update_sync (CoglContext *context);

View file

@ -463,6 +463,28 @@ _cogl_context_set_current_modelview_entry (CoglContext *context,
context->current_modelview_entry = entry; context->current_modelview_entry = entry;
} }
void
_cogl_context_update_sync (CoglContext *context)
{
const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
if (!winsys->update_sync)
return;
winsys->update_sync (context);
}
int
cogl_context_get_latest_sync_fd (CoglContext *context)
{
const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
if (!winsys->get_sync_fd)
return -1;
return winsys->get_sync_fd (context);
}
CoglGraphicsResetStatus CoglGraphicsResetStatus
cogl_get_graphics_reset_status (CoglContext *context) cogl_get_graphics_reset_status (CoglContext *context)
{ {

View file

@ -367,4 +367,18 @@ cogl_context_timestamp_query_get_time_ns (CoglContext *context,
COGL_EXPORT int64_t COGL_EXPORT int64_t
cogl_context_get_gpu_time_ns (CoglContext *context); cogl_context_get_gpu_time_ns (CoglContext *context);
/**
* cogl_context_get_latest_sync_fd
* @context: a #CoglContext pointer
*
* This function is used to get support for waiting on previous
* GPU work through sync fds. It will return a sync fd which will
* signal when the previous work has completed.
*
* Return value: sync fd for latest GPU submission if available,
* returns -1 if not.
*/
COGL_EXPORT int
cogl_context_get_latest_sync_fd (CoglContext *context);
G_END_DECLS G_END_DECLS

View file

@ -309,6 +309,9 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_FRAMEBUFFER (onscreen), COGL_FRAMEBUFFER (onscreen),
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);
/* Update our "latest" sync fd to contain all previous work */
_cogl_context_update_sync (context);
if (cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY)) if (cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY))
{ {
info->gpu_time_before_buffer_swap_ns = info->gpu_time_before_buffer_swap_ns =

View file

@ -162,6 +162,15 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroySync,
(EGLDisplay dpy, (EGLDisplay dpy,
EGLSyncKHR sync)) EGLSyncKHR sync))
COGL_WINSYS_FEATURE_END () COGL_WINSYS_FEATURE_END ()
COGL_WINSYS_FEATURE_BEGIN (native_fence_sync,
"ANDROID\0",
"native_fence_sync\0",
COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC)
COGL_WINSYS_FEATURE_FUNCTION (EGLint, eglDupNativeFenceFD,
(EGLDisplay dpy,
EGLSyncKHR sync))
COGL_WINSYS_FEATURE_END ()
#endif #endif
COGL_WINSYS_FEATURE_BEGIN (surfaceless_context, COGL_WINSYS_FEATURE_BEGIN (surfaceless_context,

View file

@ -101,6 +101,7 @@ typedef enum _CoglEGLWinsysFeature
COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT = 1L << 6, COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT = 1L << 6,
COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY = 1L << 7, COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY = 1L << 7,
COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8, COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8,
COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC = 1L << 9,
} CoglEGLWinsysFeature; } CoglEGLWinsysFeature;
typedef struct _CoglRendererEGL typedef struct _CoglRendererEGL
@ -119,6 +120,9 @@ typedef struct _CoglRendererEGL
/* vtable for platform specific parts */ /* vtable for platform specific parts */
const CoglWinsysEGLVtable *platform_vtable; const CoglWinsysEGLVtable *platform_vtable;
/* Sync for latest submitted work */
EGLSyncKHR sync;
/* Function pointers for EGL specific extensions */ /* Function pointers for EGL specific extensions */
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d) #define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d)

View file

@ -243,6 +243,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
xlib_renderer = _cogl_xlib_renderer_get_data (renderer); xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable; egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
egl_renderer->sync = EGL_NO_SYNC_KHR;
if (!_cogl_xlib_renderer_connect (renderer, error)) if (!_cogl_xlib_renderer_connect (renderer, error))
goto error; goto error;

View file

@ -441,6 +441,9 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
g_return_if_fail (egl_display != NULL); g_return_if_fail (egl_display != NULL);
if (egl_renderer->sync != EGL_NO_SYNC_KHR)
egl_renderer->pf_eglDestroySync (egl_renderer->edpy, egl_renderer->sync);
cleanup_context (display); cleanup_context (display);
if (egl_renderer->platform_vtable->display_destroy) if (egl_renderer->platform_vtable->display_destroy)
@ -573,6 +576,37 @@ _cogl_winsys_fence_destroy (CoglContext *context, void *fence)
renderer->pf_eglDestroySync (renderer->edpy, fence); renderer->pf_eglDestroySync (renderer->edpy, fence);
} }
static int
_cogl_winsys_get_sync_fd (CoglContext *context)
{
CoglRendererEGL *renderer = context->display->renderer->winsys;
int fd;
if (!renderer->pf_eglDupNativeFenceFD)
return -1;
fd = renderer->pf_eglDupNativeFenceFD (renderer->edpy, renderer->sync);
if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID)
return -1;
return fd;
}
static void
_cogl_winsys_update_sync (CoglContext *context)
{
CoglRendererEGL *renderer = context->display->renderer->winsys;
if (!renderer->pf_eglDestroySync || !renderer->pf_eglCreateSync)
return;
if (renderer->sync != EGL_NO_SYNC_KHR)
renderer->pf_eglDestroySync (renderer->edpy, renderer->sync);
renderer->sync = renderer->pf_eglCreateSync (renderer->edpy,
EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
}
#endif #endif
static CoglWinsysVtable _cogl_winsys_vtable = static CoglWinsysVtable _cogl_winsys_vtable =
@ -595,6 +629,8 @@ static CoglWinsysVtable _cogl_winsys_vtable =
.fence_add = _cogl_winsys_fence_add, .fence_add = _cogl_winsys_fence_add,
.fence_is_complete = _cogl_winsys_fence_is_complete, .fence_is_complete = _cogl_winsys_fence_is_complete,
.fence_destroy = _cogl_winsys_fence_destroy, .fence_destroy = _cogl_winsys_fence_destroy,
.get_sync_fd = _cogl_winsys_get_sync_fd,
.update_sync = _cogl_winsys_update_sync,
#endif #endif
}; };

View file

@ -141,6 +141,12 @@ typedef struct _CoglWinsysVtable
(*fence_destroy) (CoglContext *ctx, (*fence_destroy) (CoglContext *ctx,
void *fence); void *fence);
void
(*update_sync) (CoglContext *ctx);
int
(*get_sync_fd) (CoglContext *ctx);
} CoglWinsysVtable; } CoglWinsysVtable;
typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void); typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void);