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
19 #include "d3d8_private.h"
21 static inline struct d3d8_texture
*impl_from_IDirect3DTexture8(IDirect3DTexture8
*iface
)
23 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
26 static inline struct d3d8_texture
*impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8
*iface
)
28 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
31 static inline struct d3d8_texture
*impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8
*iface
)
33 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
36 static HRESULT WINAPI
d3d8_texture_2d_QueryInterface(IDirect3DTexture8
*iface
, REFIID riid
, void **out
)
38 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
40 if (IsEqualGUID(riid
, &IID_IDirect3DTexture8
)
41 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
42 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
43 || IsEqualGUID(riid
, &IID_IUnknown
))
45 IDirect3DTexture8_AddRef(iface
);
50 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
56 static ULONG WINAPI
d3d8_texture_2d_AddRef(IDirect3DTexture8
*iface
)
58 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
59 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
61 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
65 IDirect3DDevice8_AddRef(texture
->parent_device
);
67 wined3d_texture_incref(texture
->wined3d_texture
);
68 wined3d_mutex_unlock();
74 static ULONG WINAPI
d3d8_texture_2d_Release(IDirect3DTexture8
*iface
)
76 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
77 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
79 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
83 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
86 wined3d_texture_decref(texture
->wined3d_texture
);
87 wined3d_mutex_unlock();
89 /* Release the device last, as it may cause the device to be destroyed. */
90 IDirect3DDevice8_Release(parent_device
);
95 static HRESULT WINAPI
d3d8_texture_2d_GetDevice(IDirect3DTexture8
*iface
, IDirect3DDevice8
**device
)
97 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
99 TRACE("iface %p, device %p.\n", iface
, device
);
101 *device
= texture
->parent_device
;
102 IDirect3DDevice8_AddRef(*device
);
104 TRACE("Returning device %p.\n", *device
);
109 static HRESULT WINAPI
d3d8_texture_2d_SetPrivateData(IDirect3DTexture8
*iface
,
110 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
112 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
113 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
114 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
116 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
119 static HRESULT WINAPI
d3d8_texture_2d_GetPrivateData(IDirect3DTexture8
*iface
,
120 REFGUID guid
, void *data
, DWORD
*data_size
)
122 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
123 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
124 iface
, debugstr_guid(guid
), data
, data_size
);
126 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
129 static HRESULT WINAPI
d3d8_texture_2d_FreePrivateData(IDirect3DTexture8
*iface
, REFGUID guid
)
131 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
132 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
134 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
137 static DWORD WINAPI
d3d8_texture_2d_SetPriority(IDirect3DTexture8
*iface
, DWORD priority
)
139 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
142 TRACE("iface %p, priority %u.\n", iface
, priority
);
144 wined3d_mutex_lock();
145 ret
= wined3d_texture_set_priority(texture
->wined3d_texture
, priority
);
146 wined3d_mutex_unlock();
151 static DWORD WINAPI
d3d8_texture_2d_GetPriority(IDirect3DTexture8
*iface
)
153 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
156 TRACE("iface %p.\n", iface
);
158 wined3d_mutex_lock();
159 ret
= wined3d_texture_get_priority(texture
->wined3d_texture
);
160 wined3d_mutex_unlock();
165 static void WINAPI
d3d8_texture_2d_PreLoad(IDirect3DTexture8
*iface
)
167 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
169 TRACE("iface %p.\n", iface
);
171 wined3d_mutex_lock();
172 wined3d_texture_preload(texture
->wined3d_texture
);
173 wined3d_mutex_unlock();
176 static D3DRESOURCETYPE WINAPI
d3d8_texture_2d_GetType(IDirect3DTexture8
*iface
)
178 TRACE("iface %p.\n", iface
);
180 return D3DRTYPE_TEXTURE
;
183 static DWORD WINAPI
d3d8_texture_2d_SetLOD(IDirect3DTexture8
*iface
, DWORD lod
)
185 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
188 TRACE("iface %p, lod %u.\n", iface
, lod
);
190 wined3d_mutex_lock();
191 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
192 wined3d_mutex_unlock();
197 static DWORD WINAPI
d3d8_texture_2d_GetLOD(IDirect3DTexture8
*iface
)
199 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
202 TRACE("iface %p.\n", iface
);
204 wined3d_mutex_lock();
205 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
206 wined3d_mutex_unlock();
211 static DWORD WINAPI
d3d8_texture_2d_GetLevelCount(IDirect3DTexture8
*iface
)
213 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
216 TRACE("iface %p.\n", iface
);
218 wined3d_mutex_lock();
219 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
220 wined3d_mutex_unlock();
225 static HRESULT WINAPI
d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8
*iface
, UINT level
, D3DSURFACE_DESC
*desc
)
227 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
228 struct wined3d_resource
*sub_resource
;
231 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
233 wined3d_mutex_lock();
234 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
235 hr
= D3DERR_INVALIDCALL
;
238 struct wined3d_resource_desc wined3d_desc
;
240 wined3d_resource_get_desc(sub_resource
, &wined3d_desc
);
241 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
242 desc
->Type
= wined3d_desc
.resource_type
;
243 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
244 desc
->Pool
= wined3d_desc
.pool
;
245 desc
->Size
= wined3d_desc
.size
;
246 desc
->MultiSampleType
= wined3d_desc
.multisample_type
;
247 desc
->Width
= wined3d_desc
.width
;
248 desc
->Height
= wined3d_desc
.height
;
250 wined3d_mutex_unlock();
255 static HRESULT WINAPI
d3d8_texture_2d_GetSurfaceLevel(IDirect3DTexture8
*iface
,
256 UINT level
, IDirect3DSurface8
**surface
)
258 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
259 struct wined3d_resource
*sub_resource
;
260 struct d3d8_surface
*surface_impl
;
262 TRACE("iface %p, level %u, surface %p.\n", iface
, level
, surface
);
264 wined3d_mutex_lock();
265 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
267 wined3d_mutex_unlock();
268 return D3DERR_INVALIDCALL
;
271 surface_impl
= wined3d_resource_get_parent(sub_resource
);
272 *surface
= &surface_impl
->IDirect3DSurface8_iface
;
273 IDirect3DSurface8_AddRef(*surface
);
274 wined3d_mutex_unlock();
279 static HRESULT WINAPI
d3d8_texture_2d_LockRect(IDirect3DTexture8
*iface
, UINT level
,
280 D3DLOCKED_RECT
*locked_rect
, const RECT
*rect
, DWORD flags
)
282 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
283 struct wined3d_resource
*sub_resource
;
284 struct d3d8_surface
*surface_impl
;
287 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
288 iface
, level
, locked_rect
, rect
, flags
);
290 wined3d_mutex_lock();
291 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
292 hr
= D3DERR_INVALIDCALL
;
295 surface_impl
= wined3d_resource_get_parent(sub_resource
);
296 hr
= IDirect3DSurface8_LockRect(&surface_impl
->IDirect3DSurface8_iface
, locked_rect
, rect
, flags
);
298 wined3d_mutex_unlock();
303 static HRESULT WINAPI
d3d8_texture_2d_UnlockRect(IDirect3DTexture8
*iface
, UINT level
)
305 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
306 struct wined3d_resource
*sub_resource
;
307 struct d3d8_surface
*surface_impl
;
310 TRACE("iface %p, level %u.\n", iface
, level
);
312 wined3d_mutex_lock();
313 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
314 hr
= D3DERR_INVALIDCALL
;
317 surface_impl
= wined3d_resource_get_parent(sub_resource
);
318 hr
= IDirect3DSurface8_UnlockRect(&surface_impl
->IDirect3DSurface8_iface
);
320 wined3d_mutex_unlock();
325 static HRESULT WINAPI
d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8
*iface
, const RECT
*dirty_rect
)
327 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
330 TRACE("iface %p, dirty_rect %s.\n",
331 iface
, wine_dbgstr_rect(dirty_rect
));
333 wined3d_mutex_lock();
335 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, NULL
);
338 struct wined3d_box dirty_region
;
340 dirty_region
.left
= dirty_rect
->left
;
341 dirty_region
.top
= dirty_rect
->top
;
342 dirty_region
.right
= dirty_rect
->right
;
343 dirty_region
.bottom
= dirty_rect
->bottom
;
344 dirty_region
.front
= 0;
345 dirty_region
.back
= 1;
346 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, &dirty_region
);
348 wined3d_mutex_unlock();
353 static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl
=
356 d3d8_texture_2d_QueryInterface
,
357 d3d8_texture_2d_AddRef
,
358 d3d8_texture_2d_Release
,
359 /* IDirect3DResource8 */
360 d3d8_texture_2d_GetDevice
,
361 d3d8_texture_2d_SetPrivateData
,
362 d3d8_texture_2d_GetPrivateData
,
363 d3d8_texture_2d_FreePrivateData
,
364 d3d8_texture_2d_SetPriority
,
365 d3d8_texture_2d_GetPriority
,
366 d3d8_texture_2d_PreLoad
,
367 d3d8_texture_2d_GetType
,
368 /* IDirect3dBaseTexture8 */
369 d3d8_texture_2d_SetLOD
,
370 d3d8_texture_2d_GetLOD
,
371 d3d8_texture_2d_GetLevelCount
,
372 /* IDirect3DTexture8 */
373 d3d8_texture_2d_GetLevelDesc
,
374 d3d8_texture_2d_GetSurfaceLevel
,
375 d3d8_texture_2d_LockRect
,
376 d3d8_texture_2d_UnlockRect
,
377 d3d8_texture_2d_AddDirtyRect
,
380 static HRESULT WINAPI
d3d8_texture_cube_QueryInterface(IDirect3DCubeTexture8
*iface
, REFIID riid
, void **out
)
382 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
384 if (IsEqualGUID(riid
, &IID_IDirect3DCubeTexture8
)
385 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
386 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
387 || IsEqualGUID(riid
, &IID_IUnknown
))
389 IDirect3DCubeTexture8_AddRef(iface
);
394 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
397 return E_NOINTERFACE
;
400 static ULONG WINAPI
d3d8_texture_cube_AddRef(IDirect3DCubeTexture8
*iface
)
402 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
403 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
405 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
409 IDirect3DDevice8_AddRef(texture
->parent_device
);
410 wined3d_mutex_lock();
411 wined3d_texture_incref(texture
->wined3d_texture
);
412 wined3d_mutex_unlock();
418 static ULONG WINAPI
d3d8_texture_cube_Release(IDirect3DCubeTexture8
*iface
)
420 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
421 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
423 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
427 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
429 TRACE("Releasing child %p.\n", texture
->wined3d_texture
);
431 wined3d_mutex_lock();
432 wined3d_texture_decref(texture
->wined3d_texture
);
433 wined3d_mutex_unlock();
435 /* Release the device last, as it may cause the device to be destroyed. */
436 IDirect3DDevice8_Release(parent_device
);
441 static HRESULT WINAPI
d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8
*iface
, IDirect3DDevice8
**device
)
443 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
445 TRACE("iface %p, device %p.\n", iface
, device
);
447 *device
= texture
->parent_device
;
448 IDirect3DDevice8_AddRef(*device
);
450 TRACE("Returning device %p.\n", *device
);
455 static HRESULT WINAPI
d3d8_texture_cube_SetPrivateData(IDirect3DCubeTexture8
*iface
,
456 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
458 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
459 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
460 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
462 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
465 static HRESULT WINAPI
d3d8_texture_cube_GetPrivateData(IDirect3DCubeTexture8
*iface
,
466 REFGUID guid
, void *data
, DWORD
*data_size
)
468 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
469 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
470 iface
, debugstr_guid(guid
), data
, data_size
);
472 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
475 static HRESULT WINAPI
d3d8_texture_cube_FreePrivateData(IDirect3DCubeTexture8
*iface
, REFGUID guid
)
477 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
478 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
480 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
483 static DWORD WINAPI
d3d8_texture_cube_SetPriority(IDirect3DCubeTexture8
*iface
, DWORD priority
)
485 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
488 TRACE("iface %p, priority %u.\n", iface
, priority
);
490 wined3d_mutex_lock();
491 ret
= wined3d_texture_set_priority(texture
->wined3d_texture
, priority
);
492 wined3d_mutex_unlock();
497 static DWORD WINAPI
d3d8_texture_cube_GetPriority(IDirect3DCubeTexture8
*iface
)
499 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
502 TRACE("iface %p.\n", iface
);
504 wined3d_mutex_lock();
505 ret
= wined3d_texture_get_priority(texture
->wined3d_texture
);
506 wined3d_mutex_unlock();
511 static void WINAPI
d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8
*iface
)
513 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
515 TRACE("iface %p.\n", iface
);
517 wined3d_mutex_lock();
518 wined3d_texture_preload(texture
->wined3d_texture
);
519 wined3d_mutex_unlock();
522 static D3DRESOURCETYPE WINAPI
d3d8_texture_cube_GetType(IDirect3DCubeTexture8
*iface
)
524 TRACE("iface %p.\n", iface
);
526 return D3DRTYPE_CUBETEXTURE
;
529 static DWORD WINAPI
d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8
*iface
, DWORD lod
)
531 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
534 TRACE("iface %p, lod %u.\n", iface
, lod
);
536 wined3d_mutex_lock();
537 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
538 wined3d_mutex_unlock();
543 static DWORD WINAPI
d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8
*iface
)
545 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
548 TRACE("iface %p.\n", iface
);
550 wined3d_mutex_lock();
551 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
552 wined3d_mutex_unlock();
557 static DWORD WINAPI
d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8
*iface
)
559 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
562 TRACE("iface %p.\n", iface
);
564 wined3d_mutex_lock();
565 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
566 wined3d_mutex_unlock();
571 static HRESULT WINAPI
d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8
*iface
, UINT level
, D3DSURFACE_DESC
*desc
)
573 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
574 struct wined3d_resource
*sub_resource
;
577 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
579 wined3d_mutex_lock();
580 if (level
>= wined3d_texture_get_level_count(texture
->wined3d_texture
))
582 wined3d_mutex_unlock();
583 return D3DERR_INVALIDCALL
;
586 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
587 hr
= D3DERR_INVALIDCALL
;
590 struct wined3d_resource_desc wined3d_desc
;
592 wined3d_resource_get_desc(sub_resource
, &wined3d_desc
);
593 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
594 desc
->Type
= wined3d_desc
.resource_type
;
595 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
596 desc
->Pool
= wined3d_desc
.pool
;
597 desc
->Size
= wined3d_desc
.size
;
598 desc
->MultiSampleType
= wined3d_desc
.multisample_type
;
599 desc
->Width
= wined3d_desc
.width
;
600 desc
->Height
= wined3d_desc
.height
;
602 wined3d_mutex_unlock();
607 static HRESULT WINAPI
d3d8_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture8
*iface
,
608 D3DCUBEMAP_FACES face
, UINT level
, IDirect3DSurface8
**surface
)
610 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
611 struct wined3d_resource
*sub_resource
;
612 struct d3d8_surface
*surface_impl
;
613 UINT sub_resource_idx
;
616 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface
, face
, level
, surface
);
618 wined3d_mutex_lock();
619 level_count
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
620 if (level
>= level_count
)
622 wined3d_mutex_unlock();
623 return D3DERR_INVALIDCALL
;
626 sub_resource_idx
= level_count
* face
+ level
;
627 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, sub_resource_idx
)))
629 wined3d_mutex_unlock();
630 return D3DERR_INVALIDCALL
;
633 surface_impl
= wined3d_resource_get_parent(sub_resource
);
634 *surface
= &surface_impl
->IDirect3DSurface8_iface
;
635 IDirect3DSurface8_AddRef(*surface
);
636 wined3d_mutex_unlock();
641 static HRESULT WINAPI
d3d8_texture_cube_LockRect(IDirect3DCubeTexture8
*iface
,
642 D3DCUBEMAP_FACES face
, UINT level
, D3DLOCKED_RECT
*locked_rect
, const RECT
*rect
,
645 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
646 struct wined3d_resource
*sub_resource
;
647 struct d3d8_surface
*surface_impl
;
648 UINT sub_resource_idx
;
651 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
652 iface
, face
, level
, locked_rect
, rect
, flags
);
654 wined3d_mutex_lock();
655 sub_resource_idx
= wined3d_texture_get_level_count(texture
->wined3d_texture
) * face
+ level
;
656 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, sub_resource_idx
)))
657 hr
= D3DERR_INVALIDCALL
;
660 surface_impl
= wined3d_resource_get_parent(sub_resource
);
661 hr
= IDirect3DSurface8_LockRect(&surface_impl
->IDirect3DSurface8_iface
, locked_rect
, rect
, flags
);
663 wined3d_mutex_unlock();
668 static HRESULT WINAPI
d3d8_texture_cube_UnlockRect(IDirect3DCubeTexture8
*iface
,
669 D3DCUBEMAP_FACES face
, UINT level
)
671 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
672 struct wined3d_resource
*sub_resource
;
673 struct d3d8_surface
*surface_impl
;
674 UINT sub_resource_idx
;
677 TRACE("iface %p, face %#x, level %u.\n", iface
, face
, level
);
679 wined3d_mutex_lock();
680 sub_resource_idx
= wined3d_texture_get_level_count(texture
->wined3d_texture
) * face
+ level
;
681 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, sub_resource_idx
)))
682 hr
= D3DERR_INVALIDCALL
;
685 surface_impl
= wined3d_resource_get_parent(sub_resource
);
686 hr
= IDirect3DSurface8_UnlockRect(&surface_impl
->IDirect3DSurface8_iface
);
688 wined3d_mutex_unlock();
693 static HRESULT WINAPI
d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8
*iface
,
694 D3DCUBEMAP_FACES face
, const RECT
*dirty_rect
)
696 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
699 TRACE("iface %p, face %#x, dirty_rect %s.\n",
700 iface
, face
, wine_dbgstr_rect(dirty_rect
));
702 wined3d_mutex_lock();
704 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, face
, NULL
);
707 struct wined3d_box dirty_region
;
709 dirty_region
.left
= dirty_rect
->left
;
710 dirty_region
.top
= dirty_rect
->top
;
711 dirty_region
.right
= dirty_rect
->right
;
712 dirty_region
.bottom
= dirty_rect
->bottom
;
713 dirty_region
.front
= 0;
714 dirty_region
.back
= 1;
715 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, face
, &dirty_region
);
717 wined3d_mutex_unlock();
722 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl
=
725 d3d8_texture_cube_QueryInterface
,
726 d3d8_texture_cube_AddRef
,
727 d3d8_texture_cube_Release
,
728 /* IDirect3DResource8 */
729 d3d8_texture_cube_GetDevice
,
730 d3d8_texture_cube_SetPrivateData
,
731 d3d8_texture_cube_GetPrivateData
,
732 d3d8_texture_cube_FreePrivateData
,
733 d3d8_texture_cube_SetPriority
,
734 d3d8_texture_cube_GetPriority
,
735 d3d8_texture_cube_PreLoad
,
736 d3d8_texture_cube_GetType
,
737 /* IDirect3DBaseTexture8 */
738 d3d8_texture_cube_SetLOD
,
739 d3d8_texture_cube_GetLOD
,
740 d3d8_texture_cube_GetLevelCount
,
741 /* IDirect3DCubeTexture8 */
742 d3d8_texture_cube_GetLevelDesc
,
743 d3d8_texture_cube_GetCubeMapSurface
,
744 d3d8_texture_cube_LockRect
,
745 d3d8_texture_cube_UnlockRect
,
746 d3d8_texture_cube_AddDirtyRect
,
749 static HRESULT WINAPI
d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8
*iface
, REFIID riid
, void **out
)
751 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
753 if (IsEqualGUID(riid
, &IID_IDirect3DVolumeTexture8
)
754 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
755 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
756 || IsEqualGUID(riid
, &IID_IUnknown
))
758 IDirect3DVolumeTexture8_AddRef(iface
);
763 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
766 return E_NOINTERFACE
;
769 static ULONG WINAPI
d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8
*iface
)
771 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
772 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
774 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
778 IDirect3DDevice8_AddRef(texture
->parent_device
);
779 wined3d_mutex_lock();
780 wined3d_texture_incref(texture
->wined3d_texture
);
781 wined3d_mutex_unlock();
787 static ULONG WINAPI
d3d8_texture_3d_Release(IDirect3DVolumeTexture8
*iface
)
789 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
790 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
792 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
796 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
798 wined3d_mutex_lock();
799 wined3d_texture_decref(texture
->wined3d_texture
);
800 wined3d_mutex_unlock();
802 /* Release the device last, as it may cause the device to be destroyed. */
803 IDirect3DDevice8_Release(parent_device
);
808 static HRESULT WINAPI
d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8
*iface
, IDirect3DDevice8
**device
)
810 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
812 TRACE("iface %p, device %p.\n", iface
, device
);
814 *device
= texture
->parent_device
;
815 IDirect3DDevice8_AddRef(*device
);
817 TRACE("Returning device %p.\n", *device
);
822 static HRESULT WINAPI
d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8
*iface
,
823 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
825 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
826 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
827 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
829 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
832 static HRESULT WINAPI
d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8
*iface
,
833 REFGUID guid
, void *data
, DWORD
*data_size
)
835 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
836 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
837 iface
, debugstr_guid(guid
), data
, data_size
);
839 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
842 static HRESULT WINAPI
d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8
*iface
, REFGUID guid
)
844 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
845 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
847 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
850 static DWORD WINAPI
d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8
*iface
, DWORD priority
)
852 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
855 TRACE("iface %p, priority %u.\n", iface
, priority
);
857 wined3d_mutex_lock();
858 ret
= wined3d_texture_set_priority(texture
->wined3d_texture
, priority
);
859 wined3d_mutex_unlock();
864 static DWORD WINAPI
d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8
*iface
)
866 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
869 TRACE("iface %p.\n", iface
);
871 wined3d_mutex_lock();
872 ret
= wined3d_texture_get_priority(texture
->wined3d_texture
);
873 wined3d_mutex_unlock();
878 static void WINAPI
d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8
*iface
)
880 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
882 TRACE("iface %p.\n", iface
);
884 wined3d_mutex_lock();
885 wined3d_texture_preload(texture
->wined3d_texture
);
886 wined3d_mutex_unlock();
889 static D3DRESOURCETYPE WINAPI
d3d8_texture_3d_GetType(IDirect3DVolumeTexture8
*iface
)
891 TRACE("iface %p.\n", iface
);
893 return D3DRTYPE_VOLUMETEXTURE
;
896 static DWORD WINAPI
d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8
*iface
, DWORD lod
)
898 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
901 TRACE("iface %p, lod %u.\n", iface
, lod
);
903 wined3d_mutex_lock();
904 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
905 wined3d_mutex_unlock();
910 static DWORD WINAPI
d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8
*iface
)
912 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
915 TRACE("iface %p.\n", iface
);
917 wined3d_mutex_lock();
918 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
919 wined3d_mutex_unlock();
924 static DWORD WINAPI
d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8
*iface
)
926 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
929 TRACE("iface %p.\n", iface
);
931 wined3d_mutex_lock();
932 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
933 wined3d_mutex_unlock();
938 static HRESULT WINAPI
d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8
*iface
, UINT level
, D3DVOLUME_DESC
*desc
)
940 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
941 struct wined3d_resource
*sub_resource
;
944 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
946 wined3d_mutex_lock();
947 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
948 hr
= D3DERR_INVALIDCALL
;
951 struct wined3d_resource_desc wined3d_desc
;
953 wined3d_resource_get_desc(sub_resource
, &wined3d_desc
);
954 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
955 desc
->Type
= wined3d_desc
.resource_type
;
956 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
957 desc
->Pool
= wined3d_desc
.pool
;
958 desc
->Size
= wined3d_desc
.size
;
959 desc
->Width
= wined3d_desc
.width
;
960 desc
->Height
= wined3d_desc
.height
;
961 desc
->Depth
= wined3d_desc
.depth
;
963 wined3d_mutex_unlock();
968 static HRESULT WINAPI
d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8
*iface
,
969 UINT level
, IDirect3DVolume8
**volume
)
971 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
972 struct wined3d_resource
*sub_resource
;
973 struct d3d8_volume
*volume_impl
;
975 TRACE("iface %p, level %u, volume %p.\n", iface
, level
, volume
);
977 wined3d_mutex_lock();
978 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
980 wined3d_mutex_unlock();
981 return D3DERR_INVALIDCALL
;
984 volume_impl
= wined3d_resource_get_parent(sub_resource
);
985 *volume
= &volume_impl
->IDirect3DVolume8_iface
;
986 IDirect3DVolume8_AddRef(*volume
);
987 wined3d_mutex_unlock();
992 static HRESULT WINAPI
d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8
*iface
,
993 UINT level
, D3DLOCKED_BOX
*locked_box
, const D3DBOX
*box
, DWORD flags
)
995 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
996 struct wined3d_resource
*sub_resource
;
997 struct d3d8_volume
*volume_impl
;
1000 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1001 iface
, level
, locked_box
, box
, flags
);
1003 wined3d_mutex_lock();
1004 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
1005 hr
= D3DERR_INVALIDCALL
;
1008 volume_impl
= wined3d_resource_get_parent(sub_resource
);
1009 hr
= IDirect3DVolume8_LockBox(&volume_impl
->IDirect3DVolume8_iface
, locked_box
, box
, flags
);
1011 wined3d_mutex_unlock();
1016 static HRESULT WINAPI
d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8
*iface
, UINT level
)
1018 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
1019 struct wined3d_resource
*sub_resource
;
1020 struct d3d8_volume
*volume_impl
;
1023 TRACE("iface %p, level %u.\n", iface
, level
);
1025 wined3d_mutex_lock();
1026 if (!(sub_resource
= wined3d_texture_get_sub_resource(texture
->wined3d_texture
, level
)))
1027 hr
= D3DERR_INVALIDCALL
;
1030 volume_impl
= wined3d_resource_get_parent(sub_resource
);
1031 hr
= IDirect3DVolume8_UnlockBox(&volume_impl
->IDirect3DVolume8_iface
);
1033 wined3d_mutex_unlock();
1038 static HRESULT WINAPI
d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8
*iface
, const D3DBOX
*dirty_box
)
1040 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
1043 TRACE("iface %p, dirty_box %p.\n", iface
, dirty_box
);
1045 wined3d_mutex_lock();
1046 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, (const struct wined3d_box
*)dirty_box
);
1047 wined3d_mutex_unlock();
1052 static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl
=
1055 d3d8_texture_3d_QueryInterface
,
1056 d3d8_texture_3d_AddRef
,
1057 d3d8_texture_3d_Release
,
1058 /* IDirect3DResource8 */
1059 d3d8_texture_3d_GetDevice
,
1060 d3d8_texture_3d_SetPrivateData
,
1061 d3d8_texture_3d_GetPrivateData
,
1062 d3d8_texture_3d_FreePrivateData
,
1063 d3d8_texture_3d_SetPriority
,
1064 d3d8_texture_3d_GetPriority
,
1065 d3d8_texture_3d_PreLoad
,
1066 d3d8_texture_3d_GetType
,
1067 /* IDirect3DBaseTexture8 */
1068 d3d8_texture_3d_SetLOD
,
1069 d3d8_texture_3d_GetLOD
,
1070 d3d8_texture_3d_GetLevelCount
,
1071 /* IDirect3DVolumeTexture8 */
1072 d3d8_texture_3d_GetLevelDesc
,
1073 d3d8_texture_3d_GetVolumeLevel
,
1074 d3d8_texture_3d_LockBox
,
1075 d3d8_texture_3d_UnlockBox
,
1076 d3d8_texture_3d_AddDirtyBox
1079 struct d3d8_texture
*unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8
*iface
)
1084 /* SetTexture() in particular doesn't do a lot of validation on the pointer
1085 * that gets passed in, and passing an invalid pointer works as long as the
1086 * application doesn't try to actually render anything with it, so we print
1087 * a WARN and return NULL instead of having the usual assert() here.
1088 * One application affected by this is Fishdom 2. */
1089 if (iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DTexture8_Vtbl
1090 && iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DCubeTexture8_Vtbl
1091 && iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DVolumeTexture8_Vtbl
)
1093 WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface
);
1097 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
1100 static void STDMETHODCALLTYPE
d3d8_texture_wined3d_object_destroyed(void *parent
)
1102 struct d3d8_texture
*texture
= parent
;
1103 d3d8_resource_cleanup(&texture
->resource
);
1104 HeapFree(GetProcessHeap(), 0, texture
);
1107 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops
=
1109 d3d8_texture_wined3d_object_destroyed
,
1112 HRESULT
texture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1113 UINT width
, UINT height
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1115 struct wined3d_resource_desc desc
;
1116 DWORD surface_flags
= 0;
1119 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DTexture8_Vtbl
;
1120 d3d8_resource_init(&texture
->resource
);
1122 desc
.resource_type
= WINED3D_RTYPE_TEXTURE
;
1123 desc
.format
= wined3dformat_from_d3dformat(format
);
1124 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1125 desc
.multisample_quality
= 0;
1126 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1127 desc
.usage
|= WINED3DUSAGE_TEXTURE
;
1130 desc
.height
= height
;
1134 if (pool
!= D3DPOOL_DEFAULT
|| (usage
& D3DUSAGE_DYNAMIC
))
1135 surface_flags
|= WINED3D_SURFACE_MAPPABLE
;
1137 wined3d_mutex_lock();
1138 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, levels
, surface_flags
,
1139 texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1140 wined3d_mutex_unlock();
1143 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
1147 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1148 IDirect3DDevice8_AddRef(texture
->parent_device
);
1153 HRESULT
cubetexture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1154 UINT edge_length
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1156 struct wined3d_resource_desc desc
;
1157 DWORD surface_flags
= 0;
1160 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DCubeTexture8_Vtbl
;
1161 d3d8_resource_init(&texture
->resource
);
1163 desc
.resource_type
= WINED3D_RTYPE_CUBE_TEXTURE
;
1164 desc
.format
= wined3dformat_from_d3dformat(format
);
1165 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1166 desc
.multisample_quality
= 0;
1167 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1168 desc
.usage
|= WINED3DUSAGE_TEXTURE
;
1170 desc
.width
= edge_length
;
1171 desc
.height
= edge_length
;
1175 if (pool
!= D3DPOOL_DEFAULT
|| (usage
& D3DUSAGE_DYNAMIC
))
1176 surface_flags
|= WINED3D_SURFACE_MAPPABLE
;
1178 wined3d_mutex_lock();
1179 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, levels
, surface_flags
,
1180 texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1181 wined3d_mutex_unlock();
1184 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr
);
1188 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1189 IDirect3DDevice8_AddRef(texture
->parent_device
);
1194 HRESULT
volumetexture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1195 UINT width
, UINT height
, UINT depth
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1197 struct wined3d_resource_desc desc
;
1200 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DVolumeTexture8_Vtbl
;
1201 d3d8_resource_init(&texture
->resource
);
1203 desc
.resource_type
= WINED3D_RTYPE_VOLUME_TEXTURE
;
1204 desc
.format
= wined3dformat_from_d3dformat(format
);
1205 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1206 desc
.multisample_quality
= 0;
1207 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1208 desc
.usage
|= WINED3DUSAGE_TEXTURE
;
1211 desc
.height
= height
;
1215 wined3d_mutex_lock();
1216 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, levels
, 0,
1217 texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1218 wined3d_mutex_unlock();
1221 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr
);
1225 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1226 IDirect3DDevice8_AddRef(texture
->parent_device
);