rendering: add keyword-aware shader variant selection
This commit is contained in:
@@ -144,6 +144,88 @@ TEST(Shader, FindsBackendSpecificVariantAndFallsBackToGeneric) {
|
||||
EXPECT_EQ(openglVariant->sourceCode, "generic fragment");
|
||||
}
|
||||
|
||||
TEST(Shader, FindsMostSpecificKeywordVariantAndPrefersExactBackend) {
|
||||
Shader shader;
|
||||
|
||||
ShaderStageVariant baseFragment = {};
|
||||
baseFragment.stage = ShaderType::Fragment;
|
||||
baseFragment.language = ShaderLanguage::GLSL;
|
||||
baseFragment.backend = ShaderBackend::Generic;
|
||||
baseFragment.sourceCode = "generic base";
|
||||
shader.AddPassVariant("ForwardLit", baseFragment);
|
||||
|
||||
ShaderStageVariant genericKeywordFragment = {};
|
||||
genericKeywordFragment.stage = ShaderType::Fragment;
|
||||
genericKeywordFragment.language = ShaderLanguage::GLSL;
|
||||
genericKeywordFragment.backend = ShaderBackend::Generic;
|
||||
genericKeywordFragment.requiredKeywords.enabledKeywords.PushBack("XC_DEBUG");
|
||||
genericKeywordFragment.requiredKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
|
||||
genericKeywordFragment.requiredKeywords.enabledKeywords.PushBack("XC_DEBUG");
|
||||
genericKeywordFragment.sourceCode = "generic keyword";
|
||||
shader.AddPassVariant("ForwardLit", genericKeywordFragment);
|
||||
|
||||
ShaderStageVariant d3d12KeywordFragment = {};
|
||||
d3d12KeywordFragment.stage = ShaderType::Fragment;
|
||||
d3d12KeywordFragment.language = ShaderLanguage::HLSL;
|
||||
d3d12KeywordFragment.backend = ShaderBackend::D3D12;
|
||||
d3d12KeywordFragment.requiredKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
|
||||
d3d12KeywordFragment.sourceCode = "d3d12 keyword";
|
||||
shader.AddPassVariant("ForwardLit", d3d12KeywordFragment);
|
||||
|
||||
ShaderKeywordSet enabledKeywords = {};
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_DEBUG");
|
||||
|
||||
const ShaderStageVariant* d3d12Variant =
|
||||
shader.FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::D3D12,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(d3d12Variant, nullptr);
|
||||
EXPECT_EQ(d3d12Variant->sourceCode, "d3d12 keyword");
|
||||
|
||||
const ShaderStageVariant* openglVariant =
|
||||
shader.FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::OpenGL,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(openglVariant, nullptr);
|
||||
EXPECT_EQ(openglVariant->sourceCode, "generic keyword");
|
||||
ASSERT_EQ(openglVariant->requiredKeywords.enabledKeywords.Size(), 2u);
|
||||
EXPECT_EQ(openglVariant->requiredKeywords.enabledKeywords[0], "XC_ALPHA_TEST");
|
||||
EXPECT_EQ(openglVariant->requiredKeywords.enabledKeywords[1], "XC_DEBUG");
|
||||
}
|
||||
|
||||
TEST(Shader, RejectsVariantWhenRequiredKeywordsAreMissing) {
|
||||
Shader shader;
|
||||
|
||||
ShaderStageVariant keywordFragment = {};
|
||||
keywordFragment.stage = ShaderType::Fragment;
|
||||
keywordFragment.language = ShaderLanguage::GLSL;
|
||||
keywordFragment.backend = ShaderBackend::OpenGL;
|
||||
keywordFragment.requiredKeywords.enabledKeywords.PushBack("XC_CLIP");
|
||||
keywordFragment.sourceCode = "clip fragment";
|
||||
shader.AddPassVariant("ForwardLit", keywordFragment);
|
||||
|
||||
EXPECT_EQ(
|
||||
shader.FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::OpenGL),
|
||||
nullptr);
|
||||
|
||||
ShaderKeywordSet enabledKeywords = {};
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_CLIP");
|
||||
|
||||
const ShaderStageVariant* matchedVariant =
|
||||
shader.FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::OpenGL,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(matchedVariant, nullptr);
|
||||
EXPECT_EQ(matchedVariant->sourceCode, "clip fragment");
|
||||
}
|
||||
|
||||
TEST(Shader, StoresPerPassTags) {
|
||||
Shader shader;
|
||||
shader.SetPassTag("ForwardLit", "LightMode", "ForwardBase");
|
||||
|
||||
Reference in New Issue
Block a user