Remove legacy object-id and depth-style binding fallbacks

This commit is contained in:
2026-04-05 13:38:50 +08:00
parent 10fda68694
commit f407e2d15c
4 changed files with 119 additions and 79 deletions

View File

@@ -267,45 +267,6 @@ inline Containers::Array<Resources::ShaderResourceBindingDesc> BuildLegacyBuilti
return bindings;
}
inline Containers::Array<Resources::ShaderResourceBindingDesc> BuildLegacyBuiltinObjectIdPassResourceBindings() {
Containers::Array<Resources::ShaderResourceBindingDesc> bindings;
bindings.Resize(1);
bindings[0].name = "PerObjectConstants";
bindings[0].type = Resources::ShaderResourceType::ConstantBuffer;
bindings[0].set = 0;
bindings[0].binding = 0;
bindings[0].semantic = "PerObject";
return bindings;
}
inline Containers::Array<Resources::ShaderResourceBindingDesc> BuildLegacyBuiltinDepthOnlyPassResourceBindings() {
Containers::Array<Resources::ShaderResourceBindingDesc> bindings;
bindings.Resize(1);
bindings[0].name = "PerObjectConstants";
bindings[0].type = Resources::ShaderResourceType::ConstantBuffer;
bindings[0].set = 0;
bindings[0].binding = 0;
bindings[0].semantic = "PerObject";
return bindings;
}
inline Containers::Array<Resources::ShaderResourceBindingDesc> BuildLegacyBuiltinShadowCasterPassResourceBindings() {
Containers::Array<Resources::ShaderResourceBindingDesc> bindings;
bindings.Resize(1);
bindings[0].name = "PerObjectConstants";
bindings[0].type = Resources::ShaderResourceType::ConstantBuffer;
bindings[0].set = 0;
bindings[0].binding = 0;
bindings[0].semantic = "PerObject";
return bindings;
}
inline bool IsBuiltinPassResourceTypeCompatible(
BuiltinPassResourceSemantic semantic,
Resources::ShaderResourceType type) {

View File

@@ -24,18 +24,6 @@ namespace Passes {
namespace {
Containers::Array<Resources::ShaderResourceBindingDesc> BuildLegacyBuiltinDepthStylePassResourceBindings(
BuiltinMaterialPass passType) {
switch (passType) {
case BuiltinMaterialPass::DepthOnly:
return BuildLegacyBuiltinDepthOnlyPassResourceBindings();
case BuiltinMaterialPass::ShadowCaster:
return BuildLegacyBuiltinShadowCasterPassResourceBindings();
default:
return {};
}
}
bool IsSupportedPerObjectOnlyBindingPlan(const BuiltinPassResourceBindingPlan& bindingPlan) {
return bindingPlan.perObject.IsValid() &&
bindingPlan.bindings.Size() == 1u &&
@@ -91,7 +79,7 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
ApplyMaterialRenderState(material, pipelineDesc);
pipelineDesc.blendState.blendEnable = false;
pipelineDesc.blendState.colorWriteMask = 0;
pipelineDesc.blendState.colorWriteMask = pipelineDesc.renderTargetCount > 0 ? 0xF : 0;
pipelineDesc.depthStencilState.depthTestEnable = true;
pipelineDesc.depthStencilState.depthWriteEnable = true;
pipelineDesc.depthStencilState.depthFunc = static_cast<uint32_t>(RHI::ComparisonFunc::LessEqual);
@@ -101,11 +89,9 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
shader.FindVariant(passName, Resources::ShaderType::Vertex, backend)) {
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(*vertexVariant, pipelineDesc.vertexShader);
}
if (pipelineDesc.renderTargetCount > 0) {
if (const Resources::ShaderStageVariant* fragmentVariant =
shader.FindVariant(passName, Resources::ShaderType::Fragment, backend)) {
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(*fragmentVariant, pipelineDesc.fragmentShader);
}
if (const Resources::ShaderStageVariant* fragmentVariant =
shader.FindVariant(passName, Resources::ShaderType::Fragment, backend)) {
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(*fragmentVariant, pipelineDesc.fragmentShader);
}
return pipelineDesc;
@@ -387,12 +373,16 @@ bool BuiltinDepthStylePassBase::TryBuildSupportedBindingPlan(
const Resources::ShaderPass& shaderPass,
BuiltinPassResourceBindingPlan& outPlan,
Containers::String* outError) const {
Containers::Array<Resources::ShaderResourceBindingDesc> resourceBindings = shaderPass.resources;
if (resourceBindings.Empty()) {
resourceBindings = BuildLegacyBuiltinDepthStylePassResourceBindings(m_passType);
if (shaderPass.resources.Empty()) {
if (outError != nullptr) {
*outError =
Containers::String("Builtin depth-style pass requires explicit resource bindings on shader pass: ") +
shaderPass.name;
}
return false;
}
if (!TryBuildBuiltinPassResourceBindingPlan(resourceBindings, outPlan, outError)) {
if (!TryBuildBuiltinPassResourceBindingPlan(shaderPass.resources, outPlan, outError)) {
return false;
}
@@ -463,7 +453,8 @@ BuiltinDepthStylePassBase::PassResourceLayout* BuiltinDepthStylePassBase::GetOrC
return failLayout("Builtin depth-style pass failed to create pipeline layout");
}
const auto result = m_passResourceLayouts.emplace(passLayoutKey, passLayout);
const auto result = m_passResourceLayouts.emplace(passLayoutKey, std::move(passLayout));
RefreshBuiltinPassSetLayoutMetadata(result.first->second.perObjectSetLayout);
return &result.first->second;
}
@@ -597,18 +588,29 @@ bool BuiltinDepthStylePassBase::DrawVisibleItem(
const RenderSceneData& sceneData,
const VisibleRenderItem& visibleItem) {
if (visibleItem.mesh == nullptr || visibleItem.gameObject == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinDepthStylePassBase skipped visible item because mesh or game object was null");
return false;
}
const RenderResourceCache::CachedMesh* cachedMesh =
m_resourceCache.GetOrCreateMesh(m_device, visibleItem.mesh);
if (cachedMesh == nullptr || cachedMesh->vertexBufferView == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinDepthStylePassBase failed to cache mesh for ") +
visibleItem.gameObject->GetName().c_str()).CStr());
return false;
}
const Resources::Material* material = ResolveMaterial(visibleItem);
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinDepthStylePassBase could not resolve shader pass for ") +
visibleItem.gameObject->GetName().c_str()).CStr());
return false;
}
@@ -618,11 +620,20 @@ bool BuiltinDepthStylePassBase::DrawVisibleItem(
PassResourceLayout* passLayout = GetOrCreatePassResourceLayout(context, resolvedShaderPass);
if (passLayout == nullptr || passLayout->pipelineLayout == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinDepthStylePassBase failed to create pass layout for ") +
visibleItem.gameObject->GetName().c_str()).CStr());
return false;
}
RHI::RHIPipelineState* pipelineState = GetOrCreatePipelineState(context, surface, material);
if (pipelineState == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinDepthStylePassBase failed to create pipeline state for ") +
visibleItem.gameObject->GetName().c_str() +
" using pass " + resolvedShaderPass.passName).CStr());
return false;
}
@@ -642,12 +653,24 @@ bool BuiltinDepthStylePassBase::DrawVisibleItem(
*passLayout,
visibleItem.gameObject->GetID());
if (constantSet == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinDepthStylePassBase failed to allocate descriptor set for ") +
visibleItem.gameObject->GetName().c_str()).CStr());
return false;
}
const Math::Matrix4x4 projectionMatrix =
m_passType == BuiltinMaterialPass::ShadowCaster
? sceneData.cameraData.viewProjection
: sceneData.cameraData.projection;
const Math::Matrix4x4 viewMatrix =
m_passType == BuiltinMaterialPass::ShadowCaster
? Math::Matrix4x4::Identity()
: sceneData.cameraData.view;
const PerObjectConstants constants = {
sceneData.cameraData.projection,
sceneData.cameraData.view,
projectionMatrix,
viewMatrix,
visibleItem.localToWorld.Transpose()
};
constantSet->WriteConstant(passLayout->perObject.binding, &constants, sizeof(constants));
@@ -662,6 +685,10 @@ bool BuiltinDepthStylePassBase::DrawVisibleItem(
if (visibleItem.hasSection) {
const Containers::Array<Resources::MeshSection>& sections = visibleItem.mesh->GetSections();
if (visibleItem.sectionIndex >= sections.Size()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinDepthStylePassBase received invalid mesh section for ") +
visibleItem.gameObject->GetName().c_str()).CStr());
return false;
}

View File

@@ -243,9 +243,14 @@ bool BuiltinObjectIdPass::CreateResources(const RenderContext& context) {
return false;
}
Containers::Array<Resources::ShaderResourceBindingDesc> resourceBindings = objectIdPass->resources;
const Containers::Array<Resources::ShaderResourceBindingDesc>& resourceBindings = objectIdPass->resources;
if (resourceBindings.Empty()) {
resourceBindings = BuildLegacyBuiltinObjectIdPassResourceBindings();
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinObjectIdPass requires explicit resource bindings on shader pass: ") +
objectIdPass->name).CStr());
DestroyResources();
return false;
}
BuiltinPassResourceBindingPlan bindingPlan = {};