Files
XCEngine/engine/src/Rendering/Passes/BuiltinDepthStylePassBase.cpp

184 lines
6.2 KiB
C++

#include "Rendering/Passes/BuiltinDepthStylePassBase.h"
#include "RHI/RHICommandList.h"
#include "Rendering/Extraction/RenderSceneExtractor.h"
#include "Rendering/FrameData/RendererListUtils.h"
#include "Rendering/Internal/RenderSurfacePipelineUtils.h"
#include "Rendering/RenderSurface.h"
#include "Resources/Mesh/Mesh.h"
#include <cstddef>
#include <utility>
namespace XCEngine {
namespace Rendering {
namespace Passes {
BuiltinDepthStylePassBase::BuiltinDepthStylePassBase(
BuiltinMaterialPass passType,
Containers::String builtinShaderPath)
: m_passType(passType)
, m_builtinShaderPath(std::move(builtinShaderPath)) {
}
BuiltinDepthStylePassBase::~BuiltinDepthStylePassBase() {
Shutdown();
}
RHI::InputLayoutDesc BuiltinDepthStylePassBase::BuildCommonInputLayout() {
RHI::InputLayoutDesc inputLayout = {};
RHI::InputElementDesc position = {};
position.semanticName = "POSITION";
position.semanticIndex = 0;
position.format = static_cast<uint32_t>(RHI::Format::R32G32B32_Float);
position.inputSlot = 0;
position.alignedByteOffset = static_cast<uint32_t>(offsetof(Resources::StaticMeshVertex, position));
inputLayout.elements.push_back(position);
RHI::InputElementDesc normal = {};
normal.semanticName = "NORMAL";
normal.semanticIndex = 0;
normal.format = static_cast<uint32_t>(RHI::Format::R32G32B32_Float);
normal.inputSlot = 0;
normal.alignedByteOffset = static_cast<uint32_t>(offsetof(Resources::StaticMeshVertex, normal));
inputLayout.elements.push_back(normal);
RHI::InputElementDesc texcoord = {};
texcoord.semanticName = "TEXCOORD";
texcoord.semanticIndex = 0;
texcoord.format = static_cast<uint32_t>(RHI::Format::R32G32_Float);
texcoord.inputSlot = 0;
texcoord.alignedByteOffset = static_cast<uint32_t>(offsetof(Resources::StaticMeshVertex, uv0));
inputLayout.elements.push_back(texcoord);
return inputLayout;
}
bool BuiltinDepthStylePassBase::Initialize(const RenderContext& context) {
return EnsureInitialized(context);
}
void BuiltinDepthStylePassBase::Shutdown() {
DestroyResources();
}
bool BuiltinDepthStylePassBase::Execute(const RenderPassContext& context) {
if (!context.renderContext.IsValid()) {
return false;
}
if (!::XCEngine::Rendering::Internal::IsDepthStyleCompatibleSurface(context.surface)) {
return false;
}
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
const uint32_t colorAttachmentCount =
::XCEngine::Rendering::Internal::ResolveSurfaceColorAttachmentCount(context.surface);
RHI::RHIResourceView* depthAttachment = context.surface.GetDepthAttachment();
RHI::RHIResourceView* renderTarget =
(colorAttachmentCount > 0u ? colorAttachments[0] : nullptr);
const Math::RectInt renderArea = context.surface.GetRenderArea();
if (renderArea.width <= 0 || renderArea.height <= 0) {
return false;
}
if (!EnsureInitialized(context.renderContext)) {
return false;
}
RHI::RHICommandList* commandList = context.renderContext.commandList;
if (context.surface.IsAutoTransitionEnabled() && renderTarget != nullptr) {
commandList->TransitionBarrier(
renderTarget,
context.surface.GetColorStateBefore(),
RHI::ResourceStates::RenderTarget);
}
if (context.surface.IsAutoTransitionEnabled() && depthAttachment != nullptr) {
commandList->TransitionBarrier(
depthAttachment,
context.surface.GetDepthStateBefore(),
RHI::ResourceStates::DepthWrite);
}
RHI::RHIResourceView* renderTargets[] = { renderTarget };
const uint32_t renderTargetCount = renderTarget != nullptr ? 1u : 0u;
commandList->SetRenderTargets(
renderTargetCount,
renderTargetCount > 0 ? renderTargets : nullptr,
depthAttachment);
const RHI::Viewport viewport = {
static_cast<float>(renderArea.x),
static_cast<float>(renderArea.y),
static_cast<float>(renderArea.width),
static_cast<float>(renderArea.height),
0.0f,
1.0f
};
const RHI::Rect scissorRect = {
renderArea.x,
renderArea.y,
renderArea.x + renderArea.width,
renderArea.y + renderArea.height
};
const RHI::Rect clearRects[] = { scissorRect };
commandList->SetViewport(viewport);
commandList->SetScissorRect(scissorRect);
const Math::Color clearColor = context.sceneData.cameraData.clearColor;
const float clearValues[4] = { clearColor.r, clearColor.g, clearColor.b, clearColor.a };
if (renderTarget != nullptr &&
HasRenderClearFlag(context.sceneData.cameraData.clearFlags, RenderClearFlags::Color)) {
commandList->ClearRenderTarget(renderTarget, clearValues, 1, clearRects);
}
if (HasRenderClearFlag(context.sceneData.cameraData.clearFlags, RenderClearFlags::Depth)) {
commandList->ClearDepthStencil(depthAttachment, 1.0f, 0, 1, clearRects);
}
commandList->SetPrimitiveTopology(RHI::PrimitiveTopology::TriangleList);
VisitRendererListVisibleItems(
context.sceneData,
GetRendererListType(),
[&](const VisibleRenderItem& visibleItem) {
if (!ShouldRenderVisibleItem(visibleItem)) {
return;
}
DrawVisibleItem(context.renderContext, context.surface, context.sceneData, visibleItem);
});
commandList->EndRenderPass();
if (context.surface.IsAutoTransitionEnabled() && renderTarget != nullptr) {
commandList->TransitionBarrier(
renderTarget,
RHI::ResourceStates::RenderTarget,
context.surface.GetColorStateAfter());
}
if (context.surface.IsAutoTransitionEnabled() && depthAttachment != nullptr) {
commandList->TransitionBarrier(
depthAttachment,
RHI::ResourceStates::DepthWrite,
context.surface.GetDepthStateAfter());
}
return true;
}
RendererListType BuiltinDepthStylePassBase::GetRendererListType() const {
return RendererListType::AllVisible;
}
bool BuiltinDepthStylePassBase::ShouldRenderVisibleItem(const VisibleRenderItem& visibleItem) const {
(void)visibleItem;
return true;
}
} // namespace Passes
} // namespace Rendering
} // namespace XCEngine