d3d11: Disallow 0-sized buffer shader resource views.
[wine.git] / dlls / d3d11 / view.c
blob034a4940b0c5eaba44bbac08583f6732abf8819d
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 #include "config.h"
21 #include "wine/port.h"
23 #define NONAMELESSUNION
24 #include "d3d11_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
28 static HRESULT set_dsv_desc_from_resource(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource)
30 D3D11_RESOURCE_DIMENSION dimension;
32 ID3D11Resource_GetType(resource, &dimension);
34 desc->Flags = 0;
36 switch (dimension)
38 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
40 D3D11_TEXTURE1D_DESC texture_desc;
41 ID3D11Texture1D *texture;
43 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture)))
45 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n");
46 return E_INVALIDARG;
49 ID3D11Texture1D_GetDesc(texture, &texture_desc);
50 ID3D11Texture1D_Release(texture);
52 desc->Format = texture_desc.Format;
53 if (texture_desc.ArraySize == 1)
55 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
56 desc->u.Texture1D.MipSlice = 0;
58 else
60 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
61 desc->u.Texture1DArray.MipSlice = 0;
62 desc->u.Texture1DArray.FirstArraySlice = 0;
63 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
66 return S_OK;
69 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
71 D3D11_TEXTURE2D_DESC texture_desc;
72 ID3D11Texture2D *texture;
74 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
76 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
77 return E_INVALIDARG;
80 ID3D11Texture2D_GetDesc(texture, &texture_desc);
81 ID3D11Texture2D_Release(texture);
83 desc->Format = texture_desc.Format;
84 if (texture_desc.ArraySize == 1)
86 if (texture_desc.SampleDesc.Count == 1)
88 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
89 desc->u.Texture2D.MipSlice = 0;
91 else
93 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
96 else
98 if (texture_desc.SampleDesc.Count == 1)
100 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
101 desc->u.Texture2DArray.MipSlice = 0;
102 desc->u.Texture2DArray.FirstArraySlice = 0;
103 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
105 else
107 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
108 desc->u.Texture2DMSArray.FirstArraySlice = 0;
109 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
113 return S_OK;
116 default:
117 ERR("Unhandled resource dimension %#x.\n", dimension);
118 case D3D11_RESOURCE_DIMENSION_BUFFER:
119 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
120 return E_INVALIDARG;
124 static HRESULT normalize_dsv_desc(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource)
126 D3D11_RESOURCE_DIMENSION dimension;
127 unsigned int layer_count;
128 DXGI_FORMAT format;
130 ID3D11Resource_GetType(resource, &dimension);
131 switch (dimension)
133 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
135 if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1D
136 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1DARRAY)
138 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
139 return E_INVALIDARG;
142 FIXME("Unhandled 1D texture resource.\n");
143 return S_OK;
146 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
148 const struct d3d_texture2d *texture;
150 if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2D
151 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DARRAY
152 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMS
153 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY)
155 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
156 return E_INVALIDARG;
159 if (!(texture = unsafe_impl_from_ID3D11Texture2D((ID3D11Texture2D *)resource)))
161 ERR("Cannot get implementation from ID3D11Texture2D.\n");
162 return E_FAIL;
165 format = texture->desc.Format;
166 layer_count = texture->desc.ArraySize;
167 break;
170 case D3D11_RESOURCE_DIMENSION_BUFFER:
171 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
172 WARN("Invalid resource dimension %#x.\n", dimension);
173 return E_INVALIDARG;
175 default:
176 ERR("Unhandled resource dimension %#x.\n", dimension);
177 return E_FAIL;
180 if (desc->Format == DXGI_FORMAT_UNKNOWN)
181 desc->Format = format;
183 switch (desc->ViewDimension)
185 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
186 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
187 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
188 break;
190 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
191 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
192 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
193 break;
195 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
196 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
197 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
198 break;
200 default:
201 break;
204 return S_OK;
207 static HRESULT set_rtv_desc_from_resource(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource)
209 D3D11_RESOURCE_DIMENSION dimension;
210 HRESULT hr;
212 ID3D11Resource_GetType(resource, &dimension);
214 switch (dimension)
216 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
218 ID3D11Texture1D *texture;
219 D3D11_TEXTURE1D_DESC texture_desc;
221 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture);
222 if (FAILED(hr))
224 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D?\n");
225 return E_INVALIDARG;
228 ID3D11Texture1D_GetDesc(texture, &texture_desc);
229 ID3D11Texture1D_Release(texture);
231 desc->Format = texture_desc.Format;
232 if (texture_desc.ArraySize == 1)
234 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
235 desc->u.Texture1D.MipSlice = 0;
237 else
239 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
240 desc->u.Texture1DArray.MipSlice = 0;
241 desc->u.Texture1DArray.FirstArraySlice = 0;
242 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
245 return S_OK;
248 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
250 ID3D11Texture2D *texture;
251 D3D11_TEXTURE2D_DESC texture_desc;
253 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture);
254 if (FAILED(hr))
256 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D?\n");
257 return E_INVALIDARG;
260 ID3D11Texture2D_GetDesc(texture, &texture_desc);
261 ID3D11Texture2D_Release(texture);
263 desc->Format = texture_desc.Format;
264 if (texture_desc.ArraySize == 1)
266 if (texture_desc.SampleDesc.Count == 1)
268 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
269 desc->u.Texture2D.MipSlice = 0;
271 else
273 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
276 else
278 if (texture_desc.SampleDesc.Count == 1)
280 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
281 desc->u.Texture2DArray.MipSlice = 0;
282 desc->u.Texture2DArray.FirstArraySlice = 0;
283 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
285 else
287 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
288 desc->u.Texture2DMSArray.FirstArraySlice = 0;
289 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
293 return S_OK;
296 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
298 ID3D11Texture3D *texture;
299 D3D11_TEXTURE3D_DESC texture_desc;
301 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture);
302 if (FAILED(hr))
304 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D?\n");
305 return E_INVALIDARG;
308 ID3D11Texture3D_GetDesc(texture, &texture_desc);
309 ID3D11Texture3D_Release(texture);
311 desc->Format = texture_desc.Format;
312 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
313 desc->u.Texture3D.MipSlice = 0;
314 desc->u.Texture3D.FirstWSlice = 0;
315 desc->u.Texture3D.WSize = texture_desc.Depth;
317 return S_OK;
320 default:
321 FIXME("Unhandled resource dimension %#x.\n", dimension);
322 return E_INVALIDARG;
326 static HRESULT normalize_rtv_desc(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource)
328 D3D11_RESOURCE_DIMENSION dimension;
329 unsigned int layer_count;
330 DXGI_FORMAT format;
332 ID3D11Resource_GetType(resource, &dimension);
333 switch (dimension)
335 case D3D11_RESOURCE_DIMENSION_BUFFER:
337 if (desc->ViewDimension != D3D11_RTV_DIMENSION_BUFFER)
339 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
340 return E_INVALIDARG;
342 return S_OK;
345 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
347 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1D
348 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1DARRAY)
350 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
351 return E_INVALIDARG;
354 FIXME("Unhandled 1D texture resource.\n");
355 return S_OK;
358 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
360 const struct d3d_texture2d *texture;
362 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2D
363 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DARRAY
364 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMS
365 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY)
367 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
368 return E_INVALIDARG;
371 if (!(texture = unsafe_impl_from_ID3D11Texture2D((ID3D11Texture2D *)resource)))
373 ERR("Cannot get implementation from ID3D11Texture2D.\n");
374 return E_FAIL;
377 format = texture->desc.Format;
378 layer_count = texture->desc.ArraySize;
379 break;
382 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
384 const struct d3d_texture3d *texture;
386 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE3D)
388 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
389 return E_INVALIDARG;
392 if (!(texture = unsafe_impl_from_ID3D11Texture3D((ID3D11Texture3D *)resource)))
394 ERR("Cannot get implementation from ID3D11Texture3D.\n");
395 return E_FAIL;
398 format = texture->desc.Format;
399 layer_count = texture->desc.Depth;
400 break;
403 default:
404 ERR("Unhandled resource dimension %#x.\n", dimension);
405 return E_FAIL;
408 if (desc->Format == DXGI_FORMAT_UNKNOWN)
409 desc->Format = format;
411 switch (desc->ViewDimension)
413 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
414 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
415 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
416 break;
418 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
419 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
420 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
421 break;
423 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
424 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
425 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
426 break;
428 case D3D11_RTV_DIMENSION_TEXTURE3D:
429 layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice);
430 if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count)
431 desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice;
432 break;
434 default:
435 break;
438 return S_OK;
441 static HRESULT set_srv_desc_from_resource(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource)
443 D3D11_RESOURCE_DIMENSION dimension;
445 ID3D11Resource_GetType(resource, &dimension);
447 switch (dimension)
449 case D3D11_RESOURCE_DIMENSION_BUFFER:
451 D3D11_BUFFER_DESC buffer_desc;
452 ID3D11Buffer *buffer;
454 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer)))
456 ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n");
457 return E_INVALIDARG;
460 ID3D11Buffer_GetDesc(buffer, &buffer_desc);
461 ID3D11Buffer_Release(buffer);
463 if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
465 desc->Format = DXGI_FORMAT_UNKNOWN;
466 desc->ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
467 desc->u.Buffer.u1.FirstElement = 0;
468 desc->u.Buffer.u2.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
469 return S_OK;
472 return E_INVALIDARG;
475 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
477 D3D11_TEXTURE1D_DESC texture_desc;
478 ID3D11Texture1D *texture;
480 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture)))
482 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n");
483 return E_INVALIDARG;
486 ID3D11Texture1D_GetDesc(texture, &texture_desc);
487 ID3D11Texture1D_Release(texture);
489 desc->Format = texture_desc.Format;
490 if (texture_desc.ArraySize == 1)
492 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
493 desc->u.Texture1D.MostDetailedMip = 0;
494 desc->u.Texture1D.MipLevels = texture_desc.MipLevels;
496 else
498 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
499 desc->u.Texture1DArray.MostDetailedMip = 0;
500 desc->u.Texture1DArray.MipLevels = texture_desc.MipLevels;
501 desc->u.Texture1DArray.FirstArraySlice = 0;
502 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
505 return S_OK;
508 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
510 D3D11_TEXTURE2D_DESC texture_desc;
511 ID3D11Texture2D *texture;
513 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
515 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
516 return E_INVALIDARG;
519 ID3D11Texture2D_GetDesc(texture, &texture_desc);
520 ID3D11Texture2D_Release(texture);
522 desc->Format = texture_desc.Format;
523 if (texture_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
525 if (texture_desc.ArraySize >= 12)
527 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
528 desc->u.TextureCubeArray.MostDetailedMip = 0;
529 desc->u.TextureCubeArray.MipLevels = texture_desc.MipLevels;
530 desc->u.TextureCubeArray.First2DArrayFace = 0;
531 desc->u.TextureCubeArray.NumCubes = texture_desc.ArraySize / 6;
533 else
535 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
536 desc->u.TextureCube.MostDetailedMip = 0;
537 desc->u.TextureCube.MipLevels = texture_desc.MipLevels;
540 else if (texture_desc.ArraySize == 1)
542 if (texture_desc.SampleDesc.Count == 1)
544 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
545 desc->u.Texture2D.MostDetailedMip = 0;
546 desc->u.Texture2D.MipLevels = texture_desc.MipLevels;
548 else
550 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
553 else
555 if (texture_desc.SampleDesc.Count == 1)
557 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
558 desc->u.Texture2DArray.MostDetailedMip = 0;
559 desc->u.Texture2DArray.MipLevels = texture_desc.MipLevels;
560 desc->u.Texture2DArray.FirstArraySlice = 0;
561 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
563 else
565 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
566 desc->u.Texture2DMSArray.FirstArraySlice = 0;
567 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
571 return S_OK;
574 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
576 D3D11_TEXTURE3D_DESC texture_desc;
577 ID3D11Texture3D *texture;
579 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture)))
581 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n");
582 return E_INVALIDARG;
585 ID3D11Texture3D_GetDesc(texture, &texture_desc);
586 ID3D11Texture3D_Release(texture);
588 desc->Format = texture_desc.Format;
589 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
590 desc->u.Texture3D.MostDetailedMip = 0;
591 desc->u.Texture3D.MipLevels = texture_desc.MipLevels;
593 return S_OK;
596 default:
597 ERR("Unhandled resource dimension %#x.\n", dimension);
598 return E_INVALIDARG;
602 static HRESULT normalize_srv_desc(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource)
604 unsigned int miplevel_count, layer_count;
605 D3D11_RESOURCE_DIMENSION dimension;
606 DXGI_FORMAT format;
608 ID3D11Resource_GetType(resource, &dimension);
609 switch (dimension)
611 case D3D11_RESOURCE_DIMENSION_BUFFER:
613 if (desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFER
614 && desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX)
616 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
617 return E_INVALIDARG;
619 if (!desc->u.Buffer.u2.NumElements)
621 WARN("Zero sized buffer view.\n");
622 return E_INVALIDARG;
624 return S_OK;
627 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
629 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1D
630 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1DARRAY)
632 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
633 return E_INVALIDARG;
636 FIXME("Unhandled 1D texture resource.\n");
637 return S_OK;
640 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
642 const struct d3d_texture2d *texture;
644 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2D
645 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DARRAY
646 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMS
647 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY
648 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBE
649 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBEARRAY)
651 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
652 return E_INVALIDARG;
655 if (!(texture = unsafe_impl_from_ID3D11Texture2D((ID3D11Texture2D *)resource)))
657 ERR("Cannot get implementation from ID3D11Texture2D.\n");
658 return E_FAIL;
661 format = texture->desc.Format;
662 miplevel_count = texture->desc.MipLevels;
663 layer_count = texture->desc.ArraySize;
664 break;
667 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
669 const struct d3d_texture3d *texture;
671 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE3D)
673 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
674 return E_INVALIDARG;
677 if (!(texture = unsafe_impl_from_ID3D11Texture3D((ID3D11Texture3D *)resource)))
679 ERR("Cannot get implementation from ID3D11Texture3D.\n");
680 return E_FAIL;
683 format = texture->desc.Format;
684 miplevel_count = texture->desc.MipLevels;
685 layer_count = 1;
686 break;
689 default:
690 ERR("Unhandled resource dimension %#x.\n", dimension);
691 return E_FAIL;
694 if (desc->Format == DXGI_FORMAT_UNKNOWN)
695 desc->Format = format;
697 switch (desc->ViewDimension)
699 case D3D11_SRV_DIMENSION_TEXTURE1D:
700 if (desc->u.Texture1D.MipLevels == ~0u && desc->u.Texture1D.MostDetailedMip < miplevel_count)
701 desc->u.Texture1D.MipLevels = miplevel_count - desc->u.Texture1D.MostDetailedMip;
702 break;
704 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
705 if (desc->u.Texture1DArray.MipLevels == ~0u && desc->u.Texture1DArray.MostDetailedMip < miplevel_count)
706 desc->u.Texture1DArray.MipLevels = miplevel_count - desc->u.Texture1DArray.MostDetailedMip;
707 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < miplevel_count)
708 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
709 break;
711 case D3D11_SRV_DIMENSION_TEXTURE2D:
712 if (desc->u.Texture2D.MipLevels == ~0u && desc->u.Texture2D.MostDetailedMip < miplevel_count)
713 desc->u.Texture2D.MipLevels = miplevel_count - desc->u.Texture2D.MostDetailedMip;
714 break;
716 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
717 if (desc->u.Texture2DArray.MipLevels == ~0u && desc->u.Texture2DArray.MostDetailedMip < miplevel_count)
718 desc->u.Texture2DArray.MipLevels = miplevel_count - desc->u.Texture2DArray.MostDetailedMip;
719 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
720 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
721 break;
723 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
724 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
725 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
726 break;
728 case D3D11_SRV_DIMENSION_TEXTURE3D:
729 if (desc->u.Texture3D.MipLevels == ~0u && desc->u.Texture3D.MostDetailedMip < miplevel_count)
730 desc->u.Texture3D.MipLevels = miplevel_count - desc->u.Texture3D.MostDetailedMip;
731 break;
733 case D3D11_SRV_DIMENSION_TEXTURECUBE:
734 if (desc->u.TextureCube.MipLevels == ~0u && desc->u.TextureCube.MostDetailedMip < miplevel_count)
735 desc->u.TextureCube.MipLevels = miplevel_count - desc->u.TextureCube.MostDetailedMip;
736 break;
738 case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
739 if (desc->u.TextureCubeArray.MipLevels == ~0u && desc->u.TextureCubeArray.MostDetailedMip < miplevel_count)
740 desc->u.TextureCubeArray.MipLevels = miplevel_count - desc->u.TextureCubeArray.MostDetailedMip;
741 if (desc->u.TextureCubeArray.NumCubes == ~0u && desc->u.TextureCubeArray.First2DArrayFace < layer_count)
742 desc->u.TextureCubeArray.NumCubes = (layer_count - desc->u.TextureCubeArray.First2DArrayFace) / 6;
743 break;
745 default:
746 break;
749 return S_OK;
752 static HRESULT set_uav_desc_from_resource(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource)
754 D3D11_RESOURCE_DIMENSION dimension;
756 ID3D11Resource_GetType(resource, &dimension);
758 switch (dimension)
760 case D3D11_RESOURCE_DIMENSION_BUFFER:
762 D3D11_BUFFER_DESC buffer_desc;
763 ID3D11Buffer *buffer;
765 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer)))
767 ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n");
768 return E_INVALIDARG;
771 ID3D11Buffer_GetDesc(buffer, &buffer_desc);
772 ID3D11Buffer_Release(buffer);
774 if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
776 desc->Format = DXGI_FORMAT_UNKNOWN;
777 desc->ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
778 desc->u.Buffer.FirstElement = 0;
779 desc->u.Buffer.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
780 desc->u.Buffer.Flags = 0;
781 return S_OK;
784 return E_INVALIDARG;
787 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
789 D3D11_TEXTURE2D_DESC texture_desc;
790 ID3D11Texture2D *texture;
792 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
794 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
795 return E_INVALIDARG;
798 ID3D11Texture2D_GetDesc(texture, &texture_desc);
799 ID3D11Texture2D_Release(texture);
801 if (texture_desc.SampleDesc.Count != 1)
803 WARN("Trying to create view for multisample texture.\n");
804 return E_INVALIDARG;
807 desc->Format = texture_desc.Format;
808 if (texture_desc.ArraySize == 1)
810 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
811 desc->u.Texture2D.MipSlice = 0;
813 else
815 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
816 desc->u.Texture2DArray.MipSlice = 0;
817 desc->u.Texture2DArray.FirstArraySlice = 0;
818 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
821 return S_OK;
824 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
826 D3D11_TEXTURE3D_DESC texture_desc;
827 ID3D11Texture3D *texture;
829 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture)))
831 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n");
832 return E_INVALIDARG;
835 ID3D11Texture3D_GetDesc(texture, &texture_desc);
836 ID3D11Texture3D_Release(texture);
838 desc->Format = texture_desc.Format;
839 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
840 desc->u.Texture3D.MipSlice = 0;
841 desc->u.Texture3D.FirstWSlice = 0;
842 desc->u.Texture3D.WSize = texture_desc.Depth;
844 return S_OK;
847 default:
848 FIXME("Unhandled resource dimension %#x.\n", dimension);
849 return E_INVALIDARG;
853 static HRESULT normalize_uav_desc(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource)
855 D3D11_RESOURCE_DIMENSION dimension;
856 unsigned int layer_count;
857 DXGI_FORMAT format;
859 ID3D11Resource_GetType(resource, &dimension);
860 switch (dimension)
862 case D3D11_RESOURCE_DIMENSION_BUFFER:
864 if (desc->ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
866 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
867 return E_INVALIDARG;
869 return S_OK;
872 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
874 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1D
875 && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1DARRAY)
877 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
878 return E_INVALIDARG;
881 FIXME("Unhandled 1D texture resource.\n");
882 return S_OK;
885 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
887 const struct d3d_texture2d *texture;
889 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2D
890 && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2DARRAY)
892 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
893 return E_INVALIDARG;
896 if (!(texture = unsafe_impl_from_ID3D11Texture2D((ID3D11Texture2D *)resource)))
898 ERR("Cannot get implementation from ID3D11Texture2D.\n");
899 return E_FAIL;
902 format = texture->desc.Format;
903 layer_count = texture->desc.ArraySize;
904 break;
907 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
909 const struct d3d_texture3d *texture;
911 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE3D)
913 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
914 return E_INVALIDARG;
917 if (!(texture = unsafe_impl_from_ID3D11Texture3D((ID3D11Texture3D *)resource)))
919 ERR("Cannot get implementation from ID3D11Texture3D.\n");
920 return E_FAIL;
923 format = texture->desc.Format;
924 layer_count = texture->desc.Depth;
925 break;
928 default:
929 ERR("Unhandled resource dimension %#x.\n", dimension);
930 return E_FAIL;
933 if (desc->Format == DXGI_FORMAT_UNKNOWN)
934 desc->Format = format;
936 switch (desc->ViewDimension)
938 case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
939 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
940 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
941 break;
943 case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
944 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
945 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
946 break;
948 case D3D11_UAV_DIMENSION_TEXTURE3D:
949 layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice);
950 if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count)
951 desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice;
952 break;
954 default:
955 break;
958 return S_OK;
961 /* ID3D11DepthStencilView methods */
963 static inline struct d3d_depthstencil_view *impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface)
965 return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D11DepthStencilView_iface);
968 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_QueryInterface(ID3D11DepthStencilView *iface,
969 REFIID riid, void **object)
971 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
973 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
975 if (IsEqualGUID(riid, &IID_ID3D11DepthStencilView)
976 || IsEqualGUID(riid, &IID_ID3D11View)
977 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
978 || IsEqualGUID(riid, &IID_IUnknown))
980 ID3D11DepthStencilView_AddRef(iface);
981 *object = iface;
982 return S_OK;
985 if (IsEqualGUID(riid, &IID_ID3D10DepthStencilView)
986 || IsEqualGUID(riid, &IID_ID3D10View)
987 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
989 ID3D10DepthStencilView_AddRef(&view->ID3D10DepthStencilView_iface);
990 *object = &view->ID3D10DepthStencilView_iface;
991 return S_OK;
994 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
996 *object = NULL;
997 return E_NOINTERFACE;
1000 static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_AddRef(ID3D11DepthStencilView *iface)
1002 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1003 ULONG refcount = InterlockedIncrement(&view->refcount);
1005 TRACE("%p increasing refcount to %u.\n", view, refcount);
1007 if (refcount == 1)
1009 ID3D11Device_AddRef(view->device);
1010 wined3d_mutex_lock();
1011 wined3d_rendertarget_view_incref(view->wined3d_view);
1012 wined3d_mutex_unlock();
1015 return refcount;
1018 static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_Release(ID3D11DepthStencilView *iface)
1020 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1021 ULONG refcount = InterlockedDecrement(&view->refcount);
1023 TRACE("%p decreasing refcount to %u.\n", view, refcount);
1025 if (!refcount)
1027 ID3D11Device *device = view->device;
1029 wined3d_mutex_lock();
1030 wined3d_rendertarget_view_decref(view->wined3d_view);
1031 wined3d_mutex_unlock();
1033 ID3D11Device_Release(device);
1036 return refcount;
1039 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDevice(ID3D11DepthStencilView *iface,
1040 ID3D11Device **device)
1042 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1044 TRACE("iface %p, device %p.\n", iface, device);
1046 *device = view->device;
1047 ID3D11Device_AddRef(*device);
1050 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_GetPrivateData(ID3D11DepthStencilView *iface,
1051 REFGUID guid, UINT *data_size, void *data)
1053 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1055 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1057 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1060 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateData(ID3D11DepthStencilView *iface,
1061 REFGUID guid, UINT data_size, const void *data)
1063 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1065 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1067 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1070 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateDataInterface(ID3D11DepthStencilView *iface,
1071 REFGUID guid, const IUnknown *data)
1073 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1075 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1077 return d3d_set_private_data_interface(&view->private_store, guid, data);
1080 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetResource(ID3D11DepthStencilView *iface,
1081 ID3D11Resource **resource)
1083 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1085 TRACE("iface %p, resource %p.\n", iface, resource);
1087 *resource = view->resource;
1088 ID3D11Resource_AddRef(*resource);
1091 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDesc(ID3D11DepthStencilView *iface,
1092 D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1094 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1096 TRACE("iface %p, desc %p.\n", iface, desc);
1098 *desc = view->desc;
1101 static const struct ID3D11DepthStencilViewVtbl d3d11_depthstencil_view_vtbl =
1103 /* IUnknown methods */
1104 d3d11_depthstencil_view_QueryInterface,
1105 d3d11_depthstencil_view_AddRef,
1106 d3d11_depthstencil_view_Release,
1107 /* ID3D11DeviceChild methods */
1108 d3d11_depthstencil_view_GetDevice,
1109 d3d11_depthstencil_view_GetPrivateData,
1110 d3d11_depthstencil_view_SetPrivateData,
1111 d3d11_depthstencil_view_SetPrivateDataInterface,
1112 /* ID3D11View methods */
1113 d3d11_depthstencil_view_GetResource,
1114 /* ID3D11DepthStencilView methods */
1115 d3d11_depthstencil_view_GetDesc,
1118 /* ID3D10DepthStencilView methods */
1120 static inline struct d3d_depthstencil_view *impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface)
1122 return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D10DepthStencilView_iface);
1125 /* IUnknown methods */
1127 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_QueryInterface(ID3D10DepthStencilView *iface,
1128 REFIID riid, void **object)
1130 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1132 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1134 return d3d11_depthstencil_view_QueryInterface(&view->ID3D11DepthStencilView_iface, riid, object);
1137 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_AddRef(ID3D10DepthStencilView *iface)
1139 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1141 TRACE("iface %p.\n", iface);
1143 return d3d11_depthstencil_view_AddRef(&view->ID3D11DepthStencilView_iface);
1146 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_Release(ID3D10DepthStencilView *iface)
1148 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1150 TRACE("iface %p.\n", iface);
1152 return d3d11_depthstencil_view_Release(&view->ID3D11DepthStencilView_iface);
1155 /* ID3D10DeviceChild methods */
1157 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDevice(ID3D10DepthStencilView *iface, ID3D10Device **device)
1159 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1161 TRACE("iface %p, device %p.\n", iface, device);
1163 ID3D11Device_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
1166 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_GetPrivateData(ID3D10DepthStencilView *iface,
1167 REFGUID guid, UINT *data_size, void *data)
1169 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1171 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1172 iface, debugstr_guid(guid), data_size, data);
1174 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1177 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateData(ID3D10DepthStencilView *iface,
1178 REFGUID guid, UINT data_size, const void *data)
1180 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1182 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1183 iface, debugstr_guid(guid), data_size, data);
1185 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1188 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateDataInterface(ID3D10DepthStencilView *iface,
1189 REFGUID guid, const IUnknown *data)
1191 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1193 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1195 return d3d_set_private_data_interface(&view->private_store, guid, data);
1198 /* ID3D10View methods */
1200 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetResource(ID3D10DepthStencilView *iface,
1201 ID3D10Resource **resource)
1203 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1205 TRACE("iface %p, resource %p.\n", iface, resource);
1207 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
1210 /* ID3D10DepthStencilView methods */
1212 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDesc(ID3D10DepthStencilView *iface,
1213 D3D10_DEPTH_STENCIL_VIEW_DESC *desc)
1215 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1216 const D3D11_DEPTH_STENCIL_VIEW_DESC *d3d11_desc = &view->desc;
1218 TRACE("iface %p, desc %p.\n", iface, desc);
1220 desc->Format = d3d11_desc->Format;
1221 desc->ViewDimension = (D3D10_DSV_DIMENSION)d3d11_desc->ViewDimension;
1222 memcpy(&desc->u, &d3d11_desc->u, sizeof(desc->u));
1225 static const struct ID3D10DepthStencilViewVtbl d3d10_depthstencil_view_vtbl =
1227 /* IUnknown methods */
1228 d3d10_depthstencil_view_QueryInterface,
1229 d3d10_depthstencil_view_AddRef,
1230 d3d10_depthstencil_view_Release,
1231 /* ID3D10DeviceChild methods */
1232 d3d10_depthstencil_view_GetDevice,
1233 d3d10_depthstencil_view_GetPrivateData,
1234 d3d10_depthstencil_view_SetPrivateData,
1235 d3d10_depthstencil_view_SetPrivateDataInterface,
1236 /* ID3D10View methods */
1237 d3d10_depthstencil_view_GetResource,
1238 /* ID3D10DepthStencilView methods */
1239 d3d10_depthstencil_view_GetDesc,
1242 static void STDMETHODCALLTYPE d3d_depth_stencil_view_wined3d_object_destroyed(void *parent)
1244 struct d3d_depthstencil_view *view = parent;
1246 wined3d_private_store_cleanup(&view->private_store);
1247 HeapFree(GetProcessHeap(), 0, parent);
1250 static const struct wined3d_parent_ops d3d_depth_stencil_view_wined3d_parent_ops =
1252 d3d_depth_stencil_view_wined3d_object_destroyed,
1255 static void wined3d_depth_stencil_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
1256 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1258 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
1260 if (desc->Flags)
1261 FIXME("Unhandled depth stencil view flags %#x.\n", desc->Flags);
1263 wined3d_desc->flags = 0;
1264 wined3d_desc->u.texture.level_count = 1;
1265 switch (desc->ViewDimension)
1267 case D3D11_DSV_DIMENSION_TEXTURE1D:
1268 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
1269 wined3d_desc->u.texture.layer_idx = 0;
1270 wined3d_desc->u.texture.layer_count = 1;
1271 break;
1273 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
1274 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1275 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
1276 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
1277 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
1278 break;
1280 case D3D11_DSV_DIMENSION_TEXTURE2D:
1281 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
1282 wined3d_desc->u.texture.layer_idx = 0;
1283 wined3d_desc->u.texture.layer_count = 1;
1284 break;
1286 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
1287 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1288 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
1289 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
1290 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
1291 break;
1293 case D3D11_DSV_DIMENSION_TEXTURE2DMS:
1294 wined3d_desc->u.texture.level_idx = 0;
1295 wined3d_desc->u.texture.layer_idx = 0;
1296 wined3d_desc->u.texture.layer_count = 1;
1297 break;
1299 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
1300 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1301 wined3d_desc->u.texture.level_idx = 0;
1302 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
1303 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
1304 break;
1306 default:
1307 FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension);
1308 wined3d_desc->u.texture.level_idx = 0;
1309 wined3d_desc->u.texture.layer_idx = 0;
1310 wined3d_desc->u.texture.layer_count = 1;
1311 break;
1315 static HRESULT d3d_depthstencil_view_init(struct d3d_depthstencil_view *view, struct d3d_device *device,
1316 ID3D11Resource *resource, const D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1318 struct wined3d_resource *wined3d_resource;
1319 struct wined3d_view_desc wined3d_desc;
1320 HRESULT hr;
1322 view->ID3D11DepthStencilView_iface.lpVtbl = &d3d11_depthstencil_view_vtbl;
1323 view->ID3D10DepthStencilView_iface.lpVtbl = &d3d10_depthstencil_view_vtbl;
1324 view->refcount = 1;
1326 if (!desc)
1328 hr = set_dsv_desc_from_resource(&view->desc, resource);
1330 else
1332 view->desc = *desc;
1333 hr = normalize_dsv_desc(&view->desc, resource);
1335 if (FAILED(hr))
1336 return hr;
1338 wined3d_mutex_lock();
1339 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
1341 wined3d_mutex_unlock();
1342 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
1343 return E_FAIL;
1346 wined3d_depth_stencil_view_desc_from_d3d11(&wined3d_desc, &view->desc);
1347 if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource,
1348 view, &d3d_depth_stencil_view_wined3d_parent_ops, &view->wined3d_view)))
1350 wined3d_mutex_unlock();
1351 WARN("Failed to create a wined3d rendertarget view, hr %#x.\n", hr);
1352 return hr;
1355 wined3d_private_store_init(&view->private_store);
1356 wined3d_mutex_unlock();
1357 view->resource = resource;
1358 view->device = &device->ID3D11Device_iface;
1359 ID3D11Device_AddRef(view->device);
1361 return S_OK;
1364 HRESULT d3d_depthstencil_view_create(struct d3d_device *device, ID3D11Resource *resource,
1365 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, struct d3d_depthstencil_view **view)
1367 struct d3d_depthstencil_view *object;
1368 HRESULT hr;
1370 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1371 return E_OUTOFMEMORY;
1373 if (FAILED(hr = d3d_depthstencil_view_init(object, device, resource, desc)))
1375 WARN("Failed to initialize depthstencil view, hr %#x.\n", hr);
1376 HeapFree(GetProcessHeap(), 0, object);
1377 return hr;
1380 TRACE("Created depthstencil view %p.\n", object);
1381 *view = object;
1383 return S_OK;
1386 struct d3d_depthstencil_view *unsafe_impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface)
1388 if (!iface)
1389 return NULL;
1390 assert(iface->lpVtbl == &d3d11_depthstencil_view_vtbl);
1392 return impl_from_ID3D11DepthStencilView(iface);
1395 struct d3d_depthstencil_view *unsafe_impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface)
1397 if (!iface)
1398 return NULL;
1399 assert(iface->lpVtbl == &d3d10_depthstencil_view_vtbl);
1401 return impl_from_ID3D10DepthStencilView(iface);
1404 /* ID3D11RenderTargetView methods */
1406 static inline struct d3d_rendertarget_view *impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface)
1408 return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D11RenderTargetView_iface);
1411 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_QueryInterface(ID3D11RenderTargetView *iface,
1412 REFIID riid, void **object)
1414 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1416 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1418 if (IsEqualGUID(riid, &IID_ID3D11RenderTargetView)
1419 || IsEqualGUID(riid, &IID_ID3D11View)
1420 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1421 || IsEqualGUID(riid, &IID_IUnknown))
1423 ID3D11RenderTargetView_AddRef(iface);
1424 *object = iface;
1425 return S_OK;
1428 if (IsEqualGUID(riid, &IID_ID3D10RenderTargetView)
1429 || IsEqualGUID(riid, &IID_ID3D10View)
1430 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1432 ID3D10RenderTargetView_AddRef(&view->ID3D10RenderTargetView_iface);
1433 *object = &view->ID3D10RenderTargetView_iface;
1434 return S_OK;
1437 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1439 *object = NULL;
1440 return E_NOINTERFACE;
1443 static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_AddRef(ID3D11RenderTargetView *iface)
1445 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1446 ULONG refcount = InterlockedIncrement(&view->refcount);
1448 TRACE("%p increasing refcount to %u.\n", view, refcount);
1450 if (refcount == 1)
1452 ID3D11Device_AddRef(view->device);
1453 wined3d_mutex_lock();
1454 wined3d_rendertarget_view_incref(view->wined3d_view);
1455 wined3d_mutex_unlock();
1458 return refcount;
1461 static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_Release(ID3D11RenderTargetView *iface)
1463 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1464 ULONG refcount = InterlockedDecrement(&view->refcount);
1466 TRACE("%p decreasing refcount to %u.\n", view, refcount);
1468 if (!refcount)
1470 ID3D11Device *device = view->device;
1472 wined3d_mutex_lock();
1473 wined3d_rendertarget_view_decref(view->wined3d_view);
1474 wined3d_mutex_unlock();
1476 ID3D11Device_Release(device);
1479 return refcount;
1482 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDevice(ID3D11RenderTargetView *iface,
1483 ID3D11Device **device)
1485 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1487 TRACE("iface %p, device %p.\n", iface, device);
1489 *device = view->device;
1490 ID3D11Device_AddRef(*device);
1493 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_GetPrivateData(ID3D11RenderTargetView *iface,
1494 REFGUID guid, UINT *data_size, void *data)
1496 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1498 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1500 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1503 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateData(ID3D11RenderTargetView *iface,
1504 REFGUID guid, UINT data_size, const void *data)
1506 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1508 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1510 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1513 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateDataInterface(ID3D11RenderTargetView *iface,
1514 REFGUID guid, const IUnknown *data)
1516 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1518 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1520 return d3d_set_private_data_interface(&view->private_store, guid, data);
1523 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetResource(ID3D11RenderTargetView *iface,
1524 ID3D11Resource **resource)
1526 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1528 TRACE("iface %p, resource %p.\n", iface, resource);
1530 *resource = view->resource;
1531 ID3D11Resource_AddRef(*resource);
1534 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDesc(ID3D11RenderTargetView *iface,
1535 D3D11_RENDER_TARGET_VIEW_DESC *desc)
1537 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1539 TRACE("iface %p, desc %p.\n", iface, desc);
1541 *desc = view->desc;
1544 static const struct ID3D11RenderTargetViewVtbl d3d11_rendertarget_view_vtbl =
1546 /* IUnknown methods */
1547 d3d11_rendertarget_view_QueryInterface,
1548 d3d11_rendertarget_view_AddRef,
1549 d3d11_rendertarget_view_Release,
1550 /* ID3D11DeviceChild methods */
1551 d3d11_rendertarget_view_GetDevice,
1552 d3d11_rendertarget_view_GetPrivateData,
1553 d3d11_rendertarget_view_SetPrivateData,
1554 d3d11_rendertarget_view_SetPrivateDataInterface,
1555 /* ID3D11View methods */
1556 d3d11_rendertarget_view_GetResource,
1557 /* ID3D11RenderTargetView methods */
1558 d3d11_rendertarget_view_GetDesc,
1561 /* ID3D10RenderTargetView methods */
1563 static inline struct d3d_rendertarget_view *impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface)
1565 return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D10RenderTargetView_iface);
1568 /* IUnknown methods */
1570 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_QueryInterface(ID3D10RenderTargetView *iface,
1571 REFIID riid, void **object)
1573 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1575 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1577 return d3d11_rendertarget_view_QueryInterface(&view->ID3D11RenderTargetView_iface, riid, object);
1580 static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_AddRef(ID3D10RenderTargetView *iface)
1582 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1584 TRACE("iface %p.\n", iface);
1586 return d3d11_rendertarget_view_AddRef(&view->ID3D11RenderTargetView_iface);
1589 static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_Release(ID3D10RenderTargetView *iface)
1591 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1593 TRACE("iface %p.\n", iface);
1595 return d3d11_rendertarget_view_Release(&view->ID3D11RenderTargetView_iface);
1598 /* ID3D10DeviceChild methods */
1600 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDevice(ID3D10RenderTargetView *iface, ID3D10Device **device)
1602 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1604 TRACE("iface %p, device %p.\n", iface, device);
1606 ID3D11Device_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
1609 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_GetPrivateData(ID3D10RenderTargetView *iface,
1610 REFGUID guid, UINT *data_size, void *data)
1612 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1614 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1615 iface, debugstr_guid(guid), data_size, data);
1617 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1620 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateData(ID3D10RenderTargetView *iface,
1621 REFGUID guid, UINT data_size, const void *data)
1623 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1625 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1626 iface, debugstr_guid(guid), data_size, data);
1628 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1631 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateDataInterface(ID3D10RenderTargetView *iface,
1632 REFGUID guid, const IUnknown *data)
1634 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1636 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1638 return d3d_set_private_data_interface(&view->private_store, guid, data);
1641 /* ID3D10View methods */
1643 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetResource(ID3D10RenderTargetView *iface,
1644 ID3D10Resource **resource)
1646 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1648 TRACE("iface %p, resource %p\n", iface, resource);
1650 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
1653 /* ID3D10RenderTargetView methods */
1655 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDesc(ID3D10RenderTargetView *iface,
1656 D3D10_RENDER_TARGET_VIEW_DESC *desc)
1658 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1660 TRACE("iface %p, desc %p\n", iface, desc);
1662 memcpy(desc, &view->desc, sizeof(*desc));
1665 static const struct ID3D10RenderTargetViewVtbl d3d10_rendertarget_view_vtbl =
1667 /* IUnknown methods */
1668 d3d10_rendertarget_view_QueryInterface,
1669 d3d10_rendertarget_view_AddRef,
1670 d3d10_rendertarget_view_Release,
1671 /* ID3D10DeviceChild methods */
1672 d3d10_rendertarget_view_GetDevice,
1673 d3d10_rendertarget_view_GetPrivateData,
1674 d3d10_rendertarget_view_SetPrivateData,
1675 d3d10_rendertarget_view_SetPrivateDataInterface,
1676 /* ID3D10View methods */
1677 d3d10_rendertarget_view_GetResource,
1678 /* ID3D10RenderTargetView methods */
1679 d3d10_rendertarget_view_GetDesc,
1682 static void STDMETHODCALLTYPE d3d_render_target_view_wined3d_object_destroyed(void *parent)
1684 struct d3d_rendertarget_view *view = parent;
1686 wined3d_private_store_cleanup(&view->private_store);
1687 HeapFree(GetProcessHeap(), 0, parent);
1690 static const struct wined3d_parent_ops d3d_render_target_view_wined3d_parent_ops =
1692 d3d_render_target_view_wined3d_object_destroyed,
1695 static void wined3d_rendertarget_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
1696 const D3D11_RENDER_TARGET_VIEW_DESC *desc)
1698 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
1700 wined3d_desc->flags = 0;
1701 wined3d_desc->u.texture.level_count = 1;
1702 switch (desc->ViewDimension)
1704 case D3D11_RTV_DIMENSION_BUFFER:
1705 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement;
1706 wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements;
1707 break;
1709 case D3D11_RTV_DIMENSION_TEXTURE1D:
1710 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
1711 wined3d_desc->u.texture.layer_idx = 0;
1712 wined3d_desc->u.texture.layer_count = 1;
1713 break;
1715 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
1716 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1717 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
1718 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
1719 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
1720 break;
1722 case D3D11_RTV_DIMENSION_TEXTURE2D:
1723 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
1724 wined3d_desc->u.texture.layer_idx = 0;
1725 wined3d_desc->u.texture.layer_count = 1;
1726 break;
1728 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
1729 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1730 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
1731 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
1732 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
1733 break;
1735 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
1736 wined3d_desc->u.texture.level_idx = 0;
1737 wined3d_desc->u.texture.layer_idx = 0;
1738 wined3d_desc->u.texture.layer_count = 1;
1739 break;
1741 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
1742 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1743 wined3d_desc->u.texture.level_idx = 0;
1744 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
1745 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
1746 break;
1748 case D3D11_RTV_DIMENSION_TEXTURE3D:
1749 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice;
1750 wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice;
1751 wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize;
1752 break;
1754 default:
1755 FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension);
1756 wined3d_desc->u.texture.level_idx = 0;
1757 wined3d_desc->u.texture.layer_idx = 0;
1758 wined3d_desc->u.texture.layer_count = 1;
1759 break;
1763 static HRESULT d3d_rendertarget_view_init(struct d3d_rendertarget_view *view, struct d3d_device *device,
1764 ID3D11Resource *resource, const D3D11_RENDER_TARGET_VIEW_DESC *desc)
1766 struct wined3d_resource *wined3d_resource;
1767 struct wined3d_view_desc wined3d_desc;
1768 HRESULT hr;
1770 view->ID3D11RenderTargetView_iface.lpVtbl = &d3d11_rendertarget_view_vtbl;
1771 view->ID3D10RenderTargetView_iface.lpVtbl = &d3d10_rendertarget_view_vtbl;
1772 view->refcount = 1;
1774 if (!desc)
1776 hr = set_rtv_desc_from_resource(&view->desc, resource);
1778 else
1780 view->desc = *desc;
1781 hr = normalize_rtv_desc(&view->desc, resource);
1783 if (FAILED(hr))
1784 return hr;
1786 wined3d_mutex_lock();
1787 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
1789 wined3d_mutex_unlock();
1790 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
1791 return E_FAIL;
1794 wined3d_rendertarget_view_desc_from_d3d11(&wined3d_desc, &view->desc);
1795 if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource,
1796 view, &d3d_render_target_view_wined3d_parent_ops, &view->wined3d_view)))
1798 wined3d_mutex_unlock();
1799 WARN("Failed to create a wined3d rendertarget view, hr %#x.\n", hr);
1800 return hr;
1803 wined3d_private_store_init(&view->private_store);
1804 wined3d_mutex_unlock();
1805 view->resource = resource;
1806 view->device = &device->ID3D11Device_iface;
1807 ID3D11Device_AddRef(view->device);
1809 return S_OK;
1812 HRESULT d3d_rendertarget_view_create(struct d3d_device *device, ID3D11Resource *resource,
1813 const D3D11_RENDER_TARGET_VIEW_DESC *desc, struct d3d_rendertarget_view **view)
1815 struct d3d_rendertarget_view *object;
1816 HRESULT hr;
1818 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1819 return E_OUTOFMEMORY;
1821 if (FAILED(hr = d3d_rendertarget_view_init(object, device, resource, desc)))
1823 WARN("Failed to initialize rendertarget view, hr %#x.\n", hr);
1824 HeapFree(GetProcessHeap(), 0, object);
1825 return hr;
1828 TRACE("Created rendertarget view %p.\n", object);
1829 *view = object;
1831 return S_OK;
1834 struct d3d_rendertarget_view *unsafe_impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface)
1836 if (!iface)
1837 return NULL;
1838 assert(iface->lpVtbl == &d3d11_rendertarget_view_vtbl);
1840 return impl_from_ID3D11RenderTargetView(iface);
1843 struct d3d_rendertarget_view *unsafe_impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface)
1845 if (!iface)
1846 return NULL;
1847 assert(iface->lpVtbl == &d3d10_rendertarget_view_vtbl);
1849 return impl_from_ID3D10RenderTargetView(iface);
1852 /* ID3D11ShaderResourceView methods */
1854 static inline struct d3d_shader_resource_view *impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface)
1856 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D11ShaderResourceView_iface);
1859 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_QueryInterface(ID3D11ShaderResourceView *iface,
1860 REFIID riid, void **object)
1862 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1864 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1866 if (IsEqualGUID(riid, &IID_ID3D11ShaderResourceView)
1867 || IsEqualGUID(riid, &IID_ID3D11View)
1868 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1869 || IsEqualGUID(riid, &IID_IUnknown))
1871 ID3D11ShaderResourceView_AddRef(iface);
1872 *object = iface;
1873 return S_OK;
1876 if (IsEqualGUID(riid, &IID_ID3D10ShaderResourceView1)
1877 || IsEqualGUID(riid, &IID_ID3D10ShaderResourceView)
1878 || IsEqualGUID(riid, &IID_ID3D10View)
1879 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1881 ID3D10ShaderResourceView1_AddRef(&view->ID3D10ShaderResourceView1_iface);
1882 *object = &view->ID3D10ShaderResourceView1_iface;
1883 return S_OK;
1886 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1888 *object = NULL;
1889 return E_NOINTERFACE;
1892 static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_AddRef(ID3D11ShaderResourceView *iface)
1894 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1895 ULONG refcount = InterlockedIncrement(&view->refcount);
1897 TRACE("%p increasing refcount to %u.\n", view, refcount);
1899 if (refcount == 1)
1901 ID3D11Device_AddRef(view->device);
1902 wined3d_mutex_lock();
1903 wined3d_shader_resource_view_incref(view->wined3d_view);
1904 wined3d_mutex_unlock();
1907 return refcount;
1910 static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_Release(ID3D11ShaderResourceView *iface)
1912 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1913 ULONG refcount = InterlockedDecrement(&view->refcount);
1915 TRACE("%p decreasing refcount to %u.\n", view, refcount);
1917 if (!refcount)
1919 ID3D11Device *device = view->device;
1921 wined3d_mutex_lock();
1922 wined3d_shader_resource_view_decref(view->wined3d_view);
1923 wined3d_mutex_unlock();
1925 ID3D11Device_Release(device);
1928 return refcount;
1931 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDevice(ID3D11ShaderResourceView *iface,
1932 ID3D11Device **device)
1934 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1936 TRACE("iface %p, device %p.\n", iface, device);
1938 *device = view->device;
1939 ID3D11Device_AddRef(*device);
1942 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_GetPrivateData(ID3D11ShaderResourceView *iface,
1943 REFGUID guid, UINT *data_size, void *data)
1945 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1947 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1949 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1952 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateData(ID3D11ShaderResourceView *iface,
1953 REFGUID guid, UINT data_size, const void *data)
1955 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1957 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1959 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1962 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateDataInterface(ID3D11ShaderResourceView *iface,
1963 REFGUID guid, const IUnknown *data)
1965 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1967 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1969 return d3d_set_private_data_interface(&view->private_store, guid, data);
1972 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetResource(ID3D11ShaderResourceView *iface,
1973 ID3D11Resource **resource)
1975 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1977 TRACE("iface %p, resource %p.\n", iface, resource);
1979 *resource = view->resource;
1980 ID3D11Resource_AddRef(*resource);
1983 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDesc(ID3D11ShaderResourceView *iface,
1984 D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
1986 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1988 TRACE("iface %p, desc %p.\n", iface, desc);
1990 *desc = view->desc;
1993 static const struct ID3D11ShaderResourceViewVtbl d3d11_shader_resource_view_vtbl =
1995 /* IUnknown methods */
1996 d3d11_shader_resource_view_QueryInterface,
1997 d3d11_shader_resource_view_AddRef,
1998 d3d11_shader_resource_view_Release,
1999 /* ID3D11DeviceChild methods */
2000 d3d11_shader_resource_view_GetDevice,
2001 d3d11_shader_resource_view_GetPrivateData,
2002 d3d11_shader_resource_view_SetPrivateData,
2003 d3d11_shader_resource_view_SetPrivateDataInterface,
2004 /* ID3D11View methods */
2005 d3d11_shader_resource_view_GetResource,
2006 /* ID3D11ShaderResourceView methods */
2007 d3d11_shader_resource_view_GetDesc,
2010 /* ID3D10ShaderResourceView methods */
2012 static inline struct d3d_shader_resource_view *impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView1 *iface)
2014 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface);
2017 /* IUnknown methods */
2019 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_QueryInterface(ID3D10ShaderResourceView1 *iface,
2020 REFIID riid, void **object)
2022 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2024 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
2026 return d3d11_shader_resource_view_QueryInterface(&view->ID3D11ShaderResourceView_iface, riid, object);
2029 static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_AddRef(ID3D10ShaderResourceView1 *iface)
2031 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2033 TRACE("iface %p.\n", iface);
2035 return d3d11_shader_resource_view_AddRef(&view->ID3D11ShaderResourceView_iface);
2038 static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_Release(ID3D10ShaderResourceView1 *iface)
2040 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2042 TRACE("iface %p.\n", iface);
2044 return d3d11_shader_resource_view_Release(&view->ID3D11ShaderResourceView_iface);
2047 /* ID3D10DeviceChild methods */
2049 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDevice(ID3D10ShaderResourceView1 *iface,
2050 ID3D10Device **device)
2052 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2054 TRACE("iface %p, device %p.\n", iface, device);
2056 ID3D11Device_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
2059 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_GetPrivateData(ID3D10ShaderResourceView1 *iface,
2060 REFGUID guid, UINT *data_size, void *data)
2062 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2064 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
2065 iface, debugstr_guid(guid), data_size, data);
2067 return d3d_get_private_data(&view->private_store, guid, data_size, data);
2070 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateData(ID3D10ShaderResourceView1 *iface,
2071 REFGUID guid, UINT data_size, const void *data)
2073 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2075 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
2076 iface, debugstr_guid(guid), data_size, data);
2078 return d3d_set_private_data(&view->private_store, guid, data_size, data);
2081 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateDataInterface(ID3D10ShaderResourceView1 *iface,
2082 REFGUID guid, const IUnknown *data)
2084 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2086 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2088 return d3d_set_private_data_interface(&view->private_store, guid, data);
2091 /* ID3D10View methods */
2093 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetResource(ID3D10ShaderResourceView1 *iface,
2094 ID3D10Resource **resource)
2096 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2098 TRACE("iface %p, resource %p.\n", iface, resource);
2100 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
2103 /* ID3D10ShaderResourceView methods */
2105 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc(ID3D10ShaderResourceView1 *iface,
2106 D3D10_SHADER_RESOURCE_VIEW_DESC *desc)
2108 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2110 TRACE("iface %p, desc %p.\n", iface, desc);
2112 memcpy(desc, &view->desc, sizeof(*desc));
2115 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc1(ID3D10ShaderResourceView1 *iface,
2116 D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc)
2118 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2120 TRACE("iface %p, desc %p.\n", iface, desc);
2122 memcpy(desc, &view->desc, sizeof(*desc));
2125 static const struct ID3D10ShaderResourceView1Vtbl d3d10_shader_resource_view_vtbl =
2127 /* IUnknown methods */
2128 d3d10_shader_resource_view_QueryInterface,
2129 d3d10_shader_resource_view_AddRef,
2130 d3d10_shader_resource_view_Release,
2131 /* ID3D10DeviceChild methods */
2132 d3d10_shader_resource_view_GetDevice,
2133 d3d10_shader_resource_view_GetPrivateData,
2134 d3d10_shader_resource_view_SetPrivateData,
2135 d3d10_shader_resource_view_SetPrivateDataInterface,
2136 /* ID3D10View methods */
2137 d3d10_shader_resource_view_GetResource,
2138 /* ID3D10ShaderResourceView methods */
2139 d3d10_shader_resource_view_GetDesc,
2140 /* ID3D10ShaderResourceView1 methods */
2141 d3d10_shader_resource_view_GetDesc1,
2144 static void STDMETHODCALLTYPE d3d_shader_resource_view_wined3d_object_destroyed(void *parent)
2146 struct d3d_shader_resource_view *view = parent;
2148 wined3d_private_store_cleanup(&view->private_store);
2149 HeapFree(GetProcessHeap(), 0, parent);
2152 static const struct wined3d_parent_ops d3d_shader_resource_view_wined3d_parent_ops =
2154 d3d_shader_resource_view_wined3d_object_destroyed,
2157 static unsigned int wined3d_view_flags_from_d3d11_bufferex_flags(unsigned int d3d11_flags)
2159 unsigned int wined3d_flags = d3d11_flags & WINED3D_VIEW_BUFFER_RAW;
2161 if (d3d11_flags != wined3d_flags)
2162 FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags);
2164 return wined3d_flags;
2167 static HRESULT wined3d_shader_resource_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
2168 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
2170 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
2171 wined3d_desc->flags = 0;
2173 switch (desc->ViewDimension)
2175 case D3D11_SRV_DIMENSION_BUFFER:
2176 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement;
2177 wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements;
2178 break;
2180 case D3D11_SRV_DIMENSION_TEXTURE1D:
2181 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MostDetailedMip;
2182 wined3d_desc->u.texture.level_count = desc->u.Texture1D.MipLevels;
2183 wined3d_desc->u.texture.layer_idx = 0;
2184 wined3d_desc->u.texture.layer_count = 1;
2185 break;
2187 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
2188 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2189 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MostDetailedMip;
2190 wined3d_desc->u.texture.level_count = desc->u.Texture1DArray.MipLevels;
2191 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
2192 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
2193 break;
2195 case D3D11_SRV_DIMENSION_TEXTURE2D:
2196 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MostDetailedMip;
2197 wined3d_desc->u.texture.level_count = desc->u.Texture2D.MipLevels;
2198 wined3d_desc->u.texture.layer_idx = 0;
2199 wined3d_desc->u.texture.layer_count = 1;
2200 break;
2202 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
2203 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2204 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MostDetailedMip;
2205 wined3d_desc->u.texture.level_count = desc->u.Texture2DArray.MipLevels;
2206 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
2207 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
2208 break;
2210 case D3D11_SRV_DIMENSION_TEXTURE2DMS:
2211 wined3d_desc->u.texture.level_idx = 0;
2212 wined3d_desc->u.texture.level_count = 1;
2213 wined3d_desc->u.texture.layer_idx = 0;
2214 wined3d_desc->u.texture.layer_count = 1;
2215 break;
2217 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
2218 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2219 wined3d_desc->u.texture.level_idx = 0;
2220 wined3d_desc->u.texture.level_count = 1;
2221 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
2222 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
2223 break;
2225 case D3D11_SRV_DIMENSION_TEXTURE3D:
2226 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MostDetailedMip;
2227 wined3d_desc->u.texture.level_count = desc->u.Texture3D.MipLevels;
2228 wined3d_desc->u.texture.layer_idx = 0;
2229 wined3d_desc->u.texture.layer_count = 1;
2230 break;
2232 case D3D11_SRV_DIMENSION_TEXTURECUBE:
2233 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE;
2234 wined3d_desc->u.texture.level_idx = desc->u.TextureCube.MostDetailedMip;
2235 wined3d_desc->u.texture.level_count = desc->u.TextureCube.MipLevels;
2236 wined3d_desc->u.texture.layer_idx = 0;
2237 wined3d_desc->u.texture.layer_count = 6;
2238 break;
2240 case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
2241 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY;
2242 wined3d_desc->u.texture.level_idx = desc->u.TextureCubeArray.MostDetailedMip;
2243 wined3d_desc->u.texture.level_count = desc->u.TextureCubeArray.MipLevels;
2244 wined3d_desc->u.texture.layer_idx = desc->u.TextureCubeArray.First2DArrayFace;
2245 wined3d_desc->u.texture.layer_count = 6 * desc->u.TextureCubeArray.NumCubes;
2246 break;
2248 case D3D11_SRV_DIMENSION_BUFFEREX:
2249 wined3d_desc->flags = wined3d_view_flags_from_d3d11_bufferex_flags(desc->u.BufferEx.Flags);
2250 wined3d_desc->u.buffer.start_idx = desc->u.BufferEx.FirstElement;
2251 wined3d_desc->u.buffer.count = desc->u.BufferEx.NumElements;
2252 break;
2254 default:
2255 WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension);
2256 return E_FAIL;
2259 return S_OK;
2262 static HRESULT d3d_shader_resource_view_init(struct d3d_shader_resource_view *view, struct d3d_device *device,
2263 ID3D11Resource *resource, const D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
2265 struct wined3d_resource *wined3d_resource;
2266 struct wined3d_view_desc wined3d_desc;
2267 HRESULT hr;
2269 view->ID3D11ShaderResourceView_iface.lpVtbl = &d3d11_shader_resource_view_vtbl;
2270 view->ID3D10ShaderResourceView1_iface.lpVtbl = &d3d10_shader_resource_view_vtbl;
2271 view->refcount = 1;
2273 if (!desc)
2275 hr = set_srv_desc_from_resource(&view->desc, resource);
2277 else
2279 view->desc = *desc;
2280 hr = normalize_srv_desc(&view->desc, resource);
2282 if (FAILED(hr))
2283 return hr;
2285 if (FAILED(hr = wined3d_shader_resource_view_desc_from_d3d11(&wined3d_desc, &view->desc)))
2286 return hr;
2288 wined3d_mutex_lock();
2289 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
2291 wined3d_mutex_unlock();
2292 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
2293 return E_FAIL;
2296 if (FAILED(hr = wined3d_shader_resource_view_create(&wined3d_desc, wined3d_resource,
2297 view, &d3d_shader_resource_view_wined3d_parent_ops, &view->wined3d_view)))
2299 wined3d_mutex_unlock();
2300 WARN("Failed to create wined3d shader resource view, hr %#x.\n", hr);
2301 return hr;
2304 wined3d_private_store_init(&view->private_store);
2305 wined3d_mutex_unlock();
2306 view->resource = resource;
2307 view->device = &device->ID3D11Device_iface;
2308 ID3D11Device_AddRef(view->device);
2310 return S_OK;
2313 HRESULT d3d_shader_resource_view_create(struct d3d_device *device, ID3D11Resource *resource,
2314 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, struct d3d_shader_resource_view **view)
2316 struct d3d_shader_resource_view *object;
2317 HRESULT hr;
2319 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
2320 return E_OUTOFMEMORY;
2322 if (FAILED(hr = d3d_shader_resource_view_init(object, device, resource, desc)))
2324 WARN("Failed to initialize shader resource view, hr %#x.\n", hr);
2325 HeapFree(GetProcessHeap(), 0, object);
2326 return hr;
2329 TRACE("Created shader resource view %p.\n", object);
2330 *view = object;
2332 return S_OK;
2335 struct d3d_shader_resource_view *unsafe_impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface)
2337 if (!iface)
2338 return NULL;
2339 assert(iface->lpVtbl == &d3d11_shader_resource_view_vtbl);
2340 return impl_from_ID3D11ShaderResourceView(iface);
2343 struct d3d_shader_resource_view *unsafe_impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView *iface)
2345 if (!iface)
2346 return NULL;
2347 assert(iface->lpVtbl == (ID3D10ShaderResourceViewVtbl *)&d3d10_shader_resource_view_vtbl);
2348 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface);
2351 /* ID3D11UnorderedAccessView methods */
2353 static inline struct d3d11_unordered_access_view *impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface)
2355 return CONTAINING_RECORD(iface, struct d3d11_unordered_access_view, ID3D11UnorderedAccessView_iface);
2358 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_QueryInterface(ID3D11UnorderedAccessView *iface,
2359 REFIID riid, void **object)
2361 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
2363 if (IsEqualGUID(riid, &IID_ID3D11UnorderedAccessView)
2364 || IsEqualGUID(riid, &IID_ID3D11View)
2365 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
2366 || IsEqualGUID(riid, &IID_IUnknown))
2368 ID3D11UnorderedAccessView_AddRef(*object = iface);
2369 return S_OK;
2372 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
2374 *object = NULL;
2375 return E_NOINTERFACE;
2378 static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_AddRef(ID3D11UnorderedAccessView *iface)
2380 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2381 ULONG refcount = InterlockedIncrement(&view->refcount);
2383 TRACE("%p increasing refcount to %u.\n", view, refcount);
2385 if (refcount == 1)
2387 ID3D11Device_AddRef(view->device);
2388 wined3d_mutex_lock();
2389 wined3d_unordered_access_view_incref(view->wined3d_view);
2390 wined3d_mutex_unlock();
2393 return refcount;
2396 static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_Release(ID3D11UnorderedAccessView *iface)
2398 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2399 ULONG refcount = InterlockedDecrement(&view->refcount);
2401 TRACE("%p decreasing refcount to %u.\n", view, refcount);
2403 if (!refcount)
2405 ID3D11Device *device = view->device;
2407 wined3d_mutex_lock();
2408 wined3d_unordered_access_view_decref(view->wined3d_view);
2409 wined3d_mutex_unlock();
2411 ID3D11Device_Release(device);
2414 return refcount;
2417 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDevice(ID3D11UnorderedAccessView *iface,
2418 ID3D11Device **device)
2420 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2422 TRACE("iface %p, device %p.\n", iface, device);
2424 ID3D11Device_AddRef(*device = view->device);
2427 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_GetPrivateData(ID3D11UnorderedAccessView *iface,
2428 REFGUID guid, UINT *data_size, void *data)
2430 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2432 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2434 return d3d_get_private_data(&view->private_store, guid, data_size, data);
2437 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateData(ID3D11UnorderedAccessView *iface,
2438 REFGUID guid, UINT data_size, const void *data)
2440 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2442 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2444 return d3d_set_private_data(&view->private_store, guid, data_size, data);
2447 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateDataInterface(ID3D11UnorderedAccessView *iface,
2448 REFGUID guid, const IUnknown *data)
2450 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2452 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2454 return d3d_set_private_data_interface(&view->private_store, guid, data);
2457 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetResource(ID3D11UnorderedAccessView *iface,
2458 ID3D11Resource **resource)
2460 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2462 TRACE("iface %p, resource %p.\n", iface, resource);
2464 ID3D11Resource_AddRef(*resource = view->resource);
2467 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDesc(ID3D11UnorderedAccessView *iface,
2468 D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2470 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2472 TRACE("iface %p, desc %p.\n", iface, desc);
2474 *desc = view->desc;
2477 static const struct ID3D11UnorderedAccessViewVtbl d3d11_unordered_access_view_vtbl =
2479 /* IUnknown methods */
2480 d3d11_unordered_access_view_QueryInterface,
2481 d3d11_unordered_access_view_AddRef,
2482 d3d11_unordered_access_view_Release,
2483 /* ID3D11DeviceChild methods */
2484 d3d11_unordered_access_view_GetDevice,
2485 d3d11_unordered_access_view_GetPrivateData,
2486 d3d11_unordered_access_view_SetPrivateData,
2487 d3d11_unordered_access_view_SetPrivateDataInterface,
2488 /* ID3D11View methods */
2489 d3d11_unordered_access_view_GetResource,
2490 /* ID3D11UnorderedAccessView methods */
2491 d3d11_unordered_access_view_GetDesc,
2494 static void STDMETHODCALLTYPE d3d11_unordered_access_view_wined3d_object_destroyed(void *parent)
2496 struct d3d11_unordered_access_view *view = parent;
2498 wined3d_private_store_cleanup(&view->private_store);
2499 HeapFree(GetProcessHeap(), 0, parent);
2502 static const struct wined3d_parent_ops d3d11_unordered_access_view_wined3d_parent_ops =
2504 d3d11_unordered_access_view_wined3d_object_destroyed,
2507 static unsigned int wined3d_view_flags_from_d3d11_buffer_uav_flags(unsigned int d3d11_flags)
2509 unsigned int wined3d_flags = d3d11_flags & (WINED3D_VIEW_BUFFER_RAW
2510 | WINED3D_VIEW_BUFFER_APPEND | WINED3D_VIEW_BUFFER_COUNTER);
2512 if (d3d11_flags != wined3d_flags)
2513 FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags);
2515 return wined3d_flags;
2518 static HRESULT wined3d_unordered_access_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
2519 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2521 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
2523 wined3d_desc->flags = 0;
2524 wined3d_desc->u.texture.level_count = 1;
2525 switch (desc->ViewDimension)
2527 case D3D11_UAV_DIMENSION_BUFFER:
2528 wined3d_desc->flags = wined3d_view_flags_from_d3d11_buffer_uav_flags(desc->u.Buffer.Flags);
2529 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.FirstElement;
2530 wined3d_desc->u.buffer.count = desc->u.Buffer.NumElements;
2531 break;
2533 case D3D11_UAV_DIMENSION_TEXTURE1D:
2534 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
2535 wined3d_desc->u.texture.layer_idx = 0;
2536 wined3d_desc->u.texture.layer_count = 1;
2537 break;
2539 case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
2540 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2541 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
2542 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
2543 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
2544 break;
2546 case D3D11_UAV_DIMENSION_TEXTURE2D:
2547 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
2548 wined3d_desc->u.texture.layer_idx = 0;
2549 wined3d_desc->u.texture.layer_count = 1;
2550 break;
2552 case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
2553 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2554 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
2555 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
2556 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
2557 break;
2559 case D3D11_UAV_DIMENSION_TEXTURE3D:
2560 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice;
2561 wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice;
2562 wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize;
2563 break;
2565 default:
2566 WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension);
2567 return E_FAIL;
2570 return S_OK;
2573 static HRESULT d3d11_unordered_access_view_init(struct d3d11_unordered_access_view *view,
2574 struct d3d_device *device, ID3D11Resource *resource, const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2576 struct wined3d_resource *wined3d_resource;
2577 struct wined3d_view_desc wined3d_desc;
2578 HRESULT hr;
2580 view->ID3D11UnorderedAccessView_iface.lpVtbl = &d3d11_unordered_access_view_vtbl;
2581 view->refcount = 1;
2583 if (!desc)
2585 hr = set_uav_desc_from_resource(&view->desc, resource);
2587 else
2589 view->desc = *desc;
2590 hr = normalize_uav_desc(&view->desc, resource);
2592 if (FAILED(hr))
2593 return hr;
2595 if (FAILED(hr = wined3d_unordered_access_view_desc_from_d3d11(&wined3d_desc, &view->desc)))
2596 return hr;
2598 wined3d_mutex_lock();
2599 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
2601 wined3d_mutex_unlock();
2602 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
2603 return E_FAIL;
2606 if (FAILED(hr = wined3d_unordered_access_view_create(&wined3d_desc, wined3d_resource,
2607 view, &d3d11_unordered_access_view_wined3d_parent_ops, &view->wined3d_view)))
2609 wined3d_mutex_unlock();
2610 WARN("Failed to create wined3d unordered access view, hr %#x.\n", hr);
2611 return hr;
2614 wined3d_private_store_init(&view->private_store);
2615 wined3d_mutex_unlock();
2616 view->resource = resource;
2617 ID3D11Device_AddRef(view->device = &device->ID3D11Device_iface);
2619 return S_OK;
2622 HRESULT d3d11_unordered_access_view_create(struct d3d_device *device, ID3D11Resource *resource,
2623 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, struct d3d11_unordered_access_view **view)
2625 struct d3d11_unordered_access_view *object;
2626 HRESULT hr;
2628 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
2629 return E_OUTOFMEMORY;
2631 if (FAILED(hr = d3d11_unordered_access_view_init(object, device, resource, desc)))
2633 WARN("Failed to initialize unordered access view, hr %#x.\n", hr);
2634 HeapFree(GetProcessHeap(), 0, object);
2635 return hr;
2638 TRACE("Created unordered access view %p.\n", object);
2639 *view = object;
2641 return S_OK;
2644 struct d3d11_unordered_access_view *unsafe_impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface)
2646 if (!iface)
2647 return NULL;
2648 assert(iface->lpVtbl == &d3d11_unordered_access_view_vtbl);
2650 return impl_from_ID3D11UnorderedAccessView(iface);