st/nine: Force DYNAMIC SYSTEMMEM for sw vertex processing
authorAxel Davy <davyaxel0@gmail.com>
Fri, 12 Mar 2021 10:29:24 +0000 (11:29 +0100)
committerMarge Bot <eric+marge@anholt.net>
Sat, 13 Mar 2021 21:23:24 +0000 (21:23 +0000)
SW vertex processing buffers are supposed to be sorted in RAM
and to be immediately idle after use (thus you can write at the
same location again immediately).

DYNAMIC SYSTEMMEM is by far the best fit for now for these kind
of buffers, though it can be improved further. Indeed the use
pattern will cause a lot of syncs with csmt actived.
Thus disable csmt when full sw vertex processing is requested.

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9451>

src/gallium/frontends/nine/buffer9.c
src/gallium/frontends/nine/device9.c

index 81f239f..23728c2 100644 (file)
@@ -70,6 +70,25 @@ NineBuffer9_ctor( struct NineBuffer9 *This,
      * can still be read (but slower). */
     info->bind = (Type == D3DRTYPE_INDEXBUFFER) ? PIPE_BIND_INDEX_BUFFER : PIPE_BIND_VERTEX_BUFFER;
 
+    /* Software vertex processing:
+     * If the device is full software vertex processing,
+     * then the buffer is supposed to be used only for sw processing.
+     * For mixed vertex processing, buffers with D3DUSAGE_SOFTWAREPROCESSING
+     * can be used for both sw and hw processing.
+     * These buffers are expected to be stored in RAM.
+     * Apps expect locking the full buffer with no flags, then
+     * render a a few primitive, then locking again, etc
+     * to be a fast pattern. Only the SYSTEMMEM DYNAMIC path
+     * will give that pattern ok performance in our case.
+     * An alternative would be when sw processing is detected to
+     * convert Draw* calls to Draw*Up calls. */
+    if (Usage & D3DUSAGE_SOFTWAREPROCESSING ||
+        pParams->device->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) {
+        Pool = D3DPOOL_SYSTEMMEM;
+        Usage |= D3DUSAGE_DYNAMIC;
+        /* Note: the application cannot retrieve Pool and Usage */
+    }
+
     /* It is hard to find clear information on where to place the buffer in
      * memory depending on the flag.
      * MSDN: resources are static, except for those with DYNAMIC, thus why you
@@ -114,10 +133,6 @@ NineBuffer9_ctor( struct NineBuffer9 *This,
     /* if (pDesc->Usage & D3DUSAGE_NPATCHES) { } */
     /* if (pDesc->Usage & D3DUSAGE_POINTS) { } */
     /* if (pDesc->Usage & D3DUSAGE_RTPATCHES) { } */
-    /* The buffer must be usable with both sw and hw
-     * vertex processing. It is expected to be slower with hw. */
-    if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
-        info->usage = PIPE_USAGE_STAGING;
     /* if (pDesc->Usage & D3DUSAGE_TEXTAPI) { } */
 
     info->height0 = 1;
index 26f0994..bb4f5c6 100644 (file)
@@ -300,7 +300,12 @@ NineDevice9_ctor( struct NineDevice9 *This,
     /* r600, radeonsi and iris are thread safe. */
     if (pCTX->csmt_force == 1)
         This->csmt_active = true;
-    else if (pCTX->csmt_force == 0)
+    else if (pCTX->csmt_force == 0 ||
+        This->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING)
+        /* We disable csmt for software vertex processing because for now
+         * the csmt thread is too much synced for these due to the vertex
+         * buffer implementation. These buffers are typically locked
+         * without NOOVERWRITE between each draw call. */
         This->csmt_active = false;
     else if (strstr(pScreen->get_name(pScreen), "AMD") != NULL)
         This->csmt_active = true;