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 WINE_DEFAULT_DEBUG_CHANNEL(d3d8
);
23 static inline struct d3d8_texture
*impl_from_IDirect3DTexture8(IDirect3DTexture8
*iface
)
25 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
28 static inline struct d3d8_texture
*impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8
*iface
)
30 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
33 static inline struct d3d8_texture
*impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8
*iface
)
35 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
38 static HRESULT WINAPI
d3d8_texture_2d_QueryInterface(IDirect3DTexture8
*iface
, REFIID riid
, void **out
)
40 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
42 if (IsEqualGUID(riid
, &IID_IDirect3DTexture8
)
43 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
44 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
45 || IsEqualGUID(riid
, &IID_IUnknown
))
47 IDirect3DTexture8_AddRef(iface
);
52 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
58 static ULONG WINAPI
d3d8_texture_2d_AddRef(IDirect3DTexture8
*iface
)
60 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
61 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
63 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
67 struct d3d8_surface
*surface
;
69 IDirect3DDevice8_AddRef(texture
->parent_device
);
71 LIST_FOR_EACH_ENTRY(surface
, &texture
->rtv_list
, struct d3d8_surface
, rtv_entry
)
73 wined3d_rendertarget_view_incref(surface
->wined3d_rtv
);
75 wined3d_texture_incref(texture
->wined3d_texture
);
76 wined3d_mutex_unlock();
82 static ULONG WINAPI
d3d8_texture_2d_Release(IDirect3DTexture8
*iface
)
84 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
85 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
87 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
91 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
92 struct d3d8_surface
*surface
;
95 LIST_FOR_EACH_ENTRY(surface
, &texture
->rtv_list
, struct d3d8_surface
, rtv_entry
)
97 wined3d_rendertarget_view_decref(surface
->wined3d_rtv
);
99 wined3d_texture_decref(texture
->wined3d_texture
);
100 wined3d_mutex_unlock();
102 /* Release the device last, as it may cause the device to be destroyed. */
103 IDirect3DDevice8_Release(parent_device
);
108 static HRESULT WINAPI
d3d8_texture_2d_GetDevice(IDirect3DTexture8
*iface
, IDirect3DDevice8
**device
)
110 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
112 TRACE("iface %p, device %p.\n", iface
, device
);
114 *device
= texture
->parent_device
;
115 IDirect3DDevice8_AddRef(*device
);
117 TRACE("Returning device %p.\n", *device
);
122 static HRESULT WINAPI
d3d8_texture_2d_SetPrivateData(IDirect3DTexture8
*iface
,
123 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
125 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
126 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
127 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
129 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
132 static HRESULT WINAPI
d3d8_texture_2d_GetPrivateData(IDirect3DTexture8
*iface
,
133 REFGUID guid
, void *data
, DWORD
*data_size
)
135 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
136 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
137 iface
, debugstr_guid(guid
), data
, data_size
);
139 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
142 static HRESULT WINAPI
d3d8_texture_2d_FreePrivateData(IDirect3DTexture8
*iface
, REFGUID guid
)
144 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
145 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
147 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
150 static DWORD WINAPI
d3d8_texture_2d_SetPriority(IDirect3DTexture8
*iface
, DWORD priority
)
152 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
153 struct wined3d_resource
*resource
;
156 TRACE("iface %p, priority %u.\n", iface
, priority
);
158 wined3d_mutex_lock();
159 resource
= wined3d_texture_get_resource(texture
->wined3d_texture
);
160 ret
= wined3d_resource_set_priority(resource
, priority
);
161 wined3d_mutex_unlock();
166 static DWORD WINAPI
d3d8_texture_2d_GetPriority(IDirect3DTexture8
*iface
)
168 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
169 const struct wined3d_resource
*resource
;
172 TRACE("iface %p.\n", iface
);
174 wined3d_mutex_lock();
175 resource
= wined3d_texture_get_resource(texture
->wined3d_texture
);
176 ret
= wined3d_resource_get_priority(resource
);
177 wined3d_mutex_unlock();
182 static void WINAPI
d3d8_texture_2d_PreLoad(IDirect3DTexture8
*iface
)
184 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
186 TRACE("iface %p.\n", iface
);
188 wined3d_mutex_lock();
189 wined3d_resource_preload(wined3d_texture_get_resource(texture
->wined3d_texture
));
190 wined3d_mutex_unlock();
193 static D3DRESOURCETYPE WINAPI
d3d8_texture_2d_GetType(IDirect3DTexture8
*iface
)
195 TRACE("iface %p.\n", iface
);
197 return D3DRTYPE_TEXTURE
;
200 static DWORD WINAPI
d3d8_texture_2d_SetLOD(IDirect3DTexture8
*iface
, DWORD lod
)
202 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
205 TRACE("iface %p, lod %u.\n", iface
, lod
);
207 wined3d_mutex_lock();
208 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
209 wined3d_mutex_unlock();
214 static DWORD WINAPI
d3d8_texture_2d_GetLOD(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_lod(texture
->wined3d_texture
);
223 wined3d_mutex_unlock();
228 static DWORD WINAPI
d3d8_texture_2d_GetLevelCount(IDirect3DTexture8
*iface
)
230 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
233 TRACE("iface %p.\n", iface
);
235 wined3d_mutex_lock();
236 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
237 wined3d_mutex_unlock();
242 static HRESULT WINAPI
d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8
*iface
, UINT level
, D3DSURFACE_DESC
*desc
)
244 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
245 struct wined3d_sub_resource_desc wined3d_desc
;
248 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
250 wined3d_mutex_lock();
251 if (SUCCEEDED(hr
= wined3d_texture_get_sub_resource_desc(texture
->wined3d_texture
, level
, &wined3d_desc
)))
253 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
254 desc
->Type
= D3DRTYPE_SURFACE
;
255 desc
->Usage
= d3dusage_from_wined3dusage(wined3d_desc
.usage
, wined3d_desc
.bind_flags
);
256 desc
->Pool
= d3dpool_from_wined3daccess(wined3d_desc
.access
, wined3d_desc
.usage
);
257 desc
->Size
= wined3d_desc
.size
;
258 desc
->MultiSampleType
= d3dmultisample_type_from_wined3d(wined3d_desc
.multisample_type
);
259 desc
->Width
= wined3d_desc
.width
;
260 desc
->Height
= wined3d_desc
.height
;
262 wined3d_mutex_unlock();
267 static HRESULT WINAPI
d3d8_texture_2d_GetSurfaceLevel(IDirect3DTexture8
*iface
,
268 UINT level
, IDirect3DSurface8
**surface
)
270 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
271 struct d3d8_surface
*surface_impl
;
273 TRACE("iface %p, level %u, surface %p.\n", iface
, level
, surface
);
275 wined3d_mutex_lock();
276 if (!(surface_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, level
)))
278 wined3d_mutex_unlock();
279 return D3DERR_INVALIDCALL
;
282 *surface
= &surface_impl
->IDirect3DSurface8_iface
;
283 IDirect3DSurface8_AddRef(*surface
);
284 wined3d_mutex_unlock();
289 static HRESULT WINAPI
d3d8_texture_2d_LockRect(IDirect3DTexture8
*iface
, UINT level
,
290 D3DLOCKED_RECT
*locked_rect
, const RECT
*rect
, DWORD flags
)
292 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
293 struct d3d8_surface
*surface_impl
;
296 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
297 iface
, level
, locked_rect
, rect
, flags
);
299 wined3d_mutex_lock();
300 if (!(surface_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, level
)))
301 hr
= D3DERR_INVALIDCALL
;
303 hr
= IDirect3DSurface8_LockRect(&surface_impl
->IDirect3DSurface8_iface
, locked_rect
, rect
, flags
);
304 wined3d_mutex_unlock();
309 static HRESULT WINAPI
d3d8_texture_2d_UnlockRect(IDirect3DTexture8
*iface
, UINT level
)
311 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
312 struct d3d8_surface
*surface_impl
;
315 TRACE("iface %p, level %u.\n", iface
, level
);
317 wined3d_mutex_lock();
318 if (!(surface_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, level
)))
319 hr
= D3DERR_INVALIDCALL
;
321 hr
= IDirect3DSurface8_UnlockRect(&surface_impl
->IDirect3DSurface8_iface
);
322 wined3d_mutex_unlock();
327 static HRESULT WINAPI
d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8
*iface
, const RECT
*dirty_rect
)
329 struct d3d8_texture
*texture
= impl_from_IDirect3DTexture8(iface
);
332 TRACE("iface %p, dirty_rect %s.\n",
333 iface
, wine_dbgstr_rect(dirty_rect
));
335 wined3d_mutex_lock();
337 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, NULL
);
340 struct wined3d_box dirty_region
;
342 wined3d_box_set(&dirty_region
, dirty_rect
->left
, dirty_rect
->top
, dirty_rect
->right
, dirty_rect
->bottom
, 0, 1);
343 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, &dirty_region
);
345 wined3d_mutex_unlock();
350 static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl
=
353 d3d8_texture_2d_QueryInterface
,
354 d3d8_texture_2d_AddRef
,
355 d3d8_texture_2d_Release
,
356 /* IDirect3DResource8 */
357 d3d8_texture_2d_GetDevice
,
358 d3d8_texture_2d_SetPrivateData
,
359 d3d8_texture_2d_GetPrivateData
,
360 d3d8_texture_2d_FreePrivateData
,
361 d3d8_texture_2d_SetPriority
,
362 d3d8_texture_2d_GetPriority
,
363 d3d8_texture_2d_PreLoad
,
364 d3d8_texture_2d_GetType
,
365 /* IDirect3dBaseTexture8 */
366 d3d8_texture_2d_SetLOD
,
367 d3d8_texture_2d_GetLOD
,
368 d3d8_texture_2d_GetLevelCount
,
369 /* IDirect3DTexture8 */
370 d3d8_texture_2d_GetLevelDesc
,
371 d3d8_texture_2d_GetSurfaceLevel
,
372 d3d8_texture_2d_LockRect
,
373 d3d8_texture_2d_UnlockRect
,
374 d3d8_texture_2d_AddDirtyRect
,
377 static HRESULT WINAPI
d3d8_texture_cube_QueryInterface(IDirect3DCubeTexture8
*iface
, REFIID riid
, void **out
)
379 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
381 if (IsEqualGUID(riid
, &IID_IDirect3DCubeTexture8
)
382 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
383 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
384 || IsEqualGUID(riid
, &IID_IUnknown
))
386 IDirect3DCubeTexture8_AddRef(iface
);
391 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
394 return E_NOINTERFACE
;
397 static ULONG WINAPI
d3d8_texture_cube_AddRef(IDirect3DCubeTexture8
*iface
)
399 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
400 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
402 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
406 struct d3d8_surface
*surface
;
408 IDirect3DDevice8_AddRef(texture
->parent_device
);
409 wined3d_mutex_lock();
410 LIST_FOR_EACH_ENTRY(surface
, &texture
->rtv_list
, struct d3d8_surface
, rtv_entry
)
412 wined3d_rendertarget_view_incref(surface
->wined3d_rtv
);
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
;
431 struct d3d8_surface
*surface
;
433 TRACE("Releasing child %p.\n", texture
->wined3d_texture
);
435 wined3d_mutex_lock();
436 LIST_FOR_EACH_ENTRY(surface
, &texture
->rtv_list
, struct d3d8_surface
, rtv_entry
)
438 wined3d_rendertarget_view_decref(surface
->wined3d_rtv
);
440 wined3d_texture_decref(texture
->wined3d_texture
);
441 wined3d_mutex_unlock();
443 /* Release the device last, as it may cause the device to be destroyed. */
444 IDirect3DDevice8_Release(parent_device
);
449 static HRESULT WINAPI
d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8
*iface
, IDirect3DDevice8
**device
)
451 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
453 TRACE("iface %p, device %p.\n", iface
, device
);
455 *device
= texture
->parent_device
;
456 IDirect3DDevice8_AddRef(*device
);
458 TRACE("Returning device %p.\n", *device
);
463 static HRESULT WINAPI
d3d8_texture_cube_SetPrivateData(IDirect3DCubeTexture8
*iface
,
464 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
466 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
467 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
468 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
470 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
473 static HRESULT WINAPI
d3d8_texture_cube_GetPrivateData(IDirect3DCubeTexture8
*iface
,
474 REFGUID guid
, void *data
, DWORD
*data_size
)
476 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
477 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
478 iface
, debugstr_guid(guid
), data
, data_size
);
480 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
483 static HRESULT WINAPI
d3d8_texture_cube_FreePrivateData(IDirect3DCubeTexture8
*iface
, REFGUID guid
)
485 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
486 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
488 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
491 static DWORD WINAPI
d3d8_texture_cube_SetPriority(IDirect3DCubeTexture8
*iface
, DWORD priority
)
493 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
494 struct wined3d_resource
*resource
;
497 TRACE("iface %p, priority %u.\n", iface
, priority
);
499 wined3d_mutex_lock();
500 resource
= wined3d_texture_get_resource(texture
->wined3d_texture
);
501 ret
= wined3d_resource_set_priority(resource
, priority
);
502 wined3d_mutex_unlock();
507 static DWORD WINAPI
d3d8_texture_cube_GetPriority(IDirect3DCubeTexture8
*iface
)
509 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
510 const struct wined3d_resource
*resource
;
513 TRACE("iface %p.\n", iface
);
515 wined3d_mutex_lock();
516 resource
= wined3d_texture_get_resource(texture
->wined3d_texture
);
517 ret
= wined3d_resource_get_priority(resource
);
518 wined3d_mutex_unlock();
523 static void WINAPI
d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8
*iface
)
525 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
527 TRACE("iface %p.\n", iface
);
529 wined3d_mutex_lock();
530 wined3d_resource_preload(wined3d_texture_get_resource(texture
->wined3d_texture
));
531 wined3d_mutex_unlock();
534 static D3DRESOURCETYPE WINAPI
d3d8_texture_cube_GetType(IDirect3DCubeTexture8
*iface
)
536 TRACE("iface %p.\n", iface
);
538 return D3DRTYPE_CUBETEXTURE
;
541 static DWORD WINAPI
d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8
*iface
, DWORD lod
)
543 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
546 TRACE("iface %p, lod %u.\n", iface
, lod
);
548 wined3d_mutex_lock();
549 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
550 wined3d_mutex_unlock();
555 static DWORD WINAPI
d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8
*iface
)
557 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
560 TRACE("iface %p.\n", iface
);
562 wined3d_mutex_lock();
563 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
564 wined3d_mutex_unlock();
569 static DWORD WINAPI
d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8
*iface
)
571 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
574 TRACE("iface %p.\n", iface
);
576 wined3d_mutex_lock();
577 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
578 wined3d_mutex_unlock();
583 static HRESULT WINAPI
d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8
*iface
, UINT level
, D3DSURFACE_DESC
*desc
)
585 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
586 struct wined3d_sub_resource_desc wined3d_desc
;
589 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
591 wined3d_mutex_lock();
592 if (level
>= wined3d_texture_get_level_count(texture
->wined3d_texture
))
594 wined3d_mutex_unlock();
595 return D3DERR_INVALIDCALL
;
598 if (SUCCEEDED(hr
= wined3d_texture_get_sub_resource_desc(texture
->wined3d_texture
, level
, &wined3d_desc
)))
600 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
601 desc
->Type
= D3DRTYPE_SURFACE
;
602 desc
->Usage
= d3dusage_from_wined3dusage(wined3d_desc
.usage
, wined3d_desc
.bind_flags
);
603 desc
->Pool
= d3dpool_from_wined3daccess(wined3d_desc
.access
, wined3d_desc
.usage
);
604 desc
->Size
= wined3d_desc
.size
;
605 desc
->MultiSampleType
= d3dmultisample_type_from_wined3d(wined3d_desc
.multisample_type
);
606 desc
->Width
= wined3d_desc
.width
;
607 desc
->Height
= wined3d_desc
.height
;
609 wined3d_mutex_unlock();
614 static HRESULT WINAPI
d3d8_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture8
*iface
,
615 D3DCUBEMAP_FACES face
, UINT level
, IDirect3DSurface8
**surface
)
617 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
618 struct d3d8_surface
*surface_impl
;
619 UINT sub_resource_idx
;
622 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface
, face
, level
, surface
);
624 wined3d_mutex_lock();
625 level_count
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
626 if (level
>= level_count
)
628 wined3d_mutex_unlock();
629 return D3DERR_INVALIDCALL
;
632 sub_resource_idx
= level_count
* face
+ level
;
633 if (!(surface_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, sub_resource_idx
)))
635 wined3d_mutex_unlock();
636 return D3DERR_INVALIDCALL
;
639 *surface
= &surface_impl
->IDirect3DSurface8_iface
;
640 IDirect3DSurface8_AddRef(*surface
);
641 wined3d_mutex_unlock();
646 static HRESULT WINAPI
d3d8_texture_cube_LockRect(IDirect3DCubeTexture8
*iface
,
647 D3DCUBEMAP_FACES face
, UINT level
, D3DLOCKED_RECT
*locked_rect
, const RECT
*rect
,
650 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
651 struct d3d8_surface
*surface_impl
;
652 UINT sub_resource_idx
;
655 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
656 iface
, face
, level
, locked_rect
, rect
, flags
);
658 wined3d_mutex_lock();
659 sub_resource_idx
= wined3d_texture_get_level_count(texture
->wined3d_texture
) * face
+ level
;
660 if (!(surface_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, sub_resource_idx
)))
661 hr
= D3DERR_INVALIDCALL
;
663 hr
= IDirect3DSurface8_LockRect(&surface_impl
->IDirect3DSurface8_iface
, locked_rect
, rect
, flags
);
664 wined3d_mutex_unlock();
669 static HRESULT WINAPI
d3d8_texture_cube_UnlockRect(IDirect3DCubeTexture8
*iface
,
670 D3DCUBEMAP_FACES face
, UINT level
)
672 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
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 (!(surface_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, sub_resource_idx
)))
682 hr
= D3DERR_INVALIDCALL
;
684 hr
= IDirect3DSurface8_UnlockRect(&surface_impl
->IDirect3DSurface8_iface
);
685 wined3d_mutex_unlock();
690 static HRESULT WINAPI
d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8
*iface
,
691 D3DCUBEMAP_FACES face
, const RECT
*dirty_rect
)
693 struct d3d8_texture
*texture
= impl_from_IDirect3DCubeTexture8(iface
);
696 TRACE("iface %p, face %#x, dirty_rect %s.\n",
697 iface
, face
, wine_dbgstr_rect(dirty_rect
));
699 wined3d_mutex_lock();
701 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, face
, NULL
);
704 struct wined3d_box dirty_region
;
706 wined3d_box_set(&dirty_region
, dirty_rect
->left
, dirty_rect
->top
, dirty_rect
->right
, dirty_rect
->bottom
, 0, 1);
707 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, face
, &dirty_region
);
709 wined3d_mutex_unlock();
714 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl
=
717 d3d8_texture_cube_QueryInterface
,
718 d3d8_texture_cube_AddRef
,
719 d3d8_texture_cube_Release
,
720 /* IDirect3DResource8 */
721 d3d8_texture_cube_GetDevice
,
722 d3d8_texture_cube_SetPrivateData
,
723 d3d8_texture_cube_GetPrivateData
,
724 d3d8_texture_cube_FreePrivateData
,
725 d3d8_texture_cube_SetPriority
,
726 d3d8_texture_cube_GetPriority
,
727 d3d8_texture_cube_PreLoad
,
728 d3d8_texture_cube_GetType
,
729 /* IDirect3DBaseTexture8 */
730 d3d8_texture_cube_SetLOD
,
731 d3d8_texture_cube_GetLOD
,
732 d3d8_texture_cube_GetLevelCount
,
733 /* IDirect3DCubeTexture8 */
734 d3d8_texture_cube_GetLevelDesc
,
735 d3d8_texture_cube_GetCubeMapSurface
,
736 d3d8_texture_cube_LockRect
,
737 d3d8_texture_cube_UnlockRect
,
738 d3d8_texture_cube_AddDirtyRect
,
741 static HRESULT WINAPI
d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8
*iface
, REFIID riid
, void **out
)
743 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
745 if (IsEqualGUID(riid
, &IID_IDirect3DVolumeTexture8
)
746 || IsEqualGUID(riid
, &IID_IDirect3DBaseTexture8
)
747 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
748 || IsEqualGUID(riid
, &IID_IUnknown
))
750 IDirect3DVolumeTexture8_AddRef(iface
);
755 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
758 return E_NOINTERFACE
;
761 static ULONG WINAPI
d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8
*iface
)
763 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
764 ULONG ref
= InterlockedIncrement(&texture
->resource
.refcount
);
766 TRACE("%p increasing refcount to %u.\n", iface
, ref
);
770 IDirect3DDevice8_AddRef(texture
->parent_device
);
771 wined3d_mutex_lock();
772 wined3d_texture_incref(texture
->wined3d_texture
);
773 wined3d_mutex_unlock();
779 static ULONG WINAPI
d3d8_texture_3d_Release(IDirect3DVolumeTexture8
*iface
)
781 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
782 ULONG ref
= InterlockedDecrement(&texture
->resource
.refcount
);
784 TRACE("%p decreasing refcount to %u.\n", iface
, ref
);
788 IDirect3DDevice8
*parent_device
= texture
->parent_device
;
790 wined3d_mutex_lock();
791 wined3d_texture_decref(texture
->wined3d_texture
);
792 wined3d_mutex_unlock();
794 /* Release the device last, as it may cause the device to be destroyed. */
795 IDirect3DDevice8_Release(parent_device
);
800 static HRESULT WINAPI
d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8
*iface
, IDirect3DDevice8
**device
)
802 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
804 TRACE("iface %p, device %p.\n", iface
, device
);
806 *device
= texture
->parent_device
;
807 IDirect3DDevice8_AddRef(*device
);
809 TRACE("Returning device %p.\n", *device
);
814 static HRESULT WINAPI
d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8
*iface
,
815 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
817 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
818 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
819 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
821 return d3d8_resource_set_private_data(&texture
->resource
, guid
, data
, data_size
, flags
);
824 static HRESULT WINAPI
d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8
*iface
,
825 REFGUID guid
, void *data
, DWORD
*data_size
)
827 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
828 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
829 iface
, debugstr_guid(guid
), data
, data_size
);
831 return d3d8_resource_get_private_data(&texture
->resource
, guid
, data
, data_size
);
834 static HRESULT WINAPI
d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8
*iface
, REFGUID guid
)
836 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
837 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
839 return d3d8_resource_free_private_data(&texture
->resource
, guid
);
842 static DWORD WINAPI
d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8
*iface
, DWORD priority
)
844 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
845 struct wined3d_resource
*resource
;
848 TRACE("iface %p, priority %u.\n", iface
, priority
);
850 wined3d_mutex_lock();
851 resource
= wined3d_texture_get_resource(texture
->wined3d_texture
);
852 ret
= wined3d_resource_set_priority(resource
, priority
);
853 wined3d_mutex_unlock();
858 static DWORD WINAPI
d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8
*iface
)
860 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
861 const struct wined3d_resource
*resource
;
864 TRACE("iface %p.\n", iface
);
866 wined3d_mutex_lock();
867 resource
= wined3d_texture_get_resource(texture
->wined3d_texture
);
868 ret
= wined3d_resource_get_priority(resource
);
869 wined3d_mutex_unlock();
874 static void WINAPI
d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8
*iface
)
876 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
878 TRACE("iface %p.\n", iface
);
880 wined3d_mutex_lock();
881 wined3d_resource_preload(wined3d_texture_get_resource(texture
->wined3d_texture
));
882 wined3d_mutex_unlock();
885 static D3DRESOURCETYPE WINAPI
d3d8_texture_3d_GetType(IDirect3DVolumeTexture8
*iface
)
887 TRACE("iface %p.\n", iface
);
889 return D3DRTYPE_VOLUMETEXTURE
;
892 static DWORD WINAPI
d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8
*iface
, DWORD lod
)
894 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
897 TRACE("iface %p, lod %u.\n", iface
, lod
);
899 wined3d_mutex_lock();
900 ret
= wined3d_texture_set_lod(texture
->wined3d_texture
, lod
);
901 wined3d_mutex_unlock();
906 static DWORD WINAPI
d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8
*iface
)
908 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
911 TRACE("iface %p.\n", iface
);
913 wined3d_mutex_lock();
914 ret
= wined3d_texture_get_lod(texture
->wined3d_texture
);
915 wined3d_mutex_unlock();
920 static DWORD WINAPI
d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8
*iface
)
922 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
925 TRACE("iface %p.\n", iface
);
927 wined3d_mutex_lock();
928 ret
= wined3d_texture_get_level_count(texture
->wined3d_texture
);
929 wined3d_mutex_unlock();
934 static HRESULT WINAPI
d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8
*iface
, UINT level
, D3DVOLUME_DESC
*desc
)
936 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
937 struct wined3d_sub_resource_desc wined3d_desc
;
940 TRACE("iface %p, level %u, desc %p.\n", iface
, level
, desc
);
942 wined3d_mutex_lock();
943 if (SUCCEEDED(hr
= wined3d_texture_get_sub_resource_desc(texture
->wined3d_texture
, level
, &wined3d_desc
)))
945 desc
->Format
= d3dformat_from_wined3dformat(wined3d_desc
.format
);
946 desc
->Type
= D3DRTYPE_VOLUME
;
947 desc
->Usage
= d3dusage_from_wined3dusage(wined3d_desc
.usage
, wined3d_desc
.bind_flags
);
948 desc
->Pool
= d3dpool_from_wined3daccess(wined3d_desc
.access
, wined3d_desc
.usage
);
949 desc
->Size
= wined3d_desc
.size
;
950 desc
->Width
= wined3d_desc
.width
;
951 desc
->Height
= wined3d_desc
.height
;
952 desc
->Depth
= wined3d_desc
.depth
;
954 wined3d_mutex_unlock();
959 static HRESULT WINAPI
d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8
*iface
,
960 UINT level
, IDirect3DVolume8
**volume
)
962 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
963 struct d3d8_volume
*volume_impl
;
965 TRACE("iface %p, level %u, volume %p.\n", iface
, level
, volume
);
967 wined3d_mutex_lock();
968 if (!(volume_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, level
)))
970 wined3d_mutex_unlock();
971 return D3DERR_INVALIDCALL
;
974 *volume
= &volume_impl
->IDirect3DVolume8_iface
;
975 IDirect3DVolume8_AddRef(*volume
);
976 wined3d_mutex_unlock();
981 static HRESULT WINAPI
d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8
*iface
,
982 UINT level
, D3DLOCKED_BOX
*locked_box
, const D3DBOX
*box
, DWORD flags
)
984 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
985 struct d3d8_volume
*volume_impl
;
988 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
989 iface
, level
, locked_box
, box
, flags
);
991 wined3d_mutex_lock();
992 if (!(volume_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, level
)))
993 hr
= D3DERR_INVALIDCALL
;
995 hr
= IDirect3DVolume8_LockBox(&volume_impl
->IDirect3DVolume8_iface
, locked_box
, box
, flags
);
996 wined3d_mutex_unlock();
1001 static HRESULT WINAPI
d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8
*iface
, UINT level
)
1003 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
1004 struct d3d8_volume
*volume_impl
;
1007 TRACE("iface %p, level %u.\n", iface
, level
);
1009 wined3d_mutex_lock();
1010 if (!(volume_impl
= wined3d_texture_get_sub_resource_parent(texture
->wined3d_texture
, level
)))
1011 hr
= D3DERR_INVALIDCALL
;
1013 hr
= IDirect3DVolume8_UnlockBox(&volume_impl
->IDirect3DVolume8_iface
);
1014 wined3d_mutex_unlock();
1019 static HRESULT WINAPI
d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8
*iface
, const D3DBOX
*dirty_box
)
1021 struct d3d8_texture
*texture
= impl_from_IDirect3DVolumeTexture8(iface
);
1024 TRACE("iface %p, dirty_box %p.\n", iface
, dirty_box
);
1026 wined3d_mutex_lock();
1027 hr
= wined3d_texture_add_dirty_region(texture
->wined3d_texture
, 0, (const struct wined3d_box
*)dirty_box
);
1028 wined3d_mutex_unlock();
1033 static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl
=
1036 d3d8_texture_3d_QueryInterface
,
1037 d3d8_texture_3d_AddRef
,
1038 d3d8_texture_3d_Release
,
1039 /* IDirect3DResource8 */
1040 d3d8_texture_3d_GetDevice
,
1041 d3d8_texture_3d_SetPrivateData
,
1042 d3d8_texture_3d_GetPrivateData
,
1043 d3d8_texture_3d_FreePrivateData
,
1044 d3d8_texture_3d_SetPriority
,
1045 d3d8_texture_3d_GetPriority
,
1046 d3d8_texture_3d_PreLoad
,
1047 d3d8_texture_3d_GetType
,
1048 /* IDirect3DBaseTexture8 */
1049 d3d8_texture_3d_SetLOD
,
1050 d3d8_texture_3d_GetLOD
,
1051 d3d8_texture_3d_GetLevelCount
,
1052 /* IDirect3DVolumeTexture8 */
1053 d3d8_texture_3d_GetLevelDesc
,
1054 d3d8_texture_3d_GetVolumeLevel
,
1055 d3d8_texture_3d_LockBox
,
1056 d3d8_texture_3d_UnlockBox
,
1057 d3d8_texture_3d_AddDirtyBox
1060 struct d3d8_texture
*unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8
*iface
)
1065 /* SetTexture() in particular doesn't do a lot of validation on the pointer
1066 * that gets passed in, and passing an invalid pointer works as long as the
1067 * application doesn't try to actually render anything with it, so we print
1068 * a WARN and return NULL instead of having the usual assert() here.
1069 * One application affected by this is Fishdom 2. */
1070 if (iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DTexture8_Vtbl
1071 && iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DCubeTexture8_Vtbl
1072 && iface
->lpVtbl
!= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DVolumeTexture8_Vtbl
)
1074 WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface
);
1078 return CONTAINING_RECORD(iface
, struct d3d8_texture
, IDirect3DBaseTexture8_iface
);
1081 static void STDMETHODCALLTYPE
d3d8_texture_wined3d_object_destroyed(void *parent
)
1083 struct d3d8_texture
*texture
= parent
;
1084 d3d8_resource_cleanup(&texture
->resource
);
1088 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops
=
1090 d3d8_texture_wined3d_object_destroyed
,
1093 HRESULT
texture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1094 UINT width
, UINT height
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1096 struct wined3d_resource_desc desc
;
1100 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DTexture8_Vtbl
;
1101 d3d8_resource_init(&texture
->resource
);
1102 list_init(&texture
->rtv_list
);
1104 desc
.resource_type
= WINED3D_RTYPE_TEXTURE_2D
;
1105 desc
.format
= wined3dformat_from_d3dformat(format
);
1106 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1107 desc
.multisample_quality
= 0;
1108 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1109 if (pool
== D3DPOOL_SCRATCH
)
1110 desc
.usage
|= WINED3DUSAGE_SCRATCH
;
1111 desc
.bind_flags
= wined3d_bind_flags_from_d3d8_usage(usage
) | WINED3D_BIND_SHADER_RESOURCE
;
1112 desc
.access
= wined3daccess_from_d3dpool(pool
, usage
);
1114 desc
.height
= height
;
1118 if (usage
& D3DUSAGE_WRITEONLY
)
1120 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flag, returning D3DERR_INVALIDCALL.\n");
1121 return D3DERR_INVALIDCALL
;
1125 levels
= wined3d_log2i(max(width
, height
)) + 1;
1127 if (pool
== D3DPOOL_SYSTEMMEM
)
1128 flags
|= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS
;
1130 wined3d_mutex_lock();
1131 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, 1, levels
, flags
,
1132 NULL
, texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1133 wined3d_mutex_unlock();
1136 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
1140 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1141 IDirect3DDevice8_AddRef(texture
->parent_device
);
1146 HRESULT
cubetexture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1147 UINT edge_length
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1149 struct wined3d_resource_desc desc
;
1153 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DCubeTexture8_Vtbl
;
1154 d3d8_resource_init(&texture
->resource
);
1155 list_init(&texture
->rtv_list
);
1157 desc
.resource_type
= WINED3D_RTYPE_TEXTURE_2D
;
1158 desc
.format
= wined3dformat_from_d3dformat(format
);
1159 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1160 desc
.multisample_quality
= 0;
1161 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1162 desc
.usage
|= WINED3DUSAGE_LEGACY_CUBEMAP
;
1163 if (pool
== D3DPOOL_SCRATCH
)
1164 desc
.usage
|= WINED3DUSAGE_SCRATCH
;
1165 desc
.bind_flags
= wined3d_bind_flags_from_d3d8_usage(usage
) | WINED3D_BIND_SHADER_RESOURCE
;
1166 desc
.access
= wined3daccess_from_d3dpool(pool
, usage
);
1167 desc
.width
= edge_length
;
1168 desc
.height
= edge_length
;
1172 if (usage
& D3DUSAGE_WRITEONLY
)
1174 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flag, returning D3DERR_INVALIDCALL.\n");
1175 return D3DERR_INVALIDCALL
;
1179 levels
= wined3d_log2i(edge_length
) + 1;
1181 if (pool
== D3DPOOL_SYSTEMMEM
)
1182 flags
|= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS
;
1184 wined3d_mutex_lock();
1185 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, 6, levels
, flags
,
1186 NULL
, texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1187 wined3d_mutex_unlock();
1190 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr
);
1194 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1195 IDirect3DDevice8_AddRef(texture
->parent_device
);
1200 HRESULT
volumetexture_init(struct d3d8_texture
*texture
, struct d3d8_device
*device
,
1201 UINT width
, UINT height
, UINT depth
, UINT levels
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
1203 struct wined3d_resource_desc desc
;
1207 /* In d3d8, 3D textures can't be used as rendertarget or depth/stencil buffer. */
1208 if (usage
& (D3DUSAGE_RENDERTARGET
| D3DUSAGE_DEPTHSTENCIL
))
1209 return D3DERR_INVALIDCALL
;
1211 texture
->IDirect3DBaseTexture8_iface
.lpVtbl
= (const IDirect3DBaseTexture8Vtbl
*)&Direct3DVolumeTexture8_Vtbl
;
1212 d3d8_resource_init(&texture
->resource
);
1213 list_init(&texture
->rtv_list
);
1215 desc
.resource_type
= WINED3D_RTYPE_TEXTURE_3D
;
1216 desc
.format
= wined3dformat_from_d3dformat(format
);
1217 desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1218 desc
.multisample_quality
= 0;
1219 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
1220 if (pool
== D3DPOOL_SCRATCH
)
1221 desc
.usage
|= WINED3DUSAGE_SCRATCH
;
1222 desc
.bind_flags
= wined3d_bind_flags_from_d3d8_usage(usage
) | WINED3D_BIND_SHADER_RESOURCE
;
1223 desc
.access
= wined3daccess_from_d3dpool(pool
, usage
);
1225 desc
.height
= height
;
1229 if (usage
& D3DUSAGE_WRITEONLY
)
1231 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1232 return D3DERR_INVALIDCALL
;
1236 levels
= wined3d_log2i(max(max(width
, height
), depth
)) + 1;
1238 if (pool
== D3DPOOL_SYSTEMMEM
)
1239 flags
|= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS
;
1241 wined3d_mutex_lock();
1242 hr
= wined3d_texture_create(device
->wined3d_device
, &desc
, 1, levels
, flags
,
1243 NULL
, texture
, &d3d8_texture_wined3d_parent_ops
, &texture
->wined3d_texture
);
1244 wined3d_mutex_unlock();
1247 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr
);
1251 texture
->parent_device
= &device
->IDirect3DDevice8_iface
;
1252 IDirect3DDevice8_AddRef(texture
->parent_device
);