// 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, StencilAllValues) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on FAIL_OP increment_and_clamp PASS_OP invert DEPTH_FAIL_OP keep COMPARE_OP equal COMPARE_MASK 1 WRITE_MASK 2 REFERENCE 3 END STENCIL back TEST on FAIL_OP zero PASS_OP increment_and_wrap DEPTH_FAIL_OP replace COMPARE_OP greater COMPARE_MASK 4 WRITE_MASK 5 REFERENCE 6 END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); const auto& pipelines = script->GetPipelines(); ASSERT_EQ(1U, pipelines.size()); auto* pipeline = pipelines[0].get(); ASSERT_NE(nullptr, pipeline->GetDepthStencilBuffer().buffer); ASSERT_TRUE(pipeline->GetPipelineData()->GetEnableStencilTest()); ASSERT_EQ(StencilOp::kIncrementAndClamp, pipeline->GetPipelineData()->GetFrontFailOp()); ASSERT_EQ(StencilOp::kZero, pipeline->GetPipelineData()->GetBackFailOp()); ASSERT_EQ(StencilOp::kInvert, pipeline->GetPipelineData()->GetFrontPassOp()); ASSERT_EQ(StencilOp::kIncrementAndWrap, pipeline->GetPipelineData()->GetBackPassOp()); ASSERT_EQ(StencilOp::kKeep, pipeline->GetPipelineData()->GetFrontDepthFailOp()); ASSERT_EQ(StencilOp::kReplace, pipeline->GetPipelineData()->GetBackDepthFailOp()); ASSERT_EQ(CompareOp::kEqual, pipeline->GetPipelineData()->GetFrontCompareOp()); ASSERT_EQ(CompareOp::kGreater, pipeline->GetPipelineData()->GetBackCompareOp()); ASSERT_EQ(1u, pipeline->GetPipelineData()->GetFrontCompareMask()); ASSERT_EQ(4u, pipeline->GetPipelineData()->GetBackCompareMask()); ASSERT_EQ(2u, pipeline->GetPipelineData()->GetFrontWriteMask()); ASSERT_EQ(5u, pipeline->GetPipelineData()->GetBackWriteMask()); ASSERT_EQ(3u, pipeline->GetPipelineData()->GetFrontReference()); ASSERT_EQ(6u, pipeline->GetPipelineData()->GetBackReference()); } TEST_F(AmberScriptParserTest, StencilMissingFace) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL TEST on END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("16: STENCIL missing face", r.Error()); } TEST_F(AmberScriptParserTest, StencilInvalidFaceValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL foo TEST on END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("15: STENCIL invalid face: foo", r.Error()); } TEST_F(AmberScriptParserTest, StencilTestMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for TEST", r.Error()); } TEST_F(AmberScriptParserTest, StencilTestInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("16: STENCIL invalid value for TEST: foo", r.Error()); } TEST_F(AmberScriptParserTest, StencilFailMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on FAIL_OP END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("18: STENCIL invalid value for FAIL_OP", r.Error()); } TEST_F(AmberScriptParserTest, StencilFailInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on FAIL_OP foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for FAIL_OP: foo", r.Error()); } TEST_F(AmberScriptParserTest, StencilPassMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on PASS_OP END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("18: STENCIL invalid value for PASS_OP", r.Error()); } TEST_F(AmberScriptParserTest, StencilPassInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on PASS_OP foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for PASS_OP: foo", r.Error()); } TEST_F(AmberScriptParserTest, StencilDepthFailMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on DEPTH_FAIL_OP END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("18: STENCIL invalid value for DEPTH_FAIL_OP", r.Error()); } TEST_F(AmberScriptParserTest, StencilDepthFailInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on DEPTH_FAIL_OP foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for DEPTH_FAIL_OP: foo", r.Error()); } TEST_F(AmberScriptParserTest, StencilCompareMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on COMPARE_OP END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("18: STENCIL invalid value for COMPARE_OP", r.Error()); } TEST_F(AmberScriptParserTest, StencilCompareInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on COMPARE_OP foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for COMPARE_OP: foo", r.Error()); } TEST_F(AmberScriptParserTest, StencilCompareMaskMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on COMPARE_MASK END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("18: STENCIL invalid value for COMPARE_MASK", r.Error()); } TEST_F(AmberScriptParserTest, StencilCompareMaskInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on COMPARE_MASK foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for COMPARE_MASK", r.Error()); } TEST_F(AmberScriptParserTest, StencilWriteMaskMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on WRITE_MASK END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("18: STENCIL invalid value for WRITE_MASK", r.Error()); } TEST_F(AmberScriptParserTest, StencilWriteMaskInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on WRITE_MASK foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for WRITE_MASK", r.Error()); } TEST_F(AmberScriptParserTest, StencilReferenceMissingValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on REFERENCE END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("18: STENCIL invalid value for REFERENCE", r.Error()); } TEST_F(AmberScriptParserTest, StencilReferenceInvalidValue) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END BUFFER my_fb FORMAT R32G32B32A32_SFLOAT BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT PIPELINE graphics my_pipeline ATTACH my_shader ATTACH my_fragment BIND BUFFER my_fb AS color LOCATION 0 BIND BUFFER my_ds AS depth_stencil STENCIL front TEST on REFERENCE foo END END)"; Parser parser; Result r = parser.Parse(in); ASSERT_FALSE(r.IsSuccess()) << r.Error(); EXPECT_EQ("17: STENCIL invalid value for REFERENCE", r.Error()); } } // namespace amberscript } // namespace amber