[PATCH] wined3d: Use GL_MAP_PERSISTENT_BIT even for non-persistent bo maps.

Henri Verbeet hverbeet at codeweavers.com
Fri Jan 7 05:58:45 CST 2022


While the reason for doing this is to allow draws referencing mapped buffer
resources to succeed, the behaviour of the application in the referenced bug
report (FlatOut) appears to be slightly different; it does end up drawing
while buffer objects are mapped due to reordering of map operations inside the
command stream, but as far as I can tell those buffer objects are not
referenced by the draw. The driver in question (fglrx/Catalyst) appears to
simply be a bit overzealous with throwing errors, and unfortunately doesn't
provide much more information than "glDrawElementsBaseVertex has generated an
error (GL_INVALID_OPERATION)". The issue is not reproducible with Mesa
radeonsi.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46118
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/context_gl.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index c08e44ce372..9fd2ed67dcc 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2711,7 +2711,7 @@ map:
     gl_info = context_gl->gl_info;
     wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id);
 
-    if (gl_info->supported[ARB_BUFFER_STORAGE] && wined3d_map_persistent())
+    if (gl_info->supported[ARB_BUFFER_STORAGE])
     {
         GLbitfield gl_flags;
 
@@ -2719,15 +2719,28 @@ map:
          * used to create the bo, instead of the access flags passed to the
          * map call. Otherwise, if for example the initial map call that
          * caused the bo to be persistently mapped was a read-only map,
-         * subsequent write access to the bo would be undefined. */
-        gl_flags = bo->flags & ~GL_CLIENT_STORAGE_BIT;
+         * subsequent write access to the bo would be undefined.
+         *
+         * Note that we use GL_MAP_PERSISTENT_BIT for non-persistent maps here
+         * as well, in order to allow draws to succeed while referenced buffer
+         * resources are mapped. On the other hand, we don't want to use the
+         * access flags used to create the bo for non-persistent maps, because
+         * that may imply dropping GL_MAP_UNSYNCHRONIZED_BIT. */
+        if (wined3d_map_persistent())
+        {
+            gl_flags = bo->flags & ~GL_CLIENT_STORAGE_BIT;
+            if (!(gl_flags & GL_MAP_READ_BIT))
+                gl_flags |= GL_MAP_UNSYNCHRONIZED_BIT;
+            if (gl_flags & GL_MAP_WRITE_BIT)
+                gl_flags |= GL_MAP_FLUSH_EXPLICIT_BIT;
+        }
+        else
+        {
+            gl_flags = wined3d_resource_gl_map_flags(bo, flags);
+        }
         gl_flags |= GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
-        if (!(gl_flags & GL_MAP_READ_BIT))
-            gl_flags |= GL_MAP_UNSYNCHRONIZED_BIT;
-        if (gl_flags & GL_MAP_WRITE_BIT)
-            gl_flags |= GL_MAP_FLUSH_EXPLICIT_BIT;
 
-        if ((map_ptr = GL_EXTCALL(glMapBufferRange(bo->binding, 0, bo->size, gl_flags))))
+        if ((map_ptr = GL_EXTCALL(glMapBufferRange(bo->binding, 0, bo->size, gl_flags))) && wined3d_map_persistent())
             bo->b.map_ptr = map_ptr;
     }
     else if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
-- 
2.30.2




More information about the wine-devel mailing list