2 * Copyright 2005 Oliver Stieber
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "d3d8_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d8
);
24 static inline struct d3d8_texture
*impl_from_IDirect3DTexture8(IDirect3DTexture8
*iface
)
26 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
29 static inline struct d3d8_texture
*impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8
*iface
)
31 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
34 static inline struct d3d8_texture
*impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8
*iface
)
36 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
39 static HRESULT WINAPI
d3d8_texture_2d_QueryInterface(IDirect3DTexture8
*iface
, REFIID riid
, void **out
)
41 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
43 if (IsEqualGUID(riid
, &IID_IDirect3DTexture8
)
44 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
45 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
46 || IsEqualGUID(riid
, &IID_IUnknown
))
48 IDirect3DTexture8_AddRef(iface
);
53 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
59 static ULONG WINAPI
d3d8_texture_2d_AddRef(IDirect3DTexture8
*iface
)
61 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
62 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
64 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
68 IDirect3DDevice8_AddRef(texture
->parent_device
);
70 wined3d_texture_incref(texture
->wined3d_texture
);
71 wined3d_mutex_unlock();
77 static ULONG WINAPI
d3d8_texture_2d_Release(IDirect3DTexture8
*iface
)
79 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
80 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
82 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
86 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
89 wined3d_texture_decref(texture
->wined3d_texture
);
90 wined3d_mutex_unlock();
92 /* Release the device last, as it may cause the device to be destroyed. */
93 IDirect3DDevice8_Release(parent_device
);
98 static HRESULT WINAPI
d3d8_texture_2d_GetDevice(IDirect3DTexture8
*iface
, IDirect3DDevice8
**device
)
100 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
102 TRACE("iface %p, device %p.\n", iface
, device
);
104 *device
= texture
->parent_device
;
105 IDirect3DDevice8_AddRef(*device
);
107 TRACE("Returning device %p.\n", *device
);
112 static HRESULT WINAPI
d3d8_texture_2d_SetPrivateData(IDirect3DTexture8
*iface
,
113 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
115 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
116 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
117 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
119 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
122 static HRESULT WINAPI
d3d8_texture_2d_GetPrivateData(IDirect3DTexture8
*iface
,
123 REFGUID guid
, void *data
, DWORD
*data_size
)
125 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
126 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
127 iface
, debugstr_guid(guid
), data
, data_size
);
129 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
132 static HRESULT WINAPI
d3d8_texture_2d_FreePrivateData(IDirect3DTexture8
*iface
, REFGUID guid
)
134 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
135 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
137 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
140 static DWORD WINAPI
d3d8_texture_2d_SetPriority(IDirect3DTexture8
*iface
, DWORD priority
)
142 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
145 TRACE("iface %p, priority %u.\n", iface
, priority
);
147 wined3d_mutex_lock();
148 ret
= wined3d_texture_set_priority(texture
->wined3d_texture
, priority
);
149 wined3d_mutex_unlock();
154 static DWORD WINAPI
d3d8_texture_2d_GetPriority(IDirect3DTexture8
*iface
)
156 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
159 TRACE("iface %p.\n", iface
);
161 wined3d_mutex_lock();
162 ret
= wined3d_texture_get_priority(texture
->wined3d_texture
);
163 wined3d_mutex_unlock();
168 static void WINAPI
d3d8_texture_2d_PreLoad(IDirect3DTexture8
*iface
)
170 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
172 TRACE("iface %p.\n", iface
);
174 wined3d_mutex_lock();
175 wined3d_texture_preload(texture
->wined3d_texture
);
176 wined3d_mutex_unlock();
179 static D3DRESOURCETYPE WINAPI
d3d8_texture_2d_GetType(IDirect3DTexture8
*iface
)
181 TRACE("iface %p.\n", iface
);
183 return D3DRTYPE_TEXTURE
;
186 static DWORD WINAPI
d3d8_texture_2d_SetLOD(IDirect3DTexture8
*iface
, DWORD lod
)
188 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
191 TRACE("iface %p, lod %u.\n", iface
, lod
);
193 wined3d_mutex_lock();
194 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
195 wined3d_mutex_unlock();
200 static DWORD WINAPI
d3d8_texture_2d_GetLOD(IDirect3DTexture8
*iface
)
202 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
205 TRACE("iface %p.\n", iface
);
207 wined3d_mutex_lock();
208 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
209 wined3d_mutex_unlock();
214 static DWORD WINAPI
d3d8_texture_2d_GetLevelCount(IDirect3DTexture8
*iface
)
216 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
219 TRACE("iface %p.\n", iface
);
221 wined3d_mutex_lock();
222 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
223 wined3d_mutex_unlock();
228 static HRESULT WINAPI
d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8
*iface
, UINT level
, D3DSURFACE_DESC
*desc
)
230 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
231 struct wined3d_resource
*sub_resource
;
234 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
236 wined3d_mutex_lock();
237 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
238 hr
= D3DERR_INVALIDCALL
;
241 struct wined3d_resource_desc wined3d_desc
;
243 wined3d_resource_get_desc(sub_resource
, &wined3d_desc
);
244 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
245 desc
->Type
= wined3d_desc
.resource_type
;
246 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
247 desc
->Pool
= wined3d_desc
.pool
;
248 desc
->Size
= wined3d_desc
.size
;
249 desc
->MultiSampleType
= wined3d_desc
.multisample_type
;
250 desc
->Width
= wined3d_desc
.width
;
251 desc
->Height
= wined3d_desc
.height
;
253 wined3d_mutex_unlock();
258 static HRESULT WINAPI
d3d8_texture_2d_GetSurfaceLevel(IDirect3DTexture8
*iface
,
259 UINT level
, IDirect3DSurface8
**surface
)
261 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
262 struct wined3d_resource
*sub_resource
;
263 struct d3d8_surface
*surface_impl
;
265 TRACE("iface %p, level %u, surface %p.\n", iface
, level
, surface
);
267 wined3d_mutex_lock();
268 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
270 wined3d_mutex_unlock();
271 return D3DERR_INVALIDCALL
;
274 surface_impl
= wined3d_resource_get_parent(sub_resource
);
275 *surface
= &surface_impl
->IDirect3DSurface8_iface
;
276 IDirect3DSurface8_AddRef(*surface
);
277 wined3d_mutex_unlock();
282 static HRESULT WINAPI
d3d8_texture_2d_LockRect(IDirect3DTexture8
*iface
, UINT level
,
283 D3DLOCKED_RECT
*locked_rect
, const RECT
*rect
, DWORD flags
)
285 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
286 struct wined3d_resource
*sub_resource
;
287 struct d3d8_surface
*surface_impl
;
290 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
291 iface
, level
, locked_rect
, rect
, flags
);
293 wined3d_mutex_lock();
294 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
295 hr
= D3DERR_INVALIDCALL
;
298 surface_impl
= wined3d_resource_get_parent(sub_resource
);
299 hr
= IDirect3DSurface8_LockRect(&surface_impl
->IDirect3DSurface8_iface
, locked_rect
, rect
, flags
);
301 wined3d_mutex_unlock();
306 static HRESULT WINAPI
d3d8_texture_2d_UnlockRect(IDirect3DTexture8
*iface
, UINT level
)
308 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
309 struct wined3d_resource
*sub_resource
;
310 struct d3d8_surface
*surface_impl
;
313 TRACE("iface %p, level %u.\n", iface
, level
);
315 wined3d_mutex_lock();
316 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
317 hr
= D3DERR_INVALIDCALL
;
320 surface_impl
= wined3d_resource_get_parent(sub_resource
);
321 hr
= IDirect3DSurface8_UnlockRect(&surface_impl
->IDirect3DSurface8_iface
);
323 wined3d_mutex_unlock();
328 static HRESULT WINAPI
d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8
*iface
, const RECT
*dirty_rect
)
330 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
333 TRACE("iface %p, dirty_rect %s.\n",
334 iface
, wine_dbgstr_rect(dirty_rect
));
336 wined3d_mutex_lock();
338 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, NULL
);
341 struct wined3d_box dirty_region
;
343 dirty_region
.left
= dirty_rect
->left
;
344 dirty_region
.top
= dirty_rect
->top
;
345 dirty_region
.right
= dirty_rect
->right
;
346 dirty_region
.bottom
= dirty_rect
->bottom
;
347 dirty_region
.front
= 0;
348 dirty_region
.back
= 1;
349 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, &dirty_region
);
351 wined3d_mutex_unlock();
356 static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl
=
359 d3d8_texture_2d_QueryInterface
,
360 d3d8_texture_2d_AddRef
,
361 d3d8_texture_2d_Release
,
362 /* IDirect3DResource8 */
363 d3d8_texture_2d_GetDevice
,
364 d3d8_texture_2d_SetPrivateData
,
365 d3d8_texture_2d_GetPrivateData
,
366 d3d8_texture_2d_FreePrivateData
,
367 d3d8_texture_2d_SetPriority
,
368 d3d8_texture_2d_GetPriority
,
369 d3d8_texture_2d_PreLoad
,
370 d3d8_texture_2d_GetType
,
371 /* IDirect3dBaseTexture8 */
372 d3d8_texture_2d_SetLOD
,
373 d3d8_texture_2d_GetLOD
,
374 d3d8_texture_2d_GetLevelCount
,
375 /* IDirect3DTexture8 */
376 d3d8_texture_2d_GetLevelDesc
,
377 d3d8_texture_2d_GetSurfaceLevel
,
378 d3d8_texture_2d_LockRect
,
379 d3d8_texture_2d_UnlockRect
,
380 d3d8_texture_2d_AddDirtyRect
,
383 static HRESULT WINAPI
d3d8_texture_cube_QueryInterface(IDirect3DCubeTexture8
*iface
, REFIID riid
, void **out
)
385 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
387 if (IsEqualGUID(riid
, &IID_IDirect3DCubeTexture8
)
388 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
389 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
390 || IsEqualGUID(riid
, &IID_IUnknown
))
392 IDirect3DCubeTexture8_AddRef(iface
);
397 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
400 return E_NOINTERFACE
;
403 static ULONG WINAPI
d3d8_texture_cube_AddRef(IDirect3DCubeTexture8
*iface
)
405 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
406 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
408 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
412 IDirect3DDevice8_AddRef(texture
->parent_device
);
413 wined3d_mutex_lock();
414 wined3d_texture_incref(texture
->wined3d_texture
);
415 wined3d_mutex_unlock();
421 static ULONG WINAPI
d3d8_texture_cube_Release(IDirect3DCubeTexture8
*iface
)
423 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
424 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
426 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
430 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
432 TRACE("Releasing child %p.\n", texture
->wined3d_texture
);
434 wined3d_mutex_lock();
435 wined3d_texture_decref(texture
->wined3d_texture
);
436 wined3d_mutex_unlock();
438 /* Release the device last, as it may cause the device to be destroyed. */
439 IDirect3DDevice8_Release(parent_device
);
444 static HRESULT WINAPI
d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8
*iface
, IDirect3DDevice8
**device
)
446 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
448 TRACE("iface %p, device %p.\n", iface
, device
);
450 *device
= texture
->parent_device
;
451 IDirect3DDevice8_AddRef(*device
);
453 TRACE("Returning device %p.\n", *device
);
458 static HRESULT WINAPI
d3d8_texture_cube_SetPrivateData(IDirect3DCubeTexture8
*iface
,
459 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
461 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
462 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
463 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
465 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
468 static HRESULT WINAPI
d3d8_texture_cube_GetPrivateData(IDirect3DCubeTexture8
*iface
,
469 REFGUID guid
, void *data
, DWORD
*data_size
)
471 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
472 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
473 iface
, debugstr_guid(guid
), data
, data_size
);
475 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
478 static HRESULT WINAPI
d3d8_texture_cube_FreePrivateData(IDirect3DCubeTexture8
*iface
, REFGUID guid
)
480 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
481 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
483 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
486 static DWORD WINAPI
d3d8_texture_cube_SetPriority(IDirect3DCubeTexture8
*iface
, DWORD priority
)
488 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
491 TRACE("iface %p, priority %u.\n", iface
, priority
);
493 wined3d_mutex_lock();
494 ret
= wined3d_texture_set_priority(texture
->wined3d_texture
, priority
);
495 wined3d_mutex_unlock();
500 static DWORD WINAPI
d3d8_texture_cube_GetPriority(IDirect3DCubeTexture8
*iface
)
502 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
505 TRACE("iface %p.\n", iface
);
507 wined3d_mutex_lock();
508 ret
= wined3d_texture_get_priority(texture
->wined3d_texture
);
509 wined3d_mutex_unlock();
514 static void WINAPI
d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8
*iface
)
516 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
518 TRACE("iface %p.\n", iface
);
520 wined3d_mutex_lock();
521 wined3d_texture_preload(texture
->wined3d_texture
);
522 wined3d_mutex_unlock();
525 static D3DRESOURCETYPE WINAPI
d3d8_texture_cube_GetType(IDirect3DCubeTexture8
*iface
)
527 TRACE("iface %p.\n", iface
);
529 return D3DRTYPE_CUBETEXTURE
;
532 static DWORD WINAPI
d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8
*iface
, DWORD lod
)
534 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
537 TRACE("iface %p, lod %u.\n", iface
, lod
);
539 wined3d_mutex_lock();
540 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
541 wined3d_mutex_unlock();
546 static DWORD WINAPI
d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8
*iface
)
548 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
551 TRACE("iface %p.\n", iface
);
553 wined3d_mutex_lock();
554 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
555 wined3d_mutex_unlock();
560 static DWORD WINAPI
d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8
*iface
)
562 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
565 TRACE("iface %p.\n", iface
);
567 wined3d_mutex_lock();
568 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
569 wined3d_mutex_unlock();
574 static HRESULT WINAPI
d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8
*iface
, UINT level
, D3DSURFACE_DESC
*desc
)
576 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
577 struct wined3d_resource
*sub_resource
;
580 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
582 wined3d_mutex_lock();
583 if (level
>= wined3d_texture_get_level_count(texture
->wined3d_texture
))
585 wined3d_mutex_unlock();
586 return D3DERR_INVALIDCALL
;
589 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
590 hr
= D3DERR_INVALIDCALL
;
593 struct wined3d_resource_desc wined3d_desc
;
595 wined3d_resource_get_desc(sub_resource
, &wined3d_desc
);
596 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
597 desc
->Type
= wined3d_desc
.resource_type
;
598 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
599 desc
->Pool
= wined3d_desc
.pool
;
600 desc
->Size
= wined3d_desc
.size
;
601 desc
->MultiSampleType
= wined3d_desc
.multisample_type
;
602 desc
->Width
= wined3d_desc
.width
;
603 desc
->Height
= wined3d_desc
.height
;
605 wined3d_mutex_unlock();
610 static HRESULT WINAPI
d3d8_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture8
*iface
,
611 D3DCUBEMAP_FACES face
, UINT level
, IDirect3DSurface8
**surface
)
613 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
614 struct wined3d_resource
*sub_resource
;
615 struct d3d8_surface
*surface_impl
;
616 UINT sub_resource_idx
;
619 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface
, face
, level
, surface
);
621 wined3d_mutex_lock();
622 level_count
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
623 if (level
>= level_count
)
625 wined3d_mutex_unlock();
626 return D3DERR_INVALIDCALL
;
629 sub_resource_idx
= level_count
* face
+ level
;
630 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, sub_resource_idx
)))
632 wined3d_mutex_unlock();
633 return D3DERR_INVALIDCALL
;
636 surface_impl
= wined3d_resource_get_parent(sub_resource
);
637 *surface
= &surface_impl
->IDirect3DSurface8_iface
;
638 IDirect3DSurface8_AddRef(*surface
);
639 wined3d_mutex_unlock();
644 static HRESULT WINAPI
d3d8_texture_cube_LockRect(IDirect3DCubeTexture8
*iface
,
645 D3DCUBEMAP_FACES face
, UINT level
, D3DLOCKED_RECT
*locked_rect
, const RECT
*rect
,
648 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
649 struct wined3d_resource
*sub_resource
;
650 struct d3d8_surface
*surface_impl
;
651 UINT sub_resource_idx
;
654 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
655 iface
, face
, level
, locked_rect
, rect
, flags
);
657 wined3d_mutex_lock();
658 sub_resource_idx
= wined3d_texture_get_level_count(texture
->wined3d_texture
) * face
+ level
;
659 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, sub_resource_idx
)))
660 hr
= D3DERR_INVALIDCALL
;
663 surface_impl
= wined3d_resource_get_parent(sub_resource
);
664 hr
= IDirect3DSurface8_LockRect(&surface_impl
->IDirect3DSurface8_iface
, locked_rect
, rect
, flags
);
666 wined3d_mutex_unlock();
671 static HRESULT WINAPI
d3d8_texture_cube_UnlockRect(IDirect3DCubeTexture8
*iface
,
672 D3DCUBEMAP_FACES face
, UINT level
)
674 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
675 struct wined3d_resource
*sub_resource
;
676 struct d3d8_surface
*surface_impl
;
677 UINT sub_resource_idx
;
680 TRACE("iface %p, face %#x, level %u.\n", iface
, face
, level
);
682 wined3d_mutex_lock();
683 sub_resource_idx
= wined3d_texture_get_level_count(texture
->wined3d_texture
) * face
+ level
;
684 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, sub_resource_idx
)))
685 hr
= D3DERR_INVALIDCALL
;
688 surface_impl
= wined3d_resource_get_parent(sub_resource
);
689 hr
= IDirect3DSurface8_UnlockRect(&surface_impl
->IDirect3DSurface8_iface
);
691 wined3d_mutex_unlock();
696 static HRESULT WINAPI
d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8
*iface
,
697 D3DCUBEMAP_FACES face
, const RECT
*dirty_rect
)
699 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
702 TRACE("iface %p, face %#x, dirty_rect %s.\n",
703 iface
, face
, wine_dbgstr_rect(dirty_rect
));
705 wined3d_mutex_lock();
707 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, face
, NULL
);
710 struct wined3d_box dirty_region
;
712 dirty_region
.left
= dirty_rect
->left
;
713 dirty_region
.top
= dirty_rect
->top
;
714 dirty_region
.right
= dirty_rect
->right
;
715 dirty_region
.bottom
= dirty_rect
->bottom
;
716 dirty_region
.front
= 0;
717 dirty_region
.back
= 1;
718 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, face
, &dirty_region
);
720 wined3d_mutex_unlock();
725 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl
=
728 d3d8_texture_cube_QueryInterface
,
729 d3d8_texture_cube_AddRef
,
730 d3d8_texture_cube_Release
,
731 /* IDirect3DResource8 */
732 d3d8_texture_cube_GetDevice
,
733 d3d8_texture_cube_SetPrivateData
,
734 d3d8_texture_cube_GetPrivateData
,
735 d3d8_texture_cube_FreePrivateData
,
736 d3d8_texture_cube_SetPriority
,
737 d3d8_texture_cube_GetPriority
,
738 d3d8_texture_cube_PreLoad
,
739 d3d8_texture_cube_GetType
,
740 /* IDirect3DBaseTexture8 */
741 d3d8_texture_cube_SetLOD
,
742 d3d8_texture_cube_GetLOD
,
743 d3d8_texture_cube_GetLevelCount
,
744 /* IDirect3DCubeTexture8 */
745 d3d8_texture_cube_GetLevelDesc
,
746 d3d8_texture_cube_GetCubeMapSurface
,
747 d3d8_texture_cube_LockRect
,
748 d3d8_texture_cube_UnlockRect
,
749 d3d8_texture_cube_AddDirtyRect
,
752 static HRESULT WINAPI
d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8
*iface
, REFIID riid
, void **out
)
754 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
756 if (IsEqualGUID(riid
, &IID_IDirect3DVolumeTexture8
)
757 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
758 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
759 || IsEqualGUID(riid
, &IID_IUnknown
))
761 IDirect3DVolumeTexture8_AddRef(iface
);
766 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
769 return E_NOINTERFACE
;
772 static ULONG WINAPI
d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8
*iface
)
774 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
775 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
777 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
781 IDirect3DDevice8_AddRef(texture
->parent_device
);
782 wined3d_mutex_lock();
783 wined3d_texture_incref(texture
->wined3d_texture
);
784 wined3d_mutex_unlock();
790 static ULONG WINAPI
d3d8_texture_3d_Release(IDirect3DVolumeTexture8
*iface
)
792 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
793 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
795 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
799 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
801 wined3d_mutex_lock();
802 wined3d_texture_decref(texture
->wined3d_texture
);
803 wined3d_mutex_unlock();
805 /* Release the device last, as it may cause the device to be destroyed. */
806 IDirect3DDevice8_Release(parent_device
);
811 static HRESULT WINAPI
d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8
*iface
, IDirect3DDevice8
**device
)
813 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
815 TRACE("iface %p, device %p.\n", iface
, device
);
817 *device
= texture
->parent_device
;
818 IDirect3DDevice8_AddRef(*device
);
820 TRACE("Returning device %p.\n", *device
);
825 static HRESULT WINAPI
d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8
*iface
,
826 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
828 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
829 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
830 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
832 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
835 static HRESULT WINAPI
d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8
*iface
,
836 REFGUID guid
, void *data
, DWORD
*data_size
)
838 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
839 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
840 iface
, debugstr_guid(guid
), data
, data_size
);
842 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
845 static HRESULT WINAPI
d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8
*iface
, REFGUID guid
)
847 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
848 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
850 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
853 static DWORD WINAPI
d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8
*iface
, DWORD priority
)
855 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
858 TRACE("iface %p, priority %u.\n", iface
, priority
);
860 wined3d_mutex_lock();
861 ret
= wined3d_texture_set_priority(texture
->wined3d_texture
, priority
);
862 wined3d_mutex_unlock();
867 static DWORD WINAPI
d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8
*iface
)
869 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
872 TRACE("iface %p.\n", iface
);
874 wined3d_mutex_lock();
875 ret
= wined3d_texture_get_priority(texture
->wined3d_texture
);
876 wined3d_mutex_unlock();
881 static void WINAPI
d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8
*iface
)
883 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
885 TRACE("iface %p.\n", iface
);
887 wined3d_mutex_lock();
888 wined3d_texture_preload(texture
->wined3d_texture
);
889 wined3d_mutex_unlock();
892 static D3DRESOURCETYPE WINAPI
d3d8_texture_3d_GetType(IDirect3DVolumeTexture8
*iface
)
894 TRACE("iface %p.\n", iface
);
896 return D3DRTYPE_VOLUMETEXTURE
;
899 static DWORD WINAPI
d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8
*iface
, DWORD lod
)
901 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
904 TRACE("iface %p, lod %u.\n", iface
, lod
);
906 wined3d_mutex_lock();
907 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
908 wined3d_mutex_unlock();
913 static DWORD WINAPI
d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8
*iface
)
915 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
918 TRACE("iface %p.\n", iface
);
920 wined3d_mutex_lock();
921 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
922 wined3d_mutex_unlock();
927 static DWORD WINAPI
d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8
*iface
)
929 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
932 TRACE("iface %p.\n", iface
);
934 wined3d_mutex_lock();
935 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
936 wined3d_mutex_unlock();
941 static HRESULT WINAPI
d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8
*iface
, UINT level
, D3DVOLUME_DESC
*desc
)
943 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
944 struct wined3d_resource
*sub_resource
;
947 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
949 wined3d_mutex_lock();
950 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
951 hr
= D3DERR_INVALIDCALL
;
954 struct wined3d_resource_desc wined3d_desc
;
956 wined3d_resource_get_desc(sub_resource
, &wined3d_desc
);
957 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
958 desc
->Type
= wined3d_desc
.resource_type
;
959 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
960 desc
->Pool
= wined3d_desc
.pool
;
961 desc
->Size
= wined3d_desc
.size
;
962 desc
->Width
= wined3d_desc
.width
;
963 desc
->Height
= wined3d_desc
.height
;
964 desc
->Depth
= wined3d_desc
.depth
;
966 wined3d_mutex_unlock();
971 static HRESULT WINAPI
d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8
*iface
,
972 UINT level
, IDirect3DVolume8
**volume
)
974 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
975 struct wined3d_resource
*sub_resource
;
976 struct d3d8_volume
*volume_impl
;
978 TRACE("iface %p, level %u, volume %p.\n", iface
, level
, volume
);
980 wined3d_mutex_lock();
981 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
983 wined3d_mutex_unlock();
984 return D3DERR_INVALIDCALL
;
987 volume_impl
= wined3d_resource_get_parent(sub_resource
);
988 *volume
= &volume_impl
->IDirect3DVolume8_iface
;
989 IDirect3DVolume8_AddRef(*volume
);
990 wined3d_mutex_unlock();
995 static HRESULT WINAPI
d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8
*iface
,
996 UINT level
, D3DLOCKED_BOX
*locked_box
, const D3DBOX
*box
, DWORD flags
)
998 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
999 struct wined3d_resource
*sub_resource
;
1000 struct d3d8_volume
*volume_impl
;
1003 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1004 iface
, level
, locked_box
, box
, flags
);
1006 wined3d_mutex_lock();
1007 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
1008 hr
= D3DERR_INVALIDCALL
;
1011 volume_impl
= wined3d_resource_get_parent(sub_resource
);
1012 hr
= IDirect3DVolume8_LockBox(&volume_impl
->IDirect3DVolume8_iface
, locked_box
, box
, flags
);
1014 wined3d_mutex_unlock();
1019 static HRESULT WINAPI
d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8
*iface
, UINT level
)
1021 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
1022 struct wined3d_resource
*sub_resource
;
1023 struct d3d8_volume
*volume_impl
;
1026 TRACE("iface %p, level %u.\n", iface
, level
);
1028 wined3d_mutex_lock();
1029 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
1030 hr
= D3DERR_INVALIDCALL
;
1033 volume_impl
= wined3d_resource_get_parent(sub_resource
);
1034 hr
= IDirect3DVolume8_UnlockBox(&volume_impl
->IDirect3DVolume8_iface
);
1036 wined3d_mutex_unlock();
1041 static HRESULT WINAPI
d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8
*iface
, const D3DBOX
*dirty_box
)
1043 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
1046 TRACE("iface %p, dirty_box %p.\n", iface
, dirty_box
);
1048 wined3d_mutex_lock();
1049 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, (const struct wined3d_box
*)dirty_box
);
1050 wined3d_mutex_unlock();
1055 static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl
=
1058 d3d8_texture_3d_QueryInterface
,
1059 d3d8_texture_3d_AddRef
,
1060 d3d8_texture_3d_Release
,
1061 /* IDirect3DResource8 */
1062 d3d8_texture_3d_GetDevice
,
1063 d3d8_texture_3d_SetPrivateData
,
1064 d3d8_texture_3d_GetPrivateData
,
1065 d3d8_texture_3d_FreePrivateData
,
1066 d3d8_texture_3d_SetPriority
,
1067 d3d8_texture_3d_GetPriority
,
1068 d3d8_texture_3d_PreLoad
,
1069 d3d8_texture_3d_GetType
,
1070 /* IDirect3DBaseTexture8 */
1071 d3d8_texture_3d_SetLOD
,
1072 d3d8_texture_3d_GetLOD
,
1073 d3d8_texture_3d_GetLevelCount
,
1074 /* IDirect3DVolumeTexture8 */
1075 d3d8_texture_3d_GetLevelDesc
,
1076 d3d8_texture_3d_GetVolumeLevel
,
1077 d3d8_texture_3d_LockBox
,
1078 d3d8_texture_3d_UnlockBox
,
1079 d3d8_texture_3d_AddDirtyBox
1082 struct d3d8_texture
*unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8
*iface
)
1087 /* SetTexture() in particular doesn't do a lot of validation on the pointer
1088 * that gets passed in, and passing an invalid pointer works as long as the
1089 * application doesn't try to actually render anything with it, so we print
1090 * a WARN and return NULL instead of having the usual assert() here.
1091 * One application affected by this is Fishdom 2. */
1092 if (iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DTexture8_Vtbl
1093 && iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DCubeTexture8_Vtbl
1094 && iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DVolumeTexture8_Vtbl
)
1096 WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface
);
1100 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
1103 static void STDMETHODCALLTYPE
d3d8_texture_wined3d_object_destroyed(void *parent
)
1105 struct d3d8_texture
*texture
= parent
;
1106 d3d8_resource_cleanup(&texture
->resource
);
1107 HeapFree(GetProcessHeap(), 0, texture
);
1110 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops
=
1112 d3d8_texture_wined3d_object_destroyed
,
1115 HRESULT
texture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1116 UINT width
, UINT height
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1118 struct wined3d_resource_desc desc
;
1119 DWORD surface_flags
= 0;
1122 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DTexture8_Vtbl
;
1123 d3d8_resource_init(&texture
->resource
);
1125 desc
.resource_type
= WINED3D_RTYPE_TEXTURE
;
1126 desc
.format
= wined3dformat_from_d3dformat(format
);
1127 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1128 desc
.multisample_quality
= 0;
1129 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1130 desc
.usage
|= WINED3DUSAGE_TEXTURE
;
1133 desc
.height
= height
;
1137 if (pool
!= D3DPOOL_DEFAULT
|| (usage
& D3DUSAGE_DYNAMIC
))
1138 surface_flags
|= WINED3D_SURFACE_MAPPABLE
;
1140 wined3d_mutex_lock();
1141 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, levels
, surface_flags
,
1142 texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1143 wined3d_mutex_unlock();
1146 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
1150 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1151 IDirect3DDevice8_AddRef(texture
->parent_device
);
1156 HRESULT
cubetexture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1157 UINT edge_length
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1159 struct wined3d_resource_desc desc
;
1160 DWORD surface_flags
= 0;
1163 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DCubeTexture8_Vtbl
;
1164 d3d8_resource_init(&texture
->resource
);
1166 desc
.resource_type
= WINED3D_RTYPE_CUBE_TEXTURE
;
1167 desc
.format
= wined3dformat_from_d3dformat(format
);
1168 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1169 desc
.multisample_quality
= 0;
1170 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1171 desc
.usage
|= WINED3DUSAGE_TEXTURE
;
1173 desc
.width
= edge_length
;
1174 desc
.height
= edge_length
;
1178 if (pool
!= D3DPOOL_DEFAULT
|| (usage
& D3DUSAGE_DYNAMIC
))
1179 surface_flags
|= WINED3D_SURFACE_MAPPABLE
;
1181 wined3d_mutex_lock();
1182 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, levels
, surface_flags
,
1183 texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1184 wined3d_mutex_unlock();
1187 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr
);
1191 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1192 IDirect3DDevice8_AddRef(texture
->parent_device
);
1197 HRESULT
volumetexture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1198 UINT width
, UINT height
, UINT depth
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1200 struct wined3d_resource_desc desc
;
1203 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DVolumeTexture8_Vtbl
;
1204 d3d8_resource_init(&texture
->resource
);
1206 desc
.resource_type
= WINED3D_RTYPE_VOLUME_TEXTURE
;
1207 desc
.format
= wined3dformat_from_d3dformat(format
);
1208 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1209 desc
.multisample_quality
= 0;
1210 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1211 desc
.usage
|= WINED3DUSAGE_TEXTURE
;
1214 desc
.height
= height
;
1218 wined3d_mutex_lock();
1219 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, levels
, 0,
1220 texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1221 wined3d_mutex_unlock();
1224 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr
);
1228 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1229 IDirect3DDevice8_AddRef(texture
->parent_device
);