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