xref: /reactos/dll/directx/wine/d3d8/texture.c (revision b819608e)
1 /*
2  * Copyright 2005 Oliver Stieber
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include "d3d8_private.h"
20 
21 static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface)
22 {
23     return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
24 }
25 
26 static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface)
27 {
28     return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
29 }
30 
31 static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface)
32 {
33     return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
34 }
35 
36 static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out)
37 {
38     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
39 
40     if (IsEqualGUID(riid, &IID_IDirect3DTexture8)
41             || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
42             || IsEqualGUID(riid, &IID_IDirect3DResource8)
43             || IsEqualGUID(riid, &IID_IUnknown))
44     {
45         IDirect3DTexture8_AddRef(iface);
46         *out = iface;
47         return S_OK;
48     }
49 
50     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
51 
52     *out = NULL;
53     return E_NOINTERFACE;
54 }
55 
56 static ULONG WINAPI d3d8_texture_2d_AddRef(IDirect3DTexture8 *iface)
57 {
58     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
59     ULONG ref = InterlockedIncrement(&texture->resource.refcount);
60 
61     TRACE("%p increasing refcount to %u.\n", iface, ref);
62 
63     if (ref == 1)
64     {
65         IDirect3DDevice8_AddRef(texture->parent_device);
66         wined3d_mutex_lock();
67         wined3d_texture_incref(texture->wined3d_texture);
68         wined3d_mutex_unlock();
69     }
70 
71     return ref;
72 }
73 
74 static ULONG WINAPI d3d8_texture_2d_Release(IDirect3DTexture8 *iface)
75 {
76     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
77     ULONG ref = InterlockedDecrement(&texture->resource.refcount);
78 
79     TRACE("%p decreasing refcount to %u.\n", iface, ref);
80 
81     if (!ref)
82     {
83         IDirect3DDevice8 *parent_device = texture->parent_device;
84 
85         wined3d_mutex_lock();
86         wined3d_texture_decref(texture->wined3d_texture);
87         wined3d_mutex_unlock();
88 
89         /* Release the device last, as it may cause the device to be destroyed. */
90         IDirect3DDevice8_Release(parent_device);
91     }
92     return ref;
93 }
94 
95 static HRESULT WINAPI d3d8_texture_2d_GetDevice(IDirect3DTexture8 *iface, IDirect3DDevice8 **device)
96 {
97     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
98 
99     TRACE("iface %p, device %p.\n", iface, device);
100 
101     *device = texture->parent_device;
102     IDirect3DDevice8_AddRef(*device);
103 
104     TRACE("Returning device %p.\n", *device);
105 
106     return D3D_OK;
107 }
108 
109 static HRESULT WINAPI d3d8_texture_2d_SetPrivateData(IDirect3DTexture8 *iface,
110         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
111 {
112     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
113     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
114             iface, debugstr_guid(guid), data, data_size, flags);
115 
116     return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
117 }
118 
119 static HRESULT WINAPI d3d8_texture_2d_GetPrivateData(IDirect3DTexture8 *iface,
120         REFGUID guid, void *data, DWORD *data_size)
121 {
122     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
123     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
124             iface, debugstr_guid(guid), data, data_size);
125 
126     return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size);
127 }
128 
129 static HRESULT WINAPI d3d8_texture_2d_FreePrivateData(IDirect3DTexture8 *iface, REFGUID guid)
130 {
131     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
132     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
133 
134     return d3d8_resource_free_private_data(&texture->resource, guid);
135 }
136 
137 static DWORD WINAPI d3d8_texture_2d_SetPriority(IDirect3DTexture8 *iface, DWORD priority)
138 {
139     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
140     DWORD ret;
141 
142     TRACE("iface %p, priority %u.\n", iface, priority);
143 
144     wined3d_mutex_lock();
145     ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
146     wined3d_mutex_unlock();
147 
148     return ret;
149 }
150 
151 static DWORD WINAPI d3d8_texture_2d_GetPriority(IDirect3DTexture8 *iface)
152 {
153     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
154     DWORD ret;
155 
156     TRACE("iface %p.\n", iface);
157 
158     wined3d_mutex_lock();
159     ret = wined3d_texture_get_priority(texture->wined3d_texture);
160     wined3d_mutex_unlock();
161 
162     return ret;
163 }
164 
165 static void WINAPI d3d8_texture_2d_PreLoad(IDirect3DTexture8 *iface)
166 {
167     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
168 
169     TRACE("iface %p.\n", iface);
170 
171     wined3d_mutex_lock();
172     wined3d_texture_preload(texture->wined3d_texture);
173     wined3d_mutex_unlock();
174 }
175 
176 static D3DRESOURCETYPE WINAPI d3d8_texture_2d_GetType(IDirect3DTexture8 *iface)
177 {
178     TRACE("iface %p.\n", iface);
179 
180     return D3DRTYPE_TEXTURE;
181 }
182 
183 static DWORD WINAPI d3d8_texture_2d_SetLOD(IDirect3DTexture8 *iface, DWORD lod)
184 {
185     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
186     DWORD ret;
187 
188     TRACE("iface %p, lod %u.\n", iface, lod);
189 
190     wined3d_mutex_lock();
191     ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
192     wined3d_mutex_unlock();
193 
194     return ret;
195 }
196 
197 static DWORD WINAPI d3d8_texture_2d_GetLOD(IDirect3DTexture8 *iface)
198 {
199     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
200     DWORD ret;
201 
202     TRACE("iface %p.\n", iface);
203 
204     wined3d_mutex_lock();
205     ret = wined3d_texture_get_lod(texture->wined3d_texture);
206     wined3d_mutex_unlock();
207 
208     return ret;
209 }
210 
211 static DWORD WINAPI d3d8_texture_2d_GetLevelCount(IDirect3DTexture8 *iface)
212 {
213     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
214     DWORD ret;
215 
216     TRACE("iface %p.\n", iface);
217 
218     wined3d_mutex_lock();
219     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
220     wined3d_mutex_unlock();
221 
222     return ret;
223 }
224 
225 static HRESULT WINAPI d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8 *iface, UINT level, D3DSURFACE_DESC *desc)
226 {
227     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
228     struct wined3d_resource *sub_resource;
229     HRESULT hr = D3D_OK;
230 
231     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
232 
233     wined3d_mutex_lock();
234     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
235         hr = D3DERR_INVALIDCALL;
236     else
237     {
238         struct wined3d_resource_desc wined3d_desc;
239 
240         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
241         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
242         desc->Type = wined3d_desc.resource_type;
243         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
244         desc->Pool = wined3d_desc.pool;
245         desc->Size = wined3d_desc.size;
246         desc->MultiSampleType = wined3d_desc.multisample_type;
247         desc->Width = wined3d_desc.width;
248         desc->Height = wined3d_desc.height;
249     }
250     wined3d_mutex_unlock();
251 
252     return hr;
253 }
254 
255 static HRESULT WINAPI d3d8_texture_2d_GetSurfaceLevel(IDirect3DTexture8 *iface,
256         UINT level, IDirect3DSurface8 **surface)
257 {
258     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
259     struct wined3d_resource *sub_resource;
260     struct d3d8_surface *surface_impl;
261 
262     TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
263 
264     wined3d_mutex_lock();
265     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
266     {
267         wined3d_mutex_unlock();
268         return D3DERR_INVALIDCALL;
269     }
270 
271     surface_impl = wined3d_resource_get_parent(sub_resource);
272     *surface = &surface_impl->IDirect3DSurface8_iface;
273     IDirect3DSurface8_AddRef(*surface);
274     wined3d_mutex_unlock();
275 
276     return D3D_OK;
277 }
278 
279 static HRESULT WINAPI d3d8_texture_2d_LockRect(IDirect3DTexture8 *iface, UINT level,
280         D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
281 {
282     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
283     struct wined3d_resource *sub_resource;
284     struct d3d8_surface *surface_impl;
285     HRESULT hr;
286 
287     TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
288             iface, level, locked_rect, rect, flags);
289 
290     wined3d_mutex_lock();
291     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
292         hr = D3DERR_INVALIDCALL;
293     else
294     {
295         surface_impl = wined3d_resource_get_parent(sub_resource);
296         hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
297     }
298     wined3d_mutex_unlock();
299 
300     return hr;
301 }
302 
303 static HRESULT WINAPI d3d8_texture_2d_UnlockRect(IDirect3DTexture8 *iface, UINT level)
304 {
305     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
306     struct wined3d_resource *sub_resource;
307     struct d3d8_surface *surface_impl;
308     HRESULT hr;
309 
310     TRACE("iface %p, level %u.\n", iface, level);
311 
312     wined3d_mutex_lock();
313     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
314         hr = D3DERR_INVALIDCALL;
315     else
316     {
317         surface_impl = wined3d_resource_get_parent(sub_resource);
318         hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
319     }
320     wined3d_mutex_unlock();
321 
322     return hr;
323 }
324 
325 static HRESULT WINAPI d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8 *iface, const RECT *dirty_rect)
326 {
327     struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
328     HRESULT hr;
329 
330     TRACE("iface %p, dirty_rect %s.\n",
331             iface, wine_dbgstr_rect(dirty_rect));
332 
333     wined3d_mutex_lock();
334     if (!dirty_rect)
335         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
336     else
337     {
338         struct wined3d_box dirty_region;
339 
340         dirty_region.left = dirty_rect->left;
341         dirty_region.top = dirty_rect->top;
342         dirty_region.right = dirty_rect->right;
343         dirty_region.bottom = dirty_rect->bottom;
344         dirty_region.front = 0;
345         dirty_region.back = 1;
346         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
347     }
348     wined3d_mutex_unlock();
349 
350     return hr;
351 }
352 
353 static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl =
354 {
355     /* IUnknown */
356     d3d8_texture_2d_QueryInterface,
357     d3d8_texture_2d_AddRef,
358     d3d8_texture_2d_Release,
359     /* IDirect3DResource8 */
360     d3d8_texture_2d_GetDevice,
361     d3d8_texture_2d_SetPrivateData,
362     d3d8_texture_2d_GetPrivateData,
363     d3d8_texture_2d_FreePrivateData,
364     d3d8_texture_2d_SetPriority,
365     d3d8_texture_2d_GetPriority,
366     d3d8_texture_2d_PreLoad,
367     d3d8_texture_2d_GetType,
368     /* IDirect3dBaseTexture8 */
369     d3d8_texture_2d_SetLOD,
370     d3d8_texture_2d_GetLOD,
371     d3d8_texture_2d_GetLevelCount,
372     /* IDirect3DTexture8 */
373     d3d8_texture_2d_GetLevelDesc,
374     d3d8_texture_2d_GetSurfaceLevel,
375     d3d8_texture_2d_LockRect,
376     d3d8_texture_2d_UnlockRect,
377     d3d8_texture_2d_AddDirtyRect,
378 };
379 
380 static HRESULT WINAPI d3d8_texture_cube_QueryInterface(IDirect3DCubeTexture8 *iface, REFIID riid, void **out)
381 {
382     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
383 
384     if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture8)
385             || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
386             || IsEqualGUID(riid, &IID_IDirect3DResource8)
387             || IsEqualGUID(riid, &IID_IUnknown))
388     {
389         IDirect3DCubeTexture8_AddRef(iface);
390         *out = iface;
391         return S_OK;
392     }
393 
394     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
395 
396     *out = NULL;
397     return E_NOINTERFACE;
398 }
399 
400 static ULONG WINAPI d3d8_texture_cube_AddRef(IDirect3DCubeTexture8 *iface)
401 {
402     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
403     ULONG ref = InterlockedIncrement(&texture->resource.refcount);
404 
405     TRACE("%p increasing refcount to %u.\n", iface, ref);
406 
407     if (ref == 1)
408     {
409         IDirect3DDevice8_AddRef(texture->parent_device);
410         wined3d_mutex_lock();
411         wined3d_texture_incref(texture->wined3d_texture);
412         wined3d_mutex_unlock();
413     }
414 
415     return ref;
416 }
417 
418 static ULONG WINAPI d3d8_texture_cube_Release(IDirect3DCubeTexture8 *iface)
419 {
420     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
421     ULONG ref = InterlockedDecrement(&texture->resource.refcount);
422 
423     TRACE("%p decreasing refcount to %u.\n", iface, ref);
424 
425     if (!ref)
426     {
427         IDirect3DDevice8 *parent_device = texture->parent_device;
428 
429         TRACE("Releasing child %p.\n", texture->wined3d_texture);
430 
431         wined3d_mutex_lock();
432         wined3d_texture_decref(texture->wined3d_texture);
433         wined3d_mutex_unlock();
434 
435         /* Release the device last, as it may cause the device to be destroyed. */
436         IDirect3DDevice8_Release(parent_device);
437     }
438     return ref;
439 }
440 
441 static HRESULT WINAPI d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8 *iface, IDirect3DDevice8 **device)
442 {
443     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
444 
445     TRACE("iface %p, device %p.\n", iface, device);
446 
447     *device = texture->parent_device;
448     IDirect3DDevice8_AddRef(*device);
449 
450     TRACE("Returning device %p.\n", *device);
451 
452     return D3D_OK;
453 }
454 
455 static HRESULT WINAPI d3d8_texture_cube_SetPrivateData(IDirect3DCubeTexture8 *iface,
456         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
457 {
458     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
459     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
460             iface, debugstr_guid(guid), data, data_size, flags);
461 
462     return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
463 }
464 
465 static HRESULT WINAPI d3d8_texture_cube_GetPrivateData(IDirect3DCubeTexture8 *iface,
466         REFGUID guid, void *data, DWORD *data_size)
467 {
468     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
469     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
470             iface, debugstr_guid(guid), data, data_size);
471 
472     return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size);
473 }
474 
475 static HRESULT WINAPI d3d8_texture_cube_FreePrivateData(IDirect3DCubeTexture8 *iface, REFGUID guid)
476 {
477     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
478     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
479 
480     return d3d8_resource_free_private_data(&texture->resource, guid);
481 }
482 
483 static DWORD WINAPI d3d8_texture_cube_SetPriority(IDirect3DCubeTexture8 *iface, DWORD priority)
484 {
485     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
486     DWORD ret;
487 
488     TRACE("iface %p, priority %u.\n", iface, priority);
489 
490     wined3d_mutex_lock();
491     ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
492     wined3d_mutex_unlock();
493 
494     return ret;
495 }
496 
497 static DWORD WINAPI d3d8_texture_cube_GetPriority(IDirect3DCubeTexture8 *iface)
498 {
499     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
500     DWORD ret;
501 
502     TRACE("iface %p.\n", iface);
503 
504     wined3d_mutex_lock();
505     ret =  wined3d_texture_get_priority(texture->wined3d_texture);
506     wined3d_mutex_unlock();
507 
508     return ret;
509 }
510 
511 static void WINAPI d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8 *iface)
512 {
513     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
514 
515     TRACE("iface %p.\n", iface);
516 
517     wined3d_mutex_lock();
518     wined3d_texture_preload(texture->wined3d_texture);
519     wined3d_mutex_unlock();
520 }
521 
522 static D3DRESOURCETYPE WINAPI d3d8_texture_cube_GetType(IDirect3DCubeTexture8 *iface)
523 {
524     TRACE("iface %p.\n", iface);
525 
526     return D3DRTYPE_CUBETEXTURE;
527 }
528 
529 static DWORD WINAPI d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8 *iface, DWORD lod)
530 {
531     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
532     DWORD ret;
533 
534     TRACE("iface %p, lod %u.\n", iface, lod);
535 
536     wined3d_mutex_lock();
537     ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
538     wined3d_mutex_unlock();
539 
540     return ret;
541 }
542 
543 static DWORD WINAPI d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8 *iface)
544 {
545     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
546     DWORD ret;
547 
548     TRACE("iface %p.\n", iface);
549 
550     wined3d_mutex_lock();
551     ret = wined3d_texture_get_lod(texture->wined3d_texture);
552     wined3d_mutex_unlock();
553 
554     return ret;
555 }
556 
557 static DWORD WINAPI d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8 *iface)
558 {
559     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
560     DWORD ret;
561 
562     TRACE("iface %p.\n", iface);
563 
564     wined3d_mutex_lock();
565     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
566     wined3d_mutex_unlock();
567 
568     return ret;
569 }
570 
571 static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *iface, UINT level, D3DSURFACE_DESC *desc)
572 {
573     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
574     struct wined3d_resource *sub_resource;
575     HRESULT hr = D3D_OK;
576 
577     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
578 
579     wined3d_mutex_lock();
580     if (level >= wined3d_texture_get_level_count(texture->wined3d_texture))
581     {
582         wined3d_mutex_unlock();
583         return D3DERR_INVALIDCALL;
584     }
585 
586     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
587         hr = D3DERR_INVALIDCALL;
588     else
589     {
590         struct wined3d_resource_desc wined3d_desc;
591 
592         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
593         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
594         desc->Type = wined3d_desc.resource_type;
595         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
596         desc->Pool = wined3d_desc.pool;
597         desc->Size = wined3d_desc.size;
598         desc->MultiSampleType = wined3d_desc.multisample_type;
599         desc->Width = wined3d_desc.width;
600         desc->Height = wined3d_desc.height;
601     }
602     wined3d_mutex_unlock();
603 
604     return hr;
605 }
606 
607 static HRESULT WINAPI d3d8_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture8 *iface,
608         D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface8 **surface)
609 {
610     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
611     struct wined3d_resource *sub_resource;
612     struct d3d8_surface *surface_impl;
613     UINT sub_resource_idx;
614     DWORD level_count;
615 
616     TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
617 
618     wined3d_mutex_lock();
619     level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
620     if (level >= level_count)
621     {
622         wined3d_mutex_unlock();
623         return D3DERR_INVALIDCALL;
624     }
625 
626     sub_resource_idx = level_count * face + level;
627     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
628     {
629         wined3d_mutex_unlock();
630         return D3DERR_INVALIDCALL;
631     }
632 
633     surface_impl = wined3d_resource_get_parent(sub_resource);
634     *surface = &surface_impl->IDirect3DSurface8_iface;
635     IDirect3DSurface8_AddRef(*surface);
636     wined3d_mutex_unlock();
637 
638     return D3D_OK;
639 }
640 
641 static HRESULT WINAPI d3d8_texture_cube_LockRect(IDirect3DCubeTexture8 *iface,
642         D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
643         DWORD flags)
644 {
645     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
646     struct wined3d_resource *sub_resource;
647     struct d3d8_surface *surface_impl;
648     UINT sub_resource_idx;
649     HRESULT hr;
650 
651     TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
652             iface, face, level, locked_rect, rect, flags);
653 
654     wined3d_mutex_lock();
655     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
656     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
657         hr = D3DERR_INVALIDCALL;
658     else
659     {
660         surface_impl = wined3d_resource_get_parent(sub_resource);
661         hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
662     }
663     wined3d_mutex_unlock();
664 
665     return hr;
666 }
667 
668 static HRESULT WINAPI d3d8_texture_cube_UnlockRect(IDirect3DCubeTexture8 *iface,
669         D3DCUBEMAP_FACES face, UINT level)
670 {
671     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
672     struct wined3d_resource *sub_resource;
673     struct d3d8_surface *surface_impl;
674     UINT sub_resource_idx;
675     HRESULT hr;
676 
677     TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
678 
679     wined3d_mutex_lock();
680     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
681     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
682         hr = D3DERR_INVALIDCALL;
683     else
684     {
685         surface_impl = wined3d_resource_get_parent(sub_resource);
686         hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
687     }
688     wined3d_mutex_unlock();
689 
690     return hr;
691 }
692 
693 static HRESULT WINAPI d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8 *iface,
694         D3DCUBEMAP_FACES face, const RECT *dirty_rect)
695 {
696     struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
697     HRESULT hr;
698 
699     TRACE("iface %p, face %#x, dirty_rect %s.\n",
700             iface, face, wine_dbgstr_rect(dirty_rect));
701 
702     wined3d_mutex_lock();
703     if (!dirty_rect)
704         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
705     else
706     {
707         struct wined3d_box dirty_region;
708 
709         dirty_region.left = dirty_rect->left;
710         dirty_region.top = dirty_rect->top;
711         dirty_region.right = dirty_rect->right;
712         dirty_region.bottom = dirty_rect->bottom;
713         dirty_region.front = 0;
714         dirty_region.back = 1;
715         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
716     }
717     wined3d_mutex_unlock();
718 
719     return hr;
720 }
721 
722 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl =
723 {
724     /* IUnknown */
725     d3d8_texture_cube_QueryInterface,
726     d3d8_texture_cube_AddRef,
727     d3d8_texture_cube_Release,
728     /* IDirect3DResource8 */
729     d3d8_texture_cube_GetDevice,
730     d3d8_texture_cube_SetPrivateData,
731     d3d8_texture_cube_GetPrivateData,
732     d3d8_texture_cube_FreePrivateData,
733     d3d8_texture_cube_SetPriority,
734     d3d8_texture_cube_GetPriority,
735     d3d8_texture_cube_PreLoad,
736     d3d8_texture_cube_GetType,
737     /* IDirect3DBaseTexture8 */
738     d3d8_texture_cube_SetLOD,
739     d3d8_texture_cube_GetLOD,
740     d3d8_texture_cube_GetLevelCount,
741     /* IDirect3DCubeTexture8 */
742     d3d8_texture_cube_GetLevelDesc,
743     d3d8_texture_cube_GetCubeMapSurface,
744     d3d8_texture_cube_LockRect,
745     d3d8_texture_cube_UnlockRect,
746     d3d8_texture_cube_AddDirtyRect,
747 };
748 
749 static HRESULT WINAPI d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8 *iface, REFIID riid, void **out)
750 {
751     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
752 
753     if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8)
754             || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
755             || IsEqualGUID(riid, &IID_IDirect3DResource8)
756             || IsEqualGUID(riid, &IID_IUnknown))
757     {
758         IDirect3DVolumeTexture8_AddRef(iface);
759         *out = iface;
760         return S_OK;
761     }
762 
763     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
764 
765     *out = NULL;
766     return E_NOINTERFACE;
767 }
768 
769 static ULONG WINAPI d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8 *iface)
770 {
771     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
772     ULONG ref = InterlockedIncrement(&texture->resource.refcount);
773 
774     TRACE("%p increasing refcount to %u.\n", iface, ref);
775 
776     if (ref == 1)
777     {
778         IDirect3DDevice8_AddRef(texture->parent_device);
779         wined3d_mutex_lock();
780         wined3d_texture_incref(texture->wined3d_texture);
781         wined3d_mutex_unlock();
782     }
783 
784     return ref;
785 }
786 
787 static ULONG WINAPI d3d8_texture_3d_Release(IDirect3DVolumeTexture8 *iface)
788 {
789     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
790     ULONG ref = InterlockedDecrement(&texture->resource.refcount);
791 
792     TRACE("%p decreasing refcount to %u.\n", iface, ref);
793 
794     if (!ref)
795     {
796         IDirect3DDevice8 *parent_device = texture->parent_device;
797 
798         wined3d_mutex_lock();
799         wined3d_texture_decref(texture->wined3d_texture);
800         wined3d_mutex_unlock();
801 
802         /* Release the device last, as it may cause the device to be destroyed. */
803         IDirect3DDevice8_Release(parent_device);
804     }
805     return ref;
806 }
807 
808 static HRESULT WINAPI d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8 *iface, IDirect3DDevice8 **device)
809 {
810     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
811 
812     TRACE("iface %p, device %p.\n", iface, device);
813 
814     *device = texture->parent_device;
815     IDirect3DDevice8_AddRef(*device);
816 
817     TRACE("Returning device %p.\n", *device);
818 
819     return D3D_OK;
820 }
821 
822 static HRESULT WINAPI d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8 *iface,
823         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
824 {
825     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
826     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
827             iface, debugstr_guid(guid), data, data_size, flags);
828 
829     return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
830 }
831 
832 static HRESULT WINAPI d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8 *iface,
833         REFGUID guid, void *data, DWORD *data_size)
834 {
835     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
836     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
837             iface, debugstr_guid(guid), data, data_size);
838 
839     return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size);
840 }
841 
842 static HRESULT WINAPI d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8 *iface, REFGUID guid)
843 {
844     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
845     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
846 
847     return d3d8_resource_free_private_data(&texture->resource, guid);
848 }
849 
850 static DWORD WINAPI d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8 *iface, DWORD priority)
851 {
852     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
853     DWORD ret;
854 
855     TRACE("iface %p, priority %u.\n", iface, priority);
856 
857     wined3d_mutex_lock();
858     ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
859     wined3d_mutex_unlock();
860 
861     return ret;
862 }
863 
864 static DWORD WINAPI d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8 *iface)
865 {
866     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
867     DWORD ret;
868 
869     TRACE("iface %p.\n", iface);
870 
871     wined3d_mutex_lock();
872     ret = wined3d_texture_get_priority(texture->wined3d_texture);
873     wined3d_mutex_unlock();
874 
875     return ret;
876 }
877 
878 static void WINAPI d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8 *iface)
879 {
880     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
881 
882     TRACE("iface %p.\n", iface);
883 
884     wined3d_mutex_lock();
885     wined3d_texture_preload(texture->wined3d_texture);
886     wined3d_mutex_unlock();
887 }
888 
889 static D3DRESOURCETYPE WINAPI d3d8_texture_3d_GetType(IDirect3DVolumeTexture8 *iface)
890 {
891     TRACE("iface %p.\n", iface);
892 
893     return D3DRTYPE_VOLUMETEXTURE;
894 }
895 
896 static DWORD WINAPI d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8 *iface, DWORD lod)
897 {
898     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
899     DWORD ret;
900 
901     TRACE("iface %p, lod %u.\n", iface, lod);
902 
903     wined3d_mutex_lock();
904     ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
905     wined3d_mutex_unlock();
906 
907     return ret;
908 }
909 
910 static DWORD WINAPI d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8 *iface)
911 {
912     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
913     DWORD ret;
914 
915     TRACE("iface %p.\n", iface);
916 
917     wined3d_mutex_lock();
918     ret = wined3d_texture_get_lod(texture->wined3d_texture);
919     wined3d_mutex_unlock();
920 
921     return ret;
922 }
923 
924 static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface)
925 {
926     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
927     DWORD ret;
928 
929     TRACE("iface %p.\n", iface);
930 
931     wined3d_mutex_lock();
932     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
933     wined3d_mutex_unlock();
934 
935     return ret;
936 }
937 
938 static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *iface, UINT level, D3DVOLUME_DESC *desc)
939 {
940     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
941     struct wined3d_resource *sub_resource;
942     HRESULT hr = D3D_OK;
943 
944     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
945 
946     wined3d_mutex_lock();
947     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
948         hr = D3DERR_INVALIDCALL;
949     else
950     {
951         struct wined3d_resource_desc wined3d_desc;
952 
953         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
954         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
955         desc->Type = wined3d_desc.resource_type;
956         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
957         desc->Pool = wined3d_desc.pool;
958         desc->Size = wined3d_desc.size;
959         desc->Width = wined3d_desc.width;
960         desc->Height = wined3d_desc.height;
961         desc->Depth = wined3d_desc.depth;
962     }
963     wined3d_mutex_unlock();
964 
965     return hr;
966 }
967 
968 static HRESULT WINAPI d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8 *iface,
969         UINT level, IDirect3DVolume8 **volume)
970 {
971     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
972     struct wined3d_resource *sub_resource;
973     struct d3d8_volume *volume_impl;
974 
975     TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
976 
977     wined3d_mutex_lock();
978     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
979     {
980         wined3d_mutex_unlock();
981         return D3DERR_INVALIDCALL;
982     }
983 
984     volume_impl = wined3d_resource_get_parent(sub_resource);
985     *volume = &volume_impl->IDirect3DVolume8_iface;
986     IDirect3DVolume8_AddRef(*volume);
987     wined3d_mutex_unlock();
988 
989     return D3D_OK;
990 }
991 
992 static HRESULT WINAPI d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8 *iface,
993         UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
994 {
995     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
996     struct wined3d_resource *sub_resource;
997     struct d3d8_volume *volume_impl;
998     HRESULT hr;
999 
1000     TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1001             iface, level, locked_box, box, flags);
1002 
1003     wined3d_mutex_lock();
1004     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1005         hr = D3DERR_INVALIDCALL;
1006     else
1007     {
1008         volume_impl = wined3d_resource_get_parent(sub_resource);
1009         hr = IDirect3DVolume8_LockBox(&volume_impl->IDirect3DVolume8_iface, locked_box, box, flags);
1010     }
1011     wined3d_mutex_unlock();
1012 
1013     return hr;
1014 }
1015 
1016 static HRESULT WINAPI d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8 *iface, UINT level)
1017 {
1018     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
1019     struct wined3d_resource *sub_resource;
1020     struct d3d8_volume *volume_impl;
1021     HRESULT hr;
1022 
1023     TRACE("iface %p, level %u.\n", iface, level);
1024 
1025     wined3d_mutex_lock();
1026     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1027         hr = D3DERR_INVALIDCALL;
1028     else
1029     {
1030         volume_impl = wined3d_resource_get_parent(sub_resource);
1031         hr = IDirect3DVolume8_UnlockBox(&volume_impl->IDirect3DVolume8_iface);
1032     }
1033     wined3d_mutex_unlock();
1034 
1035     return hr;
1036 }
1037 
1038 static HRESULT WINAPI d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8 *iface, const D3DBOX *dirty_box)
1039 {
1040     struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
1041     HRESULT hr;
1042 
1043     TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1044 
1045     wined3d_mutex_lock();
1046     hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1047     wined3d_mutex_unlock();
1048 
1049     return hr;
1050 }
1051 
1052 static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl =
1053 {
1054     /* IUnknown */
1055     d3d8_texture_3d_QueryInterface,
1056     d3d8_texture_3d_AddRef,
1057     d3d8_texture_3d_Release,
1058     /* IDirect3DResource8 */
1059     d3d8_texture_3d_GetDevice,
1060     d3d8_texture_3d_SetPrivateData,
1061     d3d8_texture_3d_GetPrivateData,
1062     d3d8_texture_3d_FreePrivateData,
1063     d3d8_texture_3d_SetPriority,
1064     d3d8_texture_3d_GetPriority,
1065     d3d8_texture_3d_PreLoad,
1066     d3d8_texture_3d_GetType,
1067     /* IDirect3DBaseTexture8 */
1068     d3d8_texture_3d_SetLOD,
1069     d3d8_texture_3d_GetLOD,
1070     d3d8_texture_3d_GetLevelCount,
1071     /* IDirect3DVolumeTexture8 */
1072     d3d8_texture_3d_GetLevelDesc,
1073     d3d8_texture_3d_GetVolumeLevel,
1074     d3d8_texture_3d_LockBox,
1075     d3d8_texture_3d_UnlockBox,
1076     d3d8_texture_3d_AddDirtyBox
1077 };
1078 
1079 struct d3d8_texture *unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8 *iface)
1080 {
1081     if (!iface)
1082         return NULL;
1083 
1084     /* SetTexture() in particular doesn't do a lot of validation on the pointer
1085      * that gets passed in, and passing an invalid pointer works as long as the
1086      * application doesn't try to actually render anything with it, so we print
1087      * a WARN and return NULL instead of having the usual assert() here.
1088      * One application affected by this is Fishdom 2. */
1089     if (iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl
1090             && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl
1091             && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl)
1092     {
1093         WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface);
1094         return NULL;
1095     }
1096 
1097     return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
1098 }
1099 
1100 static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent)
1101 {
1102     struct d3d8_texture *texture = parent;
1103     d3d8_resource_cleanup(&texture->resource);
1104     HeapFree(GetProcessHeap(), 0, texture);
1105 }
1106 
1107 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops =
1108 {
1109     d3d8_texture_wined3d_object_destroyed,
1110 };
1111 
1112 HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
1113         UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1114 {
1115     struct wined3d_resource_desc desc;
1116     DWORD surface_flags = 0;
1117     HRESULT hr;
1118 
1119     texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl;
1120     d3d8_resource_init(&texture->resource);
1121 
1122     desc.resource_type = WINED3D_RTYPE_TEXTURE;
1123     desc.format = wined3dformat_from_d3dformat(format);
1124     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1125     desc.multisample_quality = 0;
1126     desc.usage = usage & WINED3DUSAGE_MASK;
1127     desc.usage |= WINED3DUSAGE_TEXTURE;
1128     desc.pool = pool;
1129     desc.width = width;
1130     desc.height = height;
1131     desc.depth = 1;
1132     desc.size = 0;
1133 
1134     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1135         surface_flags |= WINED3D_SURFACE_MAPPABLE;
1136 
1137     wined3d_mutex_lock();
1138     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
1139             texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
1140     wined3d_mutex_unlock();
1141     if (FAILED(hr))
1142     {
1143         WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1144         return hr;
1145     }
1146 
1147     texture->parent_device = &device->IDirect3DDevice8_iface;
1148     IDirect3DDevice8_AddRef(texture->parent_device);
1149 
1150     return D3D_OK;
1151 }
1152 
1153 HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
1154         UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1155 {
1156     struct wined3d_resource_desc desc;
1157     DWORD surface_flags = 0;
1158     HRESULT hr;
1159 
1160     texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl;
1161     d3d8_resource_init(&texture->resource);
1162 
1163     desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
1164     desc.format = wined3dformat_from_d3dformat(format);
1165     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1166     desc.multisample_quality = 0;
1167     desc.usage = usage & WINED3DUSAGE_MASK;
1168     desc.usage |= WINED3DUSAGE_TEXTURE;
1169     desc.pool = pool;
1170     desc.width = edge_length;
1171     desc.height = edge_length;
1172     desc.depth = 1;
1173     desc.size = 0;
1174 
1175     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1176         surface_flags |= WINED3D_SURFACE_MAPPABLE;
1177 
1178     wined3d_mutex_lock();
1179     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
1180             texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
1181     wined3d_mutex_unlock();
1182     if (FAILED(hr))
1183     {
1184         WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1185         return hr;
1186     }
1187 
1188     texture->parent_device = &device->IDirect3DDevice8_iface;
1189     IDirect3DDevice8_AddRef(texture->parent_device);
1190 
1191     return D3D_OK;
1192 }
1193 
1194 HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
1195         UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1196 {
1197     struct wined3d_resource_desc desc;
1198     HRESULT hr;
1199 
1200     texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl;
1201     d3d8_resource_init(&texture->resource);
1202 
1203     desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
1204     desc.format = wined3dformat_from_d3dformat(format);
1205     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1206     desc.multisample_quality = 0;
1207     desc.usage = usage & WINED3DUSAGE_MASK;
1208     desc.usage |= WINED3DUSAGE_TEXTURE;
1209     desc.pool = pool;
1210     desc.width = width;
1211     desc.height = height;
1212     desc.depth = depth;
1213     desc.size = 0;
1214 
1215     wined3d_mutex_lock();
1216     hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0,
1217             texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
1218     wined3d_mutex_unlock();
1219     if (FAILED(hr))
1220     {
1221         WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1222         return hr;
1223     }
1224 
1225     texture->parent_device = &device->IDirect3DDevice8_iface;
1226     IDirect3DDevice8_AddRef(texture->parent_device);
1227 
1228     return D3D_OK;
1229 }
1230