user32: Remove _wassert workaround.
[wine.git] / dlls / d3d8 / texture.c
blobf383b374bdefe171bbf09f60703ca879681d4ad1
1 /*
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);
48 *out = iface;
49 return S_OK;
52 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
54 *out = NULL;
55 return E_NOINTERFACE;
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);
65 if (ref == 1)
67 struct d3d8_surface *surface;
69 IDirect3DDevice8_AddRef(texture->parent_device);
70 wined3d_mutex_lock();
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();
79 return ref;
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);
89 if (!ref)
91 IDirect3DDevice8 *parent_device = texture->parent_device;
92 struct d3d8_surface *surface;
94 wined3d_mutex_lock();
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);
105 return ref;
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);
119 return D3D_OK;
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;
154 DWORD ret;
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();
163 return ret;
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;
170 DWORD ret;
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();
179 return ret;
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);
203 DWORD ret;
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();
211 return ret;
214 static DWORD WINAPI d3d8_texture_2d_GetLOD(IDirect3DTexture8 *iface)
216 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
217 DWORD ret;
219 TRACE("iface %p.\n", iface);
221 wined3d_mutex_lock();
222 ret = wined3d_texture_get_lod(texture->wined3d_texture);
223 wined3d_mutex_unlock();
225 return ret;
228 static DWORD WINAPI d3d8_texture_2d_GetLevelCount(IDirect3DTexture8 *iface)
230 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
231 DWORD ret;
233 TRACE("iface %p.\n", iface);
235 wined3d_mutex_lock();
236 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
237 wined3d_mutex_unlock();
239 return ret;
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;
246 HRESULT hr;
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();
264 return hr;
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();
286 return D3D_OK;
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;
294 HRESULT hr;
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;
302 else
303 hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
304 wined3d_mutex_unlock();
306 return hr;
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;
313 HRESULT hr;
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;
320 else
321 hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
322 wined3d_mutex_unlock();
324 return hr;
327 static HRESULT WINAPI d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8 *iface, const RECT *dirty_rect)
329 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
330 HRESULT hr;
332 TRACE("iface %p, dirty_rect %s.\n",
333 iface, wine_dbgstr_rect(dirty_rect));
335 wined3d_mutex_lock();
336 if (!dirty_rect)
337 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
338 else
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();
347 return hr;
350 static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl =
352 /* IUnknown */
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);
387 *out = iface;
388 return S_OK;
391 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
393 *out = NULL;
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);
404 if (ref == 1)
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();
418 return ref;
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);
428 if (!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);
446 return ref;
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);
460 return D3D_OK;
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;
495 DWORD ret;
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();
504 return ret;
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;
511 DWORD ret;
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();
520 return ret;
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);
544 DWORD ret;
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();
552 return ret;
555 static DWORD WINAPI d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8 *iface)
557 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
558 DWORD ret;
560 TRACE("iface %p.\n", iface);
562 wined3d_mutex_lock();
563 ret = wined3d_texture_get_lod(texture->wined3d_texture);
564 wined3d_mutex_unlock();
566 return ret;
569 static DWORD WINAPI d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8 *iface)
571 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
572 DWORD ret;
574 TRACE("iface %p.\n", iface);
576 wined3d_mutex_lock();
577 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
578 wined3d_mutex_unlock();
580 return ret;
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;
587 HRESULT hr;
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();
611 return hr;
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;
620 DWORD level_count;
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();
643 return D3D_OK;
646 static HRESULT WINAPI d3d8_texture_cube_LockRect(IDirect3DCubeTexture8 *iface,
647 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
648 DWORD flags)
650 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
651 struct d3d8_surface *surface_impl;
652 UINT sub_resource_idx;
653 HRESULT hr;
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;
662 else
663 hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
664 wined3d_mutex_unlock();
666 return hr;
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;
675 HRESULT hr;
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;
683 else
684 hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
685 wined3d_mutex_unlock();
687 return hr;
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);
694 HRESULT hr;
696 TRACE("iface %p, face %#x, dirty_rect %s.\n",
697 iface, face, wine_dbgstr_rect(dirty_rect));
699 wined3d_mutex_lock();
700 if (!dirty_rect)
701 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
702 else
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();
711 return hr;
714 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl =
716 /* IUnknown */
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);
751 *out = iface;
752 return S_OK;
755 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
757 *out = NULL;
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);
768 if (ref == 1)
770 IDirect3DDevice8_AddRef(texture->parent_device);
771 wined3d_mutex_lock();
772 wined3d_texture_incref(texture->wined3d_texture);
773 wined3d_mutex_unlock();
776 return ref;
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);
786 if (!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);
797 return ref;
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);
811 return D3D_OK;
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;
846 DWORD ret;
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();
855 return ret;
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;
862 DWORD ret;
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();
871 return ret;
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);
895 DWORD ret;
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();
903 return ret;
906 static DWORD WINAPI d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8 *iface)
908 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
909 DWORD ret;
911 TRACE("iface %p.\n", iface);
913 wined3d_mutex_lock();
914 ret = wined3d_texture_get_lod(texture->wined3d_texture);
915 wined3d_mutex_unlock();
917 return ret;
920 static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface)
922 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
923 DWORD ret;
925 TRACE("iface %p.\n", iface);
927 wined3d_mutex_lock();
928 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
929 wined3d_mutex_unlock();
931 return ret;
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;
938 HRESULT hr;
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();
956 return hr;
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();
978 return D3D_OK;
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;
986 HRESULT hr;
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;
994 else
995 hr = IDirect3DVolume8_LockBox(&volume_impl->IDirect3DVolume8_iface, locked_box, box, flags);
996 wined3d_mutex_unlock();
998 return hr;
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;
1005 HRESULT hr;
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;
1012 else
1013 hr = IDirect3DVolume8_UnlockBox(&volume_impl->IDirect3DVolume8_iface);
1014 wined3d_mutex_unlock();
1016 return hr;
1019 static HRESULT WINAPI d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8 *iface, const D3DBOX *dirty_box)
1021 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
1022 HRESULT hr;
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();
1030 return hr;
1033 static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl =
1035 /* IUnknown */
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)
1062 if (!iface)
1063 return NULL;
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);
1075 return NULL;
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);
1085 heap_free(texture);
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;
1097 DWORD flags = 0;
1098 HRESULT hr;
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);
1113 desc.width = width;
1114 desc.height = height;
1115 desc.depth = 1;
1116 desc.size = 0;
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;
1124 if (!levels)
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();
1134 if (FAILED(hr))
1136 WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1137 return hr;
1140 texture->parent_device = &device->IDirect3DDevice8_iface;
1141 IDirect3DDevice8_AddRef(texture->parent_device);
1143 return D3D_OK;
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;
1150 DWORD flags = 0;
1151 HRESULT hr;
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;
1169 desc.depth = 1;
1170 desc.size = 0;
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;
1178 if (!levels)
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();
1188 if (FAILED(hr))
1190 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1191 return hr;
1194 texture->parent_device = &device->IDirect3DDevice8_iface;
1195 IDirect3DDevice8_AddRef(texture->parent_device);
1197 return D3D_OK;
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;
1204 DWORD flags = 0;
1205 HRESULT hr;
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);
1224 desc.width = width;
1225 desc.height = height;
1226 desc.depth = depth;
1227 desc.size = 0;
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;
1235 if (!levels)
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();
1245 if (FAILED(hr))
1247 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1248 return hr;
1251 texture->parent_device = &device->IDirect3DDevice8_iface;
1252 IDirect3DDevice8_AddRef(texture->parent_device);
1254 return D3D_OK;