From 0a30deac1b8dc66d9877369442f4cbc7fbde21cb Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 6 Mar 2016 22:08:39 +0100
Subject: Revert "wined3d: Store surface/volume buffer objects in the
 sub-resource structure."

This reverts commit fbe27375370c426c781ba50841ef93ea6ff44502.
---
 dlls/wined3d/surface.c         | 52 ++++++++++++---------------------
 dlls/wined3d/texture.c         |  4 +--
 dlls/wined3d/volume.c          | 65 +++++++++++++++++-------------------------
 dlls/wined3d/wined3d_private.h |  6 ++--
 4 files changed, 51 insertions(+), 76 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 994756d..303bdc7 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -40,20 +40,13 @@ static const DWORD surface_simple_locations =
         WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY
         | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER;
 
-static unsigned int surface_get_sub_resource_idx(const struct wined3d_surface *surface)
-{
-    return surface->texture_layer * surface->container->level_count + surface->texture_level;
-}
-
 void wined3d_surface_cleanup(struct wined3d_surface *surface)
 {
     struct wined3d_surface *overlay, *cur;
-    GLuint buffer_object;
 
     TRACE("surface %p.\n", surface);
 
-    buffer_object = surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object;
-    if (buffer_object || surface->rb_multisample
+    if (surface->pbo || surface->rb_multisample
             || surface->rb_resolved || !list_empty(&surface->renderbuffers))
     {
         struct wined3d_renderbuffer_entry *entry, *entry2;
@@ -64,10 +57,10 @@ void wined3d_surface_cleanup(struct wined3d_surface *surface)
         context = context_acquire(device, NULL);
         gl_info = context->gl_info;
 
-        if (buffer_object)
+        if (surface->pbo)
         {
-            TRACE("Deleting buffer object %u.\n", buffer_object);
-            GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
+            TRACE("Deleting PBO %u.\n", surface->pbo);
+            GL_EXTCALL(glDeleteBuffers(1, &surface->pbo));
         }
 
         if (surface->rb_multisample)
@@ -471,7 +464,7 @@ static void surface_get_memory(const struct wined3d_surface *surface, struct win
     if (location & WINED3D_LOCATION_BUFFER)
     {
         data->addr = NULL;
-        data->buffer_object = surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object;
+        data->buffer_object = surface->pbo;
         return;
     }
     if (location & WINED3D_LOCATION_USER_MEMORY)
@@ -501,25 +494,23 @@ static void surface_get_memory(const struct wined3d_surface *surface, struct win
 static void surface_prepare_buffer(struct wined3d_surface *surface)
 {
     struct wined3d_context *context;
-    GLuint *buffer_object;
     GLenum error;
     const struct wined3d_gl_info *gl_info;
 
-    buffer_object = &surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object;
-    if (*buffer_object)
+    if (surface->pbo)
         return;
 
     context = context_acquire(surface->resource.device, NULL);
     gl_info = context->gl_info;
 
-    GL_EXTCALL(glGenBuffers(1, buffer_object));
+    GL_EXTCALL(glGenBuffers(1, &surface->pbo));
     error = gl_info->gl_ops.gl.p_glGetError();
-    if (!*buffer_object || error != GL_NO_ERROR)
+    if (!surface->pbo || error != GL_NO_ERROR)
         ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error);
 
-    TRACE("Binding PBO %u.\n", *buffer_object);
+    TRACE("Binding PBO %u.\n", surface->pbo);
 
-    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *buffer_object));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
     checkGLcall("glBindBuffer");
 
     GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4,
@@ -1036,13 +1027,10 @@ static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DW
 /* Context activation is done by the caller. */
 static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
 {
-    GLuint *buffer_object;
+    GL_EXTCALL(glDeleteBuffers(1, &surface->pbo));
+    checkGLcall("glDeleteBuffers(1, &surface->pbo)");
 
-    buffer_object = &surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object;
-    GL_EXTCALL(glDeleteBuffers(1, buffer_object));
-    checkGLcall("glDeleteBuffers(1, buffer_object)");
-
-    *buffer_object = 0;
+    surface->pbo = 0;
     surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER);
 }
 
@@ -1109,7 +1097,7 @@ static void surface_unload(struct wined3d_resource *resource)
     }
 
     /* Destroy PBOs, but load them into real sysmem before */
-    if (surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object)
+    if (surface->pbo)
         surface_remove_pbo(surface, gl_info);
 
     /* Destroy fbo render buffers. This is needed for implicit render targets, for
@@ -2179,9 +2167,9 @@ do { \
 HRESULT wined3d_surface_unmap(struct wined3d_surface *surface)
 {
     struct wined3d_device *device = surface->resource.device;
-    struct wined3d_texture *texture = surface->container;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
+    struct wined3d_texture *texture;
 
     TRACE("surface %p.\n", surface);
 
@@ -2203,8 +2191,7 @@ HRESULT wined3d_surface_unmap(struct wined3d_surface *surface)
             context = context_acquire(device, NULL);
             gl_info = context->gl_info;
 
-            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
-                    texture->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object));
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
             GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
             GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
             checkGLcall("glUnmapBuffer");
@@ -2218,6 +2205,7 @@ HRESULT wined3d_surface_unmap(struct wined3d_surface *surface)
 
     if (!(surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)))
     {
+        texture = surface->container;
         if (texture->swapchain && texture->swapchain->front_buffer == texture)
             texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(texture->swapchain);
         else if (texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
@@ -2319,8 +2307,7 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_
             context = context_acquire(device, NULL);
             gl_info = context->gl_info;
 
-            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
-                    texture->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object));
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
             base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE));
             GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
             checkGLcall("map PBO");
@@ -3706,8 +3693,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
     /* Don't use PBOs for converted surfaces. During PBO conversion we look at
      * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is
      * getting called. */
-    if ((format.convert || conversion)
-            && texture->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object)
+    if ((format.convert || conversion) && surface->pbo)
     {
         TRACE("Removing the pbo attached to surface %p.\n", surface);
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index cb2b310f..01f54a9 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1770,8 +1770,8 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
              return WINED3DERR_INVALIDCALL;
         }
         if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
-                || texture->flags & WINED3D_TEXTURE_PIN_SYSMEM
-                || texture->sub_resources[sub_resource_idx].buffer_object))
+                || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
+                || surface->pbo))
             surface->resource.map_binding = WINED3D_LOCATION_DIB;
     }
 
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 3782642..4b726d7 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -214,7 +214,6 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
         struct wined3d_context *context, DWORD location)
 {
     DWORD required_access = volume_access_from_location(location);
-    struct wined3d_texture *texture = volume->container;
 
     TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location),
         wined3d_debug_location(volume->locations));
@@ -237,9 +236,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
         case WINED3D_LOCATION_TEXTURE_RGB:
         case WINED3D_LOCATION_TEXTURE_SRGB:
             if ((location == WINED3D_LOCATION_TEXTURE_RGB
-                    && !(texture->flags & WINED3D_TEXTURE_RGB_ALLOCATED))
+                    && !(volume->container->flags & WINED3D_TEXTURE_RGB_ALLOCATED))
                     || (location == WINED3D_LOCATION_TEXTURE_SRGB
-                    && !(texture->flags & WINED3D_TEXTURE_SRGB_ALLOCATED)))
+                    && !(volume->container->flags & WINED3D_TEXTURE_SRGB_ALLOCATED)))
                 ERR("Trying to load (s)RGB texture without prior allocation.\n");
 
             if (volume->locations & WINED3D_LOCATION_DISCARDED)
@@ -250,18 +249,14 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
             else if (volume->locations & WINED3D_LOCATION_SYSMEM)
             {
                 struct wined3d_const_bo_address data = {0, volume->resource.heap_memory};
-                wined3d_texture_bind_and_dirtify(texture, context,
+                wined3d_texture_bind_and_dirtify(volume->container, context,
                         location == WINED3D_LOCATION_TEXTURE_SRGB);
                 wined3d_volume_upload_data(volume, context, &data);
             }
             else if (volume->locations & WINED3D_LOCATION_BUFFER)
             {
-                struct wined3d_const_bo_address data =
-                {
-                    texture->sub_resources[volume->texture_level].buffer_object,
-                    NULL
-                };
-                wined3d_texture_bind_and_dirtify(texture, context,
+                struct wined3d_const_bo_address data = {volume->pbo, NULL};
+                wined3d_texture_bind_and_dirtify(volume->container, context,
                         location == WINED3D_LOCATION_TEXTURE_SRGB);
                 wined3d_volume_upload_data(volume, context, &data);
             }
@@ -299,9 +294,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
                 struct wined3d_bo_address data = {0, volume->resource.heap_memory};
 
                 if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
-                    wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+                    wined3d_texture_bind_and_dirtify(volume->container, context, FALSE);
                 else
-                    wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+                    wined3d_texture_bind_and_dirtify(volume->container, context, TRUE);
 
                 volume->download_count++;
                 wined3d_volume_download_data(volume, context, &data);
@@ -316,7 +311,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
             break;
 
         case WINED3D_LOCATION_BUFFER:
-            if (!texture->sub_resources[volume->texture_level].buffer_object)
+            if (!volume->pbo)
                 ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n");
 
             if (volume->locations & WINED3D_LOCATION_DISCARDED)
@@ -326,16 +321,12 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume,
             }
             else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
             {
-                struct wined3d_bo_address data =
-                {
-                    texture->sub_resources[volume->texture_level].buffer_object,
-                    NULL
-                };
+                struct wined3d_bo_address data = {volume->pbo, NULL};
 
                 if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB)
-                    wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+                    wined3d_texture_bind_and_dirtify(volume->container, context, FALSE);
                 else
-                    wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+                    wined3d_texture_bind_and_dirtify(volume->container, context, TRUE);
 
                 wined3d_volume_download_data(volume, context, &data);
             }
@@ -365,31 +356,29 @@ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *
 /* Context activation is done by the caller. */
 static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct wined3d_context *context)
 {
-    GLuint *buffer_object = &volume->container->sub_resources[volume->texture_level].buffer_object;
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
-    if (*buffer_object)
+    if (volume->pbo)
         return;
 
-    GL_EXTCALL(glGenBuffers(1, buffer_object));
-    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *buffer_object));
+    GL_EXTCALL(glGenBuffers(1, &volume->pbo));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
     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", *buffer_object, volume);
+    TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume);
 }
 
 static void wined3d_volume_free_pbo(struct wined3d_volume *volume)
 {
-    GLuint *buffer_object = &volume->container->sub_resources[volume->texture_level].buffer_object;
     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", *buffer_object, volume);
-    GL_EXTCALL(glDeleteBuffers(1, buffer_object));
+    TRACE("Deleting PBO %u belonging to volume %p.\n", volume->pbo, volume);
+    GL_EXTCALL(glDeleteBuffers(1, &volume->pbo));
     checkGLcall("glDeleteBuffers");
-    *buffer_object = 0;
+    volume->pbo = 0;
     context_release(context);
 }
 
@@ -397,7 +386,7 @@ void wined3d_volume_cleanup(struct wined3d_volume *volume)
 {
     TRACE("volume %p.\n", volume);
 
-    if (volume->container->sub_resources[volume->texture_level].buffer_object)
+    if (volume->pbo)
         wined3d_volume_free_pbo(volume);
 
     resource_cleanup(&volume->resource);
@@ -428,7 +417,7 @@ static void volume_unload(struct wined3d_resource *resource)
         wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_DISCARDED);
     }
 
-    if (volume->container->sub_resources[volume->texture_level].buffer_object)
+    if (volume->pbo)
     {
         /* Should not happen because only dynamic default pool volumes
          * have a buffer, and those are not evicted by device_evit_managed_resources
@@ -468,12 +457,11 @@ 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_texture *texture = volume->container;
     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 = texture->resource.format_flags;
+    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);
@@ -495,7 +483,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
         return WINED3DERR_INVALIDCALL;
     }
     if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box
-            && !wined3d_texture_check_block_align(texture, volume->texture_level, box))
+            && !wined3d_texture_check_block_align(volume->container, volume->texture_level, box))
     {
         WARN("Map box %s is misaligned for %ux%u blocks.\n",
                 debug_box(box), format->block_width, format->block_height);
@@ -515,7 +503,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
         else
             wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
 
-        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->sub_resources[volume->texture_level].buffer_object));
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo));
 
         if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
         {
@@ -566,7 +554,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
     }
     else
     {
-        wined3d_texture_get_pitch(texture, volume->texture_level,
+        wined3d_texture_get_pitch(volume->container, volume->texture_level,
                 &map_desc->row_pitch, &map_desc->slice_pitch);
     }
 
@@ -596,7 +584,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
 
     if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
     {
-        wined3d_texture_set_dirty(texture);
+        wined3d_texture_set_dirty(volume->container);
         wined3d_volume_invalidate_location(volume, ~volume->resource.map_binding);
     }
 
@@ -624,8 +612,7 @@ HRESULT wined3d_volume_unmap(struct wined3d_volume *volume)
         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->container->sub_resources[volume->texture_level].buffer_object));
+        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");
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 468ff11..1774039 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2391,8 +2391,6 @@ struct wined3d_texture
             struct wined3d_surface *surface;
             struct wined3d_volume *volume;
         } u;
-
-        GLuint buffer_object;
     } sub_resources[1];
 };
 
@@ -2447,6 +2445,7 @@ struct wined3d_volume
     DWORD locations;
     GLint texture_level;
     DWORD download_count;
+    GLuint pbo;
 };
 
 static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource)
@@ -2522,6 +2521,9 @@ struct wined3d_surface
 
     UINT pow2Width;
     UINT pow2Height;
+
+    /* PBO */
+    GLuint                    pbo;
     GLuint rb_multisample;
     GLuint rb_resolved;
     GLenum texture_target;
-- 
2.7.1

