shell32: Indentation fix.
[wine] / dlls / d3d9 / texture.c
1 /*
2  * Copyright 2002-2005 Jason Edmeades
3  * Copyright 2002-2005 Raphael Junqueira
4  * Copyright 2005 Oliver Stieber
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22 #include "d3d9_private.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
25
26 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
27 {
28     return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
29 }
30
31 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
32 {
33     return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
34 }
35
36 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
37 {
38     return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
39 }
40
41 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
42 {
43     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
44
45     if (IsEqualGUID(riid, &IID_IDirect3DTexture9)
46             || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
47             || IsEqualGUID(riid, &IID_IDirect3DResource9)
48             || IsEqualGUID(riid, &IID_IUnknown))
49     {
50         IDirect3DTexture9_AddRef(iface);
51         *out = iface;
52         return S_OK;
53     }
54
55     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
56
57     *out = NULL;
58     return E_NOINTERFACE;
59 }
60
61 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
62 {
63     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
64     ULONG ref = InterlockedIncrement(&texture->refcount);
65
66     TRACE("%p increasing refcount to %u.\n", iface, ref);
67
68     if (ref == 1)
69     {
70         IDirect3DDevice9Ex_AddRef(texture->parent_device);
71         wined3d_mutex_lock();
72         wined3d_texture_incref(texture->wined3d_texture);
73         wined3d_mutex_unlock();
74     }
75
76     return ref;
77 }
78
79 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
80 {
81     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
82     ULONG ref = InterlockedDecrement(&texture->refcount);
83
84     TRACE("%p decreasing refcount to %u.\n", iface, ref);
85
86     if (!ref)
87     {
88         IDirect3DDevice9Ex *parent_device = texture->parent_device;
89
90         wined3d_mutex_lock();
91         wined3d_texture_decref(texture->wined3d_texture);
92         wined3d_mutex_unlock();
93
94         /* Release the device last, as it may cause the device to be destroyed. */
95         IDirect3DDevice9Ex_Release(parent_device);
96     }
97     return ref;
98 }
99
100 static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device)
101 {
102     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
103
104     TRACE("iface %p, device %p.\n", iface, device);
105
106     *device = (IDirect3DDevice9 *)texture->parent_device;
107     IDirect3DDevice9_AddRef(*device);
108
109     TRACE("Returning device %p.\n", *device);
110
111     return D3D_OK;
112 }
113
114 static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
115         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
116 {
117     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
118     struct wined3d_resource *resource;
119     HRESULT hr;
120
121     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
122             iface, debugstr_guid(guid), data, data_size, flags);
123
124     wined3d_mutex_lock();
125     resource = wined3d_texture_get_resource(texture->wined3d_texture);
126     hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
127     wined3d_mutex_unlock();
128
129     return hr;
130 }
131
132 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
133         REFGUID guid, void *data, DWORD *data_size)
134 {
135     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
136     struct wined3d_resource *resource;
137     HRESULT hr;
138
139     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
140             iface, debugstr_guid(guid), data, data_size);
141
142     wined3d_mutex_lock();
143     resource = wined3d_texture_get_resource(texture->wined3d_texture);
144     hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
145     wined3d_mutex_unlock();
146
147     return hr;
148 }
149
150 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
151 {
152     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
153     struct wined3d_resource *resource;
154     HRESULT hr;
155
156     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
157
158     wined3d_mutex_lock();
159     resource = wined3d_texture_get_resource(texture->wined3d_texture);
160     hr = wined3d_resource_free_private_data(resource, guid);
161     wined3d_mutex_unlock();
162
163     return hr;
164 }
165
166 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
167 {
168     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
169     DWORD ret;
170
171     TRACE("iface %p, priority %u.\n", iface, priority);
172
173     wined3d_mutex_lock();
174     ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
175     wined3d_mutex_unlock();
176
177     return ret;
178 }
179
180 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
181 {
182     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
183     DWORD ret;
184
185     TRACE("iface %p.\n", iface);
186
187     wined3d_mutex_lock();
188     ret = wined3d_texture_get_priority(texture->wined3d_texture);
189     wined3d_mutex_unlock();
190
191     return ret;
192 }
193
194 static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
195 {
196     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
197
198     TRACE("iface %p.\n", iface);
199
200     wined3d_mutex_lock();
201     wined3d_texture_preload(texture->wined3d_texture);
202     wined3d_mutex_unlock();
203 }
204
205 static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface)
206 {
207     TRACE("iface %p.\n", iface);
208
209     return D3DRTYPE_TEXTURE;
210 }
211
212 static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod)
213 {
214     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
215     DWORD ret;
216
217     TRACE("iface %p, lod %u.\n", iface, lod);
218
219     wined3d_mutex_lock();
220     ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
221     wined3d_mutex_unlock();
222
223     return ret;
224 }
225
226 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
227 {
228     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
229     DWORD ret;
230
231     TRACE("iface %p.\n", iface);
232
233     wined3d_mutex_lock();
234     ret = wined3d_texture_get_lod(texture->wined3d_texture);
235     wined3d_mutex_unlock();
236
237     return ret;
238 }
239
240 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
241 {
242     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
243     DWORD ret;
244
245     TRACE("iface %p.\n", iface);
246
247     wined3d_mutex_lock();
248     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
249     wined3d_mutex_unlock();
250
251     return ret;
252 }
253
254 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
255 {
256     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
257     HRESULT hr;
258
259     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
260
261     wined3d_mutex_lock();
262     hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
263             (enum wined3d_texture_filter_type)filter_type);
264     wined3d_mutex_unlock();
265
266     return hr;
267 }
268
269 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
270 {
271     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
272     D3DTEXTUREFILTERTYPE ret;
273
274     TRACE("iface %p.\n", iface);
275
276     wined3d_mutex_lock();
277     ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
278     wined3d_mutex_unlock();
279
280     return ret;
281 }
282
283 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
284 {
285     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
286
287     TRACE("iface %p.\n", iface);
288
289     wined3d_mutex_lock();
290     wined3d_texture_generate_mipmaps(texture->wined3d_texture);
291     wined3d_mutex_unlock();
292 }
293
294 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
295 {
296     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
297     struct wined3d_resource *sub_resource;
298     HRESULT hr = D3D_OK;
299
300     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
301
302     wined3d_mutex_lock();
303     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
304         hr = D3DERR_INVALIDCALL;
305     else
306     {
307         struct wined3d_resource_desc wined3d_desc;
308
309         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
310         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
311         desc->Type = wined3d_desc.resource_type;
312         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
313         desc->Pool = wined3d_desc.pool;
314         desc->MultiSampleType = wined3d_desc.multisample_type;
315         desc->MultiSampleQuality = wined3d_desc.multisample_quality;
316         desc->Width = wined3d_desc.width;
317         desc->Height = wined3d_desc.height;
318     }
319     wined3d_mutex_unlock();
320
321     return hr;
322 }
323
324 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
325         UINT level, IDirect3DSurface9 **surface)
326 {
327     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
328     struct wined3d_resource *sub_resource;
329     struct d3d9_surface *surface_impl;
330
331     TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
332
333     wined3d_mutex_lock();
334     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
335     {
336         wined3d_mutex_unlock();
337         return D3DERR_INVALIDCALL;
338     }
339
340     surface_impl = wined3d_resource_get_parent(sub_resource);
341     *surface = &surface_impl->IDirect3DSurface9_iface;
342     IDirect3DSurface9_AddRef(*surface);
343     wined3d_mutex_unlock();
344
345     return D3D_OK;
346 }
347
348 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
349         UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
350 {
351     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
352     struct wined3d_resource *sub_resource;
353     struct d3d9_surface *surface_impl;
354     HRESULT hr;
355
356     TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
357             iface, level, locked_rect, rect, flags);
358
359     wined3d_mutex_lock();
360     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
361         hr = D3DERR_INVALIDCALL;
362     else
363     {
364         surface_impl = wined3d_resource_get_parent(sub_resource);
365         hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
366     }
367     wined3d_mutex_unlock();
368
369     return hr;
370 }
371
372 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
373 {
374     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
375     struct wined3d_resource *sub_resource;
376     struct d3d9_surface *surface_impl;
377     HRESULT hr;
378
379     TRACE("iface %p, level %u.\n", iface, level);
380
381     wined3d_mutex_lock();
382     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
383         hr = D3DERR_INVALIDCALL;
384     else
385     {
386         surface_impl = wined3d_resource_get_parent(sub_resource);
387         hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
388     }
389     wined3d_mutex_unlock();
390
391     return hr;
392 }
393
394 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
395 {
396     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
397     HRESULT hr;
398
399     TRACE("iface %p, dirty_rect %s.\n",
400             iface, wine_dbgstr_rect(dirty_rect));
401
402     wined3d_mutex_lock();
403     if (!dirty_rect)
404         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
405     else
406     {
407         struct wined3d_box dirty_region;
408
409         dirty_region.left = dirty_rect->left;
410         dirty_region.top = dirty_rect->top;
411         dirty_region.right = dirty_rect->right;
412         dirty_region.bottom = dirty_rect->bottom;
413         dirty_region.front = 0;
414         dirty_region.back = 1;
415         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
416     }
417     wined3d_mutex_unlock();
418
419     return hr;
420 }
421
422 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
423 {
424     /* IUnknown */
425     d3d9_texture_2d_QueryInterface,
426     d3d9_texture_2d_AddRef,
427     d3d9_texture_2d_Release,
428      /* IDirect3DResource9 */
429     d3d9_texture_2d_GetDevice,
430     d3d9_texture_2d_SetPrivateData,
431     d3d9_texture_2d_GetPrivateData,
432     d3d9_texture_2d_FreePrivateData,
433     d3d9_texture_2d_SetPriority,
434     d3d9_texture_2d_GetPriority,
435     d3d9_texture_2d_PreLoad,
436     d3d9_texture_2d_GetType,
437     /* IDirect3dBaseTexture9 */
438     d3d9_texture_2d_SetLOD,
439     d3d9_texture_2d_GetLOD,
440     d3d9_texture_2d_GetLevelCount,
441     d3d9_texture_2d_SetAutoGenFilterType,
442     d3d9_texture_2d_GetAutoGenFilterType,
443     d3d9_texture_2d_GenerateMipSubLevels,
444     /* IDirect3DTexture9 */
445     d3d9_texture_2d_GetLevelDesc,
446     d3d9_texture_2d_GetSurfaceLevel,
447     d3d9_texture_2d_LockRect,
448     d3d9_texture_2d_UnlockRect,
449     d3d9_texture_2d_AddDirtyRect,
450 };
451
452 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
453 {
454     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
455
456     if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
457             || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
458             || IsEqualGUID(riid, &IID_IDirect3DResource9)
459             || IsEqualGUID(riid, &IID_IUnknown))
460     {
461         IDirect3DCubeTexture9_AddRef(iface);
462         *out = iface;
463         return S_OK;
464     }
465
466     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
467
468     *out = NULL;
469     return E_NOINTERFACE;
470 }
471
472 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
473 {
474     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
475     ULONG ref = InterlockedIncrement(&texture->refcount);
476
477     TRACE("%p increasing refcount to %u.\n", iface, ref);
478
479     if (ref == 1)
480     {
481         IDirect3DDevice9Ex_AddRef(texture->parent_device);
482         wined3d_mutex_lock();
483         wined3d_texture_incref(texture->wined3d_texture);
484         wined3d_mutex_unlock();
485     }
486
487     return ref;
488 }
489
490 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
491 {
492     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
493     ULONG ref = InterlockedDecrement(&texture->refcount);
494
495     TRACE("%p decreasing refcount to %u.\n", iface, ref);
496
497     if (!ref)
498     {
499         IDirect3DDevice9Ex *parent_device = texture->parent_device;
500
501         TRACE("Releasing child %p.\n", texture->wined3d_texture);
502
503         wined3d_mutex_lock();
504         wined3d_texture_decref(texture->wined3d_texture);
505         wined3d_mutex_unlock();
506
507         /* Release the device last, as it may cause the device to be destroyed. */
508         IDirect3DDevice9Ex_Release(parent_device);
509     }
510     return ref;
511 }
512
513 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
514 {
515     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
516
517     TRACE("iface %p, device %p.\n", iface, device);
518
519     *device = (IDirect3DDevice9 *)texture->parent_device;
520     IDirect3DDevice9_AddRef(*device);
521
522     TRACE("Returning device %p.\n", *device);
523
524     return D3D_OK;
525 }
526
527 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
528         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
529 {
530     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
531     struct wined3d_resource *resource;
532     HRESULT hr;
533
534     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
535             iface, debugstr_guid(guid), data, data_size, flags);
536
537     wined3d_mutex_lock();
538     resource = wined3d_texture_get_resource(texture->wined3d_texture);
539     hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
540     wined3d_mutex_unlock();
541
542     return hr;
543 }
544
545 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
546         REFGUID guid, void *data, DWORD *data_size)
547 {
548     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
549     struct wined3d_resource *resource;
550     HRESULT hr;
551
552     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
553             iface, debugstr_guid(guid), data, data_size);
554
555     wined3d_mutex_lock();
556     resource = wined3d_texture_get_resource(texture->wined3d_texture);
557     hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
558     wined3d_mutex_unlock();
559
560     return hr;
561 }
562
563 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
564 {
565     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
566     struct wined3d_resource *resource;
567     HRESULT hr;
568
569     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
570
571     wined3d_mutex_lock();
572     resource = wined3d_texture_get_resource(texture->wined3d_texture);
573     hr = wined3d_resource_free_private_data(resource, guid);
574     wined3d_mutex_unlock();
575
576     return hr;
577 }
578
579 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
580 {
581     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
582     DWORD ret;
583
584     TRACE("iface %p, priority %u.\n", iface, priority);
585
586     wined3d_mutex_lock();
587     ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
588     wined3d_mutex_unlock();
589
590     return ret;
591 }
592
593 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
594 {
595     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
596     DWORD ret;
597
598     TRACE("iface %p.\n", iface);
599
600     wined3d_mutex_lock();
601     ret = wined3d_texture_get_priority(texture->wined3d_texture);
602     wined3d_mutex_unlock();
603
604     return ret;
605 }
606
607 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
608 {
609     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
610
611     TRACE("iface %p.\n", iface);
612
613     wined3d_mutex_lock();
614     wined3d_texture_preload(texture->wined3d_texture);
615     wined3d_mutex_unlock();
616 }
617
618 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
619 {
620     TRACE("iface %p.\n", iface);
621
622     return D3DRTYPE_CUBETEXTURE;
623 }
624
625 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
626 {
627     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
628     DWORD ret;
629
630     TRACE("iface %p, lod %u.\n", iface, lod);
631
632     wined3d_mutex_lock();
633     ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
634     wined3d_mutex_unlock();
635
636     return ret;
637 }
638
639 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
640 {
641     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
642     DWORD ret;
643
644     TRACE("iface %p.\n", iface);
645
646     wined3d_mutex_lock();
647     ret = wined3d_texture_get_lod(texture->wined3d_texture);
648     wined3d_mutex_unlock();
649
650     return ret;
651 }
652
653 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
654 {
655     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
656     DWORD ret;
657
658     TRACE("iface %p.\n", iface);
659
660     wined3d_mutex_lock();
661     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
662     wined3d_mutex_unlock();
663
664     return ret;
665 }
666
667 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
668         D3DTEXTUREFILTERTYPE filter_type)
669 {
670     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
671     HRESULT hr;
672
673     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
674
675     wined3d_mutex_lock();
676     hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
677             (enum wined3d_texture_filter_type)filter_type);
678     wined3d_mutex_unlock();
679
680     return hr;
681 }
682
683 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
684 {
685     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
686     D3DTEXTUREFILTERTYPE ret;
687
688     TRACE("iface %p.\n", iface);
689
690     wined3d_mutex_lock();
691     ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
692     wined3d_mutex_unlock();
693
694     return ret;
695 }
696
697 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
698 {
699     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
700
701     TRACE("iface %p.\n", iface);
702
703     wined3d_mutex_lock();
704     wined3d_texture_generate_mipmaps(texture->wined3d_texture);
705     wined3d_mutex_unlock();
706 }
707
708 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
709 {
710     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
711     struct wined3d_resource *sub_resource;
712     HRESULT hr = D3D_OK;
713     DWORD level_count;
714
715     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
716
717     wined3d_mutex_lock();
718     level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
719     if (level >= level_count)
720     {
721         wined3d_mutex_unlock();
722         return D3DERR_INVALIDCALL;
723     }
724
725     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
726         hr = D3DERR_INVALIDCALL;
727     else
728     {
729         struct wined3d_resource_desc wined3d_desc;
730
731         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
732         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
733         desc->Type = wined3d_desc.resource_type;
734         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
735         desc->Pool = wined3d_desc.pool;
736         desc->MultiSampleType = wined3d_desc.multisample_type;
737         desc->MultiSampleQuality = wined3d_desc.multisample_quality;
738         desc->Width = wined3d_desc.width;
739         desc->Height = wined3d_desc.height;
740     }
741     wined3d_mutex_unlock();
742
743     return hr;
744 }
745
746 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
747         D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
748 {
749     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
750     struct wined3d_resource *sub_resource;
751     struct d3d9_surface *surface_impl;
752     UINT sub_resource_idx;
753     DWORD level_count;
754
755     TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
756
757     wined3d_mutex_lock();
758     level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
759     if (level >= level_count)
760     {
761         wined3d_mutex_unlock();
762         return D3DERR_INVALIDCALL;
763     }
764
765     sub_resource_idx = level_count * face + level;
766     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
767     {
768         wined3d_mutex_unlock();
769         return D3DERR_INVALIDCALL;
770     }
771
772     surface_impl = wined3d_resource_get_parent(sub_resource);
773     *surface = &surface_impl->IDirect3DSurface9_iface;
774     IDirect3DSurface9_AddRef(*surface);
775     wined3d_mutex_unlock();
776
777     return D3D_OK;
778 }
779
780 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
781         D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
782         DWORD flags)
783 {
784     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
785     struct wined3d_resource *sub_resource;
786     struct d3d9_surface *surface_impl;
787     UINT sub_resource_idx;
788     HRESULT hr;
789
790     TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
791             iface, face, level, locked_rect, rect, flags);
792
793     wined3d_mutex_lock();
794     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
795     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
796         hr = D3DERR_INVALIDCALL;
797     else
798     {
799         surface_impl = wined3d_resource_get_parent(sub_resource);
800         hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
801     }
802     wined3d_mutex_unlock();
803
804     return hr;
805 }
806
807 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
808         D3DCUBEMAP_FACES face, UINT level)
809 {
810     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
811     struct wined3d_resource *sub_resource;
812     struct d3d9_surface *surface_impl;
813     UINT sub_resource_idx;
814     HRESULT hr;
815
816     TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
817
818     wined3d_mutex_lock();
819     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
820     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
821         hr = D3DERR_INVALIDCALL;
822     else
823     {
824         surface_impl = wined3d_resource_get_parent(sub_resource);
825         hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
826     }
827     wined3d_mutex_unlock();
828
829     return hr;
830 }
831
832 static HRESULT  WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
833         D3DCUBEMAP_FACES face, const RECT *dirty_rect)
834 {
835     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
836     HRESULT hr;
837
838     TRACE("iface %p, face %#x, dirty_rect %s.\n",
839             iface, face, wine_dbgstr_rect(dirty_rect));
840
841     wined3d_mutex_lock();
842     if (!dirty_rect)
843         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
844     else
845     {
846         struct wined3d_box dirty_region;
847
848         dirty_region.left = dirty_rect->left;
849         dirty_region.top = dirty_rect->top;
850         dirty_region.right = dirty_rect->right;
851         dirty_region.bottom = dirty_rect->bottom;
852         dirty_region.front = 0;
853         dirty_region.back = 1;
854         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
855     }
856     wined3d_mutex_unlock();
857
858     return hr;
859 }
860
861 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
862 {
863     /* IUnknown */
864     d3d9_texture_cube_QueryInterface,
865     d3d9_texture_cube_AddRef,
866     d3d9_texture_cube_Release,
867     /* IDirect3DResource9 */
868     d3d9_texture_cube_GetDevice,
869     d3d9_texture_cube_SetPrivateData,
870     d3d9_texture_cube_GetPrivateData,
871     d3d9_texture_cube_FreePrivateData,
872     d3d9_texture_cube_SetPriority,
873     d3d9_texture_cube_GetPriority,
874     d3d9_texture_cube_PreLoad,
875     d3d9_texture_cube_GetType,
876     /* IDirect3DBaseTexture9 */
877     d3d9_texture_cube_SetLOD,
878     d3d9_texture_cube_GetLOD,
879     d3d9_texture_cube_GetLevelCount,
880     d3d9_texture_cube_SetAutoGenFilterType,
881     d3d9_texture_cube_GetAutoGenFilterType,
882     d3d9_texture_cube_GenerateMipSubLevels,
883     /* IDirect3DCubeTexture9 */
884     d3d9_texture_cube_GetLevelDesc,
885     d3d9_texture_cube_GetCubeMapSurface,
886     d3d9_texture_cube_LockRect,
887     d3d9_texture_cube_UnlockRect,
888     d3d9_texture_cube_AddDirtyRect,
889 };
890
891 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
892 {
893     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
894
895     if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
896             || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
897             || IsEqualGUID(riid, &IID_IDirect3DResource9)
898             || IsEqualGUID(riid, &IID_IUnknown))
899     {
900         IDirect3DVolumeTexture9_AddRef(iface);
901         *out = iface;
902         return S_OK;
903     }
904
905     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
906
907     *out = NULL;
908     return E_NOINTERFACE;
909 }
910
911 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
912 {
913     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
914     ULONG ref = InterlockedIncrement(&texture->refcount);
915
916     TRACE("%p increasing refcount to %u.\n", iface, ref);
917
918     if (ref == 1)
919     {
920         IDirect3DDevice9Ex_AddRef(texture->parent_device);
921         wined3d_mutex_lock();
922         wined3d_texture_incref(texture->wined3d_texture);
923         wined3d_mutex_unlock();
924     }
925
926     return ref;
927 }
928
929 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
930 {
931     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
932     ULONG ref = InterlockedDecrement(&texture->refcount);
933
934     TRACE("%p decreasing refcount to %u.\n", iface, ref);
935
936     if (!ref)
937     {
938         IDirect3DDevice9Ex *parent_device = texture->parent_device;
939
940         wined3d_mutex_lock();
941         wined3d_texture_decref(texture->wined3d_texture);
942         wined3d_mutex_unlock();
943
944         /* Release the device last, as it may cause the device to be destroyed. */
945         IDirect3DDevice9Ex_Release(parent_device);
946     }
947     return ref;
948 }
949
950 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
951 {
952     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
953
954     TRACE("iface %p, device %p.\n", iface, device);
955
956     *device = (IDirect3DDevice9 *)texture->parent_device;
957     IDirect3DDevice9_AddRef(*device);
958
959     TRACE("Returning device %p.\n", *device);
960
961     return D3D_OK;
962 }
963
964 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
965         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
966 {
967     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
968     struct wined3d_resource *resource;
969     HRESULT hr;
970
971     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
972             iface, debugstr_guid(guid), data, data_size, flags);
973
974     wined3d_mutex_lock();
975     resource = wined3d_texture_get_resource(texture->wined3d_texture);
976     hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
977     wined3d_mutex_unlock();
978
979     return hr;
980 }
981
982 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
983         REFGUID guid, void *data, DWORD *data_size)
984 {
985     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
986     struct wined3d_resource *resource;
987     HRESULT hr;
988
989     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
990             iface, debugstr_guid(guid), data, data_size);
991
992     wined3d_mutex_lock();
993     resource = wined3d_texture_get_resource(texture->wined3d_texture);
994     hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
995     wined3d_mutex_unlock();
996
997     return hr;
998 }
999
1000 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
1001 {
1002     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1003     struct wined3d_resource *resource;
1004     HRESULT hr;
1005
1006     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1007
1008     wined3d_mutex_lock();
1009     resource = wined3d_texture_get_resource(texture->wined3d_texture);
1010     hr = wined3d_resource_free_private_data(resource, guid);
1011     wined3d_mutex_unlock();
1012
1013     return hr;
1014 }
1015
1016 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
1017 {
1018     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1019     DWORD ret;
1020
1021     TRACE("iface %p, priority %u.\n", iface, priority);
1022
1023     wined3d_mutex_lock();
1024     ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
1025     wined3d_mutex_unlock();
1026
1027     return ret;
1028 }
1029
1030 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
1031 {
1032     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1033     DWORD ret;
1034
1035     TRACE("iface %p.\n", iface);
1036
1037     wined3d_mutex_lock();
1038     ret = wined3d_texture_get_priority(texture->wined3d_texture);
1039     wined3d_mutex_unlock();
1040
1041     return ret;
1042 }
1043
1044 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
1045 {
1046     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1047
1048     TRACE("iface %p.\n", iface);
1049
1050     wined3d_mutex_lock();
1051     wined3d_texture_preload(texture->wined3d_texture);
1052     wined3d_mutex_unlock();
1053 }
1054
1055 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
1056 {
1057     TRACE("iface %p.\n", iface);
1058
1059     return D3DRTYPE_VOLUMETEXTURE;
1060 }
1061
1062 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
1063 {
1064     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1065     DWORD ret;
1066
1067     TRACE("iface %p, lod %u.\n", iface, lod);
1068
1069     wined3d_mutex_lock();
1070     ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
1071     wined3d_mutex_unlock();
1072
1073     return ret;
1074 }
1075
1076 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
1077 {
1078     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1079     DWORD ret;
1080
1081     TRACE("iface %p.\n", iface);
1082
1083     wined3d_mutex_lock();
1084     ret = wined3d_texture_get_lod(texture->wined3d_texture);
1085     wined3d_mutex_unlock();
1086
1087     return ret;
1088 }
1089
1090 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
1091 {
1092     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1093     DWORD ret;
1094
1095     TRACE("iface %p.\n", iface);
1096
1097     wined3d_mutex_lock();
1098     ret = wined3d_texture_get_level_count(texture->wined3d_texture);
1099     wined3d_mutex_unlock();
1100
1101     return ret;
1102 }
1103
1104 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
1105         D3DTEXTUREFILTERTYPE filter_type)
1106 {
1107     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1108     HRESULT hr;
1109
1110     TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
1111
1112     wined3d_mutex_lock();
1113     hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
1114             (enum wined3d_texture_filter_type)filter_type);
1115     wined3d_mutex_unlock();
1116
1117     return hr;
1118 }
1119
1120 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
1121 {
1122     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1123     D3DTEXTUREFILTERTYPE filter_type;
1124
1125     TRACE("iface %p.\n", iface);
1126
1127     wined3d_mutex_lock();
1128     filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
1129     wined3d_mutex_unlock();
1130
1131     return filter_type;
1132 }
1133
1134 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
1135 {
1136     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1137
1138     TRACE("iface %p.\n", iface);
1139
1140     wined3d_mutex_lock();
1141     wined3d_texture_generate_mipmaps(texture->wined3d_texture);
1142     wined3d_mutex_unlock();
1143 }
1144
1145 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
1146 {
1147     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1148     struct wined3d_resource *sub_resource;
1149     HRESULT hr = D3D_OK;
1150
1151     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
1152
1153     wined3d_mutex_lock();
1154     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1155         hr = D3DERR_INVALIDCALL;
1156     else
1157     {
1158         struct wined3d_resource_desc wined3d_desc;
1159
1160         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
1161         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
1162         desc->Type = wined3d_desc.resource_type;
1163         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
1164         desc->Pool = wined3d_desc.pool;
1165         desc->Width = wined3d_desc.width;
1166         desc->Height = wined3d_desc.height;
1167         desc->Depth = wined3d_desc.depth;
1168     }
1169     wined3d_mutex_unlock();
1170
1171     return hr;
1172 }
1173
1174 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
1175         UINT level, IDirect3DVolume9 **volume)
1176 {
1177     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1178     struct wined3d_resource *sub_resource;
1179     struct d3d9_volume *volume_impl;
1180
1181     TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1182
1183     wined3d_mutex_lock();
1184     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1185     {
1186         wined3d_mutex_unlock();
1187         return D3DERR_INVALIDCALL;
1188     }
1189
1190     volume_impl = wined3d_resource_get_parent(sub_resource);
1191     *volume = &volume_impl->IDirect3DVolume9_iface;
1192     IDirect3DVolume9_AddRef(*volume);
1193     wined3d_mutex_unlock();
1194
1195     return D3D_OK;
1196 }
1197
1198 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
1199         UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1200 {
1201     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1202     struct wined3d_resource *sub_resource;
1203     struct d3d9_volume *volume_impl;
1204     HRESULT hr;
1205
1206     TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1207             iface, level, locked_box, box, flags);
1208
1209     wined3d_mutex_lock();
1210     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1211         hr = D3DERR_INVALIDCALL;
1212     else
1213     {
1214         volume_impl = wined3d_resource_get_parent(sub_resource);
1215         hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
1216     }
1217     wined3d_mutex_unlock();
1218
1219     return hr;
1220 }
1221
1222 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
1223 {
1224     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1225     struct wined3d_resource *sub_resource;
1226     struct d3d9_volume *volume_impl;
1227     HRESULT hr;
1228
1229     TRACE("iface %p, level %u.\n", iface, level);
1230
1231     wined3d_mutex_lock();
1232     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1233         hr = D3DERR_INVALIDCALL;
1234     else
1235     {
1236         volume_impl = wined3d_resource_get_parent(sub_resource);
1237         hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
1238     }
1239     wined3d_mutex_unlock();
1240
1241     return hr;
1242 }
1243
1244 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
1245 {
1246     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1247     HRESULT hr;
1248
1249     TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1250
1251     wined3d_mutex_lock();
1252     hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1253     wined3d_mutex_unlock();
1254
1255     return hr;
1256 }
1257
1258
1259 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
1260 {
1261     /* IUnknown */
1262     d3d9_texture_3d_QueryInterface,
1263     d3d9_texture_3d_AddRef,
1264     d3d9_texture_3d_Release,
1265     /* IDirect3DResource9 */
1266     d3d9_texture_3d_GetDevice,
1267     d3d9_texture_3d_SetPrivateData,
1268     d3d9_texture_3d_GetPrivateData,
1269     d3d9_texture_3d_FreePrivateData,
1270     d3d9_texture_3d_SetPriority,
1271     d3d9_texture_3d_GetPriority,
1272     d3d9_texture_3d_PreLoad,
1273     d3d9_texture_3d_GetType,
1274     /* IDirect3DBaseTexture9 */
1275     d3d9_texture_3d_SetLOD,
1276     d3d9_texture_3d_GetLOD,
1277     d3d9_texture_3d_GetLevelCount,
1278     d3d9_texture_3d_SetAutoGenFilterType,
1279     d3d9_texture_3d_GetAutoGenFilterType,
1280     d3d9_texture_3d_GenerateMipSubLevels,
1281     /* IDirect3DVolumeTexture9 */
1282     d3d9_texture_3d_GetLevelDesc,
1283     d3d9_texture_3d_GetVolumeLevel,
1284     d3d9_texture_3d_LockBox,
1285     d3d9_texture_3d_UnlockBox,
1286     d3d9_texture_3d_AddDirtyBox,
1287 };
1288
1289 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
1290 {
1291     if (!iface)
1292         return NULL;
1293     assert(iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
1294             || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
1295             || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl);
1296     return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
1297 }
1298
1299 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
1300 {
1301     HeapFree(GetProcessHeap(), 0, parent);
1302 }
1303
1304 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
1305 {
1306     d3d9_texture_wined3d_object_destroyed,
1307 };
1308
1309 HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1310         UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1311 {
1312     HRESULT hr;
1313
1314     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
1315     texture->refcount = 1;
1316
1317     wined3d_mutex_lock();
1318     hr = wined3d_texture_create_2d(device->wined3d_device, width, height, levels,
1319             usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool,
1320             texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1321     wined3d_mutex_unlock();
1322     if (FAILED(hr))
1323     {
1324         WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1325         return hr;
1326     }
1327
1328     texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1329     IDirect3DDevice9Ex_AddRef(texture->parent_device);
1330
1331     return D3D_OK;
1332 }
1333
1334 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1335         UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1336 {
1337     HRESULT hr;
1338
1339     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
1340     texture->refcount = 1;
1341
1342     wined3d_mutex_lock();
1343     hr = wined3d_texture_create_cube(device->wined3d_device, edge_length,
1344             levels, usage, wined3dformat_from_d3dformat(format), pool, texture,
1345             &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1346     wined3d_mutex_unlock();
1347     if (FAILED(hr))
1348     {
1349         WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1350         return hr;
1351     }
1352
1353     texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1354     IDirect3DDevice9Ex_AddRef(texture->parent_device);
1355
1356     return D3D_OK;
1357 }
1358
1359 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1360         UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1361 {
1362     HRESULT hr;
1363
1364     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
1365     texture->refcount = 1;
1366
1367     wined3d_mutex_lock();
1368     hr = wined3d_texture_create_3d(device->wined3d_device, width, height, depth, levels,
1369             usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture,
1370             &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1371     wined3d_mutex_unlock();
1372     if (FAILED(hr))
1373     {
1374         WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1375         return hr;
1376     }
1377
1378     texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1379     IDirect3DDevice9Ex_AddRef(texture->parent_device);
1380
1381     return D3D_OK;
1382 }