summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Stevens <stevensd@chromium.org>2020-10-01 15:39:07 +0900
committerGurchetan Singh <gurchetansingh@chromium.org>2020-10-13 00:33:59 +0000
commit313f1cc8879c853492eef2626d6e3d10f43943c5 (patch)
tree73c985462cf162c5852238f2369a7de8a9d8b61b
parent16f8d896d0fd15d183eeb35133f8a83e5f3ea65a (diff)
vrend: add support for exporting egl fences
Acked-by: Gert Wollny <gert.wollny@collabora.com>
-rw-r--r--src/virglrenderer.c6
-rw-r--r--src/virglrenderer.h3
-rw-r--r--src/vrend_renderer.c52
-rw-r--r--src/vrend_renderer.h2
-rw-r--r--src/vrend_winsys_egl.c23
-rw-r--r--src/vrend_winsys_egl.h2
6 files changed, 88 insertions, 0 deletions
diff --git a/src/virglrenderer.c b/src/virglrenderer.c
index bbf64164..29d6d340 100644
--- a/src/virglrenderer.c
+++ b/src/virglrenderer.c
@@ -763,3 +763,9 @@ virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd)
return 0;
}
+
+int
+virgl_renderer_export_fence(uint32_t client_fence_id, uint32_t *fd)
+{
+ return vrend_renderer_export_fence(client_fence_id, fd);
+}
diff --git a/src/virglrenderer.h b/src/virglrenderer.h
index db4bb5c4..b06eea12 100644
--- a/src/virglrenderer.h
+++ b/src/virglrenderer.h
@@ -297,6 +297,9 @@ VIRGL_EXPORT int virgl_renderer_resource_get_map_info(uint32_t res_handle, uint3
VIRGL_EXPORT int
virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd);
+VIRGL_EXPORT int
+virgl_renderer_export_fence(uint32_t client_fence_id, uint32_t *fd);
+
#endif /* VIRGL_RENDERER_UNSTABLE_APIS */
#endif
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index e9c3c77f..49333f05 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -10645,3 +10645,55 @@ int vrend_renderer_resource_unmap(struct pipe_resource *pres)
glBindBufferARB(res->target, 0);
return 0;
}
+
+int vrend_renderer_export_fence(uint32_t fence_id, int* out_fd) {
+#ifdef HAVE_EPOXY_EGL_H
+ if (!vrend_state.use_egl_fence) {
+ return -EINVAL;
+ }
+
+ if (vrend_state.sync_thread)
+ pipe_mutex_lock(vrend_state.fence_mutex);
+
+ struct vrend_fence *fence = NULL;
+ struct vrend_fence *iter;
+ uint32_t min_fence_id = UINT_MAX;
+
+ if (!LIST_IS_EMPTY(&vrend_state.fence_list)) {
+ min_fence_id = LIST_ENTRY(struct vrend_fence, vrend_state.fence_list.next, fences)->fence_id;
+ } else if (!LIST_IS_EMPTY(&vrend_state.fence_wait_list)) {
+ min_fence_id =
+ LIST_ENTRY(struct vrend_fence, vrend_state.fence_wait_list.next, fences)->fence_id;
+ }
+
+ if (fence_id < min_fence_id) {
+ if (vrend_state.sync_thread)
+ pipe_mutex_unlock(vrend_state.fence_mutex);
+ return virgl_egl_export_signaled_fence(egl, out_fd) ? 0 : -EINVAL;
+ }
+
+ LIST_FOR_EACH_ENTRY(iter, &vrend_state.fence_list, fences) {
+ if (iter->fence_id == fence_id) {
+ fence = iter;
+ break;
+ }
+ }
+
+ if (!fence) {
+ LIST_FOR_EACH_ENTRY(iter, &vrend_state.fence_wait_list, fences) {
+ if (iter->fence_id == fence_id) {
+ fence = iter;
+ break;
+ }
+ }
+ }
+
+ if (vrend_state.sync_thread)
+ pipe_mutex_unlock(vrend_state.fence_mutex);
+
+ if (fence && virgl_egl_export_fence(egl, fence->eglsyncobj, out_fd)) {
+ return 0;
+ }
+#endif
+ return -EINVAL;
+}
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index cf2e5932..afb900b9 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -347,6 +347,8 @@ int vrend_renderer_create_fence(int client_fence_id, uint32_t ctx_id);
void vrend_renderer_check_fences(void);
+int vrend_renderer_export_fence(uint32_t fence_id, int* out_fd);
+
bool vrend_hw_switch_context(struct vrend_context *ctx, bool now);
uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data,
uint32_t handle, enum virgl_object_type type);
diff --git a/src/vrend_winsys_egl.c b/src/vrend_winsys_egl.c
index 4994a34d..0fc41ed8 100644
--- a/src/vrend_winsys_egl.c
+++ b/src/vrend_winsys_egl.c
@@ -74,6 +74,7 @@ struct virgl_egl {
EGLConfig egl_conf;
EGLContext egl_ctx;
uint32_t extension_bits;
+ EGLSyncKHR signaled_fence;
};
static bool virgl_egl_has_extension_in_string(const char *haystack, const char *needle)
@@ -236,6 +237,16 @@ struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool g
eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
egl->egl_ctx);
+
+ if (virgl_egl_supports_fences(egl)) {
+ egl->signaled_fence = eglCreateSyncKHR(egl->egl_display,
+ EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
+ if (!egl->signaled_fence) {
+ vrend_printf("Failed to create signaled fence");
+ goto fail;
+ }
+ }
+
return egl;
fail:
@@ -245,6 +256,9 @@ struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool g
void virgl_egl_destroy(struct virgl_egl *egl)
{
+ if (egl->signaled_fence) {
+ eglDestroySyncKHR(egl->egl_display, egl->signaled_fence);
+ }
eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroyContext(egl->egl_display, egl->egl_ctx);
@@ -533,3 +547,12 @@ bool virgl_egl_client_wait_fence(struct virgl_egl *egl, EGLSyncKHR fence, uint64
}
return ret != EGL_TIMEOUT_EXPIRED_KHR;
}
+
+bool virgl_egl_export_signaled_fence(struct virgl_egl *egl, int *out_fd) {
+ return virgl_egl_export_fence(egl, egl->signaled_fence, out_fd);
+}
+
+bool virgl_egl_export_fence(struct virgl_egl *egl, EGLSyncKHR fence, int *out_fd) {
+ *out_fd = eglDupNativeFenceFDANDROID(egl->egl_display, fence);
+ return *out_fd != EGL_NO_NATIVE_FENCE_FD_ANDROID;
+}
diff --git a/src/vrend_winsys_egl.h b/src/vrend_winsys_egl.h
index 7f0a2eba..1fb0ccbc 100644
--- a/src/vrend_winsys_egl.h
+++ b/src/vrend_winsys_egl.h
@@ -64,4 +64,6 @@ bool virgl_egl_supports_fences(struct virgl_egl *egl);
EGLSyncKHR virgl_egl_fence_create(struct virgl_egl *egl);
void virgl_egl_fence_destroy(struct virgl_egl *egl, EGLSyncKHR fence);
bool virgl_egl_client_wait_fence(struct virgl_egl *egl, EGLSyncKHR fence, uint64_t timeout);
+bool virgl_egl_export_signaled_fence(struct virgl_egl *egl, int *out_fd);
+bool virgl_egl_export_fence(struct virgl_egl *egl, EGLSyncKHR fence, int *out_fd);
#endif