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