d3d9: Properly retrieve an interface pointer in IDirect3DDevice9Impl_GetBackBuffer().
[wine/multimedia.git] / dlls / d3d9 / volumetexture.c
blob66ae1e6f9b997809ed8ac12b77d0ae56f7e15e5e
1 /*
2 * IDirect3DVolumeTexture9 implementation
4 * Copyright 2002-2005 Jason Edmeades
5 * Raphael Junqueira
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.
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.
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
22 #include "config.h"
23 #include "d3d9_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
27 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
29 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
32 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
34 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
36 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
37 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
38 || IsEqualGUID(riid, &IID_IDirect3DResource9)
39 || IsEqualGUID(riid, &IID_IUnknown))
41 IDirect3DVolumeTexture9_AddRef(iface);
42 *out = iface;
43 return S_OK;
46 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
48 *out = NULL;
49 return E_NOINTERFACE;
52 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
54 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
55 ULONG ref = InterlockedIncrement(&texture->refcount);
57 TRACE("%p increasing refcount to %u.\n", iface, ref);
59 if (ref == 1)
61 IDirect3DDevice9Ex_AddRef(texture->parent_device);
62 wined3d_mutex_lock();
63 wined3d_texture_incref(texture->wined3d_texture);
64 wined3d_mutex_unlock();
67 return ref;
70 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
72 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
73 ULONG ref = InterlockedDecrement(&texture->refcount);
75 TRACE("%p decreasing refcount to %u.\n", iface, ref);
77 if (!ref)
79 IDirect3DDevice9Ex *parent_device = texture->parent_device;
81 wined3d_mutex_lock();
82 wined3d_texture_decref(texture->wined3d_texture);
83 wined3d_mutex_unlock();
85 /* Release the device last, as it may cause the device to be destroyed. */
86 IDirect3DDevice9Ex_Release(parent_device);
88 return ref;
91 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
93 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
95 TRACE("iface %p, device %p.\n", iface, device);
97 *device = (IDirect3DDevice9 *)texture->parent_device;
98 IDirect3DDevice9_AddRef(*device);
100 TRACE("Returning device %p.\n", *device);
102 return D3D_OK;
105 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
106 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
108 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
109 struct wined3d_resource *resource;
110 HRESULT hr;
112 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
113 iface, debugstr_guid(guid), data, data_size, flags);
115 wined3d_mutex_lock();
116 resource = wined3d_texture_get_resource(texture->wined3d_texture);
117 hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
118 wined3d_mutex_unlock();
120 return hr;
123 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
124 REFGUID guid, void *data, DWORD *data_size)
126 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
127 struct wined3d_resource *resource;
128 HRESULT hr;
130 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
131 iface, debugstr_guid(guid), data, data_size);
133 wined3d_mutex_lock();
134 resource = wined3d_texture_get_resource(texture->wined3d_texture);
135 hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
136 wined3d_mutex_unlock();
138 return hr;
141 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
143 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
144 struct wined3d_resource *resource;
145 HRESULT hr;
147 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
149 wined3d_mutex_lock();
150 resource = wined3d_texture_get_resource(texture->wined3d_texture);
151 hr = wined3d_resource_free_private_data(resource, guid);
152 wined3d_mutex_unlock();
154 return hr;
157 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
159 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
160 DWORD ret;
162 TRACE("iface %p, priority %u.\n", iface, priority);
164 wined3d_mutex_lock();
165 ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
166 wined3d_mutex_unlock();
168 return ret;
171 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
173 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
174 DWORD ret;
176 TRACE("iface %p.\n", iface);
178 wined3d_mutex_lock();
179 ret = wined3d_texture_get_priority(texture->wined3d_texture);
180 wined3d_mutex_unlock();
182 return ret;
185 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
187 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
189 TRACE("iface %p.\n", iface);
191 wined3d_mutex_lock();
192 wined3d_texture_preload(texture->wined3d_texture);
193 wined3d_mutex_unlock();
196 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
198 TRACE("iface %p.\n", iface);
200 return D3DRTYPE_VOLUMETEXTURE;
203 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
205 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
206 DWORD ret;
208 TRACE("iface %p, lod %u.\n", iface, lod);
210 wined3d_mutex_lock();
211 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
212 wined3d_mutex_unlock();
214 return ret;
217 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
219 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
220 DWORD ret;
222 TRACE("iface %p.\n", iface);
224 wined3d_mutex_lock();
225 ret = wined3d_texture_get_lod(texture->wined3d_texture);
226 wined3d_mutex_unlock();
228 return ret;
231 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
233 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
234 DWORD ret;
236 TRACE("iface %p.\n", iface);
238 wined3d_mutex_lock();
239 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
240 wined3d_mutex_unlock();
242 return ret;
245 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
246 D3DTEXTUREFILTERTYPE filter_type)
248 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
249 HRESULT hr;
251 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
253 wined3d_mutex_lock();
254 hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
255 (enum wined3d_texture_filter_type)filter_type);
256 wined3d_mutex_unlock();
258 return hr;
261 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
263 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
264 D3DTEXTUREFILTERTYPE filter_type;
266 TRACE("iface %p.\n", iface);
268 wined3d_mutex_lock();
269 filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
270 wined3d_mutex_unlock();
272 return filter_type;
275 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
277 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
279 TRACE("iface %p.\n", iface);
281 wined3d_mutex_lock();
282 wined3d_texture_generate_mipmaps(texture->wined3d_texture);
283 wined3d_mutex_unlock();
286 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
288 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
289 struct wined3d_resource *sub_resource;
290 HRESULT hr = D3D_OK;
292 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
294 wined3d_mutex_lock();
295 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
296 hr = D3DERR_INVALIDCALL;
297 else
299 struct wined3d_resource_desc wined3d_desc;
301 wined3d_resource_get_desc(sub_resource, &wined3d_desc);
302 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
303 desc->Type = wined3d_desc.resource_type;
304 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
305 desc->Pool = wined3d_desc.pool;
306 desc->Width = wined3d_desc.width;
307 desc->Height = wined3d_desc.height;
308 desc->Depth = wined3d_desc.depth;
310 wined3d_mutex_unlock();
312 return hr;
315 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
316 UINT level, IDirect3DVolume9 **volume)
318 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
319 struct wined3d_resource *sub_resource;
321 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
323 wined3d_mutex_lock();
324 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
326 wined3d_mutex_unlock();
327 return D3DERR_INVALIDCALL;
330 *volume = wined3d_resource_get_parent(sub_resource);
331 IDirect3DVolume9_AddRef(*volume);
332 wined3d_mutex_unlock();
334 return D3D_OK;
337 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
338 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
340 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
341 struct wined3d_resource *sub_resource;
342 HRESULT hr;
344 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
345 iface, level, locked_box, box, flags);
347 wined3d_mutex_lock();
348 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
349 hr = D3DERR_INVALIDCALL;
350 else
351 hr = IDirect3DVolume9_LockBox((IDirect3DVolume9 *)wined3d_resource_get_parent(sub_resource),
352 locked_box, box, flags);
353 wined3d_mutex_unlock();
355 return hr;
358 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
360 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
361 struct wined3d_resource *sub_resource;
362 HRESULT hr;
364 TRACE("iface %p, level %u.\n", iface, level);
366 wined3d_mutex_lock();
367 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
368 hr = D3DERR_INVALIDCALL;
369 else
370 hr = IDirect3DVolume9_UnlockBox((IDirect3DVolume9 *)wined3d_resource_get_parent(sub_resource));
371 wined3d_mutex_unlock();
373 return hr;
376 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
378 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
379 HRESULT hr;
381 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
383 wined3d_mutex_lock();
384 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
385 wined3d_mutex_unlock();
387 return hr;
391 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
393 /* IUnknown */
394 d3d9_texture_3d_QueryInterface,
395 d3d9_texture_3d_AddRef,
396 d3d9_texture_3d_Release,
397 /* IDirect3DResource9 */
398 d3d9_texture_3d_GetDevice,
399 d3d9_texture_3d_SetPrivateData,
400 d3d9_texture_3d_GetPrivateData,
401 d3d9_texture_3d_FreePrivateData,
402 d3d9_texture_3d_SetPriority,
403 d3d9_texture_3d_GetPriority,
404 d3d9_texture_3d_PreLoad,
405 d3d9_texture_3d_GetType,
406 /* IDirect3DBaseTexture9 */
407 d3d9_texture_3d_SetLOD,
408 d3d9_texture_3d_GetLOD,
409 d3d9_texture_3d_GetLevelCount,
410 d3d9_texture_3d_SetAutoGenFilterType,
411 d3d9_texture_3d_GetAutoGenFilterType,
412 d3d9_texture_3d_GenerateMipSubLevels,
413 /* IDirect3DVolumeTexture9 */
414 d3d9_texture_3d_GetLevelDesc,
415 d3d9_texture_3d_GetVolumeLevel,
416 d3d9_texture_3d_LockBox,
417 d3d9_texture_3d_UnlockBox,
418 d3d9_texture_3d_AddDirtyBox,
421 static void STDMETHODCALLTYPE volumetexture_wined3d_object_destroyed(void *parent)
423 HeapFree(GetProcessHeap(), 0, parent);
426 static const struct wined3d_parent_ops d3d9_volumetexture_wined3d_parent_ops =
428 volumetexture_wined3d_object_destroyed,
431 HRESULT volumetexture_init(struct d3d9_texture *texture, IDirect3DDevice9Impl *device,
432 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
434 HRESULT hr;
436 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
437 texture->refcount = 1;
439 wined3d_mutex_lock();
440 hr = wined3d_texture_create_3d(device->wined3d_device, width, height, depth, levels,
441 usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture,
442 &d3d9_volumetexture_wined3d_parent_ops, &texture->wined3d_texture);
443 wined3d_mutex_unlock();
444 if (FAILED(hr))
446 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
447 return hr;
450 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
451 IDirect3DDevice9Ex_AddRef(texture->parent_device);
453 return D3D_OK;