diff options
author | Marek Olšák <[email protected]> | 2017-09-02 00:31:58 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-09-11 16:29:52 +0200 |
commit | 3824ca76108076350f22489a0d73486549ef0168 (patch) | |
tree | 4542d9a3d28ab15dfa863b9f63999b8c6cf3536b /src/gallium/drivers/radeon | |
parent | 8843bf6dfd4bcca7bcb6dfa64cd959ba7bdb0931 (diff) |
radeonsi: implement pipe_context::fence_server_sync
This will be more useful once we have sync_file support.
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeon')
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.c | 45 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_winsys.h | 7 |
2 files changed, 52 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index b17bf80bf50..fc27b4c218b 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -411,6 +411,50 @@ void r600_postflush_resume_features(struct r600_common_context *ctx) r600_resume_queries(ctx); } +static void r600_add_fence_dependency(struct r600_common_context *rctx, + struct pipe_fence_handle *fence) +{ + struct radeon_winsys *ws = rctx->ws; + + if (rctx->dma.cs) + ws->cs_add_fence_dependency(rctx->dma.cs, fence); + ws->cs_add_fence_dependency(rctx->gfx.cs, fence); +} + +static void r600_fence_server_sync(struct pipe_context *ctx, + struct pipe_fence_handle *fence) +{ + struct r600_common_context *rctx = (struct r600_common_context *)ctx; + struct r600_multi_fence *rfence = (struct r600_multi_fence *)fence; + + /* Only amdgpu needs to handle fence dependencies (for fence imports). + * radeon synchronizes all rings by default and will not implement + * fence imports. + */ + if (rctx->screen->info.drm_major == 2) + return; + + /* Only imported fences need to be handled by fence_server_sync, + * because the winsys handles synchronizations automatically for BOs + * within the process. + * + * Simply skip unflushed fences here, and the winsys will drop no-op + * dependencies (i.e. dependencies within the same ring). + */ + if (rfence->gfx_unflushed.ctx) + return; + + /* All unflushed commands will not start execution before + * this fence dependency is signalled. + * + * Should we flush the context to allow more GPU parallelism? + */ + if (rfence->sdma) + r600_add_fence_dependency(rctx, rfence->sdma); + if (rfence->gfx) + r600_add_fence_dependency(rctx, rfence->gfx); +} + static void r600_flush_from_st(struct pipe_context *ctx, struct pipe_fence_handle **fence, unsigned flags) @@ -684,6 +728,7 @@ bool r600_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.fence_server_sync = r600_fence_server_sync; rctx->dma_clear_buffer = r600_dma_clear_buffer_fallback; /* evergreen_compute.c has a special codepath for global buffers. diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index f0a0a922a10..99e22e06857 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -574,6 +574,13 @@ struct radeon_winsys { void (*cs_sync_flush)(struct radeon_winsys_cs *cs); /** + * Add a fence dependency to the CS, so that the CS will wait for + * the fence before execution. + */ + void (*cs_add_fence_dependency)(struct radeon_winsys_cs *cs, + struct pipe_fence_handle *fence); + + /** * Wait for the fence and return true if the fence has been signalled. * The timeout of 0 will only return the status. * The timeout of PIPE_TIMEOUT_INFINITE will always wait until the fence |