#pragma once #include #include #include #include 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& 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 ResolveSurfaceColorFormats( const RenderSurface& surface) { std::array formats = {}; const uint32_t colorAttachmentCount = ResolveSurfaceColorAttachmentCount(surface); for (uint32_t attachmentIndex = 0; attachmentIndex < colorAttachmentCount; ++attachmentIndex) { formats[attachmentIndex] = static_cast(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 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(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(ResolveSurfaceColorFormat(surface, 0u)); pipelineDesc.sampleCount = ResolveSurfaceSampleCount(surface); pipelineDesc.sampleQuality = ResolveSurfaceSampleQuality(surface); } } // namespace Internal } // namespace Rendering } // namespace XCEngine