Files
XCEngine/engine/src/Rendering/Internal/RenderSurfacePipelineUtils.h

138 lines
4.9 KiB
C++

#pragma once
#include <XCEngine/Rendering/RenderSurface.h>
#include <XCEngine/RHI/RHIResourceView.h>
#include <array>
#include <cstdint>
namespace XCEngine {
namespace Rendering {
namespace Internal {
inline constexpr uint32_t kMaxPipelineColorAttachmentCount = 8u;
inline uint32_t ResolveSurfaceColorAttachmentCount(const RenderSurface& surface) {
uint32_t count = 0;
for (RHI::RHIResourceView* attachment : surface.GetColorAttachments()) {
if (attachment == nullptr || count >= kMaxPipelineColorAttachmentCount) {
break;
}
++count;
}
return count;
}
inline bool HasSingleColorAttachment(const RenderSurface& surface) {
return ResolveSurfaceColorAttachmentCount(surface) == 1u;
}
inline bool HasZeroOrSingleColorAttachment(const RenderSurface& surface) {
return ResolveSurfaceColorAttachmentCount(surface) <= 1u;
}
inline RHI::Format ResolveSurfaceColorFormat(
const RenderSurface& surface,
uint32_t attachmentIndex = 0u) {
const std::vector<RHI::RHIResourceView*>& colorAttachments = surface.GetColorAttachments();
if (attachmentIndex >= colorAttachments.size() || colorAttachments[attachmentIndex] == nullptr) {
return RHI::Format::Unknown;
}
return colorAttachments[attachmentIndex]->GetFormat();
}
inline bool TryResolveSingleColorAttachmentFormat(
const RenderSurface& surface,
RHI::Format& outFormat) {
if (!HasSingleColorAttachment(surface)) {
outFormat = RHI::Format::Unknown;
return false;
}
outFormat = ResolveSurfaceColorFormat(surface, 0u);
return outFormat != RHI::Format::Unknown;
}
inline bool HasKnownSingleColorAttachmentFormat(const RenderSurface& surface) {
return !HasSingleColorAttachment(surface) ||
ResolveSurfaceColorFormat(surface, 0u) != RHI::Format::Unknown;
}
inline std::array<uint32_t, kMaxPipelineColorAttachmentCount> ResolveSurfaceColorFormats(
const RenderSurface& surface) {
std::array<uint32_t, kMaxPipelineColorAttachmentCount> formats = {};
const uint32_t colorAttachmentCount = ResolveSurfaceColorAttachmentCount(surface);
for (uint32_t attachmentIndex = 0; attachmentIndex < colorAttachmentCount; ++attachmentIndex) {
formats[attachmentIndex] = static_cast<uint32_t>(ResolveSurfaceColorFormat(surface, attachmentIndex));
}
return formats;
}
inline RHI::Format ResolveSurfaceDepthFormat(const RenderSurface& surface) {
if (RHI::RHIResourceView* depthAttachment = surface.GetDepthAttachment();
depthAttachment != nullptr) {
return depthAttachment->GetFormat();
}
return RHI::Format::Unknown;
}
inline bool HasKnownDepthAttachmentFormat(const RenderSurface& surface) {
return ResolveSurfaceDepthFormat(surface) != RHI::Format::Unknown;
}
inline uint32_t ResolveSurfaceSampleCount(const RenderSurface& surface) {
return surface.GetSampleCount();
}
inline uint32_t ResolveSurfaceSampleQuality(const RenderSurface& surface) {
return surface.GetSampleQuality();
}
inline bool HasValidPipelineSampleDescription(const RenderSurface& surface) {
const uint32_t sampleCount = ResolveSurfaceSampleCount(surface);
const uint32_t sampleQuality = ResolveSurfaceSampleQuality(surface);
return sampleCount > 0u &&
(sampleCount > 1u || sampleQuality == 0u);
}
inline bool IsDepthStyleCompatibleSurface(const RenderSurface& surface) {
return HasZeroOrSingleColorAttachment(surface) &&
HasKnownSingleColorAttachmentFormat(surface) &&
HasKnownDepthAttachmentFormat(surface) &&
HasValidPipelineSampleDescription(surface);
}
inline void ApplySurfacePropertiesToGraphicsPipelineDesc(
const RenderSurface& surface,
RHI::GraphicsPipelineDesc& pipelineDesc) {
const std::array<uint32_t, kMaxPipelineColorAttachmentCount> renderTargetFormats =
ResolveSurfaceColorFormats(surface);
pipelineDesc.renderTargetCount = ResolveSurfaceColorAttachmentCount(surface);
for (uint32_t attachmentIndex = 0; attachmentIndex < pipelineDesc.renderTargetCount; ++attachmentIndex) {
pipelineDesc.renderTargetFormats[attachmentIndex] = renderTargetFormats[attachmentIndex];
}
pipelineDesc.depthStencilFormat = static_cast<uint32_t>(ResolveSurfaceDepthFormat(surface));
pipelineDesc.sampleCount = ResolveSurfaceSampleCount(surface);
pipelineDesc.sampleQuality = ResolveSurfaceSampleQuality(surface);
}
inline void ApplySingleColorAttachmentPropertiesToGraphicsPipelineDesc(
const RenderSurface& surface,
RHI::GraphicsPipelineDesc& pipelineDesc) {
pipelineDesc.renderTargetCount = HasSingleColorAttachment(surface) ? 1u : 0u;
pipelineDesc.renderTargetFormats[0] =
static_cast<uint32_t>(ResolveSurfaceColorFormat(surface, 0u));
pipelineDesc.sampleCount = ResolveSurfaceSampleCount(surface);
pipelineDesc.sampleQuality = ResolveSurfaceSampleQuality(surface);
}
} // namespace Internal
} // namespace Rendering
} // namespace XCEngine