[PATCH 07/10] wined3d: Store surface/volume buffer objects in the sub-resource structure.

Henri Verbeet hverbeet at codeweavers.com
Wed Mar 2 12:24:18 CST 2016


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/surface.c         | 52 +++++++++++++++++++++------------
 dlls/wined3d/texture.c         |  4 +--
 dlls/wined3d/volume.c          | 65 +++++++++++++++++++++++++-----------------
 dlls/wined3d/wined3d_private.h |  6 ++--
 4 files changed, 76 insertions(+), 51 deletions(-)

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




More information about the wine-patches mailing list