comdlg32: Add IServiceProvider implementation to the Item Dialog.
[wine] / dlls / d3d9 / volumetexture.c
1 /*
2  * IDirect3DVolumeTexture9 implementation
3  *
4  * Copyright 2002-2005 Jason Edmeades
5  *                     Raphael Junqueira
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include "d3d9_private.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
26
27 /* IDirect3DVolumeTexture9 IUnknown parts follow: */
28 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_QueryInterface(LPDIRECT3DVOLUMETEXTURE9 iface, REFIID riid, LPVOID* ppobj) {
29     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
30
31     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
32
33     if (IsEqualGUID(riid, &IID_IUnknown)
34     || IsEqualGUID(riid, &IID_IDirect3DResource9)
35     || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
36     || IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)) {
37         IDirect3DVolumeTexture9_AddRef(iface);
38         *ppobj = This;
39         return S_OK;
40     }
41
42     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
43     *ppobj = NULL;
44     return E_NOINTERFACE;
45 }
46
47 static ULONG WINAPI IDirect3DVolumeTexture9Impl_AddRef(LPDIRECT3DVOLUMETEXTURE9 iface) {
48     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
49     ULONG ref = InterlockedIncrement(&This->ref);
50
51     TRACE("%p increasing refcount to %u.\n", iface, ref);
52
53     if (ref == 1)
54     {
55         IDirect3DDevice9Ex_AddRef(This->parentDevice);
56         wined3d_mutex_lock();
57         wined3d_texture_incref(This->wined3d_texture);
58         wined3d_mutex_unlock();
59     }
60
61     return ref;
62 }
63
64 static ULONG WINAPI IDirect3DVolumeTexture9Impl_Release(LPDIRECT3DVOLUMETEXTURE9 iface) {
65     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
66     ULONG ref = InterlockedDecrement(&This->ref);
67
68     TRACE("%p decreasing refcount to %u.\n", iface, ref);
69
70     if (ref == 0) {
71         IDirect3DDevice9Ex *parentDevice = This->parentDevice;
72
73         wined3d_mutex_lock();
74         wined3d_texture_decref(This->wined3d_texture);
75         wined3d_mutex_unlock();
76
77         /* Release the device last, as it may cause the device to be destroyed. */
78         IDirect3DDevice9Ex_Release(parentDevice);
79     }
80     return ref;
81 }
82
83 /* IDirect3DVolumeTexture9 IDirect3DResource9 Interface follow: */
84 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
85 {
86     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
87
88     TRACE("iface %p, device %p.\n", iface, device);
89
90     *device = (IDirect3DDevice9 *)This->parentDevice;
91     IDirect3DDevice9_AddRef(*device);
92
93     TRACE("Returning device %p.\n", *device);
94
95     return D3D_OK;
96 }
97
98 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetPrivateData(LPDIRECT3DVOLUMETEXTURE9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
99     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
100     HRESULT hr;
101
102     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
103             iface, debugstr_guid(refguid), pData, SizeOfData, Flags);
104
105     wined3d_mutex_lock();
106     hr = wined3d_texture_set_private_data(This->wined3d_texture, refguid, pData, SizeOfData, Flags);
107     wined3d_mutex_unlock();
108
109     return hr;
110 }
111
112 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetPrivateData(LPDIRECT3DVOLUMETEXTURE9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
113     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
114     HRESULT hr;
115
116     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
117             iface, debugstr_guid(refguid), pData, pSizeOfData);
118
119     wined3d_mutex_lock();
120     hr = wined3d_texture_get_private_data(This->wined3d_texture, refguid, pData, pSizeOfData);
121     wined3d_mutex_unlock();
122
123     return hr;
124 }
125
126 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_FreePrivateData(LPDIRECT3DVOLUMETEXTURE9 iface, REFGUID refguid) {
127     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
128     HRESULT hr;
129
130     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(refguid));
131
132     wined3d_mutex_lock();
133     hr = wined3d_texture_free_private_data(This->wined3d_texture, refguid);
134     wined3d_mutex_unlock();
135
136     return hr;
137 }
138
139 static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetPriority(LPDIRECT3DVOLUMETEXTURE9 iface, DWORD PriorityNew) {
140     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
141     DWORD priority;
142
143     TRACE("iface %p, priority %u.\n", iface, PriorityNew);
144
145     wined3d_mutex_lock();
146     priority = wined3d_texture_set_priority(This->wined3d_texture, PriorityNew);
147     wined3d_mutex_unlock();
148
149     return priority;
150 }
151
152 static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetPriority(LPDIRECT3DVOLUMETEXTURE9 iface) {
153     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
154     DWORD priority;
155
156     TRACE("iface %p.\n", iface);
157
158     wined3d_mutex_lock();
159     priority = wined3d_texture_get_priority(This->wined3d_texture);
160     wined3d_mutex_unlock();
161
162     return priority;
163 }
164
165 static void WINAPI IDirect3DVolumeTexture9Impl_PreLoad(LPDIRECT3DVOLUMETEXTURE9 iface) {
166     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
167
168     TRACE("iface %p.\n", iface);
169
170     wined3d_mutex_lock();
171     wined3d_texture_preload(This->wined3d_texture);
172     wined3d_mutex_unlock();
173 }
174
175 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLUMETEXTURE9 iface) {
176     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
177     D3DRESOURCETYPE type;
178
179     TRACE("iface %p.\n", iface);
180
181     wined3d_mutex_lock();
182     type = wined3d_texture_get_type(This->wined3d_texture);
183     wined3d_mutex_unlock();
184
185     return type;
186 }
187
188 /* IDirect3DVolumeTexture9 IDirect3DBaseTexture9 Interface follow: */
189 static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE9 iface, DWORD LODNew) {
190     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
191     DWORD lod;
192
193     TRACE("iface %p, lod %u.\n", iface, LODNew);
194
195     wined3d_mutex_lock();
196     lod = wined3d_texture_set_lod(This->wined3d_texture, LODNew);
197     wined3d_mutex_unlock();
198
199     return lod;
200 }
201
202 static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLOD(LPDIRECT3DVOLUMETEXTURE9 iface) {
203     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
204     DWORD lod;
205
206     TRACE("iface %p.\n", iface);
207
208     wined3d_mutex_lock();
209     lod = wined3d_texture_get_lod(This->wined3d_texture);
210     wined3d_mutex_unlock();
211
212     return lod;
213 }
214
215 static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLevelCount(LPDIRECT3DVOLUMETEXTURE9 iface) {
216     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
217     DWORD level_count;
218
219     TRACE("iface %p.\n", iface);
220
221     wined3d_mutex_lock();
222     level_count = wined3d_texture_get_level_count(This->wined3d_texture);
223     wined3d_mutex_unlock();
224
225     return level_count;
226 }
227
228 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetAutoGenFilterType(LPDIRECT3DVOLUMETEXTURE9 iface, D3DTEXTUREFILTERTYPE FilterType) {
229     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
230     HRESULT hr;
231
232     TRACE("iface %p, filter_type %#x.\n", iface, FilterType);
233
234     wined3d_mutex_lock();
235     hr = wined3d_texture_set_autogen_filter_type(This->wined3d_texture, (WINED3DTEXTUREFILTERTYPE)FilterType);
236     wined3d_mutex_unlock();
237
238     return hr;
239 }
240
241 static D3DTEXTUREFILTERTYPE WINAPI IDirect3DVolumeTexture9Impl_GetAutoGenFilterType(LPDIRECT3DVOLUMETEXTURE9 iface) {
242     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
243     D3DTEXTUREFILTERTYPE filter_type;
244
245     TRACE("iface %p.\n", iface);
246
247     wined3d_mutex_lock();
248     filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(This->wined3d_texture);
249     wined3d_mutex_unlock();
250
251     return filter_type;
252 }
253
254 static void WINAPI IDirect3DVolumeTexture9Impl_GenerateMipSubLevels(LPDIRECT3DVOLUMETEXTURE9 iface) {
255     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
256
257     TRACE("iface %p.\n", iface);
258
259     wined3d_mutex_lock();
260     wined3d_texture_generate_mipmaps(This->wined3d_texture);
261     wined3d_mutex_unlock();
262 }
263
264 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetLevelDesc(IDirect3DVolumeTexture9 *iface,
265         UINT level, D3DVOLUME_DESC *desc)
266 {
267     IDirect3DVolumeTexture9Impl *texture = (IDirect3DVolumeTexture9Impl *)iface;
268     struct wined3d_resource *sub_resource;
269     HRESULT hr = D3D_OK;
270
271     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
272
273     wined3d_mutex_lock();
274     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
275         hr = D3DERR_INVALIDCALL;
276     else
277     {
278         struct wined3d_resource_desc wined3d_desc;
279
280         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
281         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
282         desc->Type = wined3d_desc.resource_type;
283         desc->Usage = wined3d_desc.usage;
284         desc->Pool = wined3d_desc.pool;
285         desc->Width = wined3d_desc.width;
286         desc->Height = wined3d_desc.height;
287         desc->Depth = wined3d_desc.depth;
288     }
289     wined3d_mutex_unlock();
290
291     return hr;
292 }
293
294 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
295         UINT level, IDirect3DVolume9 **volume)
296 {
297     IDirect3DVolumeTexture9Impl *texture = (IDirect3DVolumeTexture9Impl *)iface;
298     struct wined3d_resource *sub_resource;
299
300     TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
301
302     wined3d_mutex_lock();
303     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
304     {
305         wined3d_mutex_unlock();
306         return D3DERR_INVALIDCALL;
307     }
308
309     *volume = wined3d_resource_get_parent(sub_resource);
310     IDirect3DVolume9_AddRef(*volume);
311     wined3d_mutex_unlock();
312
313     return D3D_OK;
314 }
315
316 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_LockBox(IDirect3DVolumeTexture9 *iface,
317         UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
318 {
319     IDirect3DVolumeTexture9Impl *texture = (IDirect3DVolumeTexture9Impl *)iface;
320     struct wined3d_resource *sub_resource;
321     HRESULT hr;
322
323     TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
324             iface, level, locked_box, box, flags);
325
326     wined3d_mutex_lock();
327     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
328         hr = D3DERR_INVALIDCALL;
329     else
330         hr = IDirect3DVolume9_LockBox((IDirect3DVolume9 *)wined3d_resource_get_parent(sub_resource),
331                 locked_box, box, flags);
332     wined3d_mutex_unlock();
333
334     return hr;
335 }
336
337 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
338 {
339     IDirect3DVolumeTexture9Impl *texture = (IDirect3DVolumeTexture9Impl *)iface;
340     struct wined3d_resource *sub_resource;
341     HRESULT hr;
342
343     TRACE("iface %p, level %u.\n", iface, level);
344
345     wined3d_mutex_lock();
346     if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
347         hr = D3DERR_INVALIDCALL;
348     else
349         hr = IDirect3DVolume9_UnlockBox((IDirect3DVolume9 *)wined3d_resource_get_parent(sub_resource));
350     wined3d_mutex_unlock();
351
352     return hr;
353 }
354
355 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_AddDirtyBox(IDirect3DVolumeTexture9 *iface,
356         const D3DBOX *dirty_box)
357 {
358     IDirect3DVolumeTexture9Impl *texture = (IDirect3DVolumeTexture9Impl *)iface;
359     HRESULT hr;
360
361     TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
362
363     wined3d_mutex_lock();
364     hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const WINED3DBOX *)dirty_box);
365     wined3d_mutex_unlock();
366
367     return hr;
368 }
369
370
371 static const IDirect3DVolumeTexture9Vtbl Direct3DVolumeTexture9_Vtbl =
372 {
373     /* IUnknown */
374     IDirect3DVolumeTexture9Impl_QueryInterface,
375     IDirect3DVolumeTexture9Impl_AddRef,
376     IDirect3DVolumeTexture9Impl_Release,
377     /* IDirect3DResource9 */
378     IDirect3DVolumeTexture9Impl_GetDevice,
379     IDirect3DVolumeTexture9Impl_SetPrivateData,
380     IDirect3DVolumeTexture9Impl_GetPrivateData,
381     IDirect3DVolumeTexture9Impl_FreePrivateData,
382     IDirect3DVolumeTexture9Impl_SetPriority,
383     IDirect3DVolumeTexture9Impl_GetPriority,
384     IDirect3DVolumeTexture9Impl_PreLoad,
385     IDirect3DVolumeTexture9Impl_GetType,
386     /* IDirect3DBaseTexture9 */
387     IDirect3DVolumeTexture9Impl_SetLOD,
388     IDirect3DVolumeTexture9Impl_GetLOD,
389     IDirect3DVolumeTexture9Impl_GetLevelCount,
390     IDirect3DVolumeTexture9Impl_SetAutoGenFilterType,
391     IDirect3DVolumeTexture9Impl_GetAutoGenFilterType,
392     IDirect3DVolumeTexture9Impl_GenerateMipSubLevels,
393     /* IDirect3DVolumeTexture9 */
394     IDirect3DVolumeTexture9Impl_GetLevelDesc,
395     IDirect3DVolumeTexture9Impl_GetVolumeLevel,
396     IDirect3DVolumeTexture9Impl_LockBox,
397     IDirect3DVolumeTexture9Impl_UnlockBox,
398     IDirect3DVolumeTexture9Impl_AddDirtyBox
399 };
400
401 static void STDMETHODCALLTYPE volumetexture_wined3d_object_destroyed(void *parent)
402 {
403     HeapFree(GetProcessHeap(), 0, parent);
404 }
405
406 static const struct wined3d_parent_ops d3d9_volumetexture_wined3d_parent_ops =
407 {
408     volumetexture_wined3d_object_destroyed,
409 };
410
411 HRESULT volumetexture_init(IDirect3DVolumeTexture9Impl *texture, IDirect3DDevice9Impl *device,
412         UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
413 {
414     HRESULT hr;
415
416     texture->lpVtbl = &Direct3DVolumeTexture9_Vtbl;
417     texture->ref = 1;
418
419     wined3d_mutex_lock();
420     hr = IWineD3DDevice_CreateVolumeTexture(device->WineD3DDevice, width, height, depth, levels,
421             usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture,
422             &d3d9_volumetexture_wined3d_parent_ops, &texture->wined3d_texture);
423     wined3d_mutex_unlock();
424     if (FAILED(hr))
425     {
426         WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
427         return hr;
428     }
429
430     texture->parentDevice = (IDirect3DDevice9Ex *)device;
431     IDirect3DDevice9Ex_AddRef(texture->parentDevice);
432
433     return D3D_OK;
434 }