From 867205199c207d54cbbf54234f305c9b76c8671c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Wed, 18 Sep 2013 22:30:57 +0200
Subject: wined3d: Introduce helper functions for mapping volumes.

---
 dlls/wined3d/volume.c | 157 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 96 insertions(+), 61 deletions(-)

diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 42453ea..af3f055 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -468,12 +468,67 @@ static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *vol
     return TRUE;
 }
 
+/* Context activation is done by the caller. */
+static BOOL wined3d_volume_prepare_map_memory(struct wined3d_volume *volume, struct wined3d_context *context)
+{
+    switch (volume->resource.map_binding)
+    {
+        case WINED3D_LOCATION_BUFFER:
+            wined3d_volume_prepare_pbo(volume, context);
+            return TRUE;
+
+        case WINED3D_LOCATION_SYSMEM:
+            return volume_prepare_system_memory(volume);
+
+        default:
+            ERR("Unexpected map binding %s.\n", wined3d_debug_location(volume->resource.map_binding));
+            return FALSE;
+    }
+}
+
+static BYTE *wined3d_volume_get_map_ptr(const struct wined3d_volume *volume,
+        const struct wined3d_context *context, DWORD flags)
+{
+    const struct wined3d_gl_info *gl_info;
+    BYTE *ptr;
+
+    switch (volume->resource.map_binding)
+    {
+        case WINED3D_LOCATION_BUFFER:
+            gl_info = context->gl_info;
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
+
+            if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+            {
+                GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
+                mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT;
+                ptr = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
+                        0, volume->resource.size, mapflags));
+            }
+            else
+            {
+                GLenum access = wined3d_resource_gl_legacy_map_flags(flags);
+                ptr = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access));
+            }
+
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+            checkGLcall("Map PBO");
+            return ptr;
+
+        case WINED3D_LOCATION_SYSMEM:
+            return volume->resource.heap_memory;
+
+        default:
+            ERR("Unexpected map binding %s.\n", wined3d_debug_location(volume->resource.map_binding));
+            return NULL;
+    }
+}
+
 HRESULT wined3d_volume_map(struct wined3d_volume *volume,
         struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
 {
     struct wined3d_device *device = volume->resource.device;
     struct wined3d_context *context;
-    const struct wined3d_gl_info *gl_info;
     BYTE *base_memory;
     const struct wined3d_format *format = volume->resource.format;
     const unsigned int fmt_flags = volume->container->resource.format_flags;
@@ -506,58 +561,22 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
 
     flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags);
 
-    if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER)
+    context = context_acquire(device, NULL);
+    if (!wined3d_volume_prepare_map_memory(volume, context))
     {
-        context = context_acquire(device, NULL);
-        gl_info = context->gl_info;
-
-        wined3d_volume_prepare_pbo(volume, context);
-        if (flags & WINED3D_MAP_DISCARD)
-            wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_BUFFER);
-        else
-            wined3d_resource_load_location(&volume->resource, context, WINED3D_LOCATION_BUFFER);
-
-        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
-
-        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,
-                    0, volume->resource.size, mapflags));
-        }
-        else
-        {
-            GLenum access = wined3d_resource_gl_legacy_map_flags(flags);
-            base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access));
-        }
-
-        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
-        checkGLcall("Map PBO");
-
+        WARN("Out of memory.\n");
+        map_desc->data = NULL;
         context_release(context);
+        return E_OUTOFMEMORY;
     }
+
+    if (flags & WINED3D_MAP_DISCARD)
+        wined3d_resource_validate_location(&volume->resource, volume->resource.map_binding);
     else
-    {
-        if (!volume_prepare_system_memory(volume))
-        {
-            WARN("Out of memory.\n");
-            map_desc->data = NULL;
-            return E_OUTOFMEMORY;
-        }
+        wined3d_resource_load_location(&volume->resource, context, volume->resource.map_binding);
 
-        if (flags & WINED3D_MAP_DISCARD)
-        {
-            wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_SYSMEM);
-        }
-        else if (!(volume->resource.locations & WINED3D_LOCATION_SYSMEM))
-        {
-            context = context_acquire(device, NULL);
-            wined3d_resource_load_location(&volume->resource, context, WINED3D_LOCATION_SYSMEM);
-            context_release(context);
-        }
-        base_memory = volume->resource.heap_memory;
-    }
+    base_memory = wined3d_volume_get_map_ptr(volume, context, flags);
+    context_release(context);
 
     TRACE("Base memory pointer %p.\n", base_memory);
 
@@ -610,8 +629,34 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
     return WINED3D_OK;
 }
 
+static void wined3d_volume_release_map_ptr(const struct wined3d_volume *volume,
+        const struct wined3d_context *context)
+{
+    const struct wined3d_gl_info *gl_info;
+
+    switch (volume->resource.map_binding)
+    {
+        case WINED3D_LOCATION_BUFFER:
+            gl_info = context->gl_info;
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
+            GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+            checkGLcall("Unmap PBO");
+            return;
+
+        case WINED3D_LOCATION_SYSMEM:
+            return;
+
+        default:
+            ERR("Unexpected map binding %s.\n", wined3d_debug_location(volume->resource.map_binding));
+            return;
+    }
+}
+
 HRESULT wined3d_volume_unmap(struct wined3d_volume *volume)
 {
+    struct wined3d_device *device = volume->resource.device;
+    struct wined3d_context *context;
     TRACE("volume %p.\n", volume);
 
     if (!volume->resource.map_count)
@@ -620,19 +665,9 @@ HRESULT wined3d_volume_unmap(struct wined3d_volume *volume)
         return WINED3DERR_INVALIDCALL;
     }
 
-    if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER)
-    {
-        struct wined3d_device *device = volume->resource.device;
-        struct wined3d_context *context = context_acquire(device, NULL);
-        const struct wined3d_gl_info *gl_info = context->gl_info;
-
-        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
-        GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
-        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
-        checkGLcall("Unmap PBO");
-
-        context_release(context);
-    }
+    context = context_acquire(device, NULL);
+    wined3d_volume_release_map_ptr(volume, context);
+    context_release(context);
 
     volume->resource.map_count--;
 
-- 
2.6.0

