From af561bfd090bd5668d3e4d39d325d8f3d9edc942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Thu, 16 Apr 2020 09:25:53 +0300 Subject: [PATCH 1/3] Add CLEAR_DEPTH support for amber script. --- docs/amber_script.md | 5 + src/CMakeLists.txt | 1 + src/amberscript/parser.cc | 36 +++++- src/amberscript/parser.h | 1 + src/amberscript/parser_clear_depth_test.cc | 134 +++++++++++++++++++++ 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/amberscript/parser_clear_depth_test.cc diff --git a/docs/amber_script.md b/docs/amber_script.md index c935d5bf1..ada67251a 100644 --- a/docs/amber_script.md +++ b/docs/amber_script.md @@ -563,6 +563,7 @@ END The commands which can be used inside a `REPEAT` block are: * `CLEAR` * `CLEAR_COLOR` + * `CLEAR_DEPTH` * `COPY` * `EXPECT` * `RUN` @@ -574,6 +575,10 @@ The commands which can be used inside a `REPEAT` block are: # pipeline. The colors are integers from 0 - 255. Defaults to (0, 0, 0, 0) CLEAR_COLOR {pipeline} _r (0 - 255)_ _g (0 - 255)_ _b (0 - 255)_ _a (0 - 255)_ +# Sets the depth clear value to use for |pipeline| which must be a graphics +# pipeline. |value| must be a decimal number. +CLEAR_DEPTH {pipeline} _value_ + # Instructs the |pipeline| which must be a graphics pipeline to execute the # clear command. CLEAR {pipeline} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c18f390f3..07cff45c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,6 +132,7 @@ if (${AMBER_ENABLE_TESTS}) amberscript/parser_bind_test.cc amberscript/parser_buffer_test.cc amberscript/parser_clear_color_test.cc + amberscript/parser_clear_depth_test.cc amberscript/parser_clear_test.cc amberscript/parser_compile_options_test.cc amberscript/parser_copy_test.cc diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index ca59120a9..c67f7f012 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -243,7 +243,7 @@ Result Parser::Parse(const std::string& data) { } bool Parser::IsRepeatable(const std::string& name) const { - return name == "CLEAR" || name == "CLEAR_COLOR" || name == "COPY" || + return name == "CLEAR" || name == "CLEAR_COLOR" || name == "CLEAR_DEPTH" || name == "COPY" || name == "EXPECT" || name == "RUN" || name == "DEBUG"; } @@ -254,6 +254,8 @@ Result Parser::ParseRepeatableCommand(const std::string& name) { return ParseClear(); if (name == "CLEAR_COLOR") return ParseClearColor(); + if (name == "CLEAR_DEPTH") + return ParseClearDepth(); if (name == "COPY") return ParseCopy(); if (name == "EXPECT") @@ -2655,6 +2657,38 @@ Result Parser::ParseClearColor() { return ValidateEndOfStatement("CLEAR_COLOR command"); } + Result Parser::ParseClearDepth() { + auto token = tokenizer_->NextToken(); + if (!token->IsIdentifier()) + return Result("missing pipeline name for CLEAR_DEPTH command"); + + size_t line = tokenizer_->GetCurrentLine(); + + auto* pipeline = script_->GetPipeline(token->AsString()); + if (!pipeline) { + return Result("unknown pipeline for CLEAR_DEPTH command: " + + token->AsString()); + } + if (!pipeline->IsGraphics()) { + return Result("CLEAR_DEPTH command requires graphics pipeline"); + } + + auto cmd = MakeUnique(pipeline); + cmd->SetLine(line); + + token = tokenizer_->NextToken(); + if (token->IsEOL() || token->IsEOS()) + return Result("missing value for CLEAR_DEPTH command"); + if (!token->IsDouble()) { + return Result("invalid value for CLEAR_DEPTH command: " + + token->ToOriginalString()); + } + cmd->SetValue(token->AsFloat()); + + command_list_.push_back(std::move(cmd)); + return ValidateEndOfStatement("CLEAR_DEPTH command"); + } + Result Parser::ParseDeviceFeature() { auto token = tokenizer_->NextToken(); if (token->IsEOS() || token->IsEOL()) diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h index 524cb43b8..42908cb7f 100644 --- a/src/amberscript/parser.h +++ b/src/amberscript/parser.h @@ -73,6 +73,7 @@ class Parser : public amber::Parser { Result ParseDebugThreadBody(debug::Thread* thread); Result ParseClear(); Result ParseClearColor(); + Result ParseClearDepth(); Result ParseExpect(); Result ParseCopy(); Result ParseDeviceFeature(); diff --git a/src/amberscript/parser_clear_depth_test.cc b/src/amberscript/parser_clear_depth_test.cc new file mode 100644 index 000000000..b0a7bcad7 --- /dev/null +++ b/src/amberscript/parser_clear_depth_test.cc @@ -0,0 +1,134 @@ +// Copyright 2019 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 parseried. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gtest/gtest.h" +#include "src/amberscript/parser.h" + +namespace amber { +namespace amberscript { + +using AmberScriptParserTest = testing::Test; + +TEST_F(AmberScriptParserTest, ClearDepth) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment +END + +CLEAR_DEPTH my_pipeline 1.5)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_TRUE(r.IsSuccess()) << r.Error(); + + auto script = parser.GetScript(); + const auto& commands = script->GetCommands(); + ASSERT_EQ(1U, commands.size()); + + auto* cmd = commands[0].get(); + ASSERT_TRUE(cmd->IsClearDepth()); + + auto* clr = cmd->AsClearDepth(); + EXPECT_FLOAT_EQ(1.5, clr->GetValue()); +} + +TEST_F(AmberScriptParserTest, ClearDepthWithComputePipeline) { + std::string in = R"( +SHADER compute my_shader GLSL +# shader +END + +PIPELINE compute my_pipeline + ATTACH my_shader +END + +CLEAR_DEPTH my_pipeline 0.0)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("10: CLEAR_DEPTH command requires graphics pipeline", r.Error()); +} + +TEST_F(AmberScriptParserTest, ClearDepthMissingPipeline) { + std::string in = "CLEAR_DEPTH 0.0"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("1: missing pipeline name for CLEAR_DEPTH command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ClearDepthInvalidPipeline) { + std::string in = "CLEAR_DEPTH unknown_pipeline 0.0"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + + EXPECT_EQ("1: unknown pipeline for CLEAR_DEPTH command: unknown_pipeline", + r.Error()); +} + +struct ClearDepthTestData { + std::string data; + std::string error; +}; +using AmberScriptParserClearDepthTest = + testing::TestWithParam; +TEST_P(AmberScriptParserClearDepthTest, InvalidParams) { + auto test_data = GetParam(); + + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER my_fb FORMAT R32G32B32A32_SFLOAT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment +END + +CLEAR_DEPTH my_pipeline )" + + test_data.data; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()) << test_data.data; + EXPECT_EQ(std::string("13: ") + test_data.error, r.Error()) << test_data.data; +} + +INSTANTIATE_TEST_SUITE_P( + AmberScriptParserClearDepthTests, + AmberScriptParserClearDepthTest, + testing::Values( + ClearDepthTestData{"", "missing value for CLEAR_DEPTH command"}, + ClearDepthTestData{"INVALID", + "invalid value for CLEAR_DEPTH command: INVALID"}, + ClearDepthTestData{"5", "invalid value for CLEAR_DEPTH command: 5"}, + ClearDepthTestData{"1.0 EXTRA", + "extra parameters after CLEAR_DEPTH command: " + "EXTRA"})); // NOLINT(whitespace/parens) + +} // namespace amberscript +} // namespace amber From 5b0ed47e76d20b57330a820faf8de3b1b2c7ff05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Thu, 16 Apr 2020 09:27:23 +0300 Subject: [PATCH 2/3] Fixed copyright year. --- src/amberscript/parser_clear_depth_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amberscript/parser_clear_depth_test.cc b/src/amberscript/parser_clear_depth_test.cc index b0a7bcad7..d2615feec 100644 --- a/src/amberscript/parser_clear_depth_test.cc +++ b/src/amberscript/parser_clear_depth_test.cc @@ -1,4 +1,4 @@ -// Copyright 2019 The Amber Authors. +// Copyright 2020 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. From e2e71d5595c2481cbfc8b759c2db9ac6394c6d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Thu, 16 Apr 2020 09:41:08 +0300 Subject: [PATCH 3/3] Fixed formatting. --- src/amberscript/parser.cc | 56 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index c67f7f012..c5ff157fe 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -243,8 +243,8 @@ Result Parser::Parse(const std::string& data) { } bool Parser::IsRepeatable(const std::string& name) const { - return name == "CLEAR" || name == "CLEAR_COLOR" || name == "CLEAR_DEPTH" || name == "COPY" || - name == "EXPECT" || name == "RUN" || name == "DEBUG"; + return name == "CLEAR" || name == "CLEAR_COLOR" || name == "CLEAR_DEPTH" || + name == "COPY" || name == "EXPECT" || name == "RUN" || name == "DEBUG"; } // The given |name| must be one of the repeatable commands or this method @@ -2657,37 +2657,37 @@ Result Parser::ParseClearColor() { return ValidateEndOfStatement("CLEAR_COLOR command"); } - Result Parser::ParseClearDepth() { - auto token = tokenizer_->NextToken(); - if (!token->IsIdentifier()) - return Result("missing pipeline name for CLEAR_DEPTH command"); +Result Parser::ParseClearDepth() { + auto token = tokenizer_->NextToken(); + if (!token->IsIdentifier()) + return Result("missing pipeline name for CLEAR_DEPTH command"); - size_t line = tokenizer_->GetCurrentLine(); + size_t line = tokenizer_->GetCurrentLine(); - auto* pipeline = script_->GetPipeline(token->AsString()); - if (!pipeline) { - return Result("unknown pipeline for CLEAR_DEPTH command: " + - token->AsString()); - } - if (!pipeline->IsGraphics()) { - return Result("CLEAR_DEPTH command requires graphics pipeline"); - } + auto* pipeline = script_->GetPipeline(token->AsString()); + if (!pipeline) { + return Result("unknown pipeline for CLEAR_DEPTH command: " + + token->AsString()); + } + if (!pipeline->IsGraphics()) { + return Result("CLEAR_DEPTH command requires graphics pipeline"); + } - auto cmd = MakeUnique(pipeline); - cmd->SetLine(line); + auto cmd = MakeUnique(pipeline); + cmd->SetLine(line); - token = tokenizer_->NextToken(); - if (token->IsEOL() || token->IsEOS()) - return Result("missing value for CLEAR_DEPTH command"); - if (!token->IsDouble()) { - return Result("invalid value for CLEAR_DEPTH command: " + - token->ToOriginalString()); - } - cmd->SetValue(token->AsFloat()); + token = tokenizer_->NextToken(); + if (token->IsEOL() || token->IsEOS()) + return Result("missing value for CLEAR_DEPTH command"); + if (!token->IsDouble()) { + return Result("invalid value for CLEAR_DEPTH command: " + + token->ToOriginalString()); + } + cmd->SetValue(token->AsFloat()); - command_list_.push_back(std::move(cmd)); - return ValidateEndOfStatement("CLEAR_DEPTH command"); - } + command_list_.push_back(std::move(cmd)); + return ValidateEndOfStatement("CLEAR_DEPTH command"); +} Result Parser::ParseDeviceFeature() { auto token = tokenizer_->NextToken();