blob: 88619462ecf123d3341d621f57110485da994a1b [file] [log] [blame]
José Fonsecac8695f72013-03-06 12:12:04 +00001/**************************************************************************
2 *
3 * Copyright 2013 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 **************************************************************************/
25
26
José Fonsecabbb9eb32013-04-16 19:38:00 +010027#include <assert.h>
28
José Fonseca4bdfcb92013-07-09 13:27:00 +010029#include <iostream>
30
José Fonsecabbb9eb32013-04-16 19:38:00 +010031#include "image.hpp"
Jose Fonsecae8ba0792015-05-01 12:38:03 +010032#include "state_writer.hpp"
José Fonseca00dc2f12014-06-12 19:18:11 +010033#include "com_ptr.hpp"
José Fonsecabbb9eb32013-04-16 19:38:00 +010034
José Fonsecac8695f72013-03-06 12:12:04 +000035#include "dxgistate.hpp"
José Fonseca29d4bda2014-02-28 17:50:24 +000036#include "d3d10state.hpp"
José Fonseca00dc2f12014-06-12 19:18:11 +010037#include "d3d11state.hpp"
Jose Fonseca4a4a5cb2015-07-21 13:31:16 +010038#include "d3d11imports.hpp"
José Fonsecac8695f72013-03-06 12:12:04 +000039
José Fonsecac8695f72013-03-06 12:12:04 +000040#include "DirectXTex.h"
41
42
43namespace d3dstate {
44
45
José Fonsecabbb9eb32013-04-16 19:38:00 +010046static DXGI_FORMAT
José Fonseca52fc2b02013-10-10 18:43:33 -070047ChooseConversionFormat(DXGI_FORMAT Format, unsigned &numChannels, image::ChannelType &channelType)
José Fonsecabbb9eb32013-04-16 19:38:00 +010048{
José Fonseca52fc2b02013-10-10 18:43:33 -070049 numChannels = 4;
José Fonseca75af8672013-09-16 12:20:40 +010050 channelType = image::TYPE_UNORM8;
51
José Fonsecabbb9eb32013-04-16 19:38:00 +010052 switch (Format) {
53
54 // Float
55 case DXGI_FORMAT_R32G32B32A32_FLOAT:
56 case DXGI_FORMAT_R32G32B32_FLOAT:
57 case DXGI_FORMAT_R16G16B16A16_FLOAT:
58 case DXGI_FORMAT_R32G32_FLOAT:
59 case DXGI_FORMAT_R11G11B10_FLOAT:
60 case DXGI_FORMAT_R16G16_FLOAT:
61 case DXGI_FORMAT_R32_FLOAT:
62 case DXGI_FORMAT_R16_FLOAT:
63 case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
64 case DXGI_FORMAT_BC6H_UF16:
65 case DXGI_FORMAT_BC6H_SF16:
José Fonseca75af8672013-09-16 12:20:40 +010066 channelType = image::TYPE_FLOAT;
67 return DXGI_FORMAT_R32G32B32A32_FLOAT;
José Fonsecabbb9eb32013-04-16 19:38:00 +010068
69 // Unsigned normalized
70 case DXGI_FORMAT_R16G16B16A16_UNORM:
71 case DXGI_FORMAT_R10G10B10A2_UNORM:
72 case DXGI_FORMAT_R8G8B8A8_UNORM:
73 case DXGI_FORMAT_R16G16_UNORM:
74 case DXGI_FORMAT_R8G8_UNORM:
75 case DXGI_FORMAT_R16_UNORM:
76 case DXGI_FORMAT_R8_UNORM:
77 case DXGI_FORMAT_A8_UNORM:
78 case DXGI_FORMAT_R1_UNORM:
79 case DXGI_FORMAT_R8G8_B8G8_UNORM:
80 case DXGI_FORMAT_G8R8_G8B8_UNORM:
81 case DXGI_FORMAT_BC1_UNORM:
82 case DXGI_FORMAT_BC2_UNORM:
83 case DXGI_FORMAT_BC3_UNORM:
84 case DXGI_FORMAT_BC4_UNORM:
85 case DXGI_FORMAT_BC5_UNORM:
86 case DXGI_FORMAT_B5G6R5_UNORM:
87 case DXGI_FORMAT_B5G5R5A1_UNORM:
88 case DXGI_FORMAT_B8G8R8A8_UNORM:
89 case DXGI_FORMAT_B8G8R8X8_UNORM:
90 case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
91 case DXGI_FORMAT_BC7_UNORM:
Jose Fonsecaf0441cd2018-10-31 12:15:22 +000092 case DXGI_FORMAT_B4G4R4A4_UNORM:
José Fonsecabbb9eb32013-04-16 19:38:00 +010093 return DXGI_FORMAT_R8G8B8A8_UNORM;
94
95 // SRGB
96 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
97 case DXGI_FORMAT_BC1_UNORM_SRGB:
98 case DXGI_FORMAT_BC2_UNORM_SRGB:
99 case DXGI_FORMAT_BC3_UNORM_SRGB:
100 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
101 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
102 case DXGI_FORMAT_BC7_UNORM_SRGB:
Jose Fonseca698dc902018-12-06 10:18:58 +0000103 return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
José Fonsecabbb9eb32013-04-16 19:38:00 +0100104
105 // Signed normalized
106 case DXGI_FORMAT_R16G16B16A16_SNORM:
107 case DXGI_FORMAT_R8G8B8A8_SNORM:
108 case DXGI_FORMAT_R16G16_SNORM:
109 case DXGI_FORMAT_R8G8_SNORM:
110 case DXGI_FORMAT_R16_SNORM:
111 case DXGI_FORMAT_R8_SNORM:
112 case DXGI_FORMAT_BC4_SNORM:
113 case DXGI_FORMAT_BC5_SNORM:
114 return DXGI_FORMAT_R8G8B8A8_SNORM;
115
Jose Fonsecaf0441cd2018-10-31 12:15:22 +0000116 // 8-bit unsigned
José Fonsecabbb9eb32013-04-16 19:38:00 +0100117 case DXGI_FORMAT_R8G8B8A8_UINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100118 case DXGI_FORMAT_R8G8_UINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100119 case DXGI_FORMAT_R8_UINT:
120 return DXGI_FORMAT_R8G8B8A8_UINT;
121
Jose Fonsecaf0441cd2018-10-31 12:15:22 +0000122 // 4-channel integers
123 case DXGI_FORMAT_R32G32B32A32_UINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100124 case DXGI_FORMAT_R32G32B32A32_SINT:
Jose Fonsecaf0441cd2018-10-31 12:15:22 +0000125 case DXGI_FORMAT_R16G16B16A16_UINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100126 case DXGI_FORMAT_R16G16B16A16_SINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100127 case DXGI_FORMAT_R8G8B8A8_SINT:
Jose Fonsecaf0441cd2018-10-31 12:15:22 +0000128 case DXGI_FORMAT_R10G10B10A2_UINT:
129 numChannels = 4;
130 channelType = image::TYPE_FLOAT;
131 return DXGI_FORMAT_R32G32B32A32_FLOAT;
132
133 // 3-channel integers
134 case DXGI_FORMAT_R32G32B32_UINT:
135 case DXGI_FORMAT_R32G32B32_SINT:
136 numChannels = 3;
137 channelType = image::TYPE_FLOAT;
138 return DXGI_FORMAT_R32G32B32_FLOAT;
139
140 // 2-channel integers
141 case DXGI_FORMAT_R32G32_UINT:
142 case DXGI_FORMAT_R32G32_SINT:
143 case DXGI_FORMAT_R16G16_UINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100144 case DXGI_FORMAT_R16G16_SINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100145 case DXGI_FORMAT_R8G8_SINT:
Jose Fonsecaf0441cd2018-10-31 12:15:22 +0000146 numChannels = 2;
147 channelType = image::TYPE_FLOAT;
148 return DXGI_FORMAT_R32G32_FLOAT;
149
150 // 1-channel integers
151 case DXGI_FORMAT_R32_UINT:
152 case DXGI_FORMAT_R32_SINT:
153 case DXGI_FORMAT_R16_UINT:
José Fonsecabbb9eb32013-04-16 19:38:00 +0100154 case DXGI_FORMAT_R16_SINT:
155 case DXGI_FORMAT_R8_SINT:
Jose Fonsecaf0441cd2018-10-31 12:15:22 +0000156 numChannels = 1;
157 channelType = image::TYPE_FLOAT;
158 return DXGI_FORMAT_R32_FLOAT;
José Fonsecabbb9eb32013-04-16 19:38:00 +0100159
160 // Depth
161 case DXGI_FORMAT_D32_FLOAT:
162 case DXGI_FORMAT_D24_UNORM_S8_UINT:
163 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
164 case DXGI_FORMAT_D16_UNORM:
José Fonseca52fc2b02013-10-10 18:43:33 -0700165 numChannels = 1;
166 channelType = image::TYPE_FLOAT;
167 return DXGI_FORMAT_D32_FLOAT;
José Fonsecabbb9eb32013-04-16 19:38:00 +0100168
169 // Typeless
170 case DXGI_FORMAT_UNKNOWN:
171 case DXGI_FORMAT_R32G32B32A32_TYPELESS:
172 case DXGI_FORMAT_R32G32B32_TYPELESS:
173 case DXGI_FORMAT_R16G16B16A16_TYPELESS:
174 case DXGI_FORMAT_R32G32_TYPELESS:
175 case DXGI_FORMAT_R32G8X24_TYPELESS:
176 case DXGI_FORMAT_R10G10B10A2_TYPELESS:
177 case DXGI_FORMAT_R8G8B8A8_TYPELESS:
178 case DXGI_FORMAT_R16G16_TYPELESS:
179 case DXGI_FORMAT_R32_TYPELESS:
180 case DXGI_FORMAT_R8G8_TYPELESS:
181 case DXGI_FORMAT_R16_TYPELESS:
182 case DXGI_FORMAT_R8_TYPELESS:
183 case DXGI_FORMAT_BC1_TYPELESS:
184 case DXGI_FORMAT_BC2_TYPELESS:
185 case DXGI_FORMAT_BC3_TYPELESS:
186 case DXGI_FORMAT_BC4_TYPELESS:
187 case DXGI_FORMAT_BC5_TYPELESS:
188 case DXGI_FORMAT_B8G8R8A8_TYPELESS:
189 case DXGI_FORMAT_B8G8R8X8_TYPELESS:
190 case DXGI_FORMAT_BC6H_TYPELESS:
191 case DXGI_FORMAT_BC7_TYPELESS:
192 case DXGI_FORMAT_R24G8_TYPELESS:
193 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
194 case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
195 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
196 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
197 return DXGI_FORMAT_UNKNOWN;
198
199 default:
200 return DXGI_FORMAT_R8G8B8A8_UNORM;
201 }
202}
203
204
José Fonsecac8695f72013-03-06 12:12:04 +0000205/**
206 * Convert between DXGI formats.
207 *
208 */
209HRESULT
210ConvertFormat(DXGI_FORMAT SrcFormat,
211 void *SrcData,
212 UINT SrcPitch,
213 DXGI_FORMAT DstFormat,
214 void *DstData,
215 UINT DstPitch,
216 UINT Width, UINT Height)
217{
218 HRESULT hr;
219
220 DirectX::Image SrcImage;
221 DirectX::Image DstImage;
222
223 SrcImage.width = Width;
224 SrcImage.height = Height;
225 SrcImage.format = SrcFormat;
226 SrcImage.rowPitch = SrcPitch;
227 SrcImage.slicePitch = Height * SrcPitch;
228 SrcImage.pixels = (uint8_t*)SrcData;
229
230 DstImage.width = Width;
231 DstImage.height = Height;
232 DstImage.format = DstFormat;
233 DstImage.rowPitch = DstPitch;
234 DstImage.slicePitch = Height * DstPitch;
235 DstImage.pixels = (uint8_t*)DstData;
236
237 DirectX::Rect rect(0, 0, Width, Height);
238
José Fonseca386d29d2013-05-20 13:35:23 +0100239 hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
240 assert(SUCCEEDED(hr));
241 if (FAILED(hr)) {
242 return hr;
243 }
244
Jose Fonseca26af4c42018-09-07 13:37:06 +0100245 /*
246 * Avoid WIC, as it's not reliable (e.g, R32_FLOAT ->
247 * R32G32B32A32_FLOAT will fail with E_INVALIDARG.)
248 */
249 DWORD filter = DirectX::TEX_FILTER_FORCE_NON_WIC;
250
José Fonsecac8695f72013-03-06 12:12:04 +0000251 if (SrcFormat != DstFormat) {
252 DirectX::ScratchImage ScratchImage;
253 ScratchImage.Initialize2D(DstFormat, Width, Height, 1, 1);
254
José Fonseca4bdfcb92013-07-09 13:27:00 +0100255 if (DirectX::IsCompressed(SrcFormat)) {
256 hr = DirectX::Decompress(SrcImage, DstFormat, ScratchImage);
257 } else {
Jose Fonsecaa1fbeb52018-08-23 12:25:30 +0100258 hr = DirectX::Convert(SrcImage, DstFormat, filter, 0.0f, ScratchImage);
José Fonseca4bdfcb92013-07-09 13:27:00 +0100259 }
260
José Fonsecac8695f72013-03-06 12:12:04 +0000261 if (SUCCEEDED(hr)) {
Jose Fonseca26af4c42018-09-07 13:37:06 +0100262 hr = DirectX::CopyRectangle(*ScratchImage.GetImage(0, 0, 0), rect, DstImage, filter, 0, 0);
José Fonsecac8695f72013-03-06 12:12:04 +0000263 }
264 } else {
Jose Fonseca26af4c42018-09-07 13:37:06 +0100265 hr = DirectX::CopyRectangle(SrcImage, rect, DstImage, filter, 0, 0);
José Fonsecac8695f72013-03-06 12:12:04 +0000266 }
267
268 return hr;
269}
270
271
José Fonsecabbb9eb32013-04-16 19:38:00 +0100272image::Image *
273ConvertImage(DXGI_FORMAT SrcFormat,
274 void *SrcData,
275 UINT SrcPitch,
Zack Rusin4a7a0612018-07-03 20:34:36 -0400276 UINT Width, UINT Height,
Jose Fonseca9383c672018-07-04 16:32:50 +0100277 bool isDepthStencil)
José Fonsecabbb9eb32013-04-16 19:38:00 +0100278{
José Fonseca52fc2b02013-10-10 18:43:33 -0700279 unsigned numChannels;
José Fonseca75af8672013-09-16 12:20:40 +0100280 image::ChannelType channelType;
José Fonsecabbb9eb32013-04-16 19:38:00 +0100281
Zack Rusin4a7a0612018-07-03 20:34:36 -0400282 // DirectXTex doesn't support the typeless depth-stencil/uav variants
Jose Fonseca47f48a42015-07-06 16:45:51 +0100283 switch (SrcFormat) {
284 case DXGI_FORMAT_R24G8_TYPELESS:
285 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
286 SrcFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
287 break;
288
289 case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
290 // FIXME: This will dump the depth-channel. It would be more
291 // adequate to dump the stencil channel, but we can't achieve
292 // that with DirectXTex.
293 SrcFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
294 break;
295
296 case DXGI_FORMAT_R32G8X24_TYPELESS:
297 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
298 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
299 SrcFormat = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
300 break;
301
Zack Rusin4a7a0612018-07-03 20:34:36 -0400302 case DXGI_FORMAT_R32_TYPELESS:
Jose Fonseca9383c672018-07-04 16:32:50 +0100303 SrcFormat = isDepthStencil ? DXGI_FORMAT_D32_FLOAT : DXGI_FORMAT_R32_UINT;
Zack Rusin4a7a0612018-07-03 20:34:36 -0400304 break;
305
Jose Fonseca47f48a42015-07-06 16:45:51 +0100306 default:
307 break;
308 }
309
José Fonseca52fc2b02013-10-10 18:43:33 -0700310 DXGI_FORMAT DstFormat = ChooseConversionFormat(SrcFormat, numChannels, channelType);
José Fonsecabbb9eb32013-04-16 19:38:00 +0100311 if (DstFormat == DXGI_FORMAT_UNKNOWN) {
Jose Fonsecaa0ccc7d2018-10-31 11:44:33 +0000312 std::cerr << "warning: don't know how to convert format " << getDXGIFormatName(SrcFormat) << "\n";
José Fonsecabbb9eb32013-04-16 19:38:00 +0100313 return NULL;
314 }
315
José Fonseca52fc2b02013-10-10 18:43:33 -0700316 image::Image *image = new image::Image(Width, Height, numChannels, false, channelType);
José Fonsecabbb9eb32013-04-16 19:38:00 +0100317 if (!image) {
318 return NULL;
319 }
320 assert(image->stride() > 0);
321
322 HRESULT hr;
323 hr = ConvertFormat(SrcFormat,
324 SrcData, SrcPitch,
325 DstFormat,
326 image->start(), image->stride(),
327 Width, Height);
328 if (FAILED(hr)) {
Jose Fonsecaa1fbeb52018-08-23 12:25:30 +0100329 std::cerr << "warning: failed to convert from format " << getDXGIFormatName(SrcFormat)
330 << " to format " << getDXGIFormatName(DstFormat) << "\n";
José Fonsecabbb9eb32013-04-16 19:38:00 +0100331 delete image;
332 image = NULL;
333 }
334
335 return image;
336}
337
José Fonseca29d4bda2014-02-28 17:50:24 +0000338
339image::Image *
340getRenderTargetImage(IDXGISwapChain *pSwapChain)
341{
342 HRESULT hr;
343
344 assert(pSwapChain);
345 if (!pSwapChain) {
346 return NULL;
347 }
348
349 DXGI_SWAP_CHAIN_DESC Desc;
350 hr = pSwapChain->GetDesc(&Desc);
351 assert(SUCCEEDED(hr));
352
José Fonseca36413ec2014-08-14 13:58:19 +0100353 DXGI_FORMAT Format = Desc.BufferDesc.Format;
354
José Fonseca29d4bda2014-02-28 17:50:24 +0000355 /*
356 * There is a IDXGISurface::Map method, but swapchains are not normally mappable,
357 * and there is no way to copy into a staging resource, which effectively means there
358 * is no way to read a IDXGISwapChain using DXGI interfaces alone.
359 *
360 * We must figure out
361 * the appropriate D3D10/D3D11 interfaces, and use them instead.
362 */
363
Jose Fonseca4a4a5cb2015-07-21 13:31:16 +0100364 com_ptr<ID3D11Device1> pD3D11Device1;
365 hr = pSwapChain->GetDevice(IID_ID3D11Device1, (void **)&pD3D11Device1);
366 if (SUCCEEDED(hr)) {
367 /*
368 * With D3D11.1 runtime (that comes with Windows 8 and Windows 7
369 * Platform Update), we can no longer guess the device interface based
370 * on the success of GetDevice, since it will always succeed regardless
371 * the requested device interface, but the returned device maight be
372 * inactive/lockedout, and attempt to use it will cause the call to be
373 * ignored, though a debug runtime will issue a
374 * DEVICE_LOCKEDOUT_INTERFACE warning.
375 *
376 * See also:
377 * - https://msdn.microsoft.com/en-us/library/windows/desktop/hh404583.aspx
378 * - https://social.msdn.microsoft.com/Forums/en-US/c482bcec-b094-4df0-9253-9c496b115beb/d3d11-runtime-assertion-when-using-graphics-debugger-and-other-applications-may-be-intercepting?forum=wingameswithdirectx
379 */
380 com_ptr<ID3D11Resource> pD3D11Resource;
381 hr = pSwapChain->GetBuffer(0, IID_ID3D11Resource, (void **)&pD3D11Resource);
382 assert(SUCCEEDED(hr));
383 if (FAILED(hr)) {
384 return NULL;
385 }
386
387 com_ptr<ID3D11DeviceContext1> pD3D11DeviceContext;
388 pD3D11Device1->GetImmediateContext1(&pD3D11DeviceContext);
389
390 UINT Flags = 0;
391 UINT DeviceFlags = pD3D11Device1->GetCreationFlags();
392 if (DeviceFlags & D3D11_CREATE_DEVICE_SINGLETHREADED) {
393 Flags |= D3D11_1_CREATE_DEVICE_CONTEXT_STATE_SINGLETHREADED;
394 }
395 D3D_FEATURE_LEVEL FeatureLevel = pD3D11Device1->GetFeatureLevel();
396
397 com_ptr<ID3DDeviceContextState> pState;
398 hr = pD3D11Device1->CreateDeviceContextState(Flags, &FeatureLevel, 1, D3D11_SDK_VERSION, IID_ID3D11Device1, NULL, &pState);
399 if (SUCCEEDED(hr)) {
400 com_ptr<ID3DDeviceContextState> pPreviousState;
401 pD3D11DeviceContext->SwapDeviceContextState(pState, &pPreviousState);
402
403 image::Image *image;
404 image = getSubResourceImage(pD3D11DeviceContext, pD3D11Resource, Format, 0, 0);
405
406 pD3D11DeviceContext->SwapDeviceContextState(pPreviousState, NULL);
407
408 return image;
409 }
410 }
411
José Fonseca00dc2f12014-06-12 19:18:11 +0100412 com_ptr<ID3D11Device> pD3D11Device;
413 hr = pSwapChain->GetDevice(IID_ID3D11Device, (void **)&pD3D11Device);
414 if (SUCCEEDED(hr)) {
Jose Fonseca9bc17b72015-07-21 13:23:57 +0100415 com_ptr<ID3D11Resource> pD3D11Resource;
José Fonseca00dc2f12014-06-12 19:18:11 +0100416 hr = pSwapChain->GetBuffer(0, IID_ID3D11Resource, (void **)&pD3D11Resource);
417 assert(SUCCEEDED(hr));
418 if (FAILED(hr)) {
419 return NULL;
420 }
421
422 com_ptr<ID3D11DeviceContext> pD3D11DeviceContext;
423 pD3D11Device->GetImmediateContext(&pD3D11DeviceContext);
424
José Fonseca00dc2f12014-06-12 19:18:11 +0100425 return getSubResourceImage(pD3D11DeviceContext, pD3D11Resource, Format, 0, 0);
426 }
José Fonseca29d4bda2014-02-28 17:50:24 +0000427
Jose Fonsecabbd17872015-07-20 22:42:43 +0100428 com_ptr<ID3D10Device> pD3D10Device;
429 hr = pSwapChain->GetDevice(IID_ID3D10Device, (void **)&pD3D10Device);
430 if (SUCCEEDED(hr)) {
Jose Fonseca9bc17b72015-07-21 13:23:57 +0100431 com_ptr<ID3D10Resource> pD3D10Resource;
Jose Fonsecabbd17872015-07-20 22:42:43 +0100432 hr = pSwapChain->GetBuffer(0, IID_ID3D10Resource, (void **)&pD3D10Resource);
433 assert(SUCCEEDED(hr));
434 if (FAILED(hr)) {
435 return NULL;
436 }
437
438 return getSubResourceImage(pD3D10Device, pD3D10Resource, Format, 0, 0);
439 }
440
José Fonseca29d4bda2014-02-28 17:50:24 +0000441 return NULL;
442}
443
444
445void
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100446dumpDevice(StateWriter &writer, IDXGISwapChain *pSwapChain)
José Fonseca29d4bda2014-02-28 17:50:24 +0000447{
José Fonseca52024be2014-06-12 19:48:35 +0100448 HRESULT hr;
José Fonseca29d4bda2014-02-28 17:50:24 +0000449
José Fonseca52024be2014-06-12 19:48:35 +0100450 if (pSwapChain) {
451 com_ptr<ID3D10Device> pD3D10Device;
452 hr = pSwapChain->GetDevice(IID_ID3D10Device, (void **)&pD3D10Device);
453 if (SUCCEEDED(hr)) {
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100454 dumpDevice(writer, pD3D10Device);
José Fonseca52024be2014-06-12 19:48:35 +0100455 return;
456 }
457
José Fonseca52024be2014-06-12 19:48:35 +0100458 com_ptr<ID3D11Device> pD3D11Device;
459 hr = pSwapChain->GetDevice(IID_ID3D11Device, (void **)&pD3D11Device);
460 if (SUCCEEDED(hr)) {
461 com_ptr<ID3D11DeviceContext> pD3D11DeviceContext;
462 pD3D11Device->GetImmediateContext(&pD3D11DeviceContext);
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100463 dumpDevice(writer, pD3D11DeviceContext);
José Fonseca52024be2014-06-12 19:48:35 +0100464 return;
465 }
José Fonseca52024be2014-06-12 19:48:35 +0100466 }
467
468 // Fallback -- this should really never happen.
469 assert(0);
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100470 writer.beginMember("framebuffer");
471 writer.beginObject();
José Fonseca29d4bda2014-02-28 17:50:24 +0000472 if (pSwapChain) {
473 image::Image *image;
474 image = getRenderTargetImage(pSwapChain);
475 if (image) {
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100476 writer.beginMember("SWAP_CHAIN");
477 writer.writeImage(image);
478 writer.endMember();
José Fonseca52024be2014-06-12 19:48:35 +0100479 delete image;
José Fonseca29d4bda2014-02-28 17:50:24 +0000480 }
481 }
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100482 writer.endObject();
483 writer.endMember(); // framebuffer
José Fonseca29d4bda2014-02-28 17:50:24 +0000484}
485
486
Zack Rusin86bd4992015-03-03 21:50:43 -0500487std::string
488getDXGIFormatName(DXGI_FORMAT format)
489{
490 switch (format) {
491 case DXGI_FORMAT_UNKNOWN:
492 return "DXGI_FORMAT_UNKNOWN";
493 case DXGI_FORMAT_R32G32B32A32_TYPELESS:
494 return "DXGI_FORMAT_R32G32B32A32_TYPELESS";
495 case DXGI_FORMAT_R32G32B32A32_FLOAT:
496 return "DXGI_FORMAT_R32G32B32A32_FLOAT";
497 case DXGI_FORMAT_R32G32B32A32_UINT:
498 return "DXGI_FORMAT_R32G32B32A32_UINT";
499 case DXGI_FORMAT_R32G32B32A32_SINT:
500 return "DXGI_FORMAT_R32G32B32A32_SINT";
501 case DXGI_FORMAT_R32G32B32_TYPELESS:
502 return "DXGI_FORMAT_R32G32B32_TYPELESS";
503 case DXGI_FORMAT_R32G32B32_FLOAT:
504 return "DXGI_FORMAT_R32G32B32_FLOAT";
505 case DXGI_FORMAT_R32G32B32_UINT:
506 return "DXGI_FORMAT_R32G32B32_UINT";
507 case DXGI_FORMAT_R32G32B32_SINT:
508 return "DXGI_FORMAT_R32G32B32_SINT";
509 case DXGI_FORMAT_R16G16B16A16_TYPELESS:
510 return "DXGI_FORMAT_R16G16B16A16_TYPELESS";
511 case DXGI_FORMAT_R16G16B16A16_FLOAT:
512 return "DXGI_FORMAT_R16G16B16A16_FLOAT";
513 case DXGI_FORMAT_R16G16B16A16_UNORM:
514 return "DXGI_FORMAT_R16G16B16A16_UNORM";
515 case DXGI_FORMAT_R16G16B16A16_UINT:
516 return "DXGI_FORMAT_R16G16B16A16_UINT";
517 case DXGI_FORMAT_R16G16B16A16_SNORM:
518 return "DXGI_FORMAT_R16G16B16A16_SNORM";
519 case DXGI_FORMAT_R16G16B16A16_SINT:
520 return "DXGI_FORMAT_R16G16B16A16_SINT";
521 case DXGI_FORMAT_R32G32_TYPELESS:
522 return "DXGI_FORMAT_R32G32_TYPELESS";
523 case DXGI_FORMAT_R32G32_FLOAT:
524 return "DXGI_FORMAT_R32G32_FLOAT";
525 case DXGI_FORMAT_R32G32_UINT:
526 return "DXGI_FORMAT_R32G32_UINT";
527 case DXGI_FORMAT_R32G32_SINT:
528 return "DXGI_FORMAT_R32G32_SINT";
529 case DXGI_FORMAT_R32G8X24_TYPELESS:
530 return "DXGI_FORMAT_R32G8X24_TYPELESS";
531 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
532 return "DXGI_FORMAT_D32_FLOAT_S8X24_UINT";
533 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
534 return "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS";
535 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
536 return "DXGI_FORMAT_X32_TYPELESS_G8X24_UINT";
537 case DXGI_FORMAT_R10G10B10A2_TYPELESS:
538 return "DXGI_FORMAT_R10G10B10A2_TYPELESS";
539 case DXGI_FORMAT_R10G10B10A2_UNORM:
540 return "DXGI_FORMAT_R10G10B10A2_UNORM";
541 case DXGI_FORMAT_R10G10B10A2_UINT:
542 return "DXGI_FORMAT_R10G10B10A2_UINT";
543 case DXGI_FORMAT_R11G11B10_FLOAT:
544 return "DXGI_FORMAT_R11G11B10_FLOAT";
545 case DXGI_FORMAT_R8G8B8A8_TYPELESS:
546 return "DXGI_FORMAT_R8G8B8A8_TYPELESS";
547 case DXGI_FORMAT_R8G8B8A8_UNORM:
548 return "DXGI_FORMAT_R8G8B8A8_UNORM";
549 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
550 return "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB";
551 case DXGI_FORMAT_R8G8B8A8_UINT:
552 return "DXGI_FORMAT_R8G8B8A8_UINT";
553 case DXGI_FORMAT_R8G8B8A8_SNORM:
554 return "DXGI_FORMAT_R8G8B8A8_SNORM";
555 case DXGI_FORMAT_R8G8B8A8_SINT:
556 return "DXGI_FORMAT_R8G8B8A8_SINT";
557 case DXGI_FORMAT_R16G16_TYPELESS:
558 return "DXGI_FORMAT_R16G16_TYPELESS";
559 case DXGI_FORMAT_R16G16_FLOAT:
560 return "DXGI_FORMAT_R16G16_FLOAT";
561 case DXGI_FORMAT_R16G16_UNORM:
562 return "DXGI_FORMAT_R16G16_UNORM";
563 case DXGI_FORMAT_R16G16_UINT:
564 return "DXGI_FORMAT_R16G16_UINT";
565 case DXGI_FORMAT_R16G16_SNORM:
566 return "DXGI_FORMAT_R16G16_SNORM";
567 case DXGI_FORMAT_R16G16_SINT:
568 return "DXGI_FORMAT_R16G16_SINT";
569 case DXGI_FORMAT_R32_TYPELESS:
570 return "DXGI_FORMAT_R32_TYPELESS";
571 case DXGI_FORMAT_D32_FLOAT:
572 return "DXGI_FORMAT_D32_FLOAT";
573 case DXGI_FORMAT_R32_FLOAT:
574 return "DXGI_FORMAT_R32_FLOAT";
575 case DXGI_FORMAT_R32_UINT:
576 return "DXGI_FORMAT_R32_UINT";
577 case DXGI_FORMAT_R32_SINT:
578 return "DXGI_FORMAT_R32_SINT";
579 case DXGI_FORMAT_R24G8_TYPELESS:
580 return "DXGI_FORMAT_R24G8_TYPELESS";
581 case DXGI_FORMAT_D24_UNORM_S8_UINT:
582 return "DXGI_FORMAT_D24_UNORM_S8_UINT";
583 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
584 return "DXGI_FORMAT_R24_UNORM_X8_TYPELESS";
585 case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
586 return "DXGI_FORMAT_X24_TYPELESS_G8_UINT";
587 case DXGI_FORMAT_R8G8_TYPELESS:
588 return "DXGI_FORMAT_R8G8_TYPELESS";
589 case DXGI_FORMAT_R8G8_UNORM:
590 return "DXGI_FORMAT_R8G8_UNORM";
591 case DXGI_FORMAT_R8G8_UINT:
592 return "DXGI_FORMAT_R8G8_UINT";
593 case DXGI_FORMAT_R8G8_SNORM:
594 return "DXGI_FORMAT_R8G8_SNORM";
595 case DXGI_FORMAT_R8G8_SINT:
596 return "DXGI_FORMAT_R8G8_SINT";
597 case DXGI_FORMAT_R16_TYPELESS:
598 return "DXGI_FORMAT_R16_TYPELESS";
599 case DXGI_FORMAT_R16_FLOAT:
600 return "DXGI_FORMAT_R16_FLOAT";
601 case DXGI_FORMAT_D16_UNORM:
602 return "DXGI_FORMAT_D16_UNORM";
603 case DXGI_FORMAT_R16_UNORM:
604 return "DXGI_FORMAT_R16_UNORM";
605 case DXGI_FORMAT_R16_UINT:
606 return "DXGI_FORMAT_R16_UINT";
607 case DXGI_FORMAT_R16_SNORM:
608 return "DXGI_FORMAT_R16_SNORM";
609 case DXGI_FORMAT_R16_SINT:
610 return "DXGI_FORMAT_R16_SINT";
611 case DXGI_FORMAT_R8_TYPELESS:
612 return "DXGI_FORMAT_R8_TYPELESS";
613 case DXGI_FORMAT_R8_UNORM:
614 return "DXGI_FORMAT_R8_UNORM";
615 case DXGI_FORMAT_R8_UINT:
616 return "DXGI_FORMAT_R8_UINT";
617 case DXGI_FORMAT_R8_SNORM:
618 return "DXGI_FORMAT_R8_SNORM";
619 case DXGI_FORMAT_R8_SINT:
620 return "DXGI_FORMAT_R8_SINT";
621 case DXGI_FORMAT_A8_UNORM:
622 return "DXGI_FORMAT_A8_UNORM";
623 case DXGI_FORMAT_R1_UNORM:
624 return "DXGI_FORMAT_R1_UNORM";
625 case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
626 return "DXGI_FORMAT_R9G9B9E5_SHAREDEXP";
627 case DXGI_FORMAT_R8G8_B8G8_UNORM:
628 return "DXGI_FORMAT_R8G8_B8G8_UNORM";
629 case DXGI_FORMAT_G8R8_G8B8_UNORM:
630 return "DXGI_FORMAT_G8R8_G8B8_UNORM";
631 case DXGI_FORMAT_BC1_TYPELESS:
632 return "DXGI_FORMAT_BC1_TYPELESS";
633 case DXGI_FORMAT_BC1_UNORM:
634 return "DXGI_FORMAT_BC1_UNORM";
635 case DXGI_FORMAT_BC1_UNORM_SRGB:
636 return "DXGI_FORMAT_BC1_UNORM_SRGB";
637 case DXGI_FORMAT_BC2_TYPELESS:
638 return "DXGI_FORMAT_BC2_TYPELESS";
639 case DXGI_FORMAT_BC2_UNORM:
640 return "DXGI_FORMAT_BC2_UNORM";
641 case DXGI_FORMAT_BC2_UNORM_SRGB:
642 return "DXGI_FORMAT_BC2_UNORM_SRGB";
643 case DXGI_FORMAT_BC3_TYPELESS:
644 return "DXGI_FORMAT_BC3_TYPELESS";
645 case DXGI_FORMAT_BC3_UNORM:
646 return "DXGI_FORMAT_BC3_UNORM";
647 case DXGI_FORMAT_BC3_UNORM_SRGB:
648 return "DXGI_FORMAT_BC3_UNORM_SRGB";
649 case DXGI_FORMAT_BC4_TYPELESS:
650 return "DXGI_FORMAT_BC4_TYPELESS";
651 case DXGI_FORMAT_BC4_UNORM:
652 return "DXGI_FORMAT_BC4_UNORM";
653 case DXGI_FORMAT_BC4_SNORM:
654 return "DXGI_FORMAT_BC4_SNORM";
655 case DXGI_FORMAT_BC5_TYPELESS:
656 return "DXGI_FORMAT_BC5_TYPELESS";
657 case DXGI_FORMAT_BC5_UNORM:
658 return "DXGI_FORMAT_BC5_UNORM";
659 case DXGI_FORMAT_BC5_SNORM:
660 return "DXGI_FORMAT_BC5_SNORM";
661 case DXGI_FORMAT_B5G6R5_UNORM:
662 return "DXGI_FORMAT_B5G6R5_UNORM";
663 case DXGI_FORMAT_B5G5R5A1_UNORM:
664 return "DXGI_FORMAT_B5G5R5A1_UNORM";
665 case DXGI_FORMAT_B8G8R8A8_UNORM:
666 return "DXGI_FORMAT_B8G8R8A8_UNORM";
667 case DXGI_FORMAT_B8G8R8X8_UNORM:
668 return "DXGI_FORMAT_B8G8R8X8_UNORM";
669 case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
670 return "DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM";
671 case DXGI_FORMAT_B8G8R8A8_TYPELESS:
672 return "DXGI_FORMAT_B8G8R8A8_TYPELESS";
673 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
674 return "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB";
675 case DXGI_FORMAT_B8G8R8X8_TYPELESS:
676 return "DXGI_FORMAT_B8G8R8X8_TYPELESS";
677 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
678 return "DXGI_FORMAT_B8G8R8X8_UNORM_SRGB";
679 case DXGI_FORMAT_BC6H_TYPELESS:
680 return "DXGI_FORMAT_BC6H_TYPELESS";
681 case DXGI_FORMAT_BC6H_UF16:
682 return "DXGI_FORMAT_BC6H_UF16";
683 case DXGI_FORMAT_BC6H_SF16:
684 return "DXGI_FORMAT_BC6H_SF16";
685 case DXGI_FORMAT_BC7_TYPELESS:
686 return "DXGI_FORMAT_BC7_TYPELESS";
687 case DXGI_FORMAT_BC7_UNORM:
688 return "DXGI_FORMAT_BC7_UNORM";
689 case DXGI_FORMAT_BC7_UNORM_SRGB:
690 return "DXGI_FORMAT_BC7_UNORM_SRGB";
691 case DXGI_FORMAT_AYUV:
692 return "DXGI_FORMAT_AYUV";
693 case DXGI_FORMAT_Y410:
694 return "DXGI_FORMAT_Y410";
695 case DXGI_FORMAT_Y416:
696 return "DXGI_FORMAT_Y416";
697 case DXGI_FORMAT_NV12:
698 return "DXGI_FORMAT_NV12";
699 case DXGI_FORMAT_P010:
700 return "DXGI_FORMAT_P010";
701 case DXGI_FORMAT_P016:
702 return "DXGI_FORMAT_P016";
703 case DXGI_FORMAT_420_OPAQUE:
704 return "DXGI_FORMAT_420_OPAQUE";
705 case DXGI_FORMAT_YUY2:
706 return "DXGI_FORMAT_YUY2";
707 case DXGI_FORMAT_Y210:
708 return "DXGI_FORMAT_Y210";
709 case DXGI_FORMAT_Y216:
710 return "DXGI_FORMAT_Y216";
711 case DXGI_FORMAT_NV11:
712 return "DXGI_FORMAT_NV11";
713 case DXGI_FORMAT_AI44:
714 return "DXGI_FORMAT_AI44";
715 case DXGI_FORMAT_IA44:
716 return "DXGI_FORMAT_IA44";
717 case DXGI_FORMAT_P8:
718 return "DXGI_FORMAT_P8";
719 case DXGI_FORMAT_A8P8:
720 return "DXGI_FORMAT_A8P8";
721 case DXGI_FORMAT_B4G4R4A4_UNORM:
722 return "DXGI_FORMAT_B4G4R4A4_UNORM";
723 case DXGI_FORMAT_FORCE_UINT:
724 return "DXGI_FORMAT_FORCE_UINT";
725 default:
726 return "DXGI_ERROR_FORMAT";
727 }
728}
729
José Fonsecac8695f72013-03-06 12:12:04 +0000730} /* namespace d3dstate */