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