msvcp140: Added _Winerror_message implementation.
[wine.git] / dlls / d3d9 / texture.c
blob0858be99220d193053202da6bb1e51307baa4522
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 "d3d9_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
26 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
28 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
31 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
33 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
36 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
38 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
41 static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent)
43 struct d3d9_texture *texture = parent;
45 texture->wined3d_srv = NULL;
48 static const struct wined3d_parent_ops d3d9_srv_wined3d_parent_ops =
50 srv_wined3d_object_destroyed,
53 /* wined3d critical section must be taken by the caller. */
54 static struct wined3d_shader_resource_view *d3d9_texture_acquire_shader_resource_view(struct d3d9_texture *texture)
56 struct wined3d_sub_resource_desc sr_desc;
57 struct wined3d_view_desc desc;
58 HRESULT hr;
60 if (texture->wined3d_srv)
61 return texture->wined3d_srv;
63 wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, 0, &sr_desc);
64 desc.format_id = sr_desc.format;
65 desc.flags = 0;
66 desc.u.texture.level_idx = 0;
67 desc.u.texture.level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
68 desc.u.texture.layer_idx = 0;
69 desc.u.texture.layer_count = sr_desc.usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1;
70 if (FAILED(hr = wined3d_shader_resource_view_create(&desc,
71 wined3d_texture_get_resource(texture->wined3d_texture), texture,
72 &d3d9_srv_wined3d_parent_ops, &texture->wined3d_srv)))
74 ERR("Failed to create shader resource view, hr %#x.\n", hr);
75 return NULL;
78 return texture->wined3d_srv;
81 static void d3d9_texture_cleanup(struct d3d9_texture *texture)
83 IDirect3DDevice9Ex *parent_device = texture->parent_device;
84 struct d3d9_surface *surface;
86 wined3d_mutex_lock();
87 if (texture->wined3d_srv)
88 wined3d_shader_resource_view_decref(texture->wined3d_srv);
89 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
90 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
91 wined3d_texture_decref(texture->wined3d_texture);
92 wined3d_mutex_unlock();
94 /* Release the device last, as it may cause the device to be destroyed. */
95 IDirect3DDevice9Ex_Release(parent_device);
98 /* wined3d critical section must be taken by the caller. */
99 void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture)
101 if (!(texture->flags & D3D9_TEXTURE_MIPMAP_DIRTY))
102 return;
103 d3d9_texture_acquire_shader_resource_view(texture);
104 wined3d_shader_resource_view_generate_mipmaps(texture->wined3d_srv);
105 texture->flags &= ~D3D9_TEXTURE_MIPMAP_DIRTY;
108 void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture)
110 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
111 texture->flags |= D3D9_TEXTURE_MIPMAP_DIRTY;
114 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
116 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
118 if (IsEqualGUID(riid, &IID_IDirect3DTexture9)
119 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
120 || IsEqualGUID(riid, &IID_IDirect3DResource9)
121 || IsEqualGUID(riid, &IID_IUnknown))
123 IDirect3DTexture9_AddRef(iface);
124 *out = iface;
125 return S_OK;
128 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
130 *out = NULL;
131 return E_NOINTERFACE;
134 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
136 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
137 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
139 TRACE("%p increasing refcount to %u.\n", iface, ref);
141 if (ref == 1)
143 struct d3d9_surface *surface;
145 IDirect3DDevice9Ex_AddRef(texture->parent_device);
146 wined3d_mutex_lock();
147 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
149 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
151 wined3d_texture_incref(texture->wined3d_texture);
152 wined3d_mutex_unlock();
155 return ref;
158 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
160 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
161 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
163 TRACE("%p decreasing refcount to %u.\n", iface, ref);
165 if (!ref)
166 d3d9_texture_cleanup(texture);
167 return ref;
170 static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device)
172 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
174 TRACE("iface %p, device %p.\n", iface, device);
176 *device = (IDirect3DDevice9 *)texture->parent_device;
177 IDirect3DDevice9_AddRef(*device);
179 TRACE("Returning device %p.\n", *device);
181 return D3D_OK;
184 static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
185 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
187 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
188 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
189 iface, debugstr_guid(guid), data, data_size, flags);
191 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
194 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
195 REFGUID guid, void *data, DWORD *data_size)
197 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
198 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
199 iface, debugstr_guid(guid), data, data_size);
201 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
204 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
206 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
207 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
209 return d3d9_resource_free_private_data(&texture->resource, guid);
212 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
214 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
215 struct wined3d_resource *resource;
216 DWORD ret;
218 TRACE("iface %p, priority %u.\n", iface, priority);
220 wined3d_mutex_lock();
221 resource = wined3d_texture_get_resource(texture->wined3d_texture);
222 ret = wined3d_resource_set_priority(resource, priority);
223 wined3d_mutex_unlock();
225 return ret;
228 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
230 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
231 const struct wined3d_resource *resource;
232 DWORD ret;
234 TRACE("iface %p.\n", iface);
236 wined3d_mutex_lock();
237 resource = wined3d_texture_get_resource(texture->wined3d_texture);
238 ret = wined3d_resource_get_priority(resource);
239 wined3d_mutex_unlock();
241 return ret;
244 static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
246 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
248 TRACE("iface %p.\n", iface);
250 wined3d_mutex_lock();
251 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
252 wined3d_mutex_unlock();
255 static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface)
257 TRACE("iface %p.\n", iface);
259 return D3DRTYPE_TEXTURE;
262 static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod)
264 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
265 DWORD ret;
267 TRACE("iface %p, lod %u.\n", iface, lod);
269 wined3d_mutex_lock();
270 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
271 wined3d_mutex_unlock();
273 return ret;
276 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
278 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
279 DWORD ret;
281 TRACE("iface %p.\n", iface);
283 wined3d_mutex_lock();
284 ret = wined3d_texture_get_lod(texture->wined3d_texture);
285 wined3d_mutex_unlock();
287 return ret;
290 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
292 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
293 DWORD ret;
295 TRACE("iface %p.\n", iface);
297 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
298 return 1;
300 wined3d_mutex_lock();
301 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
302 wined3d_mutex_unlock();
304 return ret;
307 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
309 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
311 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
313 if (filter_type == D3DTEXF_NONE)
315 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
316 return D3DERR_INVALIDCALL;
318 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
319 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
320 else if (filter_type != D3DTEXF_LINEAR)
321 FIXME("Unsupported filter type %u.\n", filter_type);
323 texture->autogen_filter_type = filter_type;
324 return D3D_OK;
327 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
329 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
331 TRACE("iface %p.\n", iface);
333 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
334 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
336 return texture->autogen_filter_type;
339 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
341 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
343 TRACE("iface %p.\n", iface);
345 wined3d_mutex_lock();
346 d3d9_texture_gen_auto_mipmap(texture);
347 wined3d_mutex_unlock();
350 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
352 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
353 struct wined3d_sub_resource_desc wined3d_desc;
354 HRESULT hr;
356 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
358 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
360 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
361 return D3DERR_INVALIDCALL;
364 wined3d_mutex_lock();
365 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
367 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
368 desc->Type = D3DRTYPE_SURFACE;
369 desc->Usage = texture->usage;
370 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
371 desc->MultiSampleType = wined3d_desc.multisample_type;
372 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
373 desc->Width = wined3d_desc.width;
374 desc->Height = wined3d_desc.height;
376 wined3d_mutex_unlock();
378 return hr;
381 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
382 UINT level, IDirect3DSurface9 **surface)
384 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
385 struct d3d9_surface *surface_impl;
387 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
389 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
391 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
392 return D3DERR_INVALIDCALL;
395 wined3d_mutex_lock();
396 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
398 wined3d_mutex_unlock();
399 return D3DERR_INVALIDCALL;
402 *surface = &surface_impl->IDirect3DSurface9_iface;
403 IDirect3DSurface9_AddRef(*surface);
404 wined3d_mutex_unlock();
406 return D3D_OK;
409 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
410 UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
412 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
413 struct d3d9_surface *surface_impl;
414 HRESULT hr;
416 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
417 iface, level, locked_rect, rect, flags);
419 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
421 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
422 return D3DERR_INVALIDCALL;
425 wined3d_mutex_lock();
426 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
427 hr = D3DERR_INVALIDCALL;
428 else
429 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
430 wined3d_mutex_unlock();
432 return hr;
435 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
437 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
438 struct d3d9_surface *surface_impl;
439 HRESULT hr;
441 TRACE("iface %p, level %u.\n", iface, level);
443 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
445 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
446 return D3DERR_INVALIDCALL;
449 wined3d_mutex_lock();
450 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
451 hr = D3DERR_INVALIDCALL;
452 else
453 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
454 wined3d_mutex_unlock();
456 return hr;
459 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
461 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
462 HRESULT hr;
464 TRACE("iface %p, dirty_rect %s.\n",
465 iface, wine_dbgstr_rect(dirty_rect));
467 wined3d_mutex_lock();
468 if (!dirty_rect)
469 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
470 else
472 struct wined3d_box dirty_region;
474 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
475 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
477 wined3d_mutex_unlock();
479 return hr;
482 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
484 /* IUnknown */
485 d3d9_texture_2d_QueryInterface,
486 d3d9_texture_2d_AddRef,
487 d3d9_texture_2d_Release,
488 /* IDirect3DResource9 */
489 d3d9_texture_2d_GetDevice,
490 d3d9_texture_2d_SetPrivateData,
491 d3d9_texture_2d_GetPrivateData,
492 d3d9_texture_2d_FreePrivateData,
493 d3d9_texture_2d_SetPriority,
494 d3d9_texture_2d_GetPriority,
495 d3d9_texture_2d_PreLoad,
496 d3d9_texture_2d_GetType,
497 /* IDirect3dBaseTexture9 */
498 d3d9_texture_2d_SetLOD,
499 d3d9_texture_2d_GetLOD,
500 d3d9_texture_2d_GetLevelCount,
501 d3d9_texture_2d_SetAutoGenFilterType,
502 d3d9_texture_2d_GetAutoGenFilterType,
503 d3d9_texture_2d_GenerateMipSubLevels,
504 /* IDirect3DTexture9 */
505 d3d9_texture_2d_GetLevelDesc,
506 d3d9_texture_2d_GetSurfaceLevel,
507 d3d9_texture_2d_LockRect,
508 d3d9_texture_2d_UnlockRect,
509 d3d9_texture_2d_AddDirtyRect,
512 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
514 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
516 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
517 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
518 || IsEqualGUID(riid, &IID_IDirect3DResource9)
519 || IsEqualGUID(riid, &IID_IUnknown))
521 IDirect3DCubeTexture9_AddRef(iface);
522 *out = iface;
523 return S_OK;
526 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
528 *out = NULL;
529 return E_NOINTERFACE;
532 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
534 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
535 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
537 TRACE("%p increasing refcount to %u.\n", iface, ref);
539 if (ref == 1)
541 struct d3d9_surface *surface;
543 IDirect3DDevice9Ex_AddRef(texture->parent_device);
544 wined3d_mutex_lock();
545 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
547 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
549 wined3d_texture_incref(texture->wined3d_texture);
550 wined3d_mutex_unlock();
553 return ref;
556 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
558 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
559 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
561 TRACE("%p decreasing refcount to %u.\n", iface, ref);
563 if (!ref)
564 d3d9_texture_cleanup(texture);
565 return ref;
568 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
570 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
572 TRACE("iface %p, device %p.\n", iface, device);
574 *device = (IDirect3DDevice9 *)texture->parent_device;
575 IDirect3DDevice9_AddRef(*device);
577 TRACE("Returning device %p.\n", *device);
579 return D3D_OK;
582 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
583 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
585 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
586 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
587 iface, debugstr_guid(guid), data, data_size, flags);
589 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
592 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
593 REFGUID guid, void *data, DWORD *data_size)
595 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
596 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
597 iface, debugstr_guid(guid), data, data_size);
599 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
602 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
604 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
605 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
607 return d3d9_resource_free_private_data(&texture->resource, guid);
610 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
612 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
613 struct wined3d_resource *resource;
614 DWORD ret;
616 TRACE("iface %p, priority %u.\n", iface, priority);
618 wined3d_mutex_lock();
619 resource = wined3d_texture_get_resource(texture->wined3d_texture);
620 ret = wined3d_resource_set_priority(resource, priority);
621 wined3d_mutex_unlock();
623 return ret;
626 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
628 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
629 const struct wined3d_resource *resource;
630 DWORD ret;
632 TRACE("iface %p.\n", iface);
634 wined3d_mutex_lock();
635 resource = wined3d_texture_get_resource(texture->wined3d_texture);
636 ret = wined3d_resource_get_priority(resource);
637 wined3d_mutex_unlock();
639 return ret;
642 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
644 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
646 TRACE("iface %p.\n", iface);
648 wined3d_mutex_lock();
649 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
650 wined3d_mutex_unlock();
653 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
655 TRACE("iface %p.\n", iface);
657 return D3DRTYPE_CUBETEXTURE;
660 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
662 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
663 DWORD ret;
665 TRACE("iface %p, lod %u.\n", iface, lod);
667 wined3d_mutex_lock();
668 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
669 wined3d_mutex_unlock();
671 return ret;
674 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
676 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
677 DWORD ret;
679 TRACE("iface %p.\n", iface);
681 wined3d_mutex_lock();
682 ret = wined3d_texture_get_lod(texture->wined3d_texture);
683 wined3d_mutex_unlock();
685 return ret;
688 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
690 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
691 DWORD ret;
693 TRACE("iface %p.\n", iface);
695 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
696 return 1;
698 wined3d_mutex_lock();
699 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
700 wined3d_mutex_unlock();
702 return ret;
705 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
706 D3DTEXTUREFILTERTYPE filter_type)
708 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
710 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
712 if (filter_type == D3DTEXF_NONE)
714 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
715 return D3DERR_INVALIDCALL;
717 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
718 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
719 else if (filter_type != D3DTEXF_LINEAR)
720 FIXME("Unsupported filter type %u.\n", filter_type);
722 texture->autogen_filter_type = filter_type;
723 return D3D_OK;
726 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
728 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
730 TRACE("iface %p.\n", iface);
732 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
733 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
735 return texture->autogen_filter_type;
738 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
740 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
742 TRACE("iface %p.\n", iface);
744 wined3d_mutex_lock();
745 d3d9_texture_gen_auto_mipmap(texture);
746 wined3d_mutex_unlock();
749 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
751 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
752 struct wined3d_sub_resource_desc wined3d_desc;
753 DWORD level_count;
754 HRESULT hr;
756 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
758 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
760 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
761 return D3DERR_INVALIDCALL;
764 wined3d_mutex_lock();
765 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
766 if (level >= level_count)
768 wined3d_mutex_unlock();
769 return D3DERR_INVALIDCALL;
772 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
774 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
775 desc->Type = D3DRTYPE_SURFACE;
776 desc->Usage = texture->usage;
777 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
778 desc->MultiSampleType = wined3d_desc.multisample_type;
779 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
780 desc->Width = wined3d_desc.width;
781 desc->Height = wined3d_desc.height;
783 wined3d_mutex_unlock();
785 return hr;
788 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
789 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
791 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
792 struct d3d9_surface *surface_impl;
793 UINT sub_resource_idx;
794 DWORD level_count;
796 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
798 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
800 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
801 return D3DERR_INVALIDCALL;
804 wined3d_mutex_lock();
805 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
806 if (level >= level_count)
808 wined3d_mutex_unlock();
809 return D3DERR_INVALIDCALL;
812 sub_resource_idx = level_count * face + level;
813 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
815 wined3d_mutex_unlock();
816 return D3DERR_INVALIDCALL;
819 *surface = &surface_impl->IDirect3DSurface9_iface;
820 IDirect3DSurface9_AddRef(*surface);
821 wined3d_mutex_unlock();
823 return D3D_OK;
826 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
827 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
828 DWORD flags)
830 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
831 struct d3d9_surface *surface_impl;
832 UINT sub_resource_idx;
833 HRESULT hr;
835 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
836 iface, face, level, locked_rect, rect, flags);
838 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
840 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
841 return D3DERR_INVALIDCALL;
844 wined3d_mutex_lock();
845 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
846 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
847 hr = D3DERR_INVALIDCALL;
848 else
849 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
850 wined3d_mutex_unlock();
852 return hr;
855 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
856 D3DCUBEMAP_FACES face, UINT level)
858 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
859 struct d3d9_surface *surface_impl;
860 UINT sub_resource_idx;
861 HRESULT hr;
863 TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
865 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
867 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
868 return D3DERR_INVALIDCALL;
871 wined3d_mutex_lock();
872 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
873 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
874 hr = D3DERR_INVALIDCALL;
875 else
876 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
877 wined3d_mutex_unlock();
879 return hr;
882 static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
883 D3DCUBEMAP_FACES face, const RECT *dirty_rect)
885 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
886 HRESULT hr;
888 TRACE("iface %p, face %#x, dirty_rect %s.\n",
889 iface, face, wine_dbgstr_rect(dirty_rect));
891 wined3d_mutex_lock();
892 if (!dirty_rect)
893 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
894 else
896 struct wined3d_box dirty_region;
898 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
899 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
901 wined3d_mutex_unlock();
903 return hr;
906 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
908 /* IUnknown */
909 d3d9_texture_cube_QueryInterface,
910 d3d9_texture_cube_AddRef,
911 d3d9_texture_cube_Release,
912 /* IDirect3DResource9 */
913 d3d9_texture_cube_GetDevice,
914 d3d9_texture_cube_SetPrivateData,
915 d3d9_texture_cube_GetPrivateData,
916 d3d9_texture_cube_FreePrivateData,
917 d3d9_texture_cube_SetPriority,
918 d3d9_texture_cube_GetPriority,
919 d3d9_texture_cube_PreLoad,
920 d3d9_texture_cube_GetType,
921 /* IDirect3DBaseTexture9 */
922 d3d9_texture_cube_SetLOD,
923 d3d9_texture_cube_GetLOD,
924 d3d9_texture_cube_GetLevelCount,
925 d3d9_texture_cube_SetAutoGenFilterType,
926 d3d9_texture_cube_GetAutoGenFilterType,
927 d3d9_texture_cube_GenerateMipSubLevels,
928 /* IDirect3DCubeTexture9 */
929 d3d9_texture_cube_GetLevelDesc,
930 d3d9_texture_cube_GetCubeMapSurface,
931 d3d9_texture_cube_LockRect,
932 d3d9_texture_cube_UnlockRect,
933 d3d9_texture_cube_AddDirtyRect,
936 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
938 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
940 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
941 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
942 || IsEqualGUID(riid, &IID_IDirect3DResource9)
943 || IsEqualGUID(riid, &IID_IUnknown))
945 IDirect3DVolumeTexture9_AddRef(iface);
946 *out = iface;
947 return S_OK;
950 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
952 *out = NULL;
953 return E_NOINTERFACE;
956 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
958 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
959 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
961 TRACE("%p increasing refcount to %u.\n", iface, ref);
963 if (ref == 1)
965 IDirect3DDevice9Ex_AddRef(texture->parent_device);
966 wined3d_mutex_lock();
967 wined3d_texture_incref(texture->wined3d_texture);
968 wined3d_mutex_unlock();
971 return ref;
974 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
976 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
977 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
979 TRACE("%p decreasing refcount to %u.\n", iface, ref);
981 if (!ref)
982 d3d9_texture_cleanup(texture);
983 return ref;
986 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
988 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
990 TRACE("iface %p, device %p.\n", iface, device);
992 *device = (IDirect3DDevice9 *)texture->parent_device;
993 IDirect3DDevice9_AddRef(*device);
995 TRACE("Returning device %p.\n", *device);
997 return D3D_OK;
1000 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
1001 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
1003 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1004 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
1005 iface, debugstr_guid(guid), data, data_size, flags);
1007 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
1010 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
1011 REFGUID guid, void *data, DWORD *data_size)
1013 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1014 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
1015 iface, debugstr_guid(guid), data, data_size);
1017 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
1020 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
1022 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1023 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1025 return d3d9_resource_free_private_data(&texture->resource, guid);
1028 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
1030 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1031 struct wined3d_resource *resource;
1032 DWORD ret;
1034 TRACE("iface %p, priority %u.\n", iface, priority);
1036 wined3d_mutex_lock();
1037 resource = wined3d_texture_get_resource(texture->wined3d_texture);
1038 ret = wined3d_resource_set_priority(resource, priority);
1039 wined3d_mutex_unlock();
1041 return ret;
1044 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
1046 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1047 const struct wined3d_resource *resource;
1048 DWORD ret;
1050 TRACE("iface %p.\n", iface);
1052 wined3d_mutex_lock();
1053 resource = wined3d_texture_get_resource(texture->wined3d_texture);
1054 ret = wined3d_resource_get_priority(resource);
1055 wined3d_mutex_unlock();
1057 return ret;
1060 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
1062 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1064 TRACE("iface %p.\n", iface);
1066 wined3d_mutex_lock();
1067 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
1068 wined3d_mutex_unlock();
1071 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
1073 TRACE("iface %p.\n", iface);
1075 return D3DRTYPE_VOLUMETEXTURE;
1078 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
1080 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1081 DWORD ret;
1083 TRACE("iface %p, lod %u.\n", iface, lod);
1085 wined3d_mutex_lock();
1086 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
1087 wined3d_mutex_unlock();
1089 return ret;
1092 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
1094 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1095 DWORD ret;
1097 TRACE("iface %p.\n", iface);
1099 wined3d_mutex_lock();
1100 ret = wined3d_texture_get_lod(texture->wined3d_texture);
1101 wined3d_mutex_unlock();
1103 return ret;
1106 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
1108 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1109 DWORD ret;
1111 TRACE("iface %p.\n", iface);
1113 wined3d_mutex_lock();
1114 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
1115 wined3d_mutex_unlock();
1117 return ret;
1120 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
1121 D3DTEXTUREFILTERTYPE filter_type)
1123 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
1125 return D3DERR_INVALIDCALL;
1128 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
1130 TRACE("iface %p.\n", iface);
1132 return D3DTEXF_NONE;
1135 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
1137 TRACE("iface %p.\n", iface);
1140 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
1142 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1143 struct wined3d_sub_resource_desc wined3d_desc;
1144 HRESULT hr;
1146 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
1148 wined3d_mutex_lock();
1149 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
1151 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
1152 desc->Type = D3DRTYPE_VOLUME;
1153 desc->Usage = texture->usage;
1154 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
1155 desc->Width = wined3d_desc.width;
1156 desc->Height = wined3d_desc.height;
1157 desc->Depth = wined3d_desc.depth;
1159 wined3d_mutex_unlock();
1161 return hr;
1164 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
1165 UINT level, IDirect3DVolume9 **volume)
1167 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1168 struct d3d9_volume *volume_impl;
1170 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1172 wined3d_mutex_lock();
1173 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1175 wined3d_mutex_unlock();
1176 return D3DERR_INVALIDCALL;
1179 *volume = &volume_impl->IDirect3DVolume9_iface;
1180 IDirect3DVolume9_AddRef(*volume);
1181 wined3d_mutex_unlock();
1183 return D3D_OK;
1186 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
1187 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1189 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1190 struct d3d9_volume *volume_impl;
1191 HRESULT hr;
1193 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1194 iface, level, locked_box, box, flags);
1196 wined3d_mutex_lock();
1197 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1198 hr = D3DERR_INVALIDCALL;
1199 else
1200 hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
1201 wined3d_mutex_unlock();
1203 return hr;
1206 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
1208 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1209 struct d3d9_volume *volume_impl;
1210 HRESULT hr;
1212 TRACE("iface %p, level %u.\n", iface, level);
1214 wined3d_mutex_lock();
1215 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1216 hr = D3DERR_INVALIDCALL;
1217 else
1218 hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
1219 wined3d_mutex_unlock();
1221 return hr;
1224 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
1226 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1227 HRESULT hr;
1229 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1231 wined3d_mutex_lock();
1232 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1233 wined3d_mutex_unlock();
1235 return hr;
1239 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
1241 /* IUnknown */
1242 d3d9_texture_3d_QueryInterface,
1243 d3d9_texture_3d_AddRef,
1244 d3d9_texture_3d_Release,
1245 /* IDirect3DResource9 */
1246 d3d9_texture_3d_GetDevice,
1247 d3d9_texture_3d_SetPrivateData,
1248 d3d9_texture_3d_GetPrivateData,
1249 d3d9_texture_3d_FreePrivateData,
1250 d3d9_texture_3d_SetPriority,
1251 d3d9_texture_3d_GetPriority,
1252 d3d9_texture_3d_PreLoad,
1253 d3d9_texture_3d_GetType,
1254 /* IDirect3DBaseTexture9 */
1255 d3d9_texture_3d_SetLOD,
1256 d3d9_texture_3d_GetLOD,
1257 d3d9_texture_3d_GetLevelCount,
1258 d3d9_texture_3d_SetAutoGenFilterType,
1259 d3d9_texture_3d_GetAutoGenFilterType,
1260 d3d9_texture_3d_GenerateMipSubLevels,
1261 /* IDirect3DVolumeTexture9 */
1262 d3d9_texture_3d_GetLevelDesc,
1263 d3d9_texture_3d_GetVolumeLevel,
1264 d3d9_texture_3d_LockBox,
1265 d3d9_texture_3d_UnlockBox,
1266 d3d9_texture_3d_AddDirtyBox,
1269 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
1271 if (!iface)
1272 return NULL;
1274 if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
1275 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
1276 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
1278 WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
1279 return NULL;
1282 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
1285 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
1287 struct d3d9_texture *texture = parent;
1288 d3d9_resource_cleanup(&texture->resource);
1289 heap_free(texture);
1292 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
1294 d3d9_texture_wined3d_object_destroyed,
1297 HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1298 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1300 struct wined3d_resource_desc desc;
1301 DWORD flags = 0;
1302 HRESULT hr;
1304 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
1305 d3d9_resource_init(&texture->resource);
1306 list_init(&texture->rtv_list);
1307 texture->usage = usage;
1309 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1310 desc.format = wined3dformat_from_d3dformat(format);
1311 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1312 desc.multisample_quality = 0;
1313 desc.usage = wined3dusage_from_d3dusage(usage);
1314 desc.usage |= WINED3DUSAGE_TEXTURE;
1315 if (pool == D3DPOOL_SCRATCH)
1316 desc.usage |= WINED3DUSAGE_SCRATCH;
1317 desc.access = wined3daccess_from_d3dpool(pool, usage)
1318 | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
1319 desc.width = width;
1320 desc.height = height;
1321 desc.depth = 1;
1322 desc.size = 0;
1324 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1325 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
1327 if (is_gdi_compat_wined3dformat(desc.format))
1328 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1330 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1332 if (pool == D3DPOOL_SYSTEMMEM)
1334 WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
1335 return D3DERR_INVALIDCALL;
1337 if (levels && levels != 1)
1339 WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
1340 return D3DERR_INVALIDCALL;
1342 wined3d_mutex_lock();
1343 hr = wined3d_check_device_format(device->d3d_parent->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM,
1344 WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_GENMIPMAP, WINED3D_RTYPE_TEXTURE_2D, wined3dformat_from_d3dformat(format));
1345 wined3d_mutex_unlock();
1346 if (hr == D3D_OK)
1348 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1349 levels = 0;
1351 else
1353 WARN("D3DUSAGE_AUTOGENMIPMAP not supported on D3DFORMAT %#x, creating a texture "
1354 "with a single level.\n", format);
1355 levels = 1;
1357 texture->autogen_filter_type = D3DTEXF_LINEAR;
1359 else
1361 texture->autogen_filter_type = D3DTEXF_NONE;
1363 if (!levels)
1364 levels = wined3d_log2i(max(width, height)) + 1;
1366 wined3d_mutex_lock();
1367 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
1368 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1369 wined3d_mutex_unlock();
1370 if (FAILED(hr))
1372 WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1373 return hr;
1376 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1377 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1379 return D3D_OK;
1382 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1383 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1385 struct wined3d_resource_desc desc;
1386 DWORD flags = 0;
1387 HRESULT hr;
1389 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
1390 d3d9_resource_init(&texture->resource);
1391 list_init(&texture->rtv_list);
1392 texture->usage = usage;
1394 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1395 desc.format = wined3dformat_from_d3dformat(format);
1396 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1397 desc.multisample_quality = 0;
1398 desc.usage = wined3dusage_from_d3dusage(usage);
1399 desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
1400 if (pool == D3DPOOL_SCRATCH)
1401 desc.usage |= WINED3DUSAGE_SCRATCH;
1402 desc.access = wined3daccess_from_d3dpool(pool, usage)
1403 | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
1404 desc.width = edge_length;
1405 desc.height = edge_length;
1406 desc.depth = 1;
1407 desc.size = 0;
1409 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1410 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
1412 if (is_gdi_compat_wined3dformat(desc.format))
1413 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1415 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1417 if (pool == D3DPOOL_SYSTEMMEM)
1419 WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
1420 return D3DERR_INVALIDCALL;
1422 if (levels && levels != 1)
1424 WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels);
1425 return D3DERR_INVALIDCALL;
1427 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1428 texture->autogen_filter_type = D3DTEXF_LINEAR;
1429 levels = 0;
1431 else
1433 texture->autogen_filter_type = D3DTEXF_NONE;
1435 if (!levels)
1436 levels = wined3d_log2i(edge_length) + 1;
1438 wined3d_mutex_lock();
1439 hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
1440 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1441 wined3d_mutex_unlock();
1442 if (FAILED(hr))
1444 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1445 return hr;
1448 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1449 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1451 return D3D_OK;
1454 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1455 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1457 struct wined3d_resource_desc desc;
1458 HRESULT hr;
1460 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
1461 d3d9_resource_init(&texture->resource);
1462 list_init(&texture->rtv_list);
1463 texture->usage = usage;
1465 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
1466 desc.format = wined3dformat_from_d3dformat(format);
1467 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1468 desc.multisample_quality = 0;
1469 desc.usage = wined3dusage_from_d3dusage(usage);
1470 desc.usage |= WINED3DUSAGE_TEXTURE;
1471 if (pool == D3DPOOL_SCRATCH)
1472 desc.usage |= WINED3DUSAGE_SCRATCH;
1473 desc.access = wined3daccess_from_d3dpool(pool, usage);
1474 desc.width = width;
1475 desc.height = height;
1476 desc.depth = depth;
1477 desc.size = 0;
1479 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1481 WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n");
1482 return D3DERR_INVALIDCALL;
1484 if (!levels)
1485 levels = wined3d_log2i(max(max(width, height), depth)) + 1;
1487 wined3d_mutex_lock();
1488 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
1489 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1490 wined3d_mutex_unlock();
1491 if (FAILED(hr))
1493 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1494 return hr;
1497 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1498 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1500 return D3D_OK;