summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/EGL/eglext.h24
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c54
-rwxr-xr-xsrc/egl/drivers/dri2/platform_tizen.c28
-rw-r--r--src/egl/generate/egl.xml13
-rw-r--r--src/egl/generate/eglFunctionList.py3
-rw-r--r--src/egl/main/eglapi.c29
-rw-r--r--src/egl/main/egldisplay.h1
-rw-r--r--src/egl/main/egldriver.h3
-rw-r--r--src/egl/main/eglentrypoint.h1
-rw-r--r--src/egl/main/eglsync.c25
-rw-r--r--src/gallium/drivers/v3d/v3d_fence.c11
-rw-r--r--src/gallium/drivers/v3d/v3d_screen.c8
-rw-r--r--src/gallium/drivers/v3d/v3d_screen.h1
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 <EGL/eglmesaext.h>
+#include <EGL/eglextchromium.h>
#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
@@ -1347,6 +1347,11 @@
<param><ptype>EGLSyncKHR</ptype> <name>sync</name></param>
</command>
<command>
+ <proto><ptype>EGLint</ptype> <name>eglDupNativeFenceFDTIZEN</name></proto>
+ <param><ptype>EGLDisplay</ptype> <name>dpy</name></param>
+ <param><ptype>EGLSyncKHR</ptype> <name>sync</name></param>
+ </command>
+ <command>
<proto><ptype>EGLBoolean</ptype> <name>eglExportDMABUFImageMESA</name></proto>
<param><ptype>EGLDisplay</ptype> <name>dpy</name></param>
<param><ptype>EGLImageKHR</ptype> <name>image</name></param>
@@ -3409,6 +3414,14 @@
<enum name="EGL_NATIVE_SURFACE_TIZEN"/>
</require>
</extension>
+ <extension name="EGL_TIZEN_native_fence_sync" supported="egl">
+ <require>
+ <enum name="EGL_SYNC_NATIVE_FENCE_TIZEN"/>
+ <enum name="EGL_SYNC_NATIVE_FENCE_FD_TIZEN"/>
+ <enum name="EGL_NO_NATIVE_FENCE_FD_TIZEN"/>
+ <command name="eglDupNativeFenceFDTIZEN"/>
+ </require>
+ </extension>
<extension name="EGL_EXT_compositor" supported="egl">
<require>
<enum name="EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT"/>
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 <fcntl.h>
+
#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;