[PATCH 3/7] wined3d: Implement NOOVERWRITE and DISCARD volume maps

Stefan Dösinger stefan at codeweavers.com
Sun Aug 25 19:01:28 CDT 2013


---
 dlls/wined3d/buffer.c          | 54 ++----------------------------------------
 dlls/wined3d/resource.c        | 50 ++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/volume.c          | 39 +++++++++++++++++++++++-------
 dlls/wined3d/wined3d_private.h |  3 +++
 4 files changed, 85 insertions(+), 61 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index b3f760b..8178604 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -922,56 +922,6 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
     context_release(context);
 }
 
-static DWORD buffer_sanitize_flags(const struct wined3d_buffer *buffer, DWORD flags)
-{
-    /* Not all flags make sense together, but Windows never returns an error.
-     * Catch the cases that could cause issues. */
-    if (flags & WINED3D_MAP_READONLY)
-    {
-        if (flags & WINED3D_MAP_DISCARD)
-        {
-            WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
-            return 0;
-        }
-        if (flags & WINED3D_MAP_NOOVERWRITE)
-        {
-            WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
-            return 0;
-        }
-    }
-    else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
-            == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
-    {
-        WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together, ignoring.\n");
-        return 0;
-    }
-    else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
-            && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
-    {
-        WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
-        return 0;
-    }
-
-    return flags;
-}
-
-static GLbitfield buffer_gl_map_flags(DWORD d3d_flags)
-{
-    GLbitfield ret = 0;
-
-    if (!(d3d_flags & WINED3D_MAP_READONLY))
-        ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
-    if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
-        ret |= GL_MAP_READ_BIT;
-
-    if (d3d_flags & WINED3D_MAP_DISCARD)
-        ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
-    if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
-        ret |= GL_MAP_UNSYNCHRONIZED_BIT;
-
-    return ret;
-}
-
 struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer)
 {
     TRACE("buffer %p.\n", buffer);
@@ -986,7 +936,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
 
     TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags);
 
-    flags = buffer_sanitize_flags(buffer, flags);
+    flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags);
     count = ++buffer->resource.map_count;
 
     if (buffer->buffer_object)
@@ -1017,7 +967,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
 
                 if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
                 {
-                    GLbitfield mapflags = buffer_gl_map_flags(flags);
+                    GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
                     buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint,
                             0, buffer->resource.size, mapflags));
                     checkGLcall("glMapBufferRange");
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 59fced9..ca322b2 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -358,3 +358,53 @@ void wined3d_resource_free_sysmem(void *mem)
 
     HeapFree(GetProcessHeap(), 0, *(--p));
 }
+
+DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags)
+{
+    /* Not all flags make sense together, but Windows never returns an error.
+     * Catch the cases that could cause issues. */
+    if (flags & WINED3D_MAP_READONLY)
+    {
+        if (flags & WINED3D_MAP_DISCARD)
+        {
+            WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
+            return 0;
+        }
+        if (flags & WINED3D_MAP_NOOVERWRITE)
+        {
+            WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
+            return 0;
+        }
+    }
+    else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+            == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+    {
+        WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together, ignoring.\n");
+        return 0;
+    }
+    else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
+            && !(resource->usage & WINED3DUSAGE_DYNAMIC))
+    {
+        WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
+        return 0;
+    }
+
+    return flags;
+}
+
+GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
+{
+    GLbitfield ret = 0;
+
+    if (!(d3d_flags & WINED3D_MAP_READONLY))
+        ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
+    if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
+        ret |= GL_MAP_READ_BIT;
+
+    if (d3d_flags & WINED3D_MAP_DISCARD)
+        ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
+    if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
+        ret |= GL_MAP_UNSYNCHRONIZED_BIT;
+
+    return ret;
+}
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 8243cbd..fc12bfb 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -469,6 +469,7 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
         map_desc->data = NULL;
         return WINED3DERR_INVALIDCALL;
     }
+    flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags);
 
     if (volume->flags & WINED3D_VFLAG_PBO)
     {
@@ -476,10 +477,25 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
         gl_info = context->gl_info;
 
         wined3d_volume_prepare_pbo(volume, context);
-        wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
+        if (flags & WINED3D_MAP_DISCARD)
+            wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER);
+        else
+            wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
 
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
-        base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+
+        if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+        {
+            GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
+            mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT;
+            base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER_ARB,
+                    0, volume->resource.size, mapflags));
+        }
+        else
+        {
+            base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+        }
+
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
         checkGLcall("Map PBO");
 
@@ -487,14 +503,19 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
     }
     else
     {
-        if (!(volume->locations & WINED3D_LOCATION_SYSMEM))
+        if (!volume_prepare_system_memory(volume))
+        {
+            WARN("Out of memory.\n");
+            map_desc->data = NULL;
+            return E_OUTOFMEMORY;
+        }
+
+        if (flags & WINED3D_MAP_DISCARD)
+        {
+            wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM);
+        }
+        else if (!(volume->locations & WINED3D_LOCATION_SYSMEM))
         {
-            if (!volume_prepare_system_memory(volume))
-            {
-                WARN("Out of memory.\n");
-                map_desc->data = NULL;
-                return E_OUTOFMEMORY;
-            }
             context = context_acquire(device, NULL);
             wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM);
             context_release(context);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0bf6de0..6f38703 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1968,6 +1968,9 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
         const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
 DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN;
 void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource,
+        DWORD flags) DECLSPEC_HIDDEN;
+GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
 
 /* Tests show that the start address of resources is 32 byte aligned */
 #define RESOURCE_ALIGNMENT 16
-- 
1.8.1.5




More information about the wine-patches mailing list