From 247d135f67dde9df0d32edd3315385ad8e7dc962 Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Tue, 2 Mar 2021 22:48:56 +0100 Subject: [PATCH] st/nine: Implement SYSTEMMEM buffers same as MANAGED Use the MANAGED path for SYSTEMMEM buffers. Tests point out the locking behaviour of SYSTEMEMM buffers is very close to MANAGED. Signed-off-by: Axel Davy Part-of: --- src/gallium/frontends/nine/buffer9.c | 33 ++++++++++++++-------------- src/gallium/frontends/nine/buffer9.h | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/gallium/frontends/nine/buffer9.c b/src/gallium/frontends/nine/buffer9.c index d1368517f11..e51392675f9 100644 --- a/src/gallium/frontends/nine/buffer9.c +++ b/src/gallium/frontends/nine/buffer9.c @@ -83,10 +83,11 @@ NineBuffer9_ctor( struct NineBuffer9 *This, * vram copy are involved or not). * DEFAULT + WRITEONLY => Vram * DEFAULT + WRITEONLY + DYNAMIC => Either Vram buffer or GTT_WC, depending on what the driver wants. + * SYSTEMMEM: Same as MANAGED, but handled by the driver instead of the runtime (which means + * some small behavior differences between vendors). Implementing exactly as MANAGED should + * be fine. */ - if (Pool == D3DPOOL_SYSTEMMEM) - info->usage = PIPE_USAGE_STAGING; - else if (Pool == D3DPOOL_MANAGED) + if (Pool != D3DPOOL_DEFAULT) info->usage = PIPE_USAGE_DEFAULT; else if (Usage & D3DUSAGE_DYNAMIC && Usage & D3DUSAGE_WRITEONLY) info->usage = PIPE_USAGE_STREAM; @@ -130,7 +131,7 @@ NineBuffer9_ctor( struct NineBuffer9 *This, if (FAILED(hr)) return hr; - if (Pool == D3DPOOL_MANAGED) { + if (Pool != D3DPOOL_DEFAULT) { This->managed.data = align_calloc( nine_format_get_level_alloc_size(This->base.info.format, Size, 1, 0), 32); @@ -160,7 +161,7 @@ NineBuffer9_dtor( struct NineBuffer9 *This ) FREE(This->maps); } - if (This->base.pool == D3DPOOL_MANAGED) { + if (This->base.pool != D3DPOOL_DEFAULT) { if (This->managed.data) align_free(This->managed.data); if (list_is_linked(&This->managed.list)) @@ -238,12 +239,15 @@ NineBuffer9_Lock( struct NineBuffer9 *This, * Since these buffers are supposed to be locked once and never * writen again (MANAGED or DYNAMIC is used for the other uses cases), * performance should be unaffected. */ - if (!(This->base.usage & D3DUSAGE_DYNAMIC) && This->base.pool != D3DPOOL_MANAGED) + if (!(This->base.usage & D3DUSAGE_DYNAMIC) && This->base.pool == D3DPOOL_DEFAULT) SizeToLock = This->size - OffsetToLock; u_box_1d(OffsetToLock, SizeToLock, &box); - if (This->base.pool == D3DPOOL_MANAGED) { + if (This->base.pool != D3DPOOL_DEFAULT) { + /* Systemmem takes into account writes outside the locked region on AMD/NVidia */ + if (This->base.pool == D3DPOOL_SYSTEMMEM) + u_box_1d(0, This->size, &box); /* READONLY doesn't dirty the buffer */ /* Tests on Win: READONLY doesn't wait for the upload */ if (!(Flags & D3DLOCK_READONLY)) { @@ -274,11 +278,7 @@ NineBuffer9_Lock( struct NineBuffer9 *This, * D3DERR_WASSTILLDRAWING if the resource is in use, except for DYNAMIC. * Our tests: some apps do use both DISCARD and NOOVERWRITE at the same * time. On windows it seems to return different pointer, thus indicating - * DISCARD is taken into account. - * Our tests: SYSTEMMEM doesn't DISCARD */ - - if (This->base.pool == D3DPOOL_SYSTEMMEM) - Flags &= ~(D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE); + * DISCARD is taken into account. */ if (Flags & D3DLOCK_DISCARD) usage = PIPE_MAP_WRITE | PIPE_MAP_DISCARD_WHOLE_RESOURCE; @@ -286,9 +286,8 @@ NineBuffer9_Lock( struct NineBuffer9 *This, usage = PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED; else /* Do not ask for READ if writeonly and default pool (should be safe enough, - * as the doc says app shouldn't expect reading to work with writeonly). - * Ignore for Systemmem as it has special behaviours. */ - usage = ((This->base.usage & D3DUSAGE_WRITEONLY) && This->base.pool == D3DPOOL_DEFAULT) ? + * as the doc says app shouldn't expect reading to work with writeonly). */ + usage = (This->base.usage & D3DUSAGE_WRITEONLY) ? PIPE_MAP_WRITE : PIPE_MAP_READ_WRITE; if (Flags & D3DLOCK_DONOTWAIT && !(This->base.usage & D3DUSAGE_DYNAMIC)) @@ -442,7 +441,7 @@ NineBuffer9_Unlock( struct NineBuffer9 *This ) if (This->nlocks > 0) return D3D_OK; /* Pending unlocks. Wait all unlocks before unmapping */ - if (This->base.pool != D3DPOOL_MANAGED) { + if (This->base.pool == D3DPOOL_DEFAULT) { for (i = 0; i < This->nmaps; i++) { if (!This->maps[i].buf) { pipe = This->maps[i].is_pipe_secondary ? @@ -465,7 +464,7 @@ NineBuffer9_Unlock( struct NineBuffer9 *This ) void NineBuffer9_SetDirty( struct NineBuffer9 *This ) { - assert(This->base.pool == D3DPOOL_MANAGED); + assert(This->base.pool != D3DPOOL_DEFAULT); This->managed.dirty = TRUE; u_box_1d(0, This->size, &This->managed.dirty_box); diff --git a/src/gallium/frontends/nine/buffer9.h b/src/gallium/frontends/nine/buffer9.h index 94459ad9497..b3dec7fb910 100644 --- a/src/gallium/frontends/nine/buffer9.h +++ b/src/gallium/frontends/nine/buffer9.h @@ -104,7 +104,7 @@ NineBuffer9_Upload( struct NineBuffer9 *This ) { struct NineDevice9 *device = This->base.base.device; - assert(This->base.pool == D3DPOOL_MANAGED && This->managed.dirty); + assert(This->base.pool != D3DPOOL_DEFAULT && This->managed.dirty); nine_context_range_upload(device, &This->managed.pending_upload, (struct NineUnknown *)This, This->base.resource,