aboutsummaryrefslogtreecommitdiff
path: root/src/Renderer_DX12.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Renderer_DX12.cpp')
-rw-r--r--src/Renderer_DX12.cpp749
1 files changed, 749 insertions, 0 deletions
diff --git a/src/Renderer_DX12.cpp b/src/Renderer_DX12.cpp
new file mode 100644
index 0000000..3b4cec3
--- /dev/null
+++ b/src/Renderer_DX12.cpp
@@ -0,0 +1,749 @@
+/*
+* Copyright (c) 2008-2016, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, related documentation
+* and any modifications thereto. Any use, reproduction, disclosure or
+* distribution of this software and related documentation without an express
+* license agreement from NVIDIA CORPORATION is strictly prohibited.
+*/
+
+#if SUPPORT_D3D12
+#include "Renderer_DX12.h"
+
+//--------------------------------------------------------------------------------
+struct RenderTargetBarrierScope
+{
+ RenderTargetBarrierScope(ID3D12GraphicsCommandList* pCmdList, ID3D12Resource* pResource)
+ : m_pCmdList(pCmdList)
+ , m_pResource(pResource)
+ {
+ GFSDK_D3D12_SetResourceBarrier(pCmdList, pResource, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
+ }
+ ~RenderTargetBarrierScope()
+ {
+ GFSDK_D3D12_SetResourceBarrier(m_pCmdList, m_pResource, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+ }
+private:
+ ID3D12GraphicsCommandList* m_pCmdList;
+ ID3D12Resource* m_pResource;
+};
+
+#define RT_BARRIER_SCOPE(pCmdList, pResource) RenderTargetBarrierScope RTScope(pCmdList, pResource)
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::CreateResources(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+ m_States.Create(pGraphicsContext);
+ m_Shaders.Create(pGraphicsContext->pDevice);
+
+ m_GlobalCB.Create(pGraphicsContext, eGlobalCB, 0);
+ m_PerPassCBs.Create(pGraphicsContext, ePerPassCB);
+
+ m_LinearDepthPSO.Create(pGraphicsContext);
+ m_DebugNormalsPSO.Create(pGraphicsContext, m_States);
+ m_DeinterleavedDepthPSO.Create(pGraphicsContext, m_States);
+ m_CoarseAOPSO.Create(pGraphicsContext, m_States);
+ m_ReinterleavedAOPSO.Create(pGraphicsContext, m_States);
+ m_ReinterleavedAOBlurPSO.Create(pGraphicsContext, m_States);
+ m_ReconstructNormalPSO.Create(pGraphicsContext, m_States);
+ m_BlurXPSO.Create(pGraphicsContext, m_States);
+ m_BlurYPSO.Create(pGraphicsContext, m_States);
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::ReleaseResources()
+{
+ // Test in case Release is called without ever calling RenderAO or PreCreateRTs
+ if (m_GraphicsContext.pCmdQueue)
+ {
+ m_GraphicsContext.WaitGPUIdle();
+
+ SAFE_RELEASE(m_GraphicsContext.pCmdQueue);
+ }
+
+ m_GlobalCB.Release();
+ m_PerPassCBs.Release();
+
+ m_LinearDepthPSO.Release();
+ m_DebugNormalsPSO.Release();
+ m_DeinterleavedDepthPSO.Release();
+ m_CoarseAOPSO.Release();
+ m_ReinterleavedAOPSO.Release();
+ m_ReinterleavedAOBlurPSO.Release();
+ m_ReconstructNormalPSO.Release();
+ m_BlurXPSO.Release();
+ m_BlurYPSO.Release();
+
+ m_States.Release();
+ m_Shaders.Release();
+ m_RTs.Release();
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::Create(
+ ID3D12Device* pDevice,
+ GFSDK_SSAO_UINT NodeMask,
+ const GFSDK_SSAO_DescriptorHeaps_D3D12& DescriptorHeaps,
+ GFSDK_SSAO_Version HeaderVersion)
+{
+ if (!m_BuildVersion.Match(HeaderVersion))
+ {
+ return GFSDK_SSAO_VERSION_MISMATCH;
+ }
+
+ if (!pDevice)
+ {
+ return GFSDK_SSAO_NULL_ARGUMENT;
+ }
+
+ // Make sure that exactly one bit is set in NodeMask
+ if (NodeMask == 0 || (NodeMask & (NodeMask - 1)) != 0)
+ {
+ return GFSDK_SSAO_D3D12_INVALID_NODE_MASK;
+ }
+
+ // Make sure that NodeMask points to an existing node
+ if (NodeMask >= (1u << pDevice->GetNodeCount()))
+ {
+ return GFSDK_SSAO_D3D12_INVALID_NODE_MASK;
+ }
+
+ if (!DescriptorHeaps.CBV_SRV_UAV.pDescHeap ||
+ !DescriptorHeaps.RTV.pDescHeap)
+ {
+ return GFSDK_SSAO_NULL_ARGUMENT;
+ }
+
+ if (DescriptorHeaps.CBV_SRV_UAV.pDescHeap->GetDesc().Type != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ||
+ DescriptorHeaps.RTV.pDescHeap->GetDesc().Type != D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
+ {
+ return GFSDK_SSAO_D3D12_INVALID_HEAP_TYPE;
+ }
+
+ if (DescriptorHeaps.CBV_SRV_UAV.NumDescriptors < GFSDK_SSAO_NUM_DESCRIPTORS_CBV_SRV_UAV_HEAP_D3D12 ||
+ DescriptorHeaps.RTV.NumDescriptors < GFSDK_SSAO_NUM_DESCRIPTORS_RTV_HEAP_D3D12)
+ {
+ return GFSDK_SSAO_D3D12_INSUFFICIENT_DESCRIPTORS;
+ }
+
+ m_GraphicsContext.Init(pDevice, DescriptorHeaps, NodeMask);
+
+ D3D12_FEATURE_DATA_FEATURE_LEVELS FeatureLevelsInfo = {};
+ D3D_FEATURE_LEVEL Level = D3D_FEATURE_LEVEL_11_0;
+ FeatureLevelsInfo.NumFeatureLevels = 1;
+ FeatureLevelsInfo.pFeatureLevelsRequested = &Level;
+
+ HRESULT Hr = pDevice->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &FeatureLevelsInfo, sizeof(FeatureLevelsInfo));
+ if ((Hr != S_OK) || (FeatureLevelsInfo.MaxSupportedFeatureLevel < D3D_FEATURE_LEVEL_11_0))
+ {
+ return GFSDK_SSAO_D3D_FEATURE_LEVEL_NOT_SUPPORTED;
+ }
+
+#if ENABLE_EXCEPTIONS
+ try
+ {
+ CreateResources(&m_GraphicsContext);
+ }
+ catch (...)
+ {
+ ReleaseResources();
+
+ return GFSDK_SSAO_D3D_RESOURCE_CREATION_FAILED;
+ }
+#else
+ CreateResources(pContext);
+#endif
+
+ m_RTs.SetGraphicsContext(&m_GraphicsContext);
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::Release()
+{
+ ReleaseResources();
+ m_GraphicsContext.Release();
+ m_NewDelete.delete_(this);
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::RenderAO(
+ ID3D12CommandQueue* pCmdQueue,
+ ID3D12GraphicsCommandList* pCmdList,
+ const GFSDK_SSAO_InputData_D3D12& InputData,
+ const GFSDK_SSAO_Parameters& Parameters,
+ const GFSDK_SSAO_Output_D3D12& Output,
+ GFSDK_SSAO_RenderMask RenderMask)
+{
+ GFSDK_SSAO_Status Status;
+
+ if (!pCmdList || !pCmdQueue)
+ {
+ return GFSDK_SSAO_NULL_ARGUMENT;
+ }
+
+ if (pCmdQueue->GetDesc().NodeMask != m_GraphicsContext.NodeMask)
+ {
+ return GFSDK_SSAO_D3D12_INVALID_NODE_MASK;
+ }
+
+ SAFE_RELEASE(m_GraphicsContext.pCmdQueue);
+
+ m_GraphicsContext.pCmdList = pCmdList;
+ m_GraphicsContext.pCmdQueue = pCmdQueue;
+ m_GraphicsContext.pCmdQueue->AddRef();
+
+ Status = SetDataFlow(InputData, Parameters, Output);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ Status = m_RTs.PreCreate(m_Options);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+#if ENABLE_EXCEPTIONS
+ try
+ {
+ Render(&m_GraphicsContext, RenderMask);
+ }
+ catch (...)
+ {
+ ReleaseResources();
+
+ return GFSDK_SSAO_D3D_RESOURCE_CREATION_FAILED;
+ }
+#else
+ Render(&m_GraphicsContext, RenderMask);
+#endif
+
+ m_GraphicsContext.IncrFenceValue();
+
+ // Make sure that pCmdList is not used outside of RenderAO
+ m_GraphicsContext.pCmdList = NULL;
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::PreCreateRTs(ID3D12CommandQueue* pCmdQueue,
+ const GFSDK_SSAO_Parameters& Parameters,
+ UINT ViewportWidth,
+ UINT ViewportHeight)
+{
+ if (!pCmdQueue)
+ {
+ return GFSDK_SSAO_NULL_ARGUMENT;
+ }
+
+ if (pCmdQueue->GetDesc().NodeMask != m_GraphicsContext.NodeMask)
+ {
+ return GFSDK_SSAO_D3D12_INVALID_NODE_MASK;
+ }
+
+ SAFE_RELEASE(m_GraphicsContext.pCmdQueue);
+
+ m_GraphicsContext.pCmdQueue = pCmdQueue;
+ m_GraphicsContext.pCmdQueue->AddRef();
+
+ SetAOResolution(ViewportWidth, ViewportHeight);
+
+ m_Options.SetRenderOptions(Parameters);
+
+ return m_RTs.PreCreate(m_Options);
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::GetProjectionMatrixDepthRange(
+ const GFSDK_SSAO_InputData_D3D12& InputData,
+ GFSDK_SSAO_ProjectionMatrixDepthRange& OutputDepthRange)
+{
+ GFSDK_SSAO_Status Status;
+
+ SSAO::ProjectionMatrixInfo ProjectionMatrixInfo;
+ Status = ProjectionMatrixInfo.Init(InputData.DepthData.ProjectionMatrix, API_D3D11);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ ProjectionMatrixInfo.GetDepthRange(&OutputDepthRange);
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawLinearDepthPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawLinearDepthPS");
+#endif
+
+ if (m_InputDepth.DepthTextureType == GFSDK_SSAO_VIEW_DEPTHS &&
+ m_InputDepth.Texture.SampleCount == 1 &&
+ m_InputDepth.Viewport.RectCoversFullInputTexture)
+ {
+ m_FullResViewDepthSRV = m_InputDepth.Texture.SRV;
+ return;
+ }
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ RT_BARRIER_SCOPE(pCmdList, m_RTs.GetFullResViewDepthTexture()->RTV.pResource);
+
+ pCmdList->OMSetRenderTargets(1, &m_RTs.GetFullResViewDepthTexture()->RTV.CpuHandle, false, nullptr);
+ pCmdList->RSSetViewports(1, &m_Viewports.FullRes);
+
+ pCmdList->SetGraphicsRootSignature(m_LinearDepthPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(LinearDepthPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(LinearDepthPSO::RootParameters::Texture0, m_InputDepth.Texture.SRV.GpuHandle);
+
+ pCmdList->SetPipelineState(m_LinearDepthPSO.GetPSO(pGraphicsContext, m_Shaders, GetResolveDepthPermutation(), m_InputDepth.DepthTextureType));
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+
+ m_FullResViewDepthSRV = m_RTs.GetFullResViewDepthTexture()->SRV;
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawDeinterleavedDepthPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawDeinterleavedDepthPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ pCmdList->RSSetViewports(1, &m_Viewports.QuarterRes);
+
+ pCmdList->SetGraphicsRootSignature(m_DeinterleavedDepthPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(DeinterleavedDepthPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(DeinterleavedDepthPSO::RootParameters::Texture0, m_GraphicsContext.DescHeaps.GetGpuHandle(eFullResViewDepthTexture, 0));
+
+ pCmdList->SetPipelineState(m_DeinterleavedDepthPSO.GetPSO(pGraphicsContext, m_Shaders, m_States, m_RTs, m_Options.DepthStorage));
+
+ RT_BARRIER_SCOPE(pCmdList, m_RTs.GetQuarterResViewDepthTextureArray(m_Options)->pResource);
+
+ for (UINT SliceIndex = 0; SliceIndex < 16; SliceIndex += DeinterleavedDepthPSO::MRT_COUNT)
+ {
+ pCmdList->SetGraphicsRootDescriptorTable(DeinterleavedDepthPSO::RootParameters::Buffer1, m_GraphicsContext.DescHeaps.GetGpuHandle(ePerPassCB, SliceIndex));
+
+ D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle = m_RTs.GetQuarterResViewDepthTextureArray(m_Options)->RTVs[SliceIndex].CpuHandle;
+ BOOL RTsSingleHandleToDescriptorRange = true;
+
+ pCmdList->OMSetRenderTargets(DeinterleavedDepthPSO::MRT_COUNT, &RTVHandle, RTsSingleHandleToDescriptorRange, nullptr);
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+ }
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawReconstructedNormalPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawReconstructedNormalPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ RT_BARRIER_SCOPE(pCmdList, m_RTs.GetFullResNormalTexture()->RTV.pResource);
+
+ pCmdList->OMSetRenderTargets(1, &m_RTs.GetFullResNormalTexture()->RTV.CpuHandle, false, nullptr);
+ pCmdList->RSSetViewports(1, &m_Viewports.FullRes);
+
+ pCmdList->SetGraphicsRootSignature(m_ReconstructNormalPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(ReconstructNormalPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(ReconstructNormalPSO::RootParameters::Texture0, m_RTs.GetFullResViewDepthTexture()->SRV.GpuHandle);
+
+ pCmdList->SetPipelineState(m_ReconstructNormalPSO.GetPSO(pGraphicsContext, m_Shaders));
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawDebugNormalsPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawDebugNormalsPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ pCmdList->OMSetRenderTargets(1, &m_Output.RenderTarget.RTV.CpuHandle, false, nullptr);
+ pCmdList->RSSetViewports(1, &m_InputDepth.Viewport);
+
+ pCmdList->SetGraphicsRootSignature(m_DebugNormalsPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(DebugNormalsPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(DebugNormalsPSO::RootParameters::Texture0, m_RTs.GetFullResViewDepthTexture()->SRV.GpuHandle);
+
+ if (m_InputNormal.Texture.IsSet())
+ {
+ pCmdList->SetGraphicsRootDescriptorTable(DebugNormalsPSO::RootParameters::Texture1, m_InputNormal.Texture.SRV.GpuHandle);
+ }
+
+ pCmdList->SetPipelineState(m_DebugNormalsPSO.GetPSO(pGraphicsContext, m_Shaders, m_States, m_Output, GetFetchNormalPermutation()));
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawCoarseAOPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawCoarseAOPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ pCmdList->SetPipelineState(m_CoarseAOPSO.GetPSO(pGraphicsContext, m_Shaders, GetEnableForegroundAOPermutation(), GetEnableBackgroundAOPermutation(), GetEnableDepthThresholdPermutation(), GetFetchNormalPermutation()));
+
+ RT_BARRIER_SCOPE(pCmdList, m_RTs.GetQuarterResAOTextureArray()->pResource);
+
+ pCmdList->OMSetRenderTargets(1, &m_RTs.GetQuarterResAOTextureArray()->RTV.CpuHandle, false, nullptr);
+ pCmdList->RSSetViewports(1, &m_Viewports.QuarterRes);
+
+ pCmdList->SetGraphicsRootSignature(m_CoarseAOPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(CoarseAOPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(CoarseAOPSO::RootParameters::Texture1, GetFullResNormalBufferSRV()->GpuHandle);
+
+ for (UINT SliceIndex = 0; SliceIndex < 16; ++SliceIndex)
+ {
+ pCmdList->SetGraphicsRootDescriptorTable(CoarseAOPSO::RootParameters::Buffer1, m_GraphicsContext.DescHeaps.GetGpuHandle(ePerPassCB, SliceIndex));
+ pCmdList->SetGraphicsRootDescriptorTable(CoarseAOPSO::RootParameters::Texture0, m_RTs.GetQuarterResViewDepthTextureArray(m_Options)->SRVs[SliceIndex].GpuHandle);
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+ }
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawReinterleavedAOPS_PreBlur(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawReinterleavedAOPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ RT_BARRIER_SCOPE(pCmdList, m_RTs.GetFullResAOZTexture2()->RTV.pResource);
+
+ pCmdList->OMSetRenderTargets(1, &m_RTs.GetFullResAOZTexture2()->RTV.CpuHandle, false, nullptr);
+ pCmdList->RSSetViewports(1, &m_Viewports.FullRes);
+
+ pCmdList->SetPipelineState(m_ReinterleavedAOBlurPSO.GetPSO(pGraphicsContext, m_Shaders));
+
+ pCmdList->SetGraphicsRootSignature(m_ReinterleavedAOBlurPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(ReinterleavedAOBlurPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(ReinterleavedAOBlurPSO::RootParameters::Texture0, m_RTs.GetQuarterResAOTextureArray()->SRV.GpuHandle);
+ pCmdList->SetGraphicsRootDescriptorTable(ReinterleavedAOBlurPSO::RootParameters::Texture1, m_FullResViewDepthSRV.GpuHandle);
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawReinterleavedAOPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawReinterleavedAOPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ pCmdList->OMSetRenderTargets(1, &m_Output.RenderTarget.RTV.CpuHandle, false, nullptr);
+ pCmdList->RSSetViewports(1, &m_InputDepth.Viewport);
+
+ if (GetOutputBlendFactor())
+ {
+ pCmdList->OMSetBlendFactor(GetOutputBlendFactor());
+ }
+
+ pCmdList->SetPipelineState(m_ReinterleavedAOPSO.GetPSO(pGraphicsContext, m_Shaders, m_States, m_Output));
+
+ pCmdList->SetGraphicsRootSignature(m_ReinterleavedAOPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(ReinterleavedAOPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(ReinterleavedAOPSO::RootParameters::Texture0, m_RTs.GetQuarterResAOTextureArray()->SRV.GpuHandle);
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawBlurXPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawBlurXPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ RT_BARRIER_SCOPE(pCmdList, m_RTs.GetFullResAOZTexture()->RTV.pResource);
+
+ pCmdList->OMSetRenderTargets(1, &m_RTs.GetFullResAOZTexture()->RTV.CpuHandle, false, nullptr);
+ pCmdList->RSSetViewports(1, &m_Viewports.FullRes);
+
+ pCmdList->SetPipelineState(m_BlurXPSO.GetPSO(pGraphicsContext, m_Shaders, GetEnableSharpnessProfilePermutation(), GetBlurKernelRadiusPermutation()));
+
+ pCmdList->SetGraphicsRootSignature(m_BlurXPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(BlurXPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(BlurXPSO::RootParameters::Texture0, m_RTs.GetFullResAOZTexture2()->SRV.GpuHandle);
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::DrawBlurYPS(GFSDK_D3D12_GraphicsContext* pGraphicsContext)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"DrawBlurYPS");
+#endif
+
+ ID3D12GraphicsCommandList* pCmdList = pGraphicsContext->pCmdList;
+
+ pCmdList->RSSetViewports(1, &m_InputDepth.Viewport);
+
+ pCmdList->OMSetRenderTargets(1, &m_Output.RenderTarget.RTV.CpuHandle, false, nullptr);
+
+ if (GetOutputBlendFactor())
+ {
+ pCmdList->OMSetBlendFactor(GetOutputBlendFactor());
+ }
+
+ pCmdList->SetPipelineState(m_BlurYPSO.GetPSO(pGraphicsContext, m_Shaders, m_States, m_Output, GetEnableSharpnessProfilePermutation(), GetBlurKernelRadiusPermutation()));
+
+ pCmdList->SetGraphicsRootSignature(m_BlurYPSO.GetRS());
+ pCmdList->SetGraphicsRootDescriptorTable(BlurYPSO::RootParameters::Buffer0, m_GraphicsContext.DescHeaps.GetGpuHandle(eGlobalCB, 0));
+ pCmdList->SetGraphicsRootDescriptorTable(BlurYPSO::RootParameters::Texture0, m_RTs.GetFullResAOZTexture()->SRV.GpuHandle);
+
+ pCmdList->DrawInstanced(3, 1, 0, 0);
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::RenderHBAOPlus(GFSDK_D3D12_GraphicsContext* pGraphicsContext, GFSDK_SSAO_RenderMask RenderMask)
+{
+ if (RenderMask & GFSDK_SSAO_DRAW_Z)
+ {
+ DrawLinearDepthPS(pGraphicsContext);
+ }
+
+ if (RenderMask & GFSDK_SSAO_DRAW_DEBUG_N)
+ {
+ DrawDebugNormalsPS(pGraphicsContext);
+ }
+
+ if (RenderMask & GFSDK_SSAO_DRAW_AO)
+ {
+ DrawDeinterleavedDepthPS(pGraphicsContext);
+
+ if (!m_InputNormal.Texture.IsSet())
+ {
+ DrawReconstructedNormalPS(pGraphicsContext);
+ }
+
+ DrawCoarseAOPS(pGraphicsContext);
+
+ if (m_Options.Blur.Enable)
+ {
+ DrawReinterleavedAOPS_PreBlur(pGraphicsContext);
+ DrawBlurXPS(pGraphicsContext);
+ DrawBlurYPS(pGraphicsContext);
+ }
+ else
+ {
+ DrawReinterleavedAOPS(pGraphicsContext);
+ }
+ }
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::Render(GFSDK_D3D12_GraphicsContext* pGraphicsContext, GFSDK_SSAO_RenderMask RenderMask)
+{
+#if ENABLE_PERF_MARKERS
+ PERF_MARKER_SCOPE(L"HBAO+");
+#endif
+
+ m_GraphicsContext.pCmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ m_GlobalCB.UpdateBuffer(pGraphicsContext, RenderMask);
+
+ RenderHBAOPlus(pGraphicsContext, RenderMask);
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::SetInputData(const GFSDK_SSAO_InputData_D3D12& InputData)
+{
+ GFSDK_SSAO_Status Status;
+
+ Status = SetInputDepths(InputData.DepthData);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ Status = SetInputNormals(InputData.NormalData);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::SetInputDepths(const GFSDK_SSAO_InputDepthData_D3D12& DepthData)
+{
+ m_InputDepth = GFSDK::SSAO::D3D12::InputDepthInfo();
+
+ GFSDK_SSAO_Status Status = m_InputDepth.SetData(DepthData);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ m_GlobalCB.SetDepthData(m_InputDepth);
+
+ SetAOResolution(m_InputDepth.Viewport);
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::SetInputNormals(const GFSDK_SSAO_InputNormalData_D3D12& NormalData)
+{
+ m_InputNormal = GFSDK::SSAO::D3D12::InputNormalInfo();
+
+ if (!NormalData.Enable)
+ {
+ // Input normals disabled. In this case, the lib reconstructs normals from depths.
+ return GFSDK_SSAO_OK;
+ }
+
+ GFSDK_SSAO_Status Status = m_InputNormal.SetData(NormalData);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ m_GlobalCB.SetNormalData(NormalData);
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::SetOutput(const GFSDK_SSAO_Output_D3D12& Output)
+{
+ m_Output = GFSDK::SSAO::D3D12::OutputInfo();
+
+ GFSDK_SSAO_Status Status = m_Output.Init(Output);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::ValidateDataFlow()
+{
+ if (m_InputNormal.Texture.IsSet())
+ {
+ if (m_InputNormal.Texture.Width != m_InputDepth.Texture.Width ||
+ m_InputNormal.Texture.Height != m_InputDepth.Texture.Height)
+ {
+ return GFSDK_SSAO_INVALID_NORMAL_TEXTURE_RESOLUTION;
+ }
+ if (m_InputNormal.Texture.SampleCount != m_InputDepth.Texture.SampleCount)
+ {
+ return GFSDK_SSAO_INVALID_NORMAL_TEXTURE_SAMPLE_COUNT;
+ }
+ }
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::SetAOParameters(const GFSDK_SSAO_Parameters& Params)
+{
+ if (Params.DepthClampMode == GFSDK_SSAO_CLAMP_TO_BORDER)
+ {
+ return GFSDK_SSAO_D3D12_UNSUPPORTED_DEPTH_CLAMP_MODE;
+ }
+
+ if (Params.Blur.Enable != m_Options.Blur.Enable ||
+ Params.DepthStorage != m_Options.DepthStorage)
+ {
+ m_GraphicsContext.WaitGPUIdle();
+ m_RTs.ReleaseResources();
+ }
+
+ m_GlobalCB.SetAOParameters(Params, m_InputDepth);
+ m_Options.SetRenderOptions(Params);
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+GFSDK_SSAO_Status GFSDK::SSAO::D3D12::Renderer::SetDataFlow(
+ const GFSDK_SSAO_InputData_D3D12& InputData,
+ const GFSDK_SSAO_Parameters& Parameters,
+ const GFSDK_SSAO_Output_D3D12& Output)
+{
+ GFSDK_SSAO_Status Status;
+
+ Status = SetInputData(InputData);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ Status = SetAOParameters(Parameters);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ Status = SetOutput(Output);
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ Status = ValidateDataFlow();
+ if (Status != GFSDK_SSAO_OK)
+ {
+ return Status;
+ }
+
+ return GFSDK_SSAO_OK;
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::SetAOResolution(UINT Width, UINT Height)
+{
+ if (Width != m_RTs.GetFullWidth() ||
+ Height != m_RTs.GetFullHeight())
+ {
+ m_GraphicsContext.WaitGPUIdle();
+ m_RTs.ReleaseResources();
+ m_RTs.SetFullResolution(Width, Height);
+ m_Viewports.SetFullResolution(Width, Height);
+ m_GlobalCB.SetResolutionConstants(m_Viewports);
+ }
+}
+
+//--------------------------------------------------------------------------------
+void GFSDK::SSAO::D3D12::Renderer::SetAOResolution(const SSAO::InputViewport &Viewport)
+{
+ SetAOResolution(UINT(Viewport.Width), UINT(Viewport.Height));
+}
+
+//--------------------------------------------------------------------------------
+UINT GFSDK::SSAO::D3D12::Renderer::GetAllocatedVideoMemoryBytes()
+{
+ return m_RTs.GetCurrentAllocatedVideoMemoryBytes();
+}
+
+#endif // SUPPORT_D3D12