rendering: formalize shader keyword metadata contract

This commit is contained in:
2026-04-06 18:55:26 +08:00
parent 7acc397714
commit a8b4da16a3
16 changed files with 795 additions and 16 deletions

View File

@@ -7,6 +7,8 @@
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Core/Math/Vector4.h>
#include <initializer_list>
using namespace XCEngine::Resources;
using namespace XCEngine::Math;
@@ -41,6 +43,23 @@ Shader* CreateMaterialSchemaShader() {
return shader;
}
Shader* CreateMaterialKeywordShader(std::initializer_list<const char*> keywords) {
auto* shader = new Shader();
ShaderPass pass = {};
pass.name = "ForwardLit";
shader->AddPass(pass);
ShaderKeywordDeclaration declaration = {};
declaration.type = ShaderKeywordDeclarationType::ShaderFeatureLocal;
declaration.options.PushBack("_");
for (const char* keyword : keywords) {
declaration.options.PushBack(keyword);
}
shader->AddPassKeywordDeclaration("ForwardLit", declaration);
return shader;
}
TEST(Material, DefaultConstructor) {
Material material;
EXPECT_EQ(material.GetType(), ResourceType::Material);
@@ -534,4 +553,52 @@ TEST(Material, UpdateConstantBufferFollowsShaderSchemaOrderInsteadOfAlphabetical
EXPECT_FLOAT_EQ(secondSlot[0], 10.0f);
}
TEST(Material, KeywordsFormStableValidatedSet) {
Material material;
Shader* shader = CreateMaterialKeywordShader({"XC_MAIN_LIGHT_SHADOWS", "XC_ALPHA_TEST"});
material.SetShader(ResourceHandle<Shader>(shader));
material.EnableKeyword("XC_MAIN_LIGHT_SHADOWS");
material.EnableKeyword("XC_ALPHA_TEST");
material.EnableKeyword("XC_ALPHA_TEST");
material.EnableKeyword("_");
material.EnableKeyword("XC_UNKNOWN");
ASSERT_EQ(material.GetKeywordCount(), 2u);
EXPECT_EQ(material.GetKeyword(0), "XC_ALPHA_TEST");
EXPECT_EQ(material.GetKeyword(1), "XC_MAIN_LIGHT_SHADOWS");
EXPECT_TRUE(material.IsKeywordEnabled("XC_ALPHA_TEST"));
EXPECT_TRUE(material.IsKeywordEnabled("XC_MAIN_LIGHT_SHADOWS"));
EXPECT_FALSE(material.IsKeywordEnabled("XC_UNKNOWN"));
material.DisableKeyword("XC_ALPHA_TEST");
ASSERT_EQ(material.GetKeywordCount(), 1u);
EXPECT_EQ(material.GetKeyword(0), "XC_MAIN_LIGHT_SHADOWS");
material.ClearKeywords();
EXPECT_EQ(material.GetKeywordCount(), 0u);
}
TEST(Material, SwitchingShaderDropsUndeclaredKeywords) {
Material material;
Shader* shaderA = CreateMaterialKeywordShader({"XC_MAIN_LIGHT_SHADOWS", "XC_ALPHA_TEST"});
Shader* shaderB = CreateMaterialKeywordShader({"XC_ALPHA_TEST", "XC_EMISSION"});
material.SetShader(ResourceHandle<Shader>(shaderA));
material.EnableKeyword("XC_MAIN_LIGHT_SHADOWS");
material.EnableKeyword("XC_ALPHA_TEST");
ASSERT_EQ(material.GetKeywordCount(), 2u);
material.SetShader(ResourceHandle<Shader>(shaderB));
ASSERT_EQ(material.GetKeywordCount(), 1u);
EXPECT_FALSE(material.IsKeywordEnabled("XC_MAIN_LIGHT_SHADOWS"));
EXPECT_TRUE(material.IsKeywordEnabled("XC_ALPHA_TEST"));
material.EnableKeyword("XC_EMISSION");
ASSERT_EQ(material.GetKeywordCount(), 2u);
EXPECT_EQ(material.GetKeyword(0), "XC_ALPHA_TEST");
EXPECT_EQ(material.GetKeyword(1), "XC_EMISSION");
}
} // namespace