rendering: generate single-source shader keyword variants

This commit is contained in:
2026-04-06 19:58:49 +08:00
parent 261dd44fd5
commit f16620afc6
2 changed files with 156 additions and 30 deletions

View File

@@ -532,7 +532,7 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVar
EXPECT_TRUE(shader->PassDeclaresKeyword("ForwardLit", "XC_MAIN_LIGHT_SHADOWS"));
EXPECT_TRUE(shader->DeclaresKeyword("XC_ALPHA_TEST"));
EXPECT_FALSE(shader->DeclaresKeyword("_"));
ASSERT_EQ(pass->variants.Size(), 2u);
ASSERT_EQ(pass->variants.Size(), 8u);
const ShaderStageVariant* vertexVariant =
shader->FindVariant("ForwardLit", ShaderType::Vertex, ShaderBackend::D3D12);
@@ -543,6 +543,8 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVar
EXPECT_EQ(vertexVariant->profile, "vs_5_0");
EXPECT_NE(std::string(vertexVariant->sourceCode.CStr()).find("#include \"shaderlib/shared.hlsl\""), std::string::npos);
EXPECT_NE(std::string(vertexVariant->sourceCode.CStr()).find("XC_SINGLE_SOURCE_FRAG_BODY"), std::string::npos);
EXPECT_EQ(vertexVariant->requiredKeywords.enabledKeywords.Size(), 0u);
EXPECT_EQ(std::string(vertexVariant->sourceCode.CStr()).find("#pragma multi_compile"), std::string::npos);
const ShaderStageVariant* fragmentVariant =
shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::D3D12);
@@ -552,6 +554,24 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVar
EXPECT_EQ(fragmentVariant->entryPoint, "Frag");
EXPECT_EQ(fragmentVariant->profile, "ps_5_0");
ShaderKeywordSet enabledKeywords = {};
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
enabledKeywords.enabledKeywords.PushBack("XC_MAIN_LIGHT_SHADOWS");
const ShaderStageVariant* keywordFragmentVariant =
shader->FindVariant(
"ForwardLit",
ShaderType::Fragment,
ShaderBackend::D3D12,
enabledKeywords);
ASSERT_NE(keywordFragmentVariant, nullptr);
ASSERT_EQ(keywordFragmentVariant->requiredKeywords.enabledKeywords.Size(), 2u);
EXPECT_EQ(keywordFragmentVariant->requiredKeywords.enabledKeywords[0], "XC_ALPHA_TEST");
EXPECT_EQ(keywordFragmentVariant->requiredKeywords.enabledKeywords[1], "XC_MAIN_LIGHT_SHADOWS");
EXPECT_NE(std::string(keywordFragmentVariant->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"), std::string::npos);
EXPECT_NE(std::string(keywordFragmentVariant->sourceCode.CStr()).find("#define XC_MAIN_LIGHT_SHADOWS 1"), std::string::npos);
EXPECT_EQ(std::string(keywordFragmentVariant->sourceCode.CStr()).find("#pragma shader_feature_local"), std::string::npos);
Array<String> dependencies;
ASSERT_TRUE(loader.CollectSourceDependencies(shaderPath.string().c_str(), dependencies));
ASSERT_EQ(dependencies.Size(), 1u);
@@ -855,9 +875,29 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromSingleSourceAuthoringPr
const ShaderPass* pass = shader->FindPass("ForwardLit");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(pass->keywordDeclarations.Size(), 2u);
ASSERT_EQ(pass->variants.Size(), 8u);
EXPECT_EQ(pass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::MultiCompile);
EXPECT_EQ(pass->keywordDeclarations[1].type, ShaderKeywordDeclarationType::ShaderFeatureLocal);
ShaderKeywordSet enabledKeywords = {};
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
enabledKeywords.enabledKeywords.PushBack("XC_MAIN_LIGHT_SHADOWS");
const ShaderStageVariant* keywordFragmentVariant =
shader->FindVariant(
"ForwardLit",
ShaderType::Fragment,
ShaderBackend::D3D12,
enabledKeywords);
ASSERT_NE(keywordFragmentVariant, nullptr);
ASSERT_EQ(keywordFragmentVariant->requiredKeywords.enabledKeywords.Size(), 2u);
EXPECT_NE(
std::string(keywordFragmentVariant->sourceCode.CStr()).find("#define XC_MAIN_LIGHT_SHADOWS 1"),
std::string::npos);
EXPECT_NE(
std::string(keywordFragmentVariant->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
std::string::npos);
delete shader;
database.Shutdown();
fs::remove_all(projectRoot);