From d9a4025fa3232876b586fd80f4d77681abf923ec Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Wed, 24 Apr 2019 23:58:38 +0200 Subject: [PATCH] st/nine: Finish if nooverwrite after normal mapping d3d's nooverwrite and gallium's unsynchronized have different semantics. Indeed nooverwrite says the applications won't write to locations needed by previous draws, which is less strong than unsynchronized which won't synchronize previous writes. Thus in case app is locking without discard/nooverwrite, then using nooverwrite, we need to add a synchronization. Fixes: https://github.com/iXit/wine-nine-standalone/issues/29 Signed-off-by: Axel Davy --- src/gallium/state_trackers/nine/buffer9.c | 17 +++++++++++++++++ src/gallium/state_trackers/nine/buffer9.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/gallium/state_trackers/nine/buffer9.c b/src/gallium/state_trackers/nine/buffer9.c index 5880ee3c1a2..54855f16aef 100644 --- a/src/gallium/state_trackers/nine/buffer9.c +++ b/src/gallium/state_trackers/nine/buffer9.c @@ -358,6 +358,23 @@ NineBuffer9_Lock( struct NineBuffer9 *This, } } + /* Previous mappings may need pending commands to write to the + * buffer (staging buffer for example). Before a NOOVERWRITE, + * we thus need a finish, to guarantee any upload is finished. + * Note for discard_nooverwrite_only we don't need to do this + * check as neither discard nor nooverwrite have issues there */ + if (This->need_sync_if_nooverwrite && !(Flags & D3DLOCK_DISCARD) && + (Flags & D3DLOCK_NOOVERWRITE)) { + struct pipe_screen *screen = NineDevice9_GetScreen(device); + struct pipe_fence_handle *fence = NULL; + + pipe = NineDevice9_GetPipe(device); + pipe->flush(pipe, &fence, 0); + (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE); + screen->fence_reference(screen, &fence, NULL); + } + This->need_sync_if_nooverwrite = !(Flags & (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE)); + /* When csmt is active, we want to avoid stalls as much as possible, * and thus we want to create a new resource on discard and map it * with the secondary pipe, instead of waiting on the main pipe. */ diff --git a/src/gallium/state_trackers/nine/buffer9.h b/src/gallium/state_trackers/nine/buffer9.h index 9ccd6dab990..7ae3ea6cc07 100644 --- a/src/gallium/state_trackers/nine/buffer9.h +++ b/src/gallium/state_trackers/nine/buffer9.h @@ -56,6 +56,7 @@ struct NineBuffer9 /* Whether only discard and nooverwrite were used so far * for this buffer. Allows some optimization. */ boolean discard_nooverwrite_only; + boolean need_sync_if_nooverwrite; struct nine_subbuffer *buf; /* Specific to managed buffers */ -- 2.30.2