Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/amber_script.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ END
The commands which can be used inside a `REPEAT` block are:
* `CLEAR`
* `CLEAR_COLOR`
* `CLEAR_DEPTH`
* `COPY`
* `EXPECT`
* `RUN`
Expand All @@ -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}
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 36 additions & 2 deletions src/amberscript/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 == "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
Expand All @@ -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")
Expand Down Expand Up @@ -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<ClearDepthCommand>(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())
Expand Down
1 change: 1 addition & 0 deletions src/amberscript/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
134 changes: 134 additions & 0 deletions src/amberscript/parser_clear_depth_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// 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.
// 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<ClearDepthTestData>;
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