cmd: DIR command outputs free space for the path.
[wine.git] / dlls / d3d9 / texture.c
blob3adfaaee2f3874ee6c1e3719a658851c7a316ed1
1 /*
2 * Copyright 2002-2005 Jason Edmeades
3 * Copyright 2002-2005 Raphael Junqueira
4 * Copyright 2005 Oliver Stieber
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "d3d9_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
25 static ULONG d3d9_texture_incref(struct d3d9_texture *texture)
27 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
29 TRACE("%p increasing refcount to %lu.\n", texture, ref);
31 if (ref == 1)
33 struct d3d9_surface *surface;
35 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
36 wined3d_mutex_lock();
37 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
39 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
41 wined3d_texture_incref(d3d9_texture_get_draw_texture(texture));
42 wined3d_mutex_unlock();
45 return ref;
48 static ULONG d3d9_texture_decref(struct d3d9_texture *texture)
50 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
52 TRACE("%p decreasing refcount to %lu.\n", texture, ref);
54 if (!ref)
56 IDirect3DDevice9Ex *parent_device = &texture->parent_device->IDirect3DDevice9Ex_iface;
57 struct d3d9_surface *surface;
59 wined3d_mutex_lock();
60 if (texture->wined3d_srv)
61 wined3d_shader_resource_view_decref(texture->wined3d_srv);
62 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
63 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
64 wined3d_texture_decref(d3d9_texture_get_draw_texture(texture));
65 wined3d_mutex_unlock();
67 /* Release the device last, as it may cause the device to be destroyed. */
68 IDirect3DDevice9Ex_Release(parent_device);
70 return ref;
73 static void d3d9_texture_preload(struct d3d9_texture *texture)
75 wined3d_mutex_lock();
76 wined3d_resource_preload(wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture)));
77 wined3d_mutex_unlock();
80 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
82 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
85 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
87 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
90 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
92 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
95 static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent)
97 struct d3d9_texture *texture = parent;
99 texture->wined3d_srv = NULL;
102 static const struct wined3d_parent_ops d3d9_srv_wined3d_parent_ops =
104 srv_wined3d_object_destroyed,
107 /* wined3d critical section must be taken by the caller. */
108 static struct wined3d_shader_resource_view *d3d9_texture_acquire_shader_resource_view(struct d3d9_texture *texture)
110 struct wined3d_sub_resource_desc sr_desc;
111 struct wined3d_view_desc desc;
112 HRESULT hr;
114 if (texture->wined3d_srv)
115 return texture->wined3d_srv;
117 wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, 0, &sr_desc);
118 desc.format_id = sr_desc.format;
119 desc.flags = 0;
120 desc.u.texture.level_idx = 0;
121 desc.u.texture.level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
122 desc.u.texture.layer_idx = 0;
123 desc.u.texture.layer_count = sr_desc.usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1;
124 if (FAILED(hr = wined3d_shader_resource_view_create(&desc,
125 wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture)), texture,
126 &d3d9_srv_wined3d_parent_ops, &texture->wined3d_srv)))
128 ERR("Failed to create shader resource view, hr %#lx.\n", hr);
129 return NULL;
132 return texture->wined3d_srv;
135 /* wined3d critical section must be taken by the caller. */
136 void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture)
138 if (!(texture->flags & D3D9_TEXTURE_MIPMAP_DIRTY))
139 return;
140 d3d9_texture_acquire_shader_resource_view(texture);
141 if (texture->draw_texture)
142 wined3d_device_update_texture(texture->parent_device->wined3d_device,
143 texture->wined3d_texture, texture->draw_texture);
144 wined3d_device_context_generate_mipmaps(texture->parent_device->immediate_context, texture->wined3d_srv);
145 texture->flags &= ~D3D9_TEXTURE_MIPMAP_DIRTY;
148 void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture)
150 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
151 texture->flags |= D3D9_TEXTURE_MIPMAP_DIRTY;
154 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
156 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
158 if (IsEqualGUID(riid, &IID_IDirect3DTexture9)
159 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
160 || IsEqualGUID(riid, &IID_IDirect3DResource9)
161 || IsEqualGUID(riid, &IID_IUnknown))
163 IDirect3DTexture9_AddRef(iface);
164 *out = iface;
165 return S_OK;
168 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
170 *out = NULL;
171 return E_NOINTERFACE;
174 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
176 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
178 return d3d9_texture_incref(texture);
181 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
183 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
185 return d3d9_texture_decref(texture);
188 static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device)
190 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
192 TRACE("iface %p, device %p.\n", iface, device);
194 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
195 IDirect3DDevice9_AddRef(*device);
197 TRACE("Returning device %p.\n", *device);
199 return D3D_OK;
202 static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
203 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
205 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
206 TRACE("iface %p, guid %s, data %p, data_size %lu, flags %#lx.\n",
207 iface, debugstr_guid(guid), data, data_size, flags);
209 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
212 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
213 REFGUID guid, void *data, DWORD *data_size)
215 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
216 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
217 iface, debugstr_guid(guid), data, data_size);
219 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
222 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
224 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
225 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
227 return d3d9_resource_free_private_data(&texture->resource, guid);
230 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
232 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
233 struct wined3d_resource *resource;
234 DWORD ret;
236 TRACE("iface %p, priority %lu.\n", iface, priority);
238 wined3d_mutex_lock();
239 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
240 ret = wined3d_resource_set_priority(resource, priority);
241 wined3d_mutex_unlock();
243 return ret;
246 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
248 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
249 const struct wined3d_resource *resource;
250 DWORD ret;
252 TRACE("iface %p.\n", iface);
254 wined3d_mutex_lock();
255 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
256 ret = wined3d_resource_get_priority(resource);
257 wined3d_mutex_unlock();
259 return ret;
262 static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
264 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
266 TRACE("iface %p.\n", iface);
268 d3d9_texture_preload(texture);
271 static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface)
273 TRACE("iface %p.\n", iface);
275 return D3DRTYPE_TEXTURE;
278 static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod)
280 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
281 DWORD ret;
283 TRACE("iface %p, lod %lu.\n", iface, lod);
285 wined3d_mutex_lock();
286 ret = wined3d_texture_set_lod(d3d9_texture_get_draw_texture(texture), lod);
287 wined3d_mutex_unlock();
289 return ret;
292 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
294 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
295 DWORD ret;
297 TRACE("iface %p.\n", iface);
299 wined3d_mutex_lock();
300 ret = wined3d_texture_get_lod(d3d9_texture_get_draw_texture(texture));
301 wined3d_mutex_unlock();
303 return ret;
306 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
308 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
309 DWORD ret;
311 TRACE("iface %p.\n", iface);
313 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
314 return 1;
316 wined3d_mutex_lock();
317 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
318 wined3d_mutex_unlock();
320 return ret;
323 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
325 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
327 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
329 if (filter_type == D3DTEXF_NONE)
331 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
332 return D3DERR_INVALIDCALL;
334 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
335 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
336 else if (filter_type != D3DTEXF_LINEAR)
337 FIXME("Unsupported filter type %u.\n", filter_type);
339 texture->autogen_filter_type = filter_type;
340 return D3D_OK;
343 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
345 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
347 TRACE("iface %p.\n", iface);
349 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
350 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
352 return texture->autogen_filter_type;
355 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
357 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
359 TRACE("iface %p.\n", iface);
361 wined3d_mutex_lock();
362 d3d9_texture_gen_auto_mipmap(texture);
363 wined3d_mutex_unlock();
366 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
368 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
369 struct wined3d_sub_resource_desc wined3d_desc;
370 HRESULT hr;
372 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
374 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
376 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
377 return D3DERR_INVALIDCALL;
380 wined3d_mutex_lock();
381 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
383 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
384 desc->Type = D3DRTYPE_SURFACE;
385 desc->Usage = texture->usage;
386 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
387 desc->MultiSampleType = d3dmultisample_type_from_wined3d(wined3d_desc.multisample_type);
388 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
389 desc->Width = wined3d_desc.width;
390 desc->Height = wined3d_desc.height;
392 wined3d_mutex_unlock();
394 return hr;
397 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
398 UINT level, IDirect3DSurface9 **surface)
400 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
401 struct d3d9_surface *surface_impl;
403 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
405 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
407 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
408 return D3DERR_INVALIDCALL;
411 wined3d_mutex_lock();
412 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
414 wined3d_mutex_unlock();
415 return D3DERR_INVALIDCALL;
418 *surface = &surface_impl->IDirect3DSurface9_iface;
419 IDirect3DSurface9_AddRef(*surface);
420 wined3d_mutex_unlock();
422 return D3D_OK;
425 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
426 UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
428 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
429 struct d3d9_surface *surface_impl;
430 HRESULT hr;
432 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#lx.\n",
433 iface, level, locked_rect, rect, flags);
435 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
437 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
438 return D3DERR_INVALIDCALL;
441 wined3d_mutex_lock();
442 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
443 hr = D3DERR_INVALIDCALL;
444 else
445 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
446 wined3d_mutex_unlock();
448 return hr;
451 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
453 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
454 struct d3d9_surface *surface_impl;
455 HRESULT hr;
457 TRACE("iface %p, level %u.\n", iface, level);
459 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
461 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
462 return D3DERR_INVALIDCALL;
465 wined3d_mutex_lock();
466 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
467 hr = D3DERR_INVALIDCALL;
468 else
469 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
470 wined3d_mutex_unlock();
472 return hr;
475 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
477 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
478 HRESULT hr;
480 TRACE("iface %p, dirty_rect %s.\n",
481 iface, wine_dbgstr_rect(dirty_rect));
483 wined3d_mutex_lock();
484 if (!dirty_rect)
485 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
486 else
488 struct wined3d_box dirty_region;
490 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
491 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
493 wined3d_mutex_unlock();
495 return hr;
498 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
500 /* IUnknown */
501 d3d9_texture_2d_QueryInterface,
502 d3d9_texture_2d_AddRef,
503 d3d9_texture_2d_Release,
504 /* IDirect3DResource9 */
505 d3d9_texture_2d_GetDevice,
506 d3d9_texture_2d_SetPrivateData,
507 d3d9_texture_2d_GetPrivateData,
508 d3d9_texture_2d_FreePrivateData,
509 d3d9_texture_2d_SetPriority,
510 d3d9_texture_2d_GetPriority,
511 d3d9_texture_2d_PreLoad,
512 d3d9_texture_2d_GetType,
513 /* IDirect3dBaseTexture9 */
514 d3d9_texture_2d_SetLOD,
515 d3d9_texture_2d_GetLOD,
516 d3d9_texture_2d_GetLevelCount,
517 d3d9_texture_2d_SetAutoGenFilterType,
518 d3d9_texture_2d_GetAutoGenFilterType,
519 d3d9_texture_2d_GenerateMipSubLevels,
520 /* IDirect3DTexture9 */
521 d3d9_texture_2d_GetLevelDesc,
522 d3d9_texture_2d_GetSurfaceLevel,
523 d3d9_texture_2d_LockRect,
524 d3d9_texture_2d_UnlockRect,
525 d3d9_texture_2d_AddDirtyRect,
528 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
530 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
532 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
533 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
534 || IsEqualGUID(riid, &IID_IDirect3DResource9)
535 || IsEqualGUID(riid, &IID_IUnknown))
537 IDirect3DCubeTexture9_AddRef(iface);
538 *out = iface;
539 return S_OK;
542 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
544 *out = NULL;
545 return E_NOINTERFACE;
548 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
550 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
552 return d3d9_texture_incref(texture);
555 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
557 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
559 return d3d9_texture_decref(texture);
562 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
564 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
566 TRACE("iface %p, device %p.\n", iface, device);
568 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
569 IDirect3DDevice9_AddRef(*device);
571 TRACE("Returning device %p.\n", *device);
573 return D3D_OK;
576 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
577 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
579 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
580 TRACE("iface %p, guid %s, data %p, data_size %lu, flags %#lx.\n",
581 iface, debugstr_guid(guid), data, data_size, flags);
583 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
586 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
587 REFGUID guid, void *data, DWORD *data_size)
589 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
590 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
591 iface, debugstr_guid(guid), data, data_size);
593 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
596 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
598 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
599 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
601 return d3d9_resource_free_private_data(&texture->resource, guid);
604 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
606 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
607 struct wined3d_resource *resource;
608 DWORD ret;
610 TRACE("iface %p, priority %lu.\n", iface, priority);
612 wined3d_mutex_lock();
613 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
614 ret = wined3d_resource_set_priority(resource, priority);
615 wined3d_mutex_unlock();
617 return ret;
620 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
622 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
623 const struct wined3d_resource *resource;
624 DWORD ret;
626 TRACE("iface %p.\n", iface);
628 wined3d_mutex_lock();
629 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
630 ret = wined3d_resource_get_priority(resource);
631 wined3d_mutex_unlock();
633 return ret;
636 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
638 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
640 TRACE("iface %p.\n", iface);
642 d3d9_texture_preload(texture);
645 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
647 TRACE("iface %p.\n", iface);
649 return D3DRTYPE_CUBETEXTURE;
652 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
654 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
655 DWORD ret;
657 TRACE("iface %p, lod %lu.\n", iface, lod);
659 wined3d_mutex_lock();
660 ret = wined3d_texture_set_lod(d3d9_texture_get_draw_texture(texture), lod);
661 wined3d_mutex_unlock();
663 return ret;
666 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
668 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
669 DWORD ret;
671 TRACE("iface %p.\n", iface);
673 wined3d_mutex_lock();
674 ret = wined3d_texture_get_lod(d3d9_texture_get_draw_texture(texture));
675 wined3d_mutex_unlock();
677 return ret;
680 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
682 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
683 DWORD ret;
685 TRACE("iface %p.\n", iface);
687 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
688 return 1;
690 wined3d_mutex_lock();
691 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
692 wined3d_mutex_unlock();
694 return ret;
697 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
698 D3DTEXTUREFILTERTYPE filter_type)
700 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
702 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
704 if (filter_type == D3DTEXF_NONE)
706 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
707 return D3DERR_INVALIDCALL;
709 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
710 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
711 else if (filter_type != D3DTEXF_LINEAR)
712 FIXME("Unsupported filter type %u.\n", filter_type);
714 texture->autogen_filter_type = filter_type;
715 return D3D_OK;
718 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
720 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
722 TRACE("iface %p.\n", iface);
724 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
725 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
727 return texture->autogen_filter_type;
730 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
732 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
734 TRACE("iface %p.\n", iface);
736 wined3d_mutex_lock();
737 d3d9_texture_gen_auto_mipmap(texture);
738 wined3d_mutex_unlock();
741 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
743 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
744 struct wined3d_sub_resource_desc wined3d_desc;
745 DWORD level_count;
746 HRESULT hr;
748 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
750 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
752 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
753 return D3DERR_INVALIDCALL;
756 wined3d_mutex_lock();
757 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
758 if (level >= level_count)
760 wined3d_mutex_unlock();
761 return D3DERR_INVALIDCALL;
764 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
766 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
767 desc->Type = D3DRTYPE_SURFACE;
768 desc->Usage = texture->usage;
769 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
770 desc->MultiSampleType = d3dmultisample_type_from_wined3d(wined3d_desc.multisample_type);
771 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
772 desc->Width = wined3d_desc.width;
773 desc->Height = wined3d_desc.height;
775 wined3d_mutex_unlock();
777 return hr;
780 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
781 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
783 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
784 struct d3d9_surface *surface_impl;
785 UINT sub_resource_idx;
786 DWORD level_count;
788 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
790 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
792 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
793 return D3DERR_INVALIDCALL;
796 wined3d_mutex_lock();
797 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
798 if (level >= level_count)
800 wined3d_mutex_unlock();
801 return D3DERR_INVALIDCALL;
804 sub_resource_idx = level_count * face + level;
805 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
807 wined3d_mutex_unlock();
808 return D3DERR_INVALIDCALL;
811 *surface = &surface_impl->IDirect3DSurface9_iface;
812 IDirect3DSurface9_AddRef(*surface);
813 wined3d_mutex_unlock();
815 return D3D_OK;
818 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
819 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
820 DWORD flags)
822 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
823 struct d3d9_surface *surface_impl;
824 UINT sub_resource_idx;
825 HRESULT hr;
827 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#lx.\n",
828 iface, face, level, locked_rect, rect, flags);
830 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
832 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
833 return D3DERR_INVALIDCALL;
836 wined3d_mutex_lock();
837 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
838 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
839 hr = D3DERR_INVALIDCALL;
840 else
841 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
842 wined3d_mutex_unlock();
844 return hr;
847 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
848 D3DCUBEMAP_FACES face, UINT level)
850 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
851 struct d3d9_surface *surface_impl;
852 UINT sub_resource_idx;
853 HRESULT hr;
855 TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
857 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
859 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
860 return D3DERR_INVALIDCALL;
863 wined3d_mutex_lock();
864 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
865 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
866 hr = D3DERR_INVALIDCALL;
867 else
868 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
869 wined3d_mutex_unlock();
871 return hr;
874 static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
875 D3DCUBEMAP_FACES face, const RECT *dirty_rect)
877 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
878 HRESULT hr;
880 TRACE("iface %p, face %#x, dirty_rect %s.\n",
881 iface, face, wine_dbgstr_rect(dirty_rect));
883 wined3d_mutex_lock();
884 if (!dirty_rect)
885 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
886 else
888 struct wined3d_box dirty_region;
890 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
891 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
893 wined3d_mutex_unlock();
895 return hr;
898 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
900 /* IUnknown */
901 d3d9_texture_cube_QueryInterface,
902 d3d9_texture_cube_AddRef,
903 d3d9_texture_cube_Release,
904 /* IDirect3DResource9 */
905 d3d9_texture_cube_GetDevice,
906 d3d9_texture_cube_SetPrivateData,
907 d3d9_texture_cube_GetPrivateData,
908 d3d9_texture_cube_FreePrivateData,
909 d3d9_texture_cube_SetPriority,
910 d3d9_texture_cube_GetPriority,
911 d3d9_texture_cube_PreLoad,
912 d3d9_texture_cube_GetType,
913 /* IDirect3DBaseTexture9 */
914 d3d9_texture_cube_SetLOD,
915 d3d9_texture_cube_GetLOD,
916 d3d9_texture_cube_GetLevelCount,
917 d3d9_texture_cube_SetAutoGenFilterType,
918 d3d9_texture_cube_GetAutoGenFilterType,
919 d3d9_texture_cube_GenerateMipSubLevels,
920 /* IDirect3DCubeTexture9 */
921 d3d9_texture_cube_GetLevelDesc,
922 d3d9_texture_cube_GetCubeMapSurface,
923 d3d9_texture_cube_LockRect,
924 d3d9_texture_cube_UnlockRect,
925 d3d9_texture_cube_AddDirtyRect,
928 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
930 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
932 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
933 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
934 || IsEqualGUID(riid, &IID_IDirect3DResource9)
935 || IsEqualGUID(riid, &IID_IUnknown))
937 IDirect3DVolumeTexture9_AddRef(iface);
938 *out = iface;
939 return S_OK;
942 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
944 *out = NULL;
945 return E_NOINTERFACE;
948 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
950 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
952 return d3d9_texture_incref(texture);
955 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
957 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
959 return d3d9_texture_decref(texture);
962 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
964 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
966 TRACE("iface %p, device %p.\n", iface, device);
968 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
969 IDirect3DDevice9_AddRef(*device);
971 TRACE("Returning device %p.\n", *device);
973 return D3D_OK;
976 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
977 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
979 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
980 TRACE("iface %p, guid %s, data %p, data_size %lu, flags %#lx.\n",
981 iface, debugstr_guid(guid), data, data_size, flags);
983 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
986 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
987 REFGUID guid, void *data, DWORD *data_size)
989 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
990 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
991 iface, debugstr_guid(guid), data, data_size);
993 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
996 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
998 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
999 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1001 return d3d9_resource_free_private_data(&texture->resource, guid);
1004 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
1006 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1007 struct wined3d_resource *resource;
1008 DWORD ret;
1010 TRACE("iface %p, priority %lu.\n", iface, priority);
1012 wined3d_mutex_lock();
1013 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
1014 ret = wined3d_resource_set_priority(resource, priority);
1015 wined3d_mutex_unlock();
1017 return ret;
1020 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
1022 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1023 const struct wined3d_resource *resource;
1024 DWORD ret;
1026 TRACE("iface %p.\n", iface);
1028 wined3d_mutex_lock();
1029 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
1030 ret = wined3d_resource_get_priority(resource);
1031 wined3d_mutex_unlock();
1033 return ret;
1036 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
1038 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1040 TRACE("iface %p.\n", iface);
1042 d3d9_texture_preload(texture);
1045 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
1047 TRACE("iface %p.\n", iface);
1049 return D3DRTYPE_VOLUMETEXTURE;
1052 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
1054 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1055 DWORD ret;
1057 TRACE("iface %p, lod %lu.\n", iface, lod);
1059 wined3d_mutex_lock();
1060 ret = wined3d_texture_set_lod(d3d9_texture_get_draw_texture(texture), lod);
1061 wined3d_mutex_unlock();
1063 return ret;
1066 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
1068 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1069 DWORD ret;
1071 TRACE("iface %p.\n", iface);
1073 wined3d_mutex_lock();
1074 ret = wined3d_texture_get_lod(d3d9_texture_get_draw_texture(texture));
1075 wined3d_mutex_unlock();
1077 return ret;
1080 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
1082 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1083 DWORD ret;
1085 TRACE("iface %p.\n", iface);
1087 wined3d_mutex_lock();
1088 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
1089 wined3d_mutex_unlock();
1091 return ret;
1094 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
1095 D3DTEXTUREFILTERTYPE filter_type)
1097 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
1099 return D3DERR_INVALIDCALL;
1102 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
1104 TRACE("iface %p.\n", iface);
1106 return D3DTEXF_NONE;
1109 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
1111 TRACE("iface %p.\n", iface);
1114 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
1116 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1117 struct wined3d_sub_resource_desc wined3d_desc;
1118 HRESULT hr;
1120 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
1122 wined3d_mutex_lock();
1123 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
1125 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
1126 desc->Type = D3DRTYPE_VOLUME;
1127 desc->Usage = texture->usage;
1128 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
1129 desc->Width = wined3d_desc.width;
1130 desc->Height = wined3d_desc.height;
1131 desc->Depth = wined3d_desc.depth;
1133 wined3d_mutex_unlock();
1135 return hr;
1138 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
1139 UINT level, IDirect3DVolume9 **volume)
1141 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1142 struct d3d9_volume *volume_impl;
1144 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1146 wined3d_mutex_lock();
1147 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1149 wined3d_mutex_unlock();
1150 return D3DERR_INVALIDCALL;
1153 *volume = &volume_impl->IDirect3DVolume9_iface;
1154 IDirect3DVolume9_AddRef(*volume);
1155 wined3d_mutex_unlock();
1157 return D3D_OK;
1160 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
1161 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1163 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1164 struct d3d9_volume *volume_impl;
1165 HRESULT hr;
1167 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#lx.\n",
1168 iface, level, locked_box, box, flags);
1170 wined3d_mutex_lock();
1171 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1172 hr = D3DERR_INVALIDCALL;
1173 else
1174 hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
1175 wined3d_mutex_unlock();
1177 return hr;
1180 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
1182 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1183 struct d3d9_volume *volume_impl;
1184 HRESULT hr;
1186 TRACE("iface %p, level %u.\n", iface, level);
1188 wined3d_mutex_lock();
1189 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1190 hr = D3DERR_INVALIDCALL;
1191 else
1192 hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
1193 wined3d_mutex_unlock();
1195 return hr;
1198 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
1200 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1201 HRESULT hr;
1203 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1205 wined3d_mutex_lock();
1206 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1207 wined3d_mutex_unlock();
1209 return hr;
1213 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
1215 /* IUnknown */
1216 d3d9_texture_3d_QueryInterface,
1217 d3d9_texture_3d_AddRef,
1218 d3d9_texture_3d_Release,
1219 /* IDirect3DResource9 */
1220 d3d9_texture_3d_GetDevice,
1221 d3d9_texture_3d_SetPrivateData,
1222 d3d9_texture_3d_GetPrivateData,
1223 d3d9_texture_3d_FreePrivateData,
1224 d3d9_texture_3d_SetPriority,
1225 d3d9_texture_3d_GetPriority,
1226 d3d9_texture_3d_PreLoad,
1227 d3d9_texture_3d_GetType,
1228 /* IDirect3DBaseTexture9 */
1229 d3d9_texture_3d_SetLOD,
1230 d3d9_texture_3d_GetLOD,
1231 d3d9_texture_3d_GetLevelCount,
1232 d3d9_texture_3d_SetAutoGenFilterType,
1233 d3d9_texture_3d_GetAutoGenFilterType,
1234 d3d9_texture_3d_GenerateMipSubLevels,
1235 /* IDirect3DVolumeTexture9 */
1236 d3d9_texture_3d_GetLevelDesc,
1237 d3d9_texture_3d_GetVolumeLevel,
1238 d3d9_texture_3d_LockBox,
1239 d3d9_texture_3d_UnlockBox,
1240 d3d9_texture_3d_AddDirtyBox,
1243 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
1245 if (!iface)
1246 return NULL;
1248 if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
1249 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
1250 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
1252 WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
1253 return NULL;
1256 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
1259 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
1261 struct d3d9_texture *texture = parent;
1263 /* If the texture was managed, release the sysmem copy now. */
1264 if (texture->draw_texture)
1265 wined3d_texture_decref(texture->wined3d_texture);
1266 d3d9_resource_cleanup(&texture->resource);
1267 heap_free(texture);
1270 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
1272 d3d9_texture_wined3d_object_destroyed,
1275 static HRESULT d3d9_texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1276 const struct wined3d_resource_desc *desc, D3DPOOL pool, DWORD usage,
1277 unsigned int layer_count, unsigned int level_count)
1279 struct wined3d_adapter *wined3d_adapter;
1280 unsigned int output_idx;
1281 unsigned int flags = 0;
1282 HRESULT hr;
1284 if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
1286 WARN("Managed resources are not supported by d3d9ex devices.\n");
1287 return D3DERR_INVALIDCALL;
1290 d3d9_resource_init(&texture->resource);
1291 list_init(&texture->rtv_list);
1292 texture->usage = usage;
1294 if (desc->resource_type == WINED3D_RTYPE_TEXTURE_2D && is_gdi_compat_wined3dformat(desc->format))
1295 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1296 if (pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_MANAGED)
1297 flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
1299 if (usage & D3DUSAGE_WRITEONLY)
1301 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1302 return D3DERR_INVALIDCALL;
1304 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1306 if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
1308 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1309 return D3DERR_INVALIDCALL;
1312 if (pool == D3DPOOL_SYSTEMMEM)
1314 WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
1315 return D3DERR_INVALIDCALL;
1318 if (level_count && level_count != 1)
1320 WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u level_count, returning D3DERR_INVALIDCALL.\n", level_count);
1321 return D3DERR_INVALIDCALL;
1323 wined3d_mutex_lock();
1324 output_idx = device->adapter_ordinal;
1325 wined3d_adapter = wined3d_output_get_adapter(device->d3d_parent->wined3d_outputs[output_idx]);
1326 hr = wined3d_check_device_format(device->d3d_parent->wined3d, wined3d_adapter,
1327 WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_QUERY_GENMIPMAP,
1328 WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, desc->format);
1329 wined3d_mutex_unlock();
1330 if (hr == D3D_OK)
1332 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1333 level_count = 0;
1335 else
1337 WARN("Mipmap autogeneration is not supported on wined3d format %#x, "
1338 "creating a texture with a single level.\n", desc->format);
1339 level_count = 1;
1341 texture->autogen_filter_type = D3DTEXF_LINEAR;
1343 else
1345 texture->autogen_filter_type = D3DTEXF_NONE;
1347 if (!level_count)
1348 level_count = wined3d_log2i(max(max(desc->width, desc->height), desc->depth)) + 1;
1350 wined3d_mutex_lock();
1351 if (pool == D3DPOOL_MANAGED)
1353 struct wined3d_resource_desc managed_desc = *desc;
1355 managed_desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
1356 managed_desc.bind_flags = 0;
1357 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &managed_desc, layer_count, level_count, flags,
1358 NULL, texture, &d3d9_null_wined3d_parent_ops, &texture->wined3d_texture)))
1360 wined3d_mutex_unlock();
1361 WARN("Failed to create sysmem texture, hr %#lx.\n", hr);
1362 return hr;
1365 managed_desc.access = WINED3D_RESOURCE_ACCESS_GPU;
1366 managed_desc.bind_flags = desc->bind_flags;
1367 flags &= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1368 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &managed_desc, layer_count, level_count, flags,
1369 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->draw_texture)))
1371 wined3d_texture_decref(texture->wined3d_texture);
1372 wined3d_mutex_unlock();
1373 WARN("Failed to create draw texture, hr %#lx.\n", hr);
1374 return hr;
1377 else
1379 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, layer_count, level_count, flags,
1380 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture)))
1382 wined3d_mutex_unlock();
1383 WARN("Failed to create wined3d texture, hr %#lx.\n", hr);
1384 return hr;
1387 wined3d_mutex_unlock();
1389 texture->parent_device = device;
1390 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
1392 return D3D_OK;
1395 HRESULT d3d9_texture_2d_init(struct d3d9_texture *texture, struct d3d9_device *device, unsigned int width,
1396 unsigned int height, unsigned int level_count, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1398 struct wined3d_resource_desc desc;
1400 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1401 desc.format = wined3dformat_from_d3dformat(format);
1402 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1403 desc.multisample_quality = 0;
1404 desc.usage = wined3d_usage_from_d3d(pool, usage);
1405 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1406 desc.access = wined3daccess_from_d3dpool(pool, usage);
1407 desc.width = width;
1408 desc.height = height;
1409 desc.depth = 1;
1410 desc.size = 0;
1412 if (!device->d3d_parent->extended)
1413 desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING;
1415 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
1416 return d3d9_texture_init(texture, device, &desc, pool, usage, 1, level_count);
1419 HRESULT d3d9_texture_cube_init(struct d3d9_texture *texture, struct d3d9_device *device,
1420 unsigned int edge_length, unsigned int level_count, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1422 struct wined3d_resource_desc desc;
1424 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1425 desc.format = wined3dformat_from_d3dformat(format);
1426 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1427 desc.multisample_quality = 0;
1428 desc.usage = wined3d_usage_from_d3d(pool, usage) | WINED3DUSAGE_LEGACY_CUBEMAP;
1429 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1430 desc.access = wined3daccess_from_d3dpool(pool, usage);
1431 desc.width = edge_length;
1432 desc.height = edge_length;
1433 desc.depth = 1;
1434 desc.size = 0;
1436 if (!device->d3d_parent->extended)
1437 desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING;
1439 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
1440 return d3d9_texture_init(texture, device, &desc, pool, usage, 6, level_count);
1443 HRESULT d3d9_texture_3d_init(struct d3d9_texture *texture, struct d3d9_device *device, unsigned int width,
1444 unsigned int height, unsigned int depth, unsigned int level_count, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1446 struct wined3d_resource_desc desc;
1448 /* In d3d9, 3D textures can't be used as rendertarget or depth/stencil buffer. */
1449 if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
1450 return D3DERR_INVALIDCALL;
1452 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
1453 desc.format = wined3dformat_from_d3dformat(format);
1454 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1455 desc.multisample_quality = 0;
1456 desc.usage = wined3d_usage_from_d3d(pool, usage);
1457 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1458 desc.access = wined3daccess_from_d3dpool(pool, usage);
1459 desc.width = width;
1460 desc.height = height;
1461 desc.depth = depth;
1462 desc.size = 0;
1464 if (!device->d3d_parent->extended)
1465 desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING;
1467 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
1468 return d3d9_texture_init(texture, device, &desc, pool, usage, 1, level_count);