View difference between Paste ID: WgNAEUkp and 21NkbbPX
SHOW: | | - or go back to the newest paste.
1
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
2
index c53021b..5b4ef8e 100644
3
--- a/dlls/wined3d/buffer.c
4
+++ b/dlls/wined3d/buffer.c
5
@@ -1147,7 +1147,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
6
 
7
     hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format,
8
             WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size,
9
-            parent, parent_ops, &buffer_resource_ops);
10
+            parent, parent_ops, &buffer_resource_ops, 0);
11
     if (FAILED(hr))
12
     {
13
         WARN("Failed to initialize resource, hr %#x\n", hr);
14
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
15
index 177d23e..21b4c0d 100644
16
--- a/dlls/wined3d/resource.c
17
+++ b/dlls/wined3d/resource.c
18
@@ -82,7 +82,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
19
         enum wined3d_multisample_type multisample_type, UINT multisample_quality,
20
         DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
21
         void *parent, const struct wined3d_parent_ops *parent_ops,
22
-        const struct wined3d_resource_ops *resource_ops)
23
+        const struct wined3d_resource_ops *resource_ops, void *have_alloc)
24
 {
25
     const struct wined3d *d3d = device->wined3d;
26
 
27
@@ -120,7 +120,9 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
28
 
29
     if (size)
30
     {
31
-        if (!wined3d_resource_allocate_sysmem(resource))
32
+        if (have_alloc) {
33
+            resource->heap_memory = have_alloc;
34
+        } else if (!wined3d_resource_allocate_sysmem(resource))
35
         {
36
             ERR("Failed to allocate system memory.\n");
37
             return E_OUTOFMEMORY;
38
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
39
index 628a4a5..3ab9878 100644
40
--- a/dlls/wined3d/surface.c
41
+++ b/dlls/wined3d/surface.c
42
@@ -6307,7 +6307,7 @@ cpu:
43
 }
44
 
45
 static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container,
46
-        const struct wined3d_resource_desc *desc, DWORD flags)
47
+        const struct wined3d_resource_desc *desc, DWORD flags, void *have_alloc)
48
 {
49
     struct wined3d_device *device = container->resource.device;
50
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
51
@@ -6365,7 +6365,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text
52
 
53
     if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, format,
54
             desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height, 1,
55
-            resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops)))
56
+            resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops, have_alloc)))
57
     {
58
         WARN("Failed to initialize resource, returning %#x.\n", hr);
59
         return hr;
60
@@ -6415,7 +6415,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text
61
 }
62
 
63
 HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container,
64
-        const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface)
65
+        const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface, void *have_alloc)
66
 {
67
     struct wined3d_device_parent *device_parent = container->resource.device->device_parent;
68
     const struct wined3d_parent_ops *parent_ops;
69
@@ -6432,7 +6432,7 @@ HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container,
70
     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
71
         return E_OUTOFMEMORY;
72
 
73
-    if (FAILED(hr = surface_init(object, container, desc, flags)))
74
+    if (FAILED(hr = surface_init(object, container, desc, flags, have_alloc)))
75
     {
76
         WARN("Failed to initialize surface, returning %#x.\n", hr);
77
         HeapFree(GetProcessHeap(), 0, object);
78
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
79
index 897af19..cb03c4c 100644
80
--- a/dlls/wined3d/texture.c
81
+++ b/dlls/wined3d/texture.c
82
@@ -51,7 +51,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
83
 
84
     if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
85
             desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool,
86
-            desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops)))
87
+            desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops, 0)))
88
     {
89
         WARN("Failed to initialize resource, returning %#x\n", hr);
90
         return hr;
91
@@ -879,7 +879,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
92
             UINT idx = j * texture->level_count + i;
93
             struct wined3d_surface *surface;
94
 
95
-            if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface)))
96
+            if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface, 0)))
97
             {
98
                 WARN("Failed to create surface, hr %#x.\n", hr);
99
                 wined3d_texture_cleanup(texture);
100
@@ -897,6 +897,21 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
101
     return WINED3D_OK;
102
 }
103
 
104
+void* wined3d_resource_allocate_sysmem_from_size(SIZE_T size)
105
+{
106
+    void **p;
107
+    SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p);
108
+    void *mem;
109
+
110
+    if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + align)))
111
+        return FALSE;
112
+
113
+    p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1;
114
+    *p = mem;
115
+
116
+    return ++p;
117
+}
118
+
119
 static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
120
         UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent,
121
         const struct wined3d_parent_ops *parent_ops)
122
@@ -1029,25 +1044,42 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
123
     /* Generate all the surfaces. */
124
     surface_desc = *desc;
125
     surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
126
+
127
+    SIZE_T resource_size = 0;
128
+    UINT pw = surface_desc.width;
129
+    UINT ph = surface_desc.height;
130
+    const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format);
131
+    // compute the needed space for all mipmaps
132
+    for (i = 0; i < texture->level_count; ++i)
133
+    {
134
+        resource_size += wined3d_format_calculate_size(format, device->surface_alignment, pw, ph, 1);
135
+        // next mipmap
136
+        pw = max(1, pw >> 1);
137
+        ph = max(1, ph >> 1);
138
+    }
139
+    // alloc
140
+    void *base_surface_alloc = wined3d_resource_allocate_sysmem_from_size(resource_size);
141
+    void *last_alloc = base_surface_alloc;
142
     for (i = 0; i < texture->level_count; ++i)
143
     {
144
         struct wined3d_surface *surface;
145
 
146
-        if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface)))
147
+        if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface, last_alloc)))
148
         {
149
             WARN("Failed to create surface, hr %#x.\n", hr);
150
             wined3d_texture_cleanup(texture);
151
             return hr;
152
         }
153
+        last_alloc += wined3d_format_calculate_size(format, device->surface_alignment, surface_desc.width, surface_desc.height, 1);
154
 
155
         surface_set_texture_target(surface, texture->target, i);
156
         texture->sub_resources[i] = &surface->resource;
157
+
158
         TRACE("Created surface level %u @ %p.\n", i, surface);
159
         /* Calculate the next mipmap level. */
160
         surface_desc.width = max(1, surface_desc.width >> 1);
161
         surface_desc.height = max(1, surface_desc.height >> 1);
162
     }
163
-
164
     return WINED3D_OK;
165
 }
166
 
167
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
168
index 817fe7e..335c65e 100644
169
--- a/dlls/wined3d/volume.c
170
+++ b/dlls/wined3d/volume.c
171
@@ -839,7 +839,7 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture
172
 
173
     if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format,
174
             WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth,
175
-            size, NULL, &wined3d_null_parent_ops, &volume_resource_ops)))
176
+            size, NULL, &wined3d_null_parent_ops, &volume_resource_ops, 0)))
177
     {
178
         WARN("Failed to initialize resource, returning %#x.\n", hr);
179
         return hr;
180
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
181
index 991db87..853a6c3 100644
182
--- a/dlls/wined3d/wined3d_private.h
183
+++ b/dlls/wined3d/wined3d_private.h
184
@@ -2015,7 +2015,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
185
         enum wined3d_multisample_type multisample_type, UINT multisample_quality,
186
         DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
187
         void *parent, const struct wined3d_parent_ops *parent_ops,
188
-        const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
189
+        const struct wined3d_resource_ops *resource_ops, void *have_alloc) DECLSPEC_HIDDEN;
190
 DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN;
191
 void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
192
 BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
193
@@ -2275,7 +2275,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
194
         struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;
195
 void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN;
196
 HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container,
197
-        const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface) DECLSPEC_HIDDEN;
198
+        const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface, void *last_alloc) DECLSPEC_HIDDEN;
199
 void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
200
 
201
 void get_drawable_size_swapchain(const struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;