diff options
Diffstat (limited to 'o3d/compiler/technique/technique_parser_test.cc')
-rw-r--r-- | o3d/compiler/technique/technique_parser_test.cc | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/o3d/compiler/technique/technique_parser_test.cc b/o3d/compiler/technique/technique_parser_test.cc new file mode 100644 index 0000000..ea2ca0a --- /dev/null +++ b/o3d/compiler/technique/technique_parser_test.cc @@ -0,0 +1,414 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// Test program to exercise the Technique Antlr grammar using both files and +// in-memory string buffers. + +#include "tests/common/win/testing_common.h" +#include "compiler/technique/technique_parser.h" + +namespace o3d { + +// classes --------------------------------------------------------------------- + +class TechniqueParserTest : public testing::Test { + protected: + virtual void SetUp(); + virtual void TearDown(); + private: +}; + +void TechniqueParserTest::SetUp() { +} + +void TechniqueParserTest::TearDown() { +} + +// globals --------------------------------------------------------------------- + +char simple_fx_source[] = +"float4x4 worldViewProj : WORLDVIEWPROJECTION; \ +void vs(in float4 pos, out float4 opos) { \ + opos = mul(pos, worldViewProj); \ +} \ +float4 fs(): COLOR { \ + return float3(0.33f, 0.57f, 0.10f); \ +} \ +technique t1 { \ + pass p0 { \ + VertexShader = compile vs_2_0 vs(); \ + PixelShader = compile ps_2_0 fs(); \ + } \ +} \ +"; + +char lambert_fx_source[] = +"struct a2v { \ + float4 pos : POSITION; \ + float3 normal : NORMAL; \ +}; \ + \ +struct v2f { \ + float4 pos : POSITION; \ + float3 n : TEXCOORD0; \ + float3 l : TEXCOORD1; \ +}; \ + \ +float4x4 worldViewProj : WorldViewProjection; \ +float4x4 world : World; \ +float4x4 worldIT : WorldInverseTranspose; \ +float3 lightWorldPos; \ +float4 lightColor; \ + \ +v2f vsMain(a2v IN) { \ + v2f OUT; \ + OUT.pos = mul(IN.pos, worldViewProj); \ + OUT.n = mul(float4(IN.normal,0), worldIT).xyz; \ + OUT.l = lightWorldPos-mul(IN.pos, world).xyz; \ + return OUT; \ +} \ + \ +float4 fsMain(v2f IN): COLOR { \ + float3 l=normalize(IN.l); \ + float3 n=normalize(IN.n); \ + float4 litR=lit(dot(n,l),0,0); \ + return emissive+lightColor*(ambient+diffuse*litR.y); \ +} \ + \ +technique { \ + pass p0 { \ + VertexShader = compile vs_2_0 vsMain(); \ + PixelShader = compile ps_2_0 fsMain(); \ + } \ +} \ +"; + +// ----------------------------------------------------------------------------- + +TEST_F(TechniqueParserTest, ParseSimpleFXFromFile) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/simple.fx"; + EXPECT_TRUE(ParseFxFile(filepath, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_LT(0, static_cast<int>(technique_list.size())); + ASSERT_EQ(1, technique_list.size()); + EXPECT_EQ("t1", technique_list[0].name); + ASSERT_EQ(0, technique_list[0].annotation.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + EXPECT_EQ("p0", technique_list[0].pass[0].name); + ASSERT_EQ(0, technique_list[0].pass[0].annotation.size()); + EXPECT_EQ("vs", technique_list[0].pass[0].vertex_shader_entry); + EXPECT_EQ("vs_2_0", technique_list[0].pass[0].vertex_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].vertex_shader_arguments); + EXPECT_EQ("fs", technique_list[0].pass[0].fragment_shader_entry); + EXPECT_EQ("ps_2_0", technique_list[0].pass[0].fragment_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].fragment_shader_arguments); + ASSERT_EQ(0, technique_list[0].pass[0].state_assignment.size()); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseSimpleFXFromString) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + EXPECT_TRUE(ParseFxString(simple_fx_source, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_LT(0, static_cast<int>(technique_list.size())); + ASSERT_EQ(1, technique_list.size()); + EXPECT_EQ("t1", technique_list[0].name); + ASSERT_EQ(0, technique_list[0].annotation.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + EXPECT_EQ("p0", technique_list[0].pass[0].name); + ASSERT_EQ(0, technique_list[0].pass[0].annotation.size()); + EXPECT_EQ("vs", technique_list[0].pass[0].vertex_shader_entry); + EXPECT_EQ("vs_2_0", technique_list[0].pass[0].vertex_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].vertex_shader_arguments); + EXPECT_EQ("fs", technique_list[0].pass[0].fragment_shader_entry); + EXPECT_EQ("ps_2_0", technique_list[0].pass[0].fragment_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].fragment_shader_arguments); + ASSERT_EQ(0, technique_list[0].pass[0].state_assignment.size()); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseLambertFXFromFile) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/lambert.fx"; + EXPECT_TRUE(ParseFxFile(filepath.c_str(), + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_LT(0, static_cast<int>(technique_list.size())); + ASSERT_EQ(1, technique_list.size()); + EXPECT_EQ("", technique_list[0].name); + ASSERT_EQ(0, technique_list[0].annotation.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + EXPECT_EQ("p0", technique_list[0].pass[0].name); + ASSERT_EQ(0, technique_list[0].pass[0].annotation.size()); + EXPECT_EQ("vsMain", technique_list[0].pass[0].vertex_shader_entry); + EXPECT_EQ("vs_2_0", technique_list[0].pass[0].vertex_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].vertex_shader_arguments); + EXPECT_EQ("fsMain", technique_list[0].pass[0].fragment_shader_entry); + EXPECT_EQ("ps_2_0", technique_list[0].pass[0].fragment_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].fragment_shader_arguments); + ASSERT_EQ(0, technique_list[0].pass[0].state_assignment.size()); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseLambertFXFromString) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + EXPECT_TRUE(ParseFxString(lambert_fx_source, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_LT(0, static_cast<int>(technique_list.size())); + ASSERT_EQ(1, technique_list.size()); + EXPECT_EQ("", technique_list[0].name); + ASSERT_EQ(0, technique_list[0].annotation.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + EXPECT_EQ("p0", technique_list[0].pass[0].name); + ASSERT_EQ(0, technique_list[0].pass[0].annotation.size()); + EXPECT_EQ("vsMain", technique_list[0].pass[0].vertex_shader_entry); + EXPECT_EQ("vs_2_0", technique_list[0].pass[0].vertex_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].vertex_shader_arguments); + EXPECT_EQ("fsMain", technique_list[0].pass[0].fragment_shader_entry); + EXPECT_EQ("ps_2_0", technique_list[0].pass[0].fragment_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].fragment_shader_arguments); + ASSERT_EQ(0, technique_list[0].pass[0].state_assignment.size()); + ASSERT_EQ(0, sampler_list.size()); +} + + + +// Test the longer shaders from files ------------------------------------------ + +TEST_F(TechniqueParserTest, ParseNoShaderFXFromFile) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/noshader.fx"; + EXPECT_TRUE(ParseFxFile(filepath, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_LT(0, static_cast<int>(technique_list.size())); + ASSERT_EQ(1, technique_list.size()); + EXPECT_EQ("t1", technique_list[0].name); + ASSERT_EQ(0, technique_list[0].annotation.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + EXPECT_EQ("p0", technique_list[0].pass[0].name); + ASSERT_EQ(0, technique_list[0].pass[0].annotation.size()); + EXPECT_EQ("", technique_list[0].pass[0].vertex_shader_entry); + EXPECT_EQ("", technique_list[0].pass[0].vertex_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].vertex_shader_arguments); + EXPECT_EQ("", technique_list[0].pass[0].fragment_shader_entry); + EXPECT_EQ("", technique_list[0].pass[0].fragment_shader_profile); + EXPECT_EQ("", technique_list[0].pass[0].fragment_shader_arguments); + ASSERT_EQ(4, technique_list[0].pass[0].state_assignment.size()); + EXPECT_EQ("ZEnable", technique_list[0].pass[0].state_assignment[0].name); + EXPECT_EQ("true", technique_list[0].pass[0].state_assignment[0].value); + EXPECT_EQ("ZWriteEnable", technique_list[0].pass[0].state_assignment[1].name); + EXPECT_EQ("true", technique_list[0].pass[0].state_assignment[1].value); + EXPECT_EQ("ZFunc", technique_list[0].pass[0].state_assignment[2].name); + EXPECT_EQ("LessEqual", technique_list[0].pass[0].state_assignment[2].value); + EXPECT_EQ("CullMode", technique_list[0].pass[0].state_assignment[3].name); + EXPECT_EQ("None", technique_list[0].pass[0].state_assignment[3].value); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseNoTechniqueFXFromFile) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/notechnique.fx"; + EXPECT_TRUE(ParseFxFile(filepath, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_EQ(0, technique_list.size()); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseFurFXFromFile) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/fur.fx"; + EXPECT_TRUE(ParseFxFile(filepath, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + ASSERT_EQ(1, technique_list.size()); + EXPECT_EQ(1, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseShadowMapFXFromFile) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/shadow_map.fx"; + EXPECT_TRUE(ParseFxFile(filepath, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + ASSERT_EQ(2, technique_list.size()); + EXPECT_EQ(2, sampler_list.size()); +} + + + +// Tests of error cases -------------------------------------------------------- + +TEST_F(TechniqueParserTest, ParseEmptyString) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String empty_fx_source = ""; + EXPECT_TRUE(ParseFxString(empty_fx_source, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_EQ(0, technique_list.size()); + EXPECT_EQ(String(""), shader_source); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseInvalidString) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String invalid_fx_source = "$%^~ This is an invalid shader."; + EXPECT_FALSE(ParseFxString(invalid_fx_source, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_EQ(0, technique_list.size()); + EXPECT_EQ(0, sampler_list.size()); + // TODO: make sure the string was rejected as an invalid HLSL + // program and test the parser errors. +} + +TEST_F(TechniqueParserTest, ParseInvalidFilename) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/invalid_filename.fx"; + EXPECT_FALSE(ParseFxFile(filepath, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_EQ(technique_list.size(), 0); + EXPECT_EQ(shader_source, String("")); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseInvalidPassIdentifier) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String invalid_pass_identifier_source = "technique { pass pass { } };"; + EXPECT_FALSE(ParseFxString(invalid_pass_identifier_source, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_EQ(1, technique_list.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + EXPECT_EQ("", technique_list[0].pass[0].name); + EXPECT_EQ(shader_source, String("")); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseInvalidStateName) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + // NOTE: "FragmentShader" should read "FragmentProgram" or "PixelShader". + String invalid_pass_identifier_source = + "technique { pass { FragmentShader = compile ps_2_0 nothing(); } };"; + EXPECT_FALSE(ParseFxString(invalid_pass_identifier_source, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_EQ(1, technique_list.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + EXPECT_EQ("", technique_list[0].pass[0].name); + EXPECT_EQ(shader_source, String("")); + EXPECT_EQ(0, sampler_list.size()); +} + +TEST_F(TechniqueParserTest, ParseSampler) { + String shader_source, error_string; + TechniqueDeclarationList technique_list; + SamplerStateList sampler_list; + String filepath = *g_program_path + "/unittest_data/sampler_test.fx"; + EXPECT_TRUE(ParseFxFile(filepath, + &shader_source, + &sampler_list, + &technique_list, + &error_string)); + EXPECT_EQ(1, technique_list.size()); + ASSERT_EQ(1, technique_list[0].pass.size()); + ASSERT_EQ(1, sampler_list.size()); + EXPECT_EQ("Tex0", sampler_list[0].texture); + EXPECT_EQ("Linear", sampler_list[0].min_filter); + EXPECT_EQ("Point", sampler_list[0].mag_filter); + EXPECT_EQ("None", sampler_list[0].mip_filter); + EXPECT_EQ("Mirror", sampler_list[0].address_u); + EXPECT_EQ("Wrap", sampler_list[0].address_v); + EXPECT_EQ("Clamp", sampler_list[0].address_w); + EXPECT_EQ("16", sampler_list[0].max_anisotropy); + EXPECT_EQ("float4(1.0, 0.0, 0.0, 1.0)", sampler_list[0].border_color); +} + +} // namespace o3d |