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 <davyaxel0@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9451>
This commit is contained in:
Axel Davy 2021-03-02 22:48:56 +01:00 committed by Marge Bot
parent 634adfa253
commit 247d135f67
2 changed files with 17 additions and 18 deletions

View File

@ -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);

View File

@ -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,