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