kernel32/tests: Add a test to check some fields in fake dlls.
[wine.git] / dlls / d3d9 / texture.c
blob9f367096b715305cce3dc9e47f34db135fe50ef3
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 "config.h"
22 #include "wine/port.h"
23 #include "d3d9_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
27 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
29 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
32 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
34 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
37 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
39 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
42 static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent)
44 struct d3d9_texture *texture = parent;
46 texture->wined3d_srv = NULL;
49 static const struct wined3d_parent_ops d3d9_srv_wined3d_parent_ops =
51 srv_wined3d_object_destroyed,
54 /* wined3d critical section must be taken by the caller. */
55 static struct wined3d_shader_resource_view *d3d9_texture_acquire_shader_resource_view(struct d3d9_texture *texture)
57 struct wined3d_sub_resource_desc sr_desc;
58 struct wined3d_view_desc desc;
59 HRESULT hr;
61 if (texture->wined3d_srv)
62 return texture->wined3d_srv;
64 wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, 0, &sr_desc);
65 desc.format_id = sr_desc.format;
66 desc.flags = 0;
67 desc.u.texture.level_idx = 0;
68 desc.u.texture.level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
69 desc.u.texture.layer_idx = 0;
70 desc.u.texture.layer_count = sr_desc.usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1;
71 if (FAILED(hr = wined3d_shader_resource_view_create(&desc,
72 wined3d_texture_get_resource(texture->wined3d_texture), texture,
73 &d3d9_srv_wined3d_parent_ops, &texture->wined3d_srv)))
75 ERR("Failed to create shader resource view, hr %#x.\n", hr);
76 return NULL;
79 return texture->wined3d_srv;
82 static void d3d9_texture_cleanup(struct d3d9_texture *texture)
84 IDirect3DDevice9Ex *parent_device = texture->parent_device;
85 struct d3d9_surface *surface;
87 wined3d_mutex_lock();
88 if (texture->wined3d_srv)
89 wined3d_shader_resource_view_decref(texture->wined3d_srv);
90 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
91 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
92 wined3d_texture_decref(texture->wined3d_texture);
93 wined3d_mutex_unlock();
95 /* Release the device last, as it may cause the device to be destroyed. */
96 IDirect3DDevice9Ex_Release(parent_device);
99 /* wined3d critical section must be taken by the caller. */
100 void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture)
102 if (!(texture->flags & D3D9_TEXTURE_MIPMAP_DIRTY))
103 return;
104 d3d9_texture_acquire_shader_resource_view(texture);
105 wined3d_shader_resource_view_generate_mipmaps(texture->wined3d_srv);
106 texture->flags &= ~D3D9_TEXTURE_MIPMAP_DIRTY;
109 void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture)
111 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
112 texture->flags |= D3D9_TEXTURE_MIPMAP_DIRTY;
115 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
117 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
119 if (IsEqualGUID(riid, &IID_IDirect3DTexture9)
120 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
121 || IsEqualGUID(riid, &IID_IDirect3DResource9)
122 || IsEqualGUID(riid, &IID_IUnknown))
124 IDirect3DTexture9_AddRef(iface);
125 *out = iface;
126 return S_OK;
129 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
131 *out = NULL;
132 return E_NOINTERFACE;
135 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
137 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
138 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
140 TRACE("%p increasing refcount to %u.\n", iface, ref);
142 if (ref == 1)
144 struct d3d9_surface *surface;
146 IDirect3DDevice9Ex_AddRef(texture->parent_device);
147 wined3d_mutex_lock();
148 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
150 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
152 wined3d_texture_incref(texture->wined3d_texture);
153 wined3d_mutex_unlock();
156 return ref;
159 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
161 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
162 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
164 TRACE("%p decreasing refcount to %u.\n", iface, ref);
166 if (!ref)
167 d3d9_texture_cleanup(texture);
168 return ref;
171 static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device)
173 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
175 TRACE("iface %p, device %p.\n", iface, device);
177 *device = (IDirect3DDevice9 *)texture->parent_device;
178 IDirect3DDevice9_AddRef(*device);
180 TRACE("Returning device %p.\n", *device);
182 return D3D_OK;
185 static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
186 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
188 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
189 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
190 iface, debugstr_guid(guid), data, data_size, flags);
192 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
195 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
196 REFGUID guid, void *data, DWORD *data_size)
198 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
199 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
200 iface, debugstr_guid(guid), data, data_size);
202 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
205 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
207 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
208 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
210 return d3d9_resource_free_private_data(&texture->resource, guid);
213 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
215 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
216 struct wined3d_resource *resource;
217 DWORD ret;
219 TRACE("iface %p, priority %u.\n", iface, priority);
221 wined3d_mutex_lock();
222 resource = wined3d_texture_get_resource(texture->wined3d_texture);
223 ret = wined3d_resource_set_priority(resource, priority);
224 wined3d_mutex_unlock();
226 return ret;
229 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
231 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
232 const struct wined3d_resource *resource;
233 DWORD ret;
235 TRACE("iface %p.\n", iface);
237 wined3d_mutex_lock();
238 resource = wined3d_texture_get_resource(texture->wined3d_texture);
239 ret = wined3d_resource_get_priority(resource);
240 wined3d_mutex_unlock();
242 return ret;
245 static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
247 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
249 TRACE("iface %p.\n", iface);
251 wined3d_mutex_lock();
252 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
253 wined3d_mutex_unlock();
256 static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface)
258 TRACE("iface %p.\n", iface);
260 return D3DRTYPE_TEXTURE;
263 static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod)
265 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
266 DWORD ret;
268 TRACE("iface %p, lod %u.\n", iface, lod);
270 wined3d_mutex_lock();
271 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
272 wined3d_mutex_unlock();
274 return ret;
277 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
279 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
280 DWORD ret;
282 TRACE("iface %p.\n", iface);
284 wined3d_mutex_lock();
285 ret = wined3d_texture_get_lod(texture->wined3d_texture);
286 wined3d_mutex_unlock();
288 return ret;
291 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
293 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
294 DWORD ret;
296 TRACE("iface %p.\n", iface);
298 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
299 return 1;
301 wined3d_mutex_lock();
302 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
303 wined3d_mutex_unlock();
305 return ret;
308 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
310 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
312 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
314 if (filter_type == D3DTEXF_NONE)
316 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
317 return D3DERR_INVALIDCALL;
319 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
320 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
321 else if (filter_type != D3DTEXF_LINEAR)
322 FIXME("Unsupported filter type %u.\n", filter_type);
324 texture->autogen_filter_type = filter_type;
325 return D3D_OK;
328 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
330 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
332 TRACE("iface %p.\n", iface);
334 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
335 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
337 return texture->autogen_filter_type;
340 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
342 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
344 TRACE("iface %p.\n", iface);
346 wined3d_mutex_lock();
347 d3d9_texture_gen_auto_mipmap(texture);
348 wined3d_mutex_unlock();
351 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
353 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
354 struct wined3d_sub_resource_desc wined3d_desc;
355 HRESULT hr;
357 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
359 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
361 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
362 return D3DERR_INVALIDCALL;
365 wined3d_mutex_lock();
366 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
368 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
369 desc->Type = D3DRTYPE_SURFACE;
370 desc->Usage = texture->usage;
371 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
372 desc->MultiSampleType = wined3d_desc.multisample_type;
373 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
374 desc->Width = wined3d_desc.width;
375 desc->Height = wined3d_desc.height;
377 wined3d_mutex_unlock();
379 return hr;
382 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
383 UINT level, IDirect3DSurface9 **surface)
385 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
386 struct d3d9_surface *surface_impl;
388 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
390 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
392 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
393 return D3DERR_INVALIDCALL;
396 wined3d_mutex_lock();
397 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
399 wined3d_mutex_unlock();
400 return D3DERR_INVALIDCALL;
403 *surface = &surface_impl->IDirect3DSurface9_iface;
404 IDirect3DSurface9_AddRef(*surface);
405 wined3d_mutex_unlock();
407 return D3D_OK;
410 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
411 UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
413 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
414 struct d3d9_surface *surface_impl;
415 HRESULT hr;
417 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
418 iface, level, locked_rect, rect, flags);
420 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
422 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
423 return D3DERR_INVALIDCALL;
426 wined3d_mutex_lock();
427 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
428 hr = D3DERR_INVALIDCALL;
429 else
430 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
431 wined3d_mutex_unlock();
433 return hr;
436 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
438 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
439 struct d3d9_surface *surface_impl;
440 HRESULT hr;
442 TRACE("iface %p, level %u.\n", iface, level);
444 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
446 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
447 return D3DERR_INVALIDCALL;
450 wined3d_mutex_lock();
451 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
452 hr = D3DERR_INVALIDCALL;
453 else
454 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
455 wined3d_mutex_unlock();
457 return hr;
460 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
462 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
463 HRESULT hr;
465 TRACE("iface %p, dirty_rect %s.\n",
466 iface, wine_dbgstr_rect(dirty_rect));
468 wined3d_mutex_lock();
469 if (!dirty_rect)
470 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
471 else
473 struct wined3d_box dirty_region;
475 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
476 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
478 wined3d_mutex_unlock();
480 return hr;
483 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
485 /* IUnknown */
486 d3d9_texture_2d_QueryInterface,
487 d3d9_texture_2d_AddRef,
488 d3d9_texture_2d_Release,
489 /* IDirect3DResource9 */
490 d3d9_texture_2d_GetDevice,
491 d3d9_texture_2d_SetPrivateData,
492 d3d9_texture_2d_GetPrivateData,
493 d3d9_texture_2d_FreePrivateData,
494 d3d9_texture_2d_SetPriority,
495 d3d9_texture_2d_GetPriority,
496 d3d9_texture_2d_PreLoad,
497 d3d9_texture_2d_GetType,
498 /* IDirect3dBaseTexture9 */
499 d3d9_texture_2d_SetLOD,
500 d3d9_texture_2d_GetLOD,
501 d3d9_texture_2d_GetLevelCount,
502 d3d9_texture_2d_SetAutoGenFilterType,
503 d3d9_texture_2d_GetAutoGenFilterType,
504 d3d9_texture_2d_GenerateMipSubLevels,
505 /* IDirect3DTexture9 */
506 d3d9_texture_2d_GetLevelDesc,
507 d3d9_texture_2d_GetSurfaceLevel,
508 d3d9_texture_2d_LockRect,
509 d3d9_texture_2d_UnlockRect,
510 d3d9_texture_2d_AddDirtyRect,
513 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
515 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
517 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
518 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
519 || IsEqualGUID(riid, &IID_IDirect3DResource9)
520 || IsEqualGUID(riid, &IID_IUnknown))
522 IDirect3DCubeTexture9_AddRef(iface);
523 *out = iface;
524 return S_OK;
527 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
529 *out = NULL;
530 return E_NOINTERFACE;
533 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
535 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
536 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
538 TRACE("%p increasing refcount to %u.\n", iface, ref);
540 if (ref == 1)
542 struct d3d9_surface *surface;
544 IDirect3DDevice9Ex_AddRef(texture->parent_device);
545 wined3d_mutex_lock();
546 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
548 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
550 wined3d_texture_incref(texture->wined3d_texture);
551 wined3d_mutex_unlock();
554 return ref;
557 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
559 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
560 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
562 TRACE("%p decreasing refcount to %u.\n", iface, ref);
564 if (!ref)
565 d3d9_texture_cleanup(texture);
566 return ref;
569 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
571 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
573 TRACE("iface %p, device %p.\n", iface, device);
575 *device = (IDirect3DDevice9 *)texture->parent_device;
576 IDirect3DDevice9_AddRef(*device);
578 TRACE("Returning device %p.\n", *device);
580 return D3D_OK;
583 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
584 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
586 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
587 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
588 iface, debugstr_guid(guid), data, data_size, flags);
590 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
593 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
594 REFGUID guid, void *data, DWORD *data_size)
596 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
597 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
598 iface, debugstr_guid(guid), data, data_size);
600 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
603 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
605 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
606 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
608 return d3d9_resource_free_private_data(&texture->resource, guid);
611 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
613 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
614 struct wined3d_resource *resource;
615 DWORD ret;
617 TRACE("iface %p, priority %u.\n", iface, priority);
619 wined3d_mutex_lock();
620 resource = wined3d_texture_get_resource(texture->wined3d_texture);
621 ret = wined3d_resource_set_priority(resource, priority);
622 wined3d_mutex_unlock();
624 return ret;
627 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
629 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
630 const struct wined3d_resource *resource;
631 DWORD ret;
633 TRACE("iface %p.\n", iface);
635 wined3d_mutex_lock();
636 resource = wined3d_texture_get_resource(texture->wined3d_texture);
637 ret = wined3d_resource_get_priority(resource);
638 wined3d_mutex_unlock();
640 return ret;
643 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
645 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
647 TRACE("iface %p.\n", iface);
649 wined3d_mutex_lock();
650 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
651 wined3d_mutex_unlock();
654 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
656 TRACE("iface %p.\n", iface);
658 return D3DRTYPE_CUBETEXTURE;
661 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
663 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
664 DWORD ret;
666 TRACE("iface %p, lod %u.\n", iface, lod);
668 wined3d_mutex_lock();
669 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
670 wined3d_mutex_unlock();
672 return ret;
675 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
677 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
678 DWORD ret;
680 TRACE("iface %p.\n", iface);
682 wined3d_mutex_lock();
683 ret = wined3d_texture_get_lod(texture->wined3d_texture);
684 wined3d_mutex_unlock();
686 return ret;
689 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
691 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
692 DWORD ret;
694 TRACE("iface %p.\n", iface);
696 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
697 return 1;
699 wined3d_mutex_lock();
700 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
701 wined3d_mutex_unlock();
703 return ret;
706 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
707 D3DTEXTUREFILTERTYPE filter_type)
709 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
711 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
713 if (filter_type == D3DTEXF_NONE)
715 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
716 return D3DERR_INVALIDCALL;
718 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
719 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
720 else if (filter_type != D3DTEXF_LINEAR)
721 FIXME("Unsupported filter type %u.\n", filter_type);
723 texture->autogen_filter_type = filter_type;
724 return D3D_OK;
727 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
729 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
731 TRACE("iface %p.\n", iface);
733 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
734 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
736 return texture->autogen_filter_type;
739 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
741 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
743 TRACE("iface %p.\n", iface);
745 wined3d_mutex_lock();
746 d3d9_texture_gen_auto_mipmap(texture);
747 wined3d_mutex_unlock();
750 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
752 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
753 struct wined3d_sub_resource_desc wined3d_desc;
754 DWORD level_count;
755 HRESULT hr;
757 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
759 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
761 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
762 return D3DERR_INVALIDCALL;
765 wined3d_mutex_lock();
766 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
767 if (level >= level_count)
769 wined3d_mutex_unlock();
770 return D3DERR_INVALIDCALL;
773 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
775 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
776 desc->Type = D3DRTYPE_SURFACE;
777 desc->Usage = texture->usage;
778 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
779 desc->MultiSampleType = wined3d_desc.multisample_type;
780 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
781 desc->Width = wined3d_desc.width;
782 desc->Height = wined3d_desc.height;
784 wined3d_mutex_unlock();
786 return hr;
789 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
790 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
792 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
793 struct d3d9_surface *surface_impl;
794 UINT sub_resource_idx;
795 DWORD level_count;
797 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
799 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
801 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
802 return D3DERR_INVALIDCALL;
805 wined3d_mutex_lock();
806 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
807 if (level >= level_count)
809 wined3d_mutex_unlock();
810 return D3DERR_INVALIDCALL;
813 sub_resource_idx = level_count * face + level;
814 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
816 wined3d_mutex_unlock();
817 return D3DERR_INVALIDCALL;
820 *surface = &surface_impl->IDirect3DSurface9_iface;
821 IDirect3DSurface9_AddRef(*surface);
822 wined3d_mutex_unlock();
824 return D3D_OK;
827 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
828 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
829 DWORD flags)
831 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
832 struct d3d9_surface *surface_impl;
833 UINT sub_resource_idx;
834 HRESULT hr;
836 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
837 iface, face, level, locked_rect, rect, flags);
839 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
841 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
842 return D3DERR_INVALIDCALL;
845 wined3d_mutex_lock();
846 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
847 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
848 hr = D3DERR_INVALIDCALL;
849 else
850 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
851 wined3d_mutex_unlock();
853 return hr;
856 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
857 D3DCUBEMAP_FACES face, UINT level)
859 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
860 struct d3d9_surface *surface_impl;
861 UINT sub_resource_idx;
862 HRESULT hr;
864 TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
866 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
868 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
869 return D3DERR_INVALIDCALL;
872 wined3d_mutex_lock();
873 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
874 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
875 hr = D3DERR_INVALIDCALL;
876 else
877 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
878 wined3d_mutex_unlock();
880 return hr;
883 static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
884 D3DCUBEMAP_FACES face, const RECT *dirty_rect)
886 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
887 HRESULT hr;
889 TRACE("iface %p, face %#x, dirty_rect %s.\n",
890 iface, face, wine_dbgstr_rect(dirty_rect));
892 wined3d_mutex_lock();
893 if (!dirty_rect)
894 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
895 else
897 struct wined3d_box dirty_region;
899 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
900 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
902 wined3d_mutex_unlock();
904 return hr;
907 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
909 /* IUnknown */
910 d3d9_texture_cube_QueryInterface,
911 d3d9_texture_cube_AddRef,
912 d3d9_texture_cube_Release,
913 /* IDirect3DResource9 */
914 d3d9_texture_cube_GetDevice,
915 d3d9_texture_cube_SetPrivateData,
916 d3d9_texture_cube_GetPrivateData,
917 d3d9_texture_cube_FreePrivateData,
918 d3d9_texture_cube_SetPriority,
919 d3d9_texture_cube_GetPriority,
920 d3d9_texture_cube_PreLoad,
921 d3d9_texture_cube_GetType,
922 /* IDirect3DBaseTexture9 */
923 d3d9_texture_cube_SetLOD,
924 d3d9_texture_cube_GetLOD,
925 d3d9_texture_cube_GetLevelCount,
926 d3d9_texture_cube_SetAutoGenFilterType,
927 d3d9_texture_cube_GetAutoGenFilterType,
928 d3d9_texture_cube_GenerateMipSubLevels,
929 /* IDirect3DCubeTexture9 */
930 d3d9_texture_cube_GetLevelDesc,
931 d3d9_texture_cube_GetCubeMapSurface,
932 d3d9_texture_cube_LockRect,
933 d3d9_texture_cube_UnlockRect,
934 d3d9_texture_cube_AddDirtyRect,
937 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
939 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
941 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
942 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
943 || IsEqualGUID(riid, &IID_IDirect3DResource9)
944 || IsEqualGUID(riid, &IID_IUnknown))
946 IDirect3DVolumeTexture9_AddRef(iface);
947 *out = iface;
948 return S_OK;
951 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
953 *out = NULL;
954 return E_NOINTERFACE;
957 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
959 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
960 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
962 TRACE("%p increasing refcount to %u.\n", iface, ref);
964 if (ref == 1)
966 IDirect3DDevice9Ex_AddRef(texture->parent_device);
967 wined3d_mutex_lock();
968 wined3d_texture_incref(texture->wined3d_texture);
969 wined3d_mutex_unlock();
972 return ref;
975 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
977 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
978 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
980 TRACE("%p decreasing refcount to %u.\n", iface, ref);
982 if (!ref)
983 d3d9_texture_cleanup(texture);
984 return ref;
987 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
989 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
991 TRACE("iface %p, device %p.\n", iface, device);
993 *device = (IDirect3DDevice9 *)texture->parent_device;
994 IDirect3DDevice9_AddRef(*device);
996 TRACE("Returning device %p.\n", *device);
998 return D3D_OK;
1001 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
1002 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
1004 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1005 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
1006 iface, debugstr_guid(guid), data, data_size, flags);
1008 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
1011 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
1012 REFGUID guid, void *data, DWORD *data_size)
1014 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1015 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
1016 iface, debugstr_guid(guid), data, data_size);
1018 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
1021 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
1023 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1024 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1026 return d3d9_resource_free_private_data(&texture->resource, guid);
1029 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
1031 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1032 struct wined3d_resource *resource;
1033 DWORD ret;
1035 TRACE("iface %p, priority %u.\n", iface, priority);
1037 wined3d_mutex_lock();
1038 resource = wined3d_texture_get_resource(texture->wined3d_texture);
1039 ret = wined3d_resource_set_priority(resource, priority);
1040 wined3d_mutex_unlock();
1042 return ret;
1045 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
1047 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1048 const struct wined3d_resource *resource;
1049 DWORD ret;
1051 TRACE("iface %p.\n", iface);
1053 wined3d_mutex_lock();
1054 resource = wined3d_texture_get_resource(texture->wined3d_texture);
1055 ret = wined3d_resource_get_priority(resource);
1056 wined3d_mutex_unlock();
1058 return ret;
1061 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
1063 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1065 TRACE("iface %p.\n", iface);
1067 wined3d_mutex_lock();
1068 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
1069 wined3d_mutex_unlock();
1072 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
1074 TRACE("iface %p.\n", iface);
1076 return D3DRTYPE_VOLUMETEXTURE;
1079 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
1081 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1082 DWORD ret;
1084 TRACE("iface %p, lod %u.\n", iface, lod);
1086 wined3d_mutex_lock();
1087 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
1088 wined3d_mutex_unlock();
1090 return ret;
1093 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
1095 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1096 DWORD ret;
1098 TRACE("iface %p.\n", iface);
1100 wined3d_mutex_lock();
1101 ret = wined3d_texture_get_lod(texture->wined3d_texture);
1102 wined3d_mutex_unlock();
1104 return ret;
1107 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
1109 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1110 DWORD ret;
1112 TRACE("iface %p.\n", iface);
1114 wined3d_mutex_lock();
1115 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
1116 wined3d_mutex_unlock();
1118 return ret;
1121 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
1122 D3DTEXTUREFILTERTYPE filter_type)
1124 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
1126 return D3DERR_INVALIDCALL;
1129 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
1131 TRACE("iface %p.\n", iface);
1133 return D3DTEXF_NONE;
1136 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
1138 TRACE("iface %p.\n", iface);
1141 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
1143 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1144 struct wined3d_sub_resource_desc wined3d_desc;
1145 HRESULT hr;
1147 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
1149 wined3d_mutex_lock();
1150 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
1152 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
1153 desc->Type = D3DRTYPE_VOLUME;
1154 desc->Usage = texture->usage;
1155 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
1156 desc->Width = wined3d_desc.width;
1157 desc->Height = wined3d_desc.height;
1158 desc->Depth = wined3d_desc.depth;
1160 wined3d_mutex_unlock();
1162 return hr;
1165 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
1166 UINT level, IDirect3DVolume9 **volume)
1168 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1169 struct d3d9_volume *volume_impl;
1171 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1173 wined3d_mutex_lock();
1174 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1176 wined3d_mutex_unlock();
1177 return D3DERR_INVALIDCALL;
1180 *volume = &volume_impl->IDirect3DVolume9_iface;
1181 IDirect3DVolume9_AddRef(*volume);
1182 wined3d_mutex_unlock();
1184 return D3D_OK;
1187 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
1188 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1190 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1191 struct d3d9_volume *volume_impl;
1192 HRESULT hr;
1194 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1195 iface, level, locked_box, box, flags);
1197 wined3d_mutex_lock();
1198 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1199 hr = D3DERR_INVALIDCALL;
1200 else
1201 hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
1202 wined3d_mutex_unlock();
1204 return hr;
1207 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
1209 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1210 struct d3d9_volume *volume_impl;
1211 HRESULT hr;
1213 TRACE("iface %p, level %u.\n", iface, level);
1215 wined3d_mutex_lock();
1216 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1217 hr = D3DERR_INVALIDCALL;
1218 else
1219 hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
1220 wined3d_mutex_unlock();
1222 return hr;
1225 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
1227 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1228 HRESULT hr;
1230 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1232 wined3d_mutex_lock();
1233 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1234 wined3d_mutex_unlock();
1236 return hr;
1240 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
1242 /* IUnknown */
1243 d3d9_texture_3d_QueryInterface,
1244 d3d9_texture_3d_AddRef,
1245 d3d9_texture_3d_Release,
1246 /* IDirect3DResource9 */
1247 d3d9_texture_3d_GetDevice,
1248 d3d9_texture_3d_SetPrivateData,
1249 d3d9_texture_3d_GetPrivateData,
1250 d3d9_texture_3d_FreePrivateData,
1251 d3d9_texture_3d_SetPriority,
1252 d3d9_texture_3d_GetPriority,
1253 d3d9_texture_3d_PreLoad,
1254 d3d9_texture_3d_GetType,
1255 /* IDirect3DBaseTexture9 */
1256 d3d9_texture_3d_SetLOD,
1257 d3d9_texture_3d_GetLOD,
1258 d3d9_texture_3d_GetLevelCount,
1259 d3d9_texture_3d_SetAutoGenFilterType,
1260 d3d9_texture_3d_GetAutoGenFilterType,
1261 d3d9_texture_3d_GenerateMipSubLevels,
1262 /* IDirect3DVolumeTexture9 */
1263 d3d9_texture_3d_GetLevelDesc,
1264 d3d9_texture_3d_GetVolumeLevel,
1265 d3d9_texture_3d_LockBox,
1266 d3d9_texture_3d_UnlockBox,
1267 d3d9_texture_3d_AddDirtyBox,
1270 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
1272 if (!iface)
1273 return NULL;
1275 if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
1276 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
1277 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
1279 WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
1280 return NULL;
1283 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
1286 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
1288 struct d3d9_texture *texture = parent;
1289 d3d9_resource_cleanup(&texture->resource);
1290 heap_free(texture);
1293 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
1295 d3d9_texture_wined3d_object_destroyed,
1298 HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1299 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1301 struct wined3d_resource_desc desc;
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 hr = wined3d_check_device_format(device->d3d_parent->wined3d, WINED3DADAPTER_DEFAULT,
1352 WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_QUERY_GENMIPMAP,
1353 WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, wined3dformat_from_d3dformat(format));
1354 wined3d_mutex_unlock();
1355 if (hr == D3D_OK)
1357 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1358 levels = 0;
1360 else
1362 WARN("D3DUSAGE_AUTOGENMIPMAP not supported on D3DFORMAT %#x, creating a texture "
1363 "with a single level.\n", format);
1364 levels = 1;
1366 texture->autogen_filter_type = D3DTEXF_LINEAR;
1368 else
1370 texture->autogen_filter_type = D3DTEXF_NONE;
1372 if (!levels)
1373 levels = wined3d_log2i(max(width, height)) + 1;
1375 wined3d_mutex_lock();
1376 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
1377 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1378 wined3d_mutex_unlock();
1379 if (FAILED(hr))
1381 WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1382 return hr;
1385 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1386 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1388 return D3D_OK;
1391 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1392 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1394 struct wined3d_resource_desc desc;
1395 DWORD flags = 0;
1396 HRESULT hr;
1398 if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
1400 WARN("Managed resources are not supported by d3d9ex devices.\n");
1401 return D3DERR_INVALIDCALL;
1404 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
1405 d3d9_resource_init(&texture->resource);
1406 list_init(&texture->rtv_list);
1407 texture->usage = usage;
1409 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1410 desc.format = wined3dformat_from_d3dformat(format);
1411 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1412 desc.multisample_quality = 0;
1413 desc.usage = wined3dusage_from_d3dusage(usage);
1414 desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP;
1415 if (pool == D3DPOOL_SCRATCH)
1416 desc.usage |= WINED3DUSAGE_SCRATCH;
1417 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1418 desc.access = wined3daccess_from_d3dpool(pool, usage);
1419 desc.width = edge_length;
1420 desc.height = edge_length;
1421 desc.depth = 1;
1422 desc.size = 0;
1424 if (is_gdi_compat_wined3dformat(desc.format))
1425 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1427 if (usage & D3DUSAGE_WRITEONLY)
1429 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1430 return D3DERR_INVALIDCALL;
1432 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1434 if (pool == D3DPOOL_SYSTEMMEM)
1436 WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
1437 return D3DERR_INVALIDCALL;
1439 if (levels && levels != 1)
1441 WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
1442 return D3DERR_INVALIDCALL;
1444 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1445 texture->autogen_filter_type = D3DTEXF_LINEAR;
1446 levels = 0;
1448 else
1450 texture->autogen_filter_type = D3DTEXF_NONE;
1452 if (!levels)
1453 levels = wined3d_log2i(edge_length) + 1;
1455 wined3d_mutex_lock();
1456 hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
1457 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1458 wined3d_mutex_unlock();
1459 if (FAILED(hr))
1461 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1462 return hr;
1465 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1466 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1468 return D3D_OK;
1471 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1472 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1474 struct wined3d_resource_desc desc;
1475 HRESULT hr;
1477 if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
1479 WARN("Managed resources are not supported by d3d9ex devices.\n");
1480 return D3DERR_INVALIDCALL;
1483 /* In d3d9, 3D textures can't be used as rendertarget or depth/stencil buffer. */
1484 if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
1485 return D3DERR_INVALIDCALL;
1487 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
1488 d3d9_resource_init(&texture->resource);
1489 list_init(&texture->rtv_list);
1490 texture->usage = usage;
1492 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
1493 desc.format = wined3dformat_from_d3dformat(format);
1494 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1495 desc.multisample_quality = 0;
1496 desc.usage = wined3dusage_from_d3dusage(usage);
1497 if (pool == D3DPOOL_SCRATCH)
1498 desc.usage |= WINED3DUSAGE_SCRATCH;
1499 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1500 desc.access = wined3daccess_from_d3dpool(pool, usage);
1501 desc.width = width;
1502 desc.height = height;
1503 desc.depth = depth;
1504 desc.size = 0;
1506 if (usage & D3DUSAGE_WRITEONLY)
1508 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1509 return D3DERR_INVALIDCALL;
1511 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1513 WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n");
1514 return D3DERR_INVALIDCALL;
1516 if (!levels)
1517 levels = wined3d_log2i(max(max(width, height), depth)) + 1;
1519 wined3d_mutex_lock();
1520 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
1521 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1522 wined3d_mutex_unlock();
1523 if (FAILED(hr))
1525 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1526 return hr;
1529 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1530 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1532 return D3D_OK;