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 */