st/nine: Fix buffer locking flags handling
authorAxel Davy <axel.davy@ens.fr>
Fri, 11 Mar 2016 21:17:25 +0000 (22:17 +0100)
committerAxel Davy <axel.davy@ens.fr>
Wed, 18 May 2016 21:37:14 +0000 (23:37 +0200)
Our behaviour was not entirely similar to what
the docs and our tests describe.

Drop d3dlock_buffer_to_pipe_transfer_usage.

Signed-off-by: Axel Davy <axel.davy@ens.fr>
src/gallium/state_trackers/nine/buffer9.c
src/gallium/state_trackers/nine/nine_pipe.h

index 1b431d24730168f96aa927c0b1bfdd587deb20cf..ed0c4f1fa7f75727488f4e6953970bc944fd310e 100644 (file)
@@ -154,7 +154,7 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
 {
     struct pipe_box box;
     void *data;
-    unsigned usage = d3dlock_buffer_to_pipe_transfer_usage(Flags);
+    unsigned usage;
 
     DBG("This=%p(pipe=%p) OffsetToLock=0x%x, SizeToLock=0x%x, Flags=0x%x\n",
         This, This->base.resource,
@@ -195,6 +195,26 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
         return D3D_OK;
     }
 
+    /* Driver ddi doc: READONLY is never passed to the device. So it can only
+     * have effect on things handled by the driver (MANAGED pool for example).
+     * Msdn doc: DISCARD and NOOVERWRITE are only for DYNAMIC.
+     * ATI doc: You can use DISCARD and NOOVERWRITE without DYNAMIC.
+     * Msdn doc: D3DLOCK_DONOTWAIT is not among the valid flags for buffers.
+     * Our tests: On win 7 nvidia, D3DLOCK_DONOTWAIT does return
+     * 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. */
+
+    if (Flags & D3DLOCK_DISCARD)
+        usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
+    else if (Flags & D3DLOCK_NOOVERWRITE)
+        usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED;
+    else
+        usage = PIPE_TRANSFER_READ_WRITE;
+    if (Flags & D3DLOCK_DONOTWAIT && !(This->base.usage & D3DUSAGE_DYNAMIC))
+        usage |= PIPE_TRANSFER_DONTBLOCK;
+
     if (This->nmaps == This->maxmaps) {
         struct pipe_transfer **newmaps =
             REALLOC(This->maps, sizeof(struct pipe_transfer *)*This->maxmaps,
@@ -215,7 +235,7 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
             " box.x = %u\n"
             " box.width = %u\n",
             usage, box.x, box.width);
-        /* not sure what to return, msdn suggests this */
+
         if (Flags & D3DLOCK_DONOTWAIT)
             return D3DERR_WASSTILLDRAWING;
         return D3DERR_INVALIDCALL;
index 9c8e8e6a06250bf5f15264832df44db7dadb9209..523f659855a7f96bb09bfbcd7db1b3162285cb5d 100644 (file)
@@ -44,33 +44,6 @@ void nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *);
 
 void nine_pipe_context_clear(struct NineDevice9 *);
 
-static inline unsigned d3dlock_buffer_to_pipe_transfer_usage(DWORD Flags)
-{
-    unsigned usage;
-
-    if (Flags & D3DLOCK_DISCARD)
-        usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
-    else
-    if (Flags & D3DLOCK_READONLY)
-        usage = PIPE_TRANSFER_READ;
-    else
-        usage = PIPE_TRANSFER_READ_WRITE;
-
-    if (Flags & D3DLOCK_NOOVERWRITE)
-        usage = (PIPE_TRANSFER_UNSYNCHRONIZED |
-                 PIPE_TRANSFER_DISCARD_RANGE | usage) & ~PIPE_TRANSFER_READ;
-    else
-    if (Flags & D3DLOCK_DONOTWAIT)
-        usage |= PIPE_TRANSFER_DONTBLOCK;
-
-    /*
-    if (Flags & D3DLOCK_NO_DIRTY_UPDATE)
-        usage |= PIPE_TRANSFER_FLUSH_EXPLICIT;
-    */
-
-    return usage;
-}
-
 static inline void
 rect_to_pipe_box(struct pipe_box *dst, const RECT *src)
 {