rendering: add keyword-aware shader variant selection

This commit is contained in:
2026-04-06 19:37:01 +08:00
parent a8b4da16a3
commit 261dd44fd5
26 changed files with 469 additions and 76 deletions

View File

@@ -29,10 +29,16 @@ const Resources::ShaderPass* FindCompatibleSurfacePass(
BuiltinMaterialPass pass,
Resources::ShaderBackend backend) {
const bool shaderHasExplicitBuiltinMetadata = ShaderHasExplicitBuiltinMetadata(shader);
const Resources::ShaderKeywordSet keywordSet =
material != nullptr ? material->GetKeywordSet() : Resources::ShaderKeywordSet();
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
if (ShaderPassMatchesBuiltinPass(shaderPass, pass) &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, shaderPass.name, backend)) {
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
shaderPass.name,
backend,
keywordSet)) {
return &shaderPass;
}
}
@@ -42,7 +48,11 @@ const Resources::ShaderPass* FindCompatibleSurfacePass(
!material->GetShaderPass().Empty()) {
const Resources::ShaderPass* explicitPass = shader.FindPass(material->GetShaderPass());
if (explicitPass != nullptr &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, explicitPass->name, backend)) {
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
explicitPass->name,
backend,
keywordSet)) {
return explicitPass;
}
}
@@ -57,18 +67,30 @@ const Resources::ShaderPass* FindCompatibleSurfacePass(
const Resources::ShaderPass* defaultPass = shader.FindPass("ForwardLit");
if (defaultPass != nullptr &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, defaultPass->name, backend)) {
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
defaultPass->name,
backend,
keywordSet)) {
return defaultPass;
}
defaultPass = shader.FindPass("Default");
if (defaultPass != nullptr &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, defaultPass->name, backend)) {
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
defaultPass->name,
backend,
keywordSet)) {
return defaultPass;
}
if (shader.GetPassCount() > 0 &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, shader.GetPasses()[0].name, backend)) {
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
shader,
shader.GetPasses()[0].name,
backend,
keywordSet)) {
return &shader.GetPasses()[0];
}
@@ -93,10 +115,12 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
pipelineDesc.inputLayout = BuiltinForwardPipeline::BuildInputLayout();
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(backendType);
const Resources::ShaderKeywordSet keywordSet =
material != nullptr ? material->GetKeywordSet() : Resources::ShaderKeywordSet();
const Resources::ShaderStageVariant* vertexVariant =
shader.FindVariant(passName, Resources::ShaderType::Vertex, backend);
shader.FindVariant(passName, Resources::ShaderType::Vertex, backend, keywordSet);
const Resources::ShaderStageVariant* fragmentVariant =
shader.FindVariant(passName, Resources::ShaderType::Fragment, backend);
shader.FindVariant(passName, Resources::ShaderType::Fragment, backend, keywordSet);
if (vertexVariant != nullptr) {
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(*vertexVariant, pipelineDesc.vertexShader);
}
@@ -269,6 +293,9 @@ RHI::RHIPipelineState* BuiltinForwardPipeline::GetOrCreatePipelineState(
material != nullptr ? material->GetRenderState() : Resources::MaterialRenderState();
pipelineKey.shader = resolvedShaderPass.shader;
pipelineKey.passName = resolvedShaderPass.passName;
pipelineKey.keywordSignature =
::XCEngine::Rendering::Detail::BuildShaderKeywordSignature(
material != nullptr ? material->GetKeywordSet() : Resources::ShaderKeywordSet());
const auto existing = m_pipelineStates.find(pipelineKey);
if (existing != m_pipelineStates.end()) {