From f536f45250a52cedbcc867637f097cddaa8c4bac Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 12 Sep 2017 20:17:31 +0200 Subject: radeonsi: implement sync_file import/export MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeon/r600_pipe_common.c | 77 ++++++++++++++++++++++++++- src/gallium/drivers/radeonsi/si_pipe.c | 4 +- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 6d28cda2771..b77d85901f0 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -39,6 +39,7 @@ #include "amd/common/sid.h" #include #include +#include #include @@ -351,6 +352,75 @@ static void r600_fence_server_sync(struct pipe_context *ctx, r600_add_fence_dependency(rctx, rfence->gfx); } +static void r600_create_fence_fd(struct pipe_context *ctx, + struct pipe_fence_handle **pfence, int fd) +{ + struct r600_common_screen *rscreen = (struct r600_common_screen*)ctx->screen; + struct radeon_winsys *ws = rscreen->ws; + struct r600_multi_fence *rfence; + + *pfence = NULL; + + if (!rscreen->info.has_sync_file) + return; + + rfence = CALLOC_STRUCT(r600_multi_fence); + if (!rfence) + return; + + pipe_reference_init(&rfence->reference, 1); + rfence->gfx = ws->fence_import_sync_file(ws, fd); + if (!rfence->gfx) { + FREE(rfence); + return; + } + + *pfence = (struct pipe_fence_handle*)rfence; +} + +static int r600_fence_get_fd(struct pipe_screen *screen, + struct pipe_fence_handle *fence) +{ + struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; + struct radeon_winsys *ws = rscreen->ws; + struct r600_multi_fence *rfence = (struct r600_multi_fence *)fence; + int gfx_fd = -1, sdma_fd = -1; + + if (!rscreen->info.has_sync_file) + return -1; + + /* Deferred fences aren't supported. */ + assert(!rfence->gfx_unflushed.ctx); + if (rfence->gfx_unflushed.ctx) + return -1; + + if (rfence->sdma) { + sdma_fd = ws->fence_export_sync_file(ws, rfence->sdma); + if (sdma_fd == -1) + return -1; + } + if (rfence->gfx) { + gfx_fd = ws->fence_export_sync_file(ws, rfence->gfx); + if (gfx_fd == -1) { + if (sdma_fd != -1) + close(sdma_fd); + return -1; + } + } + + /* If we don't have FDs at this point, it means we don't have fences + * either. */ + if (sdma_fd == -1) + return gfx_fd; + if (gfx_fd == -1) + return sdma_fd; + + /* Get a fence that will be a combination of both fences. */ + sync_accumulate("radeonsi", &gfx_fd, sdma_fd); + close(sdma_fd); + return gfx_fd; +} + static void r600_flush_from_st(struct pipe_context *ctx, struct pipe_fence_handle **fence, unsigned flags) @@ -379,9 +449,12 @@ static void r600_flush_from_st(struct pipe_context *ctx, /* Instead of flushing, create a deferred fence. Constraints: * - The state tracker must allow a deferred flush. * - The state tracker must request a fence. + * - fence_get_fd is not allowed. * Thread safety in fence_finish must be ensured by the state tracker. */ - if (flags & PIPE_FLUSH_DEFERRED && fence) { + if (flags & PIPE_FLUSH_DEFERRED && + !(flags & PIPE_FLUSH_FENCE_FD) && + fence) { gfx_fence = rctx->ws->cs_get_next_fence(rctx->gfx.cs); deferred_fence = true; } else { @@ -624,6 +697,7 @@ bool si_common_context_init(struct r600_common_context *rctx, rctx->b.memory_barrier = r600_memory_barrier; rctx->b.flush = r600_flush_from_st; rctx->b.set_debug_callback = r600_set_debug_callback; + rctx->b.create_fence_fd = r600_create_fence_fd; rctx->b.fence_server_sync = r600_fence_server_sync; rctx->dma_clear_buffer = r600_dma_clear_buffer_fallback; rctx->b.buffer_subdata = si_buffer_subdata; @@ -1292,6 +1366,7 @@ bool si_common_screen_init(struct r600_common_screen *rscreen, rscreen->b.resource_destroy = u_resource_destroy_vtbl; rscreen->b.resource_from_user_memory = si_buffer_from_user_memory; rscreen->b.query_memory_info = r600_query_memory_info; + rscreen->b.fence_get_fd = r600_fence_get_fd; if (rscreen->info.has_hw_decode) { rscreen->b.get_video_param = si_vid_get_video_param; diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 5b5f83aae10..759d5394719 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -583,7 +583,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES: case PIPE_CAP_MAX_WINDOW_RECTANGLES: - case PIPE_CAP_NATIVE_FENCE_FD: case PIPE_CAP_TGSI_FS_FBFETCH: case PIPE_CAP_TGSI_MUL_ZERO_WINS: case PIPE_CAP_UMA: @@ -592,6 +591,9 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TILE_RASTER_ORDER: return 0; + case PIPE_CAP_NATIVE_FENCE_FD: + return sscreen->b.info.has_sync_file; + case PIPE_CAP_QUERY_BUFFER_OBJECT: return si_have_tgsi_compute(sscreen); -- cgit v1.2.3