#include "ViewportRenderTargets.h" namespace XCEngine::UI::Editor::App { namespace { bool CreateViewportColorResources( ::XCEngine::RHI::RHIDevice& device, ViewportRenderTargets& targets) { const auto colorDesc = BuildViewportTextureDesc(targets.width, targets.height, ::XCEngine::RHI::Format::R8G8B8A8_UNorm); targets.colorTexture = device.CreateTexture(colorDesc); if (targets.colorTexture == nullptr) { return false; } const auto colorViewDesc = BuildViewportTextureViewDesc(::XCEngine::RHI::Format::R8G8B8A8_UNorm); targets.colorView = device.CreateRenderTargetView(targets.colorTexture, colorViewDesc); return targets.colorView != nullptr; } bool CreateViewportDepthResources( ::XCEngine::RHI::RHIDevice& device, ViewportRenderTargets& targets) { const auto depthDesc = BuildViewportTextureDesc(targets.width, targets.height, ::XCEngine::RHI::Format::D24_UNorm_S8_UInt); targets.depthTexture = device.CreateTexture(depthDesc); if (targets.depthTexture == nullptr) { return false; } const auto depthViewDesc = BuildViewportTextureViewDesc(::XCEngine::RHI::Format::D24_UNorm_S8_UInt); targets.depthView = device.CreateDepthStencilView(targets.depthTexture, depthViewDesc); if (targets.depthView == nullptr) { return false; } ::XCEngine::RHI::ResourceViewDesc depthShaderViewDesc = {}; depthShaderViewDesc.dimension = ::XCEngine::RHI::ResourceViewDimension::Texture2D; depthShaderViewDesc.mipLevel = 0; targets.depthShaderView = device.CreateShaderResourceView( targets.depthTexture, depthShaderViewDesc); return targets.depthShaderView != nullptr; } bool CreateViewportObjectIdResources( ::XCEngine::RHI::RHIDevice& device, ViewportRenderTargets& targets) { const auto objectIdDesc = BuildViewportTextureDesc(targets.width, targets.height, ::XCEngine::RHI::Format::R8G8B8A8_UNorm); targets.objectIdTexture = device.CreateTexture(objectIdDesc); if (targets.objectIdTexture == nullptr) { return false; } const auto objectIdViewDesc = BuildViewportTextureViewDesc(::XCEngine::RHI::Format::R8G8B8A8_UNorm); targets.objectIdView = device.CreateRenderTargetView(targets.objectIdTexture, objectIdViewDesc); if (targets.objectIdView == nullptr) { return false; } targets.objectIdShaderView = device.CreateShaderResourceView( targets.objectIdTexture, objectIdViewDesc); if (targets.objectIdShaderView == nullptr) { return false; } const auto objectIdDepthDesc = BuildViewportTextureDesc(targets.width, targets.height, ::XCEngine::RHI::Format::D24_UNorm_S8_UInt); targets.objectIdDepthTexture = device.CreateTexture(objectIdDepthDesc); if (targets.objectIdDepthTexture == nullptr) { return false; } const auto objectIdDepthViewDesc = BuildViewportTextureViewDesc(::XCEngine::RHI::Format::D24_UNorm_S8_UInt); targets.objectIdDepthView = device.CreateDepthStencilView( targets.objectIdDepthTexture, objectIdDepthViewDesc); return targets.objectIdDepthView != nullptr; } bool CreateViewportSelectionMaskResources( ::XCEngine::RHI::RHIDevice& device, ViewportRenderTargets& targets) { const auto selectionMaskDesc = BuildViewportTextureDesc(targets.width, targets.height, ::XCEngine::RHI::Format::R8G8B8A8_UNorm); targets.selectionMaskTexture = device.CreateTexture(selectionMaskDesc); if (targets.selectionMaskTexture == nullptr) { return false; } const auto selectionMaskViewDesc = BuildViewportTextureViewDesc(::XCEngine::RHI::Format::R8G8B8A8_UNorm); targets.selectionMaskView = device.CreateRenderTargetView( targets.selectionMaskTexture, selectionMaskViewDesc); if (targets.selectionMaskView == nullptr) { return false; } targets.selectionMaskShaderView = device.CreateShaderResourceView( targets.selectionMaskTexture, selectionMaskViewDesc); return targets.selectionMaskShaderView != nullptr; } bool CreateViewportTextureDescriptor( Host::D3D12ShaderResourceDescriptorAllocator& textureDescriptorAllocator, ViewportRenderTargets& targets) { if (!textureDescriptorAllocator.CreateTextureDescriptor( targets.colorTexture, &targets.srvCpuHandle, &targets.srvGpuHandle)) { return false; } targets.textureHandle.nativeHandle = static_cast(targets.srvGpuHandle.ptr); targets.textureHandle.width = targets.width; targets.textureHandle.height = targets.height; targets.textureHandle.kind = ::XCEngine::UI::UITextureHandleKind::ShaderResourceView; targets.textureHandle.resourceHandle = reinterpret_cast(targets.colorTexture); return true; } } // namespace bool ViewportRenderTargetManager::EnsureTargets( ViewportKind kind, std::uint32_t width, std::uint32_t height, ::XCEngine::RHI::RHIDevice& device, Host::D3D12ShaderResourceDescriptorAllocator& textureDescriptorAllocator, ViewportRenderTargets& targets) const { if (width == 0u || height == 0u) { return false; } DestroyTargets(&textureDescriptorAllocator, targets); targets.width = width; targets.height = height; if (!CreateViewportColorResources(device, targets) || !CreateViewportDepthResources(device, targets) || (ViewportRequiresObjectIdResources(kind) && (!CreateViewportObjectIdResources(device, targets) || !CreateViewportSelectionMaskResources(device, targets))) || !CreateViewportTextureDescriptor(textureDescriptorAllocator, targets)) { DestroyTargets(&textureDescriptorAllocator, targets); return false; } targets.colorState = ::XCEngine::RHI::ResourceStates::Common; targets.objectIdState = ::XCEngine::RHI::ResourceStates::Common; targets.selectionMaskState = ::XCEngine::RHI::ResourceStates::Common; targets.hasValidObjectIdFrame = false; return true; } } // namespace XCEngine::UI::Editor::App