Formalize builtin shader resource contracts

This commit is contained in:
2026-04-08 04:44:36 +08:00
parent 6113ed92b0
commit 2c1c815072
26 changed files with 358 additions and 368 deletions

View File

@@ -74,6 +74,19 @@ std::string EscapeRegexLiteralForTest(const std::string& value) {
<< source;
}
void AppendDefaultBuiltinPassResources(ShaderPass& pass) {
Array<ShaderResourceBindingDesc> bindings;
const bool resolved = TryBuildBuiltinPassDefaultResourceBindings(pass, bindings);
EXPECT_TRUE(resolved);
if (!resolved) {
return;
}
for (const ShaderResourceBindingDesc& binding : bindings) {
pass.resources.PushBack(binding);
}
}
} // namespace
TEST(BuiltinForwardPipeline_Test, UsesFloat3PositionInputLayoutForStaticMeshVertices) {
@@ -127,7 +140,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinForwardShaderUsesAuthoringSurfaceContra
const ShaderPass* pass = shader->FindPass("ForwardLit");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 8u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::Back);
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
@@ -156,7 +169,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinUnlitShaderUsesAuthoringSurfaceContract
const ShaderPass* pass = shader->FindPass("Unlit");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 4u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::Back);
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
@@ -602,7 +615,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinSkyboxShaderUsesAuthoringContract) {
const ShaderPass* pass = shader->FindPass("Skybox");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 5u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::None);
EXPECT_FALSE(pass->fixedFunctionState.depthWriteEnable);
@@ -636,7 +649,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinSkyboxShaderUsesAuthoringContract) {
delete shader;
}
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitSkyboxShaderContract) {
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedSkyboxShaderContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinSkyboxShaderPath());
ASSERT_TRUE(result);
@@ -674,7 +687,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinFinalColorShaderUsesAuthoringContract)
const ShaderPass* pass = shader->FindPass("FinalColor");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 3u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::None);
EXPECT_FALSE(pass->fixedFunctionState.depthWriteEnable);
@@ -699,7 +712,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinFinalColorShaderUsesAuthoringContract)
delete shader;
}
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitFinalColorShaderContract) {
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedFinalColorShaderContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinFinalColorShaderPath());
ASSERT_TRUE(result);
@@ -735,7 +748,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinColorScalePostProcessShaderUsesAuthorin
const ShaderPass* pass = shader->FindPass("ColorScale");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 3u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::None);
EXPECT_FALSE(pass->fixedFunctionState.depthWriteEnable);
@@ -748,7 +761,7 @@ TEST(BuiltinForwardPipeline_Test, BuiltinColorScalePostProcessShaderUsesAuthorin
delete shader;
}
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitColorScalePostProcessShaderContract) {
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedColorScalePostProcessShaderContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinColorScalePostProcessShaderPath());
ASSERT_TRUE(result);
@@ -806,11 +819,11 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesAuthoringFinal
"register(b0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
d3d12Source,
"Texture2D gSourceColorTexture",
"Texture2D SourceColorTexture",
"register(t0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
d3d12Source,
"SamplerState gLinearClampSampler",
"SamplerState LinearClampSampler",
"register(s0)"));
EXPECT_EQ(d3d12Source.find("space0"), std::string::npos);
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
@@ -832,11 +845,11 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesAuthoringFinal
"register(b0, space0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
runtimeSource,
"Texture2D gSourceColorTexture",
"Texture2D SourceColorTexture",
"register(t0, space1)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
runtimeSource,
"SamplerState gLinearClampSampler",
"SamplerState LinearClampSampler",
"register(s0, space2)"));
ShaderCompileDesc vulkanCompileDesc = {};
@@ -932,11 +945,11 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesAuthoringColor
"register(b0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
d3d12Source,
"Texture2D gSourceColorTexture",
"Texture2D SourceColorTexture",
"register(t0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
d3d12Source,
"SamplerState gLinearClampSampler",
"SamplerState LinearClampSampler",
"register(s0)"));
EXPECT_EQ(d3d12Source.find("space0"), std::string::npos);
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
@@ -958,11 +971,11 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesAuthoringColor
"register(b0, space0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
runtimeSource,
"Texture2D gSourceColorTexture",
"Texture2D SourceColorTexture",
"register(t0, space1)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
runtimeSource,
"SamplerState gLinearClampSampler",
"SamplerState LinearClampSampler",
"register(s0, space2)"));
ShaderCompileDesc vulkanCompileDesc = {};
@@ -974,7 +987,7 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesAuthoringColor
const std::string vulkanSource(
reinterpret_cast<const char*>(vulkanCompileDesc.source.data()),
vulkanCompileDesc.source.size());
EXPECT_NE(vulkanSource.find("gSourceColorTexture.Sample"), std::string::npos);
EXPECT_NE(vulkanSource.find("SourceColorTexture.Sample"), std::string::npos);
EXPECT_NE(vulkanSource.find("gColorScale"), std::string::npos);
delete shader;
@@ -1025,7 +1038,7 @@ TEST(BuiltinForwardPipeline_Test, OpenGLRuntimeTranspilesColorScaleVariantToComb
delete shader;
}
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedImplicitForwardShader) {
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedForwardShaderContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinForwardLitShaderPath());
ASSERT_TRUE(result);
@@ -1065,6 +1078,7 @@ TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromBuilti
tag.name = "LightMode";
tag.value = "ForwardBase";
pass.tags.PushBack(tag);
AppendDefaultBuiltinPassResources(pass);
BuiltinPassResourceBindingPlan plan = {};
String error;
@@ -1081,7 +1095,7 @@ TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromBuilti
EXPECT_EQ(plan.descriptorSetCount, 8u);
}
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitUnlitContract) {
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedUnlitShaderContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinUnlitShaderPath());
ASSERT_TRUE(result);
@@ -1109,7 +1123,7 @@ TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromImplic
delete shader;
}
TEST(BuiltinForwardPipeline_Test, UsesNormalizedImplicitSetIndicesForForwardSurfaceResources) {
TEST(BuiltinForwardPipeline_Test, UsesLoadedForwardShaderResourceSetIndices) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinForwardLitShaderPath());
ASSERT_TRUE(result);
@@ -1120,7 +1134,7 @@ TEST(BuiltinForwardPipeline_Test, UsesNormalizedImplicitSetIndicesForForwardSurf
const ShaderPass* pass = shader->FindPass("ForwardLit");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 8u);
BuiltinPassResourceBindingPlan plan = {};
String error;
@@ -1138,7 +1152,7 @@ TEST(BuiltinForwardPipeline_Test, UsesNormalizedImplicitSetIndicesForForwardSurf
delete shader;
}
TEST(BuiltinPassLayout_Test, BuildsSharedSetLayoutsFromImplicitForwardResources) {
TEST(BuiltinPassLayout_Test, BuildsSharedSetLayoutsFromLoadedForwardShaderResources) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinForwardLitShaderPath());
ASSERT_TRUE(result);
@@ -1149,7 +1163,7 @@ TEST(BuiltinPassLayout_Test, BuildsSharedSetLayoutsFromImplicitForwardResources)
const ShaderPass* pass = shader->FindPass("ForwardLit");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 8u);
BuiltinPassResourceBindingPlan plan = {};
String error;
@@ -1209,7 +1223,7 @@ TEST(BuiltinDepthStylePass_Test, BuiltinDepthOnlyShaderUsesAuthoringContract) {
const ShaderPass* pass = shader->FindPass("DepthOnly");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 4u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::Back);
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
@@ -1229,7 +1243,7 @@ TEST(BuiltinDepthStylePass_Test, BuiltinShadowCasterShaderUsesAuthoringContract)
const ShaderPass* pass = shader->FindPass("ShadowCaster");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 4u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::Back);
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
@@ -1249,7 +1263,7 @@ TEST(BuiltinObjectIdPass_Test, BuiltinObjectIdShaderUsesAuthoringContract) {
const ShaderPass* pass = shader->FindPass("ObjectId");
ASSERT_NE(pass, nullptr);
EXPECT_TRUE(pass->resources.Empty());
EXPECT_EQ(pass->resources.Size(), 1u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::Back);
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
@@ -1287,7 +1301,7 @@ TEST(BuiltinObjectIdPass_Test, BuildsBuiltinPassResourceBindingPlanFromBuiltinOb
delete shader;
}
TEST(BuiltinObjectIdPass_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitObjectIdContract) {
TEST(BuiltinObjectIdPass_Test, BuildsBuiltinPassResourceBindingPlanFromExplicitObjectIdContract) {
ShaderPass pass = {};
pass.name = "ObjectId";
@@ -1295,6 +1309,7 @@ TEST(BuiltinObjectIdPass_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitO
tag.name = "LightMode";
tag.value = "ObjectId";
pass.tags.PushBack(tag);
AppendDefaultBuiltinPassResources(pass);
BuiltinPassResourceBindingPlan plan = {};
String error;
@@ -1306,7 +1321,7 @@ TEST(BuiltinObjectIdPass_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitO
EXPECT_EQ(plan.descriptorSetCount, 1u);
}
TEST(BuiltinDepthStylePass_Test, BuildsBuiltinPassResourceBindingPlanFromImplicitDepthOnlyContract) {
TEST(BuiltinDepthStylePass_Test, BuildsBuiltinPassResourceBindingPlanFromExplicitDepthOnlyContract) {
ShaderPass pass = {};
pass.name = "DepthOnly";
@@ -1314,6 +1329,7 @@ TEST(BuiltinDepthStylePass_Test, BuildsBuiltinPassResourceBindingPlanFromImplici
tag.name = "LightMode";
tag.value = "DepthOnly";
pass.tags.PushBack(tag);
AppendDefaultBuiltinPassResources(pass);
BuiltinPassResourceBindingPlan plan = {};
String error;