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 parseried.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "gtest/gtest.h"
16 #include "src/amberscript/parser.h"
17
18 namespace amber {
19 namespace amberscript {
20
21 using AmberScriptParserTest = testing::Test;
22
TEST_F(AmberScriptParserTest,Pipeline)23 TEST_F(AmberScriptParserTest, Pipeline) {
24 std::string in = R"(
25 SHADER vertex my_shader PASSTHROUGH
26 SHADER fragment my_fragment GLSL
27 # GLSL Shader
28 END
29
30 PIPELINE graphics my_pipeline
31 ATTACH my_shader
32 ATTACH my_fragment
33 END
34 )";
35
36 Parser parser;
37 Result r = parser.Parse(in);
38 ASSERT_TRUE(r.IsSuccess()) << r.Error();
39
40 auto script = parser.GetScript();
41 EXPECT_EQ(2U, script->GetShaders().size());
42
43 const auto& pipelines = script->GetPipelines();
44 ASSERT_EQ(1U, pipelines.size());
45
46 const auto* pipeline = pipelines[0].get();
47 EXPECT_EQ("my_pipeline", pipeline->GetName());
48 EXPECT_EQ(PipelineType::kGraphics, pipeline->GetType());
49
50 const auto& shaders = pipeline->GetShaders();
51 ASSERT_EQ(2U, shaders.size());
52
53 ASSERT_TRUE(shaders[0].GetShader() != nullptr);
54 EXPECT_EQ("my_shader", shaders[0].GetShader()->GetName());
55 EXPECT_EQ(kShaderTypeVertex, shaders[0].GetShader()->GetType());
56 EXPECT_EQ(static_cast<uint32_t>(0),
57 shaders[0].GetShaderOptimizations().size());
58
59 ASSERT_TRUE(shaders[1].GetShader() != nullptr);
60 EXPECT_EQ("my_fragment", shaders[1].GetShader()->GetName());
61 EXPECT_EQ(kShaderTypeFragment, shaders[1].GetShader()->GetType());
62 EXPECT_EQ(static_cast<uint32_t>(0),
63 shaders[1].GetShaderOptimizations().size());
64
65 EXPECT_EQ(pipelines[0]->GetPipelineData()->GetPatchControlPoints(), 3u);
66 }
67
TEST_F(AmberScriptParserTest,PipelineMissingEnd)68 TEST_F(AmberScriptParserTest, PipelineMissingEnd) {
69 std::string in = R"(
70 SHADER vertex my_shader PASSTHROUGH
71 PIPELINE graphics my_pipeline
72 ATTACH my_shader
73 )";
74
75 Parser parser;
76 Result r = parser.Parse(in);
77 ASSERT_FALSE(r.IsSuccess());
78 EXPECT_EQ("5: PIPELINE missing END command", r.Error());
79 }
80
TEST_F(AmberScriptParserTest,PipelineWithExtraParams)81 TEST_F(AmberScriptParserTest, PipelineWithExtraParams) {
82 std::string in = R"(
83 PIPELINE graphics my_pipeline INVALID
84 ATTACH my_shader
85 END
86 )";
87
88 Parser parser;
89 Result r = parser.Parse(in);
90 ASSERT_FALSE(r.IsSuccess());
91 EXPECT_EQ("2: extra parameters after PIPELINE command: INVALID", r.Error());
92 }
93
TEST_F(AmberScriptParserTest,PipelineInvalidType)94 TEST_F(AmberScriptParserTest, PipelineInvalidType) {
95 std::string in = "PIPELINE my_name\nEND";
96
97 Parser parser;
98 Result r = parser.Parse(in);
99 ASSERT_FALSE(r.IsSuccess());
100 EXPECT_EQ("1: unknown pipeline type: my_name", r.Error());
101 }
102
TEST_F(AmberScriptParserTest,PipelineMissingName)103 TEST_F(AmberScriptParserTest, PipelineMissingName) {
104 std::string in = "PIPELINE compute\nEND";
105
106 Parser parser;
107 Result r = parser.Parse(in);
108 ASSERT_FALSE(r.IsSuccess());
109 EXPECT_EQ("2: invalid token when looking for pipeline name", r.Error());
110 }
111
TEST_F(AmberScriptParserTest,PipelineWithInvalidTokenType)112 TEST_F(AmberScriptParserTest, PipelineWithInvalidTokenType) {
113 std::string in = "PIPELINE 123 my_pipeline\nEND";
114
115 Parser parser;
116 Result r = parser.Parse(in);
117 ASSERT_FALSE(r.IsSuccess());
118 EXPECT_EQ("1: invalid token when looking for pipeline type", r.Error());
119 }
120
TEST_F(AmberScriptParserTest,PipelineWithInvalidTokenName)121 TEST_F(AmberScriptParserTest, PipelineWithInvalidTokenName) {
122 std::string in = "PIPELINE compute 123\nEND";
123
124 Parser parser;
125 Result r = parser.Parse(in);
126 ASSERT_FALSE(r.IsSuccess());
127 EXPECT_EQ("1: invalid token when looking for pipeline name", r.Error());
128 }
129
TEST_F(AmberScriptParserTest,PipelineEmpty)130 TEST_F(AmberScriptParserTest, PipelineEmpty) {
131 std::string in = "PIPELINE compute my_pipeline\nEND";
132
133 Parser parser;
134 Result r = parser.Parse(in);
135 ASSERT_FALSE(r.IsSuccess());
136 EXPECT_EQ("compute pipeline requires a compute shader", r.Error());
137 }
138
TEST_F(AmberScriptParserTest,PipelineWithUnknownCommand)139 TEST_F(AmberScriptParserTest, PipelineWithUnknownCommand) {
140 std::string in = R"(
141 PIPELINE compute my_pipeline
142 SHADER vertex my_shader PASSTHROUGH
143 END)";
144
145 Parser parser;
146 Result r = parser.Parse(in);
147 ASSERT_FALSE(r.IsSuccess());
148 EXPECT_EQ("3: unknown token in pipeline block: SHADER", r.Error());
149 }
150
TEST_F(AmberScriptParserTest,DuplicatePipelineName)151 TEST_F(AmberScriptParserTest, DuplicatePipelineName) {
152 std::string in = R"(
153 SHADER vertex my_shader PASSTHROUGH
154 SHADER fragment my_fragment GLSL
155 # Fragment shader
156 END
157
158 PIPELINE graphics my_pipeline
159 ATTACH my_shader
160 ATTACH my_fragment
161 END
162 PIPELINE graphics my_pipeline
163 ATTACH my_shader
164 ATTACH my_fragment
165 END)";
166
167 Parser parser;
168 Result r = parser.Parse(in);
169 ASSERT_FALSE(r.IsSuccess());
170 EXPECT_EQ("14: duplicate pipeline name provided", r.Error());
171 }
172
TEST_F(AmberScriptParserTest,PipelineDefaultColorBuffer)173 TEST_F(AmberScriptParserTest, PipelineDefaultColorBuffer) {
174 std::string in = R"(
175 SHADER vertex my_shader PASSTHROUGH
176 SHADER fragment my_fragment GLSL
177 # GLSL Shader
178 END
179
180 PIPELINE graphics my_pipeline
181 ATTACH my_shader
182 ATTACH my_fragment
183 END
184 PIPELINE graphics my_pipeline2
185 ATTACH my_shader
186 ATTACH my_fragment
187 END)";
188
189 Parser parser;
190 Result r = parser.Parse(in);
191 ASSERT_TRUE(r.IsSuccess()) << r.Error();
192
193 auto script = parser.GetScript();
194 const auto& pipelines = script->GetPipelines();
195 ASSERT_EQ(2U, pipelines.size());
196
197 ASSERT_EQ(1U, pipelines[0]->GetColorAttachments().size());
198 const auto& buf1 = pipelines[0]->GetColorAttachments()[0];
199 ASSERT_TRUE(buf1.buffer != nullptr);
200
201 Buffer* buffer1 = buf1.buffer;
202 EXPECT_EQ(FormatType::kB8G8R8A8_UNORM, buffer1->GetFormat()->GetFormatType());
203 EXPECT_EQ(0u, buf1.location);
204 EXPECT_EQ(250u * 250u, buffer1->ElementCount());
205 EXPECT_EQ(250u * 250u * 4u, buffer1->ValueCount());
206 EXPECT_EQ(250u * 250u * 4u * sizeof(uint8_t), buffer1->GetSizeInBytes());
207
208 ASSERT_EQ(1U, pipelines[1]->GetColorAttachments().size());
209 const auto& buf2 = pipelines[1]->GetColorAttachments()[0];
210 ASSERT_TRUE(buf2.buffer != nullptr);
211 ASSERT_EQ(buffer1, buf2.buffer);
212 EXPECT_EQ(0u, buf2.location);
213 EXPECT_EQ(FormatType::kB8G8R8A8_UNORM,
214 buf2.buffer->GetFormat()->GetFormatType());
215 EXPECT_EQ(250u * 250u, buf2.buffer->ElementCount());
216 EXPECT_EQ(250u * 250u * 4u, buf2.buffer->ValueCount());
217 EXPECT_EQ(250u * 250u * 4u * sizeof(uint8_t), buf2.buffer->GetSizeInBytes());
218 }
219
TEST_F(AmberScriptParserTest,PipelineDefaultColorBufferMismatchSize)220 TEST_F(AmberScriptParserTest, PipelineDefaultColorBufferMismatchSize) {
221 std::string in = R"(
222 SHADER vertex my_shader PASSTHROUGH
223 SHADER fragment my_fragment GLSL
224 # GLSL Shader
225 END
226
227 PIPELINE graphics my_pipeline
228 ATTACH my_shader
229 ATTACH my_fragment
230 END
231 PIPELINE graphics my_pipeline2
232 ATTACH my_shader
233 ATTACH my_fragment
234 FRAMEBUFFER_SIZE 256 256
235 END)";
236
237 Parser parser;
238 Result r = parser.Parse(in);
239 ASSERT_FALSE(r.IsSuccess());
240
241 EXPECT_EQ("shared framebuffer must have same size over all PIPELINES",
242 r.Error());
243 }
244
TEST_F(AmberScriptParserTest,PipelinePolygonMode)245 TEST_F(AmberScriptParserTest, PipelinePolygonMode) {
246 std::string in = R"(
247 SHADER vertex my_shader PASSTHROUGH
248 SHADER fragment my_fragment GLSL
249 # GLSL Shader
250 END
251
252 PIPELINE graphics my_pipeline_default
253 ATTACH my_shader
254 ATTACH my_fragment
255 FRAMEBUFFER_SIZE 256 256
256 END
257 PIPELINE graphics my_pipeline_fill
258 ATTACH my_shader
259 ATTACH my_fragment
260 POLYGON_MODE fill
261 FRAMEBUFFER_SIZE 256 256
262 END
263 PIPELINE graphics my_pipeline_line
264 ATTACH my_shader
265 ATTACH my_fragment
266 POLYGON_MODE line
267 FRAMEBUFFER_SIZE 256 256
268 END
269 PIPELINE graphics my_pipeline_point
270 ATTACH my_shader
271 ATTACH my_fragment
272 POLYGON_MODE point
273 FRAMEBUFFER_SIZE 256 256
274 END)";
275
276 Parser parser;
277 Result r = parser.Parse(in);
278 ASSERT_TRUE(r.IsSuccess());
279
280 auto script = parser.GetScript();
281 const auto& pipelines = script->GetPipelines();
282 ASSERT_EQ(4U, pipelines.size());
283
284 auto mode0 = pipelines[0]->GetPipelineData()->GetPolygonMode();
285 ASSERT_EQ(mode0, PolygonMode::kFill);
286 auto mode1 = pipelines[1]->GetPipelineData()->GetPolygonMode();
287 ASSERT_EQ(mode1, PolygonMode::kFill);
288 auto mode2 = pipelines[2]->GetPipelineData()->GetPolygonMode();
289 ASSERT_EQ(mode2, PolygonMode::kLine);
290 auto mode3 = pipelines[3]->GetPipelineData()->GetPolygonMode();
291 ASSERT_EQ(mode3, PolygonMode::kPoint);
292 }
293
TEST_F(AmberScriptParserTest,PipelineMissingPolygonMode)294 TEST_F(AmberScriptParserTest, PipelineMissingPolygonMode) {
295 std::string in = R"(
296 SHADER vertex my_shader PASSTHROUGH
297 SHADER fragment my_fragment GLSL
298 # GLSL Shader
299 END
300
301 PIPELINE graphics my_pipeline
302 ATTACH my_shader
303 ATTACH my_fragment
304 POLYGON_MODE
305 FRAMEBUFFER_SIZE 256 256
306 END)";
307
308 Parser parser;
309 Result r = parser.Parse(in);
310 ASSERT_FALSE(r.IsSuccess());
311
312 EXPECT_EQ("11: missing mode in POLYGON_MODE command", r.Error());
313 }
314
TEST_F(AmberScriptParserTest,PipelineInvalidPolygonMode)315 TEST_F(AmberScriptParserTest, PipelineInvalidPolygonMode) {
316 std::string in = R"(
317 SHADER vertex my_shader PASSTHROUGH
318 SHADER fragment my_fragment GLSL
319 # GLSL Shader
320 END
321
322 PIPELINE graphics my_pipeline
323 ATTACH my_shader
324 ATTACH my_fragment
325 POLYGON_MODE foo
326 FRAMEBUFFER_SIZE 256 256
327 END)";
328
329 Parser parser;
330 Result r = parser.Parse(in);
331 ASSERT_FALSE(r.IsSuccess());
332
333 EXPECT_EQ("10: invalid polygon mode: foo", r.Error());
334 }
335
TEST_F(AmberScriptParserTest,DerivePipeline)336 TEST_F(AmberScriptParserTest, DerivePipeline) {
337 std::string in = R"(
338 SHADER vertex my_shader PASSTHROUGH
339 SHADER fragment my_fragment GLSL
340 # GLSL Shader
341 END
342 SHADER fragment other_fragment GLSL
343 # GLSL Shader
344 END
345 BUFFER buf1 DATA_TYPE int32 SIZE 20 FILL 5
346 BUFFER buf2 DATA_TYPE int32 SIZE 20 FILL 7
347
348 PIPELINE graphics parent_pipeline
349 ATTACH my_shader
350 ATTACH my_fragment
351 BIND BUFFER buf1 AS storage DESCRIPTOR_SET 1 BINDING 3
352 END
353
354 DERIVE_PIPELINE child_pipeline FROM parent_pipeline
355 ATTACH other_fragment
356 BIND BUFFER buf2 AS storage DESCRIPTOR_SET 1 BINDING 3
357 END
358 )";
359
360 Parser parser;
361 Result r = parser.Parse(in);
362 ASSERT_TRUE(r.IsSuccess()) << r.Error();
363
364 auto script = parser.GetScript();
365 const auto& pipelines = script->GetPipelines();
366 ASSERT_EQ(2U, pipelines.size());
367
368 const auto* pipeline1 = pipelines[0].get();
369 auto buffers1 = pipeline1->GetBuffers();
370 ASSERT_EQ(1U, buffers1.size());
371 EXPECT_EQ("buf1", buffers1[0].buffer->GetName());
372 EXPECT_EQ(1u, buffers1[0].descriptor_set);
373 EXPECT_EQ(3u, buffers1[0].binding);
374
375 auto shaders1 = pipeline1->GetShaders();
376 ASSERT_EQ(2U, shaders1.size());
377 EXPECT_EQ("my_shader", shaders1[0].GetShader()->GetName());
378 EXPECT_EQ("my_fragment", shaders1[1].GetShader()->GetName());
379
380 const auto* pipeline2 = pipelines[1].get();
381 EXPECT_EQ("child_pipeline", pipeline2->GetName());
382
383 auto buffers2 = pipeline2->GetBuffers();
384 ASSERT_EQ(1U, buffers2.size());
385 EXPECT_EQ("buf2", buffers2[0].buffer->GetName());
386 EXPECT_EQ(1u, buffers2[0].descriptor_set);
387 EXPECT_EQ(3u, buffers2[0].binding);
388
389 auto shaders2 = pipeline2->GetShaders();
390 ASSERT_EQ(2U, shaders2.size());
391 EXPECT_EQ("my_shader", shaders2[0].GetShader()->GetName());
392 EXPECT_EQ("other_fragment", shaders2[1].GetShader()->GetName());
393 }
394
TEST_F(AmberScriptParserTest,DerivePipelineMissingEnd)395 TEST_F(AmberScriptParserTest, DerivePipelineMissingEnd) {
396 std::string in = R"(
397 SHADER vertex my_shader PASSTHROUGH
398 SHADER fragment my_fragment GLSL
399 # GLSL Shader
400 END
401
402 PIPELINE graphics parent_pipeline
403 ATTACH my_shader
404 ATTACH my_fragment
405 END
406
407 DERIVE_PIPELINE derived_pipeline FROM parent_pipeline
408 )";
409
410 Parser parser;
411 Result r = parser.Parse(in);
412 ASSERT_FALSE(r.IsSuccess());
413 EXPECT_EQ("13: DERIVE_PIPELINE missing END command", r.Error());
414 }
415
TEST_F(AmberScriptParserTest,DerivePipelineMissingPipelineName)416 TEST_F(AmberScriptParserTest, DerivePipelineMissingPipelineName) {
417 std::string in = R"(
418 SHADER vertex my_shader PASSTHROUGH
419 SHADER fragment my_fragment GLSL
420 # GLSL Shader
421 END
422
423 PIPELINE graphics parent_pipeline
424 ATTACH my_shader
425 ATTACH my_fragment
426 END
427
428 DERIVE_PIPELINE FROM parent_pipeline
429 END
430 )";
431
432 Parser parser;
433 Result r = parser.Parse(in);
434 ASSERT_FALSE(r.IsSuccess());
435 EXPECT_EQ("12: missing pipeline name for DERIVE_PIPELINE command", r.Error());
436 }
437
TEST_F(AmberScriptParserTest,DerivePipelineMissingFrom)438 TEST_F(AmberScriptParserTest, DerivePipelineMissingFrom) {
439 std::string in = R"(
440 DERIVE_PIPELINE derived_pipeline parent_pipeline
441 END
442 )";
443
444 Parser parser;
445 Result r = parser.Parse(in);
446 ASSERT_FALSE(r.IsSuccess());
447 EXPECT_EQ("2: missing FROM in DERIVE_PIPELINE command", r.Error());
448 }
449
TEST_F(AmberScriptParserTest,DerivePipelineMissingParentPipelineName)450 TEST_F(AmberScriptParserTest, DerivePipelineMissingParentPipelineName) {
451 std::string in = R"(
452 DERIVE_PIPELINE derived_pipeline FROM
453 END
454 )";
455
456 Parser parser;
457 Result r = parser.Parse(in);
458 ASSERT_FALSE(r.IsSuccess());
459 EXPECT_EQ("3: missing parent pipeline name in DERIVE_PIPELINE command",
460 r.Error());
461 }
462
TEST_F(AmberScriptParserTest,DerivePipelineUnknownParentPipeline)463 TEST_F(AmberScriptParserTest, DerivePipelineUnknownParentPipeline) {
464 std::string in = R"(
465 DERIVE_PIPELINE derived_pipeline FROM parent_pipeline
466 END
467 )";
468
469 Parser parser;
470 Result r = parser.Parse(in);
471 ASSERT_FALSE(r.IsSuccess());
472 EXPECT_EQ("2: unknown parent pipeline in DERIVE_PIPELINE command", r.Error());
473 }
474
TEST_F(AmberScriptParserTest,DerivePipelineDuplicatePipelineName)475 TEST_F(AmberScriptParserTest, DerivePipelineDuplicatePipelineName) {
476 std::string in = R"(
477 SHADER vertex my_shader PASSTHROUGH
478 SHADER fragment my_fragment GLSL
479 # GLSL Shader
480 END
481
482 PIPELINE graphics parent_pipeline
483 ATTACH my_shader
484 ATTACH my_fragment
485 END
486
487 DERIVE_PIPELINE parent_pipeline FROM parent_pipeline
488 END
489 )";
490
491 Parser parser;
492 Result r = parser.Parse(in);
493 ASSERT_FALSE(r.IsSuccess());
494 EXPECT_EQ("12: duplicate pipeline name for DERIVE_PIPELINE command",
495 r.Error());
496 }
497
TEST_F(AmberScriptParserTest,DerivePipelineNoParams)498 TEST_F(AmberScriptParserTest, DerivePipelineNoParams) {
499 std::string in = R"(
500 DERIVE_PIPELINE
501 END
502 )";
503
504 Parser parser;
505 Result r = parser.Parse(in);
506 ASSERT_FALSE(r.IsSuccess());
507 EXPECT_EQ("3: missing pipeline name for DERIVE_PIPELINE command", r.Error());
508 }
509
TEST_F(AmberScriptParserTest,DerivePipelineSpecialized)510 TEST_F(AmberScriptParserTest, DerivePipelineSpecialized) {
511 std::string in = R"(
512 SHADER compute my_shader GLSL
513 #shaders
514 END
515 PIPELINE compute p1
516 ATTACH my_shader SPECIALIZE 3 AS uint32 4
517 END
518 DERIVE_PIPELINE p2 FROM p1
519 END
520 )";
521
522 Parser parser;
523 Result r = parser.Parse(in);
524 EXPECT_EQ("", r.Error());
525 ASSERT_TRUE(r.IsSuccess());
526
527 auto script = parser.GetScript();
528 const auto& pipelines = script->GetPipelines();
529 ASSERT_EQ(2U, pipelines.size());
530
531 const auto* p1 = pipelines[0].get();
532 const auto& s1 = p1->GetShaders();
533 ASSERT_EQ(1U, s1.size());
534
535 EXPECT_EQ(1u, s1[0].GetSpecialization().size());
536 EXPECT_EQ(4u, s1[0].GetSpecialization().at(3));
537
538 const auto* p2 = pipelines[1].get();
539 const auto& s2 = p2->GetShaders();
540 ASSERT_EQ(1U, s2.size());
541
542 EXPECT_EQ(1u, s2[0].GetSpecialization().size());
543 EXPECT_EQ(4u, s2[0].GetSpecialization().at(3));
544 }
545
TEST_F(AmberScriptParserTest,PipelinePatchControlPoints)546 TEST_F(AmberScriptParserTest, PipelinePatchControlPoints) {
547 std::string in = R"(
548 DEVICE_FEATURE tessellationShader
549
550 SHADER vertex my_shader PASSTHROUGH
551 SHADER fragment my_fragment GLSL
552 # GLSL Shader
553 END
554
555 SHADER tessellation_control my_tesc GLSL
556 # GLSL Shader
557 END
558
559 SHADER tessellation_evaluation my_tese GLSL
560 # GLSL Shader
561 END
562
563 PIPELINE graphics my_pipeline
564 ATTACH my_shader
565 ATTACH my_tesc
566 ATTACH my_tese
567 ATTACH my_fragment
568
569 PATCH_CONTROL_POINTS 4
570 END
571 )";
572
573 Parser parser;
574 Result r = parser.Parse(in);
575 ASSERT_TRUE(r.IsSuccess()) << r.Error();
576
577 auto script = parser.GetScript();
578 const auto& pipelines = script->GetPipelines();
579 ASSERT_EQ(1U, pipelines.size());
580
581 EXPECT_EQ(pipelines[0]->GetPipelineData()->GetPatchControlPoints(), 4u);
582 }
583
TEST_F(AmberScriptParserTest,PipelineDerivePatchControlPoints)584 TEST_F(AmberScriptParserTest, PipelineDerivePatchControlPoints) {
585 std::string in = R"(
586 DEVICE_FEATURE tessellationShader
587
588 SHADER vertex my_shader PASSTHROUGH
589 SHADER fragment my_fragment GLSL
590 # GLSL Shader
591 END
592
593 SHADER tessellation_control my_tesc GLSL
594 # GLSL Shader
595 END
596
597 SHADER tessellation_evaluation my_tese GLSL
598 # GLSL Shader
599 END
600
601 PIPELINE graphics my_pipeline
602 ATTACH my_shader
603 ATTACH my_tesc
604 ATTACH my_tese
605 ATTACH my_fragment
606
607 PATCH_CONTROL_POINTS 4
608 END
609
610 DERIVE_PIPELINE child_pipeline FROM my_pipeline
611 END
612 )";
613
614 Parser parser;
615 Result r = parser.Parse(in);
616 ASSERT_TRUE(r.IsSuccess()) << r.Error();
617
618 auto script = parser.GetScript();
619 const auto& pipelines = script->GetPipelines();
620 ASSERT_EQ(2U, pipelines.size());
621
622 EXPECT_EQ(pipelines[0]->GetPipelineData()->GetPatchControlPoints(), 4u);
623 EXPECT_EQ(pipelines[1]->GetPipelineData()->GetPatchControlPoints(), 4u);
624 }
625
626 } // namespace amberscript
627 } // namespace amber
628