From: Hyunjun Ko Date: Sun, 19 Apr 2020 15:20:41 +0000 (+0200) Subject: freedreno: support GL_EXT_semaphore X-Git-Tag: upstream/21.0.0~6374 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e0e9712a4d8008328578c0698157924a8aff0970;p=platform%2Fupstream%2Fmesa.git freedreno: support GL_EXT_semaphore Signed-off-by: Hyunjun Ko Reviewed-by: Rob Clark Part-of: --- diff --git a/src/freedreno/drm/freedreno_device.c b/src/freedreno/drm/freedreno_device.c index f0dc53b..fbc9bcb 100644 --- a/src/freedreno/drm/freedreno_device.c +++ b/src/freedreno/drm/freedreno_device.c @@ -153,3 +153,11 @@ bool fd_dbg(void) return dbg == 1; } + +bool fd_has_syncobj(struct fd_device *dev) +{ + uint64_t value; + if (drmGetCap(dev->fd, DRM_CAP_SYNCOBJ, &value)) + return false; + return value && dev->version >= FD_VERSION_FENCE_FD; +} diff --git a/src/freedreno/drm/freedreno_drmif.h b/src/freedreno/drm/freedreno_drmif.h index 1503847..3f7b829 100644 --- a/src/freedreno/drm/freedreno_drmif.h +++ b/src/freedreno/drm/freedreno_drmif.h @@ -98,6 +98,8 @@ enum fd_version { }; enum fd_version fd_device_version(struct fd_device *dev); +bool fd_has_syncobj(struct fd_device *dev); + /* pipe functions: */ diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 4ebb279..e783a8a 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -428,6 +428,7 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, pctx->get_device_reset_status = fd_get_device_reset_status; pctx->create_fence_fd = fd_create_fence_fd; pctx->fence_server_sync = fd_fence_server_sync; + pctx->fence_server_signal = fd_fence_server_signal; pctx->texture_barrier = fd_texture_barrier; pctx->memory_barrier = fd_memory_barrier; diff --git a/src/gallium/drivers/freedreno/freedreno_fence.c b/src/gallium/drivers/freedreno/freedreno_fence.c index 3477d98..9f0f6ee 100644 --- a/src/gallium/drivers/freedreno/freedreno_fence.c +++ b/src/gallium/drivers/freedreno/freedreno_fence.c @@ -32,6 +32,8 @@ #include "freedreno_fence.h" #include "freedreno_context.h" #include "freedreno_util.h" +/* TODO: Use the interface drm/freedreno_drmif.h instead of calling directly */ +#include struct pipe_fence_handle { struct pipe_reference reference; @@ -44,6 +46,7 @@ struct pipe_fence_handle { struct fd_screen *screen; int fence_fd; uint32_t timestamp; + uint32_t syncobj; }; static void fence_flush(struct pipe_fence_handle *fence) @@ -99,7 +102,7 @@ bool fd_fence_finish(struct pipe_screen *pscreen, } static struct pipe_fence_handle * fence_create(struct fd_context *ctx, - struct fd_batch *batch, uint32_t timestamp, int fence_fd) + struct fd_batch *batch, uint32_t timestamp, int fence_fd, int syncobj) { struct pipe_fence_handle *fence; @@ -114,6 +117,7 @@ static struct pipe_fence_handle * fence_create(struct fd_context *ctx, fence->screen = ctx->screen; fence->timestamp = timestamp; fence->fence_fd = fence_fd; + fence->syncobj = syncobj; return fence; } @@ -122,8 +126,27 @@ void fd_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfence, int fd, enum pipe_fd_type type) { - assert(type == PIPE_FD_TYPE_NATIVE_SYNC); - *pfence = fence_create(fd_context(pctx), NULL, 0, os_dupfd_cloexec(fd)); + struct fd_context *ctx = fd_context(pctx); + + switch (type) { + case PIPE_FD_TYPE_NATIVE_SYNC: + *pfence = fence_create(fd_context(pctx), NULL, 0, os_dupfd_cloexec(fd), 0); + break; + case PIPE_FD_TYPE_SYNCOBJ: { + int ret; + uint32_t syncobj; + + assert(ctx->screen->has_syncobj); + ret = drmSyncobjFDToHandle(fd_device_fd(ctx->screen->dev), fd, &syncobj); + if (!ret) + close(fd); + + *pfence = fence_create(fd_context(pctx), NULL, 0, -1, syncobj); + break; + } + default: + unreachable("Unhandled fence type"); + } } void fd_fence_server_sync(struct pipe_context *pctx, @@ -143,6 +166,16 @@ void fd_fence_server_sync(struct pipe_context *pctx, } } +void fd_fence_server_signal(struct pipe_context *pctx, + struct pipe_fence_handle *fence) +{ + struct fd_context *ctx = fd_context(pctx); + + if (fence->syncobj) { + drmSyncobjSignal(fd_device_fd(ctx->screen->dev), &fence->syncobj, 1); + } +} + int fd_fence_get_fd(struct pipe_screen *pscreen, struct pipe_fence_handle *fence) { @@ -157,5 +190,5 @@ bool fd_fence_is_fd(struct pipe_fence_handle *fence) struct pipe_fence_handle * fd_fence_create(struct fd_batch *batch) { - return fence_create(batch->ctx, batch, 0, -1); + return fence_create(batch->ctx, batch, 0, -1, 0); } diff --git a/src/gallium/drivers/freedreno/freedreno_fence.h b/src/gallium/drivers/freedreno/freedreno_fence.h index efb9aae..0d17e1e 100644 --- a/src/gallium/drivers/freedreno/freedreno_fence.h +++ b/src/gallium/drivers/freedreno/freedreno_fence.h @@ -42,6 +42,8 @@ void fd_create_fence_fd(struct pipe_context *pctx, enum pipe_fd_type type); void fd_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *fence); +void fd_fence_server_signal(struct pipe_context *ctx, + struct pipe_fence_handle *fence); int fd_fence_get_fd(struct pipe_screen *pscreen, struct pipe_fence_handle *pfence); bool fd_fence_is_fd(struct pipe_fence_handle *fence); diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 9f0867b..f7c8cf9 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -457,6 +457,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return fd_device_version(screen->dev) >= FD_VERSION_MEMORY_FD; case PIPE_CAP_NATIVE_FENCE_FD: return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD; + case PIPE_CAP_FENCE_SIGNAL: + return screen->has_syncobj; default: return u_pipe_screen_get_param_defaults(pscreen, param); } @@ -930,6 +932,8 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro) if (fd_device_version(dev) >= FD_VERSION_ROBUSTNESS) screen->has_robustness = true; + screen->has_syncobj = fd_has_syncobj(screen->dev); + struct sysinfo si; sysinfo(&si); screen->ram_size = si.totalram; diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index c2a13f5..4707496 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -76,6 +76,7 @@ struct fd_screen { uint32_t priority_mask; bool has_timestamp; bool has_robustness; + bool has_syncobj; unsigned num_perfcntr_groups; const struct fd_perfcntr_group *perfcntr_groups;