blob: 0b1bf76a291aa0aef19857a51aa964ac5a701d91 [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"
32
José Fonsecac8695f72013-03-06 12:12:04 +000033#include "dxgistate.hpp"
34
35#ifdef __MINGW32__
36#define nullptr NULL
37#endif
38#include "DirectXTex.h"
39
40
41namespace d3dstate {
42
43
José Fonsecabbb9eb32013-04-16 19:38:00 +010044static DXGI_FORMAT
45ChooseConversionFormat(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
José Fonsecac8695f72013-03-06 12:12:04 +0000179/**
180 * Convert between DXGI formats.
181 *
182 */
183HRESULT
184ConvertFormat(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
José Fonseca386d29d2013-05-20 13:35:23 +0100213 hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
214 assert(SUCCEEDED(hr));
215 if (FAILED(hr)) {
216 return hr;
217 }
218
José Fonsecac8695f72013-03-06 12:12:04 +0000219 if (SrcFormat != DstFormat) {
220 DirectX::ScratchImage ScratchImage;
221 ScratchImage.Initialize2D(DstFormat, Width, Height, 1, 1);
222
José Fonseca4bdfcb92013-07-09 13:27:00 +0100223 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
José Fonsecac8695f72013-03-06 12:12:04 +0000229 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
José Fonsecabbb9eb32013-04-16 19:38:00 +0100240image::Image *
241ConvertImage(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)) {
José Fonseca4bdfcb92013-07-09 13:27:00 +0100265 std::cerr << "warning: failed to convert from format " << SrcFormat << " to format " << DstFormat << "\n";
José Fonsecabbb9eb32013-04-16 19:38:00 +0100266 delete image;
267 image = NULL;
268 }
269
270 return image;
271}
272
José Fonsecac8695f72013-03-06 12:12:04 +0000273} /* namespace d3dstate */