wined3d: Get rid of IWineD3DCubeTexture.
[wine] / dlls / d3d8 / cubetexture.c
1 /*
2  * IDirect3DCubeTexture8 implementation
3  *
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 "d3d8_private.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
25
26 static inline IDirect3DCubeTexture8Impl *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface)
27 {
28     return CONTAINING_RECORD(iface, IDirect3DCubeTexture8Impl, IDirect3DCubeTexture8_iface);
29 }
30
31 static HRESULT WINAPI IDirect3DCubeTexture8Impl_QueryInterface(IDirect3DCubeTexture8 *iface,
32         REFIID riid, void **ppobj)
33 {
34     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
35
36     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
37
38     if (IsEqualGUID(riid, &IID_IUnknown)
39         || IsEqualGUID(riid, &IID_IDirect3DResource8)
40         || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
41         || IsEqualGUID(riid, &IID_IDirect3DCubeTexture8)) {
42         IUnknown_AddRef(iface);
43         *ppobj = This;
44         return S_OK;
45     }
46
47     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
48     *ppobj = NULL;
49     return E_NOINTERFACE;
50 }
51
52 static ULONG WINAPI IDirect3DCubeTexture8Impl_AddRef(IDirect3DCubeTexture8 *iface)
53 {
54     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
55     ULONG ref = InterlockedIncrement(&This->ref);
56
57     TRACE("%p increasing refcount to %u.\n", iface, ref);
58
59     if (ref == 1)
60     {
61         IUnknown_AddRef(This->parentDevice);
62         wined3d_mutex_lock();
63         IWineD3DBaseTexture_AddRef(This->wined3d_texture);
64         wined3d_mutex_unlock();
65     }
66
67     return ref;
68 }
69
70 static ULONG WINAPI IDirect3DCubeTexture8Impl_Release(IDirect3DCubeTexture8 *iface)
71 {
72     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
73     ULONG ref = InterlockedDecrement(&This->ref);
74
75     TRACE("%p decreasing refcount to %u.\n", iface, ref);
76
77     if (ref == 0) {
78         IDirect3DDevice8 *parentDevice = This->parentDevice;
79
80         TRACE("Releasing child %p.\n", This->wined3d_texture);
81
82         wined3d_mutex_lock();
83         IWineD3DBaseTexture_Release(This->wined3d_texture);
84         wined3d_mutex_unlock();
85
86         /* Release the device last, as it may cause the device to be destroyed. */
87         IDirect3DDevice8_Release(parentDevice);
88     }
89     return ref;
90 }
91
92 /* IDirect3DCubeTexture8 IDirect3DResource8 Interface follow: */
93 static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetDevice(IDirect3DCubeTexture8 *iface,
94         IDirect3DDevice8 **device)
95 {
96     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
97
98     TRACE("iface %p, device %p.\n", iface, device);
99
100     *device = (IDirect3DDevice8 *)This->parentDevice;
101     IDirect3DDevice8_AddRef(*device);
102
103     TRACE("Returning device %p.\n", *device);
104
105     return D3D_OK;
106 }
107
108 static HRESULT WINAPI IDirect3DCubeTexture8Impl_SetPrivateData(IDirect3DCubeTexture8 *iface,
109         REFGUID refguid, const void *pData, DWORD SizeOfData, DWORD Flags)
110 {
111     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
112     HRESULT hr;
113
114     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
115             iface, debugstr_guid(refguid), pData, SizeOfData, Flags);
116
117     wined3d_mutex_lock();
118     hr = IWineD3DBaseTexture_SetPrivateData(This->wined3d_texture, refguid, pData, SizeOfData, Flags);
119     wined3d_mutex_unlock();
120
121     return hr;
122 }
123
124 static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetPrivateData(IDirect3DCubeTexture8 *iface,
125         REFGUID refguid, void *pData, DWORD *pSizeOfData)
126 {
127     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
128     HRESULT hr;
129
130     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
131             iface, debugstr_guid(refguid), pData, pSizeOfData);
132
133     wined3d_mutex_lock();
134     hr = IWineD3DBaseTexture_GetPrivateData(This->wined3d_texture, refguid, pData, pSizeOfData);
135     wined3d_mutex_unlock();
136
137     return hr;
138 }
139
140 static HRESULT WINAPI IDirect3DCubeTexture8Impl_FreePrivateData(IDirect3DCubeTexture8 *iface,
141         REFGUID refguid)
142 {
143     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
144     HRESULT hr;
145
146     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(refguid));
147
148     wined3d_mutex_lock();
149     hr = IWineD3DBaseTexture_FreePrivateData(This->wined3d_texture, refguid);
150     wined3d_mutex_unlock();
151
152     return hr;
153 }
154
155 static DWORD WINAPI IDirect3DCubeTexture8Impl_SetPriority(IDirect3DCubeTexture8 *iface,
156         DWORD PriorityNew)
157 {
158     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
159     DWORD ret;
160
161     TRACE("iface %p, priority %u.\n", iface, PriorityNew);
162
163     wined3d_mutex_lock();
164     ret = IWineD3DBaseTexture_SetPriority(This->wined3d_texture, PriorityNew);
165     wined3d_mutex_unlock();
166
167     return ret;
168 }
169
170 static DWORD WINAPI IDirect3DCubeTexture8Impl_GetPriority(IDirect3DCubeTexture8 *iface)
171 {
172     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
173     DWORD ret;
174
175     TRACE("iface %p.\n", iface);
176
177     wined3d_mutex_lock();
178     ret =  IWineD3DBaseTexture_GetPriority(This->wined3d_texture);
179     wined3d_mutex_unlock();
180
181     return ret;
182 }
183
184 static void WINAPI IDirect3DCubeTexture8Impl_PreLoad(IDirect3DCubeTexture8 *iface)
185 {
186     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
187
188     TRACE("iface %p.\n", iface);
189
190     wined3d_mutex_lock();
191     IWineD3DBaseTexture_PreLoad(This->wined3d_texture);
192     wined3d_mutex_unlock();
193 }
194
195 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(IDirect3DCubeTexture8 *iface)
196 {
197     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
198     D3DRESOURCETYPE type;
199
200     TRACE("iface %p.\n", iface);
201
202     wined3d_mutex_lock();
203     type = IWineD3DBaseTexture_GetType(This->wined3d_texture);
204     wined3d_mutex_unlock();
205
206     return type;
207 }
208
209 /* IDirect3DCubeTexture8 IDirect3DBaseTexture8 Interface follow: */
210 static DWORD WINAPI IDirect3DCubeTexture8Impl_SetLOD(IDirect3DCubeTexture8 *iface, DWORD LODNew)
211 {
212     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
213     DWORD lod;
214
215     TRACE("iface %p, lod %u.\n", iface, LODNew);
216
217     wined3d_mutex_lock();
218     lod = IWineD3DBaseTexture_SetLOD(This->wined3d_texture, LODNew);
219     wined3d_mutex_unlock();
220
221     return lod;
222 }
223
224 static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLOD(IDirect3DCubeTexture8 *iface)
225 {
226     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
227     DWORD lod;
228
229     TRACE("iface %p.\n", iface);
230
231     wined3d_mutex_lock();
232     lod = IWineD3DBaseTexture_GetLOD(This->wined3d_texture);
233     wined3d_mutex_unlock();
234
235     return lod;
236 }
237
238 static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLevelCount(IDirect3DCubeTexture8 *iface)
239 {
240     IDirect3DCubeTexture8Impl *This = impl_from_IDirect3DCubeTexture8(iface);
241     DWORD cnt;
242
243     TRACE("iface %p.\n", iface);
244
245     wined3d_mutex_lock();
246     cnt = IWineD3DBaseTexture_GetLevelCount(This->wined3d_texture);
247     wined3d_mutex_unlock();
248
249     return cnt;
250 }
251
252 /* IDirect3DCubeTexture8 Interface follow: */
253 static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetLevelDesc(IDirect3DCubeTexture8 *iface,
254         UINT level, D3DSURFACE_DESC *desc)
255 {
256     IDirect3DCubeTexture8Impl *texture = impl_from_IDirect3DCubeTexture8(iface);
257     struct wined3d_resource *sub_resource;
258     HRESULT hr = D3D_OK;
259
260     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
261
262     wined3d_mutex_lock();
263     if (!(sub_resource = IWineD3DBaseTexture_GetSubResource(texture->wined3d_texture, level)))
264         hr = D3DERR_INVALIDCALL;
265     else
266     {
267         struct wined3d_resource_desc wined3d_desc;
268
269         wined3d_resource_get_desc(sub_resource, &wined3d_desc);
270         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
271         desc->Type = wined3d_desc.resource_type;
272         desc->Usage = wined3d_desc.usage;
273         desc->Pool = wined3d_desc.pool;
274         desc->Size = wined3d_desc.size;
275         desc->MultiSampleType = wined3d_desc.multisample_type;
276         desc->Width = wined3d_desc.width;
277         desc->Height = wined3d_desc.height;
278     }
279     wined3d_mutex_unlock();
280
281     return hr;
282 }
283
284 static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetCubeMapSurface(IDirect3DCubeTexture8 *iface,
285         D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface8 **surface)
286 {
287     IDirect3DCubeTexture8Impl *texture = impl_from_IDirect3DCubeTexture8(iface);
288     struct wined3d_resource *sub_resource;
289     UINT sub_resource_idx;
290
291     TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
292
293     wined3d_mutex_lock();
294     sub_resource_idx = IWineD3DBaseTexture_GetLevelCount(texture->wined3d_texture) * face + level;
295     if (!(sub_resource = IWineD3DBaseTexture_GetSubResource(texture->wined3d_texture, sub_resource_idx)))
296     {
297         wined3d_mutex_unlock();
298         return D3DERR_INVALIDCALL;
299     }
300
301     *surface = wined3d_resource_get_parent(sub_resource);
302     IDirect3DSurface8_AddRef(*surface);
303     wined3d_mutex_unlock();
304
305     return D3D_OK;
306 }
307
308 static HRESULT WINAPI IDirect3DCubeTexture8Impl_LockRect(IDirect3DCubeTexture8 *iface,
309         D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
310         DWORD flags)
311 {
312     IDirect3DCubeTexture8Impl *texture = impl_from_IDirect3DCubeTexture8(iface);
313     struct wined3d_resource *sub_resource;
314     UINT sub_resource_idx;
315     HRESULT hr;
316
317     TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
318             iface, face, level, locked_rect, rect, flags);
319
320     wined3d_mutex_lock();
321     sub_resource_idx = IWineD3DBaseTexture_GetLevelCount(texture->wined3d_texture) * face + level;
322     if (!(sub_resource = IWineD3DBaseTexture_GetSubResource(texture->wined3d_texture, sub_resource_idx)))
323         hr = D3DERR_INVALIDCALL;
324     else
325         hr = IDirect3DSurface8_LockRect((IDirect3DSurface8 *)wined3d_resource_get_parent(sub_resource),
326                 locked_rect, rect, flags);
327     wined3d_mutex_unlock();
328
329     return hr;
330 }
331
332 static HRESULT WINAPI IDirect3DCubeTexture8Impl_UnlockRect(IDirect3DCubeTexture8 *iface,
333         D3DCUBEMAP_FACES face, UINT level)
334 {
335     IDirect3DCubeTexture8Impl *texture = impl_from_IDirect3DCubeTexture8(iface);
336     struct wined3d_resource *sub_resource;
337     UINT sub_resource_idx;
338     HRESULT hr;
339
340     TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
341
342     wined3d_mutex_lock();
343     sub_resource_idx = IWineD3DBaseTexture_GetLevelCount(texture->wined3d_texture) * face + level;
344     if (!(sub_resource = IWineD3DBaseTexture_GetSubResource(texture->wined3d_texture, sub_resource_idx)))
345         hr = D3DERR_INVALIDCALL;
346     else
347         hr = IDirect3DSurface8_UnlockRect((IDirect3DSurface8 *)wined3d_resource_get_parent(sub_resource));
348     wined3d_mutex_unlock();
349
350     return hr;
351 }
352
353 static HRESULT WINAPI IDirect3DCubeTexture8Impl_AddDirtyRect(IDirect3DCubeTexture8 *iface,
354         D3DCUBEMAP_FACES face, const RECT *dirty_rect)
355 {
356     IDirect3DCubeTexture8Impl *texture = impl_from_IDirect3DCubeTexture8(iface);
357     HRESULT hr;
358
359     TRACE("iface %p, face %#x, dirty_rect %s.\n",
360             iface, face, wine_dbgstr_rect(dirty_rect));
361
362     wined3d_mutex_lock();
363     if (!dirty_rect)
364         hr = IWineD3DBaseTexture_AddDirtyRegion(texture->wined3d_texture, face, NULL);
365     else
366     {
367         WINED3DBOX dirty_region;
368
369         dirty_region.Left = dirty_rect->left;
370         dirty_region.Top = dirty_rect->top;
371         dirty_region.Right = dirty_rect->right;
372         dirty_region.Bottom = dirty_rect->bottom;
373         dirty_region.Front = 0;
374         dirty_region.Back = 1;
375         hr = IWineD3DBaseTexture_AddDirtyRegion(texture->wined3d_texture, face, &dirty_region);
376     }
377     wined3d_mutex_unlock();
378
379     return hr;
380 }
381
382 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl =
383 {
384     /* IUnknown */
385     IDirect3DCubeTexture8Impl_QueryInterface,
386     IDirect3DCubeTexture8Impl_AddRef,
387     IDirect3DCubeTexture8Impl_Release,
388     /* IDirect3DResource8 */
389     IDirect3DCubeTexture8Impl_GetDevice,
390     IDirect3DCubeTexture8Impl_SetPrivateData,
391     IDirect3DCubeTexture8Impl_GetPrivateData,
392     IDirect3DCubeTexture8Impl_FreePrivateData,
393     IDirect3DCubeTexture8Impl_SetPriority,
394     IDirect3DCubeTexture8Impl_GetPriority,
395     IDirect3DCubeTexture8Impl_PreLoad,
396     IDirect3DCubeTexture8Impl_GetType,
397     /* IDirect3DBaseTexture8 */
398     IDirect3DCubeTexture8Impl_SetLOD,
399     IDirect3DCubeTexture8Impl_GetLOD,
400     IDirect3DCubeTexture8Impl_GetLevelCount,
401     /* IDirect3DCubeTexture8 */
402     IDirect3DCubeTexture8Impl_GetLevelDesc,
403     IDirect3DCubeTexture8Impl_GetCubeMapSurface,
404     IDirect3DCubeTexture8Impl_LockRect,
405     IDirect3DCubeTexture8Impl_UnlockRect,
406     IDirect3DCubeTexture8Impl_AddDirtyRect
407 };
408
409 static void STDMETHODCALLTYPE d3d8_cubetexture_wined3d_object_destroyed(void *parent)
410 {
411     HeapFree(GetProcessHeap(), 0, parent);
412 }
413
414 static const struct wined3d_parent_ops d3d8_cubetexture_wined3d_parent_ops =
415 {
416     d3d8_cubetexture_wined3d_object_destroyed,
417 };
418
419 HRESULT cubetexture_init(IDirect3DCubeTexture8Impl *texture, IDirect3DDevice8Impl *device,
420         UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
421 {
422     HRESULT hr;
423
424     texture->IDirect3DCubeTexture8_iface.lpVtbl = &Direct3DCubeTexture8_Vtbl;
425     texture->ref = 1;
426
427     wined3d_mutex_lock();
428     hr = IWineD3DDevice_CreateCubeTexture(device->WineD3DDevice, edge_length, levels,
429             usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture,
430             &d3d8_cubetexture_wined3d_parent_ops, &texture->wined3d_texture);
431     wined3d_mutex_unlock();
432     if (FAILED(hr))
433     {
434         WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
435         return hr;
436     }
437
438     texture->parentDevice = &device->IDirect3DDevice8_iface;
439     IDirect3DDevice8_AddRef(texture->parentDevice);
440
441     return D3D_OK;
442 }