VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/resource.c@ 53781

Last change on this file since 53781 was 48345, checked in by vboxsync, 11 years ago

header fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/*
2 * Copyright 2002-2004 Jason Edmeades
3 * Copyright 2003-2004 Raphael Junqueira
4 * Copyright 2004 Christian Costa
5 * Copyright 2005 Oliver Stieber
6 * Copyright 2009-2010 Henri Verbeet for CodeWeavers
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23/*
24 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
25 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
26 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
27 * a choice of LGPL license versions is made available with the language indicating
28 * that LGPLv2 or any later version may be used, or where a choice of which version
29 * of the LGPL is applied is otherwise unspecified.
30 */
31
32#include "config.h"
33#include "wine/port.h"
34#include "wined3d_private.h"
35
36WINE_DEFAULT_DEBUG_CHANNEL(d3d);
37
38struct private_data
39{
40 struct list entry;
41
42 GUID tag;
43 DWORD flags; /* DDSPD_* */
44
45 union
46 {
47 void *data;
48 IUnknown *object;
49 } ptr;
50
51 DWORD size;
52};
53
54static DWORD resource_access_from_pool(enum wined3d_pool pool)
55{
56 switch (pool)
57 {
58 case WINED3D_POOL_DEFAULT:
59 return WINED3D_RESOURCE_ACCESS_GPU;
60
61 case WINED3D_POOL_MANAGED:
62 return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU;
63
64 case WINED3D_POOL_SYSTEM_MEM:
65 return WINED3D_RESOURCE_ACCESS_CPU;
66
67 case WINED3D_POOL_SCRATCH:
68 return WINED3D_RESOURCE_ACCESS_SCRATCH;
69
70 default:
71 FIXME("Unhandled pool %#x.\n", pool);
72 return 0;
73 }
74}
75
76static void resource_check_usage(DWORD usage)
77{
78 static const DWORD handled = WINED3DUSAGE_RENDERTARGET
79 | WINED3DUSAGE_DEPTHSTENCIL
80 | WINED3DUSAGE_DYNAMIC
81 | WINED3DUSAGE_AUTOGENMIPMAP
82 | WINED3DUSAGE_STATICDECL
83 | WINED3DUSAGE_OVERLAY;
84
85 if (usage & ~handled)
86 FIXME("Unhandled usage flags %#x.\n", usage & ~handled);
87}
88
89HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
90 enum wined3d_resource_type type, const struct wined3d_format *format,
91 enum wined3d_multisample_type multisample_type, UINT multisample_quality,
92 DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
93 void *parent, const struct wined3d_parent_ops *parent_ops,
94 const struct wined3d_resource_ops *resource_ops
95#ifdef VBOX_WITH_WDDM
96 , HANDLE *shared_handle
97 , void *pvClientMem
98#endif
99 )
100{
101 const struct wined3d *d3d = device->wined3d;
102
103 resource->ref = 1;
104 resource->device = device;
105 resource->type = type;
106 resource->format = format;
107 resource->multisample_type = multisample_type;
108 resource->multisample_quality = multisample_quality;
109 resource->usage = usage;
110 resource->pool = pool;
111 resource->access_flags = resource_access_from_pool(pool);
112 if (usage & WINED3DUSAGE_DYNAMIC)
113 resource->access_flags |= WINED3D_RESOURCE_ACCESS_CPU;
114 resource->width = width;
115 resource->height = height;
116 resource->depth = depth;
117 resource->size = size;
118 resource->priority = 0;
119 resource->parent = parent;
120 resource->parent_ops = parent_ops;
121 resource->resource_ops = resource_ops;
122 list_init(&resource->privateData);
123
124 resource_check_usage(usage);
125
126#ifdef VBOX_WITH_WDDM
127 resource->sharerc_handle = 0;
128 resource->sharerc_flags = 0;
129 resource->sharerc_locks = 0;
130 if (pool == WINED3D_POOL_SYSTEM_MEM && pvClientMem)
131 {
132 resource->allocatedMemory = pvClientMem;
133 resource->heapMemory = NULL;
134 }
135 else
136#endif
137 {
138#ifdef VBOX_WITH_WDDM
139 if (pool == WINED3D_POOL_DEFAULT && shared_handle)
140 {
141 resource->sharerc_handle = (DWORD)*shared_handle;
142 resource->sharerc_flags = VBOXSHRC_F_SHARED;
143 if (*shared_handle)
144 resource->sharerc_flags |= VBOXSHRC_F_SHARED_OPENED;
145 }
146#endif
147
148 if (size)
149 {
150 resource->heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + RESOURCE_ALIGNMENT);
151 if (!resource->heapMemory)
152 {
153 ERR("Out of memory!\n");
154 return WINED3DERR_OUTOFVIDEOMEMORY;
155 }
156 }
157 else
158 {
159 resource->heapMemory = NULL;
160 }
161 resource->allocatedMemory = (BYTE *)(((ULONG_PTR)resource->heapMemory
162 + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
163 }
164
165#ifndef VBOX_WITH_WDDM
166 /* Check that we have enough video ram left */
167 if (pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
168 {
169 if (size > wined3d_device_get_available_texture_mem(device))
170 {
171 ERR("Out of adapter memory\n");
172 HeapFree(GetProcessHeap(), 0, resource->heapMemory);
173 return WINED3DERR_OUTOFVIDEOMEMORY;
174 }
175 adapter_adjust_memory(device->adapter, size);
176 }
177#endif
178
179 device_resource_add(device, resource);
180
181 return WINED3D_OK;
182}
183
184void resource_cleanup(struct wined3d_resource *resource)
185{
186 const struct wined3d *d3d = resource->device->wined3d;
187 struct private_data *data;
188 struct list *e1, *e2;
189 HRESULT hr;
190
191 TRACE("Cleaning up resource %p.\n", resource);
192#ifndef VBOX_WITH_WDDM
193 if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
194 {
195 TRACE("Decrementing device memory pool by %u.\n", resource->size);
196 adapter_adjust_memory(resource->device->adapter, 0 - resource->size);
197 }
198#endif
199
200 LIST_FOR_EACH_SAFE(e1, e2, &resource->privateData)
201 {
202 data = LIST_ENTRY(e1, struct private_data, entry);
203 hr = wined3d_resource_free_private_data(resource, &data->tag);
204 if (FAILED(hr))
205 ERR("Failed to free private data when destroying resource %p, hr = %#x.\n", resource, hr);
206 }
207
208 HeapFree(GetProcessHeap(), 0, resource->heapMemory);
209 resource->allocatedMemory = 0;
210 resource->heapMemory = 0;
211
212 device_resource_released(resource->device, resource);
213}
214
215void resource_unload(struct wined3d_resource *resource)
216{
217 if (resource->map_count)
218 ERR("Resource %p is being unloaded while mapped.\n", resource);
219
220 context_resource_unloaded(resource->device,
221 resource, resource->type);
222}
223
224static struct private_data *resource_find_private_data(const struct wined3d_resource *resource, REFGUID tag)
225{
226 struct private_data *data;
227 struct list *entry;
228
229 TRACE("Searching for private data %s\n", debugstr_guid(tag));
230 LIST_FOR_EACH(entry, &resource->privateData)
231 {
232 data = LIST_ENTRY(entry, struct private_data, entry);
233 if (IsEqualGUID(&data->tag, tag)) {
234 TRACE("Found %p\n", data);
235 return data;
236 }
237 }
238 TRACE("Not found\n");
239 return NULL;
240}
241
242HRESULT CDECL wined3d_resource_set_private_data(struct wined3d_resource *resource, REFGUID guid,
243 const void *data, DWORD data_size, DWORD flags)
244{
245 struct private_data *d;
246
247 TRACE("resource %p, riid %s, data %p, data_size %u, flags %#x.\n",
248 resource, debugstr_guid(guid), data, data_size, flags);
249
250 wined3d_resource_free_private_data(resource, guid);
251
252 d = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d));
253 if (!d) return E_OUTOFMEMORY;
254
255 d->tag = *guid;
256 d->flags = flags;
257
258 if (flags & WINED3DSPD_IUNKNOWN)
259 {
260 if (data_size != sizeof(IUnknown *))
261 {
262 WARN("IUnknown data with size %u, returning WINED3DERR_INVALIDCALL.\n", data_size);
263 HeapFree(GetProcessHeap(), 0, d);
264 return WINED3DERR_INVALIDCALL;
265 }
266 d->ptr.object = (IUnknown *)data;
267 d->size = sizeof(IUnknown *);
268 IUnknown_AddRef(d->ptr.object);
269 }
270 else
271 {
272 d->ptr.data = HeapAlloc(GetProcessHeap(), 0, data_size);
273 if (!d->ptr.data)
274 {
275 HeapFree(GetProcessHeap(), 0, d);
276 return E_OUTOFMEMORY;
277 }
278 d->size = data_size;
279 memcpy(d->ptr.data, data, data_size);
280 }
281 list_add_tail(&resource->privateData, &d->entry);
282
283 return WINED3D_OK;
284}
285
286HRESULT CDECL wined3d_resource_get_private_data(const struct wined3d_resource *resource, REFGUID guid,
287 void *data, DWORD *data_size)
288{
289 const struct private_data *d;
290
291 TRACE("resource %p, guid %s, data %p, data_size %p.\n",
292 resource, debugstr_guid(guid), data, data_size);
293
294 d = resource_find_private_data(resource, guid);
295 if (!d) return WINED3DERR_NOTFOUND;
296
297 if (*data_size < d->size)
298 {
299 *data_size = d->size;
300 return WINED3DERR_MOREDATA;
301 }
302
303 if (d->flags & WINED3DSPD_IUNKNOWN)
304 {
305 *(IUnknown **)data = d->ptr.object;
306 if (resource->device->wined3d->dxVersion != 7)
307 {
308 /* D3D8 and D3D9 addref the private data, DDraw does not. This
309 * can't be handled in ddraw because it doesn't know if the
310 * pointer returned is an IUnknown * or just a blob. */
311 IUnknown_AddRef(d->ptr.object);
312 }
313 }
314 else
315 {
316 memcpy(data, d->ptr.data, d->size);
317 }
318
319 return WINED3D_OK;
320}
321HRESULT CDECL wined3d_resource_free_private_data(struct wined3d_resource *resource, REFGUID guid)
322{
323 struct private_data *data;
324
325 TRACE("resource %p, guid %s.\n", resource, debugstr_guid(guid));
326
327 data = resource_find_private_data(resource, guid);
328 if (!data) return WINED3DERR_NOTFOUND;
329
330 if (data->flags & WINED3DSPD_IUNKNOWN)
331 {
332 if (data->ptr.object)
333 IUnknown_Release(data->ptr.object);
334 }
335 else
336 {
337 HeapFree(GetProcessHeap(), 0, data->ptr.data);
338 }
339 list_remove(&data->entry);
340
341 HeapFree(GetProcessHeap(), 0, data);
342
343 return WINED3D_OK;
344}
345
346DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority)
347{
348 DWORD prev = resource->priority;
349 resource->priority = priority;
350 TRACE("resource %p, new priority %u, returning old priority %u.\n", resource, priority, prev);
351 return prev;
352}
353
354DWORD resource_get_priority(const struct wined3d_resource *resource)
355{
356 TRACE("resource %p, returning %u.\n", resource, resource->priority);
357 return resource->priority;
358}
359
360void * CDECL wined3d_resource_get_parent(const struct wined3d_resource *resource)
361{
362 return resource->parent;
363}
364
365void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc)
366{
367 desc->resource_type = resource->type;
368 desc->format = resource->format->id;
369 desc->multisample_type = resource->multisample_type;
370 desc->multisample_quality = resource->multisample_quality;
371 desc->usage = resource->usage;
372 desc->pool = resource->pool;
373 desc->width = resource->width;
374 desc->height = resource->height;
375 desc->depth = resource->depth;
376 desc->size = resource->size;
377}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette