rendering: add builtin alpha-test pass support

This commit is contained in:
2026-04-06 21:05:50 +08:00
parent eea38d57d1
commit 9568cf0a16
26 changed files with 856 additions and 104 deletions

View File

@@ -1334,8 +1334,8 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsBackendVariants) {
const ShaderPass* pass = shader->FindPass("ForwardLit");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(shader->GetProperties().Size(), 2u);
ASSERT_EQ(pass->variants.Size(), 12u);
ASSERT_EQ(shader->GetProperties().Size(), 3u);
ASSERT_EQ(pass->variants.Size(), 24u);
ASSERT_EQ(pass->tags.Size(), 1u);
ASSERT_EQ(pass->resources.Size(), 8u);
EXPECT_EQ(pass->tags[0].name, "LightMode");
@@ -1351,6 +1351,11 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsBackendVariants) {
EXPECT_EQ(baseMapProperty->type, ShaderPropertyType::Texture2D);
EXPECT_EQ(baseMapProperty->semantic, "BaseColorTexture");
const ShaderPropertyDesc* cutoffProperty = shader->FindProperty("_Cutoff");
ASSERT_NE(cutoffProperty, nullptr);
EXPECT_EQ(cutoffProperty->type, ShaderPropertyType::Range);
EXPECT_EQ(cutoffProperty->semantic, "AlphaCutoff");
const ShaderResourceBindingDesc* perObjectBinding =
shader->FindPassResourceBinding("ForwardLit", "PerObjectConstants");
ASSERT_NE(perObjectBinding, nullptr);
@@ -1390,13 +1395,18 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsBackendVariants) {
EXPECT_EQ(shadowTextureBinding->set, 6u);
EXPECT_EQ(shadowTextureBinding->binding, 0u);
EXPECT_EQ(shadowTextureBinding->semantic, "ShadowMapTexture");
ASSERT_EQ(pass->keywordDeclarations.Size(), 1u);
ASSERT_EQ(pass->keywordDeclarations.Size(), 2u);
EXPECT_EQ(pass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::MultiCompile);
ASSERT_EQ(pass->keywordDeclarations[0].options.Size(), 2u);
EXPECT_EQ(pass->keywordDeclarations[0].options[0], "_");
EXPECT_EQ(pass->keywordDeclarations[0].options[1], "XC_MAIN_LIGHT_SHADOWS");
EXPECT_EQ(pass->keywordDeclarations[1].type, ShaderKeywordDeclarationType::ShaderFeatureLocal);
ASSERT_EQ(pass->keywordDeclarations[1].options.Size(), 2u);
EXPECT_EQ(pass->keywordDeclarations[1].options[0], "_");
EXPECT_EQ(pass->keywordDeclarations[1].options[1], "XC_ALPHA_TEST");
EXPECT_TRUE(shader->PassDeclaresKeyword("ForwardLit", "XC_MAIN_LIGHT_SHADOWS"));
ASSERT_EQ(pass->variants.Size(), 12u);
EXPECT_TRUE(shader->PassDeclaresKeyword("ForwardLit", "XC_ALPHA_TEST"));
ASSERT_EQ(pass->variants.Size(), 24u);
EXPECT_NE(shader->FindVariant("ForwardLit", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
EXPECT_NE(shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
@@ -1437,6 +1447,23 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsBackendVariants) {
std::string(shadowD3D12Fragment->sourceCode.CStr()).find("gShadowMapTexture.Sample"),
std::string::npos);
ShaderKeywordSet alphaShadowKeywords = {};
alphaShadowKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
alphaShadowKeywords.enabledKeywords.PushBack("XC_MAIN_LIGHT_SHADOWS");
const ShaderStageVariant* alphaShadowD3D12Fragment = shader->FindVariant(
"ForwardLit",
ShaderType::Fragment,
ShaderBackend::D3D12,
alphaShadowKeywords);
ASSERT_NE(alphaShadowD3D12Fragment, nullptr);
EXPECT_NE(
std::string(alphaShadowD3D12Fragment->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
std::string::npos);
EXPECT_NE(
std::string(alphaShadowD3D12Fragment->sourceCode.CStr()).find("gAlphaCutoffParams"),
std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant(
"ForwardLit",
ShaderType::Fragment,
@@ -1591,15 +1618,33 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsBackendVariants) {
const ShaderPass* pass = shader->FindPass("DepthOnly");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(pass->resources.Size(), 1u);
ASSERT_EQ(shader->GetProperties().Size(), 3u);
ASSERT_EQ(pass->resources.Size(), 4u);
EXPECT_EQ(pass->resources[0].semantic, "PerObject");
EXPECT_EQ(pass->resources[0].type, ShaderResourceType::ConstantBuffer);
EXPECT_EQ(pass->resources[0].set, 0u);
EXPECT_EQ(pass->resources[0].binding, 0u);
ASSERT_EQ(pass->variants.Size(), 6u);
EXPECT_EQ(pass->resources[1].semantic, "Material");
EXPECT_EQ(pass->resources[1].type, ShaderResourceType::ConstantBuffer);
EXPECT_EQ(pass->resources[1].set, 1u);
EXPECT_EQ(pass->resources[1].binding, 0u);
EXPECT_EQ(pass->resources[2].semantic, "BaseColorTexture");
EXPECT_EQ(pass->resources[2].type, ShaderResourceType::Texture2D);
EXPECT_EQ(pass->resources[2].set, 2u);
EXPECT_EQ(pass->resources[2].binding, 0u);
EXPECT_EQ(pass->resources[3].semantic, "LinearClampSampler");
EXPECT_EQ(pass->resources[3].type, ShaderResourceType::Sampler);
EXPECT_EQ(pass->resources[3].set, 3u);
EXPECT_EQ(pass->resources[3].binding, 0u);
ASSERT_EQ(pass->variants.Size(), 12u);
ASSERT_EQ(pass->tags.Size(), 1u);
EXPECT_EQ(pass->tags[0].name, "LightMode");
EXPECT_EQ(pass->tags[0].value, "DepthOnly");
ASSERT_EQ(pass->keywordDeclarations.Size(), 1u);
EXPECT_EQ(pass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::ShaderFeatureLocal);
ASSERT_EQ(pass->keywordDeclarations[0].options.Size(), 2u);
EXPECT_EQ(pass->keywordDeclarations[0].options[0], "_");
EXPECT_EQ(pass->keywordDeclarations[0].options[1], "XC_ALPHA_TEST");
EXPECT_NE(shader->FindVariant("DepthOnly", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
EXPECT_NE(shader->FindVariant("DepthOnly", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
@@ -1629,6 +1674,22 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsBackendVariants) {
ASSERT_NE(vulkanFragment, nullptr);
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("XC_BUILTIN_DEPTH_ONLY_VULKAN_PS"), std::string::npos);
ShaderKeywordSet alphaKeywords = {};
alphaKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
const ShaderStageVariant* alphaD3D12Fragment = shader->FindVariant(
"DepthOnly",
ShaderType::Fragment,
ShaderBackend::D3D12,
alphaKeywords);
ASSERT_NE(alphaD3D12Fragment, nullptr);
EXPECT_NE(
std::string(alphaD3D12Fragment->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
std::string::npos);
EXPECT_NE(
std::string(alphaD3D12Fragment->sourceCode.CStr()).find("gAlphaCutoffParams"),
std::string::npos);
delete shader;
}
@@ -1644,15 +1705,33 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsBackendVariants) {
const ShaderPass* pass = shader->FindPass("ShadowCaster");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(pass->resources.Size(), 1u);
ASSERT_EQ(shader->GetProperties().Size(), 3u);
ASSERT_EQ(pass->resources.Size(), 4u);
EXPECT_EQ(pass->resources[0].semantic, "PerObject");
EXPECT_EQ(pass->resources[0].type, ShaderResourceType::ConstantBuffer);
EXPECT_EQ(pass->resources[0].set, 0u);
EXPECT_EQ(pass->resources[0].binding, 0u);
ASSERT_EQ(pass->variants.Size(), 6u);
EXPECT_EQ(pass->resources[1].semantic, "Material");
EXPECT_EQ(pass->resources[1].type, ShaderResourceType::ConstantBuffer);
EXPECT_EQ(pass->resources[1].set, 1u);
EXPECT_EQ(pass->resources[1].binding, 0u);
EXPECT_EQ(pass->resources[2].semantic, "BaseColorTexture");
EXPECT_EQ(pass->resources[2].type, ShaderResourceType::Texture2D);
EXPECT_EQ(pass->resources[2].set, 2u);
EXPECT_EQ(pass->resources[2].binding, 0u);
EXPECT_EQ(pass->resources[3].semantic, "LinearClampSampler");
EXPECT_EQ(pass->resources[3].type, ShaderResourceType::Sampler);
EXPECT_EQ(pass->resources[3].set, 3u);
EXPECT_EQ(pass->resources[3].binding, 0u);
ASSERT_EQ(pass->variants.Size(), 12u);
ASSERT_EQ(pass->tags.Size(), 1u);
EXPECT_EQ(pass->tags[0].name, "LightMode");
EXPECT_EQ(pass->tags[0].value, "ShadowCaster");
ASSERT_EQ(pass->keywordDeclarations.Size(), 1u);
EXPECT_EQ(pass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::ShaderFeatureLocal);
ASSERT_EQ(pass->keywordDeclarations[0].options.Size(), 2u);
EXPECT_EQ(pass->keywordDeclarations[0].options[0], "_");
EXPECT_EQ(pass->keywordDeclarations[0].options[1], "XC_ALPHA_TEST");
EXPECT_NE(shader->FindVariant("ShadowCaster", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
EXPECT_NE(shader->FindVariant("ShadowCaster", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
@@ -1688,6 +1767,22 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsBackendVariants) {
std::string(vulkanFragment->sourceCode.CStr()).find("XC_BUILTIN_SHADOW_CASTER_VULKAN_PS"),
std::string::npos);
ShaderKeywordSet alphaKeywords = {};
alphaKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
const ShaderStageVariant* alphaD3D12Fragment = shader->FindVariant(
"ShadowCaster",
ShaderType::Fragment,
ShaderBackend::D3D12,
alphaKeywords);
ASSERT_NE(alphaD3D12Fragment, nullptr);
EXPECT_NE(
std::string(alphaD3D12Fragment->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
std::string::npos);
EXPECT_NE(
std::string(alphaD3D12Fragment->sourceCode.CStr()).find("gAlphaCutoffParams"),
std::string::npos);
delete shader;
}