i965: Implement semaphore support for EXT_external_objects

Implement importing, signalling and waiting for EXT_external_objects

Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
Reviewed-by: Eleni Maria Stea <estea@igalia.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5594>
This commit is contained in:
Rohan Garg 2020-06-09 19:13:19 +02:00 committed by Rohan Garg
parent f73aeca0ce
commit 0b564e52d7
4 changed files with 111 additions and 0 deletions

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -41,9 +41,12 @@
#include <libsync.h> /* Requires Android or libdrm-2.4.72 */
#include "util/os_file.h"
#include "util/u_memory.h"
#include <xf86drm.h>
#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 *