radeonsi: add timeline semaphore support to fence operations

Thread timeline_point through si_add_fence_dependency and
si_add_syncobj_signal to the winsys. Remove the assert(!value)
guards in si_fence_server_sync and si_fence_server_signal so that
non-zero timeline point values are passed through to the winsys
fence dependency and signal lists.

Add PIPE_FD_TYPE_TIMELINE_SEMAPHORE_VK handling in si_create_fence_fd,
importing the fd as a syncobj (the timeline point is applied at
wait/signal time, not at import time).

Author: Claude Opus 4.6 <noreply@anthropic.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40526>
This commit is contained in:
Qiang Yu 2026-03-19 17:15:35 +08:00 committed by Marge Bot
parent 379bf43084
commit 26418f0f58

View file

@ -124,16 +124,18 @@ void si_cp_wait_mem(struct si_context *ctx, struct radeon_cmdbuf *cs, uint64_t v
ac_emit_cp_wait_mem(&cs->current, va, ref, mask, flags);
}
static void si_add_fence_dependency(struct si_context *sctx, struct pipe_fence_handle *fence)
static void si_add_fence_dependency(struct si_context *sctx, struct pipe_fence_handle *fence,
uint64_t timeline_point)
{
struct radeon_winsys *ws = sctx->ws;
ws->cs_add_fence_dependency(&sctx->gfx_cs, fence, 0);
ws->cs_add_fence_dependency(&sctx->gfx_cs, fence, timeline_point);
}
static void si_add_syncobj_signal(struct si_context *sctx, struct pipe_fence_handle *fence)
static void si_add_syncobj_signal(struct si_context *sctx, struct pipe_fence_handle *fence,
uint64_t timeline_point)
{
sctx->ws->cs_add_syncobj_signal(&sctx->gfx_cs, fence, 0);
sctx->ws->cs_add_syncobj_signal(&sctx->gfx_cs, fence, timeline_point);
}
static void si_fence_reference(struct pipe_screen *screen, struct pipe_fence_handle **dst,
@ -356,6 +358,13 @@ static void si_create_fence_fd(struct pipe_context *ctx, struct pipe_fence_handl
sfence->gfx = ws->fence_import_syncobj(ws, fd);
break;
case PIPE_FD_TYPE_TIMELINE_SEMAPHORE_VK:
if (!sscreen->info.has_timeline_syncobj)
goto finish;
sfence->gfx = ws->fence_import_syncobj(ws, fd);
break;
default:
UNREACHABLE("bad fence fd type when importing");
}
@ -518,12 +527,11 @@ static void si_fence_server_signal(struct pipe_context *ctx, struct pipe_fence_h
{
struct si_context *sctx = (struct si_context *)ctx;
struct si_fence *sfence = (struct si_fence *)fence;
assert(!value);
assert(sfence->gfx);
if (sfence->gfx)
si_add_syncobj_signal(sctx, sfence->gfx);
si_add_syncobj_signal(sctx, sfence->gfx, value);
/**
* The spec requires a flush here. We insert a flush
@ -547,7 +555,6 @@ static void si_fence_server_sync(struct pipe_context *ctx, struct pipe_fence_han
{
struct si_context *sctx = (struct si_context *)ctx;
struct si_fence *sfence = (struct si_fence *)fence;
assert(!value);
util_queue_fence_wait(&sfence->ready);
@ -566,7 +573,7 @@ static void si_fence_server_sync(struct pipe_context *ctx, struct pipe_fence_han
* performance. Therefore, DO NOT FLUSH.
*/
if (sfence->gfx)
si_add_fence_dependency(sctx, sfence->gfx);
si_add_fence_dependency(sctx, sfence->gfx, value);
}
void si_init_fence_functions(struct si_context *ctx)