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
_cogl_context_set_current_modelview_entry (CoglContext *context,
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;
}
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
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_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

View file

@ -309,6 +309,9 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_FRAMEBUFFER (onscreen),
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))
{
info->gpu_time_before_buffer_swap_ns =

View file

@ -162,6 +162,15 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroySync,
(EGLDisplay dpy,
EGLSyncKHR sync))
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
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_CONTEXT_PRIORITY = 1L << 7,
COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8,
COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC = 1L << 9,
} CoglEGLWinsysFeature;
typedef struct _CoglRendererEGL
@ -119,6 +120,9 @@ typedef struct _CoglRendererEGL
/* vtable for platform specific parts */
const CoglWinsysEGLVtable *platform_vtable;
/* Sync for latest submitted work */
EGLSyncKHR sync;
/* Function pointers for EGL specific extensions */
#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);
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
egl_renderer->sync = EGL_NO_SYNC_KHR;
if (!_cogl_xlib_renderer_connect (renderer, error))
goto error;

View file

@ -441,6 +441,9 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
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);
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);
}
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
static CoglWinsysVtable _cogl_winsys_vtable =
@ -595,6 +629,8 @@ static CoglWinsysVtable _cogl_winsys_vtable =
.fence_add = _cogl_winsys_fence_add,
.fence_is_complete = _cogl_winsys_fence_is_complete,
.fence_destroy = _cogl_winsys_fence_destroy,
.get_sync_fd = _cogl_winsys_get_sync_fd,
.update_sync = _cogl_winsys_update_sync,
#endif
};

View file

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