gallium: fix timeline semaphore value passing

using a screen method for this is broken since the value can change
before it is flushed. it must be passed along with the methods that use it

Acked-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35866>
This commit is contained in:
Mike Blumenkrantz 2025-07-01 11:48:43 -04:00 committed by Marge Bot
parent ab1dbd0899
commit 035d837a92
50 changed files with 146 additions and 110 deletions

View file

@ -1088,7 +1088,7 @@ wgl_wait_sync_khr(_EGLDisplay *disp, _EGLSync *sync)
struct pipe_context *pipe = wgl_ctx->ctx->st->pipe;
if (pipe->fence_server_sync)
pipe->fence_server_sync(pipe, wgl_sync->fence);
pipe->fence_server_sync(pipe, wgl_sync->fence, 0);
return EGL_TRUE;
}

View file

@ -590,12 +590,13 @@ dd_context_set_stream_output_targets(struct pipe_context *_pipe,
static void
dd_context_fence_server_sync(struct pipe_context *_pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
pipe->fence_server_sync(pipe, fence);
pipe->fence_server_sync(pipe, fence, value);
}

View file

@ -745,15 +745,6 @@ static void noop_vertex_state_destroy(struct pipe_screen *screen,
FREE(state);
}
static void noop_set_fence_timeline_value(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
uint64_t value)
{
struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen *)screen;
struct pipe_screen *oscreen = noop_screen->oscreen;
oscreen->set_fence_timeline_value(oscreen, fence, value);
}
static struct pipe_screen * noop_get_driver_pipe_screen(struct pipe_screen *_screen)
{
struct pipe_screen * screen = ((struct noop_pipe_screen*)_screen)->oscreen;
@ -816,8 +807,6 @@ struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen)
screen->vertex_state_destroy = noop_vertex_state_destroy;
if (oscreen->get_sparse_texture_virtual_page_size)
screen->get_sparse_texture_virtual_page_size = noop_get_sparse_texture_virtual_page_size;
if (oscreen->set_fence_timeline_value)
screen->set_fence_timeline_value = noop_set_fence_timeline_value;
screen->query_compression_rates = noop_query_compression_rates;
screen->query_compression_modifiers = noop_query_compression_modifiers;
screen->get_driver_pipe_screen = noop_get_driver_pipe_screen;

View file

@ -331,7 +331,8 @@ static void noop_clear_buffer(struct pipe_context *pipe,
}
static void noop_fence_server_sync(struct pipe_context *pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
}

View file

@ -1619,7 +1619,8 @@ trace_context_create_fence_fd(struct pipe_context *_pipe,
static void
trace_context_fence_server_sync(struct pipe_context *_pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t timeline_value)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
@ -1628,8 +1629,9 @@ trace_context_fence_server_sync(struct pipe_context *_pipe,
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, fence);
trace_dump_arg(uint, timeline_value);
pipe->fence_server_sync(pipe, fence);
pipe->fence_server_sync(pipe, fence, timeline_value);
trace_dump_call_end();
}
@ -1637,7 +1639,8 @@ trace_context_fence_server_sync(struct pipe_context *_pipe,
static void
trace_context_fence_server_signal(struct pipe_context *_pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t timeline_value)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
@ -1646,8 +1649,9 @@ trace_context_fence_server_signal(struct pipe_context *_pipe,
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, fence);
trace_dump_arg(uint, timeline_value);
pipe->fence_server_signal(pipe, fence);
pipe->fence_server_signal(pipe, fence, timeline_value);
trace_dump_call_end();
}

View file

@ -1243,6 +1243,7 @@ void trace_dump_pipe_picture_desc(const struct pipe_picture_desc *picture)
trace_dump_member(bool, picture, input_full_range);
trace_dump_member(format, picture, output_format);
trace_dump_member(ptr, picture, in_fence);
trace_dump_member(uint, picture, in_fence_value);
trace_dump_member(ptr, picture, out_fence);
trace_dump_struct_end();
}

View file

@ -1332,22 +1332,6 @@ static void trace_screen_vertex_state_destroy(struct pipe_screen *_screen,
screen->vertex_state_destroy(screen, state);
}
static void trace_screen_set_fence_timeline_value(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
uint64_t value)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
trace_dump_call_begin("pipe_screen", "set_fence_timeline_value");
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, fence);
trace_dump_arg(uint, value);
trace_dump_call_end();
screen->set_fence_timeline_value(screen, fence, value);
}
static void trace_screen_query_compression_rates(struct pipe_screen *_screen,
enum pipe_format format,
int max, uint32_t *rates,
@ -1569,7 +1553,6 @@ trace_screen_create(struct pipe_screen *screen)
SCR_INIT(vertex_state_destroy);
tr_scr->base.transfer_helper = screen->transfer_helper;
SCR_INIT(get_sparse_texture_virtual_page_size);
SCR_INIT(set_fence_timeline_value);
SCR_INIT(driver_thread_add_job);
SCR_INIT(query_compression_rates);
SCR_INIT(query_compression_modifiers);

View file

@ -572,7 +572,7 @@ test_sync_file_fences(struct pipe_context *ctx)
/* Run another clear after waiting for everything. */
struct pipe_fence_handle *final_fence = NULL;
ctx->fence_server_sync(ctx, merged_fence);
ctx->fence_server_sync(ctx, merged_fence, 0);
value = 0xff;
ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value));
ctx->flush(ctx, &final_fence, PIPE_FLUSH_FENCE_FD);

View file

@ -3387,21 +3387,24 @@ tc_create_fence_fd(struct pipe_context *_pipe,
struct tc_fence_call {
struct tc_call_base base;
struct pipe_fence_handle *fence;
uint64_t value;
};
static uint16_t ALWAYS_INLINE
tc_call_fence_server_sync(struct pipe_context *pipe, void *call)
{
struct pipe_fence_handle *fence = to_call(call, tc_fence_call)->fence;
struct tc_fence_call *p = (void*)to_call(call, tc_fence_call);
struct pipe_fence_handle *fence = p->fence;
pipe->fence_server_sync(pipe, fence);
pipe->fence_server_sync(pipe, fence, p->value);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
return call_size(tc_fence_call);
}
static void
tc_fence_server_sync(struct pipe_context *_pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct threaded_context *tc = threaded_context(_pipe);
struct pipe_screen *screen = tc->pipe->screen;
@ -3410,17 +3413,19 @@ tc_fence_server_sync(struct pipe_context *_pipe,
call->fence = NULL;
screen->fence_reference(screen, &call->fence, fence);
call->value = value;
}
static void
tc_fence_server_signal(struct pipe_context *_pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct threaded_context *tc = threaded_context(_pipe);
struct pipe_context *pipe = tc->pipe;
tc_sync(tc);
tc_set_driver_thread(tc);
pipe->fence_server_signal(pipe, fence);
pipe->fence_server_signal(pipe, fence, value);
tc_clear_driver_thread(tc);
}

View file

@ -147,11 +147,12 @@ agx_create_fence_fd(struct pipe_context *pctx,
}
void
agx_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *f)
agx_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *f, uint64_t value)
{
struct agx_device *dev = agx_device(pctx->screen);
struct agx_context *ctx = agx_context(pctx);
int fd = -1, ret;
assert(!value);
ret = drmSyncobjExportSyncFile(dev->fd, f->syncobj, &fd);
assert(!ret);

View file

@ -36,4 +36,5 @@ void agx_create_fence_fd(struct pipe_context *pctx,
enum pipe_fd_type type);
void agx_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *f);
struct pipe_fence_handle *f,
uint64_t value);

View file

@ -258,9 +258,10 @@ crocus_fence_flush(struct pipe_context *ctx,
}
static void
crocus_fence_await(struct pipe_context *ctx, struct pipe_fence_handle *fence)
crocus_fence_await(struct pipe_context *ctx, struct pipe_fence_handle *fence, uint64_t value)
{
struct crocus_context *ice = (struct crocus_context *)ctx;
assert(!value);
/* Unflushed fences from the same context are no-ops. */
if (ctx && ctx == fence->unflushed_ctx)
@ -532,9 +533,10 @@ crocus_fence_create_fd(struct pipe_context *ctx, struct pipe_fence_handle **out,
}
static void
crocus_fence_signal(struct pipe_context *ctx, struct pipe_fence_handle *fence)
crocus_fence_signal(struct pipe_context *ctx, struct pipe_fence_handle *fence, uint64_t value)
{
struct crocus_context *ice = (struct crocus_context *)ctx;
assert(!value);
if (ctx == fence->unflushed_ctx)
return;

View file

@ -197,21 +197,22 @@ d3d12_flush_resource(struct pipe_context *pctx,
static void
d3d12_signal(struct pipe_context *pipe,
struct pipe_fence_handle *pfence)
struct pipe_fence_handle *pfence,
uint64_t value)
{
struct d3d12_screen *screen = d3d12_screen(pipe->screen);
struct d3d12_fence *fence = d3d12_fence(pfence);
d3d12_flush_cmdlist(d3d12_context(pipe));
screen->cmdqueue->Signal(fence->cmdqueue_fence, fence->value);
d3d12_fence_signal_impl(fence, screen->cmdqueue, value);
}
static void
d3d12_wait(struct pipe_context *pipe, struct pipe_fence_handle *pfence)
d3d12_wait(struct pipe_context *pipe, struct pipe_fence_handle *pfence, uint64_t value)
{
struct d3d12_screen *screen = d3d12_screen(pipe->screen);
struct d3d12_fence *fence = d3d12_fence(pfence);
d3d12_flush_cmdlist(d3d12_context(pipe));
screen->cmdqueue->Wait(fence->cmdqueue_fence, fence->value);
d3d12_fence_wait_impl(fence, screen->cmdqueue, value);
}
static void

View file

@ -111,8 +111,6 @@ d3d12_open_fence(struct d3d12_screen *screen, HANDLE handle, const void *name, p
}
ret->type = type;
/* A new value will be assigned later */
ret->value = 0;
pipe_reference_init(&ret->reference, 1);
return ret;
}
@ -169,6 +167,22 @@ fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx,
return ret;
}
void
d3d12_fence_signal_impl(struct d3d12_fence *fence, ID3D12CommandQueue *queue, uint64_t value)
{
if (fence->type == PIPE_FD_TYPE_NATIVE_SYNC)
value = fence->value;
queue->Signal(fence->cmdqueue_fence, value);
}
void
d3d12_fence_wait_impl(struct d3d12_fence *fence, ID3D12CommandQueue *queue, uint64_t value)
{
if (fence->type == PIPE_FD_TYPE_NATIVE_SYNC)
value = fence->value;
queue->Wait(fence->cmdqueue_fence, value);
}
void
d3d12_screen_fence_init(struct pipe_screen *pscreen)
{

View file

@ -122,6 +122,11 @@ d3d12_fence_finish(struct d3d12_fence *fence, uint64_t timeout_ns);
void
d3d12_screen_fence_init(struct pipe_screen *pscreen);
void
d3d12_fence_wait_impl(struct d3d12_fence *fence, ID3D12CommandQueue *queue, uint64_t value);
void
d3d12_fence_signal_impl(struct d3d12_fence *fence, ID3D12CommandQueue *queue, uint64_t value);
#if defined(__cplusplus)
#include <memory>
struct d3d12_fence_deleter

View file

@ -1143,12 +1143,6 @@ d3d12_create_fence_win32(struct pipe_screen *pscreen, struct pipe_fence_handle *
*pfence = (struct pipe_fence_handle*) d3d12_open_fence(d3d12_screen(pscreen), handle, name, type);
}
static void
d3d12_set_fence_timeline_value(struct pipe_screen *pscreen, struct pipe_fence_handle *pfence, uint64_t value)
{
d3d12_fence(pfence)->value = value;
}
static uint32_t
d3d12_interop_query_device_info(struct pipe_screen *pscreen, uint32_t data_size, void *data)
{
@ -1288,7 +1282,6 @@ d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LU
screen->base.get_driver_uuid = d3d12_get_driver_uuid;
screen->base.get_device_node_mask = d3d12_get_node_mask;
screen->base.create_fence_win32 = d3d12_create_fence_win32;
screen->base.set_fence_timeline_value = d3d12_set_fence_timeline_value;
screen->base.interop_query_device_info = d3d12_interop_query_device_info;
screen->base.interop_export_object = d3d12_interop_export_object;
#ifdef _WIN32

View file

@ -696,7 +696,7 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
// GPU wait on the graphics context which will do the copy until the decode finishes
pD3D12Dec->base.context->fence_server_sync(pD3D12Dec->base.context,
(struct pipe_fence_handle *)pD3D12Dec->m_inflightResourcesPool[inflightIndexBeforeFlush].m_fence.get());
(struct pipe_fence_handle *)pD3D12Dec->m_inflightResourcesPool[inflightIndexBeforeFlush].m_fence.get(), 0);
// Copy all format subresources/texture planes
for (PlaneSlice = 0; PlaneSlice < pD3D12Dec->m_decodeFormatInfo.PlaneCount; PlaneSlice++) {

View file

@ -123,7 +123,8 @@ d3d12_video_encoder_flush(struct pipe_video_codec *codec)
struct d3d12_fence *input_surface_fence = pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_InputSurfaceFence;
if (input_surface_fence)
pD3D12Enc->m_spEncodeCommandQueue->Wait(input_surface_fence->cmdqueue_fence, input_surface_fence->value);
d3d12_fence_wait_impl(input_surface_fence, pD3D12Enc->m_spEncodeCommandQueue.Get(),
pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_InputSurfaceFenceValue);
if (!pD3D12Enc->m_bPendingWorkNotFlushed) {
debug_printf("[d3d12_video_encoder] d3d12_video_encoder_flush started. Nothing to flush, all up to date.\n");
@ -2727,6 +2728,7 @@ d3d12_video_encoder_begin_frame(struct pipe_video_codec * codec,
}
pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_InputSurfaceFence = d3d12_fence(picture->in_fence);
pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_InputSurfaceFenceValue = picture->in_fence_value;
pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].encode_result = PIPE_VIDEO_FEEDBACK_METADATA_ENCODE_FLAG_OK;
pD3D12Enc->m_spEncodedFrameMetadata[d3d12_video_encoder_metadata_current_index(pD3D12Enc)].encode_result = PIPE_VIDEO_FEEDBACK_METADATA_ENCODE_FLAG_OK;

View file

@ -591,6 +591,7 @@ struct d3d12_video_encoder
ComPtr<ID3D12CommandAllocator> m_spCommandAllocator;
struct d3d12_fence* m_InputSurfaceFence = NULL;
uint64_t m_InputSurfaceFenceValue = 0;
d3d12_unique_fence m_CompletionFence;
/* Stores encode result for submission error control in the D3D12_VIDEO_ENC_ASYNC_DEPTH slots */

View file

@ -195,6 +195,7 @@ d3d12_video_processor_process_frame(struct pipe_video_codec *codec,
// begin_frame gets only called once so wouldn't update process_properties->base.in_fence correctly
pD3D12Proc->input_surface_fence = (struct d3d12_fence*) process_properties->base.in_fence;
pD3D12Proc->input_surface_fence_value = process_properties->base.in_fence_value;
// Get the underlying resources from the pipe_video_buffers
struct d3d12_video_buffer *pInputVideoBuffer = (struct d3d12_video_buffer *) input_texture;
@ -370,7 +371,7 @@ d3d12_video_processor_flush(struct pipe_video_codec * codec)
struct d3d12_fence *input_surface_fence = pD3D12Proc->input_surface_fence;
if (input_surface_fence)
pD3D12Proc->m_spCommandQueue->Wait(input_surface_fence->cmdqueue_fence, input_surface_fence->value);
d3d12_fence_wait_impl(input_surface_fence, pD3D12Proc->m_spCommandQueue.Get(), pD3D12Proc->input_surface_fence_value);
ID3D12CommandList *ppCommandLists[1] = { pD3D12Proc->m_spCommandList.Get() };
pD3D12Proc->m_spCommandQueue->ExecuteCommandLists(1, ppCommandLists);

View file

@ -126,6 +126,7 @@ struct d3d12_video_processor
D3D12_FEATURE_DATA_VIDEO_PROCESS_MAX_INPUT_STREAMS m_vpMaxInputStreams = { };
struct d3d12_fence* input_surface_fence = NULL;
uint64_t input_surface_fence_value;
};
struct pipe_video_codec *

View file

@ -85,9 +85,11 @@ etna_create_fence_fd(struct pipe_context *pctx,
void
etna_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *pfence)
struct pipe_fence_handle *pfence,
uint64_t value)
{
struct etna_context *ctx = etna_context(pctx);
assert(!value);
if (pfence->fence_fd != -1)
sync_accumulate("etnaviv", &ctx->in_fence_fd, pfence->fence_fd);

View file

@ -37,7 +37,8 @@ etna_create_fence_fd(struct pipe_context *pctx,
void
etna_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *fence);
struct pipe_fence_handle *fence,
uint64_t value);
int
etna_fence_get_fd(struct pipe_screen *pscreen,

View file

@ -209,9 +209,10 @@ fd_create_pipe_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pf
}
void
fd_pipe_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *fence)
fd_pipe_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *fence, uint64_t value)
{
struct fd_context *ctx = fd_context(pctx);
assert(!value);
MESA_TRACE_FUNC();
@ -221,7 +222,7 @@ fd_pipe_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *f
fence_flush(pctx, fence, 0);
if (fence->last_fence) {
fd_pipe_fence_server_sync(pctx, fence->last_fence);
fd_pipe_fence_server_sync(pctx, fence->last_fence, 0);
return;
}
@ -273,10 +274,12 @@ fd_pipe_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *f
void
fd_pipe_fence_server_signal(struct pipe_context *pctx,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
in_dt
{
struct fd_context *ctx = fd_context(pctx);
assert(!value);
if (fence->syncobj) {
/* syncobj (ie. semaphore) fences can be used multiple times, as

View file

@ -75,9 +75,11 @@ void fd_create_pipe_fence_fd(struct pipe_context *pctx,
struct pipe_fence_handle **pfence, int fd,
enum pipe_fd_type type);
void fd_pipe_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *fence);
struct pipe_fence_handle *fence,
uint64_t value);
void fd_pipe_fence_server_signal(struct pipe_context *ctx,
struct pipe_fence_handle *fence);
struct pipe_fence_handle *fence,
uint64_t value);
int fd_pipe_fence_get_fd(struct pipe_screen *pscreen,
struct pipe_fence_handle *pfence);
bool fd_pipe_fence_is_fd(struct pipe_fence_handle *fence);

View file

@ -323,9 +323,11 @@ syncobj_wait_available(int drm_fd, uint32_t handle)
static void
iris_fence_await(struct pipe_context *ctx,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct iris_context *ice = (struct iris_context *)ctx;
assert(!value);
/* Unflushed fences from the same context are no-ops. */
if (ctx && ctx == fence->unflushed_ctx)
@ -609,9 +611,11 @@ iris_fence_create_fd(struct pipe_context *ctx,
static void
iris_fence_signal(struct pipe_context *ctx,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct iris_context *ice = (struct iris_context *)ctx;
assert(!value);
if (ctx == fence->unflushed_ctx)
return;

View file

@ -52,9 +52,11 @@ lima_create_fence_fd(struct pipe_context *pctx,
static void
lima_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct lima_context *ctx = lima_context(pctx);
assert(!value);
sync_accumulate("lima", &ctx->in_sync_fd, fence->fd);
}

View file

@ -124,9 +124,11 @@ do_flush(struct pipe_context *pipe,
static void
llvmpipe_fence_server_sync(struct pipe_context *pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct lp_fence *f = (struct lp_fence *)fence;
assert(!value);
if (!f->issued)
return;

View file

@ -960,11 +960,13 @@ panfrost_create_fence_fd(struct pipe_context *pctx,
static void
panfrost_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *f)
struct pipe_fence_handle *f,
uint64_t value)
{
struct panfrost_device *dev = pan_device(pctx->screen);
struct panfrost_context *ctx = pan_context(pctx);
int fd = -1, ret;
assert(!value);
ret = drmSyncobjExportSyncFile(panfrost_device_fd(dev), f->syncobj, &fd);
assert(!ret);

View file

@ -312,11 +312,13 @@ void r600_postflush_resume_features(struct r600_common_context *ctx)
}
static void r600_fence_server_sync(struct pipe_context *ctx,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
/* radeon synchronizes all rings by default and will not implement
* fence imports.
*/
assert(!value);
}
static void r600_flush_from_st(struct pipe_context *ctx,

View file

@ -538,10 +538,11 @@ static void si_flush_from_st(struct pipe_context *ctx, struct pipe_fence_handle
return si_flush_all_queues(ctx, fence, flags, false);
}
static void si_fence_server_signal(struct pipe_context *ctx, struct pipe_fence_handle *fence)
static void si_fence_server_signal(struct pipe_context *ctx, struct pipe_fence_handle *fence, uint64_t value)
{
struct si_context *sctx = (struct si_context *)ctx;
struct si_fence *sfence = (struct si_fence *)fence;
assert(!value);
assert(sfence->gfx);
@ -566,10 +567,11 @@ static void si_fence_server_signal(struct pipe_context *ctx, struct pipe_fence_h
si_flush_all_queues(ctx, NULL, 0, true);
}
static void si_fence_server_sync(struct pipe_context *ctx, struct pipe_fence_handle *fence)
static void si_fence_server_sync(struct pipe_context *ctx, struct pipe_fence_handle *fence, uint64_t value)
{
struct si_context *sctx = (struct si_context *)ctx;
struct si_fence *sfence = (struct si_fence *)fence;
assert(!value);
util_queue_fence_wait(&sfence->ready);

View file

@ -86,10 +86,12 @@ svga_create_fence_fd(struct pipe_context *pipe,
*/
static void
svga_fence_server_sync(struct pipe_context *pipe,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct svga_winsys_screen *sws = svga_winsys_screen(pipe->screen);
struct svga_context *svga = svga_context(pipe);
assert(!value);
sws->fence_server_sync(sws, &svga->swc->imported_fence_fd, fence);
}

View file

@ -809,11 +809,13 @@ tegra_create_fence_fd(struct pipe_context *pcontext,
static void
tegra_fence_server_sync(struct pipe_context *pcontext,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct tegra_context *context = to_tegra_context(pcontext);
assert(!value);
context->gpu->fence_server_sync(context->gpu, fence);
context->gpu->fence_server_sync(context->gpu, fence, value);
}
static struct pipe_sampler_view *

View file

@ -148,10 +148,12 @@ v3d_fence_create_fd(struct pipe_context *pctx, struct pipe_fence_handle **pf,
static void
v3d_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *pfence)
struct pipe_fence_handle *pfence,
uint64_t value)
{
struct v3d_context *v3d = (struct v3d_context*)pctx;
struct v3d_fence *fence = (struct v3d_fence *)pfence;
assert(!value);
MESA_TRACE_FUNC();

View file

@ -121,10 +121,12 @@ vc4_fence_create_fd(struct pipe_context *pctx, struct pipe_fence_handle **pf,
static void
vc4_fence_server_sync(struct pipe_context *pctx,
struct pipe_fence_handle *pfence)
struct pipe_fence_handle *pfence,
uint64_t value)
{
struct vc4_context *vc4 = vc4_context(pctx);
struct vc4_fence *fence = vc4_fence(pfence);
assert(!value);
MESA_TRACE_FUNC();

View file

@ -1399,10 +1399,12 @@ static void virgl_create_fence_fd(struct pipe_context *ctx,
}
static void virgl_fence_server_sync(struct pipe_context *ctx,
struct pipe_fence_handle *fence)
struct pipe_fence_handle *fence,
uint64_t value)
{
struct virgl_context *vctx = virgl_context(ctx);
struct virgl_screen *rs = virgl_screen(ctx->screen);
assert(!value);
if (rs->vws->fence_server_sync)
rs->vws->fence_server_sync(rs->vws, vctx->cbuf, fence);

View file

@ -232,11 +232,12 @@ fence_get_fd(struct pipe_screen *pscreen, struct pipe_fence_handle *pfence)
}
void
zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pfence)
zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pfence, uint64_t value)
{
struct zink_context *ctx = zink_context(pctx);
struct zink_tc_fence *mfence = (struct zink_tc_fence *)pfence;
struct zink_batch_state *bs = ctx->bs;
assert(!value);
util_dynarray_append(&ctx->bs->user_signal_semaphores, VkSemaphore, mfence->sem);
bs->has_work = true;
@ -249,10 +250,11 @@ zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pf
}
void
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence)
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence, uint64_t value)
{
struct zink_context *ctx = zink_context(pctx);
struct zink_tc_fence *mfence = (struct zink_tc_fence *)pfence;
assert(!value);
if (mfence->deferred_ctx == pctx || !mfence->sem)
return;

View file

@ -56,9 +56,9 @@ void
zink_create_fence_win32(struct pipe_screen *screen, struct pipe_fence_handle **pfence, void *handle, const void *name, enum pipe_fd_type type);
#endif
void
zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pfence);
zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pfence, uint64_t value);
void
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence);
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence, uint64_t value);
void
zink_screen_fence_init(struct pipe_screen *pscreen);

View file

@ -236,7 +236,7 @@ dri_server_wait_sync(struct dri_context *_ctx, void *_fence, unsigned flags)
_mesa_glthread_finish(st->ctx);
if (ctx->fence_server_sync)
ctx->fence_server_sync(ctx, fence->pipe_fence);
ctx->fence_server_sync(ctx, fence->pipe_fence, 0);
}
struct dri_image *
@ -838,7 +838,7 @@ dri_image_fence_sync(struct dri_context *ctx, struct dri_image *img)
img->in_fence_fd = -1;
pipe->create_fence_fd(pipe, &fence, fd, PIPE_FD_TYPE_NATIVE_SYNC);
pipe->fence_server_sync(pipe, fence);
pipe->fence_server_sync(pipe, fence, 0);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
close(fd);

View file

@ -385,7 +385,7 @@ handle_in_fence(struct dri_context *ctx, struct dri_image *img)
img->in_fence_fd = -1;
pipe->create_fence_fd(pipe, &fence, fd, PIPE_FD_TYPE_NATIVE_SYNC);
pipe->fence_server_sync(pipe, fence);
pipe->fence_server_sync(pipe, fence, 0);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
close(fd);

View file

@ -110,7 +110,7 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E
CHECKHR_GOTO( spDeviceContext3.As( &spDeviceContext4 ), done );
// This will signal the staging fence the d3d12 mesa backend is consuming
spDeviceContext4->Signal( m_spStagingFence11.Get(), m_SyncFenceValue );
spDeviceContext4->Signal( m_spStagingFence11.Get(), m_NextSyncFenceValue );
debug_printf( "[dx12 hmft 0x%p] DX11 *shared* input sample\n", this );
}
else
@ -135,7 +135,7 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E
// Since we're signaling from the D3D11 context on a shared fence, the signal
// will happen after the d3d11 context copy is done.
CHECKHR_GOTO( spDeviceContext3.As( &spDeviceContext4 ), done );
spDeviceContext4->Signal( m_spStagingFence11.Get(), m_SyncFenceValue );
spDeviceContext4->Signal( m_spStagingFence11.Get(), m_NextSyncFenceValue );
CHECKHR_GOTO( spSharedTexture.As( &spDXGIResource1 ), done );
CHECKHR_GOTO( spDXGIResource1->CreateSharedHandle( nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &hTexture ), done );
debug_printf( "[dx12 hmft 0x%p] DX11 input sample\n", this );
@ -169,7 +169,7 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E
// This will signal the staging fence the d3d12 mesa backend is consuming
// Since we have a Wait() on spStagingQueue added by EnqueueResourceReadyWait, this will only happen after MF
// triggered completion on the input
m_spStagingQueue->Signal( m_spStagingFence12.Get(), m_SyncFenceValue );
m_spStagingQueue->Signal( m_spStagingFence12.Get(), m_NextSyncFenceValue );
winsysHandle.com_obj = spResource.Get();
winsysHandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
@ -205,6 +205,7 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E
struct pipe_fence_handle *dst_surface_fence = nullptr;
vpblit_params.base.in_fence = m_pPipeFenceHandle; // input surface fence (driver input)
vpblit_params.base.in_fence_value = m_CurrentSyncFenceValue;
vpblit_params.base.out_fence = &dst_surface_fence; // Output surface fence (driver output)
vpblit_params.base.input_format = pDX12EncodeContext->pPipeVideoBuffer->buffer_format;
@ -500,7 +501,7 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E
}
// Set the fence to be waited on m_SyncFenceValue and increment the value for the next frame
m_pVlScreen->pscreen->set_fence_timeline_value( m_pVlScreen->pscreen, m_pPipeFenceHandle, m_SyncFenceValue++ );
m_CurrentSyncFenceValue = m_NextSyncFenceValue++;
done:
if( SUCCEEDED( hr ) )

View file

@ -204,6 +204,7 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo
pPicInfo->requested_metadata = m_EncoderCapabilities.m_HWSupportedMetadataFlags;
pPicInfo->base.in_fence = m_pPipeFenceHandle;
pPicInfo->base.in_fence_value = m_CurrentSyncFenceValue;
pPicInfo->base.input_format = pDX12EncodeContext->pPipeVideoBuffer->buffer_format;
UpdateH264EncPictureDesc( pPicInfo,

View file

@ -247,6 +247,7 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo
pPicInfo->requested_metadata = m_EncoderCapabilities.m_HWSupportedMetadataFlags;
pPicInfo->base.in_fence = m_pPipeFenceHandle;
pPicInfo->base.in_fence_value = m_CurrentSyncFenceValue;
pPicInfo->base.input_format = pDX12EncodeContext->pPipeVideoBuffer->buffer_format;
if( pDX12EncodeContext->bROI )
{

View file

@ -553,7 +553,7 @@ class __declspec( uuid( HMFT_GUID ) ) CDX12EncHMFT : CMFD3DManager,
ComPtr<ID3D12Fence> m_spStagingFence12;
struct pipe_fence_handle *m_pPipeFenceHandle = nullptr;
HANDLE m_hSharedFenceHandle = nullptr;
uint64_t m_SyncFenceValue = 1;
uint64_t m_NextSyncFenceValue = 1, m_CurrentSyncFenceValue = 0;
// Cached encoder capabilities
class encoder_capabilities m_EncoderCapabilities = {};

View file

@ -828,13 +828,15 @@ struct pipe_context {
* Insert commands to have GPU wait for fence to be signaled.
*/
void (*fence_server_sync)(struct pipe_context *pipe,
struct pipe_fence_handle *fence);
struct pipe_fence_handle *fence,
uint64_t timeline_value);
/**
* Insert commands to have the GPU signal a fence.
*/
void (*fence_server_signal)(struct pipe_context *pipe,
struct pipe_fence_handle *fence);
struct pipe_fence_handle *fence,
uint64_t timeline_value);
/**
* Create a view on a texture to be used by a shader stage.

View file

@ -755,14 +755,6 @@ struct pipe_screen {
pipe_create_vertex_state_func create_vertex_state;
pipe_vertex_state_destroy_func vertex_state_destroy;
/**
* Update a timeline semaphore value stored within a driver fence object.
* Future waits and signals will use the new value.
*/
void (*set_fence_timeline_value)(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
uint64_t value);
/**
* Get additional data for interop_query_device_info
*

View file

@ -239,6 +239,7 @@ struct pipe_picture_desc
unsigned flush_flags;
/* A fence for pipe_video_codec::begin_frame to wait on */
struct pipe_fence_handle *in_fence;
uint64_t in_fence_value;
/* A fence for pipe_video_codec::end_frame to signal job completion */
struct pipe_fence_handle **out_fence;
};

View file

@ -669,7 +669,7 @@ server_wait_semaphore(struct gl_context *ctx,
/* The driver is allowed to flush during fence_server_sync, be prepared */
st_flush_bitmap_cache(st);
pipe->fence_server_sync(pipe, semObj->fence);
pipe->fence_server_sync(pipe, semObj->fence, semObj->timeline_value);
/**
* According to the EXT_external_objects spec, the memory operations must
@ -735,7 +735,7 @@ server_signal_semaphore(struct gl_context *ctx,
/* The driver must flush during fence_server_signal, be prepared */
st_flush_bitmap_cache(st);
pipe->fence_server_signal(pipe, semObj->fence);
pipe->fence_server_signal(pipe, semObj->fence, semObj->timeline_value);
}
/**
@ -928,7 +928,6 @@ _mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
}
semObj->timeline_value = params[0];
ctx->screen->set_fence_timeline_value(ctx->screen, semObj->fence, params[0]);
}
void GLAPIENTRY

View file

@ -430,7 +430,7 @@ wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj,
screen->fence_reference(screen, &fence, syncObj->fence);
simple_mtx_unlock(&syncObj->mutex);
pipe->fence_server_sync(pipe, fence);
pipe->fence_server_sync(pipe, fence, 0);
screen->fence_reference(screen, &fence, NULL);
_mesa_unref_sync_object(ctx, syncObj, 1);
}

View file

@ -1316,7 +1316,6 @@ void st_init_extensions(struct pipe_screen *screen,
if (extensions->EXT_semaphore) {
consts->MaxTimelineSemaphoreValueDifference = screen->caps.max_timeline_semaphore_difference;
extensions->NV_timeline_semaphore = consts->MaxTimelineSemaphoreValueDifference > 0;
assert(!extensions->NV_timeline_semaphore || screen->set_fence_timeline_value);
}
consts->ForceIntegerTexNearest = options->force_integer_tex_nearest;