2 * Copyright 2009 Henri Verbeet for CodeWeavers
3 * Copyright 2015 Józef Kucia for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
24 #include "d3d11_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d11
);
28 /* ID3D11Texture1D methods */
30 static inline struct d3d_texture1d
*impl_from_ID3D11Texture1D(ID3D11Texture1D
*iface
)
32 return CONTAINING_RECORD(iface
, struct d3d_texture1d
, ID3D11Texture1D_iface
);
35 static HRESULT STDMETHODCALLTYPE
d3d11_texture1d_QueryInterface(ID3D11Texture1D
*iface
, REFIID iid
, void **out
)
37 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
39 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
41 if (IsEqualGUID(iid
, &IID_ID3D11Texture1D
)
42 || IsEqualGUID(iid
, &IID_ID3D11Resource
)
43 || IsEqualGUID(iid
, &IID_ID3D11DeviceChild
)
44 || IsEqualGUID(iid
, &IID_IUnknown
))
47 IUnknown_AddRef(iface
);
51 if (IsEqualGUID(iid
, &IID_ID3D10Texture1D
)
52 || IsEqualGUID(iid
, &IID_ID3D10Resource
)
53 || IsEqualGUID(iid
, &IID_ID3D10DeviceChild
))
55 *out
= &texture
->ID3D10Texture1D_iface
;
56 IUnknown_AddRef((IUnknown
*)*out
);
60 if (texture
->dxgi_surface
)
62 TRACE("Forwarding to dxgi surface.\n");
63 return IUnknown_QueryInterface(texture
->dxgi_surface
, iid
, out
);
66 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
72 static ULONG STDMETHODCALLTYPE
d3d11_texture1d_AddRef(ID3D11Texture1D
*iface
)
74 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
75 ULONG refcount
= InterlockedIncrement(&texture
->refcount
);
77 TRACE("%p increasing refcount to %u.\n", texture
, refcount
);
81 ID3D11Device2_AddRef(texture
->device
);
83 wined3d_texture_incref(texture
->wined3d_texture
);
84 wined3d_mutex_unlock();
90 static ULONG STDMETHODCALLTYPE
d3d11_texture1d_Release(ID3D11Texture1D
*iface
)
92 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
93 ULONG refcount
= InterlockedDecrement(&texture
->refcount
);
95 TRACE("%p decreasing refcount to %u.\n", texture
, refcount
);
99 ID3D11Device2
*device
= texture
->device
;
101 wined3d_mutex_lock();
102 wined3d_texture_decref(texture
->wined3d_texture
);
103 wined3d_mutex_unlock();
104 /* Release the device last, it may cause the wined3d device to be
106 ID3D11Device2_Release(device
);
112 static void STDMETHODCALLTYPE
d3d11_texture1d_GetDevice(ID3D11Texture1D
*iface
, ID3D11Device
**device
)
114 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
116 TRACE("iface %p, device %p.\n", iface
, device
);
118 *device
= (ID3D11Device
*)texture
->device
;
119 ID3D11Device_AddRef(*device
);
122 static HRESULT STDMETHODCALLTYPE
d3d11_texture1d_GetPrivateData(ID3D11Texture1D
*iface
,
123 REFGUID guid
, UINT
*data_size
, void *data
)
125 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
126 IDXGISurface
*dxgi_surface
;
129 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
131 if (texture
->dxgi_surface
132 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
134 hr
= IDXGISurface_GetPrivateData(dxgi_surface
, guid
, data_size
, data
);
135 IDXGISurface_Release(dxgi_surface
);
139 return d3d_get_private_data(&texture
->private_store
, guid
, data_size
, data
);
142 static HRESULT STDMETHODCALLTYPE
d3d11_texture1d_SetPrivateData(ID3D11Texture1D
*iface
,
143 REFGUID guid
, UINT data_size
, const void *data
)
145 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
146 IDXGISurface
*dxgi_surface
;
149 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
151 if (texture
->dxgi_surface
152 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
154 hr
= IDXGISurface_SetPrivateData(dxgi_surface
, guid
, data_size
, data
);
155 IDXGISurface_Release(dxgi_surface
);
159 return d3d_set_private_data(&texture
->private_store
, guid
, data_size
, data
);
162 static HRESULT STDMETHODCALLTYPE
d3d11_texture1d_SetPrivateDataInterface(ID3D11Texture1D
*iface
,
163 REFGUID guid
, const IUnknown
*data
)
165 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
166 IDXGISurface
*dxgi_surface
;
169 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
171 if (texture
->dxgi_surface
172 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
174 hr
= IDXGISurface_SetPrivateDataInterface(dxgi_surface
, guid
, data
);
175 IDXGISurface_Release(dxgi_surface
);
179 return d3d_set_private_data_interface(&texture
->private_store
, guid
, data
);
182 static void STDMETHODCALLTYPE
d3d11_texture1d_GetType(ID3D11Texture1D
*iface
,
183 D3D11_RESOURCE_DIMENSION
*resource_dimension
)
185 TRACE("iface %p, resource_dimension %p.\n", iface
, resource_dimension
);
187 *resource_dimension
= D3D11_RESOURCE_DIMENSION_TEXTURE1D
;
190 static void STDMETHODCALLTYPE
d3d11_texture1d_SetEvictionPriority(ID3D11Texture1D
*iface
, UINT eviction_priority
)
192 FIXME("iface %p, eviction_priority %#x stub!\n", iface
, eviction_priority
);
195 static UINT STDMETHODCALLTYPE
d3d11_texture1d_GetEvictionPriority(ID3D11Texture1D
*iface
)
197 FIXME("iface %p stub!\n", iface
);
202 static void STDMETHODCALLTYPE
d3d11_texture1d_GetDesc(ID3D11Texture1D
*iface
, D3D11_TEXTURE1D_DESC
*desc
)
204 struct d3d_texture1d
*texture
= impl_from_ID3D11Texture1D(iface
);
206 TRACE("iface %p, desc %p.\n", iface
, desc
);
208 *desc
= texture
->desc
;
211 static const struct ID3D11Texture1DVtbl d3d11_texture1d_vtbl
=
213 /* IUnknown methods */
214 d3d11_texture1d_QueryInterface
,
215 d3d11_texture1d_AddRef
,
216 d3d11_texture1d_Release
,
217 /* ID3D11DeviceChild methods */
218 d3d11_texture1d_GetDevice
,
219 d3d11_texture1d_GetPrivateData
,
220 d3d11_texture1d_SetPrivateData
,
221 d3d11_texture1d_SetPrivateDataInterface
,
222 /* ID3D11Resource methods */
223 d3d11_texture1d_GetType
,
224 d3d11_texture1d_SetEvictionPriority
,
225 d3d11_texture1d_GetEvictionPriority
,
226 /* ID3D11Texture1D methods */
227 d3d11_texture1d_GetDesc
,
230 struct d3d_texture1d
*unsafe_impl_from_ID3D11Texture1D(ID3D11Texture1D
*iface
)
234 assert(iface
->lpVtbl
== &d3d11_texture1d_vtbl
);
235 return CONTAINING_RECORD(iface
, struct d3d_texture1d
, ID3D11Texture1D_iface
);
238 static inline struct d3d_texture1d
*impl_from_ID3D10Texture1D(ID3D10Texture1D
*iface
)
240 return CONTAINING_RECORD(iface
, struct d3d_texture1d
, ID3D10Texture1D_iface
);
243 /* IUnknown methods */
245 static HRESULT STDMETHODCALLTYPE
d3d10_texture1d_QueryInterface(ID3D10Texture1D
*iface
, REFIID iid
, void **out
)
247 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
249 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
251 return d3d11_texture1d_QueryInterface(&texture
->ID3D11Texture1D_iface
, iid
, out
);
254 static ULONG STDMETHODCALLTYPE
d3d10_texture1d_AddRef(ID3D10Texture1D
*iface
)
256 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
258 TRACE("iface %p.\n", iface
);
260 return d3d11_texture1d_AddRef(&texture
->ID3D11Texture1D_iface
);
263 static void STDMETHODCALLTYPE
d3d_texture1d_wined3d_object_released(void *parent
)
265 struct d3d_texture1d
*texture
= parent
;
267 if (texture
->dxgi_surface
)
268 IUnknown_Release(texture
->dxgi_surface
);
269 wined3d_private_store_cleanup(&texture
->private_store
);
273 static ULONG STDMETHODCALLTYPE
d3d10_texture1d_Release(ID3D10Texture1D
*iface
)
275 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
277 TRACE("iface %p.\n", iface
);
279 return d3d11_texture1d_Release(&texture
->ID3D11Texture1D_iface
);
282 /* ID3D10DeviceChild methods */
284 static void STDMETHODCALLTYPE
d3d10_texture1d_GetDevice(ID3D10Texture1D
*iface
, ID3D10Device
**device
)
286 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
288 TRACE("iface %p, device %p.\n", iface
, device
);
290 ID3D11Device2_QueryInterface(texture
->device
, &IID_ID3D10Device
, (void **)device
);
293 static HRESULT STDMETHODCALLTYPE
d3d10_texture1d_GetPrivateData(ID3D10Texture1D
*iface
,
294 REFGUID guid
, UINT
*data_size
, void *data
)
296 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
298 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
300 return d3d11_texture1d_GetPrivateData(&texture
->ID3D11Texture1D_iface
, guid
, data_size
, data
);
303 static HRESULT STDMETHODCALLTYPE
d3d10_texture1d_SetPrivateData(ID3D10Texture1D
*iface
,
304 REFGUID guid
, UINT data_size
, const void *data
)
306 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
308 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
310 return d3d11_texture1d_SetPrivateData(&texture
->ID3D11Texture1D_iface
, guid
, data_size
, data
);
313 static HRESULT STDMETHODCALLTYPE
d3d10_texture1d_SetPrivateDataInterface(ID3D10Texture1D
*iface
,
314 REFGUID guid
, const IUnknown
*data
)
316 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
318 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
320 return d3d11_texture1d_SetPrivateDataInterface(&texture
->ID3D11Texture1D_iface
, guid
, data
);
323 /* ID3D10Resource methods */
325 static void STDMETHODCALLTYPE
d3d10_texture1d_GetType(ID3D10Texture1D
*iface
,
326 D3D10_RESOURCE_DIMENSION
*resource_dimension
)
328 TRACE("iface %p, resource_dimension %p\n", iface
, resource_dimension
);
330 *resource_dimension
= D3D10_RESOURCE_DIMENSION_TEXTURE1D
;
333 static void STDMETHODCALLTYPE
d3d10_texture1d_SetEvictionPriority(ID3D10Texture1D
*iface
, UINT eviction_priority
)
335 FIXME("iface %p, eviction_priority %u stub!\n", iface
, eviction_priority
);
338 static UINT STDMETHODCALLTYPE
d3d10_texture1d_GetEvictionPriority(ID3D10Texture1D
*iface
)
340 FIXME("iface %p stub!\n", iface
);
345 /* ID3D10Texture1D methods */
347 static HRESULT STDMETHODCALLTYPE
d3d10_texture1d_Map(ID3D10Texture1D
*iface
, UINT sub_resource_idx
,
348 D3D10_MAP map_type
, UINT map_flags
, void **data
)
350 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
351 struct wined3d_map_desc wined3d_map_desc
;
354 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, data %p.\n",
355 iface
, sub_resource_idx
, map_type
, map_flags
, data
);
358 FIXME("Ignoring map_flags %#x.\n", map_flags
);
360 wined3d_mutex_lock();
361 if (SUCCEEDED(hr
= wined3d_resource_map(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
,
362 &wined3d_map_desc
, NULL
, wined3d_map_flags_from_d3d11_map_type(map_type
))))
364 *data
= wined3d_map_desc
.data
;
366 wined3d_mutex_unlock();
371 static void STDMETHODCALLTYPE
d3d10_texture1d_Unmap(ID3D10Texture1D
*iface
, UINT sub_resource_idx
)
373 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
375 TRACE("iface %p, sub_resource_idx %u.\n", iface
, sub_resource_idx
);
377 wined3d_mutex_lock();
378 wined3d_resource_unmap(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
);
379 wined3d_mutex_unlock();
382 static void STDMETHODCALLTYPE
d3d10_texture1d_GetDesc(ID3D10Texture1D
*iface
, D3D10_TEXTURE1D_DESC
*desc
)
384 struct d3d_texture1d
*texture
= impl_from_ID3D10Texture1D(iface
);
385 D3D11_TEXTURE1D_DESC d3d11_desc
;
387 TRACE("iface %p, desc %p.\n", iface
, desc
);
389 d3d11_texture1d_GetDesc(&texture
->ID3D11Texture1D_iface
, &d3d11_desc
);
391 desc
->Width
= d3d11_desc
.Width
;
392 desc
->MipLevels
= d3d11_desc
.MipLevels
;
393 desc
->ArraySize
= d3d11_desc
.ArraySize
;
394 desc
->Format
= d3d11_desc
.Format
;
395 desc
->Usage
= d3d10_usage_from_d3d11_usage(d3d11_desc
.Usage
);
396 desc
->BindFlags
= d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc
.BindFlags
);
397 desc
->CPUAccessFlags
= d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc
.CPUAccessFlags
);
398 desc
->MiscFlags
= d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc
.MiscFlags
);
401 static const struct ID3D10Texture1DVtbl d3d10_texture1d_vtbl
=
403 /* IUnknown methods */
404 d3d10_texture1d_QueryInterface
,
405 d3d10_texture1d_AddRef
,
406 d3d10_texture1d_Release
,
407 /* ID3D10DeviceChild methods */
408 d3d10_texture1d_GetDevice
,
409 d3d10_texture1d_GetPrivateData
,
410 d3d10_texture1d_SetPrivateData
,
411 d3d10_texture1d_SetPrivateDataInterface
,
412 /* ID3D10Resource methods */
413 d3d10_texture1d_GetType
,
414 d3d10_texture1d_SetEvictionPriority
,
415 d3d10_texture1d_GetEvictionPriority
,
416 /* ID3D10Texture1D methods */
418 d3d10_texture1d_Unmap
,
419 d3d10_texture1d_GetDesc
,
422 struct d3d_texture1d
*unsafe_impl_from_ID3D10Texture1D(ID3D10Texture1D
*iface
)
426 assert(iface
->lpVtbl
== &d3d10_texture1d_vtbl
);
427 return CONTAINING_RECORD(iface
, struct d3d_texture1d
, ID3D10Texture1D_iface
);
430 static const struct wined3d_parent_ops d3d_texture1d_wined3d_parent_ops
=
432 d3d_texture1d_wined3d_object_released
,
435 HRESULT
d3d_texture1d_create(struct d3d_device
*device
, const D3D11_TEXTURE1D_DESC
*desc
,
436 const D3D11_SUBRESOURCE_DATA
*data
, struct d3d_texture1d
**out
)
438 struct wined3d_resource_desc wined3d_desc
;
439 struct d3d_texture1d
*texture
;
444 if (!(texture
= heap_alloc_zero(sizeof(*texture
))))
445 return E_OUTOFMEMORY
;
447 texture
->ID3D11Texture1D_iface
.lpVtbl
= &d3d11_texture1d_vtbl
;
448 texture
->ID3D10Texture1D_iface
.lpVtbl
= &d3d10_texture1d_vtbl
;
449 texture
->refcount
= 1;
450 wined3d_private_store_init(&texture
->private_store
);
451 texture
->desc
= *desc
;
452 levels
= desc
->MipLevels
? desc
->MipLevels
: wined3d_log2i(desc
->Width
) + 1;
453 texture
->desc
.MipLevels
= levels
;
455 wined3d_desc
.resource_type
= WINED3D_RTYPE_TEXTURE_1D
;
456 wined3d_desc
.format
= wined3dformat_from_dxgi_format(desc
->Format
);
457 wined3d_desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
458 wined3d_desc
.multisample_quality
= 0;
459 wined3d_desc
.usage
= wined3d_usage_from_d3d11(desc
->Usage
);
460 wined3d_desc
.bind_flags
= wined3d_bind_flags_from_d3d11(desc
->BindFlags
);
461 wined3d_desc
.access
= wined3d_access_from_d3d11(desc
->Usage
,
462 desc
->Usage
== D3D11_USAGE_DEFAULT
? 0 : desc
->CPUAccessFlags
);
463 wined3d_desc
.width
= desc
->Width
;
464 wined3d_desc
.height
= 1;
465 wined3d_desc
.depth
= 1;
466 wined3d_desc
.size
= 0;
468 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GDI_COMPATIBLE
)
469 flags
|= WINED3D_TEXTURE_CREATE_GET_DC
;
470 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
)
471 flags
|= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
;
473 wined3d_mutex_lock();
474 if (FAILED(hr
= wined3d_texture_create(device
->wined3d_device
, &wined3d_desc
,
475 desc
->ArraySize
, levels
, flags
, (struct wined3d_sub_resource_data
*)data
,
476 texture
, &d3d_texture1d_wined3d_parent_ops
, &texture
->wined3d_texture
)))
478 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
479 wined3d_private_store_cleanup(&texture
->private_store
);
481 wined3d_mutex_unlock();
482 if (hr
== WINED3DERR_NOTAVAILABLE
|| hr
== WINED3DERR_INVALIDCALL
)
487 if (desc
->MipLevels
== 1 && desc
->ArraySize
== 1)
489 IWineDXGIDevice
*wine_device
;
491 if (FAILED(hr
= ID3D10Device1_QueryInterface(&device
->ID3D10Device1_iface
, &IID_IWineDXGIDevice
,
492 (void **)&wine_device
)))
494 ERR("Device should implement IWineDXGIDevice.\n");
495 wined3d_texture_decref(texture
->wined3d_texture
);
496 wined3d_mutex_unlock();
500 hr
= IWineDXGIDevice_create_surface(wine_device
, texture
->wined3d_texture
, 0, NULL
,
501 (IUnknown
*)&texture
->ID3D10Texture1D_iface
, (void **)&texture
->dxgi_surface
);
502 IWineDXGIDevice_Release(wine_device
);
505 ERR("Failed to create DXGI surface, returning %#.x\n", hr
);
506 texture
->dxgi_surface
= NULL
;
507 wined3d_texture_decref(texture
->wined3d_texture
);
508 wined3d_mutex_unlock();
512 wined3d_mutex_unlock();
514 ID3D11Device2_AddRef(texture
->device
= &device
->ID3D11Device2_iface
);
516 TRACE("Created texture %p.\n", texture
);
522 /* ID3D11Texture2D methods */
524 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_QueryInterface(ID3D11Texture2D
*iface
, REFIID riid
, void **object
)
526 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
528 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
530 if (IsEqualGUID(riid
, &IID_ID3D11Texture2D
)
531 || IsEqualGUID(riid
, &IID_ID3D11Resource
)
532 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
533 || IsEqualGUID(riid
, &IID_IUnknown
))
535 *object
= &texture
->ID3D11Texture2D_iface
;
536 IUnknown_AddRef((IUnknown
*)*object
);
539 else if (IsEqualGUID(riid
, &IID_ID3D10Texture2D
)
540 || IsEqualGUID(riid
, &IID_ID3D10Resource
)
541 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
543 *object
= &texture
->ID3D10Texture2D_iface
;
544 IUnknown_AddRef((IUnknown
*)*object
);
548 if (texture
->dxgi_surface
)
550 TRACE("Forwarding to dxgi surface.\n");
551 return IUnknown_QueryInterface(texture
->dxgi_surface
, riid
, object
);
554 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
557 return E_NOINTERFACE
;
560 static ULONG STDMETHODCALLTYPE
d3d11_texture2d_AddRef(ID3D11Texture2D
*iface
)
562 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
563 ULONG refcount
= InterlockedIncrement(&texture
->refcount
);
565 TRACE("%p increasing refcount to %u.\n", texture
, refcount
);
569 ID3D11Device2_AddRef(texture
->device
);
570 wined3d_mutex_lock();
571 wined3d_texture_incref(texture
->wined3d_texture
);
572 wined3d_mutex_unlock();
578 static ULONG STDMETHODCALLTYPE
d3d11_texture2d_Release(ID3D11Texture2D
*iface
)
580 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
581 ULONG refcount
= InterlockedDecrement(&texture
->refcount
);
583 TRACE("%p decreasing refcount to %u.\n", texture
, refcount
);
587 ID3D11Device2
*device
= texture
->device
;
589 wined3d_mutex_lock();
590 wined3d_texture_decref(texture
->wined3d_texture
);
591 wined3d_mutex_unlock();
592 /* Release the device last, it may cause the wined3d device to be
594 ID3D11Device2_Release(device
);
600 static void STDMETHODCALLTYPE
d3d11_texture2d_GetDevice(ID3D11Texture2D
*iface
, ID3D11Device
**device
)
602 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
604 TRACE("iface %p, device %p.\n", iface
, device
);
606 *device
= (ID3D11Device
*)texture
->device
;
607 ID3D11Device_AddRef(*device
);
610 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_GetPrivateData(ID3D11Texture2D
*iface
,
611 REFGUID guid
, UINT
*data_size
, void *data
)
613 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
614 IDXGISurface
*dxgi_surface
;
617 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
619 if (texture
->dxgi_surface
620 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
622 hr
= IDXGISurface_GetPrivateData(dxgi_surface
, guid
, data_size
, data
);
623 IDXGISurface_Release(dxgi_surface
);
627 return d3d_get_private_data(&texture
->private_store
, guid
, data_size
, data
);
630 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_SetPrivateData(ID3D11Texture2D
*iface
,
631 REFGUID guid
, UINT data_size
, const void *data
)
633 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
634 IDXGISurface
*dxgi_surface
;
637 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
639 if (texture
->dxgi_surface
640 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
642 hr
= IDXGISurface_SetPrivateData(dxgi_surface
, guid
, data_size
, data
);
643 IDXGISurface_Release(dxgi_surface
);
647 return d3d_set_private_data(&texture
->private_store
, guid
, data_size
, data
);
650 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_SetPrivateDataInterface(ID3D11Texture2D
*iface
,
651 REFGUID guid
, const IUnknown
*data
)
653 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
654 IDXGISurface
*dxgi_surface
;
657 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
659 if (texture
->dxgi_surface
660 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
662 hr
= IDXGISurface_SetPrivateDataInterface(dxgi_surface
, guid
, data
);
663 IDXGISurface_Release(dxgi_surface
);
667 return d3d_set_private_data_interface(&texture
->private_store
, guid
, data
);
670 static void STDMETHODCALLTYPE
d3d11_texture2d_GetType(ID3D11Texture2D
*iface
,
671 D3D11_RESOURCE_DIMENSION
*resource_dimension
)
673 TRACE("iface %p, resource_dimension %p.\n", iface
, resource_dimension
);
675 *resource_dimension
= D3D11_RESOURCE_DIMENSION_TEXTURE2D
;
678 static void STDMETHODCALLTYPE
d3d11_texture2d_SetEvictionPriority(ID3D11Texture2D
*iface
, UINT eviction_priority
)
680 FIXME("iface %p, eviction_priority %#x stub!\n", iface
, eviction_priority
);
683 static UINT STDMETHODCALLTYPE
d3d11_texture2d_GetEvictionPriority(ID3D11Texture2D
*iface
)
685 FIXME("iface %p stub!\n", iface
);
690 static void STDMETHODCALLTYPE
d3d11_texture2d_GetDesc(ID3D11Texture2D
*iface
, D3D11_TEXTURE2D_DESC
*desc
)
692 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
693 struct wined3d_resource_desc wined3d_desc
;
695 TRACE("iface %p, desc %p.\n", iface
, desc
);
697 *desc
= texture
->desc
;
699 wined3d_mutex_lock();
700 wined3d_resource_get_desc(wined3d_texture_get_resource(texture
->wined3d_texture
), &wined3d_desc
);
701 wined3d_mutex_unlock();
703 /* FIXME: Resizing swapchain buffers can cause these to change. We'd like
704 * to get everything from wined3d, but e.g. bind flags don't exist as such
706 desc
->Width
= wined3d_desc
.width
;
707 desc
->Height
= wined3d_desc
.height
;
708 desc
->Format
= dxgi_format_from_wined3dformat(wined3d_desc
.format
);
709 desc
->SampleDesc
.Count
= wined3d_desc
.multisample_type
== WINED3D_MULTISAMPLE_NONE
710 ? 1 : wined3d_desc
.multisample_type
;
711 desc
->SampleDesc
.Quality
= wined3d_desc
.multisample_quality
;
714 static const struct ID3D11Texture2DVtbl d3d11_texture2d_vtbl
=
716 /* IUnknown methods */
717 d3d11_texture2d_QueryInterface
,
718 d3d11_texture2d_AddRef
,
719 d3d11_texture2d_Release
,
720 /* ID3D11DeviceChild methods */
721 d3d11_texture2d_GetDevice
,
722 d3d11_texture2d_GetPrivateData
,
723 d3d11_texture2d_SetPrivateData
,
724 d3d11_texture2d_SetPrivateDataInterface
,
725 /* ID3D11Resource methods */
726 d3d11_texture2d_GetType
,
727 d3d11_texture2d_SetEvictionPriority
,
728 d3d11_texture2d_GetEvictionPriority
,
729 /* ID3D11Texture2D methods */
730 d3d11_texture2d_GetDesc
,
733 struct d3d_texture2d
*unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D
*iface
)
737 assert(iface
->lpVtbl
== &d3d11_texture2d_vtbl
);
738 return CONTAINING_RECORD(iface
, struct d3d_texture2d
, ID3D11Texture2D_iface
);
741 /* IUnknown methods */
743 static inline struct d3d_texture2d
*impl_from_ID3D10Texture2D(ID3D10Texture2D
*iface
)
745 return CONTAINING_RECORD(iface
, struct d3d_texture2d
, ID3D10Texture2D_iface
);
748 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_QueryInterface(ID3D10Texture2D
*iface
, REFIID riid
, void **object
)
750 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
752 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
754 return d3d11_texture2d_QueryInterface(&texture
->ID3D11Texture2D_iface
, riid
, object
);
757 static ULONG STDMETHODCALLTYPE
d3d10_texture2d_AddRef(ID3D10Texture2D
*iface
)
759 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
761 TRACE("iface %p.\n", iface
);
763 return d3d11_texture2d_AddRef(&texture
->ID3D11Texture2D_iface
);
766 static void STDMETHODCALLTYPE
d3d_texture2d_wined3d_object_released(void *parent
)
768 struct d3d_texture2d
*texture
= parent
;
770 if (texture
->dxgi_surface
) IUnknown_Release(texture
->dxgi_surface
);
771 wined3d_private_store_cleanup(&texture
->private_store
);
775 static ULONG STDMETHODCALLTYPE
d3d10_texture2d_Release(ID3D10Texture2D
*iface
)
777 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
779 TRACE("iface %p.\n", iface
);
781 return d3d11_texture2d_Release(&texture
->ID3D11Texture2D_iface
);
784 /* ID3D10DeviceChild methods */
786 static void STDMETHODCALLTYPE
d3d10_texture2d_GetDevice(ID3D10Texture2D
*iface
, ID3D10Device
**device
)
788 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
790 TRACE("iface %p, device %p.\n", iface
, device
);
792 ID3D11Device2_QueryInterface(texture
->device
, &IID_ID3D10Device
, (void **)device
);
795 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_GetPrivateData(ID3D10Texture2D
*iface
,
796 REFGUID guid
, UINT
*data_size
, void *data
)
798 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
800 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
802 return d3d11_texture2d_GetPrivateData(&texture
->ID3D11Texture2D_iface
, guid
, data_size
, data
);
805 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_SetPrivateData(ID3D10Texture2D
*iface
,
806 REFGUID guid
, UINT data_size
, const void *data
)
808 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
810 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
812 return d3d11_texture2d_SetPrivateData(&texture
->ID3D11Texture2D_iface
, guid
, data_size
, data
);
815 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_SetPrivateDataInterface(ID3D10Texture2D
*iface
,
816 REFGUID guid
, const IUnknown
*data
)
818 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
820 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
822 return d3d11_texture2d_SetPrivateDataInterface(&texture
->ID3D11Texture2D_iface
, guid
, data
);
825 /* ID3D10Resource methods */
827 static void STDMETHODCALLTYPE
d3d10_texture2d_GetType(ID3D10Texture2D
*iface
,
828 D3D10_RESOURCE_DIMENSION
*resource_dimension
)
830 TRACE("iface %p, resource_dimension %p\n", iface
, resource_dimension
);
832 *resource_dimension
= D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
835 static void STDMETHODCALLTYPE
d3d10_texture2d_SetEvictionPriority(ID3D10Texture2D
*iface
, UINT eviction_priority
)
837 FIXME("iface %p, eviction_priority %u stub!\n", iface
, eviction_priority
);
840 static UINT STDMETHODCALLTYPE
d3d10_texture2d_GetEvictionPriority(ID3D10Texture2D
*iface
)
842 FIXME("iface %p stub!\n", iface
);
847 /* ID3D10Texture2D methods */
849 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_Map(ID3D10Texture2D
*iface
, UINT sub_resource_idx
,
850 D3D10_MAP map_type
, UINT map_flags
, D3D10_MAPPED_TEXTURE2D
*mapped_texture
)
852 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
853 struct wined3d_map_desc wined3d_map_desc
;
856 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n",
857 iface
, sub_resource_idx
, map_type
, map_flags
, mapped_texture
);
860 FIXME("Ignoring map_flags %#x.\n", map_flags
);
862 wined3d_mutex_lock();
863 if (SUCCEEDED(hr
= wined3d_resource_map(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
,
864 &wined3d_map_desc
, NULL
, wined3d_map_flags_from_d3d11_map_type(map_type
))))
866 mapped_texture
->pData
= wined3d_map_desc
.data
;
867 mapped_texture
->RowPitch
= wined3d_map_desc
.row_pitch
;
869 wined3d_mutex_unlock();
874 static void STDMETHODCALLTYPE
d3d10_texture2d_Unmap(ID3D10Texture2D
*iface
, UINT sub_resource_idx
)
876 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
878 TRACE("iface %p, sub_resource_idx %u.\n", iface
, sub_resource_idx
);
880 wined3d_mutex_lock();
881 wined3d_resource_unmap(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
);
882 wined3d_mutex_unlock();
885 static void STDMETHODCALLTYPE
d3d10_texture2d_GetDesc(ID3D10Texture2D
*iface
, D3D10_TEXTURE2D_DESC
*desc
)
887 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
888 D3D11_TEXTURE2D_DESC d3d11_desc
;
890 TRACE("iface %p, desc %p\n", iface
, desc
);
892 d3d11_texture2d_GetDesc(&texture
->ID3D11Texture2D_iface
, &d3d11_desc
);
894 desc
->Width
= d3d11_desc
.Width
;
895 desc
->Height
= d3d11_desc
.Height
;
896 desc
->MipLevels
= d3d11_desc
.MipLevels
;
897 desc
->ArraySize
= d3d11_desc
.ArraySize
;
898 desc
->Format
= d3d11_desc
.Format
;
899 desc
->SampleDesc
= d3d11_desc
.SampleDesc
;
900 desc
->Usage
= d3d10_usage_from_d3d11_usage(d3d11_desc
.Usage
);
901 desc
->BindFlags
= d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc
.BindFlags
);
902 desc
->CPUAccessFlags
= d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc
.CPUAccessFlags
);
903 desc
->MiscFlags
= d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc
.MiscFlags
);
906 static const struct ID3D10Texture2DVtbl d3d10_texture2d_vtbl
=
908 /* IUnknown methods */
909 d3d10_texture2d_QueryInterface
,
910 d3d10_texture2d_AddRef
,
911 d3d10_texture2d_Release
,
912 /* ID3D10DeviceChild methods */
913 d3d10_texture2d_GetDevice
,
914 d3d10_texture2d_GetPrivateData
,
915 d3d10_texture2d_SetPrivateData
,
916 d3d10_texture2d_SetPrivateDataInterface
,
917 /* ID3D10Resource methods */
918 d3d10_texture2d_GetType
,
919 d3d10_texture2d_SetEvictionPriority
,
920 d3d10_texture2d_GetEvictionPriority
,
921 /* ID3D10Texture2D methods */
923 d3d10_texture2d_Unmap
,
924 d3d10_texture2d_GetDesc
,
927 struct d3d_texture2d
*unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D
*iface
)
931 assert(iface
->lpVtbl
== &d3d10_texture2d_vtbl
);
932 return CONTAINING_RECORD(iface
, struct d3d_texture2d
, ID3D10Texture2D_iface
);
935 static const struct wined3d_parent_ops d3d_texture2d_wined3d_parent_ops
=
937 d3d_texture2d_wined3d_object_released
,
940 static BOOL
is_gdi_compatible_texture(const D3D11_TEXTURE2D_DESC
*desc
)
942 if (!(desc
->Format
== DXGI_FORMAT_B8G8R8A8_UNORM
943 || desc
->Format
== DXGI_FORMAT_B8G8R8A8_TYPELESS
944 || desc
->Format
== DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
))
947 if (desc
->Usage
!= D3D11_USAGE_DEFAULT
)
953 static BOOL
validate_texture2d_desc(const D3D11_TEXTURE2D_DESC
*desc
, D3D_FEATURE_LEVEL feature_level
)
955 if (!validate_d3d11_resource_access_flags(D3D11_RESOURCE_DIMENSION_TEXTURE2D
,
956 desc
->Usage
, desc
->BindFlags
, desc
->CPUAccessFlags
, feature_level
))
959 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_TEXTURECUBE
960 && desc
->ArraySize
< 6)
962 WARN("Invalid array size %u for cube texture.\n", desc
->ArraySize
);
966 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GDI_COMPATIBLE
967 && !is_gdi_compatible_texture(desc
))
969 WARN("Incompatible description used to create GDI compatible texture.\n");
973 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
974 && (~desc
->BindFlags
& (D3D11_BIND_RENDER_TARGET
| D3D11_BIND_SHADER_RESOURCE
)))
976 WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET and "
977 "D3D11_BIND_SHADER_RESOURCE.\n");
984 HRESULT
d3d_texture2d_create(struct d3d_device
*device
, const D3D11_TEXTURE2D_DESC
*desc
,
985 const D3D11_SUBRESOURCE_DATA
*data
, struct d3d_texture2d
**out
)
987 struct wined3d_resource_desc wined3d_desc
;
988 struct d3d_texture2d
*texture
;
993 if (!validate_texture2d_desc(desc
, device
->feature_level
))
995 WARN("Failed to validate texture desc.\n");
999 if (!(texture
= heap_alloc_zero(sizeof(*texture
))))
1000 return E_OUTOFMEMORY
;
1002 texture
->ID3D11Texture2D_iface
.lpVtbl
= &d3d11_texture2d_vtbl
;
1003 texture
->ID3D10Texture2D_iface
.lpVtbl
= &d3d10_texture2d_vtbl
;
1004 texture
->refcount
= 1;
1005 wined3d_mutex_lock();
1006 wined3d_private_store_init(&texture
->private_store
);
1007 texture
->desc
= *desc
;
1009 wined3d_desc
.resource_type
= WINED3D_RTYPE_TEXTURE_2D
;
1010 wined3d_desc
.format
= wined3dformat_from_dxgi_format(desc
->Format
);
1011 wined3d_desc
.multisample_type
= desc
->SampleDesc
.Count
> 1 ? desc
->SampleDesc
.Count
: WINED3D_MULTISAMPLE_NONE
;
1012 wined3d_desc
.multisample_quality
= desc
->SampleDesc
.Quality
;
1013 wined3d_desc
.usage
= wined3d_usage_from_d3d11(desc
->Usage
);
1014 wined3d_desc
.bind_flags
= wined3d_bind_flags_from_d3d11(desc
->BindFlags
);
1015 wined3d_desc
.access
= wined3d_access_from_d3d11(desc
->Usage
,
1016 desc
->Usage
== D3D11_USAGE_DEFAULT
? 0 : desc
->CPUAccessFlags
);
1017 wined3d_desc
.width
= desc
->Width
;
1018 wined3d_desc
.height
= desc
->Height
;
1019 wined3d_desc
.depth
= 1;
1020 wined3d_desc
.size
= 0;
1022 levels
= desc
->MipLevels
? desc
->MipLevels
: wined3d_log2i(max(desc
->Width
, desc
->Height
)) + 1;
1024 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GDI_COMPATIBLE
)
1025 flags
|= WINED3D_TEXTURE_CREATE_GET_DC
;
1026 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
)
1027 flags
|= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
;
1029 if (FAILED(hr
= wined3d_texture_create(device
->wined3d_device
, &wined3d_desc
,
1030 desc
->ArraySize
, levels
, flags
, (struct wined3d_sub_resource_data
*)data
,
1031 texture
, &d3d_texture2d_wined3d_parent_ops
, &texture
->wined3d_texture
)))
1033 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
1034 wined3d_private_store_cleanup(&texture
->private_store
);
1036 wined3d_mutex_unlock();
1037 if (hr
== WINED3DERR_NOTAVAILABLE
|| hr
== WINED3DERR_INVALIDCALL
)
1041 texture
->desc
.MipLevels
= levels
;
1043 if (desc
->MipLevels
== 1 && desc
->ArraySize
== 1)
1045 IWineDXGIDevice
*wine_device
;
1047 if (FAILED(hr
= ID3D10Device1_QueryInterface(&device
->ID3D10Device1_iface
, &IID_IWineDXGIDevice
,
1048 (void **)&wine_device
)))
1050 ERR("Device should implement IWineDXGIDevice.\n");
1051 wined3d_texture_decref(texture
->wined3d_texture
);
1052 wined3d_mutex_unlock();
1056 hr
= IWineDXGIDevice_create_surface(wine_device
, texture
->wined3d_texture
, 0, NULL
,
1057 (IUnknown
*)&texture
->ID3D10Texture2D_iface
, (void **)&texture
->dxgi_surface
);
1058 IWineDXGIDevice_Release(wine_device
);
1061 ERR("Failed to create DXGI surface, returning %#.x\n", hr
);
1062 texture
->dxgi_surface
= NULL
;
1063 wined3d_texture_decref(texture
->wined3d_texture
);
1064 wined3d_mutex_unlock();
1068 wined3d_mutex_unlock();
1070 ID3D11Device2_AddRef(texture
->device
= &device
->ID3D11Device2_iface
);
1072 TRACE("Created texture %p.\n", texture
);
1078 /* ID3D11Texture3D methods */
1080 static inline struct d3d_texture3d
*impl_from_ID3D11Texture3D(ID3D11Texture3D
*iface
)
1082 return CONTAINING_RECORD(iface
, struct d3d_texture3d
, ID3D11Texture3D_iface
);
1085 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_QueryInterface(ID3D11Texture3D
*iface
, REFIID riid
, void **object
)
1087 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1089 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1091 if (IsEqualGUID(riid
, &IID_ID3D11Texture3D
)
1092 || IsEqualGUID(riid
, &IID_ID3D11Resource
)
1093 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1094 || IsEqualGUID(riid
, &IID_IUnknown
))
1096 IUnknown_AddRef(iface
);
1100 else if (IsEqualGUID(riid
, &IID_ID3D10Texture3D
)
1101 || IsEqualGUID(riid
, &IID_ID3D10Resource
)
1102 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1104 IUnknown_AddRef(iface
);
1105 *object
= &texture
->ID3D10Texture3D_iface
;
1109 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1112 return E_NOINTERFACE
;
1115 static ULONG STDMETHODCALLTYPE
d3d11_texture3d_AddRef(ID3D11Texture3D
*iface
)
1117 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1118 ULONG refcount
= InterlockedIncrement(&texture
->refcount
);
1120 TRACE("%p increasing refcount to %u.\n", texture
, refcount
);
1124 ID3D11Device2_AddRef(texture
->device
);
1125 wined3d_mutex_lock();
1126 wined3d_texture_incref(texture
->wined3d_texture
);
1127 wined3d_mutex_unlock();
1133 static void STDMETHODCALLTYPE
d3d_texture3d_wined3d_object_released(void *parent
)
1135 struct d3d_texture3d
*texture
= parent
;
1137 wined3d_private_store_cleanup(&texture
->private_store
);
1141 static ULONG STDMETHODCALLTYPE
d3d11_texture3d_Release(ID3D11Texture3D
*iface
)
1143 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1144 ULONG refcount
= InterlockedDecrement(&texture
->refcount
);
1146 TRACE("%p decreasing refcount to %u.\n", texture
, refcount
);
1150 ID3D11Device2
*device
= texture
->device
;
1152 wined3d_mutex_lock();
1153 wined3d_texture_decref(texture
->wined3d_texture
);
1154 wined3d_mutex_unlock();
1155 /* Release the device last, it may cause the wined3d device to be
1157 ID3D11Device2_Release(device
);
1163 static void STDMETHODCALLTYPE
d3d11_texture3d_GetDevice(ID3D11Texture3D
*iface
, ID3D11Device
**device
)
1165 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1167 TRACE("iface %p, device %p.\n", iface
, device
);
1169 *device
= (ID3D11Device
*)texture
->device
;
1170 ID3D11Device_AddRef(*device
);
1173 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_GetPrivateData(ID3D11Texture3D
*iface
,
1174 REFGUID guid
, UINT
*data_size
, void *data
)
1176 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1178 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1180 return d3d_get_private_data(&texture
->private_store
, guid
, data_size
, data
);
1183 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_SetPrivateData(ID3D11Texture3D
*iface
,
1184 REFGUID guid
, UINT data_size
, const void *data
)
1186 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1188 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1190 return d3d_set_private_data(&texture
->private_store
, guid
, data_size
, data
);
1193 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_SetPrivateDataInterface(ID3D11Texture3D
*iface
,
1194 REFGUID guid
, const IUnknown
*data
)
1196 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1198 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1200 return d3d_set_private_data_interface(&texture
->private_store
, guid
, data
);
1203 static void STDMETHODCALLTYPE
d3d11_texture3d_GetType(ID3D11Texture3D
*iface
,
1204 D3D11_RESOURCE_DIMENSION
*resource_dimension
)
1206 TRACE("iface %p, resource_dimension %p.\n", iface
, resource_dimension
);
1208 *resource_dimension
= D3D11_RESOURCE_DIMENSION_TEXTURE3D
;
1211 static void STDMETHODCALLTYPE
d3d11_texture3d_SetEvictionPriority(ID3D11Texture3D
*iface
, UINT eviction_priority
)
1213 FIXME("iface %p, eviction_priority %#x stub!\n", iface
, eviction_priority
);
1216 static UINT STDMETHODCALLTYPE
d3d11_texture3d_GetEvictionPriority(ID3D11Texture3D
*iface
)
1218 FIXME("iface %p stub!\n", iface
);
1223 static void STDMETHODCALLTYPE
d3d11_texture3d_GetDesc(ID3D11Texture3D
*iface
, D3D11_TEXTURE3D_DESC
*desc
)
1225 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1227 TRACE("iface %p, desc %p.\n", iface
, desc
);
1229 *desc
= texture
->desc
;
1232 static const struct ID3D11Texture3DVtbl d3d11_texture3d_vtbl
=
1234 /* IUnknown methods */
1235 d3d11_texture3d_QueryInterface
,
1236 d3d11_texture3d_AddRef
,
1237 d3d11_texture3d_Release
,
1238 /* ID3D11DeviceChild methods */
1239 d3d11_texture3d_GetDevice
,
1240 d3d11_texture3d_GetPrivateData
,
1241 d3d11_texture3d_SetPrivateData
,
1242 d3d11_texture3d_SetPrivateDataInterface
,
1243 /* ID3D11Resource methods */
1244 d3d11_texture3d_GetType
,
1245 d3d11_texture3d_SetEvictionPriority
,
1246 d3d11_texture3d_GetEvictionPriority
,
1247 /* ID3D11Texture3D methods */
1248 d3d11_texture3d_GetDesc
,
1251 /* ID3D10Texture3D methods */
1253 static inline struct d3d_texture3d
*impl_from_ID3D10Texture3D(ID3D10Texture3D
*iface
)
1255 return CONTAINING_RECORD(iface
, struct d3d_texture3d
, ID3D10Texture3D_iface
);
1258 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_QueryInterface(ID3D10Texture3D
*iface
, REFIID riid
, void **object
)
1260 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1262 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1264 return d3d11_texture3d_QueryInterface(&texture
->ID3D11Texture3D_iface
, riid
, object
);
1267 static ULONG STDMETHODCALLTYPE
d3d10_texture3d_AddRef(ID3D10Texture3D
*iface
)
1269 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1271 TRACE("iface %p.\n", iface
);
1273 return d3d11_texture3d_AddRef(&texture
->ID3D11Texture3D_iface
);
1276 static ULONG STDMETHODCALLTYPE
d3d10_texture3d_Release(ID3D10Texture3D
*iface
)
1278 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1280 TRACE("iface %p.\n", iface
);
1282 return d3d11_texture3d_Release(&texture
->ID3D11Texture3D_iface
);
1285 static void STDMETHODCALLTYPE
d3d10_texture3d_GetDevice(ID3D10Texture3D
*iface
, ID3D10Device
**device
)
1287 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1289 TRACE("iface %p, device %p.\n", iface
, device
);
1291 ID3D11Device2_QueryInterface(texture
->device
, &IID_ID3D10Device
, (void **)device
);
1294 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_GetPrivateData(ID3D10Texture3D
*iface
,
1295 REFGUID guid
, UINT
*data_size
, void *data
)
1297 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1299 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1300 iface
, debugstr_guid(guid
), data_size
, data
);
1302 return d3d_get_private_data(&texture
->private_store
, guid
, data_size
, data
);
1305 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_SetPrivateData(ID3D10Texture3D
*iface
,
1306 REFGUID guid
, UINT data_size
, const void *data
)
1308 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1310 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1311 iface
, debugstr_guid(guid
), data_size
, data
);
1313 return d3d_set_private_data(&texture
->private_store
, guid
, data_size
, data
);
1316 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_SetPrivateDataInterface(ID3D10Texture3D
*iface
,
1317 REFGUID guid
, const IUnknown
*data
)
1319 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1321 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1323 return d3d_set_private_data_interface(&texture
->private_store
, guid
, data
);
1326 static void STDMETHODCALLTYPE
d3d10_texture3d_GetType(ID3D10Texture3D
*iface
,
1327 D3D10_RESOURCE_DIMENSION
*resource_dimension
)
1329 TRACE("iface %p, resource_dimension %p.\n", iface
, resource_dimension
);
1331 *resource_dimension
= D3D10_RESOURCE_DIMENSION_TEXTURE3D
;
1334 static void STDMETHODCALLTYPE
d3d10_texture3d_SetEvictionPriority(ID3D10Texture3D
*iface
, UINT eviction_priority
)
1336 FIXME("iface %p, eviction_priority %u stub!\n", iface
, eviction_priority
);
1339 static UINT STDMETHODCALLTYPE
d3d10_texture3d_GetEvictionPriority(ID3D10Texture3D
*iface
)
1341 FIXME("iface %p stub!\n", iface
);
1346 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_Map(ID3D10Texture3D
*iface
, UINT sub_resource_idx
,
1347 D3D10_MAP map_type
, UINT map_flags
, D3D10_MAPPED_TEXTURE3D
*mapped_texture
)
1349 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1350 struct wined3d_map_desc wined3d_map_desc
;
1353 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n",
1354 iface
, sub_resource_idx
, map_type
, map_flags
, mapped_texture
);
1357 FIXME("Ignoring map_flags %#x.\n", map_flags
);
1359 wined3d_mutex_lock();
1360 if (SUCCEEDED(hr
= wined3d_resource_map(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
,
1361 &wined3d_map_desc
, NULL
, wined3d_map_flags_from_d3d11_map_type(map_type
))))
1363 mapped_texture
->pData
= wined3d_map_desc
.data
;
1364 mapped_texture
->RowPitch
= wined3d_map_desc
.row_pitch
;
1365 mapped_texture
->DepthPitch
= wined3d_map_desc
.slice_pitch
;
1367 wined3d_mutex_unlock();
1372 static void STDMETHODCALLTYPE
d3d10_texture3d_Unmap(ID3D10Texture3D
*iface
, UINT sub_resource_idx
)
1374 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1376 TRACE("iface %p, sub_resource_idx %u.\n", iface
, sub_resource_idx
);
1378 wined3d_mutex_lock();
1379 wined3d_resource_unmap(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
);
1380 wined3d_mutex_unlock();
1383 static void STDMETHODCALLTYPE
d3d10_texture3d_GetDesc(ID3D10Texture3D
*iface
, D3D10_TEXTURE3D_DESC
*desc
)
1385 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1386 D3D11_TEXTURE3D_DESC d3d11_desc
;
1388 TRACE("iface %p, desc %p.\n", iface
, desc
);
1390 d3d11_texture3d_GetDesc(&texture
->ID3D11Texture3D_iface
, &d3d11_desc
);
1392 desc
->Width
= d3d11_desc
.Width
;
1393 desc
->Height
= d3d11_desc
.Height
;
1394 desc
->Depth
= d3d11_desc
.Depth
;
1395 desc
->MipLevels
= d3d11_desc
.MipLevels
;
1396 desc
->Format
= d3d11_desc
.Format
;
1397 desc
->Usage
= d3d10_usage_from_d3d11_usage(d3d11_desc
.Usage
);
1398 desc
->BindFlags
= d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc
.BindFlags
);
1399 desc
->CPUAccessFlags
= d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc
.CPUAccessFlags
);
1400 desc
->MiscFlags
= d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc
.MiscFlags
);
1403 static const struct ID3D10Texture3DVtbl d3d10_texture3d_vtbl
=
1405 /* IUnknown methods */
1406 d3d10_texture3d_QueryInterface
,
1407 d3d10_texture3d_AddRef
,
1408 d3d10_texture3d_Release
,
1409 /* ID3D10DeviceChild methods */
1410 d3d10_texture3d_GetDevice
,
1411 d3d10_texture3d_GetPrivateData
,
1412 d3d10_texture3d_SetPrivateData
,
1413 d3d10_texture3d_SetPrivateDataInterface
,
1414 /* ID3D10Resource methods */
1415 d3d10_texture3d_GetType
,
1416 d3d10_texture3d_SetEvictionPriority
,
1417 d3d10_texture3d_GetEvictionPriority
,
1418 /* ID3D10Texture3D methods */
1419 d3d10_texture3d_Map
,
1420 d3d10_texture3d_Unmap
,
1421 d3d10_texture3d_GetDesc
,
1424 struct d3d_texture3d
*unsafe_impl_from_ID3D10Texture3D(ID3D10Texture3D
*iface
)
1428 assert(iface
->lpVtbl
== &d3d10_texture3d_vtbl
);
1429 return CONTAINING_RECORD(iface
, struct d3d_texture3d
, ID3D10Texture3D_iface
);
1432 struct d3d_texture3d
*unsafe_impl_from_ID3D11Texture3D(ID3D11Texture3D
*iface
)
1436 assert(iface
->lpVtbl
== &d3d11_texture3d_vtbl
);
1437 return impl_from_ID3D11Texture3D(iface
);
1440 static const struct wined3d_parent_ops d3d_texture3d_wined3d_parent_ops
=
1442 d3d_texture3d_wined3d_object_released
,
1445 static HRESULT
d3d_texture3d_init(struct d3d_texture3d
*texture
, struct d3d_device
*device
,
1446 const D3D11_TEXTURE3D_DESC
*desc
, const D3D11_SUBRESOURCE_DATA
*data
)
1448 struct wined3d_resource_desc wined3d_desc
;
1449 unsigned int levels
;
1453 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
1454 && (~desc
->BindFlags
& (D3D11_BIND_RENDER_TARGET
| D3D11_BIND_SHADER_RESOURCE
)))
1456 WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET "
1457 "and D3D11_BIND_SHADER_RESOURCE.\n");
1458 return E_INVALIDARG
;
1461 texture
->ID3D11Texture3D_iface
.lpVtbl
= &d3d11_texture3d_vtbl
;
1462 texture
->ID3D10Texture3D_iface
.lpVtbl
= &d3d10_texture3d_vtbl
;
1463 texture
->refcount
= 1;
1464 wined3d_mutex_lock();
1465 wined3d_private_store_init(&texture
->private_store
);
1466 texture
->desc
= *desc
;
1468 wined3d_desc
.resource_type
= WINED3D_RTYPE_TEXTURE_3D
;
1469 wined3d_desc
.format
= wined3dformat_from_dxgi_format(desc
->Format
);
1470 wined3d_desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1471 wined3d_desc
.multisample_quality
= 0;
1472 wined3d_desc
.usage
= wined3d_usage_from_d3d11(desc
->Usage
);
1473 wined3d_desc
.bind_flags
= wined3d_bind_flags_from_d3d11(desc
->BindFlags
);
1474 wined3d_desc
.access
= wined3d_access_from_d3d11(desc
->Usage
,
1475 desc
->Usage
== D3D11_USAGE_DEFAULT
? 0 : desc
->CPUAccessFlags
);
1476 wined3d_desc
.width
= desc
->Width
;
1477 wined3d_desc
.height
= desc
->Height
;
1478 wined3d_desc
.depth
= desc
->Depth
;
1479 wined3d_desc
.size
= 0;
1481 levels
= desc
->MipLevels
? desc
->MipLevels
: wined3d_log2i(max(max(desc
->Width
, desc
->Height
), desc
->Depth
)) + 1;
1483 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
)
1484 flags
|= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
;
1486 if (FAILED(hr
= wined3d_texture_create(device
->wined3d_device
, &wined3d_desc
,
1487 1, levels
, flags
, (struct wined3d_sub_resource_data
*)data
, texture
,
1488 &d3d_texture3d_wined3d_parent_ops
, &texture
->wined3d_texture
)))
1490 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
1491 wined3d_private_store_cleanup(&texture
->private_store
);
1492 wined3d_mutex_unlock();
1493 if (hr
== WINED3DERR_INVALIDCALL
)
1497 wined3d_mutex_unlock();
1498 texture
->desc
.MipLevels
= levels
;
1500 ID3D11Device2_AddRef(texture
->device
= &device
->ID3D11Device2_iface
);
1505 HRESULT
d3d_texture3d_create(struct d3d_device
*device
, const D3D11_TEXTURE3D_DESC
*desc
,
1506 const D3D11_SUBRESOURCE_DATA
*data
, struct d3d_texture3d
**texture
)
1508 struct d3d_texture3d
*object
;
1511 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1512 return E_OUTOFMEMORY
;
1514 if (FAILED(hr
= d3d_texture3d_init(object
, device
, desc
, data
)))
1516 WARN("Failed to initialize texture, hr %#x.\n", hr
);
1521 TRACE("Created texture %p.\n", object
);