[PATCH 4/7] wined3d: Allocate system memory for complete textures.

Henri Verbeet hverbeet at codeweavers.com
Wed Apr 20 12:29:12 CDT 2016


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/d3d8/tests/device.c       |  4 +--
 dlls/d3d9/tests/device.c       |  4 +--
 dlls/wined3d/surface.c         | 21 ++++++---------
 dlls/wined3d/swapchain.c       |  6 ++---
 dlls/wined3d/texture.c         | 60 ++++++++++++++++++++++++++++++------------
 dlls/wined3d/volume.c          | 22 +++++++---------
 dlls/wined3d/wined3d_private.h |  2 ++
 7 files changed, 69 insertions(+), 50 deletions(-)

diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index 13fe51a..11969f4 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -7929,7 +7929,7 @@ static void test_miptree_layout(void)
                 if (!i)
                     base = map_desc.pBits;
                 else
-                    todo_wine ok(map_desc.pBits == base + offset,
+                    ok(map_desc.pBits == base + offset,
                             "%s, %s, level %u: Got unexpected pBits %p, expected %p.\n",
                             pools[pool_idx].name, formats[format_idx].name, i, map_desc.pBits, base + offset);
                 offset += (base_dimension >> i) * map_desc.Pitch;
@@ -7968,7 +7968,7 @@ static void test_miptree_layout(void)
                     if (!i && !j)
                         base = map_desc.pBits;
                     else
-                        todo_wine ok(map_desc.pBits == base + offset,
+                        ok(map_desc.pBits == base + offset,
                                 "%s, %s, face %u, level %u: Got unexpected pBits %p, expected %p.\n",
                                 pools[pool_idx].name, formats[format_idx].name, i, j, map_desc.pBits, base + offset);
                     offset += (base_dimension >> j) * map_desc.Pitch;
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 8fc9a22..8860bce 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -11060,7 +11060,7 @@ static void test_miptree_layout(void)
                 if (!i)
                     base = map_desc.pBits;
                 else
-                    todo_wine ok(map_desc.pBits == base + offset,
+                    ok(map_desc.pBits == base + offset,
                             "%s, %s, level %u: Got unexpected pBits %p, expected %p.\n",
                             pools[pool_idx].name, formats[format_idx].name, i, map_desc.pBits, base + offset);
                 offset += (base_dimension >> i) * map_desc.Pitch;
@@ -11099,7 +11099,7 @@ static void test_miptree_layout(void)
                     if (!i && !j)
                         base = map_desc.pBits;
                     else
-                        todo_wine ok(map_desc.pBits == base + offset,
+                        ok(map_desc.pBits == base + offset,
                                 "%s, %s, face %u, level %u: Got unexpected pBits %p, expected %p.\n",
                                 pools[pool_idx].name, formats[format_idx].name, i, j, map_desc.pBits, base + offset);
                     offset += (base_dimension >> j) * map_desc.Pitch;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 075de5f..44d442b 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -398,7 +398,7 @@ HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface)
     }
 
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
-    desc.pMemory = wined3d_texture_map_bo_address(&data, surface->resource.size,
+    desc.pMemory = wined3d_texture_map_bo_address(&data, texture->sub_resources[sub_resource_idx].size,
             gl_info, GL_PIXEL_UNPACK_BUFFER, 0);
 
     if (context)
@@ -2746,21 +2746,21 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD
     unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
     struct wined3d_texture *texture = surface->container;
     struct wined3d_device *device = texture->resource.device;
+    struct wined3d_texture_sub_resource *sub_resource;
     struct wined3d_context *context;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_bo_address dst, src;
-    UINT size = surface->resource.size;
 
+    sub_resource = &texture->sub_resources[sub_resource_idx];
     wined3d_texture_get_memory(texture, sub_resource_idx, &dst, location);
-    wined3d_texture_get_memory(texture, sub_resource_idx, &src,
-            texture->sub_resources[sub_resource_idx].locations);
+    wined3d_texture_get_memory(texture, sub_resource_idx, &src, sub_resource->locations);
 
     if (dst.buffer_object)
     {
         context = context_acquire(device, NULL);
         gl_info = context->gl_info;
         GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object));
-        GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr));
+        GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, sub_resource->size, src.addr));
         GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
         checkGLcall("Upload PBO");
         context_release(context);
@@ -2771,13 +2771,13 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD
         context = context_acquire(device, NULL);
         gl_info = context->gl_info;
         GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object));
-        GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr));
+        GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, dst.addr));
         GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
         checkGLcall("Download PBO");
         context_release(context);
         return;
     }
-    memcpy(dst.addr, src.addr, size);
+    memcpy(dst.addr, src.addr, sub_resource->size);
 }
 
 /* Context activation is done by the caller. */
@@ -4316,16 +4316,11 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format);
     UINT multisample_quality = desc->multisample_quality;
-    unsigned int resource_size;
     HRESULT hr;
 
-    resource_size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, 1);
-    if (!resource_size)
-        return WINED3DERR_INVALIDCALL;
-
     if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE,
             format, desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height,
-            1, resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops)))
+            1, 0, NULL, &wined3d_null_parent_ops, &surface_resource_ops)))
     {
         WARN("Failed to initialize resource, returning %#x.\n", hr);
         return hr;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 202a890..f982add 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -703,15 +703,15 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain,
     /* Flip the surface data. */
     dc = front->dc;
     bitmap = front->bitmap;
-    data = front->resource.heap_memory;
+    data = front->container->resource.heap_memory;
 
     front->dc = back->dc;
     front->bitmap = back->bitmap;
-    front->resource.heap_memory = back->resource.heap_memory;
+    front->container->resource.heap_memory = back->container->resource.heap_memory;
 
     back->dc = dc;
     back->bitmap = bitmap;
-    back->resource.heap_memory = data;
+    back->container->resource.heap_memory = data;
 
     /* FPS support */
     if (TRACE_ON(fps))
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 047e12d..2d92c83 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -93,8 +93,8 @@ static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
             ERR("WINED3D_LOCATION_SYSMEM is the only location for sub-resource %u of texture %p.\n",
                     i, texture);
         sub_resource->locations &= ~WINED3D_LOCATION_SYSMEM;
-        wined3d_resource_free_sysmem(sub_resource->resource);
     }
+    wined3d_resource_free_sysmem(&texture->resource);
 }
 
 void wined3d_texture_validate_location(struct wined3d_texture *texture,
@@ -203,7 +203,8 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su
     }
     if (locations & WINED3D_LOCATION_SYSMEM)
     {
-        data->addr = sub_resource->resource->heap_memory;
+        data->addr = texture->resource.heap_memory;
+        data->addr += sub_resource->offset;
         data->buffer_object = 0;
         return;
     }
@@ -219,6 +220,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
         const struct wined3d_resource_ops *resource_ops)
 {
     const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format);
+    unsigned int i, j, size, offset = 0;
     HRESULT hr;
 
     TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
@@ -229,9 +231,30 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
             debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
             flags, device, parent, parent_ops, resource_ops);
 
+    if (!desc->width || !desc->height || !desc->depth)
+        return WINED3DERR_INVALIDCALL;
+
+    for (i = 0; i < layer_count; ++i)
+    {
+        for (j = 0; j < level_count; ++j)
+        {
+            unsigned int idx = i * level_count + j;
+
+            size = wined3d_format_calculate_size(format, device->surface_alignment,
+                    max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j));
+            texture->sub_resources[idx].offset = offset;
+            texture->sub_resources[idx].size = size;
+            offset += size;
+        }
+        offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1);
+    }
+
+    if (!offset)
+        return WINED3DERR_INVALIDCALL;
+
     if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
             desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool,
-            desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops)))
+            desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops)))
     {
         static unsigned int once;
 
@@ -984,7 +1007,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
         create_dib = TRUE;
     }
 
-    wined3d_resource_free_sysmem(sub_resource->resource);
+    wined3d_resource_free_sysmem(&texture->resource);
 
     if ((texture->row_pitch = pitch))
         texture->slice_pitch = height * pitch;
@@ -998,13 +1021,14 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
     texture->resource.multisample_quality = multisample_quality;
     texture->resource.width = width;
     texture->resource.height = height;
+    texture->resource.size = texture->slice_pitch;
 
     sub_resource->resource->format = format;
     sub_resource->resource->multisample_type = multisample_type;
     sub_resource->resource->multisample_quality = multisample_quality;
     sub_resource->resource->width = width;
     sub_resource->resource->height = height;
-    sub_resource->resource->size = texture->slice_pitch;
+    sub_resource->size = texture->slice_pitch;
     sub_resource->locations = WINED3D_LOCATION_DISCARDED;
 
     if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
@@ -1055,21 +1079,20 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
 static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
         unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
 {
-    GLuint *buffer_object;
+    struct wined3d_texture_sub_resource *sub_resource;
 
-    buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object;
-    if (*buffer_object)
+    sub_resource = &texture->sub_resources[sub_resource_idx];
+    if (sub_resource->buffer_object)
         return;
 
-    GL_EXTCALL(glGenBuffers(1, buffer_object));
-    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *buffer_object));
-    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER,
-            texture->sub_resources[sub_resource_idx].resource->size, NULL, GL_STREAM_DRAW));
+    GL_EXTCALL(glGenBuffers(1, &sub_resource->buffer_object));
+    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sub_resource->buffer_object));
+    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sub_resource->size, NULL, GL_STREAM_DRAW));
     GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
     checkGLcall("Create buffer object");
 
     TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
-            *buffer_object, texture, sub_resource_idx);
+            sub_resource->buffer_object, texture, sub_resource_idx);
 }
 
 static void wined3d_texture_force_reload(struct wined3d_texture *texture)
@@ -1179,10 +1202,10 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned
     switch (location)
     {
         case WINED3D_LOCATION_SYSMEM:
-            if (texture->sub_resources[sub_resource_idx].resource->heap_memory)
+            if (texture->resource.heap_memory)
                 return TRUE;
 
-            if (!wined3d_resource_allocate_sysmem(texture->sub_resources[sub_resource_idx].resource))
+            if (!wined3d_resource_allocate_sysmem(&texture->resource))
             {
                 ERR("Failed to allocate system memory.\n");
                 return FALSE;
@@ -1589,7 +1612,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
         wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
 
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
-    base_memory = wined3d_texture_map_bo_address(&data, sub_resource->resource->size,
+    base_memory = wined3d_texture_map_bo_address(&data, sub_resource->size,
             gl_info, GL_PIXEL_UNPACK_BUFFER, flags);
     TRACE("Base memory pointer %p.\n", base_memory);
 
@@ -2128,7 +2151,10 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
     texture->target = GL_TEXTURE_3D;
 
     if (wined3d_texture_use_pbo(texture, gl_info))
+    {
+        wined3d_resource_free_sysmem(&texture->resource);
         texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
+    }
 
     if (!(volumes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*volumes) * levels)))
     {
@@ -2391,7 +2417,7 @@ HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture
     desc->width = wined3d_texture_get_level_width(texture, level_idx);
     desc->height = wined3d_texture_get_level_height(texture, level_idx);
     desc->depth = wined3d_texture_get_level_depth(texture, level_idx);
-    desc->size = texture->sub_resources[sub_resource_idx].resource->size;
+    desc->size = texture->sub_resources[sub_resource_idx].size;
 
     return WINED3D_OK;
 }
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 6a92211..41a45f1 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -146,6 +146,7 @@ static DWORD volume_access_from_location(DWORD location)
 static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
         struct wined3d_context *context, BOOL dest_is_srgb)
 {
+    struct wined3d_texture *texture = volume->container;
     struct wined3d_bo_address data;
     /* Optimizations are possible, but the effort should be put into either
      * implementing EXT_SRGB_DECODE in the driver or finding out why we
@@ -156,13 +157,12 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
 
     WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
     data.buffer_object = 0;
-    data.addr = HeapAlloc(GetProcessHeap(), 0, volume->resource.size);
-    if (!data.addr)
+    if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, texture->sub_resources[volume->texture_level].size)))
         return;
 
-    wined3d_texture_bind_and_dirtify(volume->container, context, !dest_is_srgb);
+    wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
     wined3d_volume_download_data(volume, context, &data);
-    wined3d_texture_bind_and_dirtify(volume->container, context, dest_is_srgb);
+    wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
     wined3d_volume_upload_data(volume, context, wined3d_const_bo_address(&data));
 
     HeapFree(GetProcessHeap(), 0, data.addr);
@@ -211,7 +211,8 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
         case WINED3D_LOCATION_TEXTURE_SRGB:
             if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
             {
-                struct wined3d_const_bo_address data = {0, volume->resource.heap_memory};
+                struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
+                data.addr += sub_resource->offset;
                 wined3d_texture_bind_and_dirtify(texture, context,
                         location == WINED3D_LOCATION_TEXTURE_SRGB);
                 wined3d_volume_upload_data(volume, context, &data);
@@ -241,8 +242,9 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
         case WINED3D_LOCATION_SYSMEM:
             if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
             {
-                struct wined3d_bo_address data = {0, volume->resource.heap_memory};
+                struct wined3d_bo_address data = {0, texture->resource.heap_memory};
 
+                data.addr += sub_resource->offset;
                 if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
                     wined3d_texture_bind_and_dirtify(texture, context, FALSE);
                 else
@@ -348,21 +350,15 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format);
     HRESULT hr;
-    UINT size;
-
-    size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, desc->depth);
 
     if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format,
             WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth,
-            size, NULL, &wined3d_null_parent_ops, &volume_resource_ops)))
+            0, NULL, &wined3d_null_parent_ops, &volume_resource_ops)))
     {
         WARN("Failed to initialize resource, returning %#x.\n", hr);
         return hr;
     }
 
-    if (container->resource.map_binding == WINED3D_LOCATION_BUFFER)
-        wined3d_resource_free_sysmem(&volume->resource);
-
     volume->texture_level = level;
     volume->container = container;
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4f06796..2118a14 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2505,6 +2505,8 @@ struct wined3d_texture
             struct wined3d_surface *surface;
             struct wined3d_volume *volume;
         } u;
+        unsigned int offset;
+        unsigned int size;
 
         unsigned int map_count;
         DWORD locations;
-- 
2.1.4




More information about the wine-patches mailing list