From 4778ca8d76b61195c4b1d8a861864cc3b563cd39 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Fri, 20 Mar 2020 14:58:36 +0900 Subject: Implement extension EGL_TIZEN_native_fence_sync Merged old commit: Changed the initial setting of dri2_surface to use out_fence_fd. Change-Id: Ic51d7e2441927010b5889a2328199428c06d6351 Signed-off-by: Joonbum Ko Fixed to use out_fence_fd to wait render done in twe_thread. Change-Id: I2bee255bcd5eb2697e49a5e8973c03ea65fe0e30 Signed-off-by: Joonbum Ko v3d_screen: Fixed to support capability for NATIVE_FENCE_FD. Change-Id: I3335ee417d88e51a904114869fb5ac287622c526 Signed-off-by: Joonbum Ko v3d_fence: Added function to get fence_fd from dri2. Change-Id: Ibd86254f2352a01cd993c61b0ab036c721005be0 Signed-off-by: Joonbum Ko Added new extension EGL_TIZEN_native_fence_sync. EGL_TIZEN_native_fence_sync - Added EGL_SYNC_NATIVE_FENCE_TIZEN to distinguish EGLSyncKHR. - Added EGL_SYNC_NATIVE_FENCE_FD_TIZEN to get tizen's native fence fd in the sync attribute. - Added EGL_NO_NATIVE_FENCE_FD_TIZEN to indicate no native fence fd. - The eglDupNativeFenceFDTIZEN function has been added to get an fd to indicate when rendering is complete from the egl core. Change-Id: I6876572ec04b3d1616f6b7e5018dc6647685b536 Signed-off-by: Joonbum Ko Implemented extension EGL_TIZEN_native_fence_sync. - this patch is only for the 'tizen' branch - Added new API to get native fence fd from driver. eglDupNativeFenceFDTIZEN() Change-Id: I21d46faedbfc46abd4dde03d36560bf941061d38 Signed-off-by: Joonbum Ko Signed-off-by: Joonbum Ko --- include/EGL/eglext.h | 24 ++++++++++++++++ src/egl/drivers/dri2/egl_dri2.c | 54 ++++++++++++++++++++++++++++++++++- src/egl/drivers/dri2/platform_tizen.c | 28 ++++++++++-------- src/egl/generate/egl.xml | 13 +++++++++ src/egl/generate/eglFunctionList.py | 3 ++ src/egl/main/eglapi.c | 29 ++++++++++++++++++- src/egl/main/egldisplay.h | 1 + src/egl/main/egldriver.h | 3 ++ src/egl/main/eglentrypoint.h | 1 + src/egl/main/eglsync.c | 25 ++++++++++++++++ src/gallium/drivers/v3d/v3d_fence.c | 11 +++++++ src/gallium/drivers/v3d/v3d_screen.c | 8 ++++++ src/gallium/drivers/v3d/v3d_screen.h | 1 + 13 files changed, 187 insertions(+), 14 deletions(-) diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h index d58da70e6b3..f30d27476ad 100644 --- a/include/EGL/eglext.h +++ b/include/EGL/eglext.h @@ -1475,6 +1475,30 @@ typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image); #endif #endif /* EGL_WL_create_wayland_buffer_from_image */ +#ifndef EGL_EXT_image_flush_external +#define EGL_EXT_image_flush_external 1 +#define EGL_IMAGE_EXTERNAL_FLUSH_EXT 0x32A2 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLIMAGEFLUSHEXTERNALEXTPROC) (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLIMAGEINVALIDATEEXTERNALEXTPROC) (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglImageFlushExternalEXT (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglImageInvalidateExternalEXT (EGLDisplay dpy, EGLImageKHR image, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_image_flush_external */ + +#ifndef EGL_TIZEN_native_fence_sync +#define EGL_TIZEN_native_fence_sync 1 +#define EGL_SYNC_NATIVE_FENCE_TIZEN 0x3144 +#define EGL_SYNC_NATIVE_FENCE_FD_TIZEN 0x3145 +#define EGL_NO_NATIVE_FENCE_FD_TIZEN -1 +typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDTIZENPROC) (EGLDisplay dpy, EGLSyncKHR sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDTIZEN (EGLDisplay dpy, EGLSyncKHR sync); +#endif +#endif /* EGL_TIZEN_native_fence_sync */ + +#include +#include #ifdef __cplusplus } diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index c791ee65ae2..17e32b87465 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -3459,10 +3459,17 @@ dri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy, case EGL_SYNC_REUSABLE_KHR: cnd_destroy(&dri2_sync->cond); break; +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: + if (dri2_sync->base.SyncFd != EGL_NO_NATIVE_FENCE_FD_TIZEN) + close(dri2_sync->base.SyncFd); + break; +#else case EGL_SYNC_NATIVE_FENCE_ANDROID: if (dri2_sync->base.SyncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID) close(dri2_sync->base.SyncFd); break; +#endif default: break; } @@ -3550,7 +3557,8 @@ dri2_create_sync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list) dri2_sync->base.SyncStatus = EGL_UNSIGNALED_KHR; break; - case EGL_SYNC_NATIVE_FENCE_ANDROID: +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: if (dri2_dpy->fence->create_fence_fd) { dri2_sync->fence = dri2_dpy->fence->create_fence_fd( dri2_ctx->dri_context, dri2_sync->base.SyncFd); @@ -3561,6 +3569,20 @@ dri2_create_sync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list) } break; } +#else + case EGL_SYNC_NATIVE_FENCE_ANDROID: + if (dri2_dpy->fence->create_fence_fd) { + dri2_sync->fence = dri2_dpy->fence->create_fence_fd( + dri2_ctx->dri_context, + dri2_sync->base.SyncFd); + } + if (!dri2_sync->fence) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); + free(dri2_sync); + return NULL; + } + break; +#endif p_atomic_set(&dri2_sync->refcount, 1); mtx_unlock(&dri2_dpy->lock); @@ -3633,6 +3655,31 @@ dri2_dup_native_fence_fd(_EGLDisplay *disp, _EGLSync *sync) return os_dupfd_cloexec(sync->SyncFd); } +static EGLint +dri2_dup_native_fence_fd_tizen(_EGLDisplay *dpy, _EGLSync *sync) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); + struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); + + assert(sync->Type == EGL_SYNC_NATIVE_FENCE_TIZEN); + + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_TIZEN) { + /* try to retrieve the actual native fence fd.. if rendering is + * not flushed this will just return -1, aka NO_NATIVE_FENCE_FD: + */ + sync->SyncFd = dri2_dpy->fence->get_fence_fd(dri2_dpy->dri_screen_render_gpu, + dri2_sync->fence); + } + + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_TIZEN) { + /* if native fence fd still not created, return an error: */ + _eglError(EGL_BAD_PARAMETER, "eglDupNativeFenceFDTIZEN"); + return EGL_NO_NATIVE_FENCE_FD_TIZEN; + } + + return dup(sync->SyncFd); +} + static void dri2_set_blob_cache_funcs(_EGLDisplay *disp, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) @@ -3667,7 +3714,11 @@ dri2_client_wait_sync(_EGLDisplay *disp, _EGLSync *sync, EGLint flags, switch (sync->Type) { case EGL_SYNC_FENCE_KHR: +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: +#else case EGL_SYNC_NATIVE_FENCE_ANDROID: +#endif case EGL_SYNC_CL_EVENT_KHR: if (dri2_dpy->fence->client_wait_sync( dri2_ctx ? dri2_ctx->dri_context : NULL, dri2_sync->fence, @@ -3872,5 +3923,6 @@ const _EGLDriver _eglDriver = { .GLInteropExportObject = dri2_interop_export_object, .GLInteropFlushObjects = dri2_interop_flush_objects, .DupNativeFenceFDANDROID = dri2_dup_native_fence_fd, + .DupNativeFenceFDTIZEN = dri2_dup_native_fence_fd_tizen, .SetBlobCacheFuncsANDROID = dri2_set_blob_cache_funcs, }; diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c index ab27b1928a1..d34e69bd6cd 100755 --- a/src/egl/drivers/dri2/platform_tizen.c +++ b/src/egl/drivers/dri2/platform_tizen.c @@ -224,6 +224,7 @@ tizen_window_enqueue_buffer_with_damage(_EGLDisplay *disp, { tpl_result_t ret; struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + int fence_fd = -1; /* To avoid blocking other EGL calls, release the display mutex before * we enter tizen_window_enqueue_buffer() and re-acquire the mutex upon @@ -231,17 +232,13 @@ tizen_window_enqueue_buffer_with_damage(_EGLDisplay *disp, */ mtx_unlock(&disp->Mutex); - if (n_rects < 1 || rects == NULL) { - /* if there is no damage, call the normal API tpl_surface_enqueue_buffer */ - ret = tpl_surface_enqueue_buffer(dri2_surf->tpl_surface, - dri2_surf->tbm_surface); - } else { - /* if there are rectangles of damage region, - call the API tpl_surface_enqueue_buffer_with_damage() */ - ret = tpl_surface_enqueue_buffer_with_damage(dri2_surf->tpl_surface, - dri2_surf->tbm_surface, - n_rects, rects); - } + fence_fd = dri2_surf->out_fence_fd; + dri2_surf->out_fence_fd = -1; + + ret = tpl_surface_enqueue_buffer_with_damage_and_sync(dri2_surf->tpl_surface, + dri2_surf->tbm_surface, + n_rects, rects, + fence_fd); if (ret != TPL_ERROR_NONE) { _eglLog(_EGL_DEBUG, "%s : %d :tpl_surface_enqueue fail", __func__, __LINE__); @@ -327,7 +324,7 @@ tizen_create_surface(_EGLDisplay *disp, EGLint type, } if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, - false, native_window)) + true, native_window)) goto cleanup_surface; config = dri2_get_dri_config(dri2_conf, type, @@ -1604,6 +1601,13 @@ dri2_initialize_tizen(_EGLDisplay *disp) disp->Extensions.WL_bind_wayland_display = EGL_TRUE; disp->Extensions.WL_create_wayland_buffer_from_image = EGL_FALSE; + if (dri2_dpy->fence->base.version >= 2 && + dri2_dpy->fence->get_capabilities) { + unsigned capabilities = + dri2_dpy->fence->get_capabilities(dri2_dpy->dri_screen); + disp->Extensions.TIZEN_native_fence_sync = + (capabilities & __DRI_FENCE_CAP_NATIVE_FD) != 0; + } return EGL_TRUE; diff --git a/src/egl/generate/egl.xml b/src/egl/generate/egl.xml index 9ced66d5c1e..9ccc49d3b6d 100644 --- a/src/egl/generate/egl.xml +++ b/src/egl/generate/egl.xml @@ -1346,6 +1346,11 @@ EGLDisplay dpy EGLSyncKHR sync + + EGLint eglDupNativeFenceFDTIZEN + EGLDisplay dpy + EGLSyncKHR sync + EGLBoolean eglExportDMABUFImageMESA EGLDisplay dpy @@ -3409,6 +3414,14 @@ + + + + + + + + diff --git a/src/egl/generate/eglFunctionList.py b/src/egl/generate/eglFunctionList.py index 5076ced6f11..91792fa9ffb 100644 --- a/src/egl/generate/eglFunctionList.py +++ b/src/egl/generate/eglFunctionList.py @@ -246,5 +246,8 @@ EGL_FUNCTIONS = ( _eglFunc("eglGLInteropQueryDeviceInfoMESA", "display"), _eglFunc("eglGLInteropExportObjectMESA", "display"), _eglFunc("eglGLInteropFlushObjectsMESA", "display"), + # EGL_TIZEN_native_fence_sync + _eglFunc("eglDupNativeFenceFDTIZEN", "display"), + ) diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index f2ea7d77f60..000c179d306 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -1947,7 +1947,8 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list, * error is generated. */ if (!ctx && - (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID)) + (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID + || type == EGL_SYNC_NATIVE_FENCE_TIZEN)) RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR); if (ctx && (ctx->Resource.Display != disp)) @@ -1966,10 +1967,17 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list, if (!disp->Extensions.KHR_cl_event2) RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: + if (!disp->Extensions.TIZEN_native_fence_sync) + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); + break; +#else case EGL_SYNC_NATIVE_FENCE_ANDROID: if (!disp->Extensions.ANDROID_native_fence_sync) RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; +#endif default: RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); } @@ -2251,6 +2259,25 @@ eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) RETURN_EGL_SUCCESS(disp, ret); } +static EGLint EGLAPIENTRY +eglDupNativeFenceFDTIZEN(EGLDisplay dpy, EGLSync sync) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + EGLBoolean ret; + + _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); + + if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_TIZEN))) + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_TIZEN); + + _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_TIZEN); + assert(disp->Extensions.TIZEN_native_fence_sync); + ret = disp->Driver->DupNativeFenceFDTIZEN(disp, s); + + RETURN_EGL_EVAL(disp, ret); +} + static EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects) diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 5aa86839b3d..9a1e2a1002f 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -153,6 +153,7 @@ struct _egl_extensions { #ifdef HAVE_TIZEN_PLATFORM EGLBoolean TIZEN_image_native_surface; + EGLBoolean TIZEN_native_fence_sync; #endif EGLBoolean WL_bind_wayland_display; diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 6bea4fb3d6b..101349952f1 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -143,6 +143,9 @@ struct _egl_driver { /* for EGL_ANDROID_native_fence_sync */ EGLint (*DupNativeFenceFDANDROID)(_EGLDisplay *disp, _EGLSync *sync); + /* for EGL_TIZEN_native_fence_sync */ + EGLint (*DupNativeFenceFDTIZEN)(_EGLDisplay *disp, _EGLSync *sync); + /* for EGL_NOK_swap_region */ EGLBoolean (*SwapBuffersRegionNOK)(_EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects); diff --git a/src/egl/main/eglentrypoint.h b/src/egl/main/eglentrypoint.h index 88f88e77966..f1249972f37 100644 --- a/src/egl/main/eglentrypoint.h +++ b/src/egl/main/eglentrypoint.h @@ -34,6 +34,7 @@ EGL_ENTRYPOINT(eglDestroySurface) EGL_ENTRYPOINT(eglDestroySync) EGL_ENTRYPOINT(eglDestroySyncKHR) EGL_ENTRYPOINT(eglDupNativeFenceFDANDROID) +EGL_ENTRYPOINT(eglDupNativeFenceFDTIZEN) EGL_ENTRYPOINT(eglExportDMABUFImageMESA) EGL_ENTRYPOINT(eglExportDMABUFImageQueryMESA) EGL_ENTRYPOINT(eglExportDRMImageMESA) diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c index 554077650bc..8699eddccf0 100644 --- a/src/egl/main/eglsync.c +++ b/src/egl/main/eglsync.c @@ -57,6 +57,16 @@ _eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib *attrib_list) err = EGL_BAD_ATTRIBUTE; } break; +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_FD_TIZEN: + if (sync->Type == EGL_SYNC_NATIVE_FENCE_TIZEN) { + /* we take ownership of the native fd, so no dup(): */ + sync->SyncFd = val; + } else { + err = EGL_BAD_ATTRIBUTE; + } + break; +#else case EGL_SYNC_NATIVE_FENCE_FD_ANDROID: if (sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID) { /* we take ownership of the native fd, so no dup(): */ @@ -65,6 +75,7 @@ _eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib *attrib_list) err = EGL_BAD_ATTRIBUTE; } break; +#endif default: err = EGL_BAD_ATTRIBUTE; break; @@ -96,12 +107,18 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *disp, EGLenum type, case EGL_SYNC_CL_EVENT_KHR: sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR; break; +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: + sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; + break; +#else case EGL_SYNC_NATIVE_FENCE_ANDROID: if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; else sync->SyncCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID; break; +#endif default: sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; } @@ -129,7 +146,11 @@ _eglGetSyncAttrib(_EGLDisplay *disp, _EGLSync *sync, EGLint attribute, (sync->Type == EGL_SYNC_FENCE_KHR || sync->Type == EGL_SYNC_CL_EVENT_KHR || sync->Type == EGL_SYNC_REUSABLE_KHR || +#ifdef HAVE_TIZEN_PLATFORM + sync->Type == EGL_SYNC_NATIVE_FENCE_TIZEN)) +#else sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)) +#endif disp->Driver->ClientWaitSyncKHR(disp, sync, 0, 0); *value = sync->SyncStatus; @@ -137,7 +158,11 @@ _eglGetSyncAttrib(_EGLDisplay *disp, _EGLSync *sync, EGLint attribute, case EGL_SYNC_CONDITION_KHR: if (sync->Type != EGL_SYNC_FENCE_KHR && sync->Type != EGL_SYNC_CL_EVENT_KHR && +#ifdef HAVE_TIZEN_PLATFORM + sync->Type != EGL_SYNC_NATIVE_FENCE_TIZEN) +#else sync->Type != EGL_SYNC_NATIVE_FENCE_ANDROID) +#endif return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); *value = sync->SyncCondition; break; diff --git a/src/gallium/drivers/v3d/v3d_fence.c b/src/gallium/drivers/v3d/v3d_fence.c index 3abfcd7c750..ca0a145f3d1 100644 --- a/src/gallium/drivers/v3d/v3d_fence.c +++ b/src/gallium/drivers/v3d/v3d_fence.c @@ -34,6 +34,8 @@ * fired off as our fence marker. */ +#include + #include "util/u_inlines.h" #include "util/os_time.h" @@ -140,9 +142,18 @@ v3d_fence_create(struct v3d_context *v3d) return f; } +static int +v3d_fence_get_fd(struct pipe_screen *screen, struct pipe_fence_handle *pfence) +{ + struct v3d_fence *fence = (struct v3d_fence *)pfence; + + return fcntl(fence->fd, F_DUPFD_CLOEXEC, 3); +} + void v3d_fence_init(struct v3d_screen *screen) { screen->base.fence_reference = v3d_fence_reference; screen->base.fence_finish = v3d_fence_finish; + screen->base.fence_get_fd = v3d_fence_get_fd; } diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 08d02c9a73b..188de828739 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -290,6 +290,8 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 256; case PIPE_CAP_MAX_GS_INVOCATIONS: return 32; + case PIPE_CAP_NATIVE_FENCE_FD: + return screen->has_syncobj; case PIPE_CAP_SUPPORTED_PRIM_MODES: case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: @@ -894,6 +896,8 @@ v3d_screen_create(int fd, const struct pipe_screen_config *config, { struct v3d_screen *screen = rzalloc(NULL, struct v3d_screen); struct pipe_screen *pscreen; + uint64_t syncobj_cap = 0; + int err; pscreen = &screen->base; @@ -939,6 +943,10 @@ v3d_screen_create(int fd, const struct pipe_screen_config *config, v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH); screen->has_perfmon = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_PERFMON); + err = drmGetCap(fd, DRM_CAP_SYNCOBJ, &syncobj_cap); + if (err == 0 && syncobj_cap) + screen->has_syncobj = true; + v3d_fence_init(screen); v3d_process_debug_variable(); diff --git a/src/gallium/drivers/v3d/v3d_screen.h b/src/gallium/drivers/v3d/v3d_screen.h index 1da9b83c965..b8bdbcc93f9 100644 --- a/src/gallium/drivers/v3d/v3d_screen.h +++ b/src/gallium/drivers/v3d/v3d_screen.h @@ -82,6 +82,7 @@ struct v3d_screen { bool has_csd; bool has_cache_flush; bool has_perfmon; + bool has_syncobj; bool nonmsaa_texture_size_limit; struct v3d_simulator_file *sim_file; -- cgit v1.2.3