ntoskrnl.exe: Implement NtBuildNumber.
[wine.git] / dlls / d3d11 / view.c
blob93d0b78655c137b9f2ed131236578e2d6f2acb3e
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 get_resource_properties(ID3D11Resource *resource, D3D11_RESOURCE_DIMENSION *dimension,
29 DXGI_FORMAT *format, unsigned int *miplevel_count, unsigned int *layer_count)
31 ID3D11Resource_GetType(resource, dimension);
32 switch (*dimension)
34 case D3D11_RESOURCE_DIMENSION_BUFFER:
35 return S_OK;
37 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
39 const struct d3d_texture1d *texture;
41 if (!(texture = unsafe_impl_from_ID3D11Texture1D((ID3D11Texture1D *)resource)))
43 ERR("Cannot get implementation from ID3D11Texture1D.\n");
44 return E_FAIL;
47 *format = texture->desc.Format;
48 if (miplevel_count)
49 *miplevel_count = texture->desc.MipLevels;
50 *layer_count = texture->desc.ArraySize;
51 break;
54 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
56 const struct d3d_texture2d *texture;
58 if (!(texture = unsafe_impl_from_ID3D11Texture2D((ID3D11Texture2D *)resource)))
60 ERR("Cannot get implementation from ID3D11Texture2D.\n");
61 return E_FAIL;
64 *format = texture->desc.Format;
65 if (miplevel_count)
66 *miplevel_count = texture->desc.MipLevels;
67 *layer_count = texture->desc.ArraySize;
68 break;
71 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
73 const struct d3d_texture3d *texture;
75 if (!(texture = unsafe_impl_from_ID3D11Texture3D((ID3D11Texture3D *)resource)))
77 ERR("Cannot get implementation from ID3D11Texture3D.\n");
78 return E_FAIL;
81 *format = texture->desc.Format;
82 if (miplevel_count)
83 *miplevel_count = texture->desc.MipLevels;
84 *layer_count = texture->desc.Depth;
85 break;
88 default:
89 WARN("Invalid resource dimension %#x.\n", *dimension);
90 return E_INVALIDARG;
93 return S_OK;
96 static HRESULT set_dsv_desc_from_resource(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource)
98 D3D11_RESOURCE_DIMENSION dimension;
100 ID3D11Resource_GetType(resource, &dimension);
102 desc->Flags = 0;
104 switch (dimension)
106 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
108 D3D11_TEXTURE1D_DESC texture_desc;
109 ID3D11Texture1D *texture;
111 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture)))
113 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n");
114 return E_INVALIDARG;
117 ID3D11Texture1D_GetDesc(texture, &texture_desc);
118 ID3D11Texture1D_Release(texture);
120 desc->Format = texture_desc.Format;
121 if (texture_desc.ArraySize == 1)
123 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
124 desc->u.Texture1D.MipSlice = 0;
126 else
128 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
129 desc->u.Texture1DArray.MipSlice = 0;
130 desc->u.Texture1DArray.FirstArraySlice = 0;
131 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
134 return S_OK;
137 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
139 D3D11_TEXTURE2D_DESC texture_desc;
140 ID3D11Texture2D *texture;
142 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
144 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
145 return E_INVALIDARG;
148 ID3D11Texture2D_GetDesc(texture, &texture_desc);
149 ID3D11Texture2D_Release(texture);
151 desc->Format = texture_desc.Format;
152 if (texture_desc.ArraySize == 1)
154 if (texture_desc.SampleDesc.Count == 1)
156 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
157 desc->u.Texture2D.MipSlice = 0;
159 else
161 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
164 else
166 if (texture_desc.SampleDesc.Count == 1)
168 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
169 desc->u.Texture2DArray.MipSlice = 0;
170 desc->u.Texture2DArray.FirstArraySlice = 0;
171 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
173 else
175 desc->ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
176 desc->u.Texture2DMSArray.FirstArraySlice = 0;
177 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
181 return S_OK;
184 case D3D11_RESOURCE_DIMENSION_BUFFER:
185 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
186 default:
187 WARN("Invalid resource dimension %#x.\n", dimension);
188 return E_INVALIDARG;
192 static HRESULT normalize_dsv_desc(D3D11_DEPTH_STENCIL_VIEW_DESC *desc, ID3D11Resource *resource)
194 D3D11_RESOURCE_DIMENSION dimension;
195 unsigned int layer_count;
196 DXGI_FORMAT format;
197 HRESULT hr;
199 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count)))
200 return hr;
201 switch (dimension)
203 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
204 if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1D
205 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE1DARRAY)
207 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
208 return E_INVALIDARG;
210 break;
212 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
213 if (desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2D
214 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DARRAY
215 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMS
216 && desc->ViewDimension != D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY)
218 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
219 return E_INVALIDARG;
221 break;
223 case D3D11_RESOURCE_DIMENSION_BUFFER:
224 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
225 default:
226 WARN("Invalid resource dimension %#x.\n", dimension);
227 return E_INVALIDARG;
230 if (desc->Format == DXGI_FORMAT_UNKNOWN)
231 desc->Format = format;
233 switch (desc->ViewDimension)
235 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
236 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
237 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
238 break;
240 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
241 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
242 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
243 break;
245 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
246 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
247 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
248 break;
250 default:
251 break;
254 return S_OK;
257 static HRESULT set_rtv_desc_from_resource(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource)
259 D3D11_RESOURCE_DIMENSION dimension;
260 HRESULT hr;
262 ID3D11Resource_GetType(resource, &dimension);
264 switch (dimension)
266 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
268 ID3D11Texture1D *texture;
269 D3D11_TEXTURE1D_DESC texture_desc;
271 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture);
272 if (FAILED(hr))
274 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D?\n");
275 return E_INVALIDARG;
278 ID3D11Texture1D_GetDesc(texture, &texture_desc);
279 ID3D11Texture1D_Release(texture);
281 desc->Format = texture_desc.Format;
282 if (texture_desc.ArraySize == 1)
284 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
285 desc->u.Texture1D.MipSlice = 0;
287 else
289 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
290 desc->u.Texture1DArray.MipSlice = 0;
291 desc->u.Texture1DArray.FirstArraySlice = 0;
292 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
295 return S_OK;
298 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
300 ID3D11Texture2D *texture;
301 D3D11_TEXTURE2D_DESC texture_desc;
303 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture);
304 if (FAILED(hr))
306 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D?\n");
307 return E_INVALIDARG;
310 ID3D11Texture2D_GetDesc(texture, &texture_desc);
311 ID3D11Texture2D_Release(texture);
313 desc->Format = texture_desc.Format;
314 if (texture_desc.ArraySize == 1)
316 if (texture_desc.SampleDesc.Count == 1)
318 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
319 desc->u.Texture2D.MipSlice = 0;
321 else
323 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
326 else
328 if (texture_desc.SampleDesc.Count == 1)
330 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
331 desc->u.Texture2DArray.MipSlice = 0;
332 desc->u.Texture2DArray.FirstArraySlice = 0;
333 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
335 else
337 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
338 desc->u.Texture2DMSArray.FirstArraySlice = 0;
339 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
343 return S_OK;
346 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
348 ID3D11Texture3D *texture;
349 D3D11_TEXTURE3D_DESC texture_desc;
351 hr = ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture);
352 if (FAILED(hr))
354 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D?\n");
355 return E_INVALIDARG;
358 ID3D11Texture3D_GetDesc(texture, &texture_desc);
359 ID3D11Texture3D_Release(texture);
361 desc->Format = texture_desc.Format;
362 desc->ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
363 desc->u.Texture3D.MipSlice = 0;
364 desc->u.Texture3D.FirstWSlice = 0;
365 desc->u.Texture3D.WSize = texture_desc.Depth;
367 return S_OK;
370 default:
371 FIXME("Unhandled resource dimension %#x.\n", dimension);
372 return E_INVALIDARG;
376 static HRESULT normalize_rtv_desc(D3D11_RENDER_TARGET_VIEW_DESC *desc, ID3D11Resource *resource)
378 D3D11_RESOURCE_DIMENSION dimension;
379 unsigned int layer_count;
380 DXGI_FORMAT format;
381 HRESULT hr;
383 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count)))
384 return hr;
385 switch (dimension)
387 case D3D11_RESOURCE_DIMENSION_BUFFER:
388 if (desc->ViewDimension != D3D11_RTV_DIMENSION_BUFFER)
390 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
391 return E_INVALIDARG;
393 return S_OK;
395 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
396 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1D
397 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE1DARRAY)
399 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
400 return E_INVALIDARG;
402 break;
404 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
405 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2D
406 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DARRAY
407 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMS
408 && desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY)
410 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
411 return E_INVALIDARG;
413 break;
415 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
416 if (desc->ViewDimension != D3D11_RTV_DIMENSION_TEXTURE3D)
418 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
419 return E_INVALIDARG;
421 break;
423 default:
424 WARN("Invalid resource dimension %#x.\n", dimension);
425 return E_INVALIDARG;
428 if (desc->Format == DXGI_FORMAT_UNKNOWN)
429 desc->Format = format;
431 switch (desc->ViewDimension)
433 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
434 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
435 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
436 break;
438 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
439 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
440 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
441 break;
443 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
444 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
445 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
446 break;
448 case D3D11_RTV_DIMENSION_TEXTURE3D:
449 layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice);
450 if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count)
451 desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice;
452 break;
454 default:
455 break;
458 return S_OK;
461 static HRESULT set_srv_desc_from_resource(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource)
463 D3D11_RESOURCE_DIMENSION dimension;
465 ID3D11Resource_GetType(resource, &dimension);
467 switch (dimension)
469 case D3D11_RESOURCE_DIMENSION_BUFFER:
471 D3D11_BUFFER_DESC buffer_desc;
472 ID3D11Buffer *buffer;
474 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer)))
476 ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n");
477 return E_INVALIDARG;
480 ID3D11Buffer_GetDesc(buffer, &buffer_desc);
481 ID3D11Buffer_Release(buffer);
483 if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
485 desc->Format = DXGI_FORMAT_UNKNOWN;
486 desc->ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
487 desc->u.Buffer.u1.FirstElement = 0;
488 desc->u.Buffer.u2.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
489 return S_OK;
492 return E_INVALIDARG;
495 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
497 D3D11_TEXTURE1D_DESC texture_desc;
498 ID3D11Texture1D *texture;
500 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture1D, (void **)&texture)))
502 ERR("Resource of type TEXTURE1D doesn't implement ID3D11Texture1D.\n");
503 return E_INVALIDARG;
506 ID3D11Texture1D_GetDesc(texture, &texture_desc);
507 ID3D11Texture1D_Release(texture);
509 desc->Format = texture_desc.Format;
510 if (texture_desc.ArraySize == 1)
512 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
513 desc->u.Texture1D.MostDetailedMip = 0;
514 desc->u.Texture1D.MipLevels = texture_desc.MipLevels;
516 else
518 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
519 desc->u.Texture1DArray.MostDetailedMip = 0;
520 desc->u.Texture1DArray.MipLevels = texture_desc.MipLevels;
521 desc->u.Texture1DArray.FirstArraySlice = 0;
522 desc->u.Texture1DArray.ArraySize = texture_desc.ArraySize;
525 return S_OK;
528 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
530 D3D11_TEXTURE2D_DESC texture_desc;
531 ID3D11Texture2D *texture;
533 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
535 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
536 return E_INVALIDARG;
539 ID3D11Texture2D_GetDesc(texture, &texture_desc);
540 ID3D11Texture2D_Release(texture);
542 desc->Format = texture_desc.Format;
543 if (texture_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
545 if (texture_desc.ArraySize >= 12)
547 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
548 desc->u.TextureCubeArray.MostDetailedMip = 0;
549 desc->u.TextureCubeArray.MipLevels = texture_desc.MipLevels;
550 desc->u.TextureCubeArray.First2DArrayFace = 0;
551 desc->u.TextureCubeArray.NumCubes = texture_desc.ArraySize / 6;
553 else
555 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
556 desc->u.TextureCube.MostDetailedMip = 0;
557 desc->u.TextureCube.MipLevels = texture_desc.MipLevels;
560 else if (texture_desc.ArraySize == 1)
562 if (texture_desc.SampleDesc.Count == 1)
564 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
565 desc->u.Texture2D.MostDetailedMip = 0;
566 desc->u.Texture2D.MipLevels = texture_desc.MipLevels;
568 else
570 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
573 else
575 if (texture_desc.SampleDesc.Count == 1)
577 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
578 desc->u.Texture2DArray.MostDetailedMip = 0;
579 desc->u.Texture2DArray.MipLevels = texture_desc.MipLevels;
580 desc->u.Texture2DArray.FirstArraySlice = 0;
581 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
583 else
585 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
586 desc->u.Texture2DMSArray.FirstArraySlice = 0;
587 desc->u.Texture2DMSArray.ArraySize = texture_desc.ArraySize;
591 return S_OK;
594 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
596 D3D11_TEXTURE3D_DESC texture_desc;
597 ID3D11Texture3D *texture;
599 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture)))
601 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n");
602 return E_INVALIDARG;
605 ID3D11Texture3D_GetDesc(texture, &texture_desc);
606 ID3D11Texture3D_Release(texture);
608 desc->Format = texture_desc.Format;
609 desc->ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
610 desc->u.Texture3D.MostDetailedMip = 0;
611 desc->u.Texture3D.MipLevels = texture_desc.MipLevels;
613 return S_OK;
616 default:
617 WARN("Invalid resource dimension %#x.\n", dimension);
618 return E_INVALIDARG;
622 static HRESULT normalize_srv_desc(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11Resource *resource)
624 unsigned int miplevel_count, layer_count;
625 D3D11_RESOURCE_DIMENSION dimension;
626 DXGI_FORMAT format;
627 HRESULT hr;
629 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, &miplevel_count, &layer_count)))
630 return hr;
631 switch (dimension)
633 case D3D11_RESOURCE_DIMENSION_BUFFER:
634 if (desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFER
635 && desc->ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX)
637 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
638 return E_INVALIDARG;
640 if (!desc->u.Buffer.u2.NumElements)
642 WARN("Zero sized buffer view.\n");
643 return E_INVALIDARG;
645 return S_OK;
647 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
648 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1D
649 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE1DARRAY)
651 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
652 return E_INVALIDARG;
654 break;
656 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
657 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2D
658 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DARRAY
659 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMS
660 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY
661 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBE
662 && desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURECUBEARRAY)
664 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
665 return E_INVALIDARG;
667 break;
669 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
670 if (desc->ViewDimension != D3D11_SRV_DIMENSION_TEXTURE3D)
672 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
673 return E_INVALIDARG;
675 break;
677 default:
678 WARN("Invalid resource dimension %#x.\n", dimension);
679 return E_INVALIDARG;
682 if (desc->Format == DXGI_FORMAT_UNKNOWN)
683 desc->Format = format;
685 switch (desc->ViewDimension)
687 case D3D11_SRV_DIMENSION_TEXTURE1D:
688 if (desc->u.Texture1D.MipLevels == ~0u && desc->u.Texture1D.MostDetailedMip < miplevel_count)
689 desc->u.Texture1D.MipLevels = miplevel_count - desc->u.Texture1D.MostDetailedMip;
690 break;
692 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
693 if (desc->u.Texture1DArray.MipLevels == ~0u && desc->u.Texture1DArray.MostDetailedMip < miplevel_count)
694 desc->u.Texture1DArray.MipLevels = miplevel_count - desc->u.Texture1DArray.MostDetailedMip;
695 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < miplevel_count)
696 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
697 break;
699 case D3D11_SRV_DIMENSION_TEXTURE2D:
700 if (desc->u.Texture2D.MipLevels == ~0u && desc->u.Texture2D.MostDetailedMip < miplevel_count)
701 desc->u.Texture2D.MipLevels = miplevel_count - desc->u.Texture2D.MostDetailedMip;
702 break;
704 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
705 if (desc->u.Texture2DArray.MipLevels == ~0u && desc->u.Texture2DArray.MostDetailedMip < miplevel_count)
706 desc->u.Texture2DArray.MipLevels = miplevel_count - desc->u.Texture2DArray.MostDetailedMip;
707 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
708 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
709 break;
711 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
712 if (desc->u.Texture2DMSArray.ArraySize == ~0u && desc->u.Texture2DMSArray.FirstArraySlice < layer_count)
713 desc->u.Texture2DMSArray.ArraySize = layer_count - desc->u.Texture2DMSArray.FirstArraySlice;
714 break;
716 case D3D11_SRV_DIMENSION_TEXTURE3D:
717 if (desc->u.Texture3D.MipLevels == ~0u && desc->u.Texture3D.MostDetailedMip < miplevel_count)
718 desc->u.Texture3D.MipLevels = miplevel_count - desc->u.Texture3D.MostDetailedMip;
719 break;
721 case D3D11_SRV_DIMENSION_TEXTURECUBE:
722 if (desc->u.TextureCube.MipLevels == ~0u && desc->u.TextureCube.MostDetailedMip < miplevel_count)
723 desc->u.TextureCube.MipLevels = miplevel_count - desc->u.TextureCube.MostDetailedMip;
724 break;
726 case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
727 if (desc->u.TextureCubeArray.MipLevels == ~0u && desc->u.TextureCubeArray.MostDetailedMip < miplevel_count)
728 desc->u.TextureCubeArray.MipLevels = miplevel_count - desc->u.TextureCubeArray.MostDetailedMip;
729 if (desc->u.TextureCubeArray.NumCubes == ~0u && desc->u.TextureCubeArray.First2DArrayFace < layer_count)
730 desc->u.TextureCubeArray.NumCubes = (layer_count - desc->u.TextureCubeArray.First2DArrayFace) / 6;
731 break;
733 default:
734 break;
737 return S_OK;
740 static HRESULT set_uav_desc_from_resource(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource)
742 D3D11_RESOURCE_DIMENSION dimension;
744 ID3D11Resource_GetType(resource, &dimension);
746 switch (dimension)
748 case D3D11_RESOURCE_DIMENSION_BUFFER:
750 D3D11_BUFFER_DESC buffer_desc;
751 ID3D11Buffer *buffer;
753 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Buffer, (void **)&buffer)))
755 ERR("Resource of type BUFFER doesn't implement ID3D11Buffer.\n");
756 return E_INVALIDARG;
759 ID3D11Buffer_GetDesc(buffer, &buffer_desc);
760 ID3D11Buffer_Release(buffer);
762 if (buffer_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
764 desc->Format = DXGI_FORMAT_UNKNOWN;
765 desc->ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
766 desc->u.Buffer.FirstElement = 0;
767 desc->u.Buffer.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
768 desc->u.Buffer.Flags = 0;
769 return S_OK;
772 return E_INVALIDARG;
775 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
777 D3D11_TEXTURE2D_DESC texture_desc;
778 ID3D11Texture2D *texture;
780 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture2D, (void **)&texture)))
782 ERR("Resource of type TEXTURE2D doesn't implement ID3D11Texture2D.\n");
783 return E_INVALIDARG;
786 ID3D11Texture2D_GetDesc(texture, &texture_desc);
787 ID3D11Texture2D_Release(texture);
789 if (texture_desc.SampleDesc.Count != 1)
791 WARN("Trying to create view for multisample texture.\n");
792 return E_INVALIDARG;
795 desc->Format = texture_desc.Format;
796 if (texture_desc.ArraySize == 1)
798 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
799 desc->u.Texture2D.MipSlice = 0;
801 else
803 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
804 desc->u.Texture2DArray.MipSlice = 0;
805 desc->u.Texture2DArray.FirstArraySlice = 0;
806 desc->u.Texture2DArray.ArraySize = texture_desc.ArraySize;
809 return S_OK;
812 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
814 D3D11_TEXTURE3D_DESC texture_desc;
815 ID3D11Texture3D *texture;
817 if (FAILED(ID3D11Resource_QueryInterface(resource, &IID_ID3D11Texture3D, (void **)&texture)))
819 ERR("Resource of type TEXTURE3D doesn't implement ID3D11Texture3D.\n");
820 return E_INVALIDARG;
823 ID3D11Texture3D_GetDesc(texture, &texture_desc);
824 ID3D11Texture3D_Release(texture);
826 desc->Format = texture_desc.Format;
827 desc->ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
828 desc->u.Texture3D.MipSlice = 0;
829 desc->u.Texture3D.FirstWSlice = 0;
830 desc->u.Texture3D.WSize = texture_desc.Depth;
832 return S_OK;
835 default:
836 FIXME("Unhandled resource dimension %#x.\n", dimension);
837 return E_INVALIDARG;
841 static HRESULT normalize_uav_desc(D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, ID3D11Resource *resource)
843 D3D11_RESOURCE_DIMENSION dimension;
844 unsigned int layer_count;
845 DXGI_FORMAT format;
846 HRESULT hr;
848 if (FAILED(hr = get_resource_properties(resource, &dimension, &format, NULL, &layer_count)))
849 return hr;
850 switch (dimension)
852 case D3D11_RESOURCE_DIMENSION_BUFFER:
853 if (desc->ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
855 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
856 return E_INVALIDARG;
858 return S_OK;
860 case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
861 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1D
862 && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE1DARRAY)
864 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
865 return E_INVALIDARG;
867 break;
869 case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
870 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2D
871 && desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE2DARRAY)
873 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
874 return E_INVALIDARG;
876 break;
878 case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
879 if (desc->ViewDimension != D3D11_UAV_DIMENSION_TEXTURE3D)
881 WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension);
882 return E_INVALIDARG;
884 break;
886 default:
887 WARN("Invalid resource dimension %#x.\n", dimension);
888 return E_INVALIDARG;
891 if (desc->Format == DXGI_FORMAT_UNKNOWN)
892 desc->Format = format;
894 switch (desc->ViewDimension)
896 case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
897 if (desc->u.Texture1DArray.ArraySize == ~0u && desc->u.Texture1DArray.FirstArraySlice < layer_count)
898 desc->u.Texture1DArray.ArraySize = layer_count - desc->u.Texture1DArray.FirstArraySlice;
899 break;
901 case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
902 if (desc->u.Texture2DArray.ArraySize == ~0u && desc->u.Texture2DArray.FirstArraySlice < layer_count)
903 desc->u.Texture2DArray.ArraySize = layer_count - desc->u.Texture2DArray.FirstArraySlice;
904 break;
906 case D3D11_UAV_DIMENSION_TEXTURE3D:
907 layer_count = max(1, layer_count >> desc->u.Texture3D.MipSlice);
908 if (desc->u.Texture3D.WSize == ~0u && desc->u.Texture3D.FirstWSlice < layer_count)
909 desc->u.Texture3D.WSize = layer_count - desc->u.Texture3D.FirstWSlice;
910 break;
912 default:
913 break;
916 return S_OK;
919 /* ID3D11DepthStencilView methods */
921 static inline struct d3d_depthstencil_view *impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface)
923 return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D11DepthStencilView_iface);
926 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_QueryInterface(ID3D11DepthStencilView *iface,
927 REFIID riid, void **object)
929 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
931 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
933 if (IsEqualGUID(riid, &IID_ID3D11DepthStencilView)
934 || IsEqualGUID(riid, &IID_ID3D11View)
935 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
936 || IsEqualGUID(riid, &IID_IUnknown))
938 ID3D11DepthStencilView_AddRef(iface);
939 *object = iface;
940 return S_OK;
943 if (IsEqualGUID(riid, &IID_ID3D10DepthStencilView)
944 || IsEqualGUID(riid, &IID_ID3D10View)
945 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
947 ID3D10DepthStencilView_AddRef(&view->ID3D10DepthStencilView_iface);
948 *object = &view->ID3D10DepthStencilView_iface;
949 return S_OK;
952 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
954 *object = NULL;
955 return E_NOINTERFACE;
958 static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_AddRef(ID3D11DepthStencilView *iface)
960 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
961 ULONG refcount = InterlockedIncrement(&view->refcount);
963 TRACE("%p increasing refcount to %u.\n", view, refcount);
965 if (refcount == 1)
967 ID3D11Device2_AddRef(view->device);
968 wined3d_mutex_lock();
969 wined3d_rendertarget_view_incref(view->wined3d_view);
970 wined3d_mutex_unlock();
973 return refcount;
976 static ULONG STDMETHODCALLTYPE d3d11_depthstencil_view_Release(ID3D11DepthStencilView *iface)
978 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
979 ULONG refcount = InterlockedDecrement(&view->refcount);
981 TRACE("%p decreasing refcount to %u.\n", view, refcount);
983 if (!refcount)
985 ID3D11Device2 *device = view->device;
987 wined3d_mutex_lock();
988 wined3d_rendertarget_view_decref(view->wined3d_view);
989 wined3d_mutex_unlock();
991 ID3D11Device2_Release(device);
994 return refcount;
997 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDevice(ID3D11DepthStencilView *iface,
998 ID3D11Device **device)
1000 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1002 TRACE("iface %p, device %p.\n", iface, device);
1004 *device = (ID3D11Device *)view->device;
1005 ID3D11Device_AddRef(*device);
1008 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_GetPrivateData(ID3D11DepthStencilView *iface,
1009 REFGUID guid, UINT *data_size, void *data)
1011 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1013 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1015 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1018 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateData(ID3D11DepthStencilView *iface,
1019 REFGUID guid, UINT data_size, const void *data)
1021 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1023 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1025 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1028 static HRESULT STDMETHODCALLTYPE d3d11_depthstencil_view_SetPrivateDataInterface(ID3D11DepthStencilView *iface,
1029 REFGUID guid, const IUnknown *data)
1031 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1033 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1035 return d3d_set_private_data_interface(&view->private_store, guid, data);
1038 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetResource(ID3D11DepthStencilView *iface,
1039 ID3D11Resource **resource)
1041 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1043 TRACE("iface %p, resource %p.\n", iface, resource);
1045 *resource = view->resource;
1046 ID3D11Resource_AddRef(*resource);
1049 static void STDMETHODCALLTYPE d3d11_depthstencil_view_GetDesc(ID3D11DepthStencilView *iface,
1050 D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1052 struct d3d_depthstencil_view *view = impl_from_ID3D11DepthStencilView(iface);
1054 TRACE("iface %p, desc %p.\n", iface, desc);
1056 *desc = view->desc;
1059 static const struct ID3D11DepthStencilViewVtbl d3d11_depthstencil_view_vtbl =
1061 /* IUnknown methods */
1062 d3d11_depthstencil_view_QueryInterface,
1063 d3d11_depthstencil_view_AddRef,
1064 d3d11_depthstencil_view_Release,
1065 /* ID3D11DeviceChild methods */
1066 d3d11_depthstencil_view_GetDevice,
1067 d3d11_depthstencil_view_GetPrivateData,
1068 d3d11_depthstencil_view_SetPrivateData,
1069 d3d11_depthstencil_view_SetPrivateDataInterface,
1070 /* ID3D11View methods */
1071 d3d11_depthstencil_view_GetResource,
1072 /* ID3D11DepthStencilView methods */
1073 d3d11_depthstencil_view_GetDesc,
1076 /* ID3D10DepthStencilView methods */
1078 static inline struct d3d_depthstencil_view *impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface)
1080 return CONTAINING_RECORD(iface, struct d3d_depthstencil_view, ID3D10DepthStencilView_iface);
1083 /* IUnknown methods */
1085 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_QueryInterface(ID3D10DepthStencilView *iface,
1086 REFIID riid, void **object)
1088 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1090 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1092 return d3d11_depthstencil_view_QueryInterface(&view->ID3D11DepthStencilView_iface, riid, object);
1095 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_AddRef(ID3D10DepthStencilView *iface)
1097 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1099 TRACE("iface %p.\n", iface);
1101 return d3d11_depthstencil_view_AddRef(&view->ID3D11DepthStencilView_iface);
1104 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_view_Release(ID3D10DepthStencilView *iface)
1106 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1108 TRACE("iface %p.\n", iface);
1110 return d3d11_depthstencil_view_Release(&view->ID3D11DepthStencilView_iface);
1113 /* ID3D10DeviceChild methods */
1115 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDevice(ID3D10DepthStencilView *iface, ID3D10Device **device)
1117 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1119 TRACE("iface %p, device %p.\n", iface, device);
1121 ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
1124 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_GetPrivateData(ID3D10DepthStencilView *iface,
1125 REFGUID guid, UINT *data_size, void *data)
1127 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1129 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1130 iface, debugstr_guid(guid), data_size, data);
1132 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1135 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateData(ID3D10DepthStencilView *iface,
1136 REFGUID guid, UINT data_size, const void *data)
1138 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1140 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1141 iface, debugstr_guid(guid), data_size, data);
1143 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1146 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_view_SetPrivateDataInterface(ID3D10DepthStencilView *iface,
1147 REFGUID guid, const IUnknown *data)
1149 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1151 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1153 return d3d_set_private_data_interface(&view->private_store, guid, data);
1156 /* ID3D10View methods */
1158 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetResource(ID3D10DepthStencilView *iface,
1159 ID3D10Resource **resource)
1161 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1163 TRACE("iface %p, resource %p.\n", iface, resource);
1165 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
1168 /* ID3D10DepthStencilView methods */
1170 static void STDMETHODCALLTYPE d3d10_depthstencil_view_GetDesc(ID3D10DepthStencilView *iface,
1171 D3D10_DEPTH_STENCIL_VIEW_DESC *desc)
1173 struct d3d_depthstencil_view *view = impl_from_ID3D10DepthStencilView(iface);
1174 const D3D11_DEPTH_STENCIL_VIEW_DESC *d3d11_desc = &view->desc;
1176 TRACE("iface %p, desc %p.\n", iface, desc);
1178 desc->Format = d3d11_desc->Format;
1179 desc->ViewDimension = (D3D10_DSV_DIMENSION)d3d11_desc->ViewDimension;
1180 memcpy(&desc->u, &d3d11_desc->u, sizeof(desc->u));
1183 static const struct ID3D10DepthStencilViewVtbl d3d10_depthstencil_view_vtbl =
1185 /* IUnknown methods */
1186 d3d10_depthstencil_view_QueryInterface,
1187 d3d10_depthstencil_view_AddRef,
1188 d3d10_depthstencil_view_Release,
1189 /* ID3D10DeviceChild methods */
1190 d3d10_depthstencil_view_GetDevice,
1191 d3d10_depthstencil_view_GetPrivateData,
1192 d3d10_depthstencil_view_SetPrivateData,
1193 d3d10_depthstencil_view_SetPrivateDataInterface,
1194 /* ID3D10View methods */
1195 d3d10_depthstencil_view_GetResource,
1196 /* ID3D10DepthStencilView methods */
1197 d3d10_depthstencil_view_GetDesc,
1200 static void STDMETHODCALLTYPE d3d_depth_stencil_view_wined3d_object_destroyed(void *parent)
1202 struct d3d_depthstencil_view *view = parent;
1204 wined3d_private_store_cleanup(&view->private_store);
1205 heap_free(parent);
1208 static const struct wined3d_parent_ops d3d_depth_stencil_view_wined3d_parent_ops =
1210 d3d_depth_stencil_view_wined3d_object_destroyed,
1213 static void wined3d_depth_stencil_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
1214 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1216 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
1218 if (desc->Flags)
1219 FIXME("Unhandled depth stencil view flags %#x.\n", desc->Flags);
1221 wined3d_desc->flags = 0;
1222 wined3d_desc->u.texture.level_count = 1;
1223 switch (desc->ViewDimension)
1225 case D3D11_DSV_DIMENSION_TEXTURE1D:
1226 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
1227 wined3d_desc->u.texture.layer_idx = 0;
1228 wined3d_desc->u.texture.layer_count = 1;
1229 break;
1231 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
1232 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1233 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
1234 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
1235 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
1236 break;
1238 case D3D11_DSV_DIMENSION_TEXTURE2D:
1239 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
1240 wined3d_desc->u.texture.layer_idx = 0;
1241 wined3d_desc->u.texture.layer_count = 1;
1242 break;
1244 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
1245 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1246 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
1247 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
1248 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
1249 break;
1251 case D3D11_DSV_DIMENSION_TEXTURE2DMS:
1252 wined3d_desc->u.texture.level_idx = 0;
1253 wined3d_desc->u.texture.layer_idx = 0;
1254 wined3d_desc->u.texture.layer_count = 1;
1255 break;
1257 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
1258 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1259 wined3d_desc->u.texture.level_idx = 0;
1260 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
1261 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
1262 break;
1264 default:
1265 FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension);
1266 wined3d_desc->u.texture.level_idx = 0;
1267 wined3d_desc->u.texture.layer_idx = 0;
1268 wined3d_desc->u.texture.layer_count = 1;
1269 break;
1273 static HRESULT d3d_depthstencil_view_init(struct d3d_depthstencil_view *view, struct d3d_device *device,
1274 ID3D11Resource *resource, const D3D11_DEPTH_STENCIL_VIEW_DESC *desc)
1276 struct wined3d_resource *wined3d_resource;
1277 struct wined3d_view_desc wined3d_desc;
1278 HRESULT hr;
1280 view->ID3D11DepthStencilView_iface.lpVtbl = &d3d11_depthstencil_view_vtbl;
1281 view->ID3D10DepthStencilView_iface.lpVtbl = &d3d10_depthstencil_view_vtbl;
1282 view->refcount = 1;
1284 if (!desc)
1286 hr = set_dsv_desc_from_resource(&view->desc, resource);
1288 else
1290 view->desc = *desc;
1291 hr = normalize_dsv_desc(&view->desc, resource);
1293 if (FAILED(hr))
1294 return hr;
1296 wined3d_mutex_lock();
1297 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
1299 wined3d_mutex_unlock();
1300 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
1301 return E_FAIL;
1304 wined3d_depth_stencil_view_desc_from_d3d11(&wined3d_desc, &view->desc);
1305 if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource,
1306 view, &d3d_depth_stencil_view_wined3d_parent_ops, &view->wined3d_view)))
1308 wined3d_mutex_unlock();
1309 WARN("Failed to create a wined3d rendertarget view, hr %#x.\n", hr);
1310 return hr;
1313 wined3d_private_store_init(&view->private_store);
1314 wined3d_mutex_unlock();
1315 view->resource = resource;
1316 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
1318 return S_OK;
1321 HRESULT d3d_depthstencil_view_create(struct d3d_device *device, ID3D11Resource *resource,
1322 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, struct d3d_depthstencil_view **view)
1324 struct d3d_depthstencil_view *object;
1325 HRESULT hr;
1327 if (!(object = heap_alloc_zero(sizeof(*object))))
1328 return E_OUTOFMEMORY;
1330 if (FAILED(hr = d3d_depthstencil_view_init(object, device, resource, desc)))
1332 WARN("Failed to initialize depthstencil view, hr %#x.\n", hr);
1333 heap_free(object);
1334 return hr;
1337 TRACE("Created depthstencil view %p.\n", object);
1338 *view = object;
1340 return S_OK;
1343 struct d3d_depthstencil_view *unsafe_impl_from_ID3D11DepthStencilView(ID3D11DepthStencilView *iface)
1345 if (!iface)
1346 return NULL;
1347 assert(iface->lpVtbl == &d3d11_depthstencil_view_vtbl);
1349 return impl_from_ID3D11DepthStencilView(iface);
1352 struct d3d_depthstencil_view *unsafe_impl_from_ID3D10DepthStencilView(ID3D10DepthStencilView *iface)
1354 if (!iface)
1355 return NULL;
1356 assert(iface->lpVtbl == &d3d10_depthstencil_view_vtbl);
1358 return impl_from_ID3D10DepthStencilView(iface);
1361 /* ID3D11RenderTargetView methods */
1363 static inline struct d3d_rendertarget_view *impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface)
1365 return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D11RenderTargetView_iface);
1368 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_QueryInterface(ID3D11RenderTargetView *iface,
1369 REFIID riid, void **object)
1371 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1373 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1375 if (IsEqualGUID(riid, &IID_ID3D11RenderTargetView)
1376 || IsEqualGUID(riid, &IID_ID3D11View)
1377 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1378 || IsEqualGUID(riid, &IID_IUnknown))
1380 ID3D11RenderTargetView_AddRef(iface);
1381 *object = iface;
1382 return S_OK;
1385 if (IsEqualGUID(riid, &IID_ID3D10RenderTargetView)
1386 || IsEqualGUID(riid, &IID_ID3D10View)
1387 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1389 ID3D10RenderTargetView_AddRef(&view->ID3D10RenderTargetView_iface);
1390 *object = &view->ID3D10RenderTargetView_iface;
1391 return S_OK;
1394 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1396 *object = NULL;
1397 return E_NOINTERFACE;
1400 static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_AddRef(ID3D11RenderTargetView *iface)
1402 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1403 ULONG refcount = InterlockedIncrement(&view->refcount);
1405 TRACE("%p increasing refcount to %u.\n", view, refcount);
1407 if (refcount == 1)
1409 ID3D11Device2_AddRef(view->device);
1410 wined3d_mutex_lock();
1411 wined3d_rendertarget_view_incref(view->wined3d_view);
1412 wined3d_mutex_unlock();
1415 return refcount;
1418 static ULONG STDMETHODCALLTYPE d3d11_rendertarget_view_Release(ID3D11RenderTargetView *iface)
1420 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1421 ULONG refcount = InterlockedDecrement(&view->refcount);
1423 TRACE("%p decreasing refcount to %u.\n", view, refcount);
1425 if (!refcount)
1427 ID3D11Device2 *device = view->device;
1429 wined3d_mutex_lock();
1430 wined3d_rendertarget_view_decref(view->wined3d_view);
1431 wined3d_mutex_unlock();
1433 ID3D11Device2_Release(device);
1436 return refcount;
1439 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDevice(ID3D11RenderTargetView *iface,
1440 ID3D11Device **device)
1442 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1444 TRACE("iface %p, device %p.\n", iface, device);
1446 *device = (ID3D11Device *)view->device;
1447 ID3D11Device_AddRef(*device);
1450 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_GetPrivateData(ID3D11RenderTargetView *iface,
1451 REFGUID guid, UINT *data_size, void *data)
1453 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1455 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1457 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1460 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateData(ID3D11RenderTargetView *iface,
1461 REFGUID guid, UINT data_size, const void *data)
1463 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1465 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1467 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1470 static HRESULT STDMETHODCALLTYPE d3d11_rendertarget_view_SetPrivateDataInterface(ID3D11RenderTargetView *iface,
1471 REFGUID guid, const IUnknown *data)
1473 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1475 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1477 return d3d_set_private_data_interface(&view->private_store, guid, data);
1480 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetResource(ID3D11RenderTargetView *iface,
1481 ID3D11Resource **resource)
1483 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1485 TRACE("iface %p, resource %p.\n", iface, resource);
1487 *resource = view->resource;
1488 ID3D11Resource_AddRef(*resource);
1491 static void STDMETHODCALLTYPE d3d11_rendertarget_view_GetDesc(ID3D11RenderTargetView *iface,
1492 D3D11_RENDER_TARGET_VIEW_DESC *desc)
1494 struct d3d_rendertarget_view *view = impl_from_ID3D11RenderTargetView(iface);
1496 TRACE("iface %p, desc %p.\n", iface, desc);
1498 *desc = view->desc;
1501 static const struct ID3D11RenderTargetViewVtbl d3d11_rendertarget_view_vtbl =
1503 /* IUnknown methods */
1504 d3d11_rendertarget_view_QueryInterface,
1505 d3d11_rendertarget_view_AddRef,
1506 d3d11_rendertarget_view_Release,
1507 /* ID3D11DeviceChild methods */
1508 d3d11_rendertarget_view_GetDevice,
1509 d3d11_rendertarget_view_GetPrivateData,
1510 d3d11_rendertarget_view_SetPrivateData,
1511 d3d11_rendertarget_view_SetPrivateDataInterface,
1512 /* ID3D11View methods */
1513 d3d11_rendertarget_view_GetResource,
1514 /* ID3D11RenderTargetView methods */
1515 d3d11_rendertarget_view_GetDesc,
1518 /* ID3D10RenderTargetView methods */
1520 static inline struct d3d_rendertarget_view *impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface)
1522 return CONTAINING_RECORD(iface, struct d3d_rendertarget_view, ID3D10RenderTargetView_iface);
1525 /* IUnknown methods */
1527 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_QueryInterface(ID3D10RenderTargetView *iface,
1528 REFIID riid, void **object)
1530 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1532 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1534 return d3d11_rendertarget_view_QueryInterface(&view->ID3D11RenderTargetView_iface, riid, object);
1537 static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_AddRef(ID3D10RenderTargetView *iface)
1539 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1541 TRACE("iface %p.\n", iface);
1543 return d3d11_rendertarget_view_AddRef(&view->ID3D11RenderTargetView_iface);
1546 static ULONG STDMETHODCALLTYPE d3d10_rendertarget_view_Release(ID3D10RenderTargetView *iface)
1548 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1550 TRACE("iface %p.\n", iface);
1552 return d3d11_rendertarget_view_Release(&view->ID3D11RenderTargetView_iface);
1555 /* ID3D10DeviceChild methods */
1557 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDevice(ID3D10RenderTargetView *iface, ID3D10Device **device)
1559 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1561 TRACE("iface %p, device %p.\n", iface, device);
1563 ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
1566 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_GetPrivateData(ID3D10RenderTargetView *iface,
1567 REFGUID guid, UINT *data_size, void *data)
1569 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1571 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1572 iface, debugstr_guid(guid), data_size, data);
1574 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1577 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateData(ID3D10RenderTargetView *iface,
1578 REFGUID guid, UINT data_size, const void *data)
1580 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1582 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1583 iface, debugstr_guid(guid), data_size, data);
1585 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1588 static HRESULT STDMETHODCALLTYPE d3d10_rendertarget_view_SetPrivateDataInterface(ID3D10RenderTargetView *iface,
1589 REFGUID guid, const IUnknown *data)
1591 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1593 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1595 return d3d_set_private_data_interface(&view->private_store, guid, data);
1598 /* ID3D10View methods */
1600 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetResource(ID3D10RenderTargetView *iface,
1601 ID3D10Resource **resource)
1603 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1605 TRACE("iface %p, resource %p\n", iface, resource);
1607 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
1610 /* ID3D10RenderTargetView methods */
1612 static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetDesc(ID3D10RenderTargetView *iface,
1613 D3D10_RENDER_TARGET_VIEW_DESC *desc)
1615 struct d3d_rendertarget_view *view = impl_from_ID3D10RenderTargetView(iface);
1617 TRACE("iface %p, desc %p\n", iface, desc);
1619 memcpy(desc, &view->desc, sizeof(*desc));
1622 static const struct ID3D10RenderTargetViewVtbl d3d10_rendertarget_view_vtbl =
1624 /* IUnknown methods */
1625 d3d10_rendertarget_view_QueryInterface,
1626 d3d10_rendertarget_view_AddRef,
1627 d3d10_rendertarget_view_Release,
1628 /* ID3D10DeviceChild methods */
1629 d3d10_rendertarget_view_GetDevice,
1630 d3d10_rendertarget_view_GetPrivateData,
1631 d3d10_rendertarget_view_SetPrivateData,
1632 d3d10_rendertarget_view_SetPrivateDataInterface,
1633 /* ID3D10View methods */
1634 d3d10_rendertarget_view_GetResource,
1635 /* ID3D10RenderTargetView methods */
1636 d3d10_rendertarget_view_GetDesc,
1639 static void STDMETHODCALLTYPE d3d_render_target_view_wined3d_object_destroyed(void *parent)
1641 struct d3d_rendertarget_view *view = parent;
1643 wined3d_private_store_cleanup(&view->private_store);
1644 heap_free(parent);
1647 static const struct wined3d_parent_ops d3d_render_target_view_wined3d_parent_ops =
1649 d3d_render_target_view_wined3d_object_destroyed,
1652 static void wined3d_rendertarget_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
1653 const D3D11_RENDER_TARGET_VIEW_DESC *desc)
1655 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
1657 wined3d_desc->flags = 0;
1658 wined3d_desc->u.texture.level_count = 1;
1659 switch (desc->ViewDimension)
1661 case D3D11_RTV_DIMENSION_BUFFER:
1662 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement;
1663 wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements;
1664 break;
1666 case D3D11_RTV_DIMENSION_TEXTURE1D:
1667 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
1668 wined3d_desc->u.texture.layer_idx = 0;
1669 wined3d_desc->u.texture.layer_count = 1;
1670 break;
1672 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
1673 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1674 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
1675 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
1676 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
1677 break;
1679 case D3D11_RTV_DIMENSION_TEXTURE2D:
1680 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
1681 wined3d_desc->u.texture.layer_idx = 0;
1682 wined3d_desc->u.texture.layer_count = 1;
1683 break;
1685 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
1686 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1687 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
1688 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
1689 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
1690 break;
1692 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
1693 wined3d_desc->u.texture.level_idx = 0;
1694 wined3d_desc->u.texture.layer_idx = 0;
1695 wined3d_desc->u.texture.layer_count = 1;
1696 break;
1698 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
1699 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
1700 wined3d_desc->u.texture.level_idx = 0;
1701 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
1702 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
1703 break;
1705 case D3D11_RTV_DIMENSION_TEXTURE3D:
1706 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice;
1707 wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice;
1708 wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize;
1709 break;
1711 default:
1712 FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension);
1713 wined3d_desc->u.texture.level_idx = 0;
1714 wined3d_desc->u.texture.layer_idx = 0;
1715 wined3d_desc->u.texture.layer_count = 1;
1716 break;
1720 static HRESULT d3d_rendertarget_view_init(struct d3d_rendertarget_view *view, struct d3d_device *device,
1721 ID3D11Resource *resource, const D3D11_RENDER_TARGET_VIEW_DESC *desc)
1723 struct wined3d_resource *wined3d_resource;
1724 struct wined3d_view_desc wined3d_desc;
1725 HRESULT hr;
1727 view->ID3D11RenderTargetView_iface.lpVtbl = &d3d11_rendertarget_view_vtbl;
1728 view->ID3D10RenderTargetView_iface.lpVtbl = &d3d10_rendertarget_view_vtbl;
1729 view->refcount = 1;
1731 if (!desc)
1733 hr = set_rtv_desc_from_resource(&view->desc, resource);
1735 else
1737 view->desc = *desc;
1738 hr = normalize_rtv_desc(&view->desc, resource);
1740 if (FAILED(hr))
1741 return hr;
1743 wined3d_mutex_lock();
1744 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
1746 wined3d_mutex_unlock();
1747 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
1748 return E_FAIL;
1751 wined3d_rendertarget_view_desc_from_d3d11(&wined3d_desc, &view->desc);
1752 if (FAILED(hr = wined3d_rendertarget_view_create(&wined3d_desc, wined3d_resource,
1753 view, &d3d_render_target_view_wined3d_parent_ops, &view->wined3d_view)))
1755 wined3d_mutex_unlock();
1756 WARN("Failed to create a wined3d rendertarget view, hr %#x.\n", hr);
1757 return hr;
1760 wined3d_private_store_init(&view->private_store);
1761 wined3d_mutex_unlock();
1762 view->resource = resource;
1763 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
1765 return S_OK;
1768 HRESULT d3d_rendertarget_view_create(struct d3d_device *device, ID3D11Resource *resource,
1769 const D3D11_RENDER_TARGET_VIEW_DESC *desc, struct d3d_rendertarget_view **view)
1771 struct d3d_rendertarget_view *object;
1772 HRESULT hr;
1774 if (!(object = heap_alloc_zero(sizeof(*object))))
1775 return E_OUTOFMEMORY;
1777 if (FAILED(hr = d3d_rendertarget_view_init(object, device, resource, desc)))
1779 WARN("Failed to initialize rendertarget view, hr %#x.\n", hr);
1780 heap_free(object);
1781 return hr;
1784 TRACE("Created rendertarget view %p.\n", object);
1785 *view = object;
1787 return S_OK;
1790 struct d3d_rendertarget_view *unsafe_impl_from_ID3D11RenderTargetView(ID3D11RenderTargetView *iface)
1792 if (!iface)
1793 return NULL;
1794 assert(iface->lpVtbl == &d3d11_rendertarget_view_vtbl);
1796 return impl_from_ID3D11RenderTargetView(iface);
1799 struct d3d_rendertarget_view *unsafe_impl_from_ID3D10RenderTargetView(ID3D10RenderTargetView *iface)
1801 if (!iface)
1802 return NULL;
1803 assert(iface->lpVtbl == &d3d10_rendertarget_view_vtbl);
1805 return impl_from_ID3D10RenderTargetView(iface);
1808 /* ID3D11ShaderResourceView methods */
1810 static inline struct d3d_shader_resource_view *impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface)
1812 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D11ShaderResourceView_iface);
1815 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_QueryInterface(ID3D11ShaderResourceView *iface,
1816 REFIID riid, void **object)
1818 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1820 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1822 if (IsEqualGUID(riid, &IID_ID3D11ShaderResourceView)
1823 || IsEqualGUID(riid, &IID_ID3D11View)
1824 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1825 || IsEqualGUID(riid, &IID_IUnknown))
1827 ID3D11ShaderResourceView_AddRef(iface);
1828 *object = iface;
1829 return S_OK;
1832 if (IsEqualGUID(riid, &IID_ID3D10ShaderResourceView1)
1833 || IsEqualGUID(riid, &IID_ID3D10ShaderResourceView)
1834 || IsEqualGUID(riid, &IID_ID3D10View)
1835 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1837 ID3D10ShaderResourceView1_AddRef(&view->ID3D10ShaderResourceView1_iface);
1838 *object = &view->ID3D10ShaderResourceView1_iface;
1839 return S_OK;
1842 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1844 *object = NULL;
1845 return E_NOINTERFACE;
1848 static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_AddRef(ID3D11ShaderResourceView *iface)
1850 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1851 ULONG refcount = InterlockedIncrement(&view->refcount);
1853 TRACE("%p increasing refcount to %u.\n", view, refcount);
1855 if (refcount == 1)
1857 ID3D11Device2_AddRef(view->device);
1858 wined3d_mutex_lock();
1859 wined3d_shader_resource_view_incref(view->wined3d_view);
1860 wined3d_mutex_unlock();
1863 return refcount;
1866 static ULONG STDMETHODCALLTYPE d3d11_shader_resource_view_Release(ID3D11ShaderResourceView *iface)
1868 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1869 ULONG refcount = InterlockedDecrement(&view->refcount);
1871 TRACE("%p decreasing refcount to %u.\n", view, refcount);
1873 if (!refcount)
1875 ID3D11Device2 *device = view->device;
1877 wined3d_mutex_lock();
1878 wined3d_shader_resource_view_decref(view->wined3d_view);
1879 wined3d_mutex_unlock();
1881 ID3D11Device2_Release(device);
1884 return refcount;
1887 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDevice(ID3D11ShaderResourceView *iface,
1888 ID3D11Device **device)
1890 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1892 TRACE("iface %p, device %p.\n", iface, device);
1894 *device = (ID3D11Device *)view->device;
1895 ID3D11Device_AddRef(*device);
1898 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_GetPrivateData(ID3D11ShaderResourceView *iface,
1899 REFGUID guid, UINT *data_size, void *data)
1901 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1903 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1905 return d3d_get_private_data(&view->private_store, guid, data_size, data);
1908 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateData(ID3D11ShaderResourceView *iface,
1909 REFGUID guid, UINT data_size, const void *data)
1911 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1913 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1915 return d3d_set_private_data(&view->private_store, guid, data_size, data);
1918 static HRESULT STDMETHODCALLTYPE d3d11_shader_resource_view_SetPrivateDataInterface(ID3D11ShaderResourceView *iface,
1919 REFGUID guid, const IUnknown *data)
1921 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1923 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1925 return d3d_set_private_data_interface(&view->private_store, guid, data);
1928 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetResource(ID3D11ShaderResourceView *iface,
1929 ID3D11Resource **resource)
1931 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1933 TRACE("iface %p, resource %p.\n", iface, resource);
1935 *resource = view->resource;
1936 ID3D11Resource_AddRef(*resource);
1939 static void STDMETHODCALLTYPE d3d11_shader_resource_view_GetDesc(ID3D11ShaderResourceView *iface,
1940 D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
1942 struct d3d_shader_resource_view *view = impl_from_ID3D11ShaderResourceView(iface);
1944 TRACE("iface %p, desc %p.\n", iface, desc);
1946 *desc = view->desc;
1949 static const struct ID3D11ShaderResourceViewVtbl d3d11_shader_resource_view_vtbl =
1951 /* IUnknown methods */
1952 d3d11_shader_resource_view_QueryInterface,
1953 d3d11_shader_resource_view_AddRef,
1954 d3d11_shader_resource_view_Release,
1955 /* ID3D11DeviceChild methods */
1956 d3d11_shader_resource_view_GetDevice,
1957 d3d11_shader_resource_view_GetPrivateData,
1958 d3d11_shader_resource_view_SetPrivateData,
1959 d3d11_shader_resource_view_SetPrivateDataInterface,
1960 /* ID3D11View methods */
1961 d3d11_shader_resource_view_GetResource,
1962 /* ID3D11ShaderResourceView methods */
1963 d3d11_shader_resource_view_GetDesc,
1966 /* ID3D10ShaderResourceView methods */
1968 static inline struct d3d_shader_resource_view *impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView1 *iface)
1970 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface);
1973 /* IUnknown methods */
1975 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_QueryInterface(ID3D10ShaderResourceView1 *iface,
1976 REFIID riid, void **object)
1978 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
1980 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1982 return d3d11_shader_resource_view_QueryInterface(&view->ID3D11ShaderResourceView_iface, riid, object);
1985 static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_AddRef(ID3D10ShaderResourceView1 *iface)
1987 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
1989 TRACE("iface %p.\n", iface);
1991 return d3d11_shader_resource_view_AddRef(&view->ID3D11ShaderResourceView_iface);
1994 static ULONG STDMETHODCALLTYPE d3d10_shader_resource_view_Release(ID3D10ShaderResourceView1 *iface)
1996 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
1998 TRACE("iface %p.\n", iface);
2000 return d3d11_shader_resource_view_Release(&view->ID3D11ShaderResourceView_iface);
2003 /* ID3D10DeviceChild methods */
2005 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDevice(ID3D10ShaderResourceView1 *iface,
2006 ID3D10Device **device)
2008 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2010 TRACE("iface %p, device %p.\n", iface, device);
2012 ID3D11Device2_QueryInterface(view->device, &IID_ID3D10Device, (void **)device);
2015 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_GetPrivateData(ID3D10ShaderResourceView1 *iface,
2016 REFGUID guid, UINT *data_size, void *data)
2018 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2020 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
2021 iface, debugstr_guid(guid), data_size, data);
2023 return d3d_get_private_data(&view->private_store, guid, data_size, data);
2026 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateData(ID3D10ShaderResourceView1 *iface,
2027 REFGUID guid, UINT data_size, const void *data)
2029 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2031 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
2032 iface, debugstr_guid(guid), data_size, data);
2034 return d3d_set_private_data(&view->private_store, guid, data_size, data);
2037 static HRESULT STDMETHODCALLTYPE d3d10_shader_resource_view_SetPrivateDataInterface(ID3D10ShaderResourceView1 *iface,
2038 REFGUID guid, const IUnknown *data)
2040 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2042 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2044 return d3d_set_private_data_interface(&view->private_store, guid, data);
2047 /* ID3D10View methods */
2049 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetResource(ID3D10ShaderResourceView1 *iface,
2050 ID3D10Resource **resource)
2052 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2054 TRACE("iface %p, resource %p.\n", iface, resource);
2056 ID3D11Resource_QueryInterface(view->resource, &IID_ID3D10Resource, (void **)resource);
2059 /* ID3D10ShaderResourceView methods */
2061 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc(ID3D10ShaderResourceView1 *iface,
2062 D3D10_SHADER_RESOURCE_VIEW_DESC *desc)
2064 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2066 TRACE("iface %p, desc %p.\n", iface, desc);
2068 memcpy(desc, &view->desc, sizeof(*desc));
2071 static void STDMETHODCALLTYPE d3d10_shader_resource_view_GetDesc1(ID3D10ShaderResourceView1 *iface,
2072 D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc)
2074 struct d3d_shader_resource_view *view = impl_from_ID3D10ShaderResourceView(iface);
2076 TRACE("iface %p, desc %p.\n", iface, desc);
2078 memcpy(desc, &view->desc, sizeof(*desc));
2081 static const struct ID3D10ShaderResourceView1Vtbl d3d10_shader_resource_view_vtbl =
2083 /* IUnknown methods */
2084 d3d10_shader_resource_view_QueryInterface,
2085 d3d10_shader_resource_view_AddRef,
2086 d3d10_shader_resource_view_Release,
2087 /* ID3D10DeviceChild methods */
2088 d3d10_shader_resource_view_GetDevice,
2089 d3d10_shader_resource_view_GetPrivateData,
2090 d3d10_shader_resource_view_SetPrivateData,
2091 d3d10_shader_resource_view_SetPrivateDataInterface,
2092 /* ID3D10View methods */
2093 d3d10_shader_resource_view_GetResource,
2094 /* ID3D10ShaderResourceView methods */
2095 d3d10_shader_resource_view_GetDesc,
2096 /* ID3D10ShaderResourceView1 methods */
2097 d3d10_shader_resource_view_GetDesc1,
2100 static void STDMETHODCALLTYPE d3d_shader_resource_view_wined3d_object_destroyed(void *parent)
2102 struct d3d_shader_resource_view *view = parent;
2104 wined3d_private_store_cleanup(&view->private_store);
2105 heap_free(parent);
2108 static const struct wined3d_parent_ops d3d_shader_resource_view_wined3d_parent_ops =
2110 d3d_shader_resource_view_wined3d_object_destroyed,
2113 static unsigned int wined3d_view_flags_from_d3d11_bufferex_flags(unsigned int d3d11_flags)
2115 unsigned int wined3d_flags = d3d11_flags & WINED3D_VIEW_BUFFER_RAW;
2117 if (d3d11_flags != wined3d_flags)
2118 FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags);
2120 return wined3d_flags;
2123 static HRESULT wined3d_shader_resource_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
2124 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
2126 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
2127 wined3d_desc->flags = 0;
2129 switch (desc->ViewDimension)
2131 case D3D11_SRV_DIMENSION_BUFFER:
2132 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.u1.FirstElement;
2133 wined3d_desc->u.buffer.count = desc->u.Buffer.u2.NumElements;
2134 break;
2136 case D3D11_SRV_DIMENSION_TEXTURE1D:
2137 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MostDetailedMip;
2138 wined3d_desc->u.texture.level_count = desc->u.Texture1D.MipLevels;
2139 wined3d_desc->u.texture.layer_idx = 0;
2140 wined3d_desc->u.texture.layer_count = 1;
2141 break;
2143 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
2144 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2145 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MostDetailedMip;
2146 wined3d_desc->u.texture.level_count = desc->u.Texture1DArray.MipLevels;
2147 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
2148 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
2149 break;
2151 case D3D11_SRV_DIMENSION_TEXTURE2D:
2152 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MostDetailedMip;
2153 wined3d_desc->u.texture.level_count = desc->u.Texture2D.MipLevels;
2154 wined3d_desc->u.texture.layer_idx = 0;
2155 wined3d_desc->u.texture.layer_count = 1;
2156 break;
2158 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
2159 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2160 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MostDetailedMip;
2161 wined3d_desc->u.texture.level_count = desc->u.Texture2DArray.MipLevels;
2162 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
2163 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
2164 break;
2166 case D3D11_SRV_DIMENSION_TEXTURE2DMS:
2167 wined3d_desc->u.texture.level_idx = 0;
2168 wined3d_desc->u.texture.level_count = 1;
2169 wined3d_desc->u.texture.layer_idx = 0;
2170 wined3d_desc->u.texture.layer_count = 1;
2171 break;
2173 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
2174 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2175 wined3d_desc->u.texture.level_idx = 0;
2176 wined3d_desc->u.texture.level_count = 1;
2177 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DMSArray.FirstArraySlice;
2178 wined3d_desc->u.texture.layer_count = desc->u.Texture2DMSArray.ArraySize;
2179 break;
2181 case D3D11_SRV_DIMENSION_TEXTURE3D:
2182 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MostDetailedMip;
2183 wined3d_desc->u.texture.level_count = desc->u.Texture3D.MipLevels;
2184 wined3d_desc->u.texture.layer_idx = 0;
2185 wined3d_desc->u.texture.layer_count = 1;
2186 break;
2188 case D3D11_SRV_DIMENSION_TEXTURECUBE:
2189 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE;
2190 wined3d_desc->u.texture.level_idx = desc->u.TextureCube.MostDetailedMip;
2191 wined3d_desc->u.texture.level_count = desc->u.TextureCube.MipLevels;
2192 wined3d_desc->u.texture.layer_idx = 0;
2193 wined3d_desc->u.texture.layer_count = 6;
2194 break;
2196 case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
2197 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_CUBE | WINED3D_VIEW_TEXTURE_ARRAY;
2198 wined3d_desc->u.texture.level_idx = desc->u.TextureCubeArray.MostDetailedMip;
2199 wined3d_desc->u.texture.level_count = desc->u.TextureCubeArray.MipLevels;
2200 wined3d_desc->u.texture.layer_idx = desc->u.TextureCubeArray.First2DArrayFace;
2201 wined3d_desc->u.texture.layer_count = 6 * desc->u.TextureCubeArray.NumCubes;
2202 break;
2204 case D3D11_SRV_DIMENSION_BUFFEREX:
2205 wined3d_desc->flags = wined3d_view_flags_from_d3d11_bufferex_flags(desc->u.BufferEx.Flags);
2206 wined3d_desc->u.buffer.start_idx = desc->u.BufferEx.FirstElement;
2207 wined3d_desc->u.buffer.count = desc->u.BufferEx.NumElements;
2208 break;
2210 default:
2211 WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension);
2212 return E_FAIL;
2215 return S_OK;
2218 static HRESULT d3d_shader_resource_view_init(struct d3d_shader_resource_view *view, struct d3d_device *device,
2219 ID3D11Resource *resource, const D3D11_SHADER_RESOURCE_VIEW_DESC *desc)
2221 struct wined3d_resource *wined3d_resource;
2222 struct wined3d_view_desc wined3d_desc;
2223 HRESULT hr;
2225 view->ID3D11ShaderResourceView_iface.lpVtbl = &d3d11_shader_resource_view_vtbl;
2226 view->ID3D10ShaderResourceView1_iface.lpVtbl = &d3d10_shader_resource_view_vtbl;
2227 view->refcount = 1;
2229 if (!desc)
2231 hr = set_srv_desc_from_resource(&view->desc, resource);
2233 else
2235 view->desc = *desc;
2236 hr = normalize_srv_desc(&view->desc, resource);
2238 if (FAILED(hr))
2239 return hr;
2241 if (FAILED(hr = wined3d_shader_resource_view_desc_from_d3d11(&wined3d_desc, &view->desc)))
2242 return hr;
2244 wined3d_mutex_lock();
2245 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
2247 wined3d_mutex_unlock();
2248 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
2249 return E_FAIL;
2252 if (FAILED(hr = wined3d_shader_resource_view_create(&wined3d_desc, wined3d_resource,
2253 view, &d3d_shader_resource_view_wined3d_parent_ops, &view->wined3d_view)))
2255 wined3d_mutex_unlock();
2256 WARN("Failed to create wined3d shader resource view, hr %#x.\n", hr);
2257 return hr;
2260 wined3d_private_store_init(&view->private_store);
2261 wined3d_mutex_unlock();
2262 view->resource = resource;
2263 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
2265 return S_OK;
2268 HRESULT d3d_shader_resource_view_create(struct d3d_device *device, ID3D11Resource *resource,
2269 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, struct d3d_shader_resource_view **view)
2271 struct d3d_shader_resource_view *object;
2272 HRESULT hr;
2274 if (!(object = heap_alloc_zero(sizeof(*object))))
2275 return E_OUTOFMEMORY;
2277 if (FAILED(hr = d3d_shader_resource_view_init(object, device, resource, desc)))
2279 WARN("Failed to initialize shader resource view, hr %#x.\n", hr);
2280 heap_free(object);
2281 return hr;
2284 TRACE("Created shader resource view %p.\n", object);
2285 *view = object;
2287 return S_OK;
2290 struct d3d_shader_resource_view *unsafe_impl_from_ID3D11ShaderResourceView(ID3D11ShaderResourceView *iface)
2292 if (!iface)
2293 return NULL;
2294 assert(iface->lpVtbl == &d3d11_shader_resource_view_vtbl);
2295 return impl_from_ID3D11ShaderResourceView(iface);
2298 struct d3d_shader_resource_view *unsafe_impl_from_ID3D10ShaderResourceView(ID3D10ShaderResourceView *iface)
2300 if (!iface)
2301 return NULL;
2302 assert(iface->lpVtbl == (ID3D10ShaderResourceViewVtbl *)&d3d10_shader_resource_view_vtbl);
2303 return CONTAINING_RECORD(iface, struct d3d_shader_resource_view, ID3D10ShaderResourceView1_iface);
2306 /* ID3D11UnorderedAccessView methods */
2308 static inline struct d3d11_unordered_access_view *impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface)
2310 return CONTAINING_RECORD(iface, struct d3d11_unordered_access_view, ID3D11UnorderedAccessView_iface);
2313 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_QueryInterface(ID3D11UnorderedAccessView *iface,
2314 REFIID riid, void **object)
2316 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
2318 if (IsEqualGUID(riid, &IID_ID3D11UnorderedAccessView)
2319 || IsEqualGUID(riid, &IID_ID3D11View)
2320 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
2321 || IsEqualGUID(riid, &IID_IUnknown))
2323 ID3D11UnorderedAccessView_AddRef(*object = iface);
2324 return S_OK;
2327 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
2329 *object = NULL;
2330 return E_NOINTERFACE;
2333 static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_AddRef(ID3D11UnorderedAccessView *iface)
2335 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2336 ULONG refcount = InterlockedIncrement(&view->refcount);
2338 TRACE("%p increasing refcount to %u.\n", view, refcount);
2340 if (refcount == 1)
2342 ID3D11Device2_AddRef(view->device);
2343 wined3d_mutex_lock();
2344 wined3d_unordered_access_view_incref(view->wined3d_view);
2345 wined3d_mutex_unlock();
2348 return refcount;
2351 static ULONG STDMETHODCALLTYPE d3d11_unordered_access_view_Release(ID3D11UnorderedAccessView *iface)
2353 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2354 ULONG refcount = InterlockedDecrement(&view->refcount);
2356 TRACE("%p decreasing refcount to %u.\n", view, refcount);
2358 if (!refcount)
2360 ID3D11Device2 *device = view->device;
2362 wined3d_mutex_lock();
2363 wined3d_unordered_access_view_decref(view->wined3d_view);
2364 wined3d_mutex_unlock();
2366 ID3D11Device2_Release(device);
2369 return refcount;
2372 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDevice(ID3D11UnorderedAccessView *iface,
2373 ID3D11Device **device)
2375 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2377 TRACE("iface %p, device %p.\n", iface, device);
2379 ID3D11Device_AddRef(*device = (ID3D11Device *)view->device);
2382 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_GetPrivateData(ID3D11UnorderedAccessView *iface,
2383 REFGUID guid, UINT *data_size, void *data)
2385 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2387 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2389 return d3d_get_private_data(&view->private_store, guid, data_size, data);
2392 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateData(ID3D11UnorderedAccessView *iface,
2393 REFGUID guid, UINT data_size, const void *data)
2395 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2397 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2399 return d3d_set_private_data(&view->private_store, guid, data_size, data);
2402 static HRESULT STDMETHODCALLTYPE d3d11_unordered_access_view_SetPrivateDataInterface(ID3D11UnorderedAccessView *iface,
2403 REFGUID guid, const IUnknown *data)
2405 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2407 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2409 return d3d_set_private_data_interface(&view->private_store, guid, data);
2412 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetResource(ID3D11UnorderedAccessView *iface,
2413 ID3D11Resource **resource)
2415 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2417 TRACE("iface %p, resource %p.\n", iface, resource);
2419 ID3D11Resource_AddRef(*resource = view->resource);
2422 static void STDMETHODCALLTYPE d3d11_unordered_access_view_GetDesc(ID3D11UnorderedAccessView *iface,
2423 D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2425 struct d3d11_unordered_access_view *view = impl_from_ID3D11UnorderedAccessView(iface);
2427 TRACE("iface %p, desc %p.\n", iface, desc);
2429 *desc = view->desc;
2432 static const struct ID3D11UnorderedAccessViewVtbl d3d11_unordered_access_view_vtbl =
2434 /* IUnknown methods */
2435 d3d11_unordered_access_view_QueryInterface,
2436 d3d11_unordered_access_view_AddRef,
2437 d3d11_unordered_access_view_Release,
2438 /* ID3D11DeviceChild methods */
2439 d3d11_unordered_access_view_GetDevice,
2440 d3d11_unordered_access_view_GetPrivateData,
2441 d3d11_unordered_access_view_SetPrivateData,
2442 d3d11_unordered_access_view_SetPrivateDataInterface,
2443 /* ID3D11View methods */
2444 d3d11_unordered_access_view_GetResource,
2445 /* ID3D11UnorderedAccessView methods */
2446 d3d11_unordered_access_view_GetDesc,
2449 static void STDMETHODCALLTYPE d3d11_unordered_access_view_wined3d_object_destroyed(void *parent)
2451 struct d3d11_unordered_access_view *view = parent;
2453 wined3d_private_store_cleanup(&view->private_store);
2454 heap_free(parent);
2457 static const struct wined3d_parent_ops d3d11_unordered_access_view_wined3d_parent_ops =
2459 d3d11_unordered_access_view_wined3d_object_destroyed,
2462 static unsigned int wined3d_view_flags_from_d3d11_buffer_uav_flags(unsigned int d3d11_flags)
2464 unsigned int wined3d_flags = d3d11_flags & (WINED3D_VIEW_BUFFER_RAW
2465 | WINED3D_VIEW_BUFFER_APPEND | WINED3D_VIEW_BUFFER_COUNTER);
2467 if (d3d11_flags != wined3d_flags)
2468 FIXME("Unhandled flags %#x.\n", d3d11_flags & ~wined3d_flags);
2470 return wined3d_flags;
2473 static HRESULT wined3d_unordered_access_view_desc_from_d3d11(struct wined3d_view_desc *wined3d_desc,
2474 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2476 wined3d_desc->format_id = wined3dformat_from_dxgi_format(desc->Format);
2478 wined3d_desc->flags = 0;
2479 wined3d_desc->u.texture.level_count = 1;
2480 switch (desc->ViewDimension)
2482 case D3D11_UAV_DIMENSION_BUFFER:
2483 wined3d_desc->flags = wined3d_view_flags_from_d3d11_buffer_uav_flags(desc->u.Buffer.Flags);
2484 wined3d_desc->u.buffer.start_idx = desc->u.Buffer.FirstElement;
2485 wined3d_desc->u.buffer.count = desc->u.Buffer.NumElements;
2486 break;
2488 case D3D11_UAV_DIMENSION_TEXTURE1D:
2489 wined3d_desc->u.texture.level_idx = desc->u.Texture1D.MipSlice;
2490 wined3d_desc->u.texture.layer_idx = 0;
2491 wined3d_desc->u.texture.layer_count = 1;
2492 break;
2494 case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
2495 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2496 wined3d_desc->u.texture.level_idx = desc->u.Texture1DArray.MipSlice;
2497 wined3d_desc->u.texture.layer_idx = desc->u.Texture1DArray.FirstArraySlice;
2498 wined3d_desc->u.texture.layer_count = desc->u.Texture1DArray.ArraySize;
2499 break;
2501 case D3D11_UAV_DIMENSION_TEXTURE2D:
2502 wined3d_desc->u.texture.level_idx = desc->u.Texture2D.MipSlice;
2503 wined3d_desc->u.texture.layer_idx = 0;
2504 wined3d_desc->u.texture.layer_count = 1;
2505 break;
2507 case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
2508 wined3d_desc->flags = WINED3D_VIEW_TEXTURE_ARRAY;
2509 wined3d_desc->u.texture.level_idx = desc->u.Texture2DArray.MipSlice;
2510 wined3d_desc->u.texture.layer_idx = desc->u.Texture2DArray.FirstArraySlice;
2511 wined3d_desc->u.texture.layer_count = desc->u.Texture2DArray.ArraySize;
2512 break;
2514 case D3D11_UAV_DIMENSION_TEXTURE3D:
2515 wined3d_desc->u.texture.level_idx = desc->u.Texture3D.MipSlice;
2516 wined3d_desc->u.texture.layer_idx = desc->u.Texture3D.FirstWSlice;
2517 wined3d_desc->u.texture.layer_count = desc->u.Texture3D.WSize;
2518 break;
2520 default:
2521 WARN("Unrecognized view dimension %#x.\n", desc->ViewDimension);
2522 return E_FAIL;
2525 return S_OK;
2528 static HRESULT d3d11_unordered_access_view_init(struct d3d11_unordered_access_view *view,
2529 struct d3d_device *device, ID3D11Resource *resource, const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc)
2531 struct wined3d_resource *wined3d_resource;
2532 struct wined3d_view_desc wined3d_desc;
2533 HRESULT hr;
2535 view->ID3D11UnorderedAccessView_iface.lpVtbl = &d3d11_unordered_access_view_vtbl;
2536 view->refcount = 1;
2538 if (!desc)
2540 hr = set_uav_desc_from_resource(&view->desc, resource);
2542 else
2544 view->desc = *desc;
2545 hr = normalize_uav_desc(&view->desc, resource);
2547 if (FAILED(hr))
2548 return hr;
2550 if (FAILED(hr = wined3d_unordered_access_view_desc_from_d3d11(&wined3d_desc, &view->desc)))
2551 return hr;
2553 wined3d_mutex_lock();
2554 if (!(wined3d_resource = wined3d_resource_from_d3d11_resource(resource)))
2556 wined3d_mutex_unlock();
2557 ERR("Failed to get wined3d resource for d3d11 resource %p.\n", resource);
2558 return E_FAIL;
2561 if (FAILED(hr = wined3d_unordered_access_view_create(&wined3d_desc, wined3d_resource,
2562 view, &d3d11_unordered_access_view_wined3d_parent_ops, &view->wined3d_view)))
2564 wined3d_mutex_unlock();
2565 WARN("Failed to create wined3d unordered access view, hr %#x.\n", hr);
2566 return hr;
2569 wined3d_private_store_init(&view->private_store);
2570 wined3d_mutex_unlock();
2571 view->resource = resource;
2572 ID3D11Device2_AddRef(view->device = &device->ID3D11Device2_iface);
2574 return S_OK;
2577 HRESULT d3d11_unordered_access_view_create(struct d3d_device *device, ID3D11Resource *resource,
2578 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, struct d3d11_unordered_access_view **view)
2580 struct d3d11_unordered_access_view *object;
2581 HRESULT hr;
2583 if (!(object = heap_alloc_zero(sizeof(*object))))
2584 return E_OUTOFMEMORY;
2586 if (FAILED(hr = d3d11_unordered_access_view_init(object, device, resource, desc)))
2588 WARN("Failed to initialize unordered access view, hr %#x.\n", hr);
2589 heap_free(object);
2590 return hr;
2593 TRACE("Created unordered access view %p.\n", object);
2594 *view = object;
2596 return S_OK;
2599 struct d3d11_unordered_access_view *unsafe_impl_from_ID3D11UnorderedAccessView(ID3D11UnorderedAccessView *iface)
2601 if (!iface)
2602 return NULL;
2603 assert(iface->lpVtbl == &d3d11_unordered_access_view_vtbl);
2605 return impl_from_ID3D11UnorderedAccessView(iface);