1 // Copyright 2019 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/type_parser.h"
16
17 #include <cassert>
18 #include <cstdlib>
19 #include <string>
20
21 #include "src/make_unique.h"
22
23 namespace amber {
24
25 TypeParser::TypeParser() = default;
26
27 TypeParser::~TypeParser() = default;
28
Parse(const std::string & data)29 std::unique_ptr<type::Type> TypeParser::Parse(const std::string& data) {
30 if (data.empty())
31 return nullptr;
32
33 // See if this is a custom glsl string format.
34 if (data.find('/', 0) != std::string::npos)
35 return ParseGlslFormat(data);
36
37 // Walk the string backwards. This means we'll know if it's pack and we'll
38 // know the mode before we get to a given named component.
39 size_t cur_pos = std::string::npos;
40 for (;;) {
41 size_t next_pos = data.rfind('_', cur_pos);
42 if (next_pos == std::string::npos) {
43 if (cur_pos != std::string::npos)
44 ProcessChunk(data.substr(0, cur_pos + 1));
45 break;
46 }
47
48 ProcessChunk(data.substr(next_pos + 1, cur_pos - next_pos));
49 cur_pos = next_pos - 1;
50 }
51
52 if (pieces_.empty())
53 return nullptr;
54
55 std::unique_ptr<type::Type> type = nullptr;
56 if (pack_size_ == 0 && pieces_.size() == 1 &&
57 pieces_[0].type == FormatComponentType::kR) {
58 type = MakeUnique<type::Number>(pieces_[0].mode, pieces_[0].num_bits);
59 } else {
60 type = MakeUnique<type::List>();
61 type->SetRowCount(static_cast<uint32_t>(pieces_.size()));
62 type->AsList()->SetPackSizeInBits(pack_size_);
63
64 for (const auto& piece : pieces_)
65 type->AsList()->AddMember(piece.type, piece.mode, piece.num_bits);
66 }
67
68 pack_size_ = 0;
69 mode_ = FormatMode::kSInt;
70 pieces_.clear();
71
72 return type;
73 }
74
AddPiece(FormatComponentType type,FormatMode mode,uint8_t bits)75 void TypeParser::AddPiece(FormatComponentType type,
76 FormatMode mode,
77 uint8_t bits) {
78 pieces_.insert(pieces_.begin(), Pieces{type, mode, bits});
79 }
80
ProcessChunk(const std::string & data)81 void TypeParser::ProcessChunk(const std::string& data) {
82 assert(data.size() > 0);
83
84 if (data[0] == 'P') {
85 if (data == "PACK8")
86 pack_size_ = 8;
87 else if (data == "PACK16")
88 pack_size_ = 16;
89 else if (data == "PACK32")
90 pack_size_ = 32;
91 else
92 assert(false);
93
94 return;
95 }
96
97 if (data[0] == 'U') {
98 if (data == "UINT")
99 mode_ = FormatMode::kUInt;
100 else if (data == "UNORM")
101 mode_ = FormatMode::kUNorm;
102 else if (data == "UFLOAT")
103 mode_ = FormatMode::kUFloat;
104 else if (data == "USCALED")
105 mode_ = FormatMode::kUScaled;
106 else
107 assert(false);
108
109 return;
110 }
111
112 if (data[0] == 'S') {
113 if (data == "SINT")
114 mode_ = FormatMode::kSInt;
115 else if (data == "SNORM")
116 mode_ = FormatMode::kSNorm;
117 else if (data == "SSCALED")
118 mode_ = FormatMode::kSScaled;
119 else if (data == "SFLOAT")
120 mode_ = FormatMode::kSFloat;
121 else if (data == "SRGB")
122 mode_ = FormatMode::kSRGB;
123 else if (data == "S8")
124 AddPiece(FormatComponentType::kS, mode_, 8);
125 else
126 assert(false);
127
128 return;
129 }
130
131 int32_t cur_pos = static_cast<int32_t>(data.size()) - 1;
132 for (;;) {
133 FormatComponentType type = FormatComponentType::kA;
134 while (cur_pos >= 0) {
135 if (data[static_cast<size_t>(cur_pos)] == 'X') {
136 type = FormatComponentType::kX;
137 break;
138 } else if (data[static_cast<size_t>(cur_pos)] == 'D') {
139 type = FormatComponentType::kD;
140 break;
141 } else if (data[static_cast<size_t>(cur_pos)] == 'R') {
142 type = FormatComponentType::kR;
143 break;
144 } else if (data[static_cast<size_t>(cur_pos)] == 'G') {
145 type = FormatComponentType::kG;
146 break;
147 } else if (data[static_cast<size_t>(cur_pos)] == 'B') {
148 type = FormatComponentType::kB;
149 break;
150 } else if (data[static_cast<size_t>(cur_pos)] == 'A') {
151 type = FormatComponentType::kA;
152 break;
153 }
154 --cur_pos;
155 }
156 assert(cur_pos >= 0);
157
158 char* next_str;
159 const char* str = data.c_str() + cur_pos + 1;
160
161 uint64_t val = static_cast<uint64_t>(std::strtol(str, &next_str, 10));
162 if (val > 0)
163 AddPiece(type, mode_, static_cast<uint8_t>(val));
164
165 if (cur_pos == 0)
166 break;
167
168 --cur_pos;
169 }
170 }
171
172 // static
NameToFormatType(const std::string & data)173 FormatType TypeParser::NameToFormatType(const std::string& data) {
174 if (data == "A1R5G5B5_UNORM_PACK16")
175 return FormatType::kA1R5G5B5_UNORM_PACK16;
176 if (data == "A2B10G10R10_SINT_PACK32")
177 return FormatType::kA2B10G10R10_SINT_PACK32;
178 if (data == "A2B10G10R10_SNORM_PACK32")
179 return FormatType::kA2B10G10R10_SNORM_PACK32;
180 if (data == "A2B10G10R10_SSCALED_PACK32")
181 return FormatType::kA2B10G10R10_SSCALED_PACK32;
182 if (data == "A2B10G10R10_UINT_PACK32")
183 return FormatType::kA2B10G10R10_UINT_PACK32;
184 if (data == "A2B10G10R10_UNORM_PACK32")
185 return FormatType::kA2B10G10R10_UNORM_PACK32;
186 if (data == "A2B10G10R10_USCALED_PACK32")
187 return FormatType::kA2B10G10R10_USCALED_PACK32;
188 if (data == "A2R10G10B10_SINT_PACK32")
189 return FormatType::kA2R10G10B10_SINT_PACK32;
190 if (data == "A2R10G10B10_SNORM_PACK32")
191 return FormatType::kA2R10G10B10_SNORM_PACK32;
192 if (data == "A2R10G10B10_SSCALED_PACK32")
193 return FormatType::kA2R10G10B10_SSCALED_PACK32;
194 if (data == "A2R10G10B10_UINT_PACK32")
195 return FormatType::kA2R10G10B10_UINT_PACK32;
196 if (data == "A2R10G10B10_UNORM_PACK32")
197 return FormatType::kA2R10G10B10_UNORM_PACK32;
198 if (data == "A2R10G10B10_USCALED_PACK32")
199 return FormatType::kA2R10G10B10_USCALED_PACK32;
200 if (data == "A8B8G8R8_SINT_PACK32")
201 return FormatType::kA8B8G8R8_SINT_PACK32;
202 if (data == "A8B8G8R8_SNORM_PACK32")
203 return FormatType::kA8B8G8R8_SNORM_PACK32;
204 if (data == "A8B8G8R8_SRGB_PACK32")
205 return FormatType::kA8B8G8R8_SRGB_PACK32;
206 if (data == "A8B8G8R8_SSCALED_PACK32")
207 return FormatType::kA8B8G8R8_SSCALED_PACK32;
208 if (data == "A8B8G8R8_UINT_PACK32")
209 return FormatType::kA8B8G8R8_UINT_PACK32;
210 if (data == "A8B8G8R8_UNORM_PACK32")
211 return FormatType::kA8B8G8R8_UNORM_PACK32;
212 if (data == "A8B8G8R8_USCALED_PACK32")
213 return FormatType::kA8B8G8R8_USCALED_PACK32;
214 if (data == "B10G11R11_UFLOAT_PACK32")
215 return FormatType::kB10G11R11_UFLOAT_PACK32;
216 if (data == "B4G4R4A4_UNORM_PACK16")
217 return FormatType::kB4G4R4A4_UNORM_PACK16;
218 if (data == "B5G5R5A1_UNORM_PACK16")
219 return FormatType::kB5G5R5A1_UNORM_PACK16;
220 if (data == "B5G6R5_UNORM_PACK16")
221 return FormatType::kB5G6R5_UNORM_PACK16;
222 if (data == "B8G8R8A8_SINT")
223 return FormatType::kB8G8R8A8_SINT;
224 if (data == "B8G8R8A8_SNORM")
225 return FormatType::kB8G8R8A8_SNORM;
226 if (data == "B8G8R8A8_SRGB")
227 return FormatType::kB8G8R8A8_SRGB;
228 if (data == "B8G8R8A8_SSCALED")
229 return FormatType::kB8G8R8A8_SSCALED;
230 if (data == "B8G8R8A8_UINT")
231 return FormatType::kB8G8R8A8_UINT;
232 if (data == "B8G8R8A8_UNORM")
233 return FormatType::kB8G8R8A8_UNORM;
234 if (data == "B8G8R8A8_USCALED")
235 return FormatType::kB8G8R8A8_USCALED;
236 if (data == "B8G8R8_SINT")
237 return FormatType::kB8G8R8_SINT;
238 if (data == "B8G8R8_SNORM")
239 return FormatType::kB8G8R8_SNORM;
240 if (data == "B8G8R8_SRGB")
241 return FormatType::kB8G8R8_SRGB;
242 if (data == "B8G8R8_SSCALED")
243 return FormatType::kB8G8R8_SSCALED;
244 if (data == "B8G8R8_UINT")
245 return FormatType::kB8G8R8_UINT;
246 if (data == "B8G8R8_UNORM")
247 return FormatType::kB8G8R8_UNORM;
248 if (data == "B8G8R8_USCALED")
249 return FormatType::kB8G8R8_USCALED;
250 if (data == "D16_UNORM")
251 return FormatType::kD16_UNORM;
252 if (data == "D16_UNORM_S8_UINT")
253 return FormatType::kD16_UNORM_S8_UINT;
254 if (data == "D24_UNORM_S8_UINT")
255 return FormatType::kD24_UNORM_S8_UINT;
256 if (data == "D32_SFLOAT")
257 return FormatType::kD32_SFLOAT;
258 if (data == "D32_SFLOAT_S8_UINT")
259 return FormatType::kD32_SFLOAT_S8_UINT;
260 if (data == "R16G16B16A16_SFLOAT")
261 return FormatType::kR16G16B16A16_SFLOAT;
262 if (data == "R16G16B16A16_SINT")
263 return FormatType::kR16G16B16A16_SINT;
264 if (data == "R16G16B16A16_SNORM")
265 return FormatType::kR16G16B16A16_SNORM;
266 if (data == "R16G16B16A16_SSCALED")
267 return FormatType::kR16G16B16A16_SSCALED;
268 if (data == "R16G16B16A16_UINT")
269 return FormatType::kR16G16B16A16_UINT;
270 if (data == "R16G16B16A16_UNORM")
271 return FormatType::kR16G16B16A16_UNORM;
272 if (data == "R16G16B16A16_USCALED")
273 return FormatType::kR16G16B16A16_USCALED;
274 if (data == "R16G16B16_SFLOAT")
275 return FormatType::kR16G16B16_SFLOAT;
276 if (data == "R16G16B16_SINT")
277 return FormatType::kR16G16B16_SINT;
278 if (data == "R16G16B16_SNORM")
279 return FormatType::kR16G16B16_SNORM;
280 if (data == "R16G16B16_SSCALED")
281 return FormatType::kR16G16B16_SSCALED;
282 if (data == "R16G16B16_UINT")
283 return FormatType::kR16G16B16_UINT;
284 if (data == "R16G16B16_UNORM")
285 return FormatType::kR16G16B16_UNORM;
286 if (data == "R16G16B16_USCALED")
287 return FormatType::kR16G16B16_USCALED;
288 if (data == "R16G16_SFLOAT")
289 return FormatType::kR16G16_SFLOAT;
290 if (data == "R16G16_SINT")
291 return FormatType::kR16G16_SINT;
292 if (data == "R16G16_SNORM")
293 return FormatType::kR16G16_SNORM;
294 if (data == "R16G16_SSCALED")
295 return FormatType::kR16G16_SSCALED;
296 if (data == "R16G16_UINT")
297 return FormatType::kR16G16_UINT;
298 if (data == "R16G16_UNORM")
299 return FormatType::kR16G16_UNORM;
300 if (data == "R16G16_USCALED")
301 return FormatType::kR16G16_USCALED;
302 if (data == "R16_SFLOAT")
303 return FormatType::kR16_SFLOAT;
304 if (data == "R16_SINT")
305 return FormatType::kR16_SINT;
306 if (data == "R16_SNORM")
307 return FormatType::kR16_SNORM;
308 if (data == "R16_SSCALED")
309 return FormatType::kR16_SSCALED;
310 if (data == "R16_UINT")
311 return FormatType::kR16_UINT;
312 if (data == "R16_UNORM")
313 return FormatType::kR16_UNORM;
314 if (data == "R16_USCALED")
315 return FormatType::kR16_USCALED;
316 if (data == "R32G32B32A32_SFLOAT")
317 return FormatType::kR32G32B32A32_SFLOAT;
318 if (data == "R32G32B32A32_SINT")
319 return FormatType::kR32G32B32A32_SINT;
320 if (data == "R32G32B32A32_UINT")
321 return FormatType::kR32G32B32A32_UINT;
322 if (data == "R32G32B32_SFLOAT")
323 return FormatType::kR32G32B32_SFLOAT;
324 if (data == "R32G32B32_SINT")
325 return FormatType::kR32G32B32_SINT;
326 if (data == "R32G32B32_UINT")
327 return FormatType::kR32G32B32_UINT;
328 if (data == "R32G32_SFLOAT")
329 return FormatType::kR32G32_SFLOAT;
330 if (data == "R32G32_SINT")
331 return FormatType::kR32G32_SINT;
332 if (data == "R32G32_UINT")
333 return FormatType::kR32G32_UINT;
334 if (data == "R32_SFLOAT")
335 return FormatType::kR32_SFLOAT;
336 if (data == "R32_SINT")
337 return FormatType::kR32_SINT;
338 if (data == "R32_UINT")
339 return FormatType::kR32_UINT;
340 if (data == "R4G4B4A4_UNORM_PACK16")
341 return FormatType::kR4G4B4A4_UNORM_PACK16;
342 if (data == "R4G4_UNORM_PACK8")
343 return FormatType::kR4G4_UNORM_PACK8;
344 if (data == "R5G5B5A1_UNORM_PACK16")
345 return FormatType::kR5G5B5A1_UNORM_PACK16;
346 if (data == "R5G6B5_UNORM_PACK16")
347 return FormatType::kR5G6B5_UNORM_PACK16;
348 if (data == "R64G64B64A64_SFLOAT")
349 return FormatType::kR64G64B64A64_SFLOAT;
350 if (data == "R64G64B64A64_SINT")
351 return FormatType::kR64G64B64A64_SINT;
352 if (data == "R64G64B64A64_UINT")
353 return FormatType::kR64G64B64A64_UINT;
354 if (data == "R64G64B64_SFLOAT")
355 return FormatType::kR64G64B64_SFLOAT;
356 if (data == "R64G64B64_SINT")
357 return FormatType::kR64G64B64_SINT;
358 if (data == "R64G64B64_UINT")
359 return FormatType::kR64G64B64_UINT;
360 if (data == "R64G64_SFLOAT")
361 return FormatType::kR64G64_SFLOAT;
362 if (data == "R64G64_SINT")
363 return FormatType::kR64G64_SINT;
364 if (data == "R64G64_UINT")
365 return FormatType::kR64G64_UINT;
366 if (data == "R64_SFLOAT")
367 return FormatType::kR64_SFLOAT;
368 if (data == "R64_SINT")
369 return FormatType::kR64_SINT;
370 if (data == "R64_UINT")
371 return FormatType::kR64_UINT;
372 if (data == "R8G8B8A8_SINT")
373 return FormatType::kR8G8B8A8_SINT;
374 if (data == "R8G8B8A8_SNORM")
375 return FormatType::kR8G8B8A8_SNORM;
376 if (data == "R8G8B8A8_SRGB")
377 return FormatType::kR8G8B8A8_SRGB;
378 if (data == "R8G8B8A8_SSCALED")
379 return FormatType::kR8G8B8A8_SSCALED;
380 if (data == "R8G8B8A8_UINT")
381 return FormatType::kR8G8B8A8_UINT;
382 if (data == "R8G8B8A8_UNORM")
383 return FormatType::kR8G8B8A8_UNORM;
384 if (data == "R8G8B8A8_USCALED")
385 return FormatType::kR8G8B8A8_USCALED;
386 if (data == "R8G8B8_SINT")
387 return FormatType::kR8G8B8_SINT;
388 if (data == "R8G8B8_SNORM")
389 return FormatType::kR8G8B8_SNORM;
390 if (data == "R8G8B8_SRGB")
391 return FormatType::kR8G8B8_SRGB;
392 if (data == "R8G8B8_SSCALED")
393 return FormatType::kR8G8B8_SSCALED;
394 if (data == "R8G8B8_UINT")
395 return FormatType::kR8G8B8_UINT;
396 if (data == "R8G8B8_UNORM")
397 return FormatType::kR8G8B8_UNORM;
398 if (data == "R8G8B8_USCALED")
399 return FormatType::kR8G8B8_USCALED;
400 if (data == "R8G8_SINT")
401 return FormatType::kR8G8_SINT;
402 if (data == "R8G8_SNORM")
403 return FormatType::kR8G8_SNORM;
404 if (data == "R8G8_SRGB")
405 return FormatType::kR8G8_SRGB;
406 if (data == "R8G8_SSCALED")
407 return FormatType::kR8G8_SSCALED;
408 if (data == "R8G8_UINT")
409 return FormatType::kR8G8_UINT;
410 if (data == "R8G8_UNORM")
411 return FormatType::kR8G8_UNORM;
412 if (data == "R8G8_USCALED")
413 return FormatType::kR8G8_USCALED;
414 if (data == "R8_SINT")
415 return FormatType::kR8_SINT;
416 if (data == "R8_SNORM")
417 return FormatType::kR8_SNORM;
418 if (data == "R8_SRGB")
419 return FormatType::kR8_SRGB;
420 if (data == "R8_SSCALED")
421 return FormatType::kR8_SSCALED;
422 if (data == "R8_UINT")
423 return FormatType::kR8_UINT;
424 if (data == "R8_UNORM")
425 return FormatType::kR8_UNORM;
426 if (data == "R8_USCALED")
427 return FormatType::kR8_USCALED;
428 if (data == "S8_UINT")
429 return FormatType::kS8_UINT;
430 if (data == "X8_D24_UNORM_PACK32")
431 return FormatType::kX8_D24_UNORM_PACK32;
432
433 return FormatType::kUnknown;
434 }
435
ParseGlslFormat(const std::string & fmt)436 std::unique_ptr<type::Type> TypeParser::ParseGlslFormat(
437 const std::string& fmt) {
438 size_t pos = fmt.find('/');
439 std::string gl_type = fmt.substr(0, pos);
440 std::string glsl_type = fmt.substr(pos + 1);
441
442 uint8_t bits = 0;
443 FormatMode mode = FormatMode::kUNorm;
444
445 static const struct {
446 const char* name;
447 uint8_t bits;
448 bool is_signed;
449 bool is_int;
450 } types[] = {
451 {"byte", 8, true, true}, {"ubyte", 8, false, true},
452 {"short", 16, true, true}, {"ushort", 16, false, true},
453 {"int", 32, true, true}, {"uint", 32, false, true},
454 {"half", 16, true, false}, {"float", 32, true, false},
455 {"double", 64, true, false},
456 };
457 for (auto& type : types) {
458 if (gl_type == std::string(type.name)) {
459 if (type.is_int)
460 mode = type.is_signed ? FormatMode::kSInt : FormatMode::kUInt;
461 else
462 mode = FormatMode::kSFloat;
463
464 bits = type.bits;
465 }
466 }
467
468 // Failed to find gl type.
469 if (mode == FormatMode::kUNorm)
470 return nullptr;
471
472 if (fmt.length() < 4)
473 return nullptr;
474
475 int8_t num_components = 0;
476 if (glsl_type == "float" || glsl_type == "double" || glsl_type == "int" ||
477 glsl_type == "uint") {
478 num_components = 1;
479 } else if (glsl_type.substr(0, 3) == "vec") {
480 num_components =
481 static_cast<int8_t>(strtol(glsl_type.c_str() + 3, nullptr, 10));
482 if (num_components < 2)
483 return nullptr;
484 } else if ((glsl_type[0] == 'd' || glsl_type[0] == 'i' ||
485 glsl_type[0] == 'u') &&
486 glsl_type.substr(1, 3) == "vec") {
487 num_components =
488 static_cast<int8_t>(strtol(glsl_type.c_str() + 4, nullptr, 10));
489 if (num_components < 2)
490 return nullptr;
491 }
492 if (num_components > 4)
493 return nullptr;
494
495 std::string new_name = "";
496 static const char* prefix = "RGBA";
497 for (int8_t i = 0; i < num_components; ++i)
498 new_name += prefix[i] + std::to_string(bits);
499
500 new_name += "_";
501 if (mode == FormatMode::kSInt)
502 new_name += "SINT";
503 else if (mode == FormatMode::kUInt)
504 new_name += "UINT";
505 else if (mode == FormatMode::kSFloat)
506 new_name += "SFLOAT";
507
508 return Parse(new_name);
509 }
510
511 } // namespace amber
512