winmm: Avoid explicitly casting the pointer returned from Heap(Re)Alloc.
[wine.git] / dlls / d3d11 / view.c
blob228bed0ed661883998cf9754ead25fd7968b1641
1 /*
2 * Copyright 2009 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define NONAMELESSUNION
21 #define WINE_NO_NAMELESS_EXTENSION
22 #include "d3d11_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
26 static HRESULT get_resource_properties(ID3D11Resource *resource, D3D11_RESOURCE_DIMENSION *dimension,
27 DXGI_FORMAT *format, unsigned int *miplevel_count, unsigned int *layer_count)
29 ID3D11Resource_GetType(resource, dimension);
30 switch (*dimension)
32 case D3D11_RESOURCE_DIMENSION_BUFFER:
33 return S_OK;
35 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
37 const struct d3d_texture1d *texture;
39 if (!(texture = unsafe_impl_from_ID3D11Texture1D((ID3D11Texture1D *)resource)))
41 ERR("Cannot get implementation from ID3D11Texture1D.\n");
42 return E_FAIL;
45 *format = texture->desc.Format;
46 if (miplevel_count)
47 *miplevel_count = texture->desc.MipLevels;
48 *layer_count = texture->desc.ArraySize;
49 break;
52 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
54 const struct d3d_texture2d *texture;
56 if (!(texture = unsafe_impl_from_ID3D11Texture2D((ID3D11Texture2D *)resource)))
58 ERR("Cannot get implementation from ID3D11Texture2D.\n");
59 return E_FAIL;
62 *format = texture->desc.Format;
63 if (miplevel_count)
64 *miplevel_count = texture->desc.MipLevels;
65 *layer_count = texture->desc.ArraySize;
66 break;
69 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
71 const struct d3d_texture3d *texture;
73 if (!(texture = unsafe_impl_from_ID3D11Texture3D((ID3D11Texture3D *)resource)))
75 ERR("Cannot get implementation from ID3D11Texture3D.\n");
76 return E_FAIL;
79 *format = texture->desc.Format;
80 if (miplevel_count)
81 *miplevel_count = texture->desc.MipLevels;
82 *layer_count = texture->desc.Depth;
83 break;
86 default:
87 WARN("Invalid resource dimension %#x.\n", *dimension);
88 return E_INVALIDARG;
91 return S_OK;
94 static HRESULT set_dsv_desc_from_resource(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource)
96 D3D11_RESOURCE_DIMENSION dimension;
98 ID3D11Resource_GetType(resource, &dimension);
100 desc->Flags = 0;
102 switch (dimension)
104 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
106 D3D11_TEXTURE1D_DESC texture_desc;
107 ID3D11Texture1D *texture;
109 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture)))
111 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n");
112 return E_INVALIDARG;
115 ID3D11Texture1D_GetDesc(texture, &texture_desc);
116 ID3D11Texture1D_Release(texture);
118 desc->Format = texture_desc.Format;
119 if (texture_desc.ArraySize == 1)
121 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
122 desc->u.Texture1D.MipSlice = 0;
124 else
126 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
127 desc->u.Texture1DArray.MipSlice = 0;
128 desc->u.Texture1DArray.FirstArraySlice = 0;
129 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
132 return S_OK;
135 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
137 D3D11_TEXTURE2D_DESC texture_desc;
138 ID3D11Texture2D *texture;
140 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
142 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
143 return E_INVALIDARG;
146 ID3D11Texture2D_GetDesc(texture, &texture_desc);
147 ID3D11Texture2D_Release(texture);
149 desc->Format = texture_desc.Format;
150 if (texture_desc.ArraySize == 1)
152 if (texture_desc.SampleDesc.Count == 1)
154 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
155 desc->u.Texture2D.MipSlice = 0;
157 else
159 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
162 else
164 if (texture_desc.SampleDesc.Count == 1)
166 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
167 desc->u.Texture2DArray.MipSlice = 0;
168 desc->u.Texture2DArray.FirstArraySlice = 0;
169 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
171 else
173 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
174 desc->u.Texture2DMSArray.FirstArraySlice = 0;
175 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
179 return S_OK;
182 case D3D11_RESOURCE_DIMENSION_BUFFER:
183 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
184 default:
185 WARN("Invalid resource dimension %#x.\n", dimension);
186 return E_INVALIDARG;
190 static HRESULT normalize_dsv_desc(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource)
192 D3D11_RESOURCE_DIMENSION dimension;
193 unsigned int layer_count;
194 DXGI_FORMAT format;
195 HRESULT hr;
197 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count)))
198 return hr;
199 switch (dimension)
201 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
202 if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1D
203 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1DARRAY)
205 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
206 return E_INVALIDARG;
208 break;
210 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
211 if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2D
212 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DARRAY
213 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMS
214 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY)
216 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
217 return E_INVALIDARG;
219 break;
221 case D3D11_RESOURCE_DIMENSION_BUFFER:
222 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
223 default:
224 WARN("Invalid resource dimension %#x.\n", dimension);
225 return E_INVALIDARG;
228 if (desc->Format == DXGI_FORMAT_UNKNOWN)
229 desc->Format = format;
231 switch (desc->ViewDimension)
233 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
234 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
235 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
236 break;
238 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
239 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
240 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
241 break;
243 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
244 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
245 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
246 break;
248 default:
249 break;
252 return S_OK;
255 static HRESULT set_rtv_desc_from_resource(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource)
257 D3D11_RESOURCE_DIMENSION dimension;
258 HRESULT hr;
260 ID3D11Resource_GetType(resource, &dimension);
262 switch (dimension)
264 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
266 ID3D11Texture1D *texture;
267 D3D11_TEXTURE1D_DESC texture_desc;
269 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture);
270 if (FAILED(hr))
272 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D?\n");
273 return E_INVALIDARG;
276 ID3D11Texture1D_GetDesc(texture, &texture_desc);
277 ID3D11Texture1D_Release(texture);
279 desc->Format = texture_desc.Format;
280 if (texture_desc.ArraySize == 1)
282 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
283 desc->u.Texture1D.MipSlice = 0;
285 else
287 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
288 desc->u.Texture1DArray.MipSlice = 0;
289 desc->u.Texture1DArray.FirstArraySlice = 0;
290 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
293 return S_OK;
296 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
298 ID3D11Texture2D *texture;
299 D3D11_TEXTURE2D_DESC texture_desc;
301 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture);
302 if (FAILED(hr))
304 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D?\n");
305 return E_INVALIDARG;
308 ID3D11Texture2D_GetDesc(texture, &texture_desc);
309 ID3D11Texture2D_Release(texture);
311 desc->Format = texture_desc.Format;
312 if (texture_desc.ArraySize == 1)
314 if (texture_desc.SampleDesc.Count == 1)
316 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
317 desc->u.Texture2D.MipSlice = 0;
319 else
321 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
324 else
326 if (texture_desc.SampleDesc.Count == 1)
328 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
329 desc->u.Texture2DArray.MipSlice = 0;
330 desc->u.Texture2DArray.FirstArraySlice = 0;
331 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
333 else
335 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
336 desc->u.Texture2DMSArray.FirstArraySlice = 0;
337 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
341 return S_OK;
344 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
346 ID3D11Texture3D *texture;
347 D3D11_TEXTURE3D_DESC texture_desc;
349 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture);
350 if (FAILED(hr))
352 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D?\n");
353 return E_INVALIDARG;
356 ID3D11Texture3D_GetDesc(texture, &texture_desc);
357 ID3D11Texture3D_Release(texture);
359 desc->Format = texture_desc.Format;
360 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
361 desc->u.Texture3D.MipSlice = 0;
362 desc->u.Texture3D.FirstWSlice = 0;
363 desc->u.Texture3D.WSize = texture_desc.Depth;
365 return S_OK;
368 default:
369 FIXME("Unhandled resource dimension %#x.\n", dimension);
370 return E_INVALIDARG;
374 static HRESULT normalize_rtv_desc(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource)
376 D3D11_RESOURCE_DIMENSION dimension;
377 unsigned int layer_count;
378 DXGI_FORMAT format;
379 HRESULT hr;
381 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count)))
382 return hr;
383 switch (dimension)
385 case D3D11_RESOURCE_DIMENSION_BUFFER:
386 if (desc->ViewDimension != D3D11_RTV_DIMENSION_BUFFER)
388 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
389 return E_INVALIDARG;
391 return S_OK;
393 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
394 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1D
395 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1DARRAY)
397 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
398 return E_INVALIDARG;
400 break;
402 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
403 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2D
404 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DARRAY
405 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMS
406 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY)
408 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
409 return E_INVALIDARG;
411 break;
413 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
414 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE3D)
416 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
417 return E_INVALIDARG;
419 break;
421 default:
422 WARN("Invalid resource dimension %#x.\n", dimension);
423 return E_INVALIDARG;
426 if (desc->Format == DXGI_FORMAT_UNKNOWN)
427 desc->Format = format;
429 switch (desc->ViewDimension)
431 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
432 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
433 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
434 break;
436 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
437 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
438 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
439 break;
441 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
442 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
443 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
444 break;
446 case D3D11_RTV_DIMENSION_TEXTURE3D:
447 layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice);
448 if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count)
449 desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice;
450 break;
452 default:
453 break;
456 return S_OK;
459 static HRESULT set_srv_desc_from_resource(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource)
461 D3D11_RESOURCE_DIMENSION dimension;
463 ID3D11Resource_GetType(resource, &dimension);
465 switch (dimension)
467 case D3D11_RESOURCE_DIMENSION_BUFFER:
469 D3D11_BUFFER_DESC buffer_desc;
470 ID3D11Buffer *buffer;
472 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer)))
474 ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n");
475 return E_INVALIDARG;
478 ID3D11Buffer_GetDesc(buffer, &buffer_desc);
479 ID3D11Buffer_Release(buffer);
481 if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
483 desc->Format = DXGI_FORMAT_UNKNOWN;
484 desc->ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
485 desc->u.Buffer.u1.FirstElement = 0;
486 desc->u.Buffer.u2.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
487 return S_OK;
490 return E_INVALIDARG;
493 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
495 D3D11_TEXTURE1D_DESC texture_desc;
496 ID3D11Texture1D *texture;
498 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture)))
500 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n");
501 return E_INVALIDARG;
504 ID3D11Texture1D_GetDesc(texture, &texture_desc);
505 ID3D11Texture1D_Release(texture);
507 desc->Format = texture_desc.Format;
508 if (texture_desc.ArraySize == 1)
510 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
511 desc->u.Texture1D.MostDetailedMip = 0;
512 desc->u.Texture1D.MipLevels = texture_desc.MipLevels;
514 else
516 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
517 desc->u.Texture1DArray.MostDetailedMip = 0;
518 desc->u.Texture1DArray.MipLevels = texture_desc.MipLevels;
519 desc->u.Texture1DArray.FirstArraySlice = 0;
520 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
523 return S_OK;
526 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
528 D3D11_TEXTURE2D_DESC texture_desc;
529 ID3D11Texture2D *texture;
531 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
533 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
534 return E_INVALIDARG;
537 ID3D11Texture2D_GetDesc(texture, &texture_desc);
538 ID3D11Texture2D_Release(texture);
540 desc->Format = texture_desc.Format;
541 if (texture_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
543 if (texture_desc.ArraySize >= 12)
545 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
546 desc->u.TextureCubeArray.MostDetailedMip = 0;
547 desc->u.TextureCubeArray.MipLevels = texture_desc.MipLevels;
548 desc->u.TextureCubeArray.First2DArrayFace = 0;
549 desc->u.TextureCubeArray.NumCubes = texture_desc.ArraySize / 6;
551 else
553 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
554 desc->u.TextureCube.MostDetailedMip = 0;
555 desc->u.TextureCube.MipLevels = texture_desc.MipLevels;
558 else if (texture_desc.ArraySize == 1)
560 if (texture_desc.SampleDesc.Count == 1)
562 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
563 desc->u.Texture2D.MostDetailedMip = 0;
564 desc->u.Texture2D.MipLevels = texture_desc.MipLevels;
566 else
568 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
571 else
573 if (texture_desc.SampleDesc.Count == 1)
575 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
576 desc->u.Texture2DArray.MostDetailedMip = 0;
577 desc->u.Texture2DArray.MipLevels = texture_desc.MipLevels;
578 desc->u.Texture2DArray.FirstArraySlice = 0;
579 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
581 else
583 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
584 desc->u.Texture2DMSArray.FirstArraySlice = 0;
585 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
589 return S_OK;
592 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
594 D3D11_TEXTURE3D_DESC texture_desc;
595 ID3D11Texture3D *texture;
597 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture)))
599 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n");
600 return E_INVALIDARG;
603 ID3D11Texture3D_GetDesc(texture, &texture_desc);
604 ID3D11Texture3D_Release(texture);
606 desc->Format = texture_desc.Format;
607 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
608 desc->u.Texture3D.MostDetailedMip = 0;
609 desc->u.Texture3D.MipLevels = texture_desc.MipLevels;
611 return S_OK;
614 default:
615 WARN("Invalid resource dimension %#x.\n", dimension);
616 return E_INVALIDARG;
620 static HRESULT normalize_srv_desc(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource)
622 unsigned int miplevel_count, layer_count;
623 D3D11_RESOURCE_DIMENSION dimension;
624 DXGI_FORMAT format;
625 HRESULT hr;
627 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, &miplevel_count, &layer_count)))
628 return hr;
629 switch (dimension)
631 case D3D11_RESOURCE_DIMENSION_BUFFER:
632 if (desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFER
633 && desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX)
635 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
636 return E_INVALIDARG;
638 if (!desc->u.Buffer.u2.NumElements)
640 WARN("Zero sized buffer view.\n");
641 return E_INVALIDARG;
643 return S_OK;
645 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
646 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1D
647 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1DARRAY)
649 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
650 return E_INVALIDARG;
652 break;
654 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
655 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2D
656 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DARRAY
657 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMS
658 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY
659 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBE
660 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBEARRAY)
662 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
663 return E_INVALIDARG;
665 break;
667 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
668 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE3D)
670 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
671 return E_INVALIDARG;
673 break;
675 default:
676 WARN("Invalid resource dimension %#x.\n", dimension);
677 return E_INVALIDARG;
680 if (desc->Format == DXGI_FORMAT_UNKNOWN)
681 desc->Format = format;
683 switch (desc->ViewDimension)
685 case D3D11_SRV_DIMENSION_TEXTURE1D:
686 if (desc->u.Texture1D.MipLevels == ~0u && desc->u.Texture1D.MostDetailedMip < miplevel_count)
687 desc->u.Texture1D.MipLevels = miplevel_count - desc->u.Texture1D.MostDetailedMip;
688 break;
690 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
691 if (desc->u.Texture1DArray.MipLevels == ~0u && desc->u.Texture1DArray.MostDetailedMip < miplevel_count)
692 desc->u.Texture1DArray.MipLevels = miplevel_count - desc->u.Texture1DArray.MostDetailedMip;
693 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < miplevel_count)
694 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
695 break;
697 case D3D11_SRV_DIMENSION_TEXTURE2D:
698 if (desc->u.Texture2D.MipLevels == ~0u && desc->u.Texture2D.MostDetailedMip < miplevel_count)
699 desc->u.Texture2D.MipLevels = miplevel_count - desc->u.Texture2D.MostDetailedMip;
700 break;
702 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
703 if (desc->u.Texture2DArray.MipLevels == ~0u && desc->u.Texture2DArray.MostDetailedMip < miplevel_count)
704 desc->u.Texture2DArray.MipLevels = miplevel_count - desc->u.Texture2DArray.MostDetailedMip;
705 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
706 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
707 break;
709 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
710 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
711 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
712 break;
714 case D3D11_SRV_DIMENSION_TEXTURE3D:
715 if (desc->u.Texture3D.MipLevels == ~0u && desc->u.Texture3D.MostDetailedMip < miplevel_count)
716 desc->u.Texture3D.MipLevels = miplevel_count - desc->u.Texture3D.MostDetailedMip;
717 break;
719 case D3D11_SRV_DIMENSION_TEXTURECUBE:
720 if (desc->u.TextureCube.MipLevels == ~0u && desc->u.TextureCube.MostDetailedMip < miplevel_count)
721 desc->u.TextureCube.MipLevels = miplevel_count - desc->u.TextureCube.MostDetailedMip;
722 break;
724 case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
725 if (desc->u.TextureCubeArray.MipLevels == ~0u && desc->u.TextureCubeArray.MostDetailedMip < miplevel_count)
726 desc->u.TextureCubeArray.MipLevels = miplevel_count - desc->u.TextureCubeArray.MostDetailedMip;
727 if (desc->u.TextureCubeArray.NumCubes == ~0u && desc->u.TextureCubeArray.First2DArrayFace < layer_count)
728 desc->u.TextureCubeArray.NumCubes = (layer_count - desc->u.TextureCubeArray.First2DArrayFace) / 6;
729 break;
731 default:
732 break;
735 return S_OK;
738 static HRESULT set_uav_desc_from_resource(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource)
740 D3D11_RESOURCE_DIMENSION dimension;
742 ID3D11Resource_GetType(resource, &dimension);
744 switch (dimension)
746 case D3D11_RESOURCE_DIMENSION_BUFFER:
748 D3D11_BUFFER_DESC buffer_desc;
749 ID3D11Buffer *buffer;
751 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer)))
753 ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n");
754 return E_INVALIDARG;
757 ID3D11Buffer_GetDesc(buffer, &buffer_desc);
758 ID3D11Buffer_Release(buffer);
760 if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
762 desc->Format = DXGI_FORMAT_UNKNOWN;
763 desc->ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
764 desc->u.Buffer.FirstElement = 0;
765 desc->u.Buffer.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
766 desc->u.Buffer.Flags = 0;
767 return S_OK;
770 return E_INVALIDARG;
773 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
775 D3D11_TEXTURE2D_DESC texture_desc;
776 ID3D11Texture2D *texture;
778 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
780 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
781 return E_INVALIDARG;
784 ID3D11Texture2D_GetDesc(texture, &texture_desc);
785 ID3D11Texture2D_Release(texture);
787 if (texture_desc.SampleDesc.Count != 1)
789 WARN("Trying to create view for multisample texture.\n");
790 return E_INVALIDARG;
793 desc->Format = texture_desc.Format;
794 if (texture_desc.ArraySize == 1)
796 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
797 desc->u.Texture2D.MipSlice = 0;
799 else
801 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
802 desc->u.Texture2DArray.MipSlice = 0;
803 desc->u.Texture2DArray.FirstArraySlice = 0;
804 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
807 return S_OK;
810 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
812 D3D11_TEXTURE3D_DESC texture_desc;
813 ID3D11Texture3D *texture;
815 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture)))
817 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n");
818 return E_INVALIDARG;
821 ID3D11Texture3D_GetDesc(texture, &texture_desc);
822 ID3D11Texture3D_Release(texture);
824 desc->Format = texture_desc.Format;
825 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
826 desc->u.Texture3D.MipSlice = 0;
827 desc->u.Texture3D.FirstWSlice = 0;
828 desc->u.Texture3D.WSize = texture_desc.Depth;
830 return S_OK;
833 default:
834 FIXME("Unhandled resource dimension %#x.\n", dimension);
835 return E_INVALIDARG;
839 static HRESULT normalize_uav_desc(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource)
841 D3D11_RESOURCE_DIMENSION dimension;
842 unsigned int layer_count;
843 DXGI_FORMAT format;
844 HRESULT hr;
846 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count)))
847 return hr;
848 switch (dimension)
850 case D3D11_RESOURCE_DIMENSION_BUFFER:
851 if (desc->ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
853 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
854 return E_INVALIDARG;
856 return S_OK;
858 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
859 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1D
860 && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1DARRAY)
862 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
863 return E_INVALIDARG;
865 break;
867 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
868 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2D
869 && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2DARRAY)
871 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
872 return E_INVALIDARG;
874 break;
876 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
877 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE3D)
879 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
880 return E_INVALIDARG;
882 break;
884 default:
885 WARN("Invalid resource dimension %#x.\n", dimension);
886 return E_INVALIDARG;
889 if (desc->Format == DXGI_FORMAT_UNKNOWN)
890 desc->Format = format;
892 switch (desc->ViewDimension)
894 case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
895 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
896 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
897 break;
899 case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
900 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
901 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
902 break;
904 case D3D11_UAV_DIMENSION_TEXTURE3D:
905 layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice);
906 if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count)
907 desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice;
908 break;
910 default:
911 break;
914 return S_OK;
917 /* ID3D11DepthStencilView methods */
919 static inline struct d3d_depthstencil_view *impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface)
921 return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D11DepthStencilView_iface);
924 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_QueryInterface(ID3D11DepthStencilView *iface,
925 REFIID riid, void **object)
927 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
929 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
931 if (IsEqualGUID(riid, &IID_ID3D11DepthStencilView)
932 || IsEqualGUID(riid, &IID_ID3D11View)
933 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
934 || IsEqualGUID(riid, &IID_IUnknown))
936 ID3D11DepthStencilView_AddRef(iface);
937 *object = iface;
938 return S_OK;
941 if (IsEqualGUID(riid, &IID_ID3D10DepthStencilView)
942 || IsEqualGUID(riid, &IID_ID3D10View)
943 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
945 ID3D10DepthStencilView_AddRef(&view->ID3D10DepthStencilView_iface);
946 *object = &view->ID3D10DepthStencilView_iface;
947 return S_OK;
950 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
952 *object = NULL;
953 return E_NOINTERFACE;
956 static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_AddRef(ID3D11DepthStencilView *iface)
958 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
959 ULONG refcount = InterlockedIncrement(&view->refcount);
961 TRACE("%p increasing refcount to %lu.\n", view, refcount);
963 if (refcount == 1)
965 ID3D11Device2_AddRef(view->device);
966 wined3d_rendertarget_view_incref(view->wined3d_view);
969 return refcount;
972 static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_Release(ID3D11DepthStencilView *iface)
974 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
975 ULONG refcount = InterlockedDecrement(&view->refcount);
977 TRACE("%p decreasing refcount to %lu.\n", view, refcount);
979 if (!refcount)
981 ID3D11Device2 *device = view->device;
982 wined3d_rendertarget_view_decref(view->wined3d_view);
983 ID3D11Device2_Release(device);
986 return refcount;
989 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDevice(ID3D11DepthStencilView *iface,
990 ID3D11Device **device)
992 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
994 TRACE("iface %p, device %p.\n", iface, device);
996 *device = (ID3D11Device *)view->device;
997 ID3D11Device_AddRef(*device);
1000 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_GetPrivateData(ID3D11DepthStencilView *iface,
1001 REFGUID guid, UINT *data_size, void *data)
1003 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1005 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1007 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1010 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateData(ID3D11DepthStencilView *iface,
1011 REFGUID guid, UINT data_size, const void *data)
1013 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1015 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1017 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1020 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateDataInterface(ID3D11DepthStencilView *iface,
1021 REFGUID guid, const IUnknown *data)
1023 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1025 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1027 return d3d_set_private_data_interface(&view->private_store, guid, data);
1030 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetResource(ID3D11DepthStencilView *iface,
1031 ID3D11Resource **resource)
1033 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1035 TRACE("iface %p, resource %p.\n", iface, resource);
1037 *resource = view->resource;
1038 ID3D11Resource_AddRef(*resource);
1041 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDesc(ID3D11DepthStencilView *iface,
1042 D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1044 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1046 TRACE("iface %p, desc %p.\n", iface, desc);
1048 *desc = view->desc;
1051 static const struct ID3D11DepthStencilViewVtbl d3d11_depthstencil_view_vtbl =
1053 /* IUnknown methods */
1054 d3d11_depthstencil_view_QueryInterface,
1055 d3d11_depthstencil_view_AddRef,
1056 d3d11_depthstencil_view_Release,
1057 /* ID3D11DeviceChild methods */
1058 d3d11_depthstencil_view_GetDevice,
1059 d3d11_depthstencil_view_GetPrivateData,
1060 d3d11_depthstencil_view_SetPrivateData,
1061 d3d11_depthstencil_view_SetPrivateDataInterface,
1062 /* ID3D11View methods */
1063 d3d11_depthstencil_view_GetResource,
1064 /* ID3D11DepthStencilView methods */
1065 d3d11_depthstencil_view_GetDesc,
1068 /* ID3D10DepthStencilView methods */
1070 static inline struct d3d_depthstencil_view *impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface)
1072 return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D10DepthStencilView_iface);
1075 /* IUnknown methods */
1077 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_QueryInterface(ID3D10DepthStencilView *iface,
1078 REFIID riid, void **object)
1080 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1082 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1084 return d3d11_depthstencil_view_QueryInterface(&view->ID3D11DepthStencilView_iface, riid, object);
1087 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_AddRef(ID3D10DepthStencilView *iface)
1089 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1091 TRACE("iface %p.\n", iface);
1093 return d3d11_depthstencil_view_AddRef(&view->ID3D11DepthStencilView_iface);
1096 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_Release(ID3D10DepthStencilView *iface)
1098 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1100 TRACE("iface %p.\n", iface);
1102 return d3d11_depthstencil_view_Release(&view->ID3D11DepthStencilView_iface);
1105 /* ID3D10DeviceChild methods */
1107 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDevice(ID3D10DepthStencilView *iface, ID3D10Device **device)
1109 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1111 TRACE("iface %p, device %p.\n", iface, device);
1113 ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
1116 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_GetPrivateData(ID3D10DepthStencilView *iface,
1117 REFGUID guid, UINT *data_size, void *data)
1119 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1121 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1122 iface, debugstr_guid(guid), data_size, data);
1124 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1127 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateData(ID3D10DepthStencilView *iface,
1128 REFGUID guid, UINT data_size, const void *data)
1130 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1132 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1133 iface, debugstr_guid(guid), data_size, data);
1135 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1138 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateDataInterface(ID3D10DepthStencilView *iface,
1139 REFGUID guid, const IUnknown *data)
1141 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1143 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1145 return d3d_set_private_data_interface(&view->private_store, guid, data);
1148 /* ID3D10View methods */
1150 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetResource(ID3D10DepthStencilView *iface,
1151 ID3D10Resource **resource)
1153 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1155 TRACE("iface %p, resource %p.\n", iface, resource);
1157 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
1160 /* ID3D10DepthStencilView methods */
1162 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDesc(ID3D10DepthStencilView *iface,
1163 D3D10_DEPTH_STENCIL_VIEW_DESC *desc)
1165 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1166 const D3D11_DEPTH_STENCIL_VIEW_DESC *d3d11_desc = &view->desc;
1168 TRACE("iface %p, desc %p.\n", iface, desc);
1170 desc->Format = d3d11_desc->Format;
1171 desc->ViewDimension = (D3D10_DSV_DIMENSION)d3d11_desc->ViewDimension;
1172 memcpy(&desc->u, &d3d11_desc->u, sizeof(desc->u));
1175 static const struct ID3D10DepthStencilViewVtbl d3d10_depthstencil_view_vtbl =
1177 /* IUnknown methods */
1178 d3d10_depthstencil_view_QueryInterface,
1179 d3d10_depthstencil_view_AddRef,
1180 d3d10_depthstencil_view_Release,
1181 /* ID3D10DeviceChild methods */
1182 d3d10_depthstencil_view_GetDevice,
1183 d3d10_depthstencil_view_GetPrivateData,
1184 d3d10_depthstencil_view_SetPrivateData,
1185 d3d10_depthstencil_view_SetPrivateDataInterface,
1186 /* ID3D10View methods */
1187 d3d10_depthstencil_view_GetResource,
1188 /* ID3D10DepthStencilView methods */
1189 d3d10_depthstencil_view_GetDesc,
1192 static void STDMETHODCALLTYPE d3d_depth_stencil_view_wined3d_object_destroyed(void *parent)
1194 struct d3d_depthstencil_view *view = parent;
1196 wined3d_private_store_cleanup(&view->private_store);
1197 free(parent);
1200 static const struct wined3d_parent_ops d3d_depth_stencil_view_wined3d_parent_ops =
1202 d3d_depth_stencil_view_wined3d_object_destroyed,
1205 static void wined3d_depth_stencil_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
1206 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1208 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
1210 wined3d_desc->flags = 0;
1211 if (desc->Flags & D3D11_DSV_READ_ONLY_DEPTH)
1212 wined3d_desc->flags |= WINED3D_VIEW_READ_ONLY_DEPTH;
1213 if (desc->Flags & D3D11_DSV_READ_ONLY_STENCIL)
1214 wined3d_desc->flags |= WINED3D_VIEW_READ_ONLY_STENCIL;
1216 wined3d_desc->u.texture.level_count = 1;
1217 switch (desc->ViewDimension)
1219 case D3D11_DSV_DIMENSION_TEXTURE1D:
1220 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
1221 wined3d_desc->u.texture.layer_idx = 0;
1222 wined3d_desc->u.texture.layer_count = 1;
1223 break;
1225 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
1226 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1227 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
1228 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
1229 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
1230 break;
1232 case D3D11_DSV_DIMENSION_TEXTURE2D:
1233 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
1234 wined3d_desc->u.texture.layer_idx = 0;
1235 wined3d_desc->u.texture.layer_count = 1;
1236 break;
1238 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
1239 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1240 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
1241 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
1242 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
1243 break;
1245 case D3D11_DSV_DIMENSION_TEXTURE2DMS:
1246 wined3d_desc->u.texture.level_idx = 0;
1247 wined3d_desc->u.texture.layer_idx = 0;
1248 wined3d_desc->u.texture.layer_count = 1;
1249 break;
1251 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
1252 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1253 wined3d_desc->u.texture.level_idx = 0;
1254 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
1255 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
1256 break;
1258 default:
1259 FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension);
1260 wined3d_desc->u.texture.level_idx = 0;
1261 wined3d_desc->u.texture.layer_idx = 0;
1262 wined3d_desc->u.texture.layer_count = 1;
1263 break;
1267 static HRESULT d3d_depthstencil_view_init(struct d3d_depthstencil_view *view, struct d3d_device *device,
1268 ID3D11Resource *resource, const D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1270 struct wined3d_resource *wined3d_resource;
1271 struct wined3d_view_desc wined3d_desc;
1272 HRESULT hr;
1274 view->ID3D11DepthStencilView_iface.lpVtbl = &d3d11_depthstencil_view_vtbl;
1275 view->ID3D10DepthStencilView_iface.lpVtbl = &d3d10_depthstencil_view_vtbl;
1276 view->refcount = 1;
1278 if (!desc)
1280 hr = set_dsv_desc_from_resource(&view->desc, resource);
1282 else
1284 view->desc = *desc;
1285 hr = normalize_dsv_desc(&view->desc, resource);
1287 if (FAILED(hr))
1288 return hr;
1290 wined3d_mutex_lock();
1291 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
1293 wined3d_mutex_unlock();
1294 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
1295 return E_FAIL;
1298 wined3d_depth_stencil_view_desc_from_d3d11(&wined3d_desc, &view->desc);
1299 if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource,
1300 view, &d3d_depth_stencil_view_wined3d_parent_ops, &view->wined3d_view)))
1302 wined3d_mutex_unlock();
1303 WARN("Failed to create a wined3d rendertarget view, hr %#lx.\n", hr);
1304 return hr;
1307 wined3d_private_store_init(&view->private_store);
1308 wined3d_mutex_unlock();
1309 view->resource = resource;
1310 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
1312 return S_OK;
1315 HRESULT d3d_depthstencil_view_create(struct d3d_device *device, ID3D11Resource *resource,
1316 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, struct d3d_depthstencil_view **view)
1318 struct d3d_depthstencil_view *object;
1319 HRESULT hr;
1321 if (!(object = calloc(1, sizeof(*object))))
1322 return E_OUTOFMEMORY;
1324 if (FAILED(hr = d3d_depthstencil_view_init(object, device, resource, desc)))
1326 WARN("Failed to initialise depth/stencil view, hr %#lx.\n", hr);
1327 free(object);
1328 return hr;
1331 TRACE("Created depthstencil view %p.\n", object);
1332 *view = object;
1334 return S_OK;
1337 struct d3d_depthstencil_view *unsafe_impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface)
1339 if (!iface)
1340 return NULL;
1341 assert(iface->lpVtbl == &d3d11_depthstencil_view_vtbl);
1343 return impl_from_ID3D11DepthStencilView(iface);
1346 struct d3d_depthstencil_view *unsafe_impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface)
1348 if (!iface)
1349 return NULL;
1350 assert(iface->lpVtbl == &d3d10_depthstencil_view_vtbl);
1352 return impl_from_ID3D10DepthStencilView(iface);
1355 /* ID3D11RenderTargetView methods */
1357 static inline struct d3d_rendertarget_view *impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface)
1359 return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D11RenderTargetView_iface);
1362 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_QueryInterface(ID3D11RenderTargetView *iface,
1363 REFIID riid, void **object)
1365 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1367 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1369 if (IsEqualGUID(riid, &IID_ID3D11RenderTargetView)
1370 || IsEqualGUID(riid, &IID_ID3D11View)
1371 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1372 || IsEqualGUID(riid, &IID_IUnknown))
1374 ID3D11RenderTargetView_AddRef(iface);
1375 *object = iface;
1376 return S_OK;
1379 if (IsEqualGUID(riid, &IID_ID3D10RenderTargetView)
1380 || IsEqualGUID(riid, &IID_ID3D10View)
1381 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1383 ID3D10RenderTargetView_AddRef(&view->ID3D10RenderTargetView_iface);
1384 *object = &view->ID3D10RenderTargetView_iface;
1385 return S_OK;
1388 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1390 *object = NULL;
1391 return E_NOINTERFACE;
1394 static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_AddRef(ID3D11RenderTargetView *iface)
1396 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1397 ULONG refcount = InterlockedIncrement(&view->refcount);
1399 TRACE("%p increasing refcount to %lu.\n", view, refcount);
1401 if (refcount == 1)
1403 ID3D11Device2_AddRef(view->device);
1404 wined3d_rendertarget_view_incref(view->wined3d_view);
1407 return refcount;
1410 static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_Release(ID3D11RenderTargetView *iface)
1412 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1413 ULONG refcount = InterlockedDecrement(&view->refcount);
1415 TRACE("%p decreasing refcount to %lu.\n", view, refcount);
1417 if (!refcount)
1419 ID3D11Device2 *device = view->device;
1420 wined3d_rendertarget_view_decref(view->wined3d_view);
1421 ID3D11Device2_Release(device);
1424 return refcount;
1427 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDevice(ID3D11RenderTargetView *iface,
1428 ID3D11Device **device)
1430 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1432 TRACE("iface %p, device %p.\n", iface, device);
1434 *device = (ID3D11Device *)view->device;
1435 ID3D11Device_AddRef(*device);
1438 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_GetPrivateData(ID3D11RenderTargetView *iface,
1439 REFGUID guid, UINT *data_size, void *data)
1441 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1443 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1445 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1448 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateData(ID3D11RenderTargetView *iface,
1449 REFGUID guid, UINT data_size, const void *data)
1451 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1453 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1455 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1458 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateDataInterface(ID3D11RenderTargetView *iface,
1459 REFGUID guid, const IUnknown *data)
1461 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1463 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1465 return d3d_set_private_data_interface(&view->private_store, guid, data);
1468 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetResource(ID3D11RenderTargetView *iface,
1469 ID3D11Resource **resource)
1471 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1473 TRACE("iface %p, resource %p.\n", iface, resource);
1475 *resource = view->resource;
1476 ID3D11Resource_AddRef(*resource);
1479 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDesc(ID3D11RenderTargetView *iface,
1480 D3D11_RENDER_TARGET_VIEW_DESC *desc)
1482 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1484 TRACE("iface %p, desc %p.\n", iface, desc);
1486 *desc = view->desc;
1489 static const struct ID3D11RenderTargetViewVtbl d3d11_rendertarget_view_vtbl =
1491 /* IUnknown methods */
1492 d3d11_rendertarget_view_QueryInterface,
1493 d3d11_rendertarget_view_AddRef,
1494 d3d11_rendertarget_view_Release,
1495 /* ID3D11DeviceChild methods */
1496 d3d11_rendertarget_view_GetDevice,
1497 d3d11_rendertarget_view_GetPrivateData,
1498 d3d11_rendertarget_view_SetPrivateData,
1499 d3d11_rendertarget_view_SetPrivateDataInterface,
1500 /* ID3D11View methods */
1501 d3d11_rendertarget_view_GetResource,
1502 /* ID3D11RenderTargetView methods */
1503 d3d11_rendertarget_view_GetDesc,
1506 /* ID3D10RenderTargetView methods */
1508 static inline struct d3d_rendertarget_view *impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface)
1510 return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D10RenderTargetView_iface);
1513 /* IUnknown methods */
1515 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_QueryInterface(ID3D10RenderTargetView *iface,
1516 REFIID riid, void **object)
1518 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1520 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1522 return d3d11_rendertarget_view_QueryInterface(&view->ID3D11RenderTargetView_iface, riid, object);
1525 static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_AddRef(ID3D10RenderTargetView *iface)
1527 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1529 TRACE("iface %p.\n", iface);
1531 return d3d11_rendertarget_view_AddRef(&view->ID3D11RenderTargetView_iface);
1534 static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_Release(ID3D10RenderTargetView *iface)
1536 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1538 TRACE("iface %p.\n", iface);
1540 return d3d11_rendertarget_view_Release(&view->ID3D11RenderTargetView_iface);
1543 /* ID3D10DeviceChild methods */
1545 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDevice(ID3D10RenderTargetView *iface, ID3D10Device **device)
1547 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1549 TRACE("iface %p, device %p.\n", iface, device);
1551 ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
1554 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_GetPrivateData(ID3D10RenderTargetView *iface,
1555 REFGUID guid, UINT *data_size, void *data)
1557 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1559 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1560 iface, debugstr_guid(guid), data_size, data);
1562 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1565 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateData(ID3D10RenderTargetView *iface,
1566 REFGUID guid, UINT data_size, const void *data)
1568 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1570 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1571 iface, debugstr_guid(guid), data_size, data);
1573 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1576 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateDataInterface(ID3D10RenderTargetView *iface,
1577 REFGUID guid, const IUnknown *data)
1579 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1581 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1583 return d3d_set_private_data_interface(&view->private_store, guid, data);
1586 /* ID3D10View methods */
1588 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetResource(ID3D10RenderTargetView *iface,
1589 ID3D10Resource **resource)
1591 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1593 TRACE("iface %p, resource %p\n", iface, resource);
1595 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
1598 /* ID3D10RenderTargetView methods */
1600 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDesc(ID3D10RenderTargetView *iface,
1601 D3D10_RENDER_TARGET_VIEW_DESC *desc)
1603 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1605 TRACE("iface %p, desc %p\n", iface, desc);
1607 memcpy(desc, &view->desc, sizeof(*desc));
1610 static const struct ID3D10RenderTargetViewVtbl d3d10_rendertarget_view_vtbl =
1612 /* IUnknown methods */
1613 d3d10_rendertarget_view_QueryInterface,
1614 d3d10_rendertarget_view_AddRef,
1615 d3d10_rendertarget_view_Release,
1616 /* ID3D10DeviceChild methods */
1617 d3d10_rendertarget_view_GetDevice,
1618 d3d10_rendertarget_view_GetPrivateData,
1619 d3d10_rendertarget_view_SetPrivateData,
1620 d3d10_rendertarget_view_SetPrivateDataInterface,
1621 /* ID3D10View methods */
1622 d3d10_rendertarget_view_GetResource,
1623 /* ID3D10RenderTargetView methods */
1624 d3d10_rendertarget_view_GetDesc,
1627 static void STDMETHODCALLTYPE d3d_render_target_view_wined3d_object_destroyed(void *parent)
1629 struct d3d_rendertarget_view *view = parent;
1631 wined3d_private_store_cleanup(&view->private_store);
1632 free(parent);
1635 static const struct wined3d_parent_ops d3d_render_target_view_wined3d_parent_ops =
1637 d3d_render_target_view_wined3d_object_destroyed,
1640 static void wined3d_rendertarget_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
1641 const D3D11_RENDER_TARGET_VIEW_DESC *desc)
1643 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
1645 wined3d_desc->flags = 0;
1646 wined3d_desc->u.texture.level_count = 1;
1647 switch (desc->ViewDimension)
1649 case D3D11_RTV_DIMENSION_BUFFER:
1650 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement;
1651 wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements;
1652 break;
1654 case D3D11_RTV_DIMENSION_TEXTURE1D:
1655 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
1656 wined3d_desc->u.texture.layer_idx = 0;
1657 wined3d_desc->u.texture.layer_count = 1;
1658 break;
1660 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
1661 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1662 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
1663 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
1664 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
1665 break;
1667 case D3D11_RTV_DIMENSION_TEXTURE2D:
1668 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
1669 wined3d_desc->u.texture.layer_idx = 0;
1670 wined3d_desc->u.texture.layer_count = 1;
1671 break;
1673 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
1674 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1675 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
1676 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
1677 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
1678 break;
1680 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
1681 wined3d_desc->u.texture.level_idx = 0;
1682 wined3d_desc->u.texture.layer_idx = 0;
1683 wined3d_desc->u.texture.layer_count = 1;
1684 break;
1686 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
1687 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1688 wined3d_desc->u.texture.level_idx = 0;
1689 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
1690 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
1691 break;
1693 case D3D11_RTV_DIMENSION_TEXTURE3D:
1694 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice;
1695 wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice;
1696 wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize;
1697 break;
1699 default:
1700 FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension);
1701 wined3d_desc->u.texture.level_idx = 0;
1702 wined3d_desc->u.texture.layer_idx = 0;
1703 wined3d_desc->u.texture.layer_count = 1;
1704 break;
1708 static HRESULT d3d_rendertarget_view_init(struct d3d_rendertarget_view *view, struct d3d_device *device,
1709 ID3D11Resource *resource, const D3D11_RENDER_TARGET_VIEW_DESC *desc)
1711 struct wined3d_resource *wined3d_resource;
1712 struct wined3d_view_desc wined3d_desc;
1713 HRESULT hr;
1715 view->ID3D11RenderTargetView_iface.lpVtbl = &d3d11_rendertarget_view_vtbl;
1716 view->ID3D10RenderTargetView_iface.lpVtbl = &d3d10_rendertarget_view_vtbl;
1717 view->refcount = 1;
1719 if (!desc)
1721 hr = set_rtv_desc_from_resource(&view->desc, resource);
1723 else
1725 view->desc = *desc;
1726 hr = normalize_rtv_desc(&view->desc, resource);
1728 if (FAILED(hr))
1729 return hr;
1731 wined3d_mutex_lock();
1732 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
1734 wined3d_mutex_unlock();
1735 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
1736 return E_FAIL;
1739 wined3d_rendertarget_view_desc_from_d3d11(&wined3d_desc, &view->desc);
1740 if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource,
1741 view, &d3d_render_target_view_wined3d_parent_ops, &view->wined3d_view)))
1743 wined3d_mutex_unlock();
1744 WARN("Failed to create a wined3d rendertarget view, hr %#lx.\n", hr);
1745 return hr;
1748 wined3d_private_store_init(&view->private_store);
1749 wined3d_mutex_unlock();
1750 view->resource = resource;
1751 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
1753 return S_OK;
1756 HRESULT d3d_rendertarget_view_create(struct d3d_device *device, ID3D11Resource *resource,
1757 const D3D11_RENDER_TARGET_VIEW_DESC *desc, struct d3d_rendertarget_view **view)
1759 struct d3d_rendertarget_view *object;
1760 HRESULT hr;
1762 if (!(object = calloc(1, sizeof(*object))))
1763 return E_OUTOFMEMORY;
1765 if (FAILED(hr = d3d_rendertarget_view_init(object, device, resource, desc)))
1767 WARN("Failed to initialise rendertarget view, hr %#lx.\n", hr);
1768 free(object);
1769 return hr;
1772 TRACE("Created rendertarget view %p.\n", object);
1773 *view = object;
1775 return S_OK;
1778 struct d3d_rendertarget_view *unsafe_impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface)
1780 if (!iface)
1781 return NULL;
1782 assert(iface->lpVtbl == &d3d11_rendertarget_view_vtbl);
1784 return impl_from_ID3D11RenderTargetView(iface);
1787 struct d3d_rendertarget_view *unsafe_impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface)
1789 if (!iface)
1790 return NULL;
1791 assert(iface->lpVtbl == &d3d10_rendertarget_view_vtbl);
1793 return impl_from_ID3D10RenderTargetView(iface);
1796 /* ID3D11ShaderResourceView methods */
1798 static inline struct d3d_shader_resource_view *impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface)
1800 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D11ShaderResourceView_iface);
1803 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_QueryInterface(ID3D11ShaderResourceView *iface,
1804 REFIID riid, void **object)
1806 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1808 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1810 if (IsEqualGUID(riid, &IID_ID3D11ShaderResourceView)
1811 || IsEqualGUID(riid, &IID_ID3D11View)
1812 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1813 || IsEqualGUID(riid, &IID_IUnknown))
1815 ID3D11ShaderResourceView_AddRef(iface);
1816 *object = iface;
1817 return S_OK;
1820 if (IsEqualGUID(riid, &IID_ID3D10ShaderResourceView1)
1821 || IsEqualGUID(riid, &IID_ID3D10ShaderResourceView)
1822 || IsEqualGUID(riid, &IID_ID3D10View)
1823 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1825 ID3D10ShaderResourceView1_AddRef(&view->ID3D10ShaderResourceView1_iface);
1826 *object = &view->ID3D10ShaderResourceView1_iface;
1827 return S_OK;
1830 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1832 *object = NULL;
1833 return E_NOINTERFACE;
1836 static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_AddRef(ID3D11ShaderResourceView *iface)
1838 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1839 ULONG refcount = InterlockedIncrement(&view->refcount);
1841 TRACE("%p increasing refcount to %lu.\n", view, refcount);
1843 if (refcount == 1)
1845 ID3D11Device2_AddRef(view->device);
1846 wined3d_shader_resource_view_incref(view->wined3d_view);
1849 return refcount;
1852 static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_Release(ID3D11ShaderResourceView *iface)
1854 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1855 ULONG refcount = InterlockedDecrement(&view->refcount);
1857 TRACE("%p decreasing refcount to %lu.\n", view, refcount);
1859 if (!refcount)
1861 ID3D11Device2 *device = view->device;
1862 wined3d_shader_resource_view_decref(view->wined3d_view);
1863 ID3D11Device2_Release(device);
1866 return refcount;
1869 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDevice(ID3D11ShaderResourceView *iface,
1870 ID3D11Device **device)
1872 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1874 TRACE("iface %p, device %p.\n", iface, device);
1876 *device = (ID3D11Device *)view->device;
1877 ID3D11Device_AddRef(*device);
1880 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_GetPrivateData(ID3D11ShaderResourceView *iface,
1881 REFGUID guid, UINT *data_size, void *data)
1883 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1885 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1887 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1890 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateData(ID3D11ShaderResourceView *iface,
1891 REFGUID guid, UINT data_size, const void *data)
1893 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1895 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1897 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1900 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateDataInterface(ID3D11ShaderResourceView *iface,
1901 REFGUID guid, const IUnknown *data)
1903 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1905 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1907 return d3d_set_private_data_interface(&view->private_store, guid, data);
1910 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetResource(ID3D11ShaderResourceView *iface,
1911 ID3D11Resource **resource)
1913 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1915 TRACE("iface %p, resource %p.\n", iface, resource);
1917 *resource = view->resource;
1918 ID3D11Resource_AddRef(*resource);
1921 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDesc(ID3D11ShaderResourceView *iface,
1922 D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
1924 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1926 TRACE("iface %p, desc %p.\n", iface, desc);
1928 *desc = view->desc;
1931 static const struct ID3D11ShaderResourceViewVtbl d3d11_shader_resource_view_vtbl =
1933 /* IUnknown methods */
1934 d3d11_shader_resource_view_QueryInterface,
1935 d3d11_shader_resource_view_AddRef,
1936 d3d11_shader_resource_view_Release,
1937 /* ID3D11DeviceChild methods */
1938 d3d11_shader_resource_view_GetDevice,
1939 d3d11_shader_resource_view_GetPrivateData,
1940 d3d11_shader_resource_view_SetPrivateData,
1941 d3d11_shader_resource_view_SetPrivateDataInterface,
1942 /* ID3D11View methods */
1943 d3d11_shader_resource_view_GetResource,
1944 /* ID3D11ShaderResourceView methods */
1945 d3d11_shader_resource_view_GetDesc,
1948 /* ID3D10ShaderResourceView methods */
1950 static inline struct d3d_shader_resource_view *impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView1 *iface)
1952 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface);
1955 /* IUnknown methods */
1957 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_QueryInterface(ID3D10ShaderResourceView1 *iface,
1958 REFIID riid, void **object)
1960 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
1962 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1964 return d3d11_shader_resource_view_QueryInterface(&view->ID3D11ShaderResourceView_iface, riid, object);
1967 static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_AddRef(ID3D10ShaderResourceView1 *iface)
1969 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
1971 TRACE("iface %p.\n", iface);
1973 return d3d11_shader_resource_view_AddRef(&view->ID3D11ShaderResourceView_iface);
1976 static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_Release(ID3D10ShaderResourceView1 *iface)
1978 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
1980 TRACE("iface %p.\n", iface);
1982 return d3d11_shader_resource_view_Release(&view->ID3D11ShaderResourceView_iface);
1985 /* ID3D10DeviceChild methods */
1987 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDevice(ID3D10ShaderResourceView1 *iface,
1988 ID3D10Device **device)
1990 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
1992 TRACE("iface %p, device %p.\n", iface, device);
1994 ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
1997 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_GetPrivateData(ID3D10ShaderResourceView1 *iface,
1998 REFGUID guid, UINT *data_size, void *data)
2000 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2002 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
2003 iface, debugstr_guid(guid), data_size, data);
2005 return d3d_get_private_data(&view->private_store, guid, data_size, data);
2008 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateData(ID3D10ShaderResourceView1 *iface,
2009 REFGUID guid, UINT data_size, const void *data)
2011 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2013 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
2014 iface, debugstr_guid(guid), data_size, data);
2016 return d3d_set_private_data(&view->private_store, guid, data_size, data);
2019 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateDataInterface(ID3D10ShaderResourceView1 *iface,
2020 REFGUID guid, const IUnknown *data)
2022 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2024 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2026 return d3d_set_private_data_interface(&view->private_store, guid, data);
2029 /* ID3D10View methods */
2031 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetResource(ID3D10ShaderResourceView1 *iface,
2032 ID3D10Resource **resource)
2034 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2036 TRACE("iface %p, resource %p.\n", iface, resource);
2038 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
2041 /* ID3D10ShaderResourceView methods */
2043 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc(ID3D10ShaderResourceView1 *iface,
2044 D3D10_SHADER_RESOURCE_VIEW_DESC *desc)
2046 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2048 TRACE("iface %p, desc %p.\n", iface, desc);
2050 memcpy(desc, &view->desc, sizeof(*desc));
2053 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc1(ID3D10ShaderResourceView1 *iface,
2054 D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc)
2056 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2058 TRACE("iface %p, desc %p.\n", iface, desc);
2060 memcpy(desc, &view->desc, sizeof(*desc));
2063 static const struct ID3D10ShaderResourceView1Vtbl d3d10_shader_resource_view_vtbl =
2065 /* IUnknown methods */
2066 d3d10_shader_resource_view_QueryInterface,
2067 d3d10_shader_resource_view_AddRef,
2068 d3d10_shader_resource_view_Release,
2069 /* ID3D10DeviceChild methods */
2070 d3d10_shader_resource_view_GetDevice,
2071 d3d10_shader_resource_view_GetPrivateData,
2072 d3d10_shader_resource_view_SetPrivateData,
2073 d3d10_shader_resource_view_SetPrivateDataInterface,
2074 /* ID3D10View methods */
2075 d3d10_shader_resource_view_GetResource,
2076 /* ID3D10ShaderResourceView methods */
2077 d3d10_shader_resource_view_GetDesc,
2078 /* ID3D10ShaderResourceView1 methods */
2079 d3d10_shader_resource_view_GetDesc1,
2082 static void STDMETHODCALLTYPE d3d_shader_resource_view_wined3d_object_destroyed(void *parent)
2084 struct d3d_shader_resource_view *view = parent;
2086 wined3d_private_store_cleanup(&view->private_store);
2087 free(parent);
2090 static const struct wined3d_parent_ops d3d_shader_resource_view_wined3d_parent_ops =
2092 d3d_shader_resource_view_wined3d_object_destroyed,
2095 static unsigned int wined3d_view_flags_from_d3d11_bufferex_flags(unsigned int d3d11_flags)
2097 unsigned int wined3d_flags = d3d11_flags & WINED3D_VIEW_BUFFER_RAW;
2099 if (d3d11_flags != wined3d_flags)
2100 FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags);
2102 return wined3d_flags;
2105 static HRESULT wined3d_shader_resource_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
2106 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
2108 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
2109 wined3d_desc->flags = 0;
2111 switch (desc->ViewDimension)
2113 case D3D11_SRV_DIMENSION_BUFFER:
2114 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement;
2115 wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements;
2116 break;
2118 case D3D11_SRV_DIMENSION_TEXTURE1D:
2119 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MostDetailedMip;
2120 wined3d_desc->u.texture.level_count = desc->u.Texture1D.MipLevels;
2121 wined3d_desc->u.texture.layer_idx = 0;
2122 wined3d_desc->u.texture.layer_count = 1;
2123 break;
2125 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
2126 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2127 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MostDetailedMip;
2128 wined3d_desc->u.texture.level_count = desc->u.Texture1DArray.MipLevels;
2129 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
2130 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
2131 break;
2133 case D3D11_SRV_DIMENSION_TEXTURE2D:
2134 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MostDetailedMip;
2135 wined3d_desc->u.texture.level_count = desc->u.Texture2D.MipLevels;
2136 wined3d_desc->u.texture.layer_idx = 0;
2137 wined3d_desc->u.texture.layer_count = 1;
2138 break;
2140 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
2141 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2142 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MostDetailedMip;
2143 wined3d_desc->u.texture.level_count = desc->u.Texture2DArray.MipLevels;
2144 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
2145 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
2146 break;
2148 case D3D11_SRV_DIMENSION_TEXTURE2DMS:
2149 wined3d_desc->u.texture.level_idx = 0;
2150 wined3d_desc->u.texture.level_count = 1;
2151 wined3d_desc->u.texture.layer_idx = 0;
2152 wined3d_desc->u.texture.layer_count = 1;
2153 break;
2155 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
2156 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2157 wined3d_desc->u.texture.level_idx = 0;
2158 wined3d_desc->u.texture.level_count = 1;
2159 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
2160 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
2161 break;
2163 case D3D11_SRV_DIMENSION_TEXTURE3D:
2164 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MostDetailedMip;
2165 wined3d_desc->u.texture.level_count = desc->u.Texture3D.MipLevels;
2166 wined3d_desc->u.texture.layer_idx = 0;
2167 wined3d_desc->u.texture.layer_count = 1;
2168 break;
2170 case D3D11_SRV_DIMENSION_TEXTURECUBE:
2171 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE;
2172 wined3d_desc->u.texture.level_idx = desc->u.TextureCube.MostDetailedMip;
2173 wined3d_desc->u.texture.level_count = desc->u.TextureCube.MipLevels;
2174 wined3d_desc->u.texture.layer_idx = 0;
2175 wined3d_desc->u.texture.layer_count = 6;
2176 break;
2178 case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
2179 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY;
2180 wined3d_desc->u.texture.level_idx = desc->u.TextureCubeArray.MostDetailedMip;
2181 wined3d_desc->u.texture.level_count = desc->u.TextureCubeArray.MipLevels;
2182 wined3d_desc->u.texture.layer_idx = desc->u.TextureCubeArray.First2DArrayFace;
2183 wined3d_desc->u.texture.layer_count = 6 * desc->u.TextureCubeArray.NumCubes;
2184 break;
2186 case D3D11_SRV_DIMENSION_BUFFEREX:
2187 wined3d_desc->flags = wined3d_view_flags_from_d3d11_bufferex_flags(desc->u.BufferEx.Flags);
2188 wined3d_desc->u.buffer.start_idx = desc->u.BufferEx.FirstElement;
2189 wined3d_desc->u.buffer.count = desc->u.BufferEx.NumElements;
2190 break;
2192 default:
2193 WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension);
2194 return E_FAIL;
2197 return S_OK;
2200 static HRESULT d3d_shader_resource_view_init(struct d3d_shader_resource_view *view, struct d3d_device *device,
2201 ID3D11Resource *resource, const D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
2203 struct wined3d_resource *wined3d_resource;
2204 struct wined3d_view_desc wined3d_desc;
2205 HRESULT hr;
2207 view->ID3D11ShaderResourceView_iface.lpVtbl = &d3d11_shader_resource_view_vtbl;
2208 view->ID3D10ShaderResourceView1_iface.lpVtbl = &d3d10_shader_resource_view_vtbl;
2209 view->refcount = 1;
2211 if (!desc)
2213 hr = set_srv_desc_from_resource(&view->desc, resource);
2215 else
2217 view->desc = *desc;
2218 hr = normalize_srv_desc(&view->desc, resource);
2220 if (FAILED(hr))
2221 return hr;
2223 if (FAILED(hr = wined3d_shader_resource_view_desc_from_d3d11(&wined3d_desc, &view->desc)))
2224 return hr;
2226 wined3d_mutex_lock();
2227 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
2229 wined3d_mutex_unlock();
2230 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
2231 return E_FAIL;
2234 if (FAILED(hr = wined3d_shader_resource_view_create(&wined3d_desc, wined3d_resource,
2235 view, &d3d_shader_resource_view_wined3d_parent_ops, &view->wined3d_view)))
2237 wined3d_mutex_unlock();
2238 WARN("Failed to create wined3d shader resource view, hr %#lx.\n", hr);
2239 return hr;
2242 wined3d_private_store_init(&view->private_store);
2243 wined3d_mutex_unlock();
2244 view->resource = resource;
2245 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
2247 return S_OK;
2250 HRESULT d3d_shader_resource_view_create(struct d3d_device *device, ID3D11Resource *resource,
2251 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, struct d3d_shader_resource_view **view)
2253 struct d3d_shader_resource_view *object;
2254 HRESULT hr;
2256 if (!(object = calloc(1, sizeof(*object))))
2257 return E_OUTOFMEMORY;
2259 if (FAILED(hr = d3d_shader_resource_view_init(object, device, resource, desc)))
2261 WARN("Failed to initialise shader resource view, hr %#lx.\n", hr);
2262 free(object);
2263 return hr;
2266 TRACE("Created shader resource view %p.\n", object);
2267 *view = object;
2269 return S_OK;
2272 struct d3d_shader_resource_view *unsafe_impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface)
2274 if (!iface)
2275 return NULL;
2276 assert(iface->lpVtbl == &d3d11_shader_resource_view_vtbl);
2277 return impl_from_ID3D11ShaderResourceView(iface);
2280 struct d3d_shader_resource_view *unsafe_impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView *iface)
2282 if (!iface)
2283 return NULL;
2284 assert(iface->lpVtbl == (ID3D10ShaderResourceViewVtbl *)&d3d10_shader_resource_view_vtbl);
2285 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface);
2288 /* ID3D11UnorderedAccessView methods */
2290 static inline struct d3d11_unordered_access_view *impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface)
2292 return CONTAINING_RECORD(iface, struct d3d11_unordered_access_view, ID3D11UnorderedAccessView_iface);
2295 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_QueryInterface(ID3D11UnorderedAccessView *iface,
2296 REFIID riid, void **object)
2298 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
2300 if (IsEqualGUID(riid, &IID_ID3D11UnorderedAccessView)
2301 || IsEqualGUID(riid, &IID_ID3D11View)
2302 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
2303 || IsEqualGUID(riid, &IID_IUnknown))
2305 ID3D11UnorderedAccessView_AddRef(*object = iface);
2306 return S_OK;
2309 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
2311 *object = NULL;
2312 return E_NOINTERFACE;
2315 static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_AddRef(ID3D11UnorderedAccessView *iface)
2317 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2318 ULONG refcount = InterlockedIncrement(&view->refcount);
2320 TRACE("%p increasing refcount to %lu.\n", view, refcount);
2322 if (refcount == 1)
2324 ID3D11Device2_AddRef(view->device);
2325 wined3d_unordered_access_view_incref(view->wined3d_view);
2328 return refcount;
2331 static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_Release(ID3D11UnorderedAccessView *iface)
2333 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2334 ULONG refcount = InterlockedDecrement(&view->refcount);
2336 TRACE("%p decreasing refcount to %lu.\n", view, refcount);
2338 if (!refcount)
2340 ID3D11Device2 *device = view->device;
2341 wined3d_unordered_access_view_decref(view->wined3d_view);
2342 ID3D11Device2_Release(device);
2345 return refcount;
2348 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDevice(ID3D11UnorderedAccessView *iface,
2349 ID3D11Device **device)
2351 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2353 TRACE("iface %p, device %p.\n", iface, device);
2355 ID3D11Device_AddRef(*device = (ID3D11Device *)view->device);
2358 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_GetPrivateData(ID3D11UnorderedAccessView *iface,
2359 REFGUID guid, UINT *data_size, void *data)
2361 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2363 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2365 return d3d_get_private_data(&view->private_store, guid, data_size, data);
2368 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateData(ID3D11UnorderedAccessView *iface,
2369 REFGUID guid, UINT data_size, const void *data)
2371 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2373 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2375 return d3d_set_private_data(&view->private_store, guid, data_size, data);
2378 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateDataInterface(ID3D11UnorderedAccessView *iface,
2379 REFGUID guid, const IUnknown *data)
2381 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2383 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2385 return d3d_set_private_data_interface(&view->private_store, guid, data);
2388 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetResource(ID3D11UnorderedAccessView *iface,
2389 ID3D11Resource **resource)
2391 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2393 TRACE("iface %p, resource %p.\n", iface, resource);
2395 ID3D11Resource_AddRef(*resource = view->resource);
2398 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDesc(ID3D11UnorderedAccessView *iface,
2399 D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2401 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2403 TRACE("iface %p, desc %p.\n", iface, desc);
2405 *desc = view->desc;
2408 static const struct ID3D11UnorderedAccessViewVtbl d3d11_unordered_access_view_vtbl =
2410 /* IUnknown methods */
2411 d3d11_unordered_access_view_QueryInterface,
2412 d3d11_unordered_access_view_AddRef,
2413 d3d11_unordered_access_view_Release,
2414 /* ID3D11DeviceChild methods */
2415 d3d11_unordered_access_view_GetDevice,
2416 d3d11_unordered_access_view_GetPrivateData,
2417 d3d11_unordered_access_view_SetPrivateData,
2418 d3d11_unordered_access_view_SetPrivateDataInterface,
2419 /* ID3D11View methods */
2420 d3d11_unordered_access_view_GetResource,
2421 /* ID3D11UnorderedAccessView methods */
2422 d3d11_unordered_access_view_GetDesc,
2425 static void STDMETHODCALLTYPE d3d11_unordered_access_view_wined3d_object_destroyed(void *parent)
2427 struct d3d11_unordered_access_view *view = parent;
2429 wined3d_private_store_cleanup(&view->private_store);
2430 free(parent);
2433 static const struct wined3d_parent_ops d3d11_unordered_access_view_wined3d_parent_ops =
2435 d3d11_unordered_access_view_wined3d_object_destroyed,
2438 static unsigned int wined3d_view_flags_from_d3d11_buffer_uav_flags(unsigned int d3d11_flags)
2440 unsigned int wined3d_flags = d3d11_flags & (WINED3D_VIEW_BUFFER_RAW
2441 | WINED3D_VIEW_BUFFER_APPEND | WINED3D_VIEW_BUFFER_COUNTER);
2443 if (d3d11_flags != wined3d_flags)
2444 FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags);
2446 return wined3d_flags;
2449 static HRESULT wined3d_unordered_access_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
2450 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2452 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
2454 wined3d_desc->flags = 0;
2455 wined3d_desc->u.texture.level_count = 1;
2456 switch (desc->ViewDimension)
2458 case D3D11_UAV_DIMENSION_BUFFER:
2459 wined3d_desc->flags = wined3d_view_flags_from_d3d11_buffer_uav_flags(desc->u.Buffer.Flags);
2460 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.FirstElement;
2461 wined3d_desc->u.buffer.count = desc->u.Buffer.NumElements;
2462 break;
2464 case D3D11_UAV_DIMENSION_TEXTURE1D:
2465 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
2466 wined3d_desc->u.texture.layer_idx = 0;
2467 wined3d_desc->u.texture.layer_count = 1;
2468 break;
2470 case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
2471 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2472 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
2473 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
2474 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
2475 break;
2477 case D3D11_UAV_DIMENSION_TEXTURE2D:
2478 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
2479 wined3d_desc->u.texture.layer_idx = 0;
2480 wined3d_desc->u.texture.layer_count = 1;
2481 break;
2483 case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
2484 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2485 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
2486 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
2487 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
2488 break;
2490 case D3D11_UAV_DIMENSION_TEXTURE3D:
2491 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice;
2492 wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice;
2493 wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize;
2494 break;
2496 default:
2497 WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension);
2498 return E_FAIL;
2501 return S_OK;
2504 static HRESULT d3d11_unordered_access_view_init(struct d3d11_unordered_access_view *view,
2505 struct d3d_device *device, ID3D11Resource *resource, const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2507 struct wined3d_resource *wined3d_resource;
2508 struct wined3d_view_desc wined3d_desc;
2509 HRESULT hr;
2511 view->ID3D11UnorderedAccessView_iface.lpVtbl = &d3d11_unordered_access_view_vtbl;
2512 view->refcount = 1;
2514 if (!desc)
2516 hr = set_uav_desc_from_resource(&view->desc, resource);
2518 else
2520 view->desc = *desc;
2521 hr = normalize_uav_desc(&view->desc, resource);
2523 if (FAILED(hr))
2524 return hr;
2526 if (FAILED(hr = wined3d_unordered_access_view_desc_from_d3d11(&wined3d_desc, &view->desc)))
2527 return hr;
2529 wined3d_mutex_lock();
2530 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
2532 wined3d_mutex_unlock();
2533 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
2534 return E_FAIL;
2537 if (FAILED(hr = wined3d_unordered_access_view_create(&wined3d_desc, wined3d_resource,
2538 view, &d3d11_unordered_access_view_wined3d_parent_ops, &view->wined3d_view)))
2540 wined3d_mutex_unlock();
2541 WARN("Failed to create wined3d unordered access view, hr %#lx.\n", hr);
2542 return hr;
2545 wined3d_private_store_init(&view->private_store);
2546 wined3d_mutex_unlock();
2547 view->resource = resource;
2548 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
2550 return S_OK;
2553 HRESULT d3d11_unordered_access_view_create(struct d3d_device *device, ID3D11Resource *resource,
2554 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, struct d3d11_unordered_access_view **view)
2556 struct d3d11_unordered_access_view *object;
2557 HRESULT hr;
2559 if (!(object = calloc(1, sizeof(*object))))
2560 return E_OUTOFMEMORY;
2562 if (FAILED(hr = d3d11_unordered_access_view_init(object, device, resource, desc)))
2564 WARN("Failed to initialise unordered access view, hr %#lx.\n", hr);
2565 free(object);
2566 return hr;
2569 TRACE("Created unordered access view %p.\n", object);
2570 *view = object;
2572 return S_OK;
2575 struct d3d11_unordered_access_view *unsafe_impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface)
2577 if (!iface)
2578 return NULL;
2579 assert(iface->lpVtbl == &d3d11_unordered_access_view_vtbl);
2581 return impl_from_ID3D11UnorderedAccessView(iface);