From 0b564e52d7e7500ac9eecf37282a3d331da0b6d2 Mon Sep 17 00:00:00 2001 From: Rohan Garg Date: Tue, 9 Jun 2020 19:13:19 +0200 Subject: [PATCH] i965: Implement semaphore support for EXT_external_objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement importing, signalling and waiting for EXT_external_objects Signed-off-by: Rohan Garg Reviewed-by: Eleni Maria Stea Reviewed-by: Tapani Pälli Part-of: --- src/mesa/drivers/dri/i965/brw_batch.c | 16 +++++ src/mesa/drivers/dri/i965/brw_context.h | 3 + src/mesa/drivers/dri/i965/brw_fbo.c | 1 + src/mesa/drivers/dri/i965/brw_sync.c | 91 +++++++++++++++++++++++++ 4 files changed, 111 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_batch.c b/src/mesa/drivers/dri/i965/brw_batch.c index c2d91a5c2a3..cbb7b6ba0bf 100644 --- a/src/mesa/drivers/dri/i965/brw_batch.c +++ b/src/mesa/drivers/dri/i965/brw_batch.c @@ -58,6 +58,14 @@ brw_batch_reset(struct brw_context *brw); static void brw_new_batch(struct brw_context *brw); +static unsigned +num_fences(struct brw_batch *batch) +{ + return util_dynarray_num_elements(&batch->exec_fences, + struct drm_i915_gem_exec_fence); +} + + static void dump_validation_list(struct brw_batch *batch) { @@ -728,6 +736,14 @@ execbuffer(int fd, execbuf.flags |= I915_EXEC_FENCE_OUT; } + if (num_fences(batch)) { + execbuf.flags |= I915_EXEC_FENCE_ARRAY; + execbuf.num_cliprects = num_fences(batch); + execbuf.cliprects_ptr = + (uintptr_t)util_dynarray_begin(&batch->exec_fences); + } + + int ret = drmIoctl(fd, cmd, &execbuf); if (ret != 0) ret = -errno; diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 5352fa6ac48..a8a0cf3ca4e 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -529,6 +529,9 @@ struct brw_batch { struct hash_table_u64 *state_batch_sizes; struct intel_batch_decode_ctx decoder; + + /** A list of drm_i915_exec_fences to have execbuf signal or wait on */ + struct util_dynarray exec_fences; }; #define BRW_MAX_XFB_STREAMS 4 diff --git a/src/mesa/drivers/dri/i965/brw_fbo.c b/src/mesa/drivers/dri/i965/brw_fbo.c index 01ac6cb3b83..ff30385e437 100644 --- a/src/mesa/drivers/dri/i965/brw_fbo.c +++ b/src/mesa/drivers/dri/i965/brw_fbo.c @@ -1135,4 +1135,5 @@ brw_fbo_init(struct brw_context *brw) _mesa_key_pointer_equal); brw->depth_cache = _mesa_set_create(brw->mem_ctx, _mesa_hash_pointer, _mesa_key_pointer_equal); + util_dynarray_init(&brw->batch.exec_fences, NULL); } diff --git a/src/mesa/drivers/dri/i965/brw_sync.c b/src/mesa/drivers/dri/i965/brw_sync.c index 7c3980eb5da..cd4ec8432ca 100644 --- a/src/mesa/drivers/dri/i965/brw_sync.c +++ b/src/mesa/drivers/dri/i965/brw_sync.c @@ -41,9 +41,12 @@ #include /* Requires Android or libdrm-2.4.72 */ #include "util/os_file.h" +#include "util/u_memory.h" +#include #include "brw_context.h" #include "brw_batch.h" +#include "mesa/main/externalobjects.h" struct brw_fence { struct brw_context *brw; @@ -72,6 +75,89 @@ struct brw_gl_sync { struct brw_fence fence; }; +struct intel_semaphore_object { + struct gl_semaphore_object Base; + struct drm_syncobj_handle *syncobj; +}; + +static inline struct intel_semaphore_object * +intel_semaphore_object(struct gl_semaphore_object *sem_obj) { + return (struct intel_semaphore_object*) sem_obj; +} + +static struct gl_semaphore_object * +intel_semaphoreobj_alloc(struct gl_context *ctx, GLuint name) +{ + struct intel_semaphore_object *is_obj = CALLOC_STRUCT(intel_semaphore_object); + if (!is_obj) + return NULL; + + _mesa_initialize_semaphore_object(ctx, &is_obj->Base, name); + return &is_obj->Base; +} + +static void +intel_semaphoreobj_free(struct gl_context *ctx, + struct gl_semaphore_object *semObj) +{ + _mesa_delete_semaphore_object(ctx, semObj); +} + +static void +intel_semaphoreobj_import(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + int fd) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_screen *screen = brw->screen; + struct intel_semaphore_object *iSemObj = intel_semaphore_object(semObj); + iSemObj->syncobj = CALLOC_STRUCT(drm_syncobj_handle); + iSemObj->syncobj->fd = fd; + + if (drmIoctl(screen->fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, iSemObj->syncobj) < 0) { + fprintf(stderr, "DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE failed: %s\n", + strerror(errno)); + free(iSemObj->syncobj); + } +} + +static void +intel_semaphoreobj_signal(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *dstLayouts) +{ + struct brw_context *brw = brw_context(ctx); + struct intel_semaphore_object *iSemObj = intel_semaphore_object(semObj); + struct drm_i915_gem_exec_fence *fence = + util_dynarray_grow(&brw->batch.exec_fences, struct drm_i915_gem_exec_fence *, 1); + fence->flags = I915_EXEC_FENCE_SIGNAL; + fence->handle = iSemObj->syncobj->handle; +} + +static void +intel_semaphoreobj_wait(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *srcLayouts) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_screen *screen = brw->screen; + struct intel_semaphore_object *iSemObj = intel_semaphore_object(semObj); + struct drm_syncobj_wait args = { + .handles = (uintptr_t)&iSemObj->syncobj->handle, + .count_handles = 1, + }; + + drmIoctl(screen->fd, DRM_IOCTL_SYNCOBJ_WAIT, &args); +} + static void brw_fence_init(struct brw_context *brw, struct brw_fence *fence, enum brw_fence_type type) @@ -416,6 +502,11 @@ brw_init_syncobj_functions(struct dd_function_table *functions) functions->CheckSync = brw_gl_check_sync; functions->ClientWaitSync = brw_gl_client_wait_sync; functions->ServerWaitSync = brw_gl_server_wait_sync; + functions->NewSemaphoreObject = intel_semaphoreobj_alloc; + functions->DeleteSemaphoreObject = intel_semaphoreobj_free; + functions->ImportSemaphoreFd = intel_semaphoreobj_import; + functions->ServerSignalSemaphoreObject = intel_semaphoreobj_signal; + functions->ServerWaitSemaphoreObject = intel_semaphoreobj_wait; } static void *