diff options
-rw-r--r-- | docs/amber_script.md | 29 | ||||
-rw-r--r-- | src/amberscript/parser.cc | 134 | ||||
-rw-r--r-- | src/amberscript/parser.h | 1 | ||||
-rw-r--r-- | src/amberscript/parser_test.cc | 706 | ||||
-rw-r--r-- | src/vulkan/engine_vulkan.cc | 3 | ||||
-rw-r--r-- | tests/cases/clear.amber | 39 |
6 files changed, 896 insertions, 16 deletions
diff --git a/docs/amber_script.md b/docs/amber_script.md index d1e6ecf..454cfe7 100644 --- a/docs/amber_script.md +++ b/docs/amber_script.md @@ -314,19 +314,26 @@ CLEAR <pipeline> ``` # Checks that |buffer_name| at |x|, |y| has the given |value|s when compared # with the given |comparator|. -EXPECT <buffer_name> IDX <x> <y> <comparator> <value>+ +EXPECT <pipeline_name> BUFFER <buffer_name> IDX <x> <y> <comparator> <value>+ # Checks that |buffer_name| at |x|, |y| has values within |tolerance| of |value| # when compared with the given |comparator|. The |tolerance| can be specified # as 1-4 float values separated by spaces. -EXPECT <buffer_name> IDX <x> <y> TOLERANCE <tolerance>{1,4} <comparator> \ - <value>+ +EXPECT <pipeline_name> BUFFER <buffer_name> IDX <x> <y> TOLERANCE \ + <tolerance>{1,4} <comparator> <value>+ # Checks that |buffer_name| at |x|, |y| for |width|x|height| pixels has the # given |r|, |g|, |b| values. Each r, g, b value is an integer from 0-255. -EXPECT <buffer_name> IDX <x_in_pixels> <y_in_pixels> \ +EXPECT <pipeline_name> BUFFER <buffer_name> IDX <x_in_pixels> <y_in_pixels> \ SIZE <width_in_pixels> <height_in_pixels> \ EQ_RGB <r (0 - 255)> <g (0 - 255)> <b (0 - 255)> + +# Checks that |buffer_name| at |x|, |y| for |width|x|height| pixels has the +# given |r|, |g|, |b|, |a| values. Each r, g, b, a value is an integer +# from 0-255. +EXPECT <pipeline_name> BUFFER <buffer_name> IDX <x_in_pixels> <y_in_pixels> \ + SIZE <width_in_pixels> <height_in_pixels> \ + EQ_RGBA <r (0 - 255)> <g (0 - 255)> <b (0 - 255)> <a (0 - 255)> ``` ## Examples @@ -359,13 +366,13 @@ END # pipeline RUN kComputePipeline 256 256 1 # Four corners -EXPECT kComputeBuffer IDX 0 EQ 0 0 -EXPECT kComputeBuffer IDX 2040 EQ 255 0 -EXPECT kComputeBuffer IDX 522240 EQ 0 255 -EXPECT kComputeBuffer IDX 524280 EQ 255 255 +EXPECT kComputePipeline BUFFER kComputeBuffer IDX 0 EQ 0 0 +EXPECT kComputePipeline BUFFER kComputeBuffer IDX 2040 EQ 255 0 +EXPECT kComputePipeline BUFFER kComputeBuffer IDX 522240 EQ 0 255 +EXPECT kComputePipeline BUFFER kComputeBuffer IDX 524280 EQ 255 255 # Center -EXPECT kComputeBuffer IDX 263168 EQ 128 128 +EXPECT kComputePipeline BUFFER kComputeBuffer IDX 263168 EQ 128 128 ``` ### Entry Points @@ -440,8 +447,8 @@ END # pipeline RUN kRedPipeline DRAW_RECT POS 0 0 SIZE 256 256 RUN kGreenPipeline DRAW_RECT POS 128 128 SIZE 256 256 -EXPECT kImgBuffer IDX 0 0 SIZE 127 127 EQ_RGB 255 0 0 -EXPECT kImgBuffer IDX 128 128 SIZE 128 128 EQ_RGB 0 255 0 +EXPECT kGreenPipeline BUFFER kImgBuffer IDX 0 0 SIZE 127 127 EQ_RGB 255 0 0 +EXPECT kGreenPipeline BUFFER kImgBuffer IDX 128 128 SIZE 128 128 EQ_RGB 0 255 0 ``` ### Buffers diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index a810457..9b99f91 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -50,14 +50,16 @@ Result Parser::Parse(const std::string& data) { std::string tok = token->AsString(); if (tok == "BUFFER") { r = ParseBuffer(); + } else if (tok == "CLEAR") { + r = ParseClear(); + } else if (tok == "EXPECT") { + r = ParseExpect(); } else if (tok == "PIPELINE") { r = ParsePipelineBlock(); - } else if (tok == "SHADER") { - r = ParseShaderBlock(); } else if (tok == "RUN") { r = ParseRun(); - } else if (tok == "CLEAR") { - r = ParseClear(); + } else if (tok == "SHADER") { + r = ParseShaderBlock(); } else { r = Result("unknown token: " + tok); } @@ -548,6 +550,8 @@ Result Parser::ParsePipelineBind(Pipeline* pipeline) { if (!token->IsInteger()) return Result("invalid value for BIND LOCATION"); + buffer->SetBufferType(BufferType::kColor); + Result r = pipeline->AddColorAttachment(buffer, token->AsUint32()); if (!r.IsSuccess()) return r; @@ -989,5 +993,127 @@ Result Parser::ParseClear() { return ValidateEndOfStatement("CLEAR command"); } +Result Parser::ParseExpect() { + auto token = tokenizer_->NextToken(); + if (token->IsEOS() || token->IsEOL()) + return Result("missing pipeline name in EXPECT command"); + if (!token->IsString()) + return Result("invalid pipeline name in EXPECT command"); + + auto* pipeline = script_->GetPipeline(token->AsString()); + if (!pipeline) + return Result("unknown pipeline name for EXPECT command"); + + token = tokenizer_->NextToken(); + if (token->IsEOS() || token->IsEOL()) + return Result("missing BUFFER in EXPECT command"); + if (!token->IsString() || token->AsString() != "BUFFER") { + return Result("expected BUFFER got '" + token->ToOriginalString() + + "' in " + "EXPECT command"); + } + + token = tokenizer_->NextToken(); + if (!token->IsString()) + return Result("invalid buffer name in EXPECT command"); + + auto* buffer = script_->GetBuffer(token->AsString()); + if (!buffer) + return Result("unknown buffer name for EXPECT command"); + + token = tokenizer_->NextToken(); + if (!token->IsString() || token->AsString() != "IDX") + return Result("missing IDX in EXPECT command"); + + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() < 0) + return Result("invalid X value in EXPECT command"); + token->ConvertToDouble(); + float x = token->AsFloat(); + + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() < 0) + return Result("invalid Y value in EXPECT command"); + token->ConvertToDouble(); + float y = token->AsFloat(); + + // TODO(dsinclair): Handle comparator && TOLERANCE + + token = tokenizer_->NextToken(); + if (token->IsString() && token->AsString() == "SIZE") { + bool found = false; + for (const auto& info : pipeline->GetColorAttachments()) { + if (info.buffer == buffer) { + found = true; + break; + } + } + if (!found) + return Result("buffer not in pipeline for EXPECT command"); + + auto probe = MakeUnique<ProbeCommand>(pipeline, buffer); + probe->SetX(x); + probe->SetY(y); + probe->SetProbeRect(); + + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() <= 0) + return Result("invalid width in EXPECT command"); + token->ConvertToDouble(); + probe->SetWidth(token->AsFloat()); + + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() <= 0) + return Result("invalid height in EXPECT command"); + token->ConvertToDouble(); + probe->SetHeight(token->AsFloat()); + + token = tokenizer_->NextToken(); + if (!token->IsString()) { + return Result("invalid token in EXPECT command:" + + token->ToOriginalString()); + } + + if (token->AsString() == "EQ_RGBA") { + probe->SetIsRGBA(); + } else if (token->AsString() != "EQ_RGB") { + return Result("unknown comparator type in EXPECT: " + + token->ToOriginalString()); + } + + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() < 0 || token->AsInt32() > 255) + return Result("invalid R value in EXPECT command"); + token->ConvertToDouble(); + probe->SetR(token->AsFloat()); + + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() < 0 || token->AsInt32() > 255) + return Result("invalid G value in EXPECT command"); + token->ConvertToDouble(); + probe->SetG(token->AsFloat()); + + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() < 0 || token->AsInt32() > 255) + return Result("invalid B value in EXPECT command"); + token->ConvertToDouble(); + probe->SetB(token->AsFloat()); + + if (probe->IsRGBA()) { + token = tokenizer_->NextToken(); + if (!token->IsInteger() || token->AsInt32() < 0 || token->AsInt32() > 255) + return Result("invalid A value in EXPECT command"); + token->ConvertToDouble(); + probe->SetA(token->AsFloat()); + } + + script_->AddCommand(std::move(probe)); + } else { + return Result("unexpected token in EXPECT command: " + + token->ToOriginalString()); + } + + return ValidateEndOfStatement("EXPECT command"); +} + } // namespace amberscript } // namespace amber diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h index 60b32a0..49aefd2 100644 --- a/src/amberscript/parser.h +++ b/src/amberscript/parser.h @@ -62,6 +62,7 @@ class Parser : public amber::Parser { Result ParsePipelineIndexData(Pipeline*); Result ParseRun(); Result ParseClear(); + Result ParseExpect(); std::unique_ptr<Tokenizer> tokenizer_; }; diff --git a/src/amberscript/parser_test.cc b/src/amberscript/parser_test.cc index e300614..d89c188 100644 --- a/src/amberscript/parser_test.cc +++ b/src/amberscript/parser_test.cc @@ -3502,5 +3502,711 @@ CLEAR my_pipeline EXTRA)"; EXPECT_EQ("12: extra parameters after CLEAR command", r.Error()); } +TEST_F(AmberScriptParserTest, ExpectRGB) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 5 6 SIZE 250 150 EQ_RGB 2 128 255)"; + + 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->IsProbe()); + + auto* probe = cmd->AsProbe(); + EXPECT_FALSE(probe->IsRGBA()); + EXPECT_TRUE(probe->IsProbeRect()); + EXPECT_FALSE(probe->IsRelative()); + EXPECT_FALSE(probe->IsWholeWindow()); + EXPECT_EQ(5U, probe->GetX()); + EXPECT_EQ(6U, probe->GetY()); + EXPECT_EQ(250U, probe->GetWidth()); + EXPECT_EQ(150U, probe->GetHeight()); + EXPECT_EQ(2U, probe->GetR()); + EXPECT_EQ(128U, probe->GetG()); + EXPECT_EQ(255U, probe->GetB()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBA) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 2 7 SIZE 20 88 EQ_RGBA 2 128 255 99)"; + + 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->IsProbe()); + + auto* probe = cmd->AsProbe(); + EXPECT_TRUE(probe->IsRGBA()); + EXPECT_TRUE(probe->IsProbeRect()); + EXPECT_FALSE(probe->IsRelative()); + EXPECT_FALSE(probe->IsWholeWindow()); + EXPECT_EQ(2U, probe->GetX()); + EXPECT_EQ(7U, probe->GetY()); + EXPECT_EQ(20U, probe->GetWidth()); + EXPECT_EQ(88U, probe->GetHeight()); + EXPECT_EQ(2U, probe->GetR()); + EXPECT_EQ(128U, probe->GetG()); + EXPECT_EQ(255U, probe->GetB()); + EXPECT_EQ(99U, probe->GetA()); +} + +TEST_F(AmberScriptParserTest, ExpectMissingPipelineName) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: unknown pipeline name for EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectInvalidPipelineName) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT unknown_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: unknown pipeline name for EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectMissingBuffer) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: expected BUFFER got 'my_fb' in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectMissingBufferName) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER IDX 0 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: unknown buffer name for EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectInvalidBufferName) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER unknown_buffer IDX 0 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: unknown buffer name for EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectBufferNotInPipeline) { + std::string in = R"( +SHADER vertex my_shader PASSTHROUGH +SHADER fragment my_fragment GLSL +# GLSL Shader +END +BUFFER other_fb FORMAT R32G32B32A32_SFLOAT + +PIPELINE graphics my_pipeline + ATTACH my_shader + ATTACH my_fragment +END + +EXPECT my_pipeline BUFFER other_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("13: buffer not in pipeline for EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectMissingIDX) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb 0 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: missing IDX in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectMissingIDXValues) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid X value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectMissingIdxY) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid Y value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectIdxInvalidX) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX INVAILD 0 SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid X value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectIdxInvalidY) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 INVALID SIZE 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid Y value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBMissingSize) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 250 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: unexpected token in EXPECT command: 250", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectSizeMissingValues) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid width in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectSizeMissingHeight) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid height in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectSizeInvalidWidth) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE INVALID 250 EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid width in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectSizeInvalidHeight) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 INVALID EQ_RGB 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid height in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectSizeInvalidComparitor) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 INVALID 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: unknown comparator type in EXPECT: INVALID", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBMissingValues) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid R value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBMissingB) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 128)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid B value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBMissingG) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid G value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBAMissingA) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGBA 0 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid A value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBInvalidR) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB INVALID 128 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid R value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBInvalidG) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 INVALID 255)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid G value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBInvalidB) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 128 INVALID)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: invalid B value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBAInvalidA) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 \ + EQ_RGBA 0 128 255 INVALID)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("16: invalid A value in EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBExtraParam) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 EQ_RGB 0 128 255 EXTRA)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("15: extra parameters after EXPECT command", r.Error()); +} + +TEST_F(AmberScriptParserTest, ExpectRGBAExtraParam) { + 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 + + BIND BUFFER my_fb AS color LOCATION 0 +END + +EXPECT my_pipeline BUFFER my_fb IDX 0 0 SIZE 250 250 \ + EQ_RGBA 0 128 255 99 EXTRA)"; + + Parser parser; + Result r = parser.Parse(in); + ASSERT_FALSE(r.IsSuccess()); + EXPECT_EQ("16: extra parameters after EXPECT command", r.Error()); +} + } // namespace amberscript } // namespace amber diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index 01f040b..56cb652 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -137,7 +137,8 @@ Result EngineVulkan::Shutdown() { nullptr); } - info.vk_pipeline->Shutdown(); + if (info.vk_pipeline != VK_NULL_HANDLE) + info.vk_pipeline->Shutdown(); } pool_ = nullptr; diff --git a/tests/cases/clear.amber b/tests/cases/clear.amber new file mode 100644 index 0000000..705b290 --- /dev/null +++ b/tests/cases/clear.amber @@ -0,0 +1,39 @@ +#!amber +# 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 +# +# https://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. + +SHADER vertex vtex_shader PASSTHROUGH +SHADER fragment frag_shader GLSL +#version 430 + +layout(location = 0) in vec4 color_in; +layout(location = 0) out vec4 color_out; + +void main() { + color_out = color_in; +} +END + +BUFFER img_buf FORMAT B8G8R8A8_UNORM + +PIPELINE graphics my_pipeline + ATTACH vtex_shader + ATTACH frag_shader + + FRAMEBUFFER_SIZE 256 256 + BIND BUFFER img_buf AS color LOCATION 0 +END + +CLEAR my_pipeline +EXPECT my_pipeline BUFFER img_buf IDX 0 0 SIZE 256 256 EQ_RGBA 0 0 0 0 |