From bd7832b10a3c2c43e33abff97a9447d52166da3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Wed, 18 Sep 2013 22:49:34 +0200
Subject: wined3d: Move buffer creation into the resource.

More code from volume_unload can be moved to resource_unload eventually.
Before doing that, surfaces and buffers have to be migrated to the new
location scheme. Otherwise the unimplemented buffer_load_location and
surface_load_location will write a lot of ERRs.
---
 dlls/wined3d/resource.c        | 66 ++++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/volume.c          | 63 ++--------------------------------------
 dlls/wined3d/wined3d_private.h |  4 ++-
 3 files changed, 71 insertions(+), 62 deletions(-)

diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 5204fee..0d2145f 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -223,6 +223,18 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
     return WINED3D_OK;
 }
 
+static void wined3d_resource_free_bo(struct wined3d_resource *resource)
+{
+    struct wined3d_context *context = context_acquire(resource->device, NULL);
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    TRACE("Deleting GL buffer %u belonging to resource %p.\n", resource->buffer_object, resource);
+    GL_EXTCALL(glDeleteBuffers(1, &resource->buffer_object));
+    checkGLcall("glDeleteBuffers");
+    resource->buffer_object = 0;
+    context_release(context);
+}
+
 void resource_cleanup(struct wined3d_resource *resource)
 {
     const struct wined3d *d3d = resource->device->wined3d;
@@ -235,6 +247,9 @@ void resource_cleanup(struct wined3d_resource *resource)
         adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size);
     }
 
+    if (resource->buffer_object)
+        wined3d_resource_free_bo(resource);
+
     wined3d_resource_free_sysmem(resource);
 
     device_resource_released(resource->device, resource);
@@ -245,6 +260,9 @@ void resource_unload(struct wined3d_resource *resource)
     if (resource->map_count)
         ERR("Resource %p is being unloaded while mapped.\n", resource);
 
+    if (resource->buffer_object)
+        wined3d_resource_free_bo(resource);
+
     context_resource_unloaded(resource->device,
             resource, resource->type);
 }
@@ -597,3 +615,51 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource,
             return;
     }
 }
+
+/* Context activation is done by the caller. */
+static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, const struct wined3d_context *context)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    if (resource->buffer_object)
+        return;
+
+    GL_EXTCALL(glGenBuffers(1, &resource->buffer_object));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer_object));
+    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, resource->size, NULL, GL_STREAM_DRAW));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+    checkGLcall("Create GL buffer");
+
+    TRACE("Created GL buffer %u for resource %p.\n", resource->buffer_object, resource);
+}
+
+BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource)
+{
+    if (resource->heap_memory)
+        return TRUE;
+
+    if (!wined3d_resource_allocate_sysmem(resource))
+    {
+        ERR("Failed to allocate system memory.\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/* Context activation is done by the caller. */
+BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, struct wined3d_context *context)
+{
+    switch (resource->map_binding)
+    {
+        case WINED3D_LOCATION_BUFFER:
+            wined3d_resource_prepare_bo(resource, context);
+            return TRUE;
+
+        case WINED3D_LOCATION_SYSMEM:
+            return wined3d_resource_prepare_system_memory(resource);
+
+        default:
+            ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding));
+            return FALSE;
+    }
+}
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 78b153d..c95af94 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -314,42 +314,10 @@ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *
             srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB);
 }
 
-/* Context activation is done by the caller. */
-static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct wined3d_context *context)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    if (volume->resource.buffer_object)
-        return;
-
-    GL_EXTCALL(glGenBuffers(1, &volume->resource.buffer_object));
-    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->resource.buffer_object));
-    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, volume->resource.size, NULL, GL_STREAM_DRAW));
-    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
-    checkGLcall("Create PBO");
-
-    TRACE("Created PBO %u for volume %p.\n", volume->resource.buffer_object, volume);
-}
-
-static void wined3d_volume_free_pbo(struct wined3d_volume *volume)
-{
-    struct wined3d_context *context = context_acquire(volume->resource.device, NULL);
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-
-    TRACE("Deleting PBO %u belonging to volume %p.\n", volume->resource.buffer_object, volume);
-    GL_EXTCALL(glDeleteBuffers(1, &volume->resource.buffer_object));
-    checkGLcall("glDeleteBuffersARB");
-    volume->resource.buffer_object = 0;
-    context_release(context);
-}
-
 void wined3d_volume_destroy(struct wined3d_volume *volume)
 {
     TRACE("volume %p.\n", volume);
 
-    if (volume->resource.buffer_object)
-        wined3d_volume_free_pbo(volume);
-
     resource_cleanup(&volume->resource);
     volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent);
     HeapFree(GetProcessHeap(), 0, volume);
@@ -366,7 +334,7 @@ static void volume_unload(struct wined3d_resource *resource)
 
     TRACE("texture %p.\n", resource);
 
-    if (volume_prepare_system_memory(volume))
+    if (wined3d_resource_prepare_system_memory(&volume->resource))
     {
         context = context_acquire(device, NULL);
         wined3d_resource_load_location(&volume->resource, context, WINED3D_LOCATION_SYSMEM);
@@ -380,15 +348,6 @@ static void volume_unload(struct wined3d_resource *resource)
         wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_DISCARDED);
     }
 
-    if (volume->resource.buffer_object)
-    {
-        /* Should not happen because only dynamic default pool volumes
-         * have a buffer, and those are not evicted by device_evit_managed_resources
-         * and must be freed before a non-ex device reset. */
-        ERR("Unloading a volume with a buffer\n");
-        wined3d_volume_free_pbo(volume);
-    }
-
     /* The texture name is managed by the container. */
 
     resource_unload(resource);
@@ -444,24 +403,6 @@ 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;
-    }
-}
-
 HRESULT wined3d_volume_map(struct wined3d_volume *volume,
         struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
 {
@@ -500,7 +441,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
     flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags);
 
     context = context_acquire(device, NULL);
-    if (!wined3d_volume_prepare_map_memory(volume, context))
+    if (!wined3d_resource_prepare_map_memory(&volume->resource, context))
     {
         WARN("Out of memory.\n");
         map_desc->data = NULL;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 6dc1b04..0049165 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2238,6 +2238,9 @@ 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;
+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;
@@ -2367,7 +2370,6 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc
     return CONTAINING_RECORD(resource, struct wined3d_volume, resource);
 }
 
-BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
 HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc,
         unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN;
 void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
-- 
2.6.4

