wined3d: Check for SRV/RTV binding conflicts per wined3d_state.
[wine.git] / dlls / d3d9 / texture.c
blob19f0363db0781f16eec5c5b13b3827c6afd7f946
1 /*
2 * Copyright 2002-2005 Jason Edmeades
3 * Copyright 2002-2005 Raphael Junqueira
4 * Copyright 2005 Oliver Stieber
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "d3d9_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
25 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
27 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
30 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
32 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
35 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
37 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
40 static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent)
42 struct d3d9_texture *texture = parent;
44 texture->wined3d_srv = NULL;
47 static const struct wined3d_parent_ops d3d9_srv_wined3d_parent_ops =
49 srv_wined3d_object_destroyed,
52 /* wined3d critical section must be taken by the caller. */
53 static struct wined3d_shader_resource_view *d3d9_texture_acquire_shader_resource_view(struct d3d9_texture *texture)
55 struct wined3d_sub_resource_desc sr_desc;
56 struct wined3d_view_desc desc;
57 HRESULT hr;
59 if (texture->wined3d_srv)
60 return texture->wined3d_srv;
62 wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, 0, &sr_desc);
63 desc.format_id = sr_desc.format;
64 desc.flags = 0;
65 desc.u.texture.level_idx = 0;
66 desc.u.texture.level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
67 desc.u.texture.layer_idx = 0;
68 desc.u.texture.layer_count = sr_desc.usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1;
69 if (FAILED(hr = wined3d_shader_resource_view_create(&desc,
70 wined3d_texture_get_resource(texture->wined3d_texture), texture,
71 &d3d9_srv_wined3d_parent_ops, &texture->wined3d_srv)))
73 ERR("Failed to create shader resource view, hr %#x.\n", hr);
74 return NULL;
77 return texture->wined3d_srv;
80 static void d3d9_texture_cleanup(struct d3d9_texture *texture)
82 IDirect3DDevice9Ex *parent_device = &texture->parent_device->IDirect3DDevice9Ex_iface;
83 struct d3d9_surface *surface;
85 wined3d_mutex_lock();
86 if (texture->wined3d_srv)
87 wined3d_shader_resource_view_decref(texture->wined3d_srv);
88 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
89 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
90 wined3d_texture_decref(texture->wined3d_texture);
91 wined3d_mutex_unlock();
93 /* Release the device last, as it may cause the device to be destroyed. */
94 IDirect3DDevice9Ex_Release(parent_device);
97 /* wined3d critical section must be taken by the caller. */
98 void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture)
100 if (!(texture->flags & D3D9_TEXTURE_MIPMAP_DIRTY))
101 return;
102 d3d9_texture_acquire_shader_resource_view(texture);
103 wined3d_device_context_generate_mipmaps(texture->parent_device->immediate_context, texture->wined3d_srv);
104 texture->flags &= ~D3D9_TEXTURE_MIPMAP_DIRTY;
107 void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture)
109 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
110 texture->flags |= D3D9_TEXTURE_MIPMAP_DIRTY;
113 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
115 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
117 if (IsEqualGUID(riid, &IID_IDirect3DTexture9)
118 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
119 || IsEqualGUID(riid, &IID_IDirect3DResource9)
120 || IsEqualGUID(riid, &IID_IUnknown))
122 IDirect3DTexture9_AddRef(iface);
123 *out = iface;
124 return S_OK;
127 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
129 *out = NULL;
130 return E_NOINTERFACE;
133 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
135 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
136 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
138 TRACE("%p increasing refcount to %u.\n", iface, ref);
140 if (ref == 1)
142 struct d3d9_surface *surface;
144 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
145 wined3d_mutex_lock();
146 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
148 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
150 wined3d_texture_incref(texture->wined3d_texture);
151 wined3d_mutex_unlock();
154 return ref;
157 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
159 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
160 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
162 TRACE("%p decreasing refcount to %u.\n", iface, ref);
164 if (!ref)
165 d3d9_texture_cleanup(texture);
166 return ref;
169 static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device)
171 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
173 TRACE("iface %p, device %p.\n", iface, device);
175 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
176 IDirect3DDevice9_AddRef(*device);
178 TRACE("Returning device %p.\n", *device);
180 return D3D_OK;
183 static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
184 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
186 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
187 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
188 iface, debugstr_guid(guid), data, data_size, flags);
190 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
193 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
194 REFGUID guid, void *data, DWORD *data_size)
196 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
197 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
198 iface, debugstr_guid(guid), data, data_size);
200 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
203 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
205 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
206 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
208 return d3d9_resource_free_private_data(&texture->resource, guid);
211 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
213 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
214 struct wined3d_resource *resource;
215 DWORD ret;
217 TRACE("iface %p, priority %u.\n", iface, priority);
219 wined3d_mutex_lock();
220 resource = wined3d_texture_get_resource(texture->wined3d_texture);
221 ret = wined3d_resource_set_priority(resource, priority);
222 wined3d_mutex_unlock();
224 return ret;
227 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
229 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
230 const struct wined3d_resource *resource;
231 DWORD ret;
233 TRACE("iface %p.\n", iface);
235 wined3d_mutex_lock();
236 resource = wined3d_texture_get_resource(texture->wined3d_texture);
237 ret = wined3d_resource_get_priority(resource);
238 wined3d_mutex_unlock();
240 return ret;
243 static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
245 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
247 TRACE("iface %p.\n", iface);
249 wined3d_mutex_lock();
250 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
251 wined3d_mutex_unlock();
254 static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface)
256 TRACE("iface %p.\n", iface);
258 return D3DRTYPE_TEXTURE;
261 static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod)
263 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
264 DWORD ret;
266 TRACE("iface %p, lod %u.\n", iface, lod);
268 wined3d_mutex_lock();
269 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
270 wined3d_mutex_unlock();
272 return ret;
275 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
277 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
278 DWORD ret;
280 TRACE("iface %p.\n", iface);
282 wined3d_mutex_lock();
283 ret = wined3d_texture_get_lod(texture->wined3d_texture);
284 wined3d_mutex_unlock();
286 return ret;
289 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
291 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
292 DWORD ret;
294 TRACE("iface %p.\n", iface);
296 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
297 return 1;
299 wined3d_mutex_lock();
300 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
301 wined3d_mutex_unlock();
303 return ret;
306 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
308 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
310 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
312 if (filter_type == D3DTEXF_NONE)
314 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
315 return D3DERR_INVALIDCALL;
317 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
318 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
319 else if (filter_type != D3DTEXF_LINEAR)
320 FIXME("Unsupported filter type %u.\n", filter_type);
322 texture->autogen_filter_type = filter_type;
323 return D3D_OK;
326 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
328 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
330 TRACE("iface %p.\n", iface);
332 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
333 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
335 return texture->autogen_filter_type;
338 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
340 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
342 TRACE("iface %p.\n", iface);
344 wined3d_mutex_lock();
345 d3d9_texture_gen_auto_mipmap(texture);
346 wined3d_mutex_unlock();
349 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
351 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
352 struct wined3d_sub_resource_desc wined3d_desc;
353 HRESULT hr;
355 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
357 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
359 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
360 return D3DERR_INVALIDCALL;
363 wined3d_mutex_lock();
364 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
366 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
367 desc->Type = D3DRTYPE_SURFACE;
368 desc->Usage = texture->usage;
369 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
370 desc->MultiSampleType = d3dmultisample_type_from_wined3d(wined3d_desc.multisample_type);
371 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
372 desc->Width = wined3d_desc.width;
373 desc->Height = wined3d_desc.height;
375 wined3d_mutex_unlock();
377 return hr;
380 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
381 UINT level, IDirect3DSurface9 **surface)
383 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
384 struct d3d9_surface *surface_impl;
386 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
388 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
390 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
391 return D3DERR_INVALIDCALL;
394 wined3d_mutex_lock();
395 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
397 wined3d_mutex_unlock();
398 return D3DERR_INVALIDCALL;
401 *surface = &surface_impl->IDirect3DSurface9_iface;
402 IDirect3DSurface9_AddRef(*surface);
403 wined3d_mutex_unlock();
405 return D3D_OK;
408 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
409 UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
411 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
412 struct d3d9_surface *surface_impl;
413 HRESULT hr;
415 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
416 iface, level, locked_rect, rect, flags);
418 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
420 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
421 return D3DERR_INVALIDCALL;
424 wined3d_mutex_lock();
425 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
426 hr = D3DERR_INVALIDCALL;
427 else
428 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
429 wined3d_mutex_unlock();
431 return hr;
434 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
436 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
437 struct d3d9_surface *surface_impl;
438 HRESULT hr;
440 TRACE("iface %p, level %u.\n", iface, level);
442 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
444 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
445 return D3DERR_INVALIDCALL;
448 wined3d_mutex_lock();
449 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
450 hr = D3DERR_INVALIDCALL;
451 else
452 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
453 wined3d_mutex_unlock();
455 return hr;
458 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
460 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
461 HRESULT hr;
463 TRACE("iface %p, dirty_rect %s.\n",
464 iface, wine_dbgstr_rect(dirty_rect));
466 wined3d_mutex_lock();
467 if (!dirty_rect)
468 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
469 else
471 struct wined3d_box dirty_region;
473 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
474 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
476 wined3d_mutex_unlock();
478 return hr;
481 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
483 /* IUnknown */
484 d3d9_texture_2d_QueryInterface,
485 d3d9_texture_2d_AddRef,
486 d3d9_texture_2d_Release,
487 /* IDirect3DResource9 */
488 d3d9_texture_2d_GetDevice,
489 d3d9_texture_2d_SetPrivateData,
490 d3d9_texture_2d_GetPrivateData,
491 d3d9_texture_2d_FreePrivateData,
492 d3d9_texture_2d_SetPriority,
493 d3d9_texture_2d_GetPriority,
494 d3d9_texture_2d_PreLoad,
495 d3d9_texture_2d_GetType,
496 /* IDirect3dBaseTexture9 */
497 d3d9_texture_2d_SetLOD,
498 d3d9_texture_2d_GetLOD,
499 d3d9_texture_2d_GetLevelCount,
500 d3d9_texture_2d_SetAutoGenFilterType,
501 d3d9_texture_2d_GetAutoGenFilterType,
502 d3d9_texture_2d_GenerateMipSubLevels,
503 /* IDirect3DTexture9 */
504 d3d9_texture_2d_GetLevelDesc,
505 d3d9_texture_2d_GetSurfaceLevel,
506 d3d9_texture_2d_LockRect,
507 d3d9_texture_2d_UnlockRect,
508 d3d9_texture_2d_AddDirtyRect,
511 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
513 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
515 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
516 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
517 || IsEqualGUID(riid, &IID_IDirect3DResource9)
518 || IsEqualGUID(riid, &IID_IUnknown))
520 IDirect3DCubeTexture9_AddRef(iface);
521 *out = iface;
522 return S_OK;
525 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
527 *out = NULL;
528 return E_NOINTERFACE;
531 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
533 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
534 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
536 TRACE("%p increasing refcount to %u.\n", iface, ref);
538 if (ref == 1)
540 struct d3d9_surface *surface;
542 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
543 wined3d_mutex_lock();
544 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
546 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
548 wined3d_texture_incref(texture->wined3d_texture);
549 wined3d_mutex_unlock();
552 return ref;
555 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
557 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
558 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
560 TRACE("%p decreasing refcount to %u.\n", iface, ref);
562 if (!ref)
563 d3d9_texture_cleanup(texture);
564 return ref;
567 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
569 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
571 TRACE("iface %p, device %p.\n", iface, device);
573 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
574 IDirect3DDevice9_AddRef(*device);
576 TRACE("Returning device %p.\n", *device);
578 return D3D_OK;
581 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
582 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
584 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
585 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
586 iface, debugstr_guid(guid), data, data_size, flags);
588 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
591 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
592 REFGUID guid, void *data, DWORD *data_size)
594 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
595 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
596 iface, debugstr_guid(guid), data, data_size);
598 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
601 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
603 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
604 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
606 return d3d9_resource_free_private_data(&texture->resource, guid);
609 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
611 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
612 struct wined3d_resource *resource;
613 DWORD ret;
615 TRACE("iface %p, priority %u.\n", iface, priority);
617 wined3d_mutex_lock();
618 resource = wined3d_texture_get_resource(texture->wined3d_texture);
619 ret = wined3d_resource_set_priority(resource, priority);
620 wined3d_mutex_unlock();
622 return ret;
625 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
627 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
628 const struct wined3d_resource *resource;
629 DWORD ret;
631 TRACE("iface %p.\n", iface);
633 wined3d_mutex_lock();
634 resource = wined3d_texture_get_resource(texture->wined3d_texture);
635 ret = wined3d_resource_get_priority(resource);
636 wined3d_mutex_unlock();
638 return ret;
641 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
643 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
645 TRACE("iface %p.\n", iface);
647 wined3d_mutex_lock();
648 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
649 wined3d_mutex_unlock();
652 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
654 TRACE("iface %p.\n", iface);
656 return D3DRTYPE_CUBETEXTURE;
659 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
661 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
662 DWORD ret;
664 TRACE("iface %p, lod %u.\n", iface, lod);
666 wined3d_mutex_lock();
667 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
668 wined3d_mutex_unlock();
670 return ret;
673 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
675 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
676 DWORD ret;
678 TRACE("iface %p.\n", iface);
680 wined3d_mutex_lock();
681 ret = wined3d_texture_get_lod(texture->wined3d_texture);
682 wined3d_mutex_unlock();
684 return ret;
687 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
689 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
690 DWORD ret;
692 TRACE("iface %p.\n", iface);
694 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
695 return 1;
697 wined3d_mutex_lock();
698 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
699 wined3d_mutex_unlock();
701 return ret;
704 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
705 D3DTEXTUREFILTERTYPE filter_type)
707 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
709 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
711 if (filter_type == D3DTEXF_NONE)
713 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
714 return D3DERR_INVALIDCALL;
716 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
717 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
718 else if (filter_type != D3DTEXF_LINEAR)
719 FIXME("Unsupported filter type %u.\n", filter_type);
721 texture->autogen_filter_type = filter_type;
722 return D3D_OK;
725 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
727 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
729 TRACE("iface %p.\n", iface);
731 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
732 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
734 return texture->autogen_filter_type;
737 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
739 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
741 TRACE("iface %p.\n", iface);
743 wined3d_mutex_lock();
744 d3d9_texture_gen_auto_mipmap(texture);
745 wined3d_mutex_unlock();
748 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
750 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
751 struct wined3d_sub_resource_desc wined3d_desc;
752 DWORD level_count;
753 HRESULT hr;
755 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
757 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
759 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
760 return D3DERR_INVALIDCALL;
763 wined3d_mutex_lock();
764 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
765 if (level >= level_count)
767 wined3d_mutex_unlock();
768 return D3DERR_INVALIDCALL;
771 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
773 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
774 desc->Type = D3DRTYPE_SURFACE;
775 desc->Usage = texture->usage;
776 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
777 desc->MultiSampleType = d3dmultisample_type_from_wined3d(wined3d_desc.multisample_type);
778 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
779 desc->Width = wined3d_desc.width;
780 desc->Height = wined3d_desc.height;
782 wined3d_mutex_unlock();
784 return hr;
787 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
788 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
790 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
791 struct d3d9_surface *surface_impl;
792 UINT sub_resource_idx;
793 DWORD level_count;
795 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
797 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
799 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
800 return D3DERR_INVALIDCALL;
803 wined3d_mutex_lock();
804 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
805 if (level >= level_count)
807 wined3d_mutex_unlock();
808 return D3DERR_INVALIDCALL;
811 sub_resource_idx = level_count * face + level;
812 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
814 wined3d_mutex_unlock();
815 return D3DERR_INVALIDCALL;
818 *surface = &surface_impl->IDirect3DSurface9_iface;
819 IDirect3DSurface9_AddRef(*surface);
820 wined3d_mutex_unlock();
822 return D3D_OK;
825 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
826 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
827 DWORD flags)
829 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
830 struct d3d9_surface *surface_impl;
831 UINT sub_resource_idx;
832 HRESULT hr;
834 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
835 iface, face, level, locked_rect, rect, flags);
837 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
839 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
840 return D3DERR_INVALIDCALL;
843 wined3d_mutex_lock();
844 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
845 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
846 hr = D3DERR_INVALIDCALL;
847 else
848 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
849 wined3d_mutex_unlock();
851 return hr;
854 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
855 D3DCUBEMAP_FACES face, UINT level)
857 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
858 struct d3d9_surface *surface_impl;
859 UINT sub_resource_idx;
860 HRESULT hr;
862 TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
864 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
866 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
867 return D3DERR_INVALIDCALL;
870 wined3d_mutex_lock();
871 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
872 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
873 hr = D3DERR_INVALIDCALL;
874 else
875 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
876 wined3d_mutex_unlock();
878 return hr;
881 static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
882 D3DCUBEMAP_FACES face, const RECT *dirty_rect)
884 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
885 HRESULT hr;
887 TRACE("iface %p, face %#x, dirty_rect %s.\n",
888 iface, face, wine_dbgstr_rect(dirty_rect));
890 wined3d_mutex_lock();
891 if (!dirty_rect)
892 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
893 else
895 struct wined3d_box dirty_region;
897 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
898 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
900 wined3d_mutex_unlock();
902 return hr;
905 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
907 /* IUnknown */
908 d3d9_texture_cube_QueryInterface,
909 d3d9_texture_cube_AddRef,
910 d3d9_texture_cube_Release,
911 /* IDirect3DResource9 */
912 d3d9_texture_cube_GetDevice,
913 d3d9_texture_cube_SetPrivateData,
914 d3d9_texture_cube_GetPrivateData,
915 d3d9_texture_cube_FreePrivateData,
916 d3d9_texture_cube_SetPriority,
917 d3d9_texture_cube_GetPriority,
918 d3d9_texture_cube_PreLoad,
919 d3d9_texture_cube_GetType,
920 /* IDirect3DBaseTexture9 */
921 d3d9_texture_cube_SetLOD,
922 d3d9_texture_cube_GetLOD,
923 d3d9_texture_cube_GetLevelCount,
924 d3d9_texture_cube_SetAutoGenFilterType,
925 d3d9_texture_cube_GetAutoGenFilterType,
926 d3d9_texture_cube_GenerateMipSubLevels,
927 /* IDirect3DCubeTexture9 */
928 d3d9_texture_cube_GetLevelDesc,
929 d3d9_texture_cube_GetCubeMapSurface,
930 d3d9_texture_cube_LockRect,
931 d3d9_texture_cube_UnlockRect,
932 d3d9_texture_cube_AddDirtyRect,
935 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
937 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
939 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
940 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
941 || IsEqualGUID(riid, &IID_IDirect3DResource9)
942 || IsEqualGUID(riid, &IID_IUnknown))
944 IDirect3DVolumeTexture9_AddRef(iface);
945 *out = iface;
946 return S_OK;
949 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
951 *out = NULL;
952 return E_NOINTERFACE;
955 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
957 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
958 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
960 TRACE("%p increasing refcount to %u.\n", iface, ref);
962 if (ref == 1)
964 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
965 wined3d_mutex_lock();
966 wined3d_texture_incref(texture->wined3d_texture);
967 wined3d_mutex_unlock();
970 return ref;
973 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
975 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
976 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
978 TRACE("%p decreasing refcount to %u.\n", iface, ref);
980 if (!ref)
981 d3d9_texture_cleanup(texture);
982 return ref;
985 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
987 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
989 TRACE("iface %p, device %p.\n", iface, device);
991 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
992 IDirect3DDevice9_AddRef(*device);
994 TRACE("Returning device %p.\n", *device);
996 return D3D_OK;
999 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
1000 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
1002 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1003 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
1004 iface, debugstr_guid(guid), data, data_size, flags);
1006 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
1009 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
1010 REFGUID guid, void *data, DWORD *data_size)
1012 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1013 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
1014 iface, debugstr_guid(guid), data, data_size);
1016 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
1019 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
1021 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1022 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1024 return d3d9_resource_free_private_data(&texture->resource, guid);
1027 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
1029 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1030 struct wined3d_resource *resource;
1031 DWORD ret;
1033 TRACE("iface %p, priority %u.\n", iface, priority);
1035 wined3d_mutex_lock();
1036 resource = wined3d_texture_get_resource(texture->wined3d_texture);
1037 ret = wined3d_resource_set_priority(resource, priority);
1038 wined3d_mutex_unlock();
1040 return ret;
1043 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
1045 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1046 const struct wined3d_resource *resource;
1047 DWORD ret;
1049 TRACE("iface %p.\n", iface);
1051 wined3d_mutex_lock();
1052 resource = wined3d_texture_get_resource(texture->wined3d_texture);
1053 ret = wined3d_resource_get_priority(resource);
1054 wined3d_mutex_unlock();
1056 return ret;
1059 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
1061 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1063 TRACE("iface %p.\n", iface);
1065 wined3d_mutex_lock();
1066 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
1067 wined3d_mutex_unlock();
1070 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
1072 TRACE("iface %p.\n", iface);
1074 return D3DRTYPE_VOLUMETEXTURE;
1077 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
1079 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1080 DWORD ret;
1082 TRACE("iface %p, lod %u.\n", iface, lod);
1084 wined3d_mutex_lock();
1085 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
1086 wined3d_mutex_unlock();
1088 return ret;
1091 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
1093 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1094 DWORD ret;
1096 TRACE("iface %p.\n", iface);
1098 wined3d_mutex_lock();
1099 ret = wined3d_texture_get_lod(texture->wined3d_texture);
1100 wined3d_mutex_unlock();
1102 return ret;
1105 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
1107 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1108 DWORD ret;
1110 TRACE("iface %p.\n", iface);
1112 wined3d_mutex_lock();
1113 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
1114 wined3d_mutex_unlock();
1116 return ret;
1119 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
1120 D3DTEXTUREFILTERTYPE filter_type)
1122 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
1124 return D3DERR_INVALIDCALL;
1127 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
1129 TRACE("iface %p.\n", iface);
1131 return D3DTEXF_NONE;
1134 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
1136 TRACE("iface %p.\n", iface);
1139 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
1141 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1142 struct wined3d_sub_resource_desc wined3d_desc;
1143 HRESULT hr;
1145 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
1147 wined3d_mutex_lock();
1148 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
1150 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
1151 desc->Type = D3DRTYPE_VOLUME;
1152 desc->Usage = texture->usage;
1153 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
1154 desc->Width = wined3d_desc.width;
1155 desc->Height = wined3d_desc.height;
1156 desc->Depth = wined3d_desc.depth;
1158 wined3d_mutex_unlock();
1160 return hr;
1163 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
1164 UINT level, IDirect3DVolume9 **volume)
1166 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1167 struct d3d9_volume *volume_impl;
1169 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1171 wined3d_mutex_lock();
1172 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1174 wined3d_mutex_unlock();
1175 return D3DERR_INVALIDCALL;
1178 *volume = &volume_impl->IDirect3DVolume9_iface;
1179 IDirect3DVolume9_AddRef(*volume);
1180 wined3d_mutex_unlock();
1182 return D3D_OK;
1185 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
1186 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1188 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1189 struct d3d9_volume *volume_impl;
1190 HRESULT hr;
1192 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1193 iface, level, locked_box, box, flags);
1195 wined3d_mutex_lock();
1196 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1197 hr = D3DERR_INVALIDCALL;
1198 else
1199 hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
1200 wined3d_mutex_unlock();
1202 return hr;
1205 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
1207 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1208 struct d3d9_volume *volume_impl;
1209 HRESULT hr;
1211 TRACE("iface %p, level %u.\n", iface, level);
1213 wined3d_mutex_lock();
1214 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1215 hr = D3DERR_INVALIDCALL;
1216 else
1217 hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
1218 wined3d_mutex_unlock();
1220 return hr;
1223 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
1225 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1226 HRESULT hr;
1228 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1230 wined3d_mutex_lock();
1231 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1232 wined3d_mutex_unlock();
1234 return hr;
1238 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
1240 /* IUnknown */
1241 d3d9_texture_3d_QueryInterface,
1242 d3d9_texture_3d_AddRef,
1243 d3d9_texture_3d_Release,
1244 /* IDirect3DResource9 */
1245 d3d9_texture_3d_GetDevice,
1246 d3d9_texture_3d_SetPrivateData,
1247 d3d9_texture_3d_GetPrivateData,
1248 d3d9_texture_3d_FreePrivateData,
1249 d3d9_texture_3d_SetPriority,
1250 d3d9_texture_3d_GetPriority,
1251 d3d9_texture_3d_PreLoad,
1252 d3d9_texture_3d_GetType,
1253 /* IDirect3DBaseTexture9 */
1254 d3d9_texture_3d_SetLOD,
1255 d3d9_texture_3d_GetLOD,
1256 d3d9_texture_3d_GetLevelCount,
1257 d3d9_texture_3d_SetAutoGenFilterType,
1258 d3d9_texture_3d_GetAutoGenFilterType,
1259 d3d9_texture_3d_GenerateMipSubLevels,
1260 /* IDirect3DVolumeTexture9 */
1261 d3d9_texture_3d_GetLevelDesc,
1262 d3d9_texture_3d_GetVolumeLevel,
1263 d3d9_texture_3d_LockBox,
1264 d3d9_texture_3d_UnlockBox,
1265 d3d9_texture_3d_AddDirtyBox,
1268 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
1270 if (!iface)
1271 return NULL;
1273 if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
1274 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
1275 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
1277 WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
1278 return NULL;
1281 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
1284 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
1286 struct d3d9_texture *texture = parent;
1287 d3d9_resource_cleanup(&texture->resource);
1288 heap_free(texture);
1291 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
1293 d3d9_texture_wined3d_object_destroyed,
1296 HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1297 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1299 struct wined3d_adapter *wined3d_adapter;
1300 struct wined3d_resource_desc desc;
1301 unsigned int output_idx;
1302 DWORD flags = 0;
1303 HRESULT hr;
1305 if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
1307 WARN("Managed resources are not supported by d3d9ex devices.\n");
1308 return D3DERR_INVALIDCALL;
1311 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
1312 d3d9_resource_init(&texture->resource);
1313 list_init(&texture->rtv_list);
1314 texture->usage = usage;
1316 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1317 desc.format = wined3dformat_from_d3dformat(format);
1318 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1319 desc.multisample_quality = 0;
1320 desc.usage = wined3dusage_from_d3dusage(usage);
1321 if (pool == D3DPOOL_SCRATCH)
1322 desc.usage |= WINED3DUSAGE_SCRATCH;
1323 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1324 desc.access = wined3daccess_from_d3dpool(pool, usage);
1325 desc.width = width;
1326 desc.height = height;
1327 desc.depth = 1;
1328 desc.size = 0;
1330 if (is_gdi_compat_wined3dformat(desc.format))
1331 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1333 if (usage & D3DUSAGE_WRITEONLY)
1335 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1336 return D3DERR_INVALIDCALL;
1338 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1340 if (pool == D3DPOOL_SYSTEMMEM)
1342 WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
1343 return D3DERR_INVALIDCALL;
1345 if (levels && levels != 1)
1347 WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
1348 return D3DERR_INVALIDCALL;
1350 wined3d_mutex_lock();
1351 output_idx = device->adapter_ordinal;
1352 wined3d_adapter = wined3d_output_get_adapter(device->d3d_parent->wined3d_outputs[output_idx]);
1353 hr = wined3d_check_device_format(device->d3d_parent->wined3d, wined3d_adapter,
1354 WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_QUERY_GENMIPMAP,
1355 WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, wined3dformat_from_d3dformat(format));
1356 wined3d_mutex_unlock();
1357 if (hr == D3D_OK)
1359 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1360 levels = 0;
1362 else
1364 WARN("D3DUSAGE_AUTOGENMIPMAP not supported on D3DFORMAT %#x, creating a texture "
1365 "with a single level.\n", format);
1366 levels = 1;
1368 texture->autogen_filter_type = D3DTEXF_LINEAR;
1370 else
1372 texture->autogen_filter_type = D3DTEXF_NONE;
1374 if (!levels)
1375 levels = wined3d_log2i(max(width, height)) + 1;
1376 if (pool == D3DPOOL_SYSTEMMEM)
1377 flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
1379 wined3d_mutex_lock();
1380 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
1381 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1382 wined3d_mutex_unlock();
1383 if (FAILED(hr))
1385 WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1386 return hr;
1389 texture->parent_device = device;
1390 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
1392 return D3D_OK;
1395 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1396 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1398 struct wined3d_resource_desc desc;
1399 DWORD flags = 0;
1400 HRESULT hr;
1402 if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
1404 WARN("Managed resources are not supported by d3d9ex devices.\n");
1405 return D3DERR_INVALIDCALL;
1408 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
1409 d3d9_resource_init(&texture->resource);
1410 list_init(&texture->rtv_list);
1411 texture->usage = usage;
1413 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1414 desc.format = wined3dformat_from_d3dformat(format);
1415 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1416 desc.multisample_quality = 0;
1417 desc.usage = wined3dusage_from_d3dusage(usage);
1418 desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP;
1419 if (pool == D3DPOOL_SCRATCH)
1420 desc.usage |= WINED3DUSAGE_SCRATCH;
1421 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1422 desc.access = wined3daccess_from_d3dpool(pool, usage);
1423 desc.width = edge_length;
1424 desc.height = edge_length;
1425 desc.depth = 1;
1426 desc.size = 0;
1428 if (is_gdi_compat_wined3dformat(desc.format))
1429 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1431 if (usage & D3DUSAGE_WRITEONLY)
1433 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1434 return D3DERR_INVALIDCALL;
1436 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1438 if (pool == D3DPOOL_SYSTEMMEM)
1440 WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
1441 return D3DERR_INVALIDCALL;
1443 if (levels && levels != 1)
1445 WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
1446 return D3DERR_INVALIDCALL;
1448 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1449 texture->autogen_filter_type = D3DTEXF_LINEAR;
1450 levels = 0;
1452 else
1454 texture->autogen_filter_type = D3DTEXF_NONE;
1456 if (!levels)
1457 levels = wined3d_log2i(edge_length) + 1;
1458 if (pool == D3DPOOL_SYSTEMMEM)
1459 flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
1461 wined3d_mutex_lock();
1462 hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
1463 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1464 wined3d_mutex_unlock();
1465 if (FAILED(hr))
1467 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1468 return hr;
1471 texture->parent_device = device;
1472 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
1474 return D3D_OK;
1477 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1478 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1480 struct wined3d_resource_desc desc;
1481 DWORD flags = 0;
1482 HRESULT hr;
1484 if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
1486 WARN("Managed resources are not supported by d3d9ex devices.\n");
1487 return D3DERR_INVALIDCALL;
1490 /* In d3d9, 3D textures can't be used as rendertarget or depth/stencil buffer. */
1491 if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
1492 return D3DERR_INVALIDCALL;
1494 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
1495 d3d9_resource_init(&texture->resource);
1496 list_init(&texture->rtv_list);
1497 texture->usage = usage;
1499 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
1500 desc.format = wined3dformat_from_d3dformat(format);
1501 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1502 desc.multisample_quality = 0;
1503 desc.usage = wined3dusage_from_d3dusage(usage);
1504 if (pool == D3DPOOL_SCRATCH)
1505 desc.usage |= WINED3DUSAGE_SCRATCH;
1506 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1507 desc.access = wined3daccess_from_d3dpool(pool, usage);
1508 desc.width = width;
1509 desc.height = height;
1510 desc.depth = depth;
1511 desc.size = 0;
1513 if (usage & D3DUSAGE_WRITEONLY)
1515 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1516 return D3DERR_INVALIDCALL;
1518 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1520 WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n");
1521 return D3DERR_INVALIDCALL;
1523 if (!levels)
1524 levels = wined3d_log2i(max(max(width, height), depth)) + 1;
1525 if (pool == D3DPOOL_SYSTEMMEM)
1526 flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
1528 wined3d_mutex_lock();
1529 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
1530 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1531 wined3d_mutex_unlock();
1532 if (FAILED(hr))
1534 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1535 return hr;
1538 texture->parent_device = device;
1539 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
1541 return D3D_OK;