138 lines
4.9 KiB
C++
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
|