From fad67dd2abc5311a596066f749a29a86daf7488f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Thu, 19 Sep 2013 17:51:38 +0200
Subject: wined3d: Move most of volume_map to resource.c

The CPU access check can be moved once surfaces don't have to lock for
sysmem blits. Surfaces and volume have different block alignment and
boundary check behaviours.
---
 dlls/wined3d/resource.c        | 111 +++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/volume.c          |  98 +++---------------------------------
 dlls/wined3d/wined3d_private.h |   3 ++
 3 files changed, 120 insertions(+), 92 deletions(-)

diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 2a73c0e..a08631f 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -791,3 +791,114 @@ BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource,
 
     return TRUE;
 }
+
+HRESULT wined3d_resource_map(struct wined3d_resource *resource,
+        struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+    struct wined3d_device *device = resource->device;
+    struct wined3d_context *context = NULL;
+    BYTE *base_memory;
+    const struct wined3d_format *format = resource->format;
+    const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D];
+
+    TRACE("resource %p, map_desc %p, box %s, flags %#x.\n",
+            resource, map_desc, debug_box(box), flags);
+
+    if (resource->map_count)
+    {
+        WARN("Volume is already mapped.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    flags = wined3d_resource_sanitize_map_flags(resource, flags);
+
+    if (device->d3d_initialized)
+        context = context_acquire(device, NULL);
+
+    if (!wined3d_resource_prepare_map_memory(resource, context))
+    {
+        WARN("Out of memory.\n");
+        map_desc->data = NULL;
+        context_release(context);
+        return E_OUTOFMEMORY;
+    }
+
+    if (flags & WINED3D_MAP_DISCARD)
+        wined3d_resource_validate_location(resource, resource->map_binding);
+    else
+        wined3d_resource_load_location(resource, context, resource->map_binding);
+
+    base_memory = wined3d_resource_get_map_ptr(resource, context, flags);
+
+    if (context)
+        context_release(context);
+
+    TRACE("Base memory pointer %p.\n", base_memory);
+
+    if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
+    {
+        map_desc->row_pitch = resource->width * format->byte_count;
+        map_desc->slice_pitch = map_desc->row_pitch * resource->height;
+    }
+    else
+    {
+        wined3d_resource_get_pitch(resource, &map_desc->row_pitch, &map_desc->slice_pitch);
+    }
+
+    if (!box)
+    {
+        map_desc->data = base_memory;
+    }
+    else
+    {
+        if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS)
+        {
+            /* Compressed textures are block based, so calculate the offset of
+             * the block that contains the top-left pixel of the locked rectangle. */
+            map_desc->data = base_memory
+                    + (box->front * map_desc->slice_pitch)
+                    + ((box->top / format->block_height) * map_desc->row_pitch)
+                    + ((box->left / format->block_width) * format->block_byte_count);
+        }
+        else
+        {
+            map_desc->data = base_memory
+                    + (map_desc->slice_pitch * box->front)
+                    + (map_desc->row_pitch * box->top)
+                    + (box->left * format->byte_count);
+        }
+    }
+
+    if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
+        wined3d_resource_invalidate_location(resource, ~resource->map_binding);
+
+    resource->map_count++;
+
+    TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n",
+            map_desc->data, map_desc->row_pitch, map_desc->slice_pitch);
+
+    return WINED3D_OK;
+}
+
+HRESULT wined3d_resource_unmap(struct wined3d_resource *resource)
+{
+    struct wined3d_device *device = resource->device;
+    struct wined3d_context *context = NULL;
+    TRACE("resource %p.\n", resource);
+
+    if (!resource->map_count)
+    {
+        WARN("Trying to unlock an unlocked resource %p.\n", resource);
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (device->d3d_initialized)
+        context = context_acquire(device, NULL);
+    wined3d_resource_release_map_ptr(resource, context);
+    if (context)
+        context_release(context);
+
+    resource->map_count--;
+
+    return WINED3D_OK;
+}
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index e10318b..925c833 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -368,26 +368,16 @@ static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *vol
 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;
-    BYTE *base_memory;
+    HRESULT hr;
     const struct wined3d_format *format = volume->resource.format;
     const unsigned int fmt_flags = volume->container->resource.format_flags;
 
-    TRACE("volume %p, map_desc %p, box %s, flags %#x.\n",
-            volume, map_desc, debug_box(box), flags);
-
     map_desc->data = NULL;
     if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU))
     {
         WARN("Volume %p is not CPU accessible.\n", volume);
         return WINED3DERR_INVALIDCALL;
     }
-    if (volume->resource.map_count)
-    {
-        WARN("Volume is already mapped.\n");
-        return WINED3DERR_INVALIDCALL;
-    }
     if (!wined3d_volume_check_box_dimensions(volume, box))
     {
         WARN("Map box is invalid.\n");
@@ -400,92 +390,16 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
         return WINED3DERR_INVALIDCALL;
     }
 
-    flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags);
-
-    context = context_acquire(device, NULL);
-    if (!wined3d_resource_prepare_map_memory(&volume->resource, context))
-    {
-        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
-        wined3d_resource_load_location(&volume->resource, context, volume->resource.map_binding);
-
-    base_memory = wined3d_resource_get_map_ptr(&volume->resource, context, flags);
-    context_release(context);
-
-    TRACE("Base memory pointer %p.\n", base_memory);
-
-    if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
-    {
-        map_desc->row_pitch = volume->resource.width * format->byte_count;
-        map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height;
-    }
-    else
-    {
-        wined3d_texture_get_pitch(volume->container, volume->texture_level,
-                &map_desc->row_pitch, &map_desc->slice_pitch);
-    }
-
-    if (!box)
-    {
-        map_desc->data = base_memory;
-    }
-    else
-    {
-        if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS)
-        {
-            /* Compressed textures are block based, so calculate the offset of
-             * the block that contains the top-left pixel of the locked rectangle. */
-            map_desc->data = base_memory
-                    + (box->front * map_desc->slice_pitch)
-                    + ((box->top / format->block_height) * map_desc->row_pitch)
-                    + ((box->left / format->block_width) * format->block_byte_count);
-        }
-        else
-        {
-            map_desc->data = base_memory
-                    + (map_desc->slice_pitch * box->front)
-                    + (map_desc->row_pitch * box->top)
-                    + (box->left * volume->resource.format->byte_count);
-        }
-    }
-
-    if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
-        wined3d_resource_invalidate_location(&volume->resource, ~volume->resource.map_binding);
-
-    volume->resource.map_count++;
-
-    TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n",
-            map_desc->data, map_desc->row_pitch, map_desc->slice_pitch);
+    hr = wined3d_resource_map(&volume->resource, map_desc, box, flags);
+    if (FAILED(hr))
+        return hr;
 
-    return WINED3D_OK;
+    return hr;
 }
 
 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)
-    {
-        WARN("Trying to unlock an unlocked volume %p.\n", volume);
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    context = context_acquire(device, NULL);
-    wined3d_resource_release_map_ptr(&volume->resource, context);
-    context_release(context);
-
-    volume->resource.map_count--;
-
-    return WINED3D_OK;
+    return wined3d_resource_unmap(&volume->resource);
 }
 
 static ULONG volume_resource_incref(struct wined3d_resource *resource)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 501d3f0..9ad7fd0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2325,12 +2325,15 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO
 BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_resource_load_location(struct wined3d_resource *resource,
         struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
+HRESULT wined3d_resource_map(struct wined3d_resource *resource, struct wined3d_map_desc *map_desc,
+        const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource,
         struct wined3d_context *context) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource,
         const struct wined3d_context *context) DECLSPEC_HIDDEN;
 DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN;
+HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN;
 
-- 
2.7.1

