• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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