Mesa (master): st/nine: Implement SYSTEMMEM buffers same as MANAGED

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Mar 13 21:39:03 UTC 2021


Module: Mesa
Branch: master
Commit: 247d135f67dde9df0d32edd3315385ad8e7dc962
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=247d135f67dde9df0d32edd3315385ad8e7dc962

Author: Axel Davy <davyaxel0 at gmail.com>
Date:   Tue Mar  2 22:48:56 2021 +0100

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 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9451>

---

 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,



More information about the mesa-commit mailing list