diff options
author | dan sinclair <dj2@everburning.com> | 2018-12-11 15:11:15 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-11 15:11:15 -0500 |
commit | fb1ade89cc3b73c63c4295d3b2b6eddfd8972a6b (patch) | |
tree | bc87ed570dfa620420fffee9f4f70dcc4c17993b | |
parent | 4566ccba2cee294a043b272e728b5d2cdc08bba1 (diff) | |
download | amber-fb1ade89cc3b73c63c4295d3b2b6eddfd8972a6b.tar.gz |
Merge scripts and executors. (#170)
This CL merges the vk and amber Script classes along with the vk and
amber Executor classes.
28 files changed, 460 insertions, 854 deletions
@@ -5,10 +5,7 @@ LOCAL_MODULE:=amber LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti LOCAL_SRC_FILES:= \ src/amber.cc \ - src/amberscript/executor.cc \ src/amberscript/parser.cc \ - src/amberscript/pipeline.cc \ - src/amberscript/script.cc \ src/buffer.cc \ src/command.cc \ src/command_data.cc \ @@ -17,6 +14,7 @@ LOCAL_SRC_FILES:= \ src/executor.cc \ src/format.cc \ src/parser.cc \ + src/pipeline.cc \ src/pipeline_data.cc \ src/recipe.cc \ src/result.cc \ @@ -28,10 +26,8 @@ LOCAL_SRC_FILES:= \ src/verifier.cc \ src/vkscript/command_parser.cc \ src/vkscript/datum_type_parser.cc \ - src/vkscript/executor.cc \ src/vkscript/format_parser.cc \ src/vkscript/parser.cc \ - src/vkscript/script.cc \ src/vkscript/section_parser.cc LOCAL_STATIC_LIBRARIES:=glslang SPIRV-Tools shaderc LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 230c8db..67184d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,10 +14,7 @@ set(AMBER_SOURCES amber.cc - amberscript/executor.cc amberscript/parser.cc - amberscript/pipeline.cc - amberscript/script.cc buffer.cc command.cc command_data.cc @@ -26,6 +23,7 @@ set(AMBER_SOURCES executor.cc format.cc parser.cc + pipeline.cc pipeline_data.cc recipe.cc result.cc @@ -38,10 +36,8 @@ set(AMBER_SOURCES verifier.cc vkscript/command_parser.cc vkscript/datum_type_parser.cc - vkscript/executor.cc vkscript/format_parser.cc vkscript/parser.cc - vkscript/script.cc vkscript/section_parser.cc ) @@ -78,10 +74,10 @@ endif() if (${AMBER_ENABLE_TESTS}) set(TEST_SRCS amberscript/parser_test.cc - amberscript/pipeline_test.cc - amberscript/script_test.cc buffer_test.cc command_data_test.cc + executor_test.cc + pipeline_test.cc result_test.cc script_test.cc shader_compiler_test.cc @@ -89,7 +85,6 @@ if (${AMBER_ENABLE_TESTS}) verifier_test.cc vkscript/command_parser_test.cc vkscript/datum_type_parser_test.cc - vkscript/executor_test.cc vkscript/format_parser_test.cc vkscript/parser_test.cc vkscript/section_parser_test.cc diff --git a/src/amber.cc b/src/amber.cc index 5cb3309..65ef22d 100644 --- a/src/amber.cc +++ b/src/amber.cc @@ -17,13 +17,11 @@ #include <memory> #include <string> -#include "src/amberscript/executor.h" #include "src/amberscript/parser.h" #include "src/engine.h" #include "src/executor.h" #include "src/make_unique.h" #include "src/parser.h" -#include "src/vkscript/executor.h" #include "src/vkscript/parser.h" namespace amber { @@ -81,13 +79,8 @@ amber::Result Amber::ExecuteWithShaderData(const amber::Recipe* recipe, if (!r.IsSuccess()) return r; - std::unique_ptr<Executor> executor; - if (script->IsVkScript()) - executor = MakeUnique<vkscript::Executor>(); - else - executor = MakeUnique<amberscript::Executor>(); - - r = executor->Execute(engine.get(), script, shader_data); + Executor executor; + r = executor.Execute(engine.get(), script, shader_data); if (!r.IsSuccess()) return r; diff --git a/src/amberscript/executor.cc b/src/amberscript/executor.cc deleted file mode 100644 index 1c9954b..0000000 --- a/src/amberscript/executor.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/amberscript/executor.h" - -namespace amber { -namespace amberscript { - -Executor::Executor() : amber::Executor() {} - -Executor::~Executor() = default; - -Result Executor::Execute(Engine*, - const amber::Script* src_script, - const ShaderMap&) { - if (!src_script->IsAmberScript()) - return Result("AmberScript executor called with non-amber script source"); - - // const amberscript::Script* script = ToAmberScript(src_script); - - return {}; -} - -} // namespace amberscript -} // namespace amber diff --git a/src/amberscript/executor.h b/src/amberscript/executor.h deleted file mode 100644 index 71b6098..0000000 --- a/src/amberscript/executor.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_AMBERSCRIPT_EXECUTOR_H_ -#define SRC_AMBERSCRIPT_EXECUTOR_H_ - -#include "amber/result.h" -#include "src/engine.h" -#include "src/executor.h" -#include "src/script.h" - -namespace amber { -namespace amberscript { - -class Executor : public amber::Executor { - public: - Executor(); - ~Executor() override; - - Result Execute(Engine*, const amber::Script*, const ShaderMap&) override; -}; - -} // namespace amberscript -} // namespace amber - -#endif // SRC_AMBERSCRIPT_EXECUTOR_H_ diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index d45c52a..2e004cb 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -27,8 +27,7 @@ namespace amber { namespace amberscript { -Parser::Parser() - : amber::Parser(), script_(MakeUnique<amberscript::Script>()) {} +Parser::Parser() : amber::Parser(), script_(MakeUnique<Script>()) {} Parser::~Parser() = default; diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h index 7e4b764..7f0fc05 100644 --- a/src/amberscript/parser.h +++ b/src/amberscript/parser.h @@ -20,7 +20,6 @@ #include <utility> #include "amber/result.h" -#include "src/amberscript/script.h" #include "src/parser.h" #include "src/script.h" @@ -37,9 +36,7 @@ class Parser : public amber::Parser { // amber::Parser Result Parse(const std::string& data) override; - std::unique_ptr<amber::Script> GetScript() override { - return std::move(script_); - } + std::unique_ptr<Script> GetScript() override { return std::move(script_); } private: std::string make_error(const std::string& err); @@ -63,7 +60,7 @@ class Parser : public amber::Parser { Result ParsePipelineEntryPoint(Pipeline*); Result ParsePipelineShaderOptimizations(Pipeline*); - std::unique_ptr<amberscript::Script> script_; + std::unique_ptr<Script> script_; std::unique_ptr<Tokenizer> tokenizer_; }; diff --git a/src/amberscript/parser_test.cc b/src/amberscript/parser_test.cc index fd57a5d..03f3fe8 100644 --- a/src/amberscript/parser_test.cc +++ b/src/amberscript/parser_test.cc @@ -60,7 +60,7 @@ TEST_F(AmberScriptParserTest, EmptyInput) { ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); - ASSERT_TRUE(script->IsAmberScript()); + ASSERT_TRUE(script != nullptr); } TEST_F(AmberScriptParserTest, InvalidStartToken) { @@ -90,8 +90,7 @@ TEST_F(AmberScriptParserTest, ShaderPassThrough) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& shaders = script->GetShaders(); ASSERT_EQ(1U, shaders.size()); @@ -197,8 +196,7 @@ SHADER geometry shader_name GLSL Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& shaders = script->GetShaders(); ASSERT_EQ(1U, shaders.size()); @@ -312,8 +310,7 @@ void main() { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& shaders = script->GetShaders(); ASSERT_EQ(1U, shaders.size()); @@ -354,8 +351,7 @@ TEST_P(AmberScriptParserShaderFormatTest, ShaderFormats) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& shaders = script->GetShaders(); ASSERT_EQ(1U, shaders.size()); @@ -407,8 +403,7 @@ END Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); EXPECT_EQ(2U, script->GetShaders().size()); const auto& pipelines = script->GetPipelines(); @@ -672,8 +667,7 @@ END Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& pipelines = script->GetPipelines(); ASSERT_EQ(1U, pipelines.size()); @@ -819,8 +813,7 @@ END Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& pipelines = script->GetPipelines(); ASSERT_EQ(1U, pipelines.size()); @@ -949,8 +942,7 @@ END)"; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -980,8 +972,7 @@ TEST_F(AmberScriptParserTest, BufferFill) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1010,8 +1001,7 @@ TEST_F(AmberScriptParserTest, BufferFillFloat) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1041,8 +1031,7 @@ TEST_F(AmberScriptParserTest, BufferSeries) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1073,8 +1062,7 @@ TEST_F(AmberScriptParserTest, BufferSeriesFloat) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1103,8 +1091,7 @@ TEST_F(AmberScriptParserTest, BufferFramebuffer) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1131,8 +1118,7 @@ END)"; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(2U, buffers.size()); @@ -1179,8 +1165,7 @@ BUFFER index my_index_buffer DATA_TYPE vec2<int32> SIZE 5 FILL 2)"; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1216,8 +1201,7 @@ END Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1253,8 +1237,7 @@ END Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1633,8 +1616,7 @@ TEST_P(AmberScriptParserBufferTypeTest, BufferTypes) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); @@ -1665,8 +1647,7 @@ TEST_P(AmberScriptParserBufferDataTypeTest, BufferTypes) { Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << test_data.name << " :" << r.Error(); - auto parent_script = parser.GetScript(); - auto script = ToAmberScript(parent_script.get()); + auto script = parser.GetScript(); const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); diff --git a/src/amberscript/script.cc b/src/amberscript/script.cc deleted file mode 100644 index 17bfedc..0000000 --- a/src/amberscript/script.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/amberscript/script.h" - -namespace amber { -namespace amberscript { - -Script::Script() : amber::Script(ScriptType::kAmberScript) {} - -Script::~Script() = default; - -} // namespace amberscript - -const amberscript::Script* ToAmberScript(const amber::Script* s) { - return static_cast<const amberscript::Script*>(s); -} - -} // namespace amber diff --git a/src/amberscript/script.h b/src/amberscript/script.h deleted file mode 100644 index 81d0258..0000000 --- a/src/amberscript/script.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_AMBERSCRIPT_SCRIPT_H_ -#define SRC_AMBERSCRIPT_SCRIPT_H_ - -#include <map> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "src/amberscript/pipeline.h" -#include "src/buffer.h" -#include "src/script.h" - -namespace amber { -namespace amberscript { - -class Script : public amber::Script { - public: - Script(); - ~Script() override; - - Result AddPipeline(std::unique_ptr<Pipeline> pipeline) { - if (name_to_pipeline_.count(pipeline->GetName()) > 0) - return Result("duplicate pipeline name provided"); - - pipelines_.push_back(std::move(pipeline)); - name_to_pipeline_[pipelines_.back()->GetName()] = pipelines_.back().get(); - return {}; - } - - Pipeline* GetPipeline(const std::string& name) const { - auto it = name_to_pipeline_.find(name); - return it == name_to_pipeline_.end() ? nullptr : it->second; - } - - const std::vector<std::unique_ptr<Pipeline>>& GetPipelines() const { - return pipelines_; - } - - Result AddBuffer(std::unique_ptr<Buffer> buffer) { - if (name_to_buffer_.count(buffer->GetName()) > 0) - return Result("duplicate buffer name provided"); - - buffers_.push_back(std::move(buffer)); - name_to_buffer_[buffers_.back()->GetName()] = buffers_.back().get(); - return {}; - } - - Buffer* GetBuffer(const std::string& name) const { - auto it = name_to_buffer_.find(name); - return it == name_to_buffer_.end() ? nullptr : it->second; - } - - const std::vector<std::unique_ptr<Buffer>>& GetBuffers() const { - return buffers_; - } - - private: - std::map<std::string, Pipeline*> name_to_pipeline_; - std::map<std::string, Buffer*> name_to_buffer_; - std::vector<std::unique_ptr<Pipeline>> pipelines_; - std::vector<std::unique_ptr<Buffer>> buffers_; -}; - -} // namespace amberscript - -const amberscript::Script* ToAmberScript(const amber::Script* s); - -} // namespace amber - -#endif // SRC_AMBERSCRIPT_SCRIPT_H_ diff --git a/src/amberscript/script_test.cc b/src/amberscript/script_test.cc deleted file mode 100644 index 2a2bd5e..0000000 --- a/src/amberscript/script_test.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <utility> - -#include "gtest/gtest.h" -#include "src/amberscript/pipeline.h" -#include "src/amberscript/script.h" -#include "src/buffer.h" -#include "src/make_unique.h" -#include "src/shader.h" - -namespace amber { -namespace amberscript { - -using ScriptTest = testing::Test; - -TEST_F(ScriptTest, AddShader) { - auto shader = MakeUnique<Shader>(ShaderType::kVertex); - shader->SetName("My Shader"); - - Script s; - Result r = s.AddShader(std::move(shader)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); -} - -TEST_F(ScriptTest, AddDuplicateShader) { - auto shader1 = MakeUnique<Shader>(ShaderType::kVertex); - shader1->SetName("My Shader"); - - Script s; - Result r = s.AddShader(std::move(shader1)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - auto shader2 = MakeUnique<Shader>(ShaderType::kFragment); - shader2->SetName("My Shader"); - - r = s.AddShader(std::move(shader2)); - ASSERT_FALSE(r.IsSuccess()); - EXPECT_EQ("duplicate shader name provided", r.Error()); -} - -TEST_F(ScriptTest, GetShader) { - auto shader = MakeUnique<Shader>(ShaderType::kVertex); - shader->SetName("My Shader"); - - auto* ptr = shader.get(); - - Script s; - Result r = s.AddShader(std::move(shader)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - EXPECT_EQ(ptr, s.GetShader("My Shader")); -} - -TEST_F(ScriptTest, GetMissingShader) { - Script s; - EXPECT_TRUE(s.GetShader("My Shader") == nullptr); -} - -TEST_F(ScriptTest, GetShadersEmpty) { - Script s; - const auto& shaders = s.GetShaders(); - EXPECT_TRUE(shaders.empty()); -} - -TEST_F(ScriptTest, GetShaders) { - auto shader1 = MakeUnique<Shader>(ShaderType::kVertex); - shader1->SetName("My Shader"); - - const auto* ptr1 = shader1.get(); - - Script s; - Result r = s.AddShader(std::move(shader1)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - auto shader2 = MakeUnique<Shader>(ShaderType::kFragment); - shader2->SetName("My Fragment"); - - const auto* ptr2 = shader2.get(); - - r = s.AddShader(std::move(shader2)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - const auto& shaders = s.GetShaders(); - ASSERT_EQ(2U, shaders.size()); - EXPECT_EQ(ptr1, shaders[0].get()); - EXPECT_EQ(ptr2, shaders[1].get()); -} - -TEST_F(ScriptTest, AddPipeline) { - auto pipeline = MakeUnique<Pipeline>(PipelineType::kCompute); - pipeline->SetName("my_pipeline"); - - Script s; - Result r = s.AddPipeline(std::move(pipeline)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); -} - -TEST_F(ScriptTest, AddDuplicatePipeline) { - auto pipeline1 = MakeUnique<Pipeline>(PipelineType::kCompute); - pipeline1->SetName("my_pipeline"); - - Script s; - Result r = s.AddPipeline(std::move(pipeline1)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - auto pipeline2 = MakeUnique<Pipeline>(PipelineType::kGraphics); - pipeline2->SetName("my_pipeline"); - r = s.AddPipeline(std::move(pipeline2)); - ASSERT_FALSE(r.IsSuccess()); - EXPECT_EQ("duplicate pipeline name provided", r.Error()); -} - -TEST_F(ScriptTest, GetPipeline) { - auto pipeline = MakeUnique<Pipeline>(PipelineType::kCompute); - pipeline->SetName("my_pipeline"); - - const auto* ptr = pipeline.get(); - - Script s; - Result r = s.AddPipeline(std::move(pipeline)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - EXPECT_EQ(ptr, s.GetPipeline("my_pipeline")); -} - -TEST_F(ScriptTest, GetMissingPipeline) { - Script s; - EXPECT_TRUE(s.GetPipeline("my_pipeline") == nullptr); -} - -TEST_F(ScriptTest, GetPipelinesEmpty) { - Script s; - const auto& pipelines = s.GetPipelines(); - EXPECT_TRUE(pipelines.empty()); -} - -TEST_F(ScriptTest, GetPipelines) { - auto pipeline1 = MakeUnique<Pipeline>(PipelineType::kCompute); - pipeline1->SetName("my_pipeline1"); - - const auto* ptr1 = pipeline1.get(); - - Script s; - Result r = s.AddPipeline(std::move(pipeline1)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - auto pipeline2 = MakeUnique<Pipeline>(PipelineType::kGraphics); - pipeline2->SetName("my_pipeline2"); - - const auto* ptr2 = pipeline2.get(); - - r = s.AddPipeline(std::move(pipeline2)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - const auto& pipelines = s.GetPipelines(); - ASSERT_EQ(2U, pipelines.size()); - EXPECT_EQ(ptr1, pipelines[0].get()); - EXPECT_EQ(ptr2, pipelines[1].get()); -} - -TEST_F(ScriptTest, AddDataBuffer) { - auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); - buffer->SetName("my_buffer"); - - Script s; - Result r = s.AddBuffer(std::move(buffer)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); -} - -TEST_F(ScriptTest, AddDuplicateDataBuffer) { - auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); - buffer1->SetName("my_buffer"); - - Script s; - Result r = s.AddBuffer(std::move(buffer1)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); - buffer2->SetName("my_buffer"); - - r = s.AddBuffer(std::move(buffer2)); - ASSERT_FALSE(r.IsSuccess()); - EXPECT_EQ("duplicate buffer name provided", r.Error()); -} - -TEST_F(ScriptTest, GetDataBuffer) { - auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); - buffer->SetName("my_buffer"); - - const auto* ptr = buffer.get(); - - Script s; - Result r = s.AddBuffer(std::move(buffer)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - EXPECT_EQ(ptr, s.GetBuffer("my_buffer")); -} - -TEST_F(ScriptTest, GetMissingBuffer) { - Script s; - EXPECT_TRUE(s.GetBuffer("my_buffer") == nullptr); -} - -TEST_F(ScriptTest, GetBuffersEmpty) { - Script s; - const auto& buffers = s.GetBuffers(); - EXPECT_TRUE(buffers.empty()); -} - -TEST_F(ScriptTest, GetBuffers) { - auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); - buffer1->SetName("my_buffer1"); - - const auto* ptr1 = buffer1.get(); - - Script s; - Result r = s.AddBuffer(std::move(buffer1)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); - buffer2->SetName("my_buffer2"); - - const auto* ptr2 = buffer2.get(); - - r = s.AddBuffer(std::move(buffer2)); - ASSERT_TRUE(r.IsSuccess()) << r.Error(); - - const auto& buffers = s.GetBuffers(); - ASSERT_EQ(2U, buffers.size()); - EXPECT_EQ(ptr1, buffers[0].get()); - EXPECT_EQ(ptr2, buffers[1].get()); -} - -} // namespace amberscript -} // namespace amber diff --git a/src/engine.h b/src/engine.h index 4ee149f..b45ed36 100644 --- a/src/engine.h +++ b/src/engine.h @@ -25,14 +25,10 @@ #include "src/command.h" #include "src/feature.h" #include "src/format.h" +#include "src/pipeline.h" namespace amber { -enum class PipelineType : uint8_t { - kCompute = 0, - kGraphics, -}; - enum class ResourceInfoType : uint8_t { kBuffer = 0, kImage, diff --git a/src/executor.cc b/src/executor.cc index 249a89f..c6f8eae 100644 --- a/src/executor.cc +++ b/src/executor.cc @@ -14,10 +14,144 @@ #include "src/executor.h" +#include <cassert> +#include <vector> + +#include "src/engine.h" +#include "src/script.h" +#include "src/shader_compiler.h" + namespace amber { Executor::Executor() = default; Executor::~Executor() = default; +Result Executor::Execute(Engine* engine, + const amber::Script* script, + const ShaderMap& shader_map) { + engine->SetEngineData(script->GetEngineData()); + + // Process Shader nodes + PipelineType pipeline_type = PipelineType::kGraphics; + for (const auto& shader : script->GetShaders()) { + ShaderCompiler sc; + + Result r; + std::vector<uint32_t> data; + std::tie(r, data) = sc.Compile(shader.get(), shader_map); + if (!r.IsSuccess()) + return r; + + r = engine->SetShader(shader->GetType(), data); + if (!r.IsSuccess()) + return r; + + if (shader->GetType() == ShaderType::kCompute) + pipeline_type = PipelineType::kCompute; + } + + // Handle Image and Depth buffers early so they are available when we call + // the CreatePipeline method. + for (const auto& buf : script->GetBuffers()) { + // Image and depth are handled earler. They will be moved to the pipeline + // object when it exists. + if (buf->GetBufferType() != BufferType::kColor && + buf->GetBufferType() != BufferType::kDepth) { + continue; + } + + Result r = engine->SetBuffer( + buf->GetBufferType(), buf->GetLocation(), + buf->IsFormatBuffer() ? buf->AsFormatBuffer()->GetFormat() : Format(), + buf->GetData()); + if (!r.IsSuccess()) + return r; + } + + // TODO(jaebaek): Support multiple pipelines. + Result r = engine->CreatePipeline(pipeline_type); + if (!r.IsSuccess()) + return r; + + // Process Buffers + for (const auto& buf : script->GetBuffers()) { + // Image and depth are handled earler. They will be moved to the pipeline + // object when it exists. + if (buf->GetBufferType() == BufferType::kColor || + buf->GetBufferType() == BufferType::kDepth) { + continue; + } + + r = engine->SetBuffer( + buf->GetBufferType(), buf->GetLocation(), + buf->IsFormatBuffer() ? buf->AsFormatBuffer()->GetFormat() : Format(), + buf->GetData()); + if (!r.IsSuccess()) + return r; + } + + // Process Commands + for (const auto& cmd : script->GetCommands()) { + if (cmd->IsProbe()) { + ResourceInfo info; + + r = engine->DoProcessCommands(); + if (!r.IsSuccess()) + return r; + + // This must come after processing commands because we require + // the frambuffer buffer to be mapped into host memory and have + // a valid host-side pointer. + r = engine->GetFrameBufferInfo(&info); + if (!r.IsSuccess()) + return r; + assert(info.cpu_memory != nullptr); + + r = verifier_.Probe(cmd->AsProbe(), info.image_info.texel_stride, + info.image_info.row_stride, info.image_info.width, + info.image_info.height, info.cpu_memory); + } else if (cmd->IsProbeSSBO()) { + auto probe_ssbo = cmd->AsProbeSSBO(); + ResourceInfo info; + r = engine->GetDescriptorInfo(probe_ssbo->GetDescriptorSet(), + probe_ssbo->GetBinding(), &info); + if (!r.IsSuccess()) + return r; + + r = engine->DoProcessCommands(); + if (!r.IsSuccess()) + return r; + + r = verifier_.ProbeSSBO(probe_ssbo, info.size_in_bytes, info.cpu_memory); + } else if (cmd->IsClear()) { + r = engine->DoClear(cmd->AsClear()); + } else if (cmd->IsClearColor()) { + r = engine->DoClearColor(cmd->AsClearColor()); + } else if (cmd->IsClearDepth()) { + r = engine->DoClearDepth(cmd->AsClearDepth()); + } else if (cmd->IsClearStencil()) { + r = engine->DoClearStencil(cmd->AsClearStencil()); + } else if (cmd->IsDrawRect()) { + r = engine->DoDrawRect(cmd->AsDrawRect()); + } else if (cmd->IsDrawArrays()) { + r = engine->DoDrawArrays(cmd->AsDrawArrays()); + } else if (cmd->IsCompute()) { + r = engine->DoCompute(cmd->AsCompute()); + } else if (cmd->IsEntryPoint()) { + r = engine->DoEntryPoint(cmd->AsEntryPoint()); + } else if (cmd->IsPatchParameterVertices()) { + r = engine->DoPatchParameterVertices(cmd->AsPatchParameterVertices()); + } else if (cmd->IsBuffer()) { + r = engine->DoBuffer(cmd->AsBuffer()); + } else { + return Result("Unknown command type"); + } + + if (!r.IsSuccess()) + return r; + } + return {}; +} + } // namespace amber diff --git a/src/executor.h b/src/executor.h index b2ba7e5..1144b89 100644 --- a/src/executor.h +++ b/src/executor.h @@ -18,17 +18,19 @@ #include "amber/result.h" #include "src/engine.h" #include "src/script.h" +#include "src/verifier.h" namespace amber { class Executor { public: - virtual ~Executor(); + Executor(); + ~Executor(); - virtual Result Execute(Engine*, const Script*, const ShaderMap&) = 0; + Result Execute(Engine*, const Script*, const ShaderMap&); - protected: - Executor(); + private: + Verifier verifier_; }; } // namespace amber diff --git a/src/vkscript/executor_test.cc b/src/executor_test.cc index 8d51772..5f8cbf7 100644 --- a/src/vkscript/executor_test.cc +++ b/src/executor_test.cc @@ -19,8 +19,8 @@ #include "gtest/gtest.h" #include "src/engine.h" +#include "src/executor.h" #include "src/make_unique.h" -#include "src/vkscript/executor.h" #include "src/vkscript/parser.h" namespace amber { @@ -282,7 +282,7 @@ logicOp)"; script->RequiredExtensions()); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); const auto& features = ToStub(engine.get())->GetFeatures(); @@ -315,7 +315,7 @@ VK_KHR_variable_pointers)"; script->RequiredExtensions()); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); const auto& features = ToStub(engine.get())->GetFeatures(); @@ -348,7 +348,7 @@ depthstencil D24_UNORM_S8_UINT)"; script->RequiredExtensions()); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); const auto& features = ToStub(engine.get())->GetFeatures(); @@ -378,7 +378,7 @@ fence_timeout 12345)"; script->RequiredExtensions()); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); const auto& features = ToStub(engine.get())->GetFeatures(); @@ -414,7 +414,7 @@ fence_timeout 12345)"; script->RequiredExtensions()); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); const auto& features = ToStub(engine.get())->GetFeatures(); @@ -452,7 +452,7 @@ void main() {} auto script = parser.GetScript(); Executor ex; - r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); auto shader_types = ToStub(engine.get())->GetShaderTypesSeen(); @@ -477,7 +477,7 @@ void main() {} auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("shader command failed", r.Error()); } @@ -495,7 +495,7 @@ clear)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); EXPECT_TRUE(ToStub(engine.get())->DidClearCommand()); } @@ -513,7 +513,7 @@ clear)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("clear command failed", r.Error()); } @@ -530,7 +530,7 @@ clear color 244 123 123 13)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidClearColorCommand()); @@ -557,7 +557,7 @@ clear color 123 123 123 123)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("clear color command failed", r.Error()); } @@ -574,7 +574,7 @@ clear depth 24)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidClearDepthCommand()); } @@ -592,7 +592,7 @@ clear depth 24)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("clear depth command failed", r.Error()); } @@ -609,7 +609,7 @@ clear stencil 24)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidClearStencilCommand()); } @@ -627,7 +627,7 @@ clear stencil 24)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("clear stencil command failed", r.Error()); } @@ -644,7 +644,7 @@ draw rect 2 4 10 20)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidDrawRectCommand()); } @@ -662,7 +662,7 @@ draw rect 2 4 10 20)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("draw rect command failed", r.Error()); } @@ -679,7 +679,7 @@ draw arrays TRIANGLE_LIST 0 0)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidDrawArraysCommand()); } @@ -697,7 +697,7 @@ draw arrays TRIANGLE_LIST 0 0)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("draw arrays command failed", r.Error()); } @@ -714,7 +714,7 @@ compute 2 3 4)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidComputeCommand()); } @@ -732,7 +732,7 @@ compute 2 3 4)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("compute command failed", r.Error()); } @@ -749,7 +749,7 @@ vertex entrypoint main)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidEntryPointCommand()); } @@ -767,7 +767,7 @@ vertex entrypoint main)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("entrypoint command failed", r.Error()); } @@ -784,7 +784,7 @@ patch parameter vertices 10)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidPatchParameterVerticesCommand()); } @@ -802,7 +802,7 @@ patch parameter vertices 10)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("patch command failed", r.Error()); } @@ -819,7 +819,7 @@ probe rect rgba 2 3 40 40 0.2 0.4 0.4 0.3)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); // ASSERT_TRUE(ToStub(engine.get())->DidProbeCommand()); } @@ -837,7 +837,7 @@ probe rect rgba 2 3 40 40 0.2 0.4 0.4 0.3)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("probe command failed", r.Error()); } @@ -854,7 +854,7 @@ ssbo 0 24)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); ASSERT_TRUE(ToStub(engine.get())->DidBufferCommand()); } @@ -872,7 +872,7 @@ ssbo 0 24)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("buffer command failed", r.Error()); } @@ -889,7 +889,7 @@ probe ssbo vec3 0 2 <= 2 3 4)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); // ASSERT_TRUE(ToStub(engine.get())->DidProbeSSBOCommand()); } @@ -907,7 +907,7 @@ probe ssbo vec3 0 2 <= 2 3 4)"; auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_FALSE(r.IsSuccess()); EXPECT_EQ("probe ssbo command failed", r.Error()); } @@ -926,7 +926,7 @@ TEST_F(VkScriptExecutorTest, VertexData) { auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); auto stub = ToStub(engine.get()); @@ -971,7 +971,7 @@ TEST_F(VkScriptExecutorTest, IndexBuffer) { auto script = parser.GetScript(); Executor ex; - Result r = ex.Execute(engine.get(), ToVkScript(script.get()), ShaderMap()); + Result r = ex.Execute(engine.get(), script.get(), ShaderMap()); ASSERT_TRUE(r.IsSuccess()); auto stub = ToStub(engine.get()); diff --git a/src/amberscript/pipeline.cc b/src/pipeline.cc index 94f498b..fa94dd5 100644 --- a/src/amberscript/pipeline.cc +++ b/src/pipeline.cc @@ -12,13 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/amberscript/pipeline.h" +#include "src/pipeline.h" #include <algorithm> #include <set> namespace amber { -namespace amberscript { Pipeline::ShaderInfo::ShaderInfo(const Shader* shader) : shader_(shader), entry_point_("main") {} @@ -140,5 +139,4 @@ Result Pipeline::ValidateCompute() const { return {}; } -} // namespace amberscript } // namespace amber diff --git a/src/amberscript/pipeline.h b/src/pipeline.h index ba7bdb1..881ecc6 100644 --- a/src/amberscript/pipeline.h +++ b/src/pipeline.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef SRC_AMBERSCRIPT_PIPELINE_H_ -#define SRC_AMBERSCRIPT_PIPELINE_H_ +#ifndef SRC_PIPELINE_H_ +#define SRC_PIPELINE_H_ #include <string> #include <vector> @@ -22,7 +22,6 @@ #include "src/shader.h" namespace amber { -namespace amberscript { enum class PipelineType { kCompute = 0, kGraphics }; @@ -79,7 +78,6 @@ class Pipeline { std::vector<ShaderInfo> shaders_; }; -} // namespace amberscript } // namespace amber -#endif // SRC_AMBERSCRIPT_PIPELINE_H_ +#endif // SRC_PIPELINE_H_ diff --git a/src/amberscript/pipeline_test.cc b/src/pipeline_test.cc index b0866f1..3902baf 100644 --- a/src/amberscript/pipeline_test.cc +++ b/src/pipeline_test.cc @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/amberscript/pipeline.h" +#include "src/pipeline.h" #include "gtest/gtest.h" namespace amber { -namespace amberscript { namespace { struct ShaderTypeData { @@ -329,5 +328,4 @@ TEST_F(AmberScriptPipelineTest, SetEntryPointMulitpleTimes) { EXPECT_EQ("multiple entry points given for the same shader", r.Error()); } -} // namespace amberscript } // namespace amber diff --git a/src/script.cc b/src/script.cc index 3685cfc..978df32 100644 --- a/src/script.cc +++ b/src/script.cc @@ -16,7 +16,7 @@ namespace amber { -Script::Script(ScriptType type) : script_type_(type) {} +Script::Script() = default; Script::~Script() = default; diff --git a/src/script.h b/src/script.h index 024ca9c..1ebab3a 100644 --- a/src/script.h +++ b/src/script.h @@ -28,22 +28,35 @@ #include "src/command.h" #include "src/engine.h" #include "src/feature.h" +#include "src/pipeline.h" #include "src/shader.h" namespace amber { -enum class ScriptType : uint8_t { kVkScript = 0, kAmberScript }; - class Script : public RecipeImpl { public: + Script(); ~Script() override; - bool IsVkScript() const { return script_type_ == ScriptType::kVkScript; } - bool IsAmberScript() const { - return script_type_ == ScriptType::kAmberScript; + std::vector<ShaderInfo> GetShaderInfo() const override; + + Result AddPipeline(std::unique_ptr<Pipeline> pipeline) { + if (name_to_pipeline_.count(pipeline->GetName()) > 0) + return Result("duplicate pipeline name provided"); + + pipelines_.push_back(std::move(pipeline)); + name_to_pipeline_[pipelines_.back()->GetName()] = pipelines_.back().get(); + return {}; } - std::vector<ShaderInfo> GetShaderInfo() const override; + Pipeline* GetPipeline(const std::string& name) const { + auto it = name_to_pipeline_.find(name); + return it == name_to_pipeline_.end() ? nullptr : it->second; + } + + const std::vector<std::unique_ptr<Pipeline>>& GetPipelines() const { + return pipelines_; + } Result AddShader(std::unique_ptr<Shader> shader) { if (name_to_shader_.count(shader->GetName()) > 0) @@ -72,6 +85,11 @@ class Script : public RecipeImpl { return {}; } + Buffer* GetBuffer(const std::string& name) const { + auto it = name_to_buffer_.find(name); + return it == name_to_buffer_.end() ? nullptr : it->second; + } + const std::vector<std::unique_ptr<Buffer>>& GetBuffers() const { return buffers_; } @@ -100,22 +118,20 @@ class Script : public RecipeImpl { return commands_; } - protected: - explicit Script(ScriptType); - private: struct { std::vector<Feature> required_features; std::vector<std::string> required_extensions; } engine_info_; - ScriptType script_type_; EngineData engine_data_; std::map<std::string, Shader*> name_to_shader_; std::map<std::string, Buffer*> name_to_buffer_; + std::map<std::string, Pipeline*> name_to_pipeline_; std::vector<std::unique_ptr<Shader>> shaders_; std::vector<std::unique_ptr<Command>> commands_; std::vector<std::unique_ptr<Buffer>> buffers_; + std::vector<std::unique_ptr<Pipeline>> pipelines_; }; } // namespace amber diff --git a/src/script_test.cc b/src/script_test.cc index 41f611f..4bc9e75 100644 --- a/src/script_test.cc +++ b/src/script_test.cc @@ -25,7 +25,7 @@ namespace { class ScriptProxy : public Script { public: - ScriptProxy() : Script(ScriptType::kVkScript) {} + ScriptProxy() = default; ~ScriptProxy() override = default; }; @@ -70,4 +70,222 @@ TEST_F(ScriptTest, GetShaderInfoNoShaders) { EXPECT_TRUE(info.empty()); } +TEST_F(ScriptTest, AddShader) { + auto shader = MakeUnique<Shader>(ShaderType::kVertex); + shader->SetName("My Shader"); + + Script s; + Result r = s.AddShader(std::move(shader)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); +} + +TEST_F(ScriptTest, AddDuplicateShader) { + auto shader1 = MakeUnique<Shader>(ShaderType::kVertex); + shader1->SetName("My Shader"); + + Script s; + Result r = s.AddShader(std::move(shader1)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto shader2 = MakeUnique<Shader>(ShaderType::kFragment); + shader2->SetName("My Shader"); + + r = s.AddShader(std::move(shader2)); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("duplicate shader name provided", r.Error()); +} + +TEST_F(ScriptTest, GetShader) { + auto shader = MakeUnique<Shader>(ShaderType::kVertex); + shader->SetName("My Shader"); + + auto* ptr = shader.get(); + + Script s; + Result r = s.AddShader(std::move(shader)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + EXPECT_EQ(ptr, s.GetShader("My Shader")); +} + +TEST_F(ScriptTest, GetMissingShader) { + Script s; + EXPECT_TRUE(s.GetShader("My Shader") == nullptr); +} + +TEST_F(ScriptTest, GetShadersEmpty) { + Script s; + const auto& shaders = s.GetShaders(); + EXPECT_TRUE(shaders.empty()); +} + +TEST_F(ScriptTest, GetShaders) { + auto shader1 = MakeUnique<Shader>(ShaderType::kVertex); + shader1->SetName("My Shader"); + + const auto* ptr1 = shader1.get(); + + Script s; + Result r = s.AddShader(std::move(shader1)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto shader2 = MakeUnique<Shader>(ShaderType::kFragment); + shader2->SetName("My Fragment"); + + const auto* ptr2 = shader2.get(); + + r = s.AddShader(std::move(shader2)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + const auto& shaders = s.GetShaders(); + ASSERT_EQ(2U, shaders.size()); + EXPECT_EQ(ptr1, shaders[0].get()); + EXPECT_EQ(ptr2, shaders[1].get()); +} + +TEST_F(ScriptTest, AddPipeline) { + auto pipeline = MakeUnique<Pipeline>(PipelineType::kCompute); + pipeline->SetName("my_pipeline"); + + Script s; + Result r = s.AddPipeline(std::move(pipeline)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); +} + +TEST_F(ScriptTest, AddDuplicatePipeline) { + auto pipeline1 = MakeUnique<Pipeline>(PipelineType::kCompute); + pipeline1->SetName("my_pipeline"); + + Script s; + Result r = s.AddPipeline(std::move(pipeline1)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto pipeline2 = MakeUnique<Pipeline>(PipelineType::kGraphics); + pipeline2->SetName("my_pipeline"); + r = s.AddPipeline(std::move(pipeline2)); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("duplicate pipeline name provided", r.Error()); +} + +TEST_F(ScriptTest, GetPipeline) { + auto pipeline = MakeUnique<Pipeline>(PipelineType::kCompute); + pipeline->SetName("my_pipeline"); + + const auto* ptr = pipeline.get(); + + Script s; + Result r = s.AddPipeline(std::move(pipeline)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + EXPECT_EQ(ptr, s.GetPipeline("my_pipeline")); +} + +TEST_F(ScriptTest, GetMissingPipeline) { + Script s; + EXPECT_TRUE(s.GetPipeline("my_pipeline") == nullptr); +} + +TEST_F(ScriptTest, GetPipelinesEmpty) { + Script s; + const auto& pipelines = s.GetPipelines(); + EXPECT_TRUE(pipelines.empty()); +} + +TEST_F(ScriptTest, GetPipelines) { + auto pipeline1 = MakeUnique<Pipeline>(PipelineType::kCompute); + pipeline1->SetName("my_pipeline1"); + + const auto* ptr1 = pipeline1.get(); + + Script s; + Result r = s.AddPipeline(std::move(pipeline1)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto pipeline2 = MakeUnique<Pipeline>(PipelineType::kGraphics); + pipeline2->SetName("my_pipeline2"); + + const auto* ptr2 = pipeline2.get(); + + r = s.AddPipeline(std::move(pipeline2)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + const auto& pipelines = s.GetPipelines(); + ASSERT_EQ(2U, pipelines.size()); + EXPECT_EQ(ptr1, pipelines[0].get()); + EXPECT_EQ(ptr2, pipelines[1].get()); +} + +TEST_F(ScriptTest, AddDataBuffer) { + auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); + buffer->SetName("my_buffer"); + + Script s; + Result r = s.AddBuffer(std::move(buffer)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); +} + +TEST_F(ScriptTest, AddDuplicateDataBuffer) { + auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); + buffer1->SetName("my_buffer"); + + Script s; + Result r = s.AddBuffer(std::move(buffer1)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); + buffer2->SetName("my_buffer"); + + r = s.AddBuffer(std::move(buffer2)); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("duplicate buffer name provided", r.Error()); +} + +TEST_F(ScriptTest, GetDataBuffer) { + auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); + buffer->SetName("my_buffer"); + + const auto* ptr = buffer.get(); + + Script s; + Result r = s.AddBuffer(std::move(buffer)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + EXPECT_EQ(ptr, s.GetBuffer("my_buffer")); +} + +TEST_F(ScriptTest, GetMissingBuffer) { + Script s; + EXPECT_TRUE(s.GetBuffer("my_buffer") == nullptr); +} + +TEST_F(ScriptTest, GetBuffersEmpty) { + Script s; + const auto& buffers = s.GetBuffers(); + EXPECT_TRUE(buffers.empty()); +} + +TEST_F(ScriptTest, GetBuffers) { + auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); + buffer1->SetName("my_buffer1"); + + const auto* ptr1 = buffer1.get(); + + Script s; + Result r = s.AddBuffer(std::move(buffer1)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); + buffer2->SetName("my_buffer2"); + + const auto* ptr2 = buffer2.get(); + + r = s.AddBuffer(std::move(buffer2)); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + const auto& buffers = s.GetBuffers(); + ASSERT_EQ(2U, buffers.size()); + EXPECT_EQ(ptr1, buffers[0].get()); + EXPECT_EQ(ptr2, buffers[1].get()); +} + } // namespace amber diff --git a/src/vkscript/executor.cc b/src/vkscript/executor.cc deleted file mode 100644 index 1bed156..0000000 --- a/src/vkscript/executor.cc +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/vkscript/executor.h" - -#include <cassert> -#include <vector> - -#include "src/engine.h" -#include "src/shader_compiler.h" -#include "src/vkscript/script.h" - -namespace amber { -namespace vkscript { - -Executor::Executor() : amber::Executor() {} - -Executor::~Executor() = default; - -Result Executor::Execute(Engine* engine, - const amber::Script* script, - const ShaderMap& shader_map) { - if (!script->IsVkScript()) - return Result("VkScript Executor called with non-vkscript source"); - - engine->SetEngineData(script->GetEngineData()); - - // Process Shader nodes - PipelineType pipeline_type = PipelineType::kGraphics; - for (const auto& shader : script->GetShaders()) { - ShaderCompiler sc; - - Result r; - std::vector<uint32_t> data; - std::tie(r, data) = sc.Compile(shader.get(), shader_map); - if (!r.IsSuccess()) - return r; - - r = engine->SetShader(shader->GetType(), data); - if (!r.IsSuccess()) - return r; - - if (shader->GetType() == ShaderType::kCompute) - pipeline_type = PipelineType::kCompute; - } - - // Handle Image and Depth buffers early so they are available when we call - // the CreatePipeline method. - for (const auto& buf : script->GetBuffers()) { - // Image and depth are handled earler. They will be moved to the pipeline - // object when it exists. - if (buf->GetBufferType() != BufferType::kColor && - buf->GetBufferType() != BufferType::kDepth) { - continue; - } - - Result r = engine->SetBuffer( - buf->GetBufferType(), buf->GetLocation(), - buf->IsFormatBuffer() ? buf->AsFormatBuffer()->GetFormat() : Format(), - buf->GetData()); - if (!r.IsSuccess()) - return r; - } - - // TODO(jaebaek): Support multiple pipelines. - Result r = engine->CreatePipeline(pipeline_type); - if (!r.IsSuccess()) - return r; - - // Process Buffers - for (const auto& buf : script->GetBuffers()) { - // Image and depth are handled earler. They will be moved to the pipeline - // object when it exists. - if (buf->GetBufferType() == BufferType::kColor || - buf->GetBufferType() == BufferType::kDepth) { - continue; - } - - r = engine->SetBuffer( - buf->GetBufferType(), buf->GetLocation(), - buf->IsFormatBuffer() ? buf->AsFormatBuffer()->GetFormat() : Format(), - buf->GetData()); - if (!r.IsSuccess()) - return r; - } - - // Process Commands - for (const auto& cmd : script->GetCommands()) { - if (cmd->IsProbe()) { - ResourceInfo info; - - r = engine->DoProcessCommands(); - if (!r.IsSuccess()) - return r; - - // This must come after processing commands because we require - // the frambuffer buffer to be mapped into host memory and have - // a valid host-side pointer. - r = engine->GetFrameBufferInfo(&info); - if (!r.IsSuccess()) - return r; - assert(info.cpu_memory != nullptr); - - r = verifier_.Probe(cmd->AsProbe(), info.image_info.texel_stride, - info.image_info.row_stride, info.image_info.width, - info.image_info.height, info.cpu_memory); - } else if (cmd->IsProbeSSBO()) { - auto probe_ssbo = cmd->AsProbeSSBO(); - ResourceInfo info; - r = engine->GetDescriptorInfo(probe_ssbo->GetDescriptorSet(), - probe_ssbo->GetBinding(), &info); - if (!r.IsSuccess()) - return r; - - r = engine->DoProcessCommands(); - if (!r.IsSuccess()) - return r; - - r = verifier_.ProbeSSBO(probe_ssbo, info.size_in_bytes, info.cpu_memory); - } else if (cmd->IsClear()) { - r = engine->DoClear(cmd->AsClear()); - } else if (cmd->IsClearColor()) { - r = engine->DoClearColor(cmd->AsClearColor()); - } else if (cmd->IsClearDepth()) { - r = engine->DoClearDepth(cmd->AsClearDepth()); - } else if (cmd->IsClearStencil()) { - r = engine->DoClearStencil(cmd->AsClearStencil()); - } else if (cmd->IsDrawRect()) { - r = engine->DoDrawRect(cmd->AsDrawRect()); - } else if (cmd->IsDrawArrays()) { - r = engine->DoDrawArrays(cmd->AsDrawArrays()); - } else if (cmd->IsCompute()) { - r = engine->DoCompute(cmd->AsCompute()); - } else if (cmd->IsEntryPoint()) { - r = engine->DoEntryPoint(cmd->AsEntryPoint()); - } else if (cmd->IsPatchParameterVertices()) { - r = engine->DoPatchParameterVertices(cmd->AsPatchParameterVertices()); - } else if (cmd->IsBuffer()) { - r = engine->DoBuffer(cmd->AsBuffer()); - } else { - return Result("Unknown command type"); - } - - if (!r.IsSuccess()) - return r; - } - return {}; -} - -} // namespace vkscript -} // namespace amber diff --git a/src/vkscript/executor.h b/src/vkscript/executor.h deleted file mode 100644 index abbe978..0000000 --- a/src/vkscript/executor.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_VKSCRIPT_EXECUTOR_H_ -#define SRC_VKSCRIPT_EXECUTOR_H_ - -#include "amber/result.h" -#include "src/executor.h" -#include "src/verifier.h" - -namespace amber { -namespace vkscript { - -class Executor : public amber::Executor { - public: - Executor(); - ~Executor() override; - - Result Execute(Engine*, const amber::Script*, const ShaderMap&) override; - - private: - Verifier verifier_; -}; - -} // namespace vkscript -} // namespace amber - -#endif // SRC_VKSCRIPT_EXECUTOR_H_ diff --git a/src/vkscript/parser.cc b/src/vkscript/parser.cc index b375eed..d731911 100644 --- a/src/vkscript/parser.cc +++ b/src/vkscript/parser.cc @@ -153,7 +153,7 @@ Feature NameToFeature(const std::string& name) { } // namespace -Parser::Parser() : amber::Parser(), script_(MakeUnique<vkscript::Script>()) {} +Parser::Parser() : amber::Parser(), script_(MakeUnique<Script>()) {} Parser::~Parser() = default; diff --git a/src/vkscript/parser.h b/src/vkscript/parser.h index 08a4fd6..2987ef7 100644 --- a/src/vkscript/parser.h +++ b/src/vkscript/parser.h @@ -21,7 +21,7 @@ #include "amber/result.h" #include "src/parser.h" -#include "src/vkscript/script.h" +#include "src/script.h" #include "src/vkscript/section_parser.h" namespace amber { @@ -34,9 +34,7 @@ class Parser : public amber::Parser { // amber::Parser Result Parse(const std::string& data) override; - std::unique_ptr<amber::Script> GetScript() override { - return std::move(script_); - } + std::unique_ptr<Script> GetScript() override { return std::move(script_); } Result ProcessRequireBlockForTesting(const std::string& block) { return ProcessRequireBlock(block); @@ -59,7 +57,7 @@ class Parser : public amber::Parser { Result ProcessVertexDataBlock(const std::string&); Result ProcessTestBlock(const std::string&); - std::unique_ptr<vkscript::Script> script_; + std::unique_ptr<Script> script_; }; } // namespace vkscript diff --git a/src/vkscript/parser_test.cc b/src/vkscript/parser_test.cc index 2a57fe8..1a016af 100644 --- a/src/vkscript/parser_test.cc +++ b/src/vkscript/parser_test.cc @@ -102,7 +102,7 @@ TEST_F(VkScriptParserTest, RequireBlockNoArgumentFeatures) { ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); - auto& feats = ToVkScript(script.get())->RequiredFeatures(); + auto& feats = script->RequiredFeatures(); ASSERT_EQ(1U, feats.size()); EXPECT_EQ(feature.feature, feats[0]); } diff --git a/src/vkscript/script.cc b/src/vkscript/script.cc deleted file mode 100644 index c185995..0000000 --- a/src/vkscript/script.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/vkscript/script.h" - -#include <utility> - -#include "src/make_unique.h" - -namespace amber { - -const vkscript::Script* ToVkScript(const amber::Script* s) { - return static_cast<const vkscript::Script*>(s); -} - -namespace vkscript { - -Script::Script() : amber::Script(ScriptType::kVkScript) {} - -Script::~Script() = default; - -} // namespace vkscript -} // namespace amber diff --git a/src/vkscript/script.h b/src/vkscript/script.h deleted file mode 100644 index bf88a6c..0000000 --- a/src/vkscript/script.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 The Amber Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_VKSCRIPT_SCRIPT_H_ -#define SRC_VKSCRIPT_SCRIPT_H_ - -#include <memory> -#include <vector> - -#include "src/buffer.h" -#include "src/command.h" -#include "src/make_unique.h" -#include "src/script.h" -#include "src/vkscript/section_parser.h" - -namespace amber { -namespace vkscript { - -class Script : public amber::Script { - public: - Script(); - ~Script() override; -}; - -} // namespace vkscript - -const vkscript::Script* ToVkScript(const amber::Script* s); - -} // namespace amber - -#endif // SRC_VKSCRIPT_SCRIPT_H_ |