Commit 48458c92 authored by Qiang Yu's avatar Qiang Yu

lima: support EGL_ANDROID_native_fence_sync

Signed-off-by: Qiang Yu's avatarQiang Yu <yuq825@gmail.com>
parent ad570b85
......@@ -49,4 +49,6 @@ C_SOURCES := \
lima_util.h \
lima_texture.c \
lima_texture.h \
lima_fence.c \
lima_fence.h \
$(ir_SOURCES)
......@@ -38,6 +38,7 @@
#include "lima_bo.h"
#include "lima_submit.h"
#include "lima_util.h"
#include "lima_fence.h"
#include <lima_drm.h>
#include <xf86drm.h>
......@@ -179,6 +180,7 @@ lima_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->base.destroy = lima_context_destroy;
lima_resource_context_init(ctx);
lima_fence_context_init(ctx);
lima_state_init(ctx);
lima_draw_init(ctx);
lima_program_init(ctx);
......
......@@ -40,6 +40,7 @@
#include "lima_submit.h"
#include "lima_texture.h"
#include "lima_util.h"
#include "lima_fence.h"
#include <lima_drm.h>
......@@ -1070,14 +1071,9 @@ lima_pack_pp_frame_reg(struct lima_context *ctx, uint32_t *frame_reg,
wb[0].mrt_bits = swap_channels ? 0x4 : 0x0;
}
void
lima_flush(struct lima_context *ctx)
static void
_lima_flush(struct lima_context *ctx)
{
if (!ctx->num_draws) {
debug_printf("%s: do nothing\n", __FUNCTION__);
return;
}
lima_finish_plbu_cmd(ctx);
int vs_cmd_size = ctx->vs_cmd_array.size;
......@@ -1175,15 +1171,36 @@ lima_flush(struct lima_context *ctx)
ctx->plb_index = (ctx->plb_index + 1) % lima_ctx_num_plb;
}
void
lima_flush(struct lima_context *ctx)
{
if (!ctx->num_draws) {
debug_printf("%s: do nothing\n", __FUNCTION__);
return;
}
_lima_flush(ctx);
}
static void
lima_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
unsigned flags)
{
debug_checkpoint();
debug_printf("%s: flags=%x\n", __FUNCTION__, flags);
struct lima_context *ctx = lima_context(pctx);
lima_flush(ctx);
if (!ctx->num_draws) {
debug_printf("%s: do nothing\n", __FUNCTION__);
return;
}
if ((flags & PIPE_FLUSH_FENCE_FD) && fence)
lima_submit_need_sync_fd(ctx->pp_submit);
_lima_flush(ctx);
if (fence)
*fence = lima_fence_create(ctx, lima_submit_get_sync_fd(ctx->pp_submit));
}
void
......
/*
* Copyright (c) 2018 Lima Project
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#include <libsync.h>
#include <util/u_memory.h>
#include <util/u_inlines.h>
#include "lima_drm.h"
#include "lima_screen.h"
#include "lima_context.h"
#include "lima_fence.h"
#include "lima_submit.h"
struct pipe_fence_handle {
struct pipe_reference reference;
struct lima_context *ctx;
uint32_t seqno;
int sync_fd;
};
static void
lima_create_fence_fd(struct pipe_context *pctx,
struct pipe_fence_handle **fence,
int fd)
{
debug_printf("%s: fd=%d\n", __FUNCTION__, fd);
struct lima_context *ctx = lima_context(pctx);
*fence = lima_fence_create(ctx, dup(fd));
}
static void
lima_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *fence)
{
debug_checkpoint();
struct lima_context *ctx = lima_context(pctx);
union drm_lima_gem_submit_dep dep;
if (fence->sync_fd >= 0) {
dep.type = LIMA_SUBMIT_DEP_SYNC_FD;
dep.sync_fd.fd = fence->sync_fd;
debug_printf("add sync fd dep %d\n", fence->sync_fd);
}
else {
dep.type = LIMA_SUBMIT_DEP_FENCE;
dep.fence.ctx = ctx->id;
dep.fence.pipe = LIMA_PIPE_PP;
dep.fence.seq = fence->seqno;
debug_printf("add native fence %u\n", fence->seqno);
}
lima_submit_add_dep(ctx->gp_submit, &dep);
}
void lima_fence_context_init(struct lima_context *ctx)
{
ctx->base.create_fence_fd = lima_create_fence_fd;
ctx->base.fence_server_sync = lima_fence_server_sync;
}
struct pipe_fence_handle *
lima_fence_create(struct lima_context *ctx, int sync_fd)
{
debug_printf("%s: sync_fd=%d\n", __FUNCTION__, sync_fd);
struct pipe_fence_handle *fence;
fence = CALLOC_STRUCT(pipe_fence_handle);
if (!fence)
return NULL;
pipe_reference_init(&fence->reference, 1);
fence->ctx = ctx;
fence->sync_fd = sync_fd;
if (sync_fd < 0) {
if (!lima_submit_get_fence(ctx->pp_submit, &fence->seqno)) {
FREE(fence);
return NULL;
}
}
return fence;
}
static int
lima_fence_get_fd(struct pipe_screen *pscreen,
struct pipe_fence_handle *fence)
{
debug_checkpoint();
assert(fence->sync_fd >= 0);
return dup(fence->sync_fd);
}
static void
lima_fence_destroy(struct pipe_fence_handle *fence)
{
if (fence->sync_fd >= 0)
close(fence->sync_fd);
FREE(fence);
}
static void
lima_fence_reference(struct pipe_screen *pscreen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
debug_checkpoint();
if (pipe_reference(&(*ptr)->reference, &fence->reference))
lima_fence_destroy(*ptr);
*ptr = fence;
}
static boolean
lima_fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx,
struct pipe_fence_handle *fence, uint64_t timeout)
{
debug_checkpoint();
if (fence->sync_fd >= 0) {
debug_printf("wait sync fd %d\n", fence->sync_fd);
return !sync_wait(fence->sync_fd, timeout / 1000000);
}
debug_printf("wait native fence %u\n", fence->seqno);
return lima_submit_wait_fence(fence->ctx->pp_submit, fence->seqno, timeout);
}
void
lima_fence_screen_init(struct lima_screen *screen)
{
screen->base.fence_reference = lima_fence_reference;
screen->base.fence_finish = lima_fence_finish;
screen->base.fence_get_fd = lima_fence_get_fd;
}
/*
* Copyright (c) 2018 Lima Project
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#ifndef H_LIMA_FENCE
#define H_LIMA_FENCE
struct pipe_fence_handle;
struct lima_context;
struct lima_screen;
struct pipe_fence_handle *
lima_fence_create(struct lima_context *ctx, int sync_fd);
void lima_fence_screen_init(struct lima_screen *screen);
void lima_fence_context_init(struct lima_context *ctx);
#endif
......@@ -34,6 +34,7 @@
#include "lima_program.h"
#include "lima_vamgr.h"
#include "lima_bo.h"
#include "lima_fence.h"
#include "ir/lima_ir.h"
#include "xf86drm.h"
......@@ -104,6 +105,7 @@ lima_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_UMA:
case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
case PIPE_CAP_FORCE_COMPUTE_MINMAX_INDICES:
case PIPE_CAP_NATIVE_FENCE_FD:
return 1;
/* Unimplemented, but for exporting OpenGL 2.0 */
......@@ -431,6 +433,7 @@ lima_screen_create(int fd, struct renderonly *ro)
screen->base.get_compiler_options = lima_screen_get_compiler_options;
lima_resource_screen_init(screen);
lima_fence_screen_init(screen);
slab_create_parent(&screen->transfer_pool, sizeof(struct lima_transfer), 16);
......
......@@ -49,6 +49,9 @@ struct lima_submit {
uint32_t pipe;
uint32_t ctx;
int sync_fd;
bool need_sync_fd;
struct util_dynarray gem_bos;
struct util_dynarray deps;
......@@ -147,6 +150,7 @@ bool lima_submit_start(struct lima_submit *submit, void *frame, uint32_t size)
.frame_size = size,
.deps = submit->deps.size ? VOID2U64(util_dynarray_begin(&submit->deps)) : 0,
.nr_deps = submit->deps.size / sizeof(union drm_lima_gem_submit_dep),
.flags = submit->need_sync_fd ? LIMA_SUBMIT_FLAG_SYNC_FD_OUT : 0,
},
};
......@@ -157,6 +161,8 @@ bool lima_submit_start(struct lima_submit *submit, void *frame, uint32_t size)
job->fence = req.out.fence;
list_add(&job->list, &submit->busy_job_list);
submit->sync_fd = submit->need_sync_fd ? req.out.sync_fd : -1;
int i = 0;
list_for_each_entry_safe(struct lima_submit_job, j,
&submit->busy_job_list, list) {
......@@ -171,6 +177,7 @@ bool lima_submit_start(struct lima_submit *submit, void *frame, uint32_t size)
util_dynarray_clear(&submit->gem_bos);
util_dynarray_clear(&submit->deps);
submit->need_sync_fd = false;
submit->current_job = NULL;
return ret;
}
......@@ -249,3 +256,13 @@ bool lima_submit_add_dep(struct lima_submit *submit,
*submit_dep = *dep;
return true;
}
void lima_submit_need_sync_fd(struct lima_submit *submit)
{
submit->need_sync_fd = true;
}
int lima_submit_get_sync_fd(struct lima_submit *submit)
{
return submit->sync_fd;
}
......@@ -42,5 +42,7 @@ bool lima_submit_wait_fence(struct lima_submit *submit, uint32_t fence,
uint64_t timeout_ns);
bool lima_submit_add_dep(struct lima_submit *submit,
union drm_lima_gem_submit_dep *dep);
void lima_submit_need_sync_fd(struct lima_submit *submit);
int lima_submit_get_sync_fd(struct lima_submit *submit);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment