• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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/vkscript/section_parser.h"
16 
17 #include "gtest/gtest.h"
18 #include "src/shader_data.h"
19 
20 namespace amber {
21 namespace vkscript {
22 
23 using SectionParserTest = testing::Test;
24 
TEST_F(SectionParserTest,SectionParserCommentSection)25 TEST_F(SectionParserTest, SectionParserCommentSection) {
26   std::string input = "[comment]\nThis is the comment body\n.Lots of Text.";
27 
28   SectionParser p;
29   Result r = p.SplitSectionsForTesting(input);
30   ASSERT_TRUE(r.IsSuccess());
31 
32   auto sections = p.Sections();
33   EXPECT_TRUE(sections.empty());
34 }
35 
TEST_F(SectionParserTest,ParseShaderGlslVertex)36 TEST_F(SectionParserTest, ParseShaderGlslVertex) {
37   std::string shader = R"(#version 430
38 void main() {
39 })";
40   std::string input = "[vertex shader]\n" + shader;
41 
42   SectionParser p;
43   Result r = p.SplitSectionsForTesting(input);
44   ASSERT_TRUE(r.IsSuccess());
45 
46   auto sections = p.Sections();
47   ASSERT_EQ(1U, sections.size());
48   EXPECT_EQ(NodeType::kShader, sections[0].section_type);
49   EXPECT_EQ(kShaderTypeVertex, sections[0].shader_type);
50   EXPECT_EQ(kShaderFormatGlsl, sections[0].format);
51   EXPECT_EQ(shader, sections[0].contents);
52 }
53 
TEST_F(SectionParserTest,ParseShaderGlslVertexPassthrough)54 TEST_F(SectionParserTest, ParseShaderGlslVertexPassthrough) {
55   std::string input = "[vertex shader passthrough]";
56 
57   SectionParser p;
58   Result r = p.SplitSectionsForTesting(input);
59   ASSERT_TRUE(r.IsSuccess());
60 
61   auto sections = p.Sections();
62   ASSERT_EQ(1U, sections.size());
63   EXPECT_EQ(NodeType::kShader, sections[0].section_type);
64   EXPECT_EQ(kShaderTypeVertex, sections[0].shader_type);
65   EXPECT_EQ(kShaderFormatSpirvAsm, sections[0].format);
66   EXPECT_EQ(kPassThroughShader, sections[0].contents);
67 }
68 
TEST_F(SectionParserTest,SectionParserMultipleSections)69 TEST_F(SectionParserTest, SectionParserMultipleSections) {
70   std::string input = R"(
71 [comment]
72 This is a test.
73 
74 [vertex shader passthrough]
75 [fragment shader]
76 #version 430
77 void main() {}
78 
79 [geometry shader]
80 float4 main() {}
81 
82 [comment]
83 Another comment section.
84 Multi line.
85 
86 [indices]
87 1 2 3 4
88 5 6 7 8
89 [test]
90 test body.)";
91 
92   SectionParser p;
93   Result r = p.SplitSectionsForTesting(input);
94   ASSERT_TRUE(r.IsSuccess()) << r.Error();
95 
96   auto sections = p.Sections();
97   ASSERT_EQ(5U, sections.size());
98 
99   // Passthrough vertext shader
100   EXPECT_EQ(NodeType::kShader, sections[0].section_type);
101   EXPECT_EQ(kShaderTypeVertex, sections[0].shader_type);
102   EXPECT_EQ(kShaderFormatSpirvAsm, sections[0].format);
103   EXPECT_EQ(kPassThroughShader, sections[0].contents);
104 
105   // fragment shader
106   EXPECT_EQ(NodeType::kShader, sections[1].section_type);
107   EXPECT_EQ(kShaderTypeFragment, sections[1].shader_type);
108   EXPECT_EQ(kShaderFormatGlsl, sections[1].format);
109   EXPECT_EQ("#version 430\nvoid main() {}", sections[1].contents);
110 
111   // geometry shader
112   EXPECT_EQ(NodeType::kShader, sections[2].section_type);
113   EXPECT_EQ(kShaderTypeGeometry, sections[2].shader_type);
114   EXPECT_EQ(kShaderFormatGlsl, sections[2].format);
115   EXPECT_EQ("float4 main() {}", sections[2].contents);
116 
117   // indices
118   EXPECT_EQ(NodeType::kIndices, sections[3].section_type);
119   EXPECT_EQ(kShaderFormatText, sections[3].format);
120   EXPECT_EQ("1 2 3 4\n5 6 7 8", sections[3].contents);
121 
122   // test
123   EXPECT_EQ(NodeType::kTest, sections[4].section_type);
124   EXPECT_EQ(kShaderFormatText, sections[4].format);
125   EXPECT_EQ("test body.", sections[4].contents);
126 }
127 
TEST_F(SectionParserTest,SkipCommentLinesOutsideSections)128 TEST_F(SectionParserTest, SkipCommentLinesOutsideSections) {
129   std::string input = "# comment 1\n#comment 2\r\n[vertex shader]";
130 
131   SectionParser p;
132   Result r = p.SplitSectionsForTesting(input);
133   ASSERT_TRUE(r.IsSuccess());
134 
135   auto sections = p.Sections();
136   ASSERT_EQ(1U, sections.size());
137   EXPECT_EQ(NodeType::kShader, sections[0].section_type);
138   EXPECT_EQ(kShaderTypeVertex, sections[0].shader_type);
139   EXPECT_EQ(kShaderFormatGlsl, sections[0].format);
140   EXPECT_EQ("", sections[0].contents);
141 }
142 
TEST_F(SectionParserTest,SkipBlankLinesOutsideSections)143 TEST_F(SectionParserTest, SkipBlankLinesOutsideSections) {
144   std::string input = "\n\r\n[vertex shader]";
145 
146   SectionParser p;
147   Result r = p.SplitSectionsForTesting(input);
148   ASSERT_TRUE(r.IsSuccess()) << r.Error();
149 
150   auto sections = p.Sections();
151   ASSERT_EQ(1U, sections.size());
152   EXPECT_EQ(NodeType::kShader, sections[0].section_type);
153   EXPECT_EQ(kShaderTypeVertex, sections[0].shader_type);
154   EXPECT_EQ(kShaderFormatGlsl, sections[0].format);
155   EXPECT_EQ("", sections[0].contents);
156 }
157 
TEST_F(SectionParserTest,UnknownTextOutsideSection)158 TEST_F(SectionParserTest, UnknownTextOutsideSection) {
159   std::string input = "Invalid Text";
160 
161   SectionParser p;
162   Result r = p.SplitSectionsForTesting(input);
163   EXPECT_FALSE(r.IsSuccess());
164   EXPECT_EQ("1: Invalid character", r.Error());
165 }
166 
TEST_F(SectionParserTest,UnknownSectionName)167 TEST_F(SectionParserTest, UnknownSectionName) {
168   std::string input = "[Invalid Section]";
169 
170   SectionParser p;
171   Result r = p.SplitSectionsForTesting(input);
172   EXPECT_FALSE(r.IsSuccess());
173   EXPECT_EQ("1: Invalid name: Invalid Section", r.Error());
174 }
175 
TEST_F(SectionParserTest,MissingSectionClose)176 TEST_F(SectionParserTest, MissingSectionClose) {
177   std::string input = "[vertex shader\nMore Content";
178 
179   SectionParser p;
180   Result r = p.SplitSectionsForTesting(input);
181   EXPECT_FALSE(r.IsSuccess());
182   EXPECT_EQ("1: Missing section close", r.Error());
183 }
184 
TEST_F(SectionParserTest,NameToNodeType)185 TEST_F(SectionParserTest, NameToNodeType) {
186   struct {
187     const char* name;
188     NodeType section_type;
189     ShaderType shader_type;
190     ShaderFormat fmt;
191   } name_cases[] = {
192       {"comment", NodeType::kComment, kShaderTypeVertex, kShaderFormatText},
193       {"indices", NodeType::kIndices, kShaderTypeVertex, kShaderFormatText},
194       {"require", NodeType::kRequire, kShaderTypeVertex, kShaderFormatText},
195       {"test", NodeType::kTest, kShaderTypeVertex, kShaderFormatText},
196       {"vertex data", NodeType::kVertexData, kShaderTypeVertex,
197        kShaderFormatText},
198 
199       {"compute shader", NodeType::kShader, kShaderTypeCompute,
200        kShaderFormatGlsl},
201       {"fragment shader", NodeType::kShader, kShaderTypeFragment,
202        kShaderFormatGlsl},
203       {"geometry shader", NodeType::kShader, kShaderTypeGeometry,
204        kShaderFormatGlsl},
205       {"tessellation control shader", NodeType::kShader,
206        kShaderTypeTessellationControl, kShaderFormatGlsl},
207       {"tessellation evaluation shader", NodeType::kShader,
208        kShaderTypeTessellationEvaluation, kShaderFormatGlsl},
209       {"vertex shader", NodeType::kShader, kShaderTypeVertex,
210        kShaderFormatGlsl},
211       {"compute shader spirv", NodeType::kShader, kShaderTypeCompute,
212        kShaderFormatSpirvAsm},
213       {"fragment shader spirv", NodeType::kShader, kShaderTypeFragment,
214        kShaderFormatSpirvAsm},
215       {"geometry shader spirv", NodeType::kShader, kShaderTypeGeometry,
216        kShaderFormatSpirvAsm},
217       {"tessellation control shader spirv", NodeType::kShader,
218        kShaderTypeTessellationControl, kShaderFormatSpirvAsm},
219       {"tessellation evaluation shader spirv", NodeType::kShader,
220        kShaderTypeTessellationEvaluation, kShaderFormatSpirvAsm},
221       {"vertex shader spirv", NodeType::kShader, kShaderTypeVertex,
222        kShaderFormatSpirvAsm},
223       {"compute shader spirv hex", NodeType::kShader, kShaderTypeCompute,
224        kShaderFormatSpirvHex},
225       {"fragment shader spirv hex", NodeType::kShader, kShaderTypeFragment,
226        kShaderFormatSpirvHex},
227       {"geometry shader spirv hex", NodeType::kShader, kShaderTypeGeometry,
228        kShaderFormatSpirvHex},
229       {"tessellation control shader spirv hex", NodeType::kShader,
230        kShaderTypeTessellationControl, kShaderFormatSpirvHex},
231       {"tessellation evaluation shader spirv hex", NodeType::kShader,
232        kShaderTypeTessellationEvaluation, kShaderFormatSpirvHex},
233       {"vertex shader spirv hex", NodeType::kShader, kShaderTypeVertex,
234        kShaderFormatSpirvHex},
235       {"vertex shader passthrough", NodeType::kShader, kShaderTypeVertex,
236        kShaderFormatDefault}};
237 
238   for (auto name_case : name_cases) {
239     NodeType section_type = NodeType::kTest;
240     ShaderType shader_type = kShaderTypeVertex;
241     ShaderFormat fmt = kShaderFormatText;
242     SectionParser p;
243     Result r = p.NameToNodeTypeForTesting(name_case.name, &section_type,
244                                           &shader_type, &fmt);
245 
246     ASSERT_TRUE(r.IsSuccess()) << r.Error();
247     EXPECT_EQ(name_case.section_type, section_type) << name_case.name;
248     EXPECT_EQ(name_case.shader_type, shader_type) << name_case.name;
249     EXPECT_EQ(name_case.fmt, fmt) << name_case.name;
250   }
251 }
252 
TEST_F(SectionParserTest,NameToNodeTypeInvalidName)253 TEST_F(SectionParserTest, NameToNodeTypeInvalidName) {
254   NodeType section_type = NodeType::kTest;
255   ShaderType shader_type = kShaderTypeVertex;
256   ShaderFormat fmt = kShaderFormatText;
257   SectionParser p;
258   Result r = p.NameToNodeTypeForTesting("InvalidName", &section_type,
259                                         &shader_type, &fmt);
260   ASSERT_FALSE(r.IsSuccess());
261   EXPECT_EQ("Invalid name: InvalidName", r.Error());
262 }
263 
TEST_F(SectionParserTest,NameToSectionInvalidSuffix)264 TEST_F(SectionParserTest, NameToSectionInvalidSuffix) {
265   struct {
266     const char* name;
267   } cases[] = {{"comment spirv"},     {"indices spirv"},
268                {"require spirv"},     {"test spirv"},
269                {"vertex data spirv"}, {"comment spirv hex"},
270                {"indices spirv hex"}, {"require spirv hex"},
271                {"test spirv hex"},    {"vertex data spirv hex"}};
272 
273   for (auto name_case : cases) {
274     NodeType section_type = NodeType::kTest;
275     ShaderType shader_type = kShaderTypeVertex;
276     ShaderFormat fmt = kShaderFormatText;
277     SectionParser p;
278 
279     Result r = p.NameToNodeTypeForTesting(name_case.name, &section_type,
280                                           &shader_type, &fmt);
281     ASSERT_FALSE(r.IsSuccess()) << name_case.name;
282     EXPECT_EQ("Invalid source format: " + std::string(name_case.name),
283               r.Error());
284   }
285 }
286 
TEST_F(SectionParserTest,HasShader)287 TEST_F(SectionParserTest, HasShader) {
288   EXPECT_TRUE(SectionParser::HasShader(NodeType::kShader));
289 }
290 
TEST_F(SectionParserTest,HasNoShader)291 TEST_F(SectionParserTest, HasNoShader) {
292   const NodeType false_types[] = {NodeType::kComment, NodeType::kTest,
293                                   NodeType::kIndices, NodeType::kVertexData,
294                                   NodeType::kRequire};
295   for (auto type : false_types) {
296     EXPECT_FALSE(SectionParser::HasShader(type));
297   }
298 }
299 
300 }  // namespace vkscript
301 }  // namespace amber
302