d3d11: Remove null dxgi object checks.
[wine.git] / dlls / d3d11 / texture.c
blob64e78702fd7f39b6b500a07b59299bf17aae09bd
1 /*
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
21 #include "d3d11_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
25 /* ID3D11Texture1D methods */
27 static inline struct d3d_texture1d *impl_from_ID3D11Texture1D(ID3D11Texture1D *iface)
29 return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D11Texture1D_iface);
32 static HRESULT STDMETHODCALLTYPE d3d11_texture1d_QueryInterface(ID3D11Texture1D *iface, REFIID iid, void **out)
34 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
35 HRESULT hr;
37 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
39 if (IsEqualGUID(iid, &IID_ID3D11Texture1D)
40 || IsEqualGUID(iid, &IID_ID3D11Resource)
41 || IsEqualGUID(iid, &IID_ID3D11DeviceChild)
42 || IsEqualGUID(iid, &IID_IUnknown))
44 *out = iface;
45 IUnknown_AddRef(iface);
46 return S_OK;
49 if (IsEqualGUID(iid, &IID_ID3D10Texture1D)
50 || IsEqualGUID(iid, &IID_ID3D10Resource)
51 || IsEqualGUID(iid, &IID_ID3D10DeviceChild))
53 *out = &texture->ID3D10Texture1D_iface;
54 IUnknown_AddRef((IUnknown *)*out);
55 return S_OK;
58 TRACE("Forwarding to dxgi resource.\n");
60 if (FAILED(hr = IUnknown_QueryInterface(texture->dxgi_resource, iid, out)))
62 WARN("%s not implemented, returning %#lx.\n", debugstr_guid(iid), hr);
63 *out = NULL;
66 return hr;
69 static ULONG STDMETHODCALLTYPE d3d11_texture1d_AddRef(ID3D11Texture1D *iface)
71 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
72 ULONG refcount = InterlockedIncrement(&texture->refcount);
74 TRACE("%p increasing refcount to %lu.\n", texture, refcount);
76 if (refcount == 1)
78 ID3D11Device2_AddRef(texture->device);
79 wined3d_texture_incref(texture->wined3d_texture);
82 return refcount;
85 static ULONG STDMETHODCALLTYPE d3d11_texture1d_Release(ID3D11Texture1D *iface)
87 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
88 ULONG refcount = InterlockedDecrement(&texture->refcount);
90 TRACE("%p decreasing refcount to %lu.\n", texture, refcount);
92 if (!refcount)
94 ID3D11Device2 *device = texture->device;
95 wined3d_texture_decref(texture->wined3d_texture);
96 /* Release the device last, it may cause the wined3d device to be
97 * destroyed. */
98 ID3D11Device2_Release(device);
101 return refcount;
104 static void STDMETHODCALLTYPE d3d11_texture1d_GetDevice(ID3D11Texture1D *iface, ID3D11Device **device)
106 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
108 TRACE("iface %p, device %p.\n", iface, device);
110 *device = (ID3D11Device *)texture->device;
111 ID3D11Device_AddRef(*device);
114 static HRESULT STDMETHODCALLTYPE d3d11_texture1d_GetPrivateData(ID3D11Texture1D *iface,
115 REFGUID guid, UINT *data_size, void *data)
117 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
118 IDXGIResource *dxgi_resource;
119 HRESULT hr;
121 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
123 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
125 hr = IDXGIResource_GetPrivateData(dxgi_resource, guid, data_size, data);
126 IDXGIResource_Release(dxgi_resource);
129 return hr;
132 static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateData(ID3D11Texture1D *iface,
133 REFGUID guid, UINT data_size, const void *data)
135 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
136 IDXGIResource *dxgi_resource;
137 HRESULT hr;
139 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
141 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
143 hr = IDXGIResource_SetPrivateData(dxgi_resource, guid, data_size, data);
144 IDXGIResource_Release(dxgi_resource);
147 return hr;
150 static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateDataInterface(ID3D11Texture1D *iface,
151 REFGUID guid, const IUnknown *data)
153 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
154 IDXGIResource *dxgi_resource;
155 HRESULT hr;
157 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
159 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
161 hr = IDXGIResource_SetPrivateDataInterface(dxgi_resource, guid, data);
162 IDXGIResource_Release(dxgi_resource);
165 return hr;
168 static void STDMETHODCALLTYPE d3d11_texture1d_GetType(ID3D11Texture1D *iface,
169 D3D11_RESOURCE_DIMENSION *resource_dimension)
171 TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension);
173 *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE1D;
176 static void STDMETHODCALLTYPE d3d11_texture1d_SetEvictionPriority(ID3D11Texture1D *iface, UINT eviction_priority)
178 FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority);
181 static UINT STDMETHODCALLTYPE d3d11_texture1d_GetEvictionPriority(ID3D11Texture1D *iface)
183 FIXME("iface %p stub!\n", iface);
185 return 0;
188 static void STDMETHODCALLTYPE d3d11_texture1d_GetDesc(ID3D11Texture1D *iface, D3D11_TEXTURE1D_DESC *desc)
190 struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface);
192 TRACE("iface %p, desc %p.\n", iface, desc);
194 *desc = texture->desc;
197 static const struct ID3D11Texture1DVtbl d3d11_texture1d_vtbl =
199 /* IUnknown methods */
200 d3d11_texture1d_QueryInterface,
201 d3d11_texture1d_AddRef,
202 d3d11_texture1d_Release,
203 /* ID3D11DeviceChild methods */
204 d3d11_texture1d_GetDevice,
205 d3d11_texture1d_GetPrivateData,
206 d3d11_texture1d_SetPrivateData,
207 d3d11_texture1d_SetPrivateDataInterface,
208 /* ID3D11Resource methods */
209 d3d11_texture1d_GetType,
210 d3d11_texture1d_SetEvictionPriority,
211 d3d11_texture1d_GetEvictionPriority,
212 /* ID3D11Texture1D methods */
213 d3d11_texture1d_GetDesc,
216 struct d3d_texture1d *unsafe_impl_from_ID3D11Texture1D(ID3D11Texture1D *iface)
218 if (!iface)
219 return NULL;
220 assert(iface->lpVtbl == &d3d11_texture1d_vtbl);
221 return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D11Texture1D_iface);
224 static inline struct d3d_texture1d *impl_from_ID3D10Texture1D(ID3D10Texture1D *iface)
226 return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D10Texture1D_iface);
229 /* IUnknown methods */
231 static HRESULT STDMETHODCALLTYPE d3d10_texture1d_QueryInterface(ID3D10Texture1D *iface, REFIID iid, void **out)
233 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
235 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
237 return d3d11_texture1d_QueryInterface(&texture->ID3D11Texture1D_iface, iid, out);
240 static ULONG STDMETHODCALLTYPE d3d10_texture1d_AddRef(ID3D10Texture1D *iface)
242 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
244 TRACE("iface %p.\n", iface);
246 return d3d11_texture1d_AddRef(&texture->ID3D11Texture1D_iface);
249 static void STDMETHODCALLTYPE d3d_texture1d_wined3d_object_released(void *parent)
251 struct d3d_texture1d *texture = parent;
253 if (texture->dxgi_resource)
254 IUnknown_Release(texture->dxgi_resource);
255 heap_free(texture);
258 static ULONG STDMETHODCALLTYPE d3d10_texture1d_Release(ID3D10Texture1D *iface)
260 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
262 TRACE("iface %p.\n", iface);
264 return d3d11_texture1d_Release(&texture->ID3D11Texture1D_iface);
267 /* ID3D10DeviceChild methods */
269 static void STDMETHODCALLTYPE d3d10_texture1d_GetDevice(ID3D10Texture1D *iface, ID3D10Device **device)
271 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
273 TRACE("iface %p, device %p.\n", iface, device);
275 ID3D11Device2_QueryInterface(texture->device, &IID_ID3D10Device, (void **)device);
278 static HRESULT STDMETHODCALLTYPE d3d10_texture1d_GetPrivateData(ID3D10Texture1D *iface,
279 REFGUID guid, UINT *data_size, void *data)
281 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
283 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
285 return d3d11_texture1d_GetPrivateData(&texture->ID3D11Texture1D_iface, guid, data_size, data);
288 static HRESULT STDMETHODCALLTYPE d3d10_texture1d_SetPrivateData(ID3D10Texture1D *iface,
289 REFGUID guid, UINT data_size, const void *data)
291 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
293 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
295 return d3d11_texture1d_SetPrivateData(&texture->ID3D11Texture1D_iface, guid, data_size, data);
298 static HRESULT STDMETHODCALLTYPE d3d10_texture1d_SetPrivateDataInterface(ID3D10Texture1D *iface,
299 REFGUID guid, const IUnknown *data)
301 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
303 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
305 return d3d11_texture1d_SetPrivateDataInterface(&texture->ID3D11Texture1D_iface, guid, data);
308 /* ID3D10Resource methods */
310 static void STDMETHODCALLTYPE d3d10_texture1d_GetType(ID3D10Texture1D *iface,
311 D3D10_RESOURCE_DIMENSION *resource_dimension)
313 TRACE("iface %p, resource_dimension %p\n", iface, resource_dimension);
315 *resource_dimension = D3D10_RESOURCE_DIMENSION_TEXTURE1D;
318 static void STDMETHODCALLTYPE d3d10_texture1d_SetEvictionPriority(ID3D10Texture1D *iface, UINT eviction_priority)
320 FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority);
323 static UINT STDMETHODCALLTYPE d3d10_texture1d_GetEvictionPriority(ID3D10Texture1D *iface)
325 FIXME("iface %p stub!\n", iface);
327 return 0;
330 /* ID3D10Texture1D methods */
332 static HRESULT STDMETHODCALLTYPE d3d10_texture1d_Map(ID3D10Texture1D *iface, UINT sub_resource_idx,
333 D3D10_MAP map_type, UINT map_flags, void **data)
335 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
336 struct wined3d_map_desc wined3d_map_desc;
337 HRESULT hr;
339 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, data %p.\n",
340 iface, sub_resource_idx, map_type, map_flags, data);
342 if (map_flags)
343 FIXME("Ignoring map_flags %#x.\n", map_flags);
345 if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx,
346 &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d10_map_type(map_type))))
348 *data = wined3d_map_desc.data;
351 return hr;
354 static void STDMETHODCALLTYPE d3d10_texture1d_Unmap(ID3D10Texture1D *iface, UINT sub_resource_idx)
356 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
358 TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx);
360 wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx);
363 static void STDMETHODCALLTYPE d3d10_texture1d_GetDesc(ID3D10Texture1D *iface, D3D10_TEXTURE1D_DESC *desc)
365 struct d3d_texture1d *texture = impl_from_ID3D10Texture1D(iface);
366 D3D11_TEXTURE1D_DESC d3d11_desc;
368 TRACE("iface %p, desc %p.\n", iface, desc);
370 d3d11_texture1d_GetDesc(&texture->ID3D11Texture1D_iface, &d3d11_desc);
372 desc->Width = d3d11_desc.Width;
373 desc->MipLevels = d3d11_desc.MipLevels;
374 desc->ArraySize = d3d11_desc.ArraySize;
375 desc->Format = d3d11_desc.Format;
376 desc->Usage = d3d10_usage_from_d3d11_usage(d3d11_desc.Usage);
377 desc->BindFlags = d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc.BindFlags);
378 desc->CPUAccessFlags = d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc.CPUAccessFlags);
379 desc->MiscFlags = d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc.MiscFlags);
382 static const struct ID3D10Texture1DVtbl d3d10_texture1d_vtbl =
384 /* IUnknown methods */
385 d3d10_texture1d_QueryInterface,
386 d3d10_texture1d_AddRef,
387 d3d10_texture1d_Release,
388 /* ID3D10DeviceChild methods */
389 d3d10_texture1d_GetDevice,
390 d3d10_texture1d_GetPrivateData,
391 d3d10_texture1d_SetPrivateData,
392 d3d10_texture1d_SetPrivateDataInterface,
393 /* ID3D10Resource methods */
394 d3d10_texture1d_GetType,
395 d3d10_texture1d_SetEvictionPriority,
396 d3d10_texture1d_GetEvictionPriority,
397 /* ID3D10Texture1D methods */
398 d3d10_texture1d_Map,
399 d3d10_texture1d_Unmap,
400 d3d10_texture1d_GetDesc,
403 struct d3d_texture1d *unsafe_impl_from_ID3D10Texture1D(ID3D10Texture1D *iface)
405 if (!iface)
406 return NULL;
407 assert(iface->lpVtbl == &d3d10_texture1d_vtbl);
408 return CONTAINING_RECORD(iface, struct d3d_texture1d, ID3D10Texture1D_iface);
411 static const struct wined3d_parent_ops d3d_texture1d_wined3d_parent_ops =
413 d3d_texture1d_wined3d_object_released,
416 HRESULT d3d_device_create_dxgi_resource(IUnknown *device, struct wined3d_resource *wined3d_resource,
417 IUnknown *outer, BOOL needs_surface, IUnknown **dxgi_resource)
419 IWineDXGIDevice *wine_device;
420 HRESULT hr;
422 if (FAILED(hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&wine_device)))
424 ERR("Device should implement IWineDXGIDevice.\n");
425 return E_FAIL;
428 hr = IWineDXGIDevice_create_resource(wine_device, wined3d_resource, 0, NULL, outer,
429 needs_surface, (void **)dxgi_resource);
430 IWineDXGIDevice_Release(wine_device);
431 if (FAILED(hr))
433 ERR("Failed to create DXGI resource, returning %#.lx\n", hr);
434 *dxgi_resource = NULL;
437 return hr;
440 HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DESC *desc,
441 const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture1d **out)
443 struct wined3d_resource_desc wined3d_desc;
444 struct d3d_texture1d *texture;
445 unsigned int levels;
446 BOOL needs_surface;
447 DWORD flags = 0;
448 HRESULT hr;
450 if (!(texture = heap_alloc_zero(sizeof(*texture))))
451 return E_OUTOFMEMORY;
453 texture->ID3D11Texture1D_iface.lpVtbl = &d3d11_texture1d_vtbl;
454 texture->ID3D10Texture1D_iface.lpVtbl = &d3d10_texture1d_vtbl;
455 texture->refcount = 1;
456 texture->desc = *desc;
457 levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(desc->Width) + 1;
458 texture->desc.MipLevels = levels;
460 wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_1D;
461 wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format);
462 wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
463 wined3d_desc.multisample_quality = 0;
464 wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage);
465 wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags, desc->MiscFlags);
466 wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage,
467 desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags);
468 wined3d_desc.width = desc->Width;
469 wined3d_desc.height = 1;
470 wined3d_desc.depth = 1;
471 wined3d_desc.size = 0;
473 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
474 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
475 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
476 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
478 wined3d_mutex_lock();
479 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc,
480 desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data,
481 texture, &d3d_texture1d_wined3d_parent_ops, &texture->wined3d_texture)))
483 WARN("Failed to create wined3d texture, hr %#lx.\n", hr);
484 heap_free(texture);
485 wined3d_mutex_unlock();
486 if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL)
487 hr = E_INVALIDARG;
488 return hr;
491 needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1;
492 hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface,
493 wined3d_texture_get_resource(texture->wined3d_texture), (IUnknown *)&texture->ID3D10Texture1D_iface,
494 needs_surface, &texture->dxgi_resource);
495 if (FAILED(hr))
497 ERR("Failed to create DXGI resource, returning %#.lx\n", hr);
498 wined3d_texture_decref(texture->wined3d_texture);
499 wined3d_mutex_unlock();
500 return hr;
502 wined3d_mutex_unlock();
504 ID3D11Device2_AddRef(texture->device = &device->ID3D11Device2_iface);
506 TRACE("Created texture %p.\n", texture);
507 *out = texture;
509 return S_OK;
512 /* ID3D11Texture2D methods */
514 static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(ID3D11Texture2D *iface, REFIID riid, void **object)
516 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
517 HRESULT hr;
519 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
521 if (IsEqualGUID(riid, &IID_ID3D11Texture2D)
522 || IsEqualGUID(riid, &IID_ID3D11Resource)
523 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
524 || IsEqualGUID(riid, &IID_IUnknown))
526 *object = &texture->ID3D11Texture2D_iface;
527 IUnknown_AddRef((IUnknown *)*object);
528 return S_OK;
530 else if (IsEqualGUID(riid, &IID_ID3D10Texture2D)
531 || IsEqualGUID(riid, &IID_ID3D10Resource)
532 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
534 *object = &texture->ID3D10Texture2D_iface;
535 IUnknown_AddRef((IUnknown *)*object);
536 return S_OK;
539 TRACE("Forwarding to dxgi resource.\n");
541 if (FAILED(hr = IUnknown_QueryInterface(texture->dxgi_resource, riid, object)))
543 WARN("%s not implemented, returning %#lx.\n", debugstr_guid(riid), hr);
544 *object = NULL;
547 return hr;
550 static ULONG STDMETHODCALLTYPE d3d11_texture2d_AddRef(ID3D11Texture2D *iface)
552 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
553 ULONG refcount = InterlockedIncrement(&texture->refcount);
555 TRACE("%p increasing refcount to %lu.\n", texture, refcount);
557 if (refcount == 1)
559 ID3D11Device2_AddRef(texture->device);
560 wined3d_texture_incref(texture->wined3d_texture);
563 return refcount;
566 static ULONG STDMETHODCALLTYPE d3d11_texture2d_Release(ID3D11Texture2D *iface)
568 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
569 ULONG refcount = InterlockedDecrement(&texture->refcount);
571 TRACE("%p decreasing refcount to %lu.\n", texture, refcount);
573 if (!refcount)
575 ID3D11Device2 *device = texture->device;
576 wined3d_texture_decref(texture->wined3d_texture);
577 /* Release the device last, it may cause the wined3d device to be
578 * destroyed. */
579 ID3D11Device2_Release(device);
582 return refcount;
585 static void STDMETHODCALLTYPE d3d11_texture2d_GetDevice(ID3D11Texture2D *iface, ID3D11Device **device)
587 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
589 TRACE("iface %p, device %p.\n", iface, device);
591 *device = (ID3D11Device *)texture->device;
592 ID3D11Device_AddRef(*device);
595 static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(ID3D11Texture2D *iface,
596 REFGUID guid, UINT *data_size, void *data)
598 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
599 IDXGIResource *dxgi_resource;
600 HRESULT hr;
602 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
604 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
606 hr = IDXGIResource_GetPrivateData(dxgi_resource, guid, data_size, data);
607 IDXGIResource_Release(dxgi_resource);
610 return hr;
613 static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(ID3D11Texture2D *iface,
614 REFGUID guid, UINT data_size, const void *data)
616 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
617 IDXGIResource *dxgi_resource;
618 HRESULT hr;
620 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
622 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
624 hr = IDXGIResource_SetPrivateData(dxgi_resource, guid, data_size, data);
625 IDXGIResource_Release(dxgi_resource);
628 return hr;
631 static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(ID3D11Texture2D *iface,
632 REFGUID guid, const IUnknown *data)
634 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
635 IDXGIResource *dxgi_resource;
636 HRESULT hr;
638 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
640 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
642 hr = IDXGIResource_SetPrivateDataInterface(dxgi_resource, guid, data);
643 IDXGIResource_Release(dxgi_resource);
646 return hr;
649 static void STDMETHODCALLTYPE d3d11_texture2d_GetType(ID3D11Texture2D *iface,
650 D3D11_RESOURCE_DIMENSION *resource_dimension)
652 TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension);
654 *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D;
657 static void STDMETHODCALLTYPE d3d11_texture2d_SetEvictionPriority(ID3D11Texture2D *iface, UINT eviction_priority)
659 FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority);
662 static UINT STDMETHODCALLTYPE d3d11_texture2d_GetEvictionPriority(ID3D11Texture2D *iface)
664 FIXME("iface %p stub!\n", iface);
666 return 0;
669 static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(ID3D11Texture2D *iface, D3D11_TEXTURE2D_DESC *desc)
671 struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
672 struct wined3d_resource_desc wined3d_desc;
674 TRACE("iface %p, desc %p.\n", iface, desc);
676 *desc = texture->desc;
678 wined3d_mutex_lock();
679 wined3d_resource_get_desc(wined3d_texture_get_resource(texture->wined3d_texture), &wined3d_desc);
680 wined3d_mutex_unlock();
682 /* FIXME: Resizing swapchain buffers can cause these to change. We'd like
683 * to get everything from wined3d, but e.g. bind flags don't exist as such
684 * there (yet). */
685 desc->Width = wined3d_desc.width;
686 desc->Height = wined3d_desc.height;
687 desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.format);
688 desc->SampleDesc.Count = wined3d_desc.multisample_type == WINED3D_MULTISAMPLE_NONE
689 ? 1 : wined3d_desc.multisample_type;
690 desc->SampleDesc.Quality = wined3d_desc.multisample_quality;
693 static const struct ID3D11Texture2DVtbl d3d11_texture2d_vtbl =
695 /* IUnknown methods */
696 d3d11_texture2d_QueryInterface,
697 d3d11_texture2d_AddRef,
698 d3d11_texture2d_Release,
699 /* ID3D11DeviceChild methods */
700 d3d11_texture2d_GetDevice,
701 d3d11_texture2d_GetPrivateData,
702 d3d11_texture2d_SetPrivateData,
703 d3d11_texture2d_SetPrivateDataInterface,
704 /* ID3D11Resource methods */
705 d3d11_texture2d_GetType,
706 d3d11_texture2d_SetEvictionPriority,
707 d3d11_texture2d_GetEvictionPriority,
708 /* ID3D11Texture2D methods */
709 d3d11_texture2d_GetDesc,
712 struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface)
714 if (!iface)
715 return NULL;
716 assert(iface->lpVtbl == &d3d11_texture2d_vtbl);
717 return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D11Texture2D_iface);
720 /* IUnknown methods */
722 static inline struct d3d_texture2d *impl_from_ID3D10Texture2D(ID3D10Texture2D *iface)
724 return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D10Texture2D_iface);
727 static HRESULT STDMETHODCALLTYPE d3d10_texture2d_QueryInterface(ID3D10Texture2D *iface, REFIID riid, void **object)
729 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
731 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
733 return d3d11_texture2d_QueryInterface(&texture->ID3D11Texture2D_iface, riid, object);
736 static ULONG STDMETHODCALLTYPE d3d10_texture2d_AddRef(ID3D10Texture2D *iface)
738 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
740 TRACE("iface %p.\n", iface);
742 return d3d11_texture2d_AddRef(&texture->ID3D11Texture2D_iface);
745 static void STDMETHODCALLTYPE d3d_texture2d_wined3d_object_released(void *parent)
747 struct d3d_texture2d *texture = parent;
749 if (texture->dxgi_resource) IUnknown_Release(texture->dxgi_resource);
750 heap_free(texture);
753 static ULONG STDMETHODCALLTYPE d3d10_texture2d_Release(ID3D10Texture2D *iface)
755 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
757 TRACE("iface %p.\n", iface);
759 return d3d11_texture2d_Release(&texture->ID3D11Texture2D_iface);
762 /* ID3D10DeviceChild methods */
764 static void STDMETHODCALLTYPE d3d10_texture2d_GetDevice(ID3D10Texture2D *iface, ID3D10Device **device)
766 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
768 TRACE("iface %p, device %p.\n", iface, device);
770 ID3D11Device2_QueryInterface(texture->device, &IID_ID3D10Device, (void **)device);
773 static HRESULT STDMETHODCALLTYPE d3d10_texture2d_GetPrivateData(ID3D10Texture2D *iface,
774 REFGUID guid, UINT *data_size, void *data)
776 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
778 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
780 return d3d11_texture2d_GetPrivateData(&texture->ID3D11Texture2D_iface, guid, data_size, data);
783 static HRESULT STDMETHODCALLTYPE d3d10_texture2d_SetPrivateData(ID3D10Texture2D *iface,
784 REFGUID guid, UINT data_size, const void *data)
786 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
788 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
790 return d3d11_texture2d_SetPrivateData(&texture->ID3D11Texture2D_iface, guid, data_size, data);
793 static HRESULT STDMETHODCALLTYPE d3d10_texture2d_SetPrivateDataInterface(ID3D10Texture2D *iface,
794 REFGUID guid, const IUnknown *data)
796 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
798 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
800 return d3d11_texture2d_SetPrivateDataInterface(&texture->ID3D11Texture2D_iface, guid, data);
803 /* ID3D10Resource methods */
805 static void STDMETHODCALLTYPE d3d10_texture2d_GetType(ID3D10Texture2D *iface,
806 D3D10_RESOURCE_DIMENSION *resource_dimension)
808 TRACE("iface %p, resource_dimension %p\n", iface, resource_dimension);
810 *resource_dimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
813 static void STDMETHODCALLTYPE d3d10_texture2d_SetEvictionPriority(ID3D10Texture2D *iface, UINT eviction_priority)
815 FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority);
818 static UINT STDMETHODCALLTYPE d3d10_texture2d_GetEvictionPriority(ID3D10Texture2D *iface)
820 FIXME("iface %p stub!\n", iface);
822 return 0;
825 /* ID3D10Texture2D methods */
827 static HRESULT STDMETHODCALLTYPE d3d10_texture2d_Map(ID3D10Texture2D *iface, UINT sub_resource_idx,
828 D3D10_MAP map_type, UINT map_flags, D3D10_MAPPED_TEXTURE2D *mapped_texture)
830 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
831 struct wined3d_map_desc wined3d_map_desc;
832 HRESULT hr;
834 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n",
835 iface, sub_resource_idx, map_type, map_flags, mapped_texture);
837 if (map_flags)
838 FIXME("Ignoring map_flags %#x.\n", map_flags);
840 if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx,
841 &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d10_map_type(map_type))))
843 mapped_texture->pData = wined3d_map_desc.data;
844 mapped_texture->RowPitch = wined3d_map_desc.row_pitch;
847 return hr;
850 static void STDMETHODCALLTYPE d3d10_texture2d_Unmap(ID3D10Texture2D *iface, UINT sub_resource_idx)
852 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
854 TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx);
856 wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx);
859 static void STDMETHODCALLTYPE d3d10_texture2d_GetDesc(ID3D10Texture2D *iface, D3D10_TEXTURE2D_DESC *desc)
861 struct d3d_texture2d *texture = impl_from_ID3D10Texture2D(iface);
862 D3D11_TEXTURE2D_DESC d3d11_desc;
864 TRACE("iface %p, desc %p\n", iface, desc);
866 d3d11_texture2d_GetDesc(&texture->ID3D11Texture2D_iface, &d3d11_desc);
868 desc->Width = d3d11_desc.Width;
869 desc->Height = d3d11_desc.Height;
870 desc->MipLevels = d3d11_desc.MipLevels;
871 desc->ArraySize = d3d11_desc.ArraySize;
872 desc->Format = d3d11_desc.Format;
873 desc->SampleDesc = d3d11_desc.SampleDesc;
874 desc->Usage = d3d10_usage_from_d3d11_usage(d3d11_desc.Usage);
875 desc->BindFlags = d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc.BindFlags);
876 desc->CPUAccessFlags = d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc.CPUAccessFlags);
877 desc->MiscFlags = d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc.MiscFlags);
880 static const struct ID3D10Texture2DVtbl d3d10_texture2d_vtbl =
882 /* IUnknown methods */
883 d3d10_texture2d_QueryInterface,
884 d3d10_texture2d_AddRef,
885 d3d10_texture2d_Release,
886 /* ID3D10DeviceChild methods */
887 d3d10_texture2d_GetDevice,
888 d3d10_texture2d_GetPrivateData,
889 d3d10_texture2d_SetPrivateData,
890 d3d10_texture2d_SetPrivateDataInterface,
891 /* ID3D10Resource methods */
892 d3d10_texture2d_GetType,
893 d3d10_texture2d_SetEvictionPriority,
894 d3d10_texture2d_GetEvictionPriority,
895 /* ID3D10Texture2D methods */
896 d3d10_texture2d_Map,
897 d3d10_texture2d_Unmap,
898 d3d10_texture2d_GetDesc,
901 struct d3d_texture2d *unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D *iface)
903 if (!iface)
904 return NULL;
905 assert(iface->lpVtbl == &d3d10_texture2d_vtbl);
906 return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D10Texture2D_iface);
909 static const struct wined3d_parent_ops d3d_texture2d_wined3d_parent_ops =
911 d3d_texture2d_wined3d_object_released,
914 static BOOL is_gdi_compatible_texture(const D3D11_TEXTURE2D_DESC *desc)
916 if (!(desc->Format == DXGI_FORMAT_B8G8R8A8_UNORM
917 || desc->Format == DXGI_FORMAT_B8G8R8A8_TYPELESS
918 || desc->Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB))
919 return FALSE;
921 if (desc->Usage != D3D11_USAGE_DEFAULT)
922 return FALSE;
924 return TRUE;
927 static BOOL validate_texture2d_desc(const D3D11_TEXTURE2D_DESC *desc, D3D_FEATURE_LEVEL feature_level)
929 if (!validate_d3d11_resource_access_flags(D3D11_RESOURCE_DIMENSION_TEXTURE2D,
930 desc->Usage, desc->BindFlags, desc->CPUAccessFlags, feature_level))
931 return FALSE;
933 if (desc->MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE
934 && desc->ArraySize < 6)
936 WARN("Invalid array size %u for cube texture.\n", desc->ArraySize);
937 return FALSE;
940 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE
941 && !is_gdi_compatible_texture(desc))
943 WARN("Incompatible description used to create GDI compatible texture.\n");
944 return FALSE;
947 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS
948 && (~desc->BindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)))
950 WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET and "
951 "D3D11_BIND_SHADER_RESOURCE.\n");
952 return FALSE;
955 return TRUE;
958 HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc,
959 const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out)
961 struct wined3d_resource_desc wined3d_desc;
962 struct d3d_texture2d *texture;
963 unsigned int levels;
964 BOOL needs_surface;
965 DWORD flags = 0;
966 HRESULT hr;
968 if (!validate_texture2d_desc(desc, device->state->feature_level))
970 WARN("Failed to validate texture desc.\n");
971 return E_INVALIDARG;
974 if (!(texture = heap_alloc_zero(sizeof(*texture))))
975 return E_OUTOFMEMORY;
977 texture->ID3D11Texture2D_iface.lpVtbl = &d3d11_texture2d_vtbl;
978 texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl;
979 texture->refcount = 1;
980 wined3d_mutex_lock();
981 texture->desc = *desc;
983 wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
984 wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format);
985 wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE;
986 wined3d_desc.multisample_quality = desc->SampleDesc.Quality;
987 wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage);
988 wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags, desc->MiscFlags);
989 wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage,
990 desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags);
991 wined3d_desc.width = desc->Width;
992 wined3d_desc.height = desc->Height;
993 wined3d_desc.depth = 1;
994 wined3d_desc.size = 0;
996 levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1;
998 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
999 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1000 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
1001 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1003 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc,
1004 desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data,
1005 texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture)))
1007 WARN("Failed to create wined3d texture, hr %#lx.\n", hr);
1008 heap_free(texture);
1009 wined3d_mutex_unlock();
1010 if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL)
1011 hr = E_INVALIDARG;
1012 return hr;
1014 texture->desc.MipLevels = levels;
1016 needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1;
1017 hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface,
1018 wined3d_texture_get_resource(texture->wined3d_texture), (IUnknown *)&texture->ID3D10Texture2D_iface,
1019 needs_surface, &texture->dxgi_resource);
1020 if (FAILED(hr))
1022 ERR("Failed to create DXGI resource, returning %#.lx\n", hr);
1023 wined3d_texture_decref(texture->wined3d_texture);
1024 wined3d_mutex_unlock();
1025 return hr;
1027 wined3d_mutex_unlock();
1029 ID3D11Device2_AddRef(texture->device = &device->ID3D11Device2_iface);
1031 TRACE("Created texture %p.\n", texture);
1032 *out = texture;
1034 return S_OK;
1037 /* ID3D11Texture3D methods */
1039 static inline struct d3d_texture3d *impl_from_ID3D11Texture3D(ID3D11Texture3D *iface)
1041 return CONTAINING_RECORD(iface, struct d3d_texture3d, ID3D11Texture3D_iface);
1044 static HRESULT STDMETHODCALLTYPE d3d11_texture3d_QueryInterface(ID3D11Texture3D *iface, REFIID riid, void **object)
1046 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1047 HRESULT hr;
1049 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1051 if (IsEqualGUID(riid, &IID_ID3D11Texture3D)
1052 || IsEqualGUID(riid, &IID_ID3D11Resource)
1053 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1054 || IsEqualGUID(riid, &IID_IUnknown))
1056 IUnknown_AddRef(iface);
1057 *object = iface;
1058 return S_OK;
1060 else if (IsEqualGUID(riid, &IID_ID3D10Texture3D)
1061 || IsEqualGUID(riid, &IID_ID3D10Resource)
1062 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1064 IUnknown_AddRef(iface);
1065 *object = &texture->ID3D10Texture3D_iface;
1066 return S_OK;
1069 TRACE("Forwarding to dxgi resource.\n");
1071 if (FAILED(hr = IUnknown_QueryInterface(texture->dxgi_resource, riid, object)))
1073 WARN("%s not implemented, returning %#lx.\n", debugstr_guid(riid), hr);
1074 *object = NULL;
1077 return hr;
1080 static ULONG STDMETHODCALLTYPE d3d11_texture3d_AddRef(ID3D11Texture3D *iface)
1082 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1083 ULONG refcount = InterlockedIncrement(&texture->refcount);
1085 TRACE("%p increasing refcount to %lu.\n", texture, refcount);
1087 if (refcount == 1)
1089 ID3D11Device2_AddRef(texture->device);
1090 wined3d_texture_incref(texture->wined3d_texture);
1093 return refcount;
1096 static void STDMETHODCALLTYPE d3d_texture3d_wined3d_object_released(void *parent)
1098 struct d3d_texture3d *texture = parent;
1100 if (texture->dxgi_resource)
1101 IUnknown_Release(texture->dxgi_resource);
1102 heap_free(parent);
1105 static ULONG STDMETHODCALLTYPE d3d11_texture3d_Release(ID3D11Texture3D *iface)
1107 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1108 ULONG refcount = InterlockedDecrement(&texture->refcount);
1110 TRACE("%p decreasing refcount to %lu.\n", texture, refcount);
1112 if (!refcount)
1114 ID3D11Device2 *device = texture->device;
1116 wined3d_texture_decref(texture->wined3d_texture);
1117 /* Release the device last, it may cause the wined3d device to be
1118 * destroyed. */
1119 ID3D11Device2_Release(device);
1122 return refcount;
1125 static void STDMETHODCALLTYPE d3d11_texture3d_GetDevice(ID3D11Texture3D *iface, ID3D11Device **device)
1127 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1129 TRACE("iface %p, device %p.\n", iface, device);
1131 *device = (ID3D11Device *)texture->device;
1132 ID3D11Device_AddRef(*device);
1135 static HRESULT STDMETHODCALLTYPE d3d11_texture3d_GetPrivateData(ID3D11Texture3D *iface,
1136 REFGUID guid, UINT *data_size, void *data)
1138 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1139 IDXGIResource *dxgi_resource;
1140 HRESULT hr;
1142 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1144 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
1146 hr = IDXGIResource_GetPrivateData(dxgi_resource, guid, data_size, data);
1147 IDXGIResource_Release(dxgi_resource);
1150 return hr;
1153 static HRESULT STDMETHODCALLTYPE d3d11_texture3d_SetPrivateData(ID3D11Texture3D *iface,
1154 REFGUID guid, UINT data_size, const void *data)
1156 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1157 IDXGIResource *dxgi_resource;
1158 HRESULT hr;
1160 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1162 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
1164 hr = IDXGIResource_SetPrivateData(dxgi_resource, guid, data_size, data);
1165 IDXGIResource_Release(dxgi_resource);
1168 return hr;
1171 static HRESULT STDMETHODCALLTYPE d3d11_texture3d_SetPrivateDataInterface(ID3D11Texture3D *iface,
1172 REFGUID guid, const IUnknown *data)
1174 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1175 IDXGIResource *dxgi_resource;
1176 HRESULT hr;
1178 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1180 if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource)))
1182 hr = IDXGIResource_SetPrivateDataInterface(dxgi_resource, guid, data);
1183 IDXGIResource_Release(dxgi_resource);
1186 return hr;
1189 static void STDMETHODCALLTYPE d3d11_texture3d_GetType(ID3D11Texture3D *iface,
1190 D3D11_RESOURCE_DIMENSION *resource_dimension)
1192 TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension);
1194 *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE3D;
1197 static void STDMETHODCALLTYPE d3d11_texture3d_SetEvictionPriority(ID3D11Texture3D *iface, UINT eviction_priority)
1199 FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority);
1202 static UINT STDMETHODCALLTYPE d3d11_texture3d_GetEvictionPriority(ID3D11Texture3D *iface)
1204 FIXME("iface %p stub!\n", iface);
1206 return 0;
1209 static void STDMETHODCALLTYPE d3d11_texture3d_GetDesc(ID3D11Texture3D *iface, D3D11_TEXTURE3D_DESC *desc)
1211 struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface);
1213 TRACE("iface %p, desc %p.\n", iface, desc);
1215 *desc = texture->desc;
1218 static const struct ID3D11Texture3DVtbl d3d11_texture3d_vtbl =
1220 /* IUnknown methods */
1221 d3d11_texture3d_QueryInterface,
1222 d3d11_texture3d_AddRef,
1223 d3d11_texture3d_Release,
1224 /* ID3D11DeviceChild methods */
1225 d3d11_texture3d_GetDevice,
1226 d3d11_texture3d_GetPrivateData,
1227 d3d11_texture3d_SetPrivateData,
1228 d3d11_texture3d_SetPrivateDataInterface,
1229 /* ID3D11Resource methods */
1230 d3d11_texture3d_GetType,
1231 d3d11_texture3d_SetEvictionPriority,
1232 d3d11_texture3d_GetEvictionPriority,
1233 /* ID3D11Texture3D methods */
1234 d3d11_texture3d_GetDesc,
1237 /* ID3D10Texture3D methods */
1239 static inline struct d3d_texture3d *impl_from_ID3D10Texture3D(ID3D10Texture3D *iface)
1241 return CONTAINING_RECORD(iface, struct d3d_texture3d, ID3D10Texture3D_iface);
1244 static HRESULT STDMETHODCALLTYPE d3d10_texture3d_QueryInterface(ID3D10Texture3D *iface, REFIID riid, void **object)
1246 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1248 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1250 return d3d11_texture3d_QueryInterface(&texture->ID3D11Texture3D_iface, riid, object);
1253 static ULONG STDMETHODCALLTYPE d3d10_texture3d_AddRef(ID3D10Texture3D *iface)
1255 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1257 TRACE("iface %p.\n", iface);
1259 return d3d11_texture3d_AddRef(&texture->ID3D11Texture3D_iface);
1262 static ULONG STDMETHODCALLTYPE d3d10_texture3d_Release(ID3D10Texture3D *iface)
1264 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1266 TRACE("iface %p.\n", iface);
1268 return d3d11_texture3d_Release(&texture->ID3D11Texture3D_iface);
1271 static void STDMETHODCALLTYPE d3d10_texture3d_GetDevice(ID3D10Texture3D *iface, ID3D10Device **device)
1273 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1275 TRACE("iface %p, device %p.\n", iface, device);
1277 ID3D11Device2_QueryInterface(texture->device, &IID_ID3D10Device, (void **)device);
1280 static HRESULT STDMETHODCALLTYPE d3d10_texture3d_GetPrivateData(ID3D10Texture3D *iface,
1281 REFGUID guid, UINT *data_size, void *data)
1283 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1285 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1287 return d3d11_texture3d_GetPrivateData(&texture->ID3D11Texture3D_iface, guid, data_size, data);
1290 static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateData(ID3D10Texture3D *iface,
1291 REFGUID guid, UINT data_size, const void *data)
1293 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1295 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1297 return d3d11_texture3d_SetPrivateData(&texture->ID3D11Texture3D_iface, guid, data_size, data);
1300 static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateDataInterface(ID3D10Texture3D *iface,
1301 REFGUID guid, const IUnknown *data)
1303 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1305 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1307 return d3d11_texture3d_SetPrivateDataInterface(&texture->ID3D11Texture3D_iface, guid, data);
1310 static void STDMETHODCALLTYPE d3d10_texture3d_GetType(ID3D10Texture3D *iface,
1311 D3D10_RESOURCE_DIMENSION *resource_dimension)
1313 TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension);
1315 *resource_dimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
1318 static void STDMETHODCALLTYPE d3d10_texture3d_SetEvictionPriority(ID3D10Texture3D *iface, UINT eviction_priority)
1320 FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority);
1323 static UINT STDMETHODCALLTYPE d3d10_texture3d_GetEvictionPriority(ID3D10Texture3D *iface)
1325 FIXME("iface %p stub!\n", iface);
1327 return 0;
1330 static HRESULT STDMETHODCALLTYPE d3d10_texture3d_Map(ID3D10Texture3D *iface, UINT sub_resource_idx,
1331 D3D10_MAP map_type, UINT map_flags, D3D10_MAPPED_TEXTURE3D *mapped_texture)
1333 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1334 struct wined3d_map_desc wined3d_map_desc;
1335 HRESULT hr;
1337 TRACE("iface %p, sub_resource_idx %u, map_type %u, map_flags %#x, mapped_texture %p.\n",
1338 iface, sub_resource_idx, map_type, map_flags, mapped_texture);
1340 if (map_flags)
1341 FIXME("Ignoring map_flags %#x.\n", map_flags);
1343 if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx,
1344 &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d10_map_type(map_type))))
1346 mapped_texture->pData = wined3d_map_desc.data;
1347 mapped_texture->RowPitch = wined3d_map_desc.row_pitch;
1348 mapped_texture->DepthPitch = wined3d_map_desc.slice_pitch;
1351 return hr;
1354 static void STDMETHODCALLTYPE d3d10_texture3d_Unmap(ID3D10Texture3D *iface, UINT sub_resource_idx)
1356 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1358 TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx);
1360 wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx);
1363 static void STDMETHODCALLTYPE d3d10_texture3d_GetDesc(ID3D10Texture3D *iface, D3D10_TEXTURE3D_DESC *desc)
1365 struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
1366 D3D11_TEXTURE3D_DESC d3d11_desc;
1368 TRACE("iface %p, desc %p.\n", iface, desc);
1370 d3d11_texture3d_GetDesc(&texture->ID3D11Texture3D_iface, &d3d11_desc);
1372 desc->Width = d3d11_desc.Width;
1373 desc->Height = d3d11_desc.Height;
1374 desc->Depth = d3d11_desc.Depth;
1375 desc->MipLevels = d3d11_desc.MipLevels;
1376 desc->Format = d3d11_desc.Format;
1377 desc->Usage = d3d10_usage_from_d3d11_usage(d3d11_desc.Usage);
1378 desc->BindFlags = d3d10_bind_flags_from_d3d11_bind_flags(d3d11_desc.BindFlags);
1379 desc->CPUAccessFlags = d3d10_cpu_access_flags_from_d3d11_cpu_access_flags(d3d11_desc.CPUAccessFlags);
1380 desc->MiscFlags = d3d10_resource_misc_flags_from_d3d11_resource_misc_flags(d3d11_desc.MiscFlags);
1383 static const struct ID3D10Texture3DVtbl d3d10_texture3d_vtbl =
1385 /* IUnknown methods */
1386 d3d10_texture3d_QueryInterface,
1387 d3d10_texture3d_AddRef,
1388 d3d10_texture3d_Release,
1389 /* ID3D10DeviceChild methods */
1390 d3d10_texture3d_GetDevice,
1391 d3d10_texture3d_GetPrivateData,
1392 d3d10_texture3d_SetPrivateData,
1393 d3d10_texture3d_SetPrivateDataInterface,
1394 /* ID3D10Resource methods */
1395 d3d10_texture3d_GetType,
1396 d3d10_texture3d_SetEvictionPriority,
1397 d3d10_texture3d_GetEvictionPriority,
1398 /* ID3D10Texture3D methods */
1399 d3d10_texture3d_Map,
1400 d3d10_texture3d_Unmap,
1401 d3d10_texture3d_GetDesc,
1404 struct d3d_texture3d *unsafe_impl_from_ID3D10Texture3D(ID3D10Texture3D *iface)
1406 if (!iface)
1407 return NULL;
1408 assert(iface->lpVtbl == &d3d10_texture3d_vtbl);
1409 return CONTAINING_RECORD(iface, struct d3d_texture3d, ID3D10Texture3D_iface);
1412 struct d3d_texture3d *unsafe_impl_from_ID3D11Texture3D(ID3D11Texture3D *iface)
1414 if (!iface)
1415 return NULL;
1416 assert(iface->lpVtbl == &d3d11_texture3d_vtbl);
1417 return impl_from_ID3D11Texture3D(iface);
1420 static const struct wined3d_parent_ops d3d_texture3d_wined3d_parent_ops =
1422 d3d_texture3d_wined3d_object_released,
1425 static HRESULT d3d_texture3d_init(struct d3d_texture3d *texture, struct d3d_device *device,
1426 const D3D11_TEXTURE3D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data)
1428 struct wined3d_resource_desc wined3d_desc;
1429 unsigned int levels;
1430 DWORD flags = 0;
1431 HRESULT hr;
1433 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS
1434 && (~desc->BindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)))
1436 WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET "
1437 "and D3D11_BIND_SHADER_RESOURCE.\n");
1438 return E_INVALIDARG;
1441 texture->ID3D11Texture3D_iface.lpVtbl = &d3d11_texture3d_vtbl;
1442 texture->ID3D10Texture3D_iface.lpVtbl = &d3d10_texture3d_vtbl;
1443 texture->refcount = 1;
1444 wined3d_mutex_lock();
1445 texture->desc = *desc;
1447 wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
1448 wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format);
1449 wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1450 wined3d_desc.multisample_quality = 0;
1451 wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage);
1452 wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags, desc->MiscFlags);
1453 wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage,
1454 desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags);
1455 wined3d_desc.width = desc->Width;
1456 wined3d_desc.height = desc->Height;
1457 wined3d_desc.depth = desc->Depth;
1458 wined3d_desc.size = 0;
1460 levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(max(desc->Width, desc->Height), desc->Depth)) + 1;
1462 if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
1463 flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
1465 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc,
1466 1, levels, flags, (struct wined3d_sub_resource_data *)data, texture,
1467 &d3d_texture3d_wined3d_parent_ops, &texture->wined3d_texture)))
1469 WARN("Failed to create wined3d texture, hr %#lx.\n", hr);
1470 wined3d_mutex_unlock();
1471 if (hr == WINED3DERR_INVALIDCALL)
1472 hr = E_INVALIDARG;
1473 return hr;
1476 hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface,
1477 wined3d_texture_get_resource(texture->wined3d_texture), (IUnknown *)&texture->ID3D10Texture3D_iface,
1478 FALSE, &texture->dxgi_resource);
1479 if (FAILED(hr))
1481 ERR("Failed to create DXGI resource, returning %#.lx\n", hr);
1482 wined3d_texture_decref(texture->wined3d_texture);
1483 wined3d_mutex_unlock();
1484 return hr;
1486 wined3d_mutex_unlock();
1487 texture->desc.MipLevels = levels;
1489 ID3D11Device2_AddRef(texture->device = &device->ID3D11Device2_iface);
1491 return S_OK;
1494 HRESULT d3d_texture3d_create(struct d3d_device *device, const D3D11_TEXTURE3D_DESC *desc,
1495 const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture3d **texture)
1497 struct d3d_texture3d *object;
1498 HRESULT hr;
1500 if (!(object = heap_alloc_zero(sizeof(*object))))
1501 return E_OUTOFMEMORY;
1503 if (FAILED(hr = d3d_texture3d_init(object, device, desc, data)))
1505 WARN("Failed to initialise texture, hr %#lx.\n", hr);
1506 heap_free(object);
1507 return hr;
1510 TRACE("Created texture %p.\n", object);
1511 *texture = object;
1513 return S_OK;