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/executor.h"
16 
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "gtest/gtest.h"
23 #include "src/engine.h"
24 #include "src/make_unique.h"
25 #include "src/vkscript/parser.h"
26 
27 namespace amber {
28 namespace vkscript {
29 namespace {
30 
31 class EngineStub : public Engine {
32  public:
EngineStub()33   EngineStub() : Engine() {}
34   ~EngineStub() override = default;
35 
36   // Engine
Initialize(EngineConfig *,Delegate *,const std::vector<std::string> & features,const std::vector<std::string> & instance_exts,const std::vector<std::string> & device_exts)37   Result Initialize(EngineConfig*,
38                     Delegate*,
39                     const std::vector<std::string>& features,
40                     const std::vector<std::string>& instance_exts,
41                     const std::vector<std::string>& device_exts) override {
42     features_ = features;
43     instance_extensions_ = instance_exts;
44     device_extensions_ = device_exts;
45     return {};
46   }
47 
GetFeatures() const48   const std::vector<std::string>& GetFeatures() const { return features_; }
GetDeviceExtensions() const49   const std::vector<std::string>& GetDeviceExtensions() const {
50     return device_extensions_;
51   }
GetFenceTimeoutMs()52   uint32_t GetFenceTimeoutMs() { return GetEngineData().fence_timeout_ms; }
53 
CreatePipeline(Pipeline *)54   Result CreatePipeline(Pipeline*) override { return {}; }
55 
FailClearColorCommand()56   void FailClearColorCommand() { fail_clear_color_command_ = true; }
DidClearColorCommand()57   bool DidClearColorCommand() { return did_clear_color_command_ = true; }
GetLastClearColorCommand()58   ClearColorCommand* GetLastClearColorCommand() { return last_clear_color_; }
DoClearColor(const ClearColorCommand * cmd)59   Result DoClearColor(const ClearColorCommand* cmd) override {
60     did_clear_color_command_ = true;
61 
62     if (fail_clear_color_command_)
63       return Result("clear color command failed");
64 
65     last_clear_color_ = const_cast<ClearColorCommand*>(cmd);
66     return {};
67   }
68 
FailClearStencilCommand()69   void FailClearStencilCommand() { fail_clear_stencil_command_ = true; }
DidClearStencilCommand() const70   bool DidClearStencilCommand() const { return did_clear_stencil_command_; }
DoClearStencil(const ClearStencilCommand *)71   Result DoClearStencil(const ClearStencilCommand*) override {
72     did_clear_stencil_command_ = true;
73 
74     if (fail_clear_stencil_command_)
75       return Result("clear stencil command failed");
76 
77     return {};
78   }
79 
FailClearDepthCommand()80   void FailClearDepthCommand() { fail_clear_depth_command_ = true; }
DidClearDepthCommand() const81   bool DidClearDepthCommand() const { return did_clear_depth_command_; }
DoClearDepth(const ClearDepthCommand *)82   Result DoClearDepth(const ClearDepthCommand*) override {
83     did_clear_depth_command_ = true;
84 
85     if (fail_clear_depth_command_)
86       return Result("clear depth command failed");
87 
88     return {};
89   }
90 
FailClearCommand()91   void FailClearCommand() { fail_clear_command_ = true; }
DidClearCommand() const92   bool DidClearCommand() const { return did_clear_command_; }
DoClear(const ClearCommand *)93   Result DoClear(const ClearCommand*) override {
94     did_clear_command_ = true;
95 
96     if (fail_clear_command_)
97       return Result("clear command failed");
98     return {};
99   }
100 
FailDrawRectCommand()101   void FailDrawRectCommand() { fail_draw_rect_command_ = true; }
DidDrawRectCommand() const102   bool DidDrawRectCommand() const { return did_draw_rect_command_; }
DoDrawRect(const DrawRectCommand *)103   Result DoDrawRect(const DrawRectCommand*) override {
104     did_draw_rect_command_ = true;
105 
106     if (fail_draw_rect_command_)
107       return Result("draw rect command failed");
108     return {};
109   }
110 
DoDrawGrid(const DrawGridCommand *)111   Result DoDrawGrid(const DrawGridCommand*) override {
112     did_draw_grid_command_ = true;
113 
114     if (fail_draw_grid_command_)
115       return Result("draw grid command failed");
116     return {};
117   }
118 
FailDrawArraysCommand()119   void FailDrawArraysCommand() { fail_draw_arrays_command_ = true; }
DidDrawArraysCommand() const120   bool DidDrawArraysCommand() const { return did_draw_arrays_command_; }
DoDrawArrays(const DrawArraysCommand *)121   Result DoDrawArrays(const DrawArraysCommand*) override {
122     did_draw_arrays_command_ = true;
123 
124     if (fail_draw_arrays_command_)
125       return Result("draw arrays command failed");
126     return {};
127   }
128 
FailComputeCommand()129   void FailComputeCommand() { fail_compute_command_ = true; }
DidComputeCommand() const130   bool DidComputeCommand() const { return did_compute_command_; }
DoCompute(const ComputeCommand *)131   Result DoCompute(const ComputeCommand*) override {
132     did_compute_command_ = true;
133 
134     if (fail_compute_command_)
135       return Result("compute command failed");
136     return {};
137   }
138 
FailEntryPointCommand()139   void FailEntryPointCommand() { fail_entry_point_command_ = true; }
DidEntryPointCommand() const140   bool DidEntryPointCommand() const { return did_entry_point_command_; }
DoEntryPoint(const EntryPointCommand *)141   Result DoEntryPoint(const EntryPointCommand*) override {
142     did_entry_point_command_ = true;
143 
144     if (fail_entry_point_command_)
145       return Result("entrypoint command failed");
146     return {};
147   }
148 
FailPatchParameterVerticesCommand()149   void FailPatchParameterVerticesCommand() { fail_patch_command_ = true; }
DidPatchParameterVerticesCommand() const150   bool DidPatchParameterVerticesCommand() const { return did_patch_command_; }
DoPatchParameterVertices(const PatchParameterVerticesCommand *)151   Result DoPatchParameterVertices(
152       const PatchParameterVerticesCommand*) override {
153     did_patch_command_ = true;
154 
155     if (fail_patch_command_)
156       return Result("patch command failed");
157     return {};
158   }
159 
FailBufferCommand()160   void FailBufferCommand() { fail_buffer_command_ = true; }
DidBufferCommand() const161   bool DidBufferCommand() const { return did_buffer_command_; }
DoBuffer(const BufferCommand *)162   Result DoBuffer(const BufferCommand*) override {
163     did_buffer_command_ = true;
164 
165     if (fail_buffer_command_)
166       return Result("buffer command failed");
167     return {};
168   }
169 
170  private:
171   bool fail_clear_command_ = false;
172   bool fail_clear_color_command_ = false;
173   bool fail_clear_stencil_command_ = false;
174   bool fail_clear_depth_command_ = false;
175   bool fail_draw_rect_command_ = false;
176   bool fail_draw_grid_command_ = false;
177   bool fail_draw_arrays_command_ = false;
178   bool fail_compute_command_ = false;
179   bool fail_entry_point_command_ = false;
180   bool fail_patch_command_ = false;
181   bool fail_buffer_command_ = false;
182 
183   bool did_clear_command_ = false;
184   bool did_clear_color_command_ = false;
185   bool did_clear_stencil_command_ = false;
186   bool did_clear_depth_command_ = false;
187   bool did_draw_rect_command_ = false;
188   bool did_draw_grid_command_ = false;
189   bool did_draw_arrays_command_ = false;
190   bool did_compute_command_ = false;
191   bool did_entry_point_command_ = false;
192   bool did_patch_command_ = false;
193   bool did_buffer_command_ = false;
194 
195   std::vector<std::string> features_;
196   std::vector<std::string> instance_extensions_;
197   std::vector<std::string> device_extensions_;
198 
199   ClearColorCommand* last_clear_color_ = nullptr;
200 };
201 
202 class VkScriptExecutorTest : public testing::Test {
203  public:
204   VkScriptExecutorTest() = default;
205   ~VkScriptExecutorTest() override = default;
206 
MakeEngine()207   std::unique_ptr<Engine> MakeEngine() { return MakeUnique<EngineStub>(); }
MakeAndInitializeEngine(const std::vector<std::string> & features,const std::vector<std::string> & instance_extensions,const std::vector<std::string> & device_extensions)208   std::unique_ptr<Engine> MakeAndInitializeEngine(
209       const std::vector<std::string>& features,
210       const std::vector<std::string>& instance_extensions,
211       const std::vector<std::string>& device_extensions) {
212     std::unique_ptr<Engine> engine = MakeUnique<EngineStub>();
213     engine->Initialize(nullptr, nullptr, features, instance_extensions,
214                        device_extensions);
215     return engine;
216   }
ToStub(Engine * engine)217   EngineStub* ToStub(Engine* engine) {
218     return static_cast<EngineStub*>(engine);
219   }
220 };
221 
222 }  // namespace
223 
TEST_F(VkScriptExecutorTest,ExecutesRequiredFeatures)224 TEST_F(VkScriptExecutorTest, ExecutesRequiredFeatures) {
225   std::string input = R"(
226 [require]
227 robustBufferAccess
228 logicOp)";
229 
230   Parser parser;
231   parser.SkipValidationForTest();
232   ASSERT_TRUE(parser.Parse(input).IsSuccess());
233 
234   auto script = parser.GetScript();
235   auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
236                                         script->GetRequiredInstanceExtensions(),
237                                         script->GetRequiredDeviceExtensions());
238 
239   Options options;
240   Executor ex;
241   Result r =
242       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
243   ASSERT_TRUE(r.IsSuccess());
244 
245   const auto& features = ToStub(engine.get())->GetFeatures();
246   ASSERT_EQ(2U, features.size());
247   EXPECT_EQ("robustBufferAccess", features[0]);
248   EXPECT_EQ("logicOp", features[1]);
249 
250   const auto& extensions = ToStub(engine.get())->GetDeviceExtensions();
251   ASSERT_EQ(static_cast<size_t>(0U), extensions.size());
252 }
253 
TEST_F(VkScriptExecutorTest,ExecutesRequiredExtensions)254 TEST_F(VkScriptExecutorTest, ExecutesRequiredExtensions) {
255   std::string input = R"(
256 [require]
257 VK_KHR_storage_buffer_storage_class
258 VK_KHR_variable_pointers)";
259 
260   Parser parser;
261   parser.SkipValidationForTest();
262   ASSERT_TRUE(parser.Parse(input).IsSuccess());
263 
264   auto script = parser.GetScript();
265   auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
266                                         script->GetRequiredInstanceExtensions(),
267                                         script->GetRequiredDeviceExtensions());
268 
269   Options options;
270   Executor ex;
271   Result r =
272       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
273   ASSERT_TRUE(r.IsSuccess());
274 
275   const auto& features = ToStub(engine.get())->GetFeatures();
276   ASSERT_EQ(static_cast<size_t>(0U), features.size());
277 
278   const auto& extensions = ToStub(engine.get())->GetDeviceExtensions();
279   ASSERT_EQ(2U, extensions.size());
280   EXPECT_EQ("VK_KHR_storage_buffer_storage_class", extensions[0]);
281   EXPECT_EQ("VK_KHR_variable_pointers", extensions[1]);
282 }
283 
TEST_F(VkScriptExecutorTest,ExecutesRequiredFrameBuffers)284 TEST_F(VkScriptExecutorTest, ExecutesRequiredFrameBuffers) {
285   std::string input = R"(
286 [require]
287 framebuffer R32G32B32A32_SFLOAT
288 depthstencil D24_UNORM_S8_UINT)";
289 
290   Parser parser;
291   parser.SkipValidationForTest();
292   ASSERT_TRUE(parser.Parse(input).IsSuccess());
293 
294   auto script = parser.GetScript();
295   auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
296                                         script->GetRequiredInstanceExtensions(),
297                                         script->GetRequiredDeviceExtensions());
298 
299   Options options;
300   Executor ex;
301   Result r =
302       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
303   ASSERT_TRUE(r.IsSuccess());
304 
305   const auto& features = ToStub(engine.get())->GetFeatures();
306   ASSERT_EQ(static_cast<size_t>(0U), features.size());
307 
308   const auto& extensions = ToStub(engine.get())->GetDeviceExtensions();
309   ASSERT_EQ(static_cast<size_t>(0U), extensions.size());
310 }
311 
TEST_F(VkScriptExecutorTest,ExecutesRequiredFenceTimeout)312 TEST_F(VkScriptExecutorTest, ExecutesRequiredFenceTimeout) {
313   std::string input = R"(
314 [require]
315 fence_timeout 12345)";
316 
317   Parser parser;
318   parser.SkipValidationForTest();
319   ASSERT_TRUE(parser.Parse(input).IsSuccess());
320 
321   auto script = parser.GetScript();
322   auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
323                                         script->GetRequiredInstanceExtensions(),
324                                         script->GetRequiredDeviceExtensions());
325 
326   Options options;
327   Executor ex;
328   Result r =
329       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
330   ASSERT_TRUE(r.IsSuccess());
331 
332   const auto& features = ToStub(engine.get())->GetFeatures();
333   ASSERT_EQ(static_cast<size_t>(0U), features.size());
334 
335   const auto& extensions = ToStub(engine.get())->GetDeviceExtensions();
336   ASSERT_EQ(static_cast<size_t>(0U), extensions.size());
337 
338   EXPECT_EQ(12345U, ToStub(engine.get())->GetFenceTimeoutMs());
339 }
340 
TEST_F(VkScriptExecutorTest,ExecutesRequiredAll)341 TEST_F(VkScriptExecutorTest, ExecutesRequiredAll) {
342   std::string input = R"(
343 [require]
344 robustBufferAccess
345 logicOp
346 VK_KHR_storage_buffer_storage_class
347 VK_KHR_variable_pointers
348 framebuffer R32G32B32A32_SFLOAT
349 depthstencil D24_UNORM_S8_UINT
350 fence_timeout 12345)";
351 
352   Parser parser;
353   parser.SkipValidationForTest();
354   ASSERT_TRUE(parser.Parse(input).IsSuccess());
355 
356   auto script = parser.GetScript();
357   auto engine = MakeAndInitializeEngine(script->GetRequiredFeatures(),
358                                         script->GetRequiredInstanceExtensions(),
359                                         script->GetRequiredDeviceExtensions());
360 
361   Options options;
362   Executor ex;
363   Result r =
364       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
365   ASSERT_TRUE(r.IsSuccess());
366 
367   const auto& features = ToStub(engine.get())->GetFeatures();
368   ASSERT_EQ(2U, features.size());
369   EXPECT_EQ("robustBufferAccess", features[0]);
370   EXPECT_EQ("logicOp", features[1]);
371 
372   const auto& extensions = ToStub(engine.get())->GetDeviceExtensions();
373   ASSERT_EQ(2U, extensions.size());
374   EXPECT_EQ("VK_KHR_storage_buffer_storage_class", extensions[0]);
375   EXPECT_EQ("VK_KHR_variable_pointers", extensions[1]);
376 
377   EXPECT_EQ(12345U, ToStub(engine.get())->GetFenceTimeoutMs());
378 }
379 
TEST_F(VkScriptExecutorTest,ClearCommand)380 TEST_F(VkScriptExecutorTest, ClearCommand) {
381   std::string input = R"(
382 [test]
383 clear)";
384 
385   Parser parser;
386   parser.SkipValidationForTest();
387   ASSERT_TRUE(parser.Parse(input).IsSuccess());
388 
389   auto engine = MakeEngine();
390   auto script = parser.GetScript();
391 
392   Options options;
393   Executor ex;
394   Result r =
395       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
396   ASSERT_TRUE(r.IsSuccess());
397   EXPECT_TRUE(ToStub(engine.get())->DidClearCommand());
398 }
399 
TEST_F(VkScriptExecutorTest,ClearCommandFailure)400 TEST_F(VkScriptExecutorTest, ClearCommandFailure) {
401   std::string input = R"(
402 [test]
403 clear)";
404 
405   Parser parser;
406   parser.SkipValidationForTest();
407   ASSERT_TRUE(parser.Parse(input).IsSuccess());
408 
409   auto engine = MakeEngine();
410   ToStub(engine.get())->FailClearCommand();
411   auto script = parser.GetScript();
412 
413   Options options;
414   Executor ex;
415   Result r =
416       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
417   ASSERT_FALSE(r.IsSuccess());
418   EXPECT_EQ("clear command failed", r.Error());
419 }
420 
TEST_F(VkScriptExecutorTest,ClearColorCommand)421 TEST_F(VkScriptExecutorTest, ClearColorCommand) {
422   std::string input = R"(
423 [test]
424 clear color 244 123 123 13)";
425 
426   Parser parser;
427   parser.SkipValidationForTest();
428   ASSERT_TRUE(parser.Parse(input).IsSuccess());
429 
430   auto engine = MakeEngine();
431   auto script = parser.GetScript();
432 
433   Options options;
434   Executor ex;
435   Result r =
436       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
437   ASSERT_TRUE(r.IsSuccess());
438   ASSERT_TRUE(ToStub(engine.get())->DidClearColorCommand());
439 
440   auto* cmd = ToStub(engine.get())->GetLastClearColorCommand();
441   ASSERT_TRUE(cmd != nullptr);
442   ASSERT_TRUE(cmd->IsClearColor());
443 
444   EXPECT_EQ(244U, cmd->GetR());
445   EXPECT_EQ(123U, cmd->GetG());
446   EXPECT_EQ(123U, cmd->GetB());
447   EXPECT_EQ(13U, cmd->GetA());
448 }
449 
TEST_F(VkScriptExecutorTest,ClearColorCommandFailure)450 TEST_F(VkScriptExecutorTest, ClearColorCommandFailure) {
451   std::string input = R"(
452 [test]
453 clear color 123 123 123 123)";
454 
455   Parser parser;
456   parser.SkipValidationForTest();
457   ASSERT_TRUE(parser.Parse(input).IsSuccess());
458 
459   auto engine = MakeEngine();
460   ToStub(engine.get())->FailClearColorCommand();
461   auto script = parser.GetScript();
462 
463   Options options;
464   Executor ex;
465   Result r =
466       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
467   ASSERT_FALSE(r.IsSuccess());
468   EXPECT_EQ("clear color command failed", r.Error());
469 }
470 
TEST_F(VkScriptExecutorTest,ClearDepthCommand)471 TEST_F(VkScriptExecutorTest, ClearDepthCommand) {
472   std::string input = R"(
473 [test]
474 clear depth 24)";
475 
476   Parser parser;
477   parser.SkipValidationForTest();
478   ASSERT_TRUE(parser.Parse(input).IsSuccess());
479 
480   auto engine = MakeEngine();
481   auto script = parser.GetScript();
482 
483   Options options;
484   Executor ex;
485   Result r =
486       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
487   ASSERT_TRUE(r.IsSuccess());
488   ASSERT_TRUE(ToStub(engine.get())->DidClearDepthCommand());
489 }
490 
TEST_F(VkScriptExecutorTest,ClearDepthCommandFailure)491 TEST_F(VkScriptExecutorTest, ClearDepthCommandFailure) {
492   std::string input = R"(
493 [test]
494 clear depth 24)";
495 
496   Parser parser;
497   parser.SkipValidationForTest();
498   ASSERT_TRUE(parser.Parse(input).IsSuccess());
499 
500   auto engine = MakeEngine();
501   ToStub(engine.get())->FailClearDepthCommand();
502   auto script = parser.GetScript();
503 
504   Options options;
505   Executor ex;
506   Result r =
507       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
508   ASSERT_FALSE(r.IsSuccess());
509   EXPECT_EQ("clear depth command failed", r.Error());
510 }
511 
TEST_F(VkScriptExecutorTest,ClearStencilCommand)512 TEST_F(VkScriptExecutorTest, ClearStencilCommand) {
513   std::string input = R"(
514 [test]
515 clear stencil 24)";
516 
517   Parser parser;
518   parser.SkipValidationForTest();
519   ASSERT_TRUE(parser.Parse(input).IsSuccess());
520 
521   auto engine = MakeEngine();
522   auto script = parser.GetScript();
523 
524   Options options;
525   Executor ex;
526   Result r =
527       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
528   ASSERT_TRUE(r.IsSuccess());
529   ASSERT_TRUE(ToStub(engine.get())->DidClearStencilCommand());
530 }
531 
TEST_F(VkScriptExecutorTest,ClearStencilCommandFailure)532 TEST_F(VkScriptExecutorTest, ClearStencilCommandFailure) {
533   std::string input = R"(
534 [test]
535 clear stencil 24)";
536 
537   Parser parser;
538   parser.SkipValidationForTest();
539   ASSERT_TRUE(parser.Parse(input).IsSuccess());
540 
541   auto engine = MakeEngine();
542   ToStub(engine.get())->FailClearStencilCommand();
543   auto script = parser.GetScript();
544 
545   Options options;
546   Executor ex;
547   Result r =
548       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
549   ASSERT_FALSE(r.IsSuccess());
550   EXPECT_EQ("clear stencil command failed", r.Error());
551 }
552 
TEST_F(VkScriptExecutorTest,DrawRectCommand)553 TEST_F(VkScriptExecutorTest, DrawRectCommand) {
554   std::string input = R"(
555 [test]
556 draw rect 2 4 10 20)";
557 
558   Parser parser;
559   parser.SkipValidationForTest();
560   ASSERT_TRUE(parser.Parse(input).IsSuccess());
561 
562   auto engine = MakeEngine();
563   auto script = parser.GetScript();
564 
565   Options options;
566   Executor ex;
567   Result r =
568       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
569   ASSERT_TRUE(r.IsSuccess());
570   ASSERT_TRUE(ToStub(engine.get())->DidDrawRectCommand());
571 }
572 
TEST_F(VkScriptExecutorTest,DrawRectCommandFailure)573 TEST_F(VkScriptExecutorTest, DrawRectCommandFailure) {
574   std::string input = R"(
575 [test]
576 draw rect 2 4 10 20)";
577 
578   Parser parser;
579   parser.SkipValidationForTest();
580   ASSERT_TRUE(parser.Parse(input).IsSuccess());
581 
582   auto engine = MakeEngine();
583   ToStub(engine.get())->FailDrawRectCommand();
584   auto script = parser.GetScript();
585 
586   Options options;
587   Executor ex;
588   Result r =
589       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
590   ASSERT_FALSE(r.IsSuccess());
591   EXPECT_EQ("draw rect command failed", r.Error());
592 }
593 
TEST_F(VkScriptExecutorTest,DrawArraysCommand)594 TEST_F(VkScriptExecutorTest, DrawArraysCommand) {
595   std::string input = R"(
596 [test]
597 draw arrays TRIANGLE_LIST 0 0)";
598 
599   Parser parser;
600   parser.SkipValidationForTest();
601   ASSERT_TRUE(parser.Parse(input).IsSuccess());
602 
603   auto engine = MakeEngine();
604   auto script = parser.GetScript();
605 
606   Options options;
607   Executor ex;
608   Result r =
609       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
610   ASSERT_TRUE(r.IsSuccess());
611   ASSERT_TRUE(ToStub(engine.get())->DidDrawArraysCommand());
612 }
613 
TEST_F(VkScriptExecutorTest,DrawArraysCommandFailure)614 TEST_F(VkScriptExecutorTest, DrawArraysCommandFailure) {
615   std::string input = R"(
616 [test]
617 draw arrays TRIANGLE_LIST 0 0)";
618 
619   Parser parser;
620   parser.SkipValidationForTest();
621   ASSERT_TRUE(parser.Parse(input).IsSuccess());
622 
623   auto engine = MakeEngine();
624   ToStub(engine.get())->FailDrawArraysCommand();
625   auto script = parser.GetScript();
626 
627   Options options;
628   Executor ex;
629   Result r =
630       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
631   ASSERT_FALSE(r.IsSuccess());
632   EXPECT_EQ("draw arrays command failed", r.Error());
633 }
634 
TEST_F(VkScriptExecutorTest,ComputeCommand)635 TEST_F(VkScriptExecutorTest, ComputeCommand) {
636   std::string input = R"(
637 [test]
638 compute 2 3 4)";
639 
640   Parser parser;
641   parser.SkipValidationForTest();
642   ASSERT_TRUE(parser.Parse(input).IsSuccess());
643 
644   auto engine = MakeEngine();
645   auto script = parser.GetScript();
646 
647   Options options;
648   Executor ex;
649   Result r =
650       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
651   ASSERT_TRUE(r.IsSuccess());
652   ASSERT_TRUE(ToStub(engine.get())->DidComputeCommand());
653 }
654 
TEST_F(VkScriptExecutorTest,ComputeCommandFailure)655 TEST_F(VkScriptExecutorTest, ComputeCommandFailure) {
656   std::string input = R"(
657 [test]
658 compute 2 3 4)";
659 
660   Parser parser;
661   parser.SkipValidationForTest();
662   ASSERT_TRUE(parser.Parse(input).IsSuccess());
663 
664   auto engine = MakeEngine();
665   ToStub(engine.get())->FailComputeCommand();
666   auto script = parser.GetScript();
667 
668   Options options;
669   Executor ex;
670   Result r =
671       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
672   ASSERT_FALSE(r.IsSuccess());
673   EXPECT_EQ("compute command failed", r.Error());
674 }
675 
TEST_F(VkScriptExecutorTest,EntryPointCommand)676 TEST_F(VkScriptExecutorTest, EntryPointCommand) {
677   std::string input = R"(
678 [test]
679 vertex entrypoint main)";
680 
681   Parser parser;
682   parser.SkipValidationForTest();
683   ASSERT_TRUE(parser.Parse(input).IsSuccess());
684 
685   auto engine = MakeEngine();
686   auto script = parser.GetScript();
687 
688   Options options;
689   Executor ex;
690   Result r =
691       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
692   ASSERT_TRUE(r.IsSuccess());
693   ASSERT_TRUE(ToStub(engine.get())->DidEntryPointCommand());
694 }
695 
TEST_F(VkScriptExecutorTest,EntryPointCommandFailure)696 TEST_F(VkScriptExecutorTest, EntryPointCommandFailure) {
697   std::string input = R"(
698 [test]
699 vertex entrypoint main)";
700 
701   Parser parser;
702   parser.SkipValidationForTest();
703   ASSERT_TRUE(parser.Parse(input).IsSuccess());
704 
705   auto engine = MakeEngine();
706   ToStub(engine.get())->FailEntryPointCommand();
707   auto script = parser.GetScript();
708 
709   Options options;
710   Executor ex;
711   Result r =
712       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
713   ASSERT_FALSE(r.IsSuccess());
714   EXPECT_EQ("entrypoint command failed", r.Error());
715 }
716 
TEST_F(VkScriptExecutorTest,PatchParameterVerticesCommand)717 TEST_F(VkScriptExecutorTest, PatchParameterVerticesCommand) {
718   std::string input = R"(
719 [test]
720 patch parameter vertices 10)";
721 
722   Parser parser;
723   parser.SkipValidationForTest();
724   ASSERT_TRUE(parser.Parse(input).IsSuccess());
725 
726   auto engine = MakeEngine();
727   auto script = parser.GetScript();
728 
729   Options options;
730   Executor ex;
731   Result r =
732       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
733   ASSERT_TRUE(r.IsSuccess());
734   ASSERT_TRUE(ToStub(engine.get())->DidPatchParameterVerticesCommand());
735 }
736 
TEST_F(VkScriptExecutorTest,PatchParameterVerticesCommandFailure)737 TEST_F(VkScriptExecutorTest, PatchParameterVerticesCommandFailure) {
738   std::string input = R"(
739 [test]
740 patch parameter vertices 10)";
741 
742   Parser parser;
743   parser.SkipValidationForTest();
744   ASSERT_TRUE(parser.Parse(input).IsSuccess());
745 
746   auto engine = MakeEngine();
747   ToStub(engine.get())->FailPatchParameterVerticesCommand();
748   auto script = parser.GetScript();
749 
750   Options options;
751   Executor ex;
752   Result r =
753       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
754   ASSERT_FALSE(r.IsSuccess());
755   EXPECT_EQ("patch command failed", r.Error());
756 }
757 
TEST_F(VkScriptExecutorTest,DISABLED_ProbeCommand)758 TEST_F(VkScriptExecutorTest, DISABLED_ProbeCommand) {
759   std::string input = R"(
760 [test]
761 probe rect rgba 2 3 40 40 0.2 0.4 0.4 0.3)";
762 
763   Parser parser;
764   ASSERT_TRUE(parser.Parse(input).IsSuccess());
765 
766   auto engine = MakeEngine();
767   auto script = parser.GetScript();
768 
769   Options options;
770   Executor ex;
771   Result r =
772       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
773   ASSERT_TRUE(r.IsSuccess());
774   // ASSERT_TRUE(ToStub(engine.get())->DidProbeCommand());
775 }
776 
TEST_F(VkScriptExecutorTest,DISABLED_ProbeCommandFailure)777 TEST_F(VkScriptExecutorTest, DISABLED_ProbeCommandFailure) {
778   std::string input = R"(
779 [test]
780 probe rect rgba 2 3 40 40 0.2 0.4 0.4 0.3)";
781 
782   Parser parser;
783   ASSERT_TRUE(parser.Parse(input).IsSuccess());
784 
785   auto engine = MakeEngine();
786   // ToStub(engine.get())->FailProbeCommand();
787   auto script = parser.GetScript();
788 
789   Options options;
790   Executor ex;
791   Result r =
792       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
793   ASSERT_FALSE(r.IsSuccess());
794   EXPECT_EQ("probe command failed", r.Error());
795 }
796 
TEST_F(VkScriptExecutorTest,BufferCommand)797 TEST_F(VkScriptExecutorTest, BufferCommand) {
798   std::string input = R"(
799 [test]
800 ssbo 0 24)";
801 
802   Parser parser;
803   parser.SkipValidationForTest();
804   ASSERT_TRUE(parser.Parse(input).IsSuccess());
805 
806   auto engine = MakeEngine();
807   auto script = parser.GetScript();
808 
809   Options options;
810   Executor ex;
811   Result r =
812       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
813   ASSERT_TRUE(r.IsSuccess());
814   ASSERT_TRUE(ToStub(engine.get())->DidBufferCommand());
815 }
816 
TEST_F(VkScriptExecutorTest,BufferCommandFailure)817 TEST_F(VkScriptExecutorTest, BufferCommandFailure) {
818   std::string input = R"(
819 [test]
820 ssbo 0 24)";
821 
822   Parser parser;
823   parser.SkipValidationForTest();
824   ASSERT_TRUE(parser.Parse(input).IsSuccess());
825 
826   auto engine = MakeEngine();
827   ToStub(engine.get())->FailBufferCommand();
828   auto script = parser.GetScript();
829 
830   Options options;
831   Executor ex;
832   Result r =
833       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
834   ASSERT_FALSE(r.IsSuccess());
835   EXPECT_EQ("buffer command failed", r.Error());
836 }
837 
TEST_F(VkScriptExecutorTest,DISABLED_ProbeSSBOCommand)838 TEST_F(VkScriptExecutorTest, DISABLED_ProbeSSBOCommand) {
839   std::string input = R"(
840 [test]
841 probe ssbo vec3 0 2 <= 2 3 4)";
842 
843   Parser parser;
844   ASSERT_TRUE(parser.Parse(input).IsSuccess());
845 
846   auto engine = MakeEngine();
847   auto script = parser.GetScript();
848 
849   Options options;
850   Executor ex;
851   Result r =
852       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
853   ASSERT_TRUE(r.IsSuccess());
854   // ASSERT_TRUE(ToStub(engine.get())->DidProbeSSBOCommand());
855 }
856 
TEST_F(VkScriptExecutorTest,DISABLED_ProbeSSBOCommandFailure)857 TEST_F(VkScriptExecutorTest, DISABLED_ProbeSSBOCommandFailure) {
858   std::string input = R"(
859 [test]
860 probe ssbo vec3 0 2 <= 2 3 4)";
861 
862   Parser parser;
863   ASSERT_TRUE(parser.Parse(input).IsSuccess());
864 
865   auto engine = MakeEngine();
866   // ToStub(engine.get())->FailProbeSSBOCommand();
867   auto script = parser.GetScript();
868 
869   Options options;
870   Executor ex;
871   Result r =
872       ex.Execute(engine.get(), script.get(), ShaderMap(), &options, nullptr);
873   ASSERT_FALSE(r.IsSuccess());
874   EXPECT_EQ("probe ssbo command failed", r.Error());
875 }
876 
877 }  // namespace vkscript
878 }  // namespace amber
879