rendering: thread global shader keywords into builtin variants
This commit is contained in:
@@ -23,14 +23,22 @@ namespace {
|
||||
constexpr float kForwardAmbientIntensity = 0.28f;
|
||||
constexpr float kSpotInnerAngleRatio = 0.8f;
|
||||
|
||||
Resources::ShaderKeywordSet ResolvePassKeywordSet(
|
||||
const RenderSceneData& sceneData,
|
||||
const Resources::Material* material) {
|
||||
return Resources::CombineShaderKeywordSets(
|
||||
sceneData.globalShaderKeywords,
|
||||
material != nullptr ? material->GetKeywordSet() : Resources::ShaderKeywordSet());
|
||||
}
|
||||
|
||||
const Resources::ShaderPass* FindCompatibleSurfacePass(
|
||||
const Resources::Shader& shader,
|
||||
const RenderSceneData& sceneData,
|
||||
const Resources::Material* material,
|
||||
BuiltinMaterialPass pass,
|
||||
Resources::ShaderBackend backend) {
|
||||
const bool shaderHasExplicitBuiltinMetadata = ShaderHasExplicitBuiltinMetadata(shader);
|
||||
const Resources::ShaderKeywordSet keywordSet =
|
||||
material != nullptr ? material->GetKeywordSet() : Resources::ShaderKeywordSet();
|
||||
const Resources::ShaderKeywordSet keywordSet = ResolvePassKeywordSet(sceneData, material);
|
||||
|
||||
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
|
||||
if (ShaderPassMatchesBuiltinPass(shaderPass, pass) &&
|
||||
@@ -102,6 +110,7 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
|
||||
RHI::RHIPipelineLayout* pipelineLayout,
|
||||
const Resources::Shader& shader,
|
||||
const Containers::String& passName,
|
||||
const Resources::ShaderKeywordSet& keywordSet,
|
||||
const Resources::Material* material) {
|
||||
RHI::GraphicsPipelineDesc pipelineDesc = {};
|
||||
pipelineDesc.pipelineLayout = pipelineLayout;
|
||||
@@ -115,8 +124,6 @@ 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, keywordSet);
|
||||
const Resources::ShaderStageVariant* fragmentVariant =
|
||||
@@ -150,6 +157,7 @@ bool BuiltinForwardPipeline::TryResolveSurfacePassType(
|
||||
}
|
||||
|
||||
BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveSurfaceShaderPass(
|
||||
const RenderSceneData& sceneData,
|
||||
const Resources::Material* material) const {
|
||||
ResolvedShaderPass resolved = {};
|
||||
BuiltinMaterialPass pass = BuiltinMaterialPass::ForwardLit;
|
||||
@@ -162,7 +170,7 @@ BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveSurfac
|
||||
if (material != nullptr && material->GetShader() != nullptr) {
|
||||
const Resources::Shader* materialShader = material->GetShader();
|
||||
if (const Resources::ShaderPass* shaderPass =
|
||||
FindCompatibleSurfacePass(*materialShader, material, pass, backend)) {
|
||||
FindCompatibleSurfacePass(*materialShader, sceneData, material, pass, backend)) {
|
||||
resolved.shader = materialShader;
|
||||
resolved.pass = shaderPass;
|
||||
resolved.passName = shaderPass->name;
|
||||
@@ -175,7 +183,7 @@ BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveSurfac
|
||||
if (builtinShaderHandle->IsValid()) {
|
||||
const Resources::Shader* builtinShader = builtinShaderHandle->Get();
|
||||
if (const Resources::ShaderPass* shaderPass =
|
||||
FindCompatibleSurfacePass(*builtinShader, nullptr, pass, backend)) {
|
||||
FindCompatibleSurfacePass(*builtinShader, sceneData, nullptr, pass, backend)) {
|
||||
resolved.shader = builtinShader;
|
||||
resolved.pass = shaderPass;
|
||||
resolved.passName = shaderPass->name;
|
||||
@@ -274,8 +282,10 @@ BuiltinForwardPipeline::PassResourceLayout* BuiltinForwardPipeline::GetOrCreateP
|
||||
|
||||
RHI::RHIPipelineState* BuiltinForwardPipeline::GetOrCreatePipelineState(
|
||||
const RenderContext& context,
|
||||
const RenderSceneData& sceneData,
|
||||
const Resources::Material* material) {
|
||||
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
|
||||
const Resources::ShaderKeywordSet keywordSet = ResolvePassKeywordSet(sceneData, material);
|
||||
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(sceneData, material);
|
||||
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
@@ -293,9 +303,7 @@ 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());
|
||||
pipelineKey.keywordSignature = ::XCEngine::Rendering::Detail::BuildShaderKeywordSignature(keywordSet);
|
||||
|
||||
const auto existing = m_pipelineStates.find(pipelineKey);
|
||||
if (existing != m_pipelineStates.end()) {
|
||||
@@ -308,6 +316,7 @@ RHI::RHIPipelineState* BuiltinForwardPipeline::GetOrCreatePipelineState(
|
||||
passLayout->pipelineLayout,
|
||||
*resolvedShaderPass.shader,
|
||||
resolvedShaderPass.passName,
|
||||
keywordSet,
|
||||
material);
|
||||
RHI::RHIPipelineState* pipelineState = context.device->CreatePipelineState(pipelineDesc);
|
||||
if (pipelineState == nullptr || !pipelineState->IsValid()) {
|
||||
@@ -665,7 +674,7 @@ bool BuiltinForwardPipeline::DrawVisibleItem(
|
||||
};
|
||||
|
||||
const Resources::Material* material = ResolveMaterial(visibleItem);
|
||||
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
|
||||
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(sceneData, material);
|
||||
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user