]> git.cworth.org Git - apitrace/blob - retrace/dxgistate.cpp
0b1bf76a291aa0aef19857a51aa964ac5a701d91
[apitrace] / retrace / dxgistate.cpp
1 /**************************************************************************
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
27 #include <assert.h>
28
29 #include <iostream>
30
31 #include "image.hpp"
32
33 #include "dxgistate.hpp"
34
35 #ifdef __MINGW32__
36 #define nullptr NULL
37 #endif
38 #include "DirectXTex.h"
39
40
41 namespace d3dstate {
42
43
44 static DXGI_FORMAT
45 ChooseConversionFormat(DXGI_FORMAT Format)
46 {
47     switch (Format) {
48
49     // Float
50     case DXGI_FORMAT_R32G32B32A32_FLOAT:
51     case DXGI_FORMAT_R32G32B32_FLOAT:
52     case DXGI_FORMAT_R16G16B16A16_FLOAT:
53     case DXGI_FORMAT_R32G32_FLOAT:
54     case DXGI_FORMAT_R11G11B10_FLOAT:
55     case DXGI_FORMAT_R16G16_FLOAT:
56     case DXGI_FORMAT_R32_FLOAT:
57     case DXGI_FORMAT_R16_FLOAT:
58     case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
59     case DXGI_FORMAT_BC6H_UF16:
60     case DXGI_FORMAT_BC6H_SF16:
61         return DXGI_FORMAT_R8G8B8A8_UNORM;
62
63     // Unsigned normalized
64     case DXGI_FORMAT_R16G16B16A16_UNORM:
65     case DXGI_FORMAT_R10G10B10A2_UNORM:
66     case DXGI_FORMAT_R8G8B8A8_UNORM:
67     case DXGI_FORMAT_R16G16_UNORM:
68     case DXGI_FORMAT_R8G8_UNORM:
69     case DXGI_FORMAT_R16_UNORM:
70     case DXGI_FORMAT_R8_UNORM:
71     case DXGI_FORMAT_A8_UNORM:
72     case DXGI_FORMAT_R1_UNORM:
73     case DXGI_FORMAT_R8G8_B8G8_UNORM:
74     case DXGI_FORMAT_G8R8_G8B8_UNORM:
75     case DXGI_FORMAT_BC1_UNORM:
76     case DXGI_FORMAT_BC2_UNORM:
77     case DXGI_FORMAT_BC3_UNORM:
78     case DXGI_FORMAT_BC4_UNORM:
79     case DXGI_FORMAT_BC5_UNORM:
80     case DXGI_FORMAT_B5G6R5_UNORM:
81     case DXGI_FORMAT_B5G5R5A1_UNORM:
82     case DXGI_FORMAT_B8G8R8A8_UNORM:
83     case DXGI_FORMAT_B8G8R8X8_UNORM:
84     case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
85     case DXGI_FORMAT_BC7_UNORM:
86         return DXGI_FORMAT_R8G8B8A8_UNORM;
87
88     // SRGB
89     case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
90     case DXGI_FORMAT_BC1_UNORM_SRGB:
91     case DXGI_FORMAT_BC2_UNORM_SRGB:
92     case DXGI_FORMAT_BC3_UNORM_SRGB:
93     case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
94     case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
95     case DXGI_FORMAT_BC7_UNORM_SRGB:
96         return DXGI_FORMAT_R8G8B8A8_UNORM;
97
98     // Signed normalized
99     case DXGI_FORMAT_R16G16B16A16_SNORM:
100     case DXGI_FORMAT_R8G8B8A8_SNORM:
101     case DXGI_FORMAT_R16G16_SNORM:
102     case DXGI_FORMAT_R8G8_SNORM:
103     case DXGI_FORMAT_R16_SNORM:
104     case DXGI_FORMAT_R8_SNORM:
105     case DXGI_FORMAT_BC4_SNORM:
106     case DXGI_FORMAT_BC5_SNORM:
107         return DXGI_FORMAT_R8G8B8A8_SNORM;
108
109     // Unsigned
110     case DXGI_FORMAT_R32G32B32A32_UINT:
111     case DXGI_FORMAT_R32G32B32_UINT:
112     case DXGI_FORMAT_R16G16B16A16_UINT:
113     case DXGI_FORMAT_R32G32_UINT:
114     case DXGI_FORMAT_R10G10B10A2_UINT:
115     case DXGI_FORMAT_R8G8B8A8_UINT:
116     case DXGI_FORMAT_R16G16_UINT:
117     case DXGI_FORMAT_R32_UINT:
118     case DXGI_FORMAT_R8G8_UINT:
119     case DXGI_FORMAT_R16_UINT:
120     case DXGI_FORMAT_R8_UINT:
121         return DXGI_FORMAT_R8G8B8A8_UINT;
122
123     // Signed
124     case DXGI_FORMAT_R32G32B32A32_SINT:
125     case DXGI_FORMAT_R32G32B32_SINT:
126     case DXGI_FORMAT_R16G16B16A16_SINT:
127     case DXGI_FORMAT_R32G32_SINT:
128     case DXGI_FORMAT_R8G8B8A8_SINT:
129     case DXGI_FORMAT_R16G16_SINT:
130     case DXGI_FORMAT_R32_SINT:
131     case DXGI_FORMAT_R8G8_SINT:
132     case DXGI_FORMAT_R16_SINT:
133     case DXGI_FORMAT_R8_SINT:
134         return DXGI_FORMAT_R8G8B8A8_SINT;
135
136     // Depth
137     case DXGI_FORMAT_D32_FLOAT:
138     case DXGI_FORMAT_D24_UNORM_S8_UINT:
139     case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
140     case DXGI_FORMAT_D16_UNORM:
141         return DXGI_FORMAT_R8G8B8A8_UNORM;
142
143     // Typeless
144     case DXGI_FORMAT_UNKNOWN:
145     case DXGI_FORMAT_R32G32B32A32_TYPELESS:
146     case DXGI_FORMAT_R32G32B32_TYPELESS:
147     case DXGI_FORMAT_R16G16B16A16_TYPELESS:
148     case DXGI_FORMAT_R32G32_TYPELESS:
149     case DXGI_FORMAT_R32G8X24_TYPELESS:
150     case DXGI_FORMAT_R10G10B10A2_TYPELESS:
151     case DXGI_FORMAT_R8G8B8A8_TYPELESS:
152     case DXGI_FORMAT_R16G16_TYPELESS:
153     case DXGI_FORMAT_R32_TYPELESS:
154     case DXGI_FORMAT_R8G8_TYPELESS:
155     case DXGI_FORMAT_R16_TYPELESS:
156     case DXGI_FORMAT_R8_TYPELESS:
157     case DXGI_FORMAT_BC1_TYPELESS:
158     case DXGI_FORMAT_BC2_TYPELESS:
159     case DXGI_FORMAT_BC3_TYPELESS:
160     case DXGI_FORMAT_BC4_TYPELESS:
161     case DXGI_FORMAT_BC5_TYPELESS:
162     case DXGI_FORMAT_B8G8R8A8_TYPELESS:
163     case DXGI_FORMAT_B8G8R8X8_TYPELESS:
164     case DXGI_FORMAT_BC6H_TYPELESS:
165     case DXGI_FORMAT_BC7_TYPELESS:
166     case DXGI_FORMAT_R24G8_TYPELESS:
167     case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
168     case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
169     case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
170     case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
171         return DXGI_FORMAT_UNKNOWN;
172
173     default:
174         return DXGI_FORMAT_R8G8B8A8_UNORM;
175     }
176 }
177
178
179 /**
180  * Convert between DXGI formats.
181  *
182  */
183 HRESULT
184 ConvertFormat(DXGI_FORMAT SrcFormat,
185               void *SrcData,
186               UINT SrcPitch,
187               DXGI_FORMAT DstFormat,
188               void *DstData,
189               UINT DstPitch,
190               UINT Width, UINT Height)
191 {
192     HRESULT hr;
193
194     DirectX::Image SrcImage;
195     DirectX::Image DstImage;
196
197     SrcImage.width = Width;
198     SrcImage.height = Height;
199     SrcImage.format = SrcFormat;
200     SrcImage.rowPitch = SrcPitch;
201     SrcImage.slicePitch = Height * SrcPitch;
202     SrcImage.pixels = (uint8_t*)SrcData;
203
204     DstImage.width = Width;
205     DstImage.height = Height;
206     DstImage.format = DstFormat;
207     DstImage.rowPitch = DstPitch;
208     DstImage.slicePitch = Height * DstPitch;
209     DstImage.pixels = (uint8_t*)DstData;
210
211     DirectX::Rect rect(0, 0, Width, Height);
212
213     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
214     assert(SUCCEEDED(hr));
215     if (FAILED(hr)) {
216         return hr;
217     }
218
219     if (SrcFormat != DstFormat) {
220         DirectX::ScratchImage ScratchImage;
221         ScratchImage.Initialize2D(DstFormat, Width, Height, 1, 1);
222
223         if (DirectX::IsCompressed(SrcFormat)) {
224             hr = DirectX::Decompress(SrcImage, DstFormat, ScratchImage);
225         } else {
226             hr = DirectX::Convert(SrcImage, DstFormat, DirectX::TEX_FILTER_DEFAULT, 0.0f, ScratchImage);
227         }
228
229         if (SUCCEEDED(hr)) {
230             hr = CopyRectangle(*ScratchImage.GetImage(0, 0, 0), rect, DstImage, DirectX::TEX_FILTER_DEFAULT, 0, 0);
231         }
232     } else {
233         hr = CopyRectangle(SrcImage, rect, DstImage, DirectX::TEX_FILTER_DEFAULT, 0, 0);
234     }
235
236     return hr;
237 }
238
239
240 image::Image *
241 ConvertImage(DXGI_FORMAT SrcFormat,
242              void *SrcData,
243              UINT SrcPitch,
244              UINT Width, UINT Height)
245 {
246
247     DXGI_FORMAT DstFormat = ChooseConversionFormat(SrcFormat);
248     if (DstFormat == DXGI_FORMAT_UNKNOWN) {
249         return NULL;
250     }
251
252     image::Image *image = new image::Image(Width, Height, 4);
253     if (!image) {
254         return NULL;
255     }
256     assert(image->stride() > 0);
257
258     HRESULT hr;
259     hr = ConvertFormat(SrcFormat,
260                        SrcData, SrcPitch,
261                        DstFormat,
262                        image->start(), image->stride(),
263                        Width, Height);
264     if (FAILED(hr)) {
265         std::cerr << "warning: failed to convert from format " << SrcFormat << " to format " << DstFormat << "\n";
266         delete image;
267         image = NULL;
268     }
269
270     return image;
271 }
272
273 } /* namespace d3dstate */