ntdll: Connect syscall frames across user callbacks on x86-64.
[wine.git] / dlls / d3d9 / texture.c
bloba3a4dc41272ccf0c40f865eadd91215cdccbf052
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_stateblock_set_texture_lod(texture->parent_device->state,
287 d3d9_texture_get_draw_texture(texture), lod);
288 wined3d_mutex_unlock();
290 return ret;
293 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
295 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
296 DWORD ret;
298 TRACE("iface %p.\n", iface);
300 wined3d_mutex_lock();
301 ret = wined3d_texture_get_lod(d3d9_texture_get_draw_texture(texture));
302 wined3d_mutex_unlock();
304 return ret;
307 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
309 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
310 DWORD ret;
312 TRACE("iface %p.\n", iface);
314 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
315 return 1;
317 wined3d_mutex_lock();
318 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
319 wined3d_mutex_unlock();
321 return ret;
324 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
326 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
328 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
330 if (filter_type == D3DTEXF_NONE)
332 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
333 return D3DERR_INVALIDCALL;
335 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
336 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
337 else if (filter_type != D3DTEXF_LINEAR)
338 FIXME("Unsupported filter type %u.\n", filter_type);
340 texture->autogen_filter_type = filter_type;
341 return D3D_OK;
344 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
346 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
348 TRACE("iface %p.\n", iface);
350 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
351 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
353 return texture->autogen_filter_type;
356 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
358 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
360 TRACE("iface %p.\n", iface);
362 wined3d_mutex_lock();
363 d3d9_texture_gen_auto_mipmap(texture);
364 wined3d_mutex_unlock();
367 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
369 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
370 struct wined3d_sub_resource_desc wined3d_desc;
371 HRESULT hr;
373 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
375 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
377 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
378 return D3DERR_INVALIDCALL;
381 wined3d_mutex_lock();
382 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
384 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
385 desc->Type = D3DRTYPE_SURFACE;
386 desc->Usage = texture->usage;
387 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
388 desc->MultiSampleType = d3dmultisample_type_from_wined3d(wined3d_desc.multisample_type);
389 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
390 desc->Width = wined3d_desc.width;
391 desc->Height = wined3d_desc.height;
393 wined3d_mutex_unlock();
395 return hr;
398 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
399 UINT level, IDirect3DSurface9 **surface)
401 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
402 struct d3d9_surface *surface_impl;
404 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
406 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
408 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
409 return D3DERR_INVALIDCALL;
412 wined3d_mutex_lock();
413 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
415 wined3d_mutex_unlock();
416 return D3DERR_INVALIDCALL;
419 *surface = &surface_impl->IDirect3DSurface9_iface;
420 IDirect3DSurface9_AddRef(*surface);
421 wined3d_mutex_unlock();
423 return D3D_OK;
426 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
427 UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
429 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
430 struct d3d9_surface *surface_impl;
431 HRESULT hr;
433 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#lx.\n",
434 iface, level, locked_rect, rect, flags);
436 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
438 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
439 return D3DERR_INVALIDCALL;
442 wined3d_mutex_lock();
443 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
444 hr = D3DERR_INVALIDCALL;
445 else
446 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
447 wined3d_mutex_unlock();
449 return hr;
452 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
454 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
455 struct d3d9_surface *surface_impl;
456 HRESULT hr;
458 TRACE("iface %p, level %u.\n", iface, level);
460 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
462 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
463 return D3DERR_INVALIDCALL;
466 wined3d_mutex_lock();
467 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
468 hr = D3DERR_INVALIDCALL;
469 else
470 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
471 wined3d_mutex_unlock();
473 return hr;
476 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
478 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
479 HRESULT hr;
481 TRACE("iface %p, dirty_rect %s.\n",
482 iface, wine_dbgstr_rect(dirty_rect));
484 wined3d_mutex_lock();
485 if (!dirty_rect)
486 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
487 else
489 struct wined3d_box dirty_region;
491 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
492 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
494 wined3d_mutex_unlock();
496 return hr;
499 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
501 /* IUnknown */
502 d3d9_texture_2d_QueryInterface,
503 d3d9_texture_2d_AddRef,
504 d3d9_texture_2d_Release,
505 /* IDirect3DResource9 */
506 d3d9_texture_2d_GetDevice,
507 d3d9_texture_2d_SetPrivateData,
508 d3d9_texture_2d_GetPrivateData,
509 d3d9_texture_2d_FreePrivateData,
510 d3d9_texture_2d_SetPriority,
511 d3d9_texture_2d_GetPriority,
512 d3d9_texture_2d_PreLoad,
513 d3d9_texture_2d_GetType,
514 /* IDirect3dBaseTexture9 */
515 d3d9_texture_2d_SetLOD,
516 d3d9_texture_2d_GetLOD,
517 d3d9_texture_2d_GetLevelCount,
518 d3d9_texture_2d_SetAutoGenFilterType,
519 d3d9_texture_2d_GetAutoGenFilterType,
520 d3d9_texture_2d_GenerateMipSubLevels,
521 /* IDirect3DTexture9 */
522 d3d9_texture_2d_GetLevelDesc,
523 d3d9_texture_2d_GetSurfaceLevel,
524 d3d9_texture_2d_LockRect,
525 d3d9_texture_2d_UnlockRect,
526 d3d9_texture_2d_AddDirtyRect,
529 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
531 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
533 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
534 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
535 || IsEqualGUID(riid, &IID_IDirect3DResource9)
536 || IsEqualGUID(riid, &IID_IUnknown))
538 IDirect3DCubeTexture9_AddRef(iface);
539 *out = iface;
540 return S_OK;
543 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
545 *out = NULL;
546 return E_NOINTERFACE;
549 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
551 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
553 return d3d9_texture_incref(texture);
556 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
558 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
560 return d3d9_texture_decref(texture);
563 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
565 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
567 TRACE("iface %p, device %p.\n", iface, device);
569 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
570 IDirect3DDevice9_AddRef(*device);
572 TRACE("Returning device %p.\n", *device);
574 return D3D_OK;
577 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
578 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
580 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
581 TRACE("iface %p, guid %s, data %p, data_size %lu, flags %#lx.\n",
582 iface, debugstr_guid(guid), data, data_size, flags);
584 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
587 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
588 REFGUID guid, void *data, DWORD *data_size)
590 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
591 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
592 iface, debugstr_guid(guid), data, data_size);
594 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
597 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
599 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
600 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
602 return d3d9_resource_free_private_data(&texture->resource, guid);
605 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
607 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
608 struct wined3d_resource *resource;
609 DWORD ret;
611 TRACE("iface %p, priority %lu.\n", iface, priority);
613 wined3d_mutex_lock();
614 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
615 ret = wined3d_resource_set_priority(resource, priority);
616 wined3d_mutex_unlock();
618 return ret;
621 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
623 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
624 const struct wined3d_resource *resource;
625 DWORD ret;
627 TRACE("iface %p.\n", iface);
629 wined3d_mutex_lock();
630 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
631 ret = wined3d_resource_get_priority(resource);
632 wined3d_mutex_unlock();
634 return ret;
637 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
639 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
641 TRACE("iface %p.\n", iface);
643 d3d9_texture_preload(texture);
646 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
648 TRACE("iface %p.\n", iface);
650 return D3DRTYPE_CUBETEXTURE;
653 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
655 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
656 DWORD ret;
658 TRACE("iface %p, lod %lu.\n", iface, lod);
660 wined3d_mutex_lock();
661 ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state,
662 d3d9_texture_get_draw_texture(texture), lod);
663 wined3d_mutex_unlock();
665 return ret;
668 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
670 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
671 DWORD ret;
673 TRACE("iface %p.\n", iface);
675 wined3d_mutex_lock();
676 ret = wined3d_texture_get_lod(d3d9_texture_get_draw_texture(texture));
677 wined3d_mutex_unlock();
679 return ret;
682 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
684 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
685 DWORD ret;
687 TRACE("iface %p.\n", iface);
689 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
690 return 1;
692 wined3d_mutex_lock();
693 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
694 wined3d_mutex_unlock();
696 return ret;
699 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
700 D3DTEXTUREFILTERTYPE filter_type)
702 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
704 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
706 if (filter_type == D3DTEXF_NONE)
708 WARN("Invalid filter type D3DTEXF_NONE specified.\n");
709 return D3DERR_INVALIDCALL;
711 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
712 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
713 else if (filter_type != D3DTEXF_LINEAR)
714 FIXME("Unsupported filter type %u.\n", filter_type);
716 texture->autogen_filter_type = filter_type;
717 return D3D_OK;
720 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
722 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
724 TRACE("iface %p.\n", iface);
726 if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
727 WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
729 return texture->autogen_filter_type;
732 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
734 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
736 TRACE("iface %p.\n", iface);
738 wined3d_mutex_lock();
739 d3d9_texture_gen_auto_mipmap(texture);
740 wined3d_mutex_unlock();
743 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
745 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
746 struct wined3d_sub_resource_desc wined3d_desc;
747 DWORD level_count;
748 HRESULT hr;
750 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
752 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
754 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
755 return D3DERR_INVALIDCALL;
758 wined3d_mutex_lock();
759 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
760 if (level >= level_count)
762 wined3d_mutex_unlock();
763 return D3DERR_INVALIDCALL;
766 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
768 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
769 desc->Type = D3DRTYPE_SURFACE;
770 desc->Usage = texture->usage;
771 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
772 desc->MultiSampleType = d3dmultisample_type_from_wined3d(wined3d_desc.multisample_type);
773 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
774 desc->Width = wined3d_desc.width;
775 desc->Height = wined3d_desc.height;
777 wined3d_mutex_unlock();
779 return hr;
782 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
783 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
785 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
786 struct d3d9_surface *surface_impl;
787 UINT sub_resource_idx;
788 DWORD level_count;
790 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
792 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
794 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
795 return D3DERR_INVALIDCALL;
798 wined3d_mutex_lock();
799 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
800 if (level >= level_count)
802 wined3d_mutex_unlock();
803 return D3DERR_INVALIDCALL;
806 sub_resource_idx = level_count * face + level;
807 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
809 wined3d_mutex_unlock();
810 return D3DERR_INVALIDCALL;
813 *surface = &surface_impl->IDirect3DSurface9_iface;
814 IDirect3DSurface9_AddRef(*surface);
815 wined3d_mutex_unlock();
817 return D3D_OK;
820 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
821 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
822 DWORD flags)
824 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
825 struct d3d9_surface *surface_impl;
826 UINT sub_resource_idx;
827 HRESULT hr;
829 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#lx.\n",
830 iface, face, level, locked_rect, rect, flags);
832 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
834 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
835 return D3DERR_INVALIDCALL;
838 wined3d_mutex_lock();
839 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
840 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
841 hr = D3DERR_INVALIDCALL;
842 else
843 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
844 wined3d_mutex_unlock();
846 return hr;
849 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
850 D3DCUBEMAP_FACES face, UINT level)
852 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
853 struct d3d9_surface *surface_impl;
854 UINT sub_resource_idx;
855 HRESULT hr;
857 TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
859 if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level)
861 WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n");
862 return D3DERR_INVALIDCALL;
865 wined3d_mutex_lock();
866 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
867 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
868 hr = D3DERR_INVALIDCALL;
869 else
870 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
871 wined3d_mutex_unlock();
873 return hr;
876 static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
877 D3DCUBEMAP_FACES face, const RECT *dirty_rect)
879 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
880 HRESULT hr;
882 TRACE("iface %p, face %#x, dirty_rect %s.\n",
883 iface, face, wine_dbgstr_rect(dirty_rect));
885 wined3d_mutex_lock();
886 if (!dirty_rect)
887 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
888 else
890 struct wined3d_box dirty_region;
892 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
893 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
895 wined3d_mutex_unlock();
897 return hr;
900 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
902 /* IUnknown */
903 d3d9_texture_cube_QueryInterface,
904 d3d9_texture_cube_AddRef,
905 d3d9_texture_cube_Release,
906 /* IDirect3DResource9 */
907 d3d9_texture_cube_GetDevice,
908 d3d9_texture_cube_SetPrivateData,
909 d3d9_texture_cube_GetPrivateData,
910 d3d9_texture_cube_FreePrivateData,
911 d3d9_texture_cube_SetPriority,
912 d3d9_texture_cube_GetPriority,
913 d3d9_texture_cube_PreLoad,
914 d3d9_texture_cube_GetType,
915 /* IDirect3DBaseTexture9 */
916 d3d9_texture_cube_SetLOD,
917 d3d9_texture_cube_GetLOD,
918 d3d9_texture_cube_GetLevelCount,
919 d3d9_texture_cube_SetAutoGenFilterType,
920 d3d9_texture_cube_GetAutoGenFilterType,
921 d3d9_texture_cube_GenerateMipSubLevels,
922 /* IDirect3DCubeTexture9 */
923 d3d9_texture_cube_GetLevelDesc,
924 d3d9_texture_cube_GetCubeMapSurface,
925 d3d9_texture_cube_LockRect,
926 d3d9_texture_cube_UnlockRect,
927 d3d9_texture_cube_AddDirtyRect,
930 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
932 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
934 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
935 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
936 || IsEqualGUID(riid, &IID_IDirect3DResource9)
937 || IsEqualGUID(riid, &IID_IUnknown))
939 IDirect3DVolumeTexture9_AddRef(iface);
940 *out = iface;
941 return S_OK;
944 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
946 *out = NULL;
947 return E_NOINTERFACE;
950 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
952 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
954 return d3d9_texture_incref(texture);
957 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
959 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
961 return d3d9_texture_decref(texture);
964 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
966 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
968 TRACE("iface %p, device %p.\n", iface, device);
970 *device = (IDirect3DDevice9 *)&texture->parent_device->IDirect3DDevice9Ex_iface;
971 IDirect3DDevice9_AddRef(*device);
973 TRACE("Returning device %p.\n", *device);
975 return D3D_OK;
978 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
979 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
981 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
982 TRACE("iface %p, guid %s, data %p, data_size %lu, flags %#lx.\n",
983 iface, debugstr_guid(guid), data, data_size, flags);
985 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
988 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
989 REFGUID guid, void *data, DWORD *data_size)
991 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
992 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
993 iface, debugstr_guid(guid), data, data_size);
995 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
998 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
1000 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1001 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1003 return d3d9_resource_free_private_data(&texture->resource, guid);
1006 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
1008 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1009 struct wined3d_resource *resource;
1010 DWORD ret;
1012 TRACE("iface %p, priority %lu.\n", iface, priority);
1014 wined3d_mutex_lock();
1015 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
1016 ret = wined3d_resource_set_priority(resource, priority);
1017 wined3d_mutex_unlock();
1019 return ret;
1022 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
1024 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1025 const struct wined3d_resource *resource;
1026 DWORD ret;
1028 TRACE("iface %p.\n", iface);
1030 wined3d_mutex_lock();
1031 resource = wined3d_texture_get_resource(d3d9_texture_get_draw_texture(texture));
1032 ret = wined3d_resource_get_priority(resource);
1033 wined3d_mutex_unlock();
1035 return ret;
1038 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
1040 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1042 TRACE("iface %p.\n", iface);
1044 d3d9_texture_preload(texture);
1047 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
1049 TRACE("iface %p.\n", iface);
1051 return D3DRTYPE_VOLUMETEXTURE;
1054 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
1056 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1057 DWORD ret;
1059 TRACE("iface %p, lod %lu.\n", iface, lod);
1061 wined3d_mutex_lock();
1062 ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state,
1063 d3d9_texture_get_draw_texture(texture), lod);
1064 wined3d_mutex_unlock();
1066 return ret;
1069 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
1071 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1072 DWORD ret;
1074 TRACE("iface %p.\n", iface);
1076 wined3d_mutex_lock();
1077 ret = wined3d_texture_get_lod(d3d9_texture_get_draw_texture(texture));
1078 wined3d_mutex_unlock();
1080 return ret;
1083 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
1085 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1086 DWORD ret;
1088 TRACE("iface %p.\n", iface);
1090 wined3d_mutex_lock();
1091 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
1092 wined3d_mutex_unlock();
1094 return ret;
1097 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
1098 D3DTEXTUREFILTERTYPE filter_type)
1100 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
1102 return D3DERR_INVALIDCALL;
1105 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
1107 TRACE("iface %p.\n", iface);
1109 return D3DTEXF_NONE;
1112 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
1114 TRACE("iface %p.\n", iface);
1117 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
1119 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1120 struct wined3d_sub_resource_desc wined3d_desc;
1121 HRESULT hr;
1123 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
1125 wined3d_mutex_lock();
1126 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
1128 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
1129 desc->Type = D3DRTYPE_VOLUME;
1130 desc->Usage = texture->usage;
1131 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
1132 desc->Width = wined3d_desc.width;
1133 desc->Height = wined3d_desc.height;
1134 desc->Depth = wined3d_desc.depth;
1136 wined3d_mutex_unlock();
1138 return hr;
1141 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
1142 UINT level, IDirect3DVolume9 **volume)
1144 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1145 struct d3d9_volume *volume_impl;
1147 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1149 wined3d_mutex_lock();
1150 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1152 wined3d_mutex_unlock();
1153 return D3DERR_INVALIDCALL;
1156 *volume = &volume_impl->IDirect3DVolume9_iface;
1157 IDirect3DVolume9_AddRef(*volume);
1158 wined3d_mutex_unlock();
1160 return D3D_OK;
1163 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
1164 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1166 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1167 struct d3d9_volume *volume_impl;
1168 HRESULT hr;
1170 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#lx.\n",
1171 iface, level, locked_box, box, flags);
1173 wined3d_mutex_lock();
1174 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1175 hr = D3DERR_INVALIDCALL;
1176 else
1177 hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
1178 wined3d_mutex_unlock();
1180 return hr;
1183 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
1185 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1186 struct d3d9_volume *volume_impl;
1187 HRESULT hr;
1189 TRACE("iface %p, level %u.\n", iface, level);
1191 wined3d_mutex_lock();
1192 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1193 hr = D3DERR_INVALIDCALL;
1194 else
1195 hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
1196 wined3d_mutex_unlock();
1198 return hr;
1201 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
1203 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1204 HRESULT hr;
1206 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1208 wined3d_mutex_lock();
1209 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1210 wined3d_mutex_unlock();
1212 return hr;
1216 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
1218 /* IUnknown */
1219 d3d9_texture_3d_QueryInterface,
1220 d3d9_texture_3d_AddRef,
1221 d3d9_texture_3d_Release,
1222 /* IDirect3DResource9 */
1223 d3d9_texture_3d_GetDevice,
1224 d3d9_texture_3d_SetPrivateData,
1225 d3d9_texture_3d_GetPrivateData,
1226 d3d9_texture_3d_FreePrivateData,
1227 d3d9_texture_3d_SetPriority,
1228 d3d9_texture_3d_GetPriority,
1229 d3d9_texture_3d_PreLoad,
1230 d3d9_texture_3d_GetType,
1231 /* IDirect3DBaseTexture9 */
1232 d3d9_texture_3d_SetLOD,
1233 d3d9_texture_3d_GetLOD,
1234 d3d9_texture_3d_GetLevelCount,
1235 d3d9_texture_3d_SetAutoGenFilterType,
1236 d3d9_texture_3d_GetAutoGenFilterType,
1237 d3d9_texture_3d_GenerateMipSubLevels,
1238 /* IDirect3DVolumeTexture9 */
1239 d3d9_texture_3d_GetLevelDesc,
1240 d3d9_texture_3d_GetVolumeLevel,
1241 d3d9_texture_3d_LockBox,
1242 d3d9_texture_3d_UnlockBox,
1243 d3d9_texture_3d_AddDirtyBox,
1246 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
1248 if (!iface)
1249 return NULL;
1251 if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
1252 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
1253 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
1255 WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
1256 return NULL;
1259 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
1262 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
1264 struct d3d9_texture *texture = parent;
1266 /* If the texture was managed, release the sysmem copy now. */
1267 if (texture->draw_texture)
1268 wined3d_texture_decref(texture->wined3d_texture);
1269 d3d9_resource_cleanup(&texture->resource);
1270 free(texture);
1273 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
1275 d3d9_texture_wined3d_object_destroyed,
1278 static HRESULT d3d9_texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1279 const struct wined3d_resource_desc *desc, D3DPOOL pool, DWORD usage,
1280 unsigned int layer_count, unsigned int level_count)
1282 struct wined3d_adapter *wined3d_adapter;
1283 unsigned int output_idx;
1284 unsigned int flags = 0;
1285 HRESULT hr;
1287 if (pool == D3DPOOL_MANAGED && device->d3d_parent->extended)
1289 WARN("Managed resources are not supported by d3d9ex devices.\n");
1290 return D3DERR_INVALIDCALL;
1293 d3d9_resource_init(&texture->resource);
1294 list_init(&texture->rtv_list);
1295 texture->usage = usage;
1297 if (desc->resource_type == WINED3D_RTYPE_TEXTURE_2D && is_gdi_compat_wined3dformat(desc->format))
1298 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1299 if (pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_MANAGED)
1300 flags |= WINED3D_TEXTURE_CREATE_RECORD_DIRTY_REGIONS;
1302 if (usage & D3DUSAGE_WRITEONLY)
1304 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1305 return D3DERR_INVALIDCALL;
1307 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1309 if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
1311 WARN("Texture can't be created with the D3DUSAGE_WRITEONLY flags, returning D3DERR_INVALIDCALL.\n");
1312 return D3DERR_INVALIDCALL;
1315 if (pool == D3DPOOL_SYSTEMMEM)
1317 WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n");
1318 return D3DERR_INVALIDCALL;
1321 if (level_count && level_count != 1)
1323 WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u level_count, returning D3DERR_INVALIDCALL.\n", level_count);
1324 return D3DERR_INVALIDCALL;
1326 wined3d_mutex_lock();
1327 output_idx = device->adapter_ordinal;
1328 wined3d_adapter = wined3d_output_get_adapter(device->d3d_parent->wined3d_outputs[output_idx]);
1329 hr = wined3d_check_device_format(device->d3d_parent->wined3d, wined3d_adapter,
1330 WINED3D_DEVICE_TYPE_HAL, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_QUERY_GENMIPMAP,
1331 WINED3D_BIND_SHADER_RESOURCE, WINED3D_RTYPE_TEXTURE_2D, desc->format);
1332 wined3d_mutex_unlock();
1333 if (hr == D3D_OK)
1335 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1336 level_count = 0;
1338 else
1340 WARN("Mipmap autogeneration is not supported on wined3d format %#x, "
1341 "creating a texture with a single level.\n", desc->format);
1342 level_count = 1;
1344 texture->autogen_filter_type = D3DTEXF_LINEAR;
1346 else
1348 texture->autogen_filter_type = D3DTEXF_NONE;
1350 if (!level_count)
1351 level_count = wined3d_log2i(max(max(desc->width, desc->height), desc->depth)) + 1;
1353 wined3d_mutex_lock();
1354 if (pool == D3DPOOL_MANAGED)
1356 struct wined3d_resource_desc managed_desc = *desc;
1358 managed_desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
1359 managed_desc.bind_flags = 0;
1360 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &managed_desc, layer_count, level_count, flags,
1361 NULL, texture, &d3d9_null_wined3d_parent_ops, &texture->wined3d_texture)))
1363 wined3d_mutex_unlock();
1364 WARN("Failed to create sysmem texture, hr %#lx.\n", hr);
1365 return hr;
1368 managed_desc.access = WINED3D_RESOURCE_ACCESS_GPU;
1369 managed_desc.bind_flags = desc->bind_flags;
1370 flags &= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1371 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &managed_desc, layer_count, level_count, flags,
1372 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->draw_texture)))
1374 wined3d_texture_decref(texture->wined3d_texture);
1375 wined3d_mutex_unlock();
1376 WARN("Failed to create draw texture, hr %#lx.\n", hr);
1377 return hr;
1380 else
1382 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, layer_count, level_count, flags,
1383 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture)))
1385 wined3d_mutex_unlock();
1386 WARN("Failed to create wined3d texture, hr %#lx.\n", hr);
1387 return hr;
1390 wined3d_mutex_unlock();
1392 texture->parent_device = device;
1393 IDirect3DDevice9Ex_AddRef(&texture->parent_device->IDirect3DDevice9Ex_iface);
1395 return D3D_OK;
1398 HRESULT d3d9_texture_2d_init(struct d3d9_texture *texture, struct d3d9_device *device, unsigned int width,
1399 unsigned int height, unsigned int level_count, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1401 struct wined3d_resource_desc desc;
1403 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1404 desc.format = wined3dformat_from_d3dformat(format);
1405 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1406 desc.multisample_quality = 0;
1407 desc.usage = wined3d_usage_from_d3d(pool, usage);
1408 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1409 desc.access = wined3daccess_from_d3dpool(pool, usage);
1410 desc.width = width;
1411 desc.height = height;
1412 desc.depth = 1;
1413 desc.size = 0;
1415 if (!device->d3d_parent->extended)
1416 desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING;
1418 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
1419 return d3d9_texture_init(texture, device, &desc, pool, usage, 1, level_count);
1422 HRESULT d3d9_texture_cube_init(struct d3d9_texture *texture, struct d3d9_device *device,
1423 unsigned int edge_length, unsigned int level_count, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1425 struct wined3d_resource_desc desc;
1427 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1428 desc.format = wined3dformat_from_d3dformat(format);
1429 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1430 desc.multisample_quality = 0;
1431 desc.usage = wined3d_usage_from_d3d(pool, usage) | WINED3DUSAGE_LEGACY_CUBEMAP;
1432 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1433 desc.access = wined3daccess_from_d3dpool(pool, usage);
1434 desc.width = edge_length;
1435 desc.height = edge_length;
1436 desc.depth = 1;
1437 desc.size = 0;
1439 if (!device->d3d_parent->extended)
1440 desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING;
1442 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
1443 return d3d9_texture_init(texture, device, &desc, pool, usage, 6, level_count);
1446 HRESULT d3d9_texture_3d_init(struct d3d9_texture *texture, struct d3d9_device *device, unsigned int width,
1447 unsigned int height, unsigned int depth, unsigned int level_count, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1449 struct wined3d_resource_desc desc;
1451 /* In d3d9, 3D textures can't be used as rendertarget or depth/stencil buffer. */
1452 if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
1453 return D3DERR_INVALIDCALL;
1455 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
1456 desc.format = wined3dformat_from_d3dformat(format);
1457 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1458 desc.multisample_quality = 0;
1459 desc.usage = wined3d_usage_from_d3d(pool, usage);
1460 desc.bind_flags = wined3d_bind_flags_from_d3d9_usage(usage) | WINED3D_BIND_SHADER_RESOURCE;
1461 desc.access = wined3daccess_from_d3dpool(pool, usage);
1462 desc.width = width;
1463 desc.height = height;
1464 desc.depth = depth;
1465 desc.size = 0;
1467 if (!device->d3d_parent->extended)
1468 desc.usage |= WINED3DUSAGE_VIDMEM_ACCOUNTING;
1470 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
1471 return d3d9_texture_init(texture, device, &desc, pool, usage, 1, level_count);