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
->BindFlags
, desc
->Usage
);
460 wined3d_desc
.access
= wined3d_access_from_d3d11(desc
->Usage
,
461 desc
->Usage
== D3D11_USAGE_DEFAULT
? 0 : desc
->CPUAccessFlags
);
462 wined3d_desc
.width
= desc
->Width
;
463 wined3d_desc
.height
= 1;
464 wined3d_desc
.depth
= 1;
465 wined3d_desc
.size
= 0;
467 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GDI_COMPATIBLE
)
468 flags
|= WINED3D_TEXTURE_CREATE_GET_DC
;
469 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
)
470 flags
|= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
;
472 wined3d_mutex_lock();
473 if (FAILED(hr
= wined3d_texture_create(device
->wined3d_device
, &wined3d_desc
,
474 desc
->ArraySize
, levels
, flags
, (struct wined3d_sub_resource_data
*)data
,
475 texture
, &d3d_texture1d_wined3d_parent_ops
, &texture
->wined3d_texture
)))
477 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
478 wined3d_private_store_cleanup(&texture
->private_store
);
480 wined3d_mutex_unlock();
481 if (hr
== WINED3DERR_NOTAVAILABLE
|| hr
== WINED3DERR_INVALIDCALL
)
486 if (desc
->MipLevels
== 1 && desc
->ArraySize
== 1)
488 IWineDXGIDevice
*wine_device
;
490 if (FAILED(hr
= ID3D10Device1_QueryInterface(&device
->ID3D10Device1_iface
, &IID_IWineDXGIDevice
,
491 (void **)&wine_device
)))
493 ERR("Device should implement IWineDXGIDevice.\n");
494 wined3d_texture_decref(texture
->wined3d_texture
);
495 wined3d_mutex_unlock();
499 hr
= IWineDXGIDevice_create_surface(wine_device
, texture
->wined3d_texture
, 0, NULL
,
500 (IUnknown
*)&texture
->ID3D10Texture1D_iface
, (void **)&texture
->dxgi_surface
);
501 IWineDXGIDevice_Release(wine_device
);
504 ERR("Failed to create DXGI surface, returning %#.x\n", hr
);
505 texture
->dxgi_surface
= NULL
;
506 wined3d_texture_decref(texture
->wined3d_texture
);
507 wined3d_mutex_unlock();
511 wined3d_mutex_unlock();
513 ID3D11Device2_AddRef(texture
->device
= &device
->ID3D11Device2_iface
);
515 TRACE("Created texture %p.\n", texture
);
521 /* ID3D11Texture2D methods */
523 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_QueryInterface(ID3D11Texture2D
*iface
, REFIID riid
, void **object
)
525 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
527 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
529 if (IsEqualGUID(riid
, &IID_ID3D11Texture2D
)
530 || IsEqualGUID(riid
, &IID_ID3D11Resource
)
531 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
532 || IsEqualGUID(riid
, &IID_IUnknown
))
534 *object
= &texture
->ID3D11Texture2D_iface
;
535 IUnknown_AddRef((IUnknown
*)*object
);
538 else if (IsEqualGUID(riid
, &IID_ID3D10Texture2D
)
539 || IsEqualGUID(riid
, &IID_ID3D10Resource
)
540 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
542 *object
= &texture
->ID3D10Texture2D_iface
;
543 IUnknown_AddRef((IUnknown
*)*object
);
547 if (texture
->dxgi_surface
)
549 TRACE("Forwarding to dxgi surface.\n");
550 return IUnknown_QueryInterface(texture
->dxgi_surface
, riid
, object
);
553 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
556 return E_NOINTERFACE
;
559 static ULONG STDMETHODCALLTYPE
d3d11_texture2d_AddRef(ID3D11Texture2D
*iface
)
561 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
562 ULONG refcount
= InterlockedIncrement(&texture
->refcount
);
564 TRACE("%p increasing refcount to %u.\n", texture
, refcount
);
568 ID3D11Device2_AddRef(texture
->device
);
569 wined3d_mutex_lock();
570 wined3d_texture_incref(texture
->wined3d_texture
);
571 wined3d_mutex_unlock();
577 static ULONG STDMETHODCALLTYPE
d3d11_texture2d_Release(ID3D11Texture2D
*iface
)
579 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
580 ULONG refcount
= InterlockedDecrement(&texture
->refcount
);
582 TRACE("%p decreasing refcount to %u.\n", texture
, refcount
);
586 ID3D11Device2
*device
= texture
->device
;
588 wined3d_mutex_lock();
589 wined3d_texture_decref(texture
->wined3d_texture
);
590 wined3d_mutex_unlock();
591 /* Release the device last, it may cause the wined3d device to be
593 ID3D11Device2_Release(device
);
599 static void STDMETHODCALLTYPE
d3d11_texture2d_GetDevice(ID3D11Texture2D
*iface
, ID3D11Device
**device
)
601 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
603 TRACE("iface %p, device %p.\n", iface
, device
);
605 *device
= (ID3D11Device
*)texture
->device
;
606 ID3D11Device_AddRef(*device
);
609 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_GetPrivateData(ID3D11Texture2D
*iface
,
610 REFGUID guid
, UINT
*data_size
, void *data
)
612 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
613 IDXGISurface
*dxgi_surface
;
616 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
618 if (texture
->dxgi_surface
619 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
621 hr
= IDXGISurface_GetPrivateData(dxgi_surface
, guid
, data_size
, data
);
622 IDXGISurface_Release(dxgi_surface
);
626 return d3d_get_private_data(&texture
->private_store
, guid
, data_size
, data
);
629 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_SetPrivateData(ID3D11Texture2D
*iface
,
630 REFGUID guid
, UINT data_size
, const void *data
)
632 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
633 IDXGISurface
*dxgi_surface
;
636 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
638 if (texture
->dxgi_surface
639 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
641 hr
= IDXGISurface_SetPrivateData(dxgi_surface
, guid
, data_size
, data
);
642 IDXGISurface_Release(dxgi_surface
);
646 return d3d_set_private_data(&texture
->private_store
, guid
, data_size
, data
);
649 static HRESULT STDMETHODCALLTYPE
d3d11_texture2d_SetPrivateDataInterface(ID3D11Texture2D
*iface
,
650 REFGUID guid
, const IUnknown
*data
)
652 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
653 IDXGISurface
*dxgi_surface
;
656 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
658 if (texture
->dxgi_surface
659 && SUCCEEDED(IUnknown_QueryInterface(texture
->dxgi_surface
, &IID_IDXGISurface
, (void **)&dxgi_surface
)))
661 hr
= IDXGISurface_SetPrivateDataInterface(dxgi_surface
, guid
, data
);
662 IDXGISurface_Release(dxgi_surface
);
666 return d3d_set_private_data_interface(&texture
->private_store
, guid
, data
);
669 static void STDMETHODCALLTYPE
d3d11_texture2d_GetType(ID3D11Texture2D
*iface
,
670 D3D11_RESOURCE_DIMENSION
*resource_dimension
)
672 TRACE("iface %p, resource_dimension %p.\n", iface
, resource_dimension
);
674 *resource_dimension
= D3D11_RESOURCE_DIMENSION_TEXTURE2D
;
677 static void STDMETHODCALLTYPE
d3d11_texture2d_SetEvictionPriority(ID3D11Texture2D
*iface
, UINT eviction_priority
)
679 FIXME("iface %p, eviction_priority %#x stub!\n", iface
, eviction_priority
);
682 static UINT STDMETHODCALLTYPE
d3d11_texture2d_GetEvictionPriority(ID3D11Texture2D
*iface
)
684 FIXME("iface %p stub!\n", iface
);
689 static void STDMETHODCALLTYPE
d3d11_texture2d_GetDesc(ID3D11Texture2D
*iface
, D3D11_TEXTURE2D_DESC
*desc
)
691 struct d3d_texture2d
*texture
= impl_from_ID3D11Texture2D(iface
);
692 struct wined3d_resource_desc wined3d_desc
;
694 TRACE("iface %p, desc %p.\n", iface
, desc
);
696 *desc
= texture
->desc
;
698 wined3d_mutex_lock();
699 wined3d_resource_get_desc(wined3d_texture_get_resource(texture
->wined3d_texture
), &wined3d_desc
);
700 wined3d_mutex_unlock();
702 /* FIXME: Resizing swapchain buffers can cause these to change. We'd like
703 * to get everything from wined3d, but e.g. bind flags don't exist as such
705 desc
->Width
= wined3d_desc
.width
;
706 desc
->Height
= wined3d_desc
.height
;
707 desc
->Format
= dxgi_format_from_wined3dformat(wined3d_desc
.format
);
708 desc
->SampleDesc
.Count
= wined3d_desc
.multisample_type
== WINED3D_MULTISAMPLE_NONE
709 ? 1 : wined3d_desc
.multisample_type
;
710 desc
->SampleDesc
.Quality
= wined3d_desc
.multisample_quality
;
713 static const struct ID3D11Texture2DVtbl d3d11_texture2d_vtbl
=
715 /* IUnknown methods */
716 d3d11_texture2d_QueryInterface
,
717 d3d11_texture2d_AddRef
,
718 d3d11_texture2d_Release
,
719 /* ID3D11DeviceChild methods */
720 d3d11_texture2d_GetDevice
,
721 d3d11_texture2d_GetPrivateData
,
722 d3d11_texture2d_SetPrivateData
,
723 d3d11_texture2d_SetPrivateDataInterface
,
724 /* ID3D11Resource methods */
725 d3d11_texture2d_GetType
,
726 d3d11_texture2d_SetEvictionPriority
,
727 d3d11_texture2d_GetEvictionPriority
,
728 /* ID3D11Texture2D methods */
729 d3d11_texture2d_GetDesc
,
732 struct d3d_texture2d
*unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D
*iface
)
736 assert(iface
->lpVtbl
== &d3d11_texture2d_vtbl
);
737 return CONTAINING_RECORD(iface
, struct d3d_texture2d
, ID3D11Texture2D_iface
);
740 /* IUnknown methods */
742 static inline struct d3d_texture2d
*impl_from_ID3D10Texture2D(ID3D10Texture2D
*iface
)
744 return CONTAINING_RECORD(iface
, struct d3d_texture2d
, ID3D10Texture2D_iface
);
747 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_QueryInterface(ID3D10Texture2D
*iface
, REFIID riid
, void **object
)
749 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
751 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
753 return d3d11_texture2d_QueryInterface(&texture
->ID3D11Texture2D_iface
, riid
, object
);
756 static ULONG STDMETHODCALLTYPE
d3d10_texture2d_AddRef(ID3D10Texture2D
*iface
)
758 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
760 TRACE("iface %p.\n", iface
);
762 return d3d11_texture2d_AddRef(&texture
->ID3D11Texture2D_iface
);
765 static void STDMETHODCALLTYPE
d3d_texture2d_wined3d_object_released(void *parent
)
767 struct d3d_texture2d
*texture
= parent
;
769 if (texture
->dxgi_surface
) IUnknown_Release(texture
->dxgi_surface
);
770 wined3d_private_store_cleanup(&texture
->private_store
);
774 static ULONG STDMETHODCALLTYPE
d3d10_texture2d_Release(ID3D10Texture2D
*iface
)
776 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
778 TRACE("iface %p.\n", iface
);
780 return d3d11_texture2d_Release(&texture
->ID3D11Texture2D_iface
);
783 /* ID3D10DeviceChild methods */
785 static void STDMETHODCALLTYPE
d3d10_texture2d_GetDevice(ID3D10Texture2D
*iface
, ID3D10Device
**device
)
787 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
789 TRACE("iface %p, device %p.\n", iface
, device
);
791 ID3D11Device2_QueryInterface(texture
->device
, &IID_ID3D10Device
, (void **)device
);
794 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_GetPrivateData(ID3D10Texture2D
*iface
,
795 REFGUID guid
, UINT
*data_size
, void *data
)
797 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
799 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
801 return d3d11_texture2d_GetPrivateData(&texture
->ID3D11Texture2D_iface
, guid
, data_size
, data
);
804 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_SetPrivateData(ID3D10Texture2D
*iface
,
805 REFGUID guid
, UINT data_size
, const void *data
)
807 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
809 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
811 return d3d11_texture2d_SetPrivateData(&texture
->ID3D11Texture2D_iface
, guid
, data_size
, data
);
814 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_SetPrivateDataInterface(ID3D10Texture2D
*iface
,
815 REFGUID guid
, const IUnknown
*data
)
817 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
819 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
821 return d3d11_texture2d_SetPrivateDataInterface(&texture
->ID3D11Texture2D_iface
, guid
, data
);
824 /* ID3D10Resource methods */
826 static void STDMETHODCALLTYPE
d3d10_texture2d_GetType(ID3D10Texture2D
*iface
,
827 D3D10_RESOURCE_DIMENSION
*resource_dimension
)
829 TRACE("iface %p, resource_dimension %p\n", iface
, resource_dimension
);
831 *resource_dimension
= D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
834 static void STDMETHODCALLTYPE
d3d10_texture2d_SetEvictionPriority(ID3D10Texture2D
*iface
, UINT eviction_priority
)
836 FIXME("iface %p, eviction_priority %u stub!\n", iface
, eviction_priority
);
839 static UINT STDMETHODCALLTYPE
d3d10_texture2d_GetEvictionPriority(ID3D10Texture2D
*iface
)
841 FIXME("iface %p stub!\n", iface
);
846 /* ID3D10Texture2D methods */
848 static HRESULT STDMETHODCALLTYPE
d3d10_texture2d_Map(ID3D10Texture2D
*iface
, UINT sub_resource_idx
,
849 D3D10_MAP map_type
, UINT map_flags
, D3D10_MAPPED_TEXTURE2D
*mapped_texture
)
851 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
852 struct wined3d_map_desc wined3d_map_desc
;
855 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n",
856 iface
, sub_resource_idx
, map_type
, map_flags
, mapped_texture
);
859 FIXME("Ignoring map_flags %#x.\n", map_flags
);
861 wined3d_mutex_lock();
862 if (SUCCEEDED(hr
= wined3d_resource_map(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
,
863 &wined3d_map_desc
, NULL
, wined3d_map_flags_from_d3d11_map_type(map_type
))))
865 mapped_texture
->pData
= wined3d_map_desc
.data
;
866 mapped_texture
->RowPitch
= wined3d_map_desc
.row_pitch
;
868 wined3d_mutex_unlock();
873 static void STDMETHODCALLTYPE
d3d10_texture2d_Unmap(ID3D10Texture2D
*iface
, UINT sub_resource_idx
)
875 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
877 TRACE("iface %p, sub_resource_idx %u.\n", iface
, sub_resource_idx
);
879 wined3d_mutex_lock();
880 wined3d_resource_unmap(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
);
881 wined3d_mutex_unlock();
884 static void STDMETHODCALLTYPE
d3d10_texture2d_GetDesc(ID3D10Texture2D
*iface
, D3D10_TEXTURE2D_DESC
*desc
)
886 struct d3d_texture2d
*texture
= impl_from_ID3D10Texture2D(iface
);
887 D3D11_TEXTURE2D_DESC d3d11_desc
;
889 TRACE("iface %p, desc %p\n", iface
, desc
);
891 d3d11_texture2d_GetDesc(&texture
->ID3D11Texture2D_iface
, &d3d11_desc
);
893 desc
->Width
= d3d11_desc
.Width
;
894 desc
->Height
= d3d11_desc
.Height
;
895 desc
->MipLevels
= d3d11_desc
.MipLevels
;
896 desc
->ArraySize
= d3d11_desc
.ArraySize
;
897 desc
->Format
= d3d11_desc
.Format
;
898 desc
->SampleDesc
= d3d11_desc
.SampleDesc
;
899 desc
->Usage
= d3d10_usage_from_d3d11_usage(d3d11_desc
.Usage
);
900 desc
->BindFlags
= d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc
.BindFlags
);
901 desc
->CPUAccessFlags
= d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc
.CPUAccessFlags
);
902 desc
->MiscFlags
= d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc
.MiscFlags
);
905 static const struct ID3D10Texture2DVtbl d3d10_texture2d_vtbl
=
907 /* IUnknown methods */
908 d3d10_texture2d_QueryInterface
,
909 d3d10_texture2d_AddRef
,
910 d3d10_texture2d_Release
,
911 /* ID3D10DeviceChild methods */
912 d3d10_texture2d_GetDevice
,
913 d3d10_texture2d_GetPrivateData
,
914 d3d10_texture2d_SetPrivateData
,
915 d3d10_texture2d_SetPrivateDataInterface
,
916 /* ID3D10Resource methods */
917 d3d10_texture2d_GetType
,
918 d3d10_texture2d_SetEvictionPriority
,
919 d3d10_texture2d_GetEvictionPriority
,
920 /* ID3D10Texture2D methods */
922 d3d10_texture2d_Unmap
,
923 d3d10_texture2d_GetDesc
,
926 struct d3d_texture2d
*unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D
*iface
)
930 assert(iface
->lpVtbl
== &d3d10_texture2d_vtbl
);
931 return CONTAINING_RECORD(iface
, struct d3d_texture2d
, ID3D10Texture2D_iface
);
934 static const struct wined3d_parent_ops d3d_texture2d_wined3d_parent_ops
=
936 d3d_texture2d_wined3d_object_released
,
939 static BOOL
is_gdi_compatible_texture(const D3D11_TEXTURE2D_DESC
*desc
)
941 if (!(desc
->Format
== DXGI_FORMAT_B8G8R8A8_UNORM
942 || desc
->Format
== DXGI_FORMAT_B8G8R8A8_TYPELESS
943 || desc
->Format
== DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
))
946 if (desc
->Usage
!= D3D11_USAGE_DEFAULT
)
952 static BOOL
validate_texture2d_desc(const D3D11_TEXTURE2D_DESC
*desc
, D3D_FEATURE_LEVEL feature_level
)
954 if (!validate_d3d11_resource_access_flags(D3D11_RESOURCE_DIMENSION_TEXTURE2D
,
955 desc
->Usage
, desc
->BindFlags
, desc
->CPUAccessFlags
, feature_level
))
958 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_TEXTURECUBE
959 && desc
->ArraySize
< 6)
961 WARN("Invalid array size %u for cube texture.\n", desc
->ArraySize
);
965 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GDI_COMPATIBLE
966 && !is_gdi_compatible_texture(desc
))
968 WARN("Incompatible description used to create GDI compatible texture.\n");
972 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
973 && (~desc
->BindFlags
& (D3D11_BIND_RENDER_TARGET
| D3D11_BIND_SHADER_RESOURCE
)))
975 WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET and "
976 "D3D11_BIND_SHADER_RESOURCE.\n");
983 HRESULT
d3d_texture2d_create(struct d3d_device
*device
, const D3D11_TEXTURE2D_DESC
*desc
,
984 const D3D11_SUBRESOURCE_DATA
*data
, struct d3d_texture2d
**out
)
986 struct wined3d_resource_desc wined3d_desc
;
987 struct d3d_texture2d
*texture
;
992 if (!validate_texture2d_desc(desc
, device
->feature_level
))
994 WARN("Failed to validate texture desc.\n");
998 if (!(texture
= heap_alloc_zero(sizeof(*texture
))))
999 return E_OUTOFMEMORY
;
1001 texture
->ID3D11Texture2D_iface
.lpVtbl
= &d3d11_texture2d_vtbl
;
1002 texture
->ID3D10Texture2D_iface
.lpVtbl
= &d3d10_texture2d_vtbl
;
1003 texture
->refcount
= 1;
1004 wined3d_mutex_lock();
1005 wined3d_private_store_init(&texture
->private_store
);
1006 texture
->desc
= *desc
;
1008 wined3d_desc
.resource_type
= WINED3D_RTYPE_TEXTURE_2D
;
1009 wined3d_desc
.format
= wined3dformat_from_dxgi_format(desc
->Format
);
1010 wined3d_desc
.multisample_type
= desc
->SampleDesc
.Count
> 1 ? desc
->SampleDesc
.Count
: WINED3D_MULTISAMPLE_NONE
;
1011 wined3d_desc
.multisample_quality
= desc
->SampleDesc
.Quality
;
1012 wined3d_desc
.usage
= wined3d_usage_from_d3d11(desc
->BindFlags
, desc
->Usage
);
1013 wined3d_desc
.access
= wined3d_access_from_d3d11(desc
->Usage
,
1014 desc
->Usage
== D3D11_USAGE_DEFAULT
? 0 : desc
->CPUAccessFlags
);
1015 wined3d_desc
.width
= desc
->Width
;
1016 wined3d_desc
.height
= desc
->Height
;
1017 wined3d_desc
.depth
= 1;
1018 wined3d_desc
.size
= 0;
1020 levels
= desc
->MipLevels
? desc
->MipLevels
: wined3d_log2i(max(desc
->Width
, desc
->Height
)) + 1;
1022 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GDI_COMPATIBLE
)
1023 flags
|= WINED3D_TEXTURE_CREATE_GET_DC
;
1024 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
)
1025 flags
|= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
;
1027 if (FAILED(hr
= wined3d_texture_create(device
->wined3d_device
, &wined3d_desc
,
1028 desc
->ArraySize
, levels
, flags
, (struct wined3d_sub_resource_data
*)data
,
1029 texture
, &d3d_texture2d_wined3d_parent_ops
, &texture
->wined3d_texture
)))
1031 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
1032 wined3d_private_store_cleanup(&texture
->private_store
);
1034 wined3d_mutex_unlock();
1035 if (hr
== WINED3DERR_NOTAVAILABLE
|| hr
== WINED3DERR_INVALIDCALL
)
1039 texture
->desc
.MipLevels
= levels
;
1041 if (desc
->MipLevels
== 1 && desc
->ArraySize
== 1)
1043 IWineDXGIDevice
*wine_device
;
1045 if (FAILED(hr
= ID3D10Device1_QueryInterface(&device
->ID3D10Device1_iface
, &IID_IWineDXGIDevice
,
1046 (void **)&wine_device
)))
1048 ERR("Device should implement IWineDXGIDevice.\n");
1049 wined3d_texture_decref(texture
->wined3d_texture
);
1050 wined3d_mutex_unlock();
1054 hr
= IWineDXGIDevice_create_surface(wine_device
, texture
->wined3d_texture
, 0, NULL
,
1055 (IUnknown
*)&texture
->ID3D10Texture2D_iface
, (void **)&texture
->dxgi_surface
);
1056 IWineDXGIDevice_Release(wine_device
);
1059 ERR("Failed to create DXGI surface, returning %#.x\n", hr
);
1060 texture
->dxgi_surface
= NULL
;
1061 wined3d_texture_decref(texture
->wined3d_texture
);
1062 wined3d_mutex_unlock();
1066 wined3d_mutex_unlock();
1068 ID3D11Device2_AddRef(texture
->device
= &device
->ID3D11Device2_iface
);
1070 TRACE("Created texture %p.\n", texture
);
1076 /* ID3D11Texture3D methods */
1078 static inline struct d3d_texture3d
*impl_from_ID3D11Texture3D(ID3D11Texture3D
*iface
)
1080 return CONTAINING_RECORD(iface
, struct d3d_texture3d
, ID3D11Texture3D_iface
);
1083 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_QueryInterface(ID3D11Texture3D
*iface
, REFIID riid
, void **object
)
1085 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1087 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1089 if (IsEqualGUID(riid
, &IID_ID3D11Texture3D
)
1090 || IsEqualGUID(riid
, &IID_ID3D11Resource
)
1091 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1092 || IsEqualGUID(riid
, &IID_IUnknown
))
1094 IUnknown_AddRef(iface
);
1098 else if (IsEqualGUID(riid
, &IID_ID3D10Texture3D
)
1099 || IsEqualGUID(riid
, &IID_ID3D10Resource
)
1100 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1102 IUnknown_AddRef(iface
);
1103 *object
= &texture
->ID3D10Texture3D_iface
;
1107 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1110 return E_NOINTERFACE
;
1113 static ULONG STDMETHODCALLTYPE
d3d11_texture3d_AddRef(ID3D11Texture3D
*iface
)
1115 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1116 ULONG refcount
= InterlockedIncrement(&texture
->refcount
);
1118 TRACE("%p increasing refcount to %u.\n", texture
, refcount
);
1122 ID3D11Device2_AddRef(texture
->device
);
1123 wined3d_mutex_lock();
1124 wined3d_texture_incref(texture
->wined3d_texture
);
1125 wined3d_mutex_unlock();
1131 static void STDMETHODCALLTYPE
d3d_texture3d_wined3d_object_released(void *parent
)
1133 struct d3d_texture3d
*texture
= parent
;
1135 wined3d_private_store_cleanup(&texture
->private_store
);
1139 static ULONG STDMETHODCALLTYPE
d3d11_texture3d_Release(ID3D11Texture3D
*iface
)
1141 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1142 ULONG refcount
= InterlockedDecrement(&texture
->refcount
);
1144 TRACE("%p decreasing refcount to %u.\n", texture
, refcount
);
1148 ID3D11Device2
*device
= texture
->device
;
1150 wined3d_mutex_lock();
1151 wined3d_texture_decref(texture
->wined3d_texture
);
1152 wined3d_mutex_unlock();
1153 /* Release the device last, it may cause the wined3d device to be
1155 ID3D11Device2_Release(device
);
1161 static void STDMETHODCALLTYPE
d3d11_texture3d_GetDevice(ID3D11Texture3D
*iface
, ID3D11Device
**device
)
1163 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1165 TRACE("iface %p, device %p.\n", iface
, device
);
1167 *device
= (ID3D11Device
*)texture
->device
;
1168 ID3D11Device_AddRef(*device
);
1171 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_GetPrivateData(ID3D11Texture3D
*iface
,
1172 REFGUID guid
, UINT
*data_size
, void *data
)
1174 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1176 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1178 return d3d_get_private_data(&texture
->private_store
, guid
, data_size
, data
);
1181 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_SetPrivateData(ID3D11Texture3D
*iface
,
1182 REFGUID guid
, UINT data_size
, const void *data
)
1184 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1186 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1188 return d3d_set_private_data(&texture
->private_store
, guid
, data_size
, data
);
1191 static HRESULT STDMETHODCALLTYPE
d3d11_texture3d_SetPrivateDataInterface(ID3D11Texture3D
*iface
,
1192 REFGUID guid
, const IUnknown
*data
)
1194 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1196 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1198 return d3d_set_private_data_interface(&texture
->private_store
, guid
, data
);
1201 static void STDMETHODCALLTYPE
d3d11_texture3d_GetType(ID3D11Texture3D
*iface
,
1202 D3D11_RESOURCE_DIMENSION
*resource_dimension
)
1204 TRACE("iface %p, resource_dimension %p.\n", iface
, resource_dimension
);
1206 *resource_dimension
= D3D11_RESOURCE_DIMENSION_TEXTURE3D
;
1209 static void STDMETHODCALLTYPE
d3d11_texture3d_SetEvictionPriority(ID3D11Texture3D
*iface
, UINT eviction_priority
)
1211 FIXME("iface %p, eviction_priority %#x stub!\n", iface
, eviction_priority
);
1214 static UINT STDMETHODCALLTYPE
d3d11_texture3d_GetEvictionPriority(ID3D11Texture3D
*iface
)
1216 FIXME("iface %p stub!\n", iface
);
1221 static void STDMETHODCALLTYPE
d3d11_texture3d_GetDesc(ID3D11Texture3D
*iface
, D3D11_TEXTURE3D_DESC
*desc
)
1223 struct d3d_texture3d
*texture
= impl_from_ID3D11Texture3D(iface
);
1225 TRACE("iface %p, desc %p.\n", iface
, desc
);
1227 *desc
= texture
->desc
;
1230 static const struct ID3D11Texture3DVtbl d3d11_texture3d_vtbl
=
1232 /* IUnknown methods */
1233 d3d11_texture3d_QueryInterface
,
1234 d3d11_texture3d_AddRef
,
1235 d3d11_texture3d_Release
,
1236 /* ID3D11DeviceChild methods */
1237 d3d11_texture3d_GetDevice
,
1238 d3d11_texture3d_GetPrivateData
,
1239 d3d11_texture3d_SetPrivateData
,
1240 d3d11_texture3d_SetPrivateDataInterface
,
1241 /* ID3D11Resource methods */
1242 d3d11_texture3d_GetType
,
1243 d3d11_texture3d_SetEvictionPriority
,
1244 d3d11_texture3d_GetEvictionPriority
,
1245 /* ID3D11Texture3D methods */
1246 d3d11_texture3d_GetDesc
,
1249 /* ID3D10Texture3D methods */
1251 static inline struct d3d_texture3d
*impl_from_ID3D10Texture3D(ID3D10Texture3D
*iface
)
1253 return CONTAINING_RECORD(iface
, struct d3d_texture3d
, ID3D10Texture3D_iface
);
1256 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_QueryInterface(ID3D10Texture3D
*iface
, REFIID riid
, void **object
)
1258 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1260 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1262 return d3d11_texture3d_QueryInterface(&texture
->ID3D11Texture3D_iface
, riid
, object
);
1265 static ULONG STDMETHODCALLTYPE
d3d10_texture3d_AddRef(ID3D10Texture3D
*iface
)
1267 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1269 TRACE("iface %p.\n", iface
);
1271 return d3d11_texture3d_AddRef(&texture
->ID3D11Texture3D_iface
);
1274 static ULONG STDMETHODCALLTYPE
d3d10_texture3d_Release(ID3D10Texture3D
*iface
)
1276 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1278 TRACE("iface %p.\n", iface
);
1280 return d3d11_texture3d_Release(&texture
->ID3D11Texture3D_iface
);
1283 static void STDMETHODCALLTYPE
d3d10_texture3d_GetDevice(ID3D10Texture3D
*iface
, ID3D10Device
**device
)
1285 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1287 TRACE("iface %p, device %p.\n", iface
, device
);
1289 ID3D11Device2_QueryInterface(texture
->device
, &IID_ID3D10Device
, (void **)device
);
1292 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_GetPrivateData(ID3D10Texture3D
*iface
,
1293 REFGUID guid
, UINT
*data_size
, void *data
)
1295 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1297 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1298 iface
, debugstr_guid(guid
), data_size
, data
);
1300 return d3d_get_private_data(&texture
->private_store
, guid
, data_size
, data
);
1303 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_SetPrivateData(ID3D10Texture3D
*iface
,
1304 REFGUID guid
, UINT data_size
, const void *data
)
1306 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1308 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1309 iface
, debugstr_guid(guid
), data_size
, data
);
1311 return d3d_set_private_data(&texture
->private_store
, guid
, data_size
, data
);
1314 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_SetPrivateDataInterface(ID3D10Texture3D
*iface
,
1315 REFGUID guid
, const IUnknown
*data
)
1317 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1319 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1321 return d3d_set_private_data_interface(&texture
->private_store
, guid
, data
);
1324 static void STDMETHODCALLTYPE
d3d10_texture3d_GetType(ID3D10Texture3D
*iface
,
1325 D3D10_RESOURCE_DIMENSION
*resource_dimension
)
1327 TRACE("iface %p, resource_dimension %p.\n", iface
, resource_dimension
);
1329 *resource_dimension
= D3D10_RESOURCE_DIMENSION_TEXTURE3D
;
1332 static void STDMETHODCALLTYPE
d3d10_texture3d_SetEvictionPriority(ID3D10Texture3D
*iface
, UINT eviction_priority
)
1334 FIXME("iface %p, eviction_priority %u stub!\n", iface
, eviction_priority
);
1337 static UINT STDMETHODCALLTYPE
d3d10_texture3d_GetEvictionPriority(ID3D10Texture3D
*iface
)
1339 FIXME("iface %p stub!\n", iface
);
1344 static HRESULT STDMETHODCALLTYPE
d3d10_texture3d_Map(ID3D10Texture3D
*iface
, UINT sub_resource_idx
,
1345 D3D10_MAP map_type
, UINT map_flags
, D3D10_MAPPED_TEXTURE3D
*mapped_texture
)
1347 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1348 struct wined3d_map_desc wined3d_map_desc
;
1351 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n",
1352 iface
, sub_resource_idx
, map_type
, map_flags
, mapped_texture
);
1355 FIXME("Ignoring map_flags %#x.\n", map_flags
);
1357 wined3d_mutex_lock();
1358 if (SUCCEEDED(hr
= wined3d_resource_map(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
,
1359 &wined3d_map_desc
, NULL
, wined3d_map_flags_from_d3d11_map_type(map_type
))))
1361 mapped_texture
->pData
= wined3d_map_desc
.data
;
1362 mapped_texture
->RowPitch
= wined3d_map_desc
.row_pitch
;
1363 mapped_texture
->DepthPitch
= wined3d_map_desc
.slice_pitch
;
1365 wined3d_mutex_unlock();
1370 static void STDMETHODCALLTYPE
d3d10_texture3d_Unmap(ID3D10Texture3D
*iface
, UINT sub_resource_idx
)
1372 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1374 TRACE("iface %p, sub_resource_idx %u.\n", iface
, sub_resource_idx
);
1376 wined3d_mutex_lock();
1377 wined3d_resource_unmap(wined3d_texture_get_resource(texture
->wined3d_texture
), sub_resource_idx
);
1378 wined3d_mutex_unlock();
1381 static void STDMETHODCALLTYPE
d3d10_texture3d_GetDesc(ID3D10Texture3D
*iface
, D3D10_TEXTURE3D_DESC
*desc
)
1383 struct d3d_texture3d
*texture
= impl_from_ID3D10Texture3D(iface
);
1384 D3D11_TEXTURE3D_DESC d3d11_desc
;
1386 TRACE("iface %p, desc %p.\n", iface
, desc
);
1388 d3d11_texture3d_GetDesc(&texture
->ID3D11Texture3D_iface
, &d3d11_desc
);
1390 desc
->Width
= d3d11_desc
.Width
;
1391 desc
->Height
= d3d11_desc
.Height
;
1392 desc
->Depth
= d3d11_desc
.Depth
;
1393 desc
->MipLevels
= d3d11_desc
.MipLevels
;
1394 desc
->Format
= d3d11_desc
.Format
;
1395 desc
->Usage
= d3d10_usage_from_d3d11_usage(d3d11_desc
.Usage
);
1396 desc
->BindFlags
= d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc
.BindFlags
);
1397 desc
->CPUAccessFlags
= d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc
.CPUAccessFlags
);
1398 desc
->MiscFlags
= d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc
.MiscFlags
);
1401 static const struct ID3D10Texture3DVtbl d3d10_texture3d_vtbl
=
1403 /* IUnknown methods */
1404 d3d10_texture3d_QueryInterface
,
1405 d3d10_texture3d_AddRef
,
1406 d3d10_texture3d_Release
,
1407 /* ID3D10DeviceChild methods */
1408 d3d10_texture3d_GetDevice
,
1409 d3d10_texture3d_GetPrivateData
,
1410 d3d10_texture3d_SetPrivateData
,
1411 d3d10_texture3d_SetPrivateDataInterface
,
1412 /* ID3D10Resource methods */
1413 d3d10_texture3d_GetType
,
1414 d3d10_texture3d_SetEvictionPriority
,
1415 d3d10_texture3d_GetEvictionPriority
,
1416 /* ID3D10Texture3D methods */
1417 d3d10_texture3d_Map
,
1418 d3d10_texture3d_Unmap
,
1419 d3d10_texture3d_GetDesc
,
1422 struct d3d_texture3d
*unsafe_impl_from_ID3D10Texture3D(ID3D10Texture3D
*iface
)
1426 assert(iface
->lpVtbl
== &d3d10_texture3d_vtbl
);
1427 return CONTAINING_RECORD(iface
, struct d3d_texture3d
, ID3D10Texture3D_iface
);
1430 struct d3d_texture3d
*unsafe_impl_from_ID3D11Texture3D(ID3D11Texture3D
*iface
)
1434 assert(iface
->lpVtbl
== &d3d11_texture3d_vtbl
);
1435 return impl_from_ID3D11Texture3D(iface
);
1438 static const struct wined3d_parent_ops d3d_texture3d_wined3d_parent_ops
=
1440 d3d_texture3d_wined3d_object_released
,
1443 static HRESULT
d3d_texture3d_init(struct d3d_texture3d
*texture
, struct d3d_device
*device
,
1444 const D3D11_TEXTURE3D_DESC
*desc
, const D3D11_SUBRESOURCE_DATA
*data
)
1446 struct wined3d_resource_desc wined3d_desc
;
1447 unsigned int levels
;
1451 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
1452 && (~desc
->BindFlags
& (D3D11_BIND_RENDER_TARGET
| D3D11_BIND_SHADER_RESOURCE
)))
1454 WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET "
1455 "and D3D11_BIND_SHADER_RESOURCE.\n");
1456 return E_INVALIDARG
;
1459 texture
->ID3D11Texture3D_iface
.lpVtbl
= &d3d11_texture3d_vtbl
;
1460 texture
->ID3D10Texture3D_iface
.lpVtbl
= &d3d10_texture3d_vtbl
;
1461 texture
->refcount
= 1;
1462 wined3d_mutex_lock();
1463 wined3d_private_store_init(&texture
->private_store
);
1464 texture
->desc
= *desc
;
1466 wined3d_desc
.resource_type
= WINED3D_RTYPE_TEXTURE_3D
;
1467 wined3d_desc
.format
= wined3dformat_from_dxgi_format(desc
->Format
);
1468 wined3d_desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
1469 wined3d_desc
.multisample_quality
= 0;
1470 wined3d_desc
.usage
= wined3d_usage_from_d3d11(desc
->BindFlags
, desc
->Usage
);
1471 wined3d_desc
.access
= wined3d_access_from_d3d11(desc
->Usage
,
1472 desc
->Usage
== D3D11_USAGE_DEFAULT
? 0 : desc
->CPUAccessFlags
);
1473 wined3d_desc
.width
= desc
->Width
;
1474 wined3d_desc
.height
= desc
->Height
;
1475 wined3d_desc
.depth
= desc
->Depth
;
1476 wined3d_desc
.size
= 0;
1478 levels
= desc
->MipLevels
? desc
->MipLevels
: wined3d_log2i(max(max(desc
->Width
, desc
->Height
), desc
->Depth
)) + 1;
1480 if (desc
->MiscFlags
& D3D11_RESOURCE_MISC_GENERATE_MIPS
)
1481 flags
|= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
;
1483 if (FAILED(hr
= wined3d_texture_create(device
->wined3d_device
, &wined3d_desc
,
1484 1, levels
, flags
, (struct wined3d_sub_resource_data
*)data
, texture
,
1485 &d3d_texture3d_wined3d_parent_ops
, &texture
->wined3d_texture
)))
1487 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
1488 wined3d_private_store_cleanup(&texture
->private_store
);
1489 wined3d_mutex_unlock();
1490 if (hr
== WINED3DERR_INVALIDCALL
)
1494 wined3d_mutex_unlock();
1495 texture
->desc
.MipLevels
= levels
;
1497 ID3D11Device2_AddRef(texture
->device
= &device
->ID3D11Device2_iface
);
1502 HRESULT
d3d_texture3d_create(struct d3d_device
*device
, const D3D11_TEXTURE3D_DESC
*desc
,
1503 const D3D11_SUBRESOURCE_DATA
*data
, struct d3d_texture3d
**texture
)
1505 struct d3d_texture3d
*object
;
1508 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1509 return E_OUTOFMEMORY
;
1511 if (FAILED(hr
= d3d_texture3d_init(object
, device
, desc
, data
)))
1513 WARN("Failed to initialize texture, hr %#x.\n", hr
);
1518 TRACE("Created texture %p.\n", object
);