chore: checkpoint current workspace changes

This commit is contained in:
2026-04-11 22:14:02 +08:00
parent 3e55f8c204
commit 8848cfd958
227 changed files with 34027 additions and 6711 deletions

View File

@@ -6,7 +6,8 @@
#include "RHI/RHICommandList.h"
#include "RHI/RHIDevice.h"
#include "Rendering/Builtin/BuiltinPassLayoutUtils.h"
#include "Rendering/Detail/ShaderVariantUtils.h"
#include "Rendering/Internal/RenderSurfacePipelineUtils.h"
#include "Rendering/Internal/ShaderVariantUtils.h"
#include "Rendering/FrameData/RenderSceneData.h"
#include "Rendering/FrameData/VisibleVolumeItem.h"
#include "Rendering/RenderSurface.h"
@@ -16,7 +17,9 @@
#include "Resources/Volume/VolumeField.h"
#include <algorithm>
#include <chrono>
#include <cstddef>
#include <string>
namespace XCEngine {
namespace Rendering {
@@ -24,6 +27,19 @@ namespace Passes {
namespace {
uint64_t GetVolumeTraceSteadyMs() {
using Clock = std::chrono::steady_clock;
static const Clock::time_point s_start = Clock::now();
return static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
Clock::now() - s_start).count());
}
void LogVolumeTraceRendering(const std::string& message) {
Containers::String entry("[VolumeTrace] ");
entry += message.c_str();
Debug::Logger::Get().Info(Debug::LogCategory::Rendering, entry);
}
bool IsDepthFormat(RHI::Format format) {
return format == RHI::Format::D24_UNorm_S8_UInt ||
format == RHI::Format::D32_Float;
@@ -45,7 +61,7 @@ const Resources::ShaderPass* FindCompatibleVolumePass(
const Resources::ShaderKeywordSet keywordSet = ResolvePassKeywordSet(sceneData, material);
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
if (ShaderPassMatchesBuiltinPass(shaderPass, BuiltinMaterialPass::Volumetric) &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(
::XCEngine::Rendering::Internal::ShaderPassHasGraphicsVariants(
shader,
shaderPass.name,
backend,
@@ -65,22 +81,22 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
const Containers::String& passName,
const Resources::ShaderKeywordSet& keywordSet,
const Resources::Material* material,
RHI::Format renderTargetFormat,
RHI::Format depthStencilFormat) {
const RenderSurface& surface) {
RHI::GraphicsPipelineDesc pipelineDesc = {};
pipelineDesc.pipelineLayout = pipelineLayout;
pipelineDesc.topologyType = static_cast<uint32_t>(RHI::PrimitiveTopologyType::Triangle);
pipelineDesc.renderTargetCount = 1;
pipelineDesc.renderTargetFormats[0] = static_cast<uint32_t>(renderTargetFormat);
pipelineDesc.depthStencilFormat = static_cast<uint32_t>(depthStencilFormat);
pipelineDesc.sampleCount = 1;
::XCEngine::Rendering::Internal::ApplySingleColorAttachmentPropertiesToGraphicsPipelineDesc(
surface,
pipelineDesc);
pipelineDesc.depthStencilFormat =
static_cast<uint32_t>(::XCEngine::Rendering::Internal::ResolveSurfaceDepthFormat(surface));
pipelineDesc.inputLayout = BuiltinVolumetricPass::BuildInputLayout();
ApplyResolvedRenderState(&shaderPass, material, pipelineDesc);
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(backendType);
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Internal::ToShaderBackend(backendType);
if (const Resources::ShaderStageVariant* vertexVariant =
shader.FindVariant(passName, Resources::ShaderType::Vertex, backend, keywordSet)) {
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
::XCEngine::Rendering::Internal::ApplyShaderStageVariant(
shader.GetPath(),
shaderPass,
backend,
@@ -89,7 +105,7 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
}
if (const Resources::ShaderStageVariant* fragmentVariant =
shader.FindVariant(passName, Resources::ShaderType::Fragment, backend, keywordSet)) {
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
::XCEngine::Rendering::Internal::ApplyShaderStageVariant(
shader.GetPath(),
shaderPass,
backend,
@@ -194,6 +210,38 @@ bool BuiltinVolumetricPass::Initialize(const RenderContext& context) {
return EnsureInitialized(context);
}
bool BuiltinVolumetricPass::PrepareVolumeResources(
const RenderContext& context,
const RenderSceneData& sceneData) {
if (!EnsureInitialized(context)) {
return false;
}
if (!sceneData.visibleVolumes.empty()) {
const RenderResourceCache::CachedMesh* cachedMesh =
m_resourceCache.GetOrCreateMesh(m_device, m_builtinCubeMesh.Get());
if (cachedMesh == nullptr || cachedMesh->vertexBufferView == nullptr) {
return false;
}
}
for (const VisibleVolumeItem& visibleVolume : sceneData.visibleVolumes) {
if (visibleVolume.volumeField == nullptr ||
visibleVolume.material == nullptr ||
visibleVolume.volumeField->GetStorageKind() != Resources::VolumeStorageKind::NanoVDB) {
continue;
}
const RenderResourceCache::CachedVolumeField* cachedVolume =
m_resourceCache.GetOrCreateVolumeField(m_device, visibleVolume.volumeField);
if (cachedVolume == nullptr || cachedVolume->shaderResourceView == nullptr) {
return false;
}
}
return true;
}
bool BuiltinVolumetricPass::Execute(const RenderPassContext& context) {
if (!context.renderContext.IsValid()) {
return false;
@@ -204,7 +252,10 @@ bool BuiltinVolumetricPass::Execute(const RenderPassContext& context) {
}
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
if (colorAttachments.empty() || colorAttachments[0] == nullptr || context.surface.GetDepthAttachment() == nullptr) {
if (!::XCEngine::Rendering::Internal::HasSingleColorAttachment(context.surface) ||
colorAttachments.empty() ||
colorAttachments[0] == nullptr ||
context.surface.GetDepthAttachment() == nullptr) {
return false;
}
@@ -213,7 +264,7 @@ bool BuiltinVolumetricPass::Execute(const RenderPassContext& context) {
return false;
}
if (!EnsureInitialized(context.renderContext)) {
if (!PrepareVolumeResources(context.renderContext, context.sceneData)) {
return false;
}
@@ -316,7 +367,7 @@ BuiltinVolumetricPass::ResolvedShaderPass BuiltinVolumetricPass::ResolveVolumeSh
}
const Resources::Shader* shader = material->GetShader();
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(m_backendType);
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Internal::ToShaderBackend(m_backendType);
if (const Resources::ShaderPass* shaderPass =
FindCompatibleVolumePass(*shader, sceneData, material, backend)) {
resolved.shader = shader;
@@ -343,6 +394,12 @@ BuiltinVolumetricPass::PassResourceLayout* BuiltinVolumetricPass::GetOrCreatePas
return &existing->second;
}
const uint64_t layoutStartMs = GetVolumeTraceSteadyMs();
LogVolumeTraceRendering(
"VolumetricPass layout create begin steady_ms=" + std::to_string(layoutStartMs) +
" shader=" + std::string(resolvedShaderPass.shader->GetPath().CStr()) +
" pass=" + std::string(resolvedShaderPass.passName.CStr()));
PassResourceLayout passLayout = {};
auto failLayout = [this, &passLayout](const char* message) -> PassResourceLayout* {
Debug::Logger::Get().Error(Debug::LogCategory::Rendering, message);
@@ -397,6 +454,12 @@ BuiltinVolumetricPass::PassResourceLayout* BuiltinVolumetricPass::GetOrCreatePas
const auto result = m_passResourceLayouts.emplace(passLayoutKey, passLayout);
PassResourceLayout& storedPassLayout = result.first->second;
RefreshBuiltinPassSetLayouts(storedPassLayout.setLayouts);
const uint64_t layoutEndMs = GetVolumeTraceSteadyMs();
LogVolumeTraceRendering(
"VolumetricPass layout create end steady_ms=" + std::to_string(layoutEndMs) +
" total_ms=" + std::to_string(layoutEndMs - layoutStartMs) +
" shader=" + std::string(resolvedShaderPass.shader->GetPath().CStr()) +
" pass=" + std::string(resolvedShaderPass.passName.CStr()));
return &storedPassLayout;
}
@@ -416,31 +479,35 @@ RHI::RHIPipelineState* BuiltinVolumetricPass::GetOrCreatePipelineState(
}
const Resources::ShaderKeywordSet keywordSet = ResolvePassKeywordSet(sceneData, material);
const std::vector<RHI::RHIResourceView*>& colorAttachments = surface.GetColorAttachments();
const RHI::Format renderTargetFormat =
(!colorAttachments.empty() && colorAttachments[0] != nullptr)
? colorAttachments[0]->GetFormat()
: RHI::Format::Unknown;
::XCEngine::Rendering::Internal::ResolveSurfaceColorFormat(surface, 0u);
const RHI::Format depthStencilFormat =
surface.GetDepthAttachment() != nullptr
? surface.GetDepthAttachment()->GetFormat()
: RHI::Format::Unknown;
::XCEngine::Rendering::Internal::ResolveSurfaceDepthFormat(surface);
PipelineStateKey pipelineKey = {};
pipelineKey.renderState =
BuildStaticPipelineRenderStateKey(ResolveEffectiveRenderState(resolvedShaderPass.pass, material));
pipelineKey.shader = resolvedShaderPass.shader;
pipelineKey.passName = resolvedShaderPass.passName;
pipelineKey.keywordSignature = ::XCEngine::Rendering::Detail::BuildShaderKeywordSignature(keywordSet);
pipelineKey.renderTargetCount = renderTargetFormat != RHI::Format::Unknown ? 1u : 0u;
pipelineKey.keywordSignature = ::XCEngine::Rendering::Internal::BuildShaderKeywordSignature(keywordSet);
pipelineKey.renderTargetCount =
::XCEngine::Rendering::Internal::HasSingleColorAttachment(surface) ? 1u : 0u;
pipelineKey.renderTargetFormat = static_cast<uint32_t>(renderTargetFormat);
pipelineKey.depthStencilFormat = static_cast<uint32_t>(depthStencilFormat);
pipelineKey.sampleCount = ::XCEngine::Rendering::Internal::ResolveSurfaceSampleCount(surface);
pipelineKey.sampleQuality = ::XCEngine::Rendering::Internal::ResolveSurfaceSampleQuality(surface);
const auto existing = m_pipelineStates.find(pipelineKey);
if (existing != m_pipelineStates.end()) {
return existing->second;
}
const uint64_t pipelineStartMs = GetVolumeTraceSteadyMs();
LogVolumeTraceRendering(
"VolumetricPass pipeline create begin steady_ms=" + std::to_string(pipelineStartMs) +
" shader=" + std::string(resolvedShaderPass.shader->GetPath().CStr()) +
" pass=" + std::string(resolvedShaderPass.passName.CStr()));
const RHI::GraphicsPipelineDesc pipelineDesc =
CreatePipelineDesc(
context.backendType,
@@ -450,18 +517,27 @@ RHI::RHIPipelineState* BuiltinVolumetricPass::GetOrCreatePipelineState(
resolvedShaderPass.passName,
keywordSet,
material,
renderTargetFormat,
depthStencilFormat);
surface);
RHI::RHIPipelineState* pipelineState = context.device->CreatePipelineState(pipelineDesc);
if (pipelineState == nullptr || !pipelineState->IsValid()) {
if (pipelineState != nullptr) {
pipelineState->Shutdown();
delete pipelineState;
}
LogVolumeTraceRendering(
"VolumetricPass pipeline create failed steady_ms=" + std::to_string(GetVolumeTraceSteadyMs()) +
" shader=" + std::string(resolvedShaderPass.shader->GetPath().CStr()) +
" pass=" + std::string(resolvedShaderPass.passName.CStr()));
return nullptr;
}
m_pipelineStates.emplace(pipelineKey, pipelineState);
const uint64_t pipelineEndMs = GetVolumeTraceSteadyMs();
LogVolumeTraceRendering(
"VolumetricPass pipeline create end steady_ms=" + std::to_string(pipelineEndMs) +
" total_ms=" + std::to_string(pipelineEndMs - pipelineStartMs) +
" shader=" + std::string(resolvedShaderPass.shader->GetPath().CStr()) +
" pass=" + std::string(resolvedShaderPass.passName.CStr()));
return pipelineState;
}