// This code contains NVIDIA Confidential Information and is disclosed to you // under a form of NVIDIA software license agreement provided separately to you. // // Notice // NVIDIA Corporation and its licensors retain all intellectual property and // proprietary rights in and to this software and 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. // // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. // // Information and code furnished is believed to be accurate and reliable. // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such // information or for any infringement of patents or other rights of third parties that may // result from its use. No license is granted by implication or otherwise under any patent // or patent rights of NVIDIA Corporation. Details are subject to change without notice. // This code supersedes and replaces all information previously supplied. // NVIDIA Corporation products are not authorized for use as critical // components in life support devices or systems without express written approval of // NVIDIA Corporation. // // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. #pragma once #if SUPPORT_D3D12 #include #include #include #include #include #include #include #include "d3dx12.h" typedef D3D12_SHADER_BYTECODE GFSDK_D3D12_VertexShader; typedef D3D12_SHADER_BYTECODE GFSDK_D3D12_GeometryShader; typedef D3D12_SHADER_BYTECODE GFSDK_D3D12_PixelShader; //-------------------------------------------------------------------------------- struct ShaderResourceView { ShaderResourceView() { memset(this, 0, sizeof(*this)); } ShaderResourceView(GFSDK_SSAO_ShaderResourceView_D3D12 A) : pResource(A.pResource) , GpuHandle({ A.GpuHandle }) { } ID3D12Resource* pResource; D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle; }; struct RenderTargetView { RenderTargetView() { memset(this, 0, sizeof(*this)); } RenderTargetView(GFSDK_SSAO_RenderTargetView_D3D12 A) : pResource(A.pResource) , CpuHandle({ A.CpuHandle }) { } ID3D12Resource* pResource; D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle; }; struct GFSDK_D3D12_DescriptorHeap { D3D12_DESCRIPTOR_HEAP_DESC Desc; ID3D12DescriptorHeap* pDescHeap; D3D12_CPU_DESCRIPTOR_HANDLE hCPUHeap; D3D12_GPU_DESCRIPTOR_HANDLE hGPUHeap; UINT HandleIncrementSize; UINT NumDescriptors; UINT BaseIndex; void InitDescriptorHeap(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE HeapType, const GFSDK_SSAO_DescriptorHeapRange_D3D12* pHeapInfo, bool bShaderVisible) { NumDescriptors = pHeapInfo->pDescHeap->GetDesc().NumDescriptors; pDescHeap = pHeapInfo->pDescHeap; BaseIndex = pHeapInfo->BaseIndex; if (NumDescriptors > 0) { pDescHeap->AddRef(); hCPUHeap = pDescHeap->GetCPUDescriptorHandleForHeapStart(); if (bShaderVisible) { hGPUHeap = pDescHeap->GetGPUDescriptorHandleForHeapStart(); } HandleIncrementSize = pDevice->GetDescriptorHandleIncrementSize(HeapType); } else { pDescHeap = nullptr; HandleIncrementSize = 0; } } void Release() { SAFE_RELEASE(pDescHeap); } D3D12_CPU_DESCRIPTOR_HANDLE GetCPUHandle(UINT index) { ASSERT(index < NumDescriptors); return{ hCPUHeap.ptr + (BaseIndex + index) * HandleIncrementSize }; } D3D12_GPU_DESCRIPTOR_HANDLE GetGPUHandle(UINT index) { ASSERT(index < NumDescriptors); return{ hGPUHeap.ptr + (BaseIndex + index) * HandleIncrementSize }; } }; enum CBVSRVUAVLayoutBase { eGlobalCB = 0, ePerPassCB, ePerPassCBEnd = ePerPassCB + 16 - 1, eFullResViewDepthTexture, eFullResViewDepthTexture2, eFullResNormalTexture, eQuarterResViewDepthTextureArray, eQuarterResViewDepthTextureArrayEnd = eQuarterResViewDepthTextureArray + 16, eQuarterResAOTextureArray, eQuarterResAOTextureArrayEnd = eQuarterResAOTextureArray + 16, eFullResAOZTexture, eFullResAOZTexture2, eCBVSRVUAVLayoutBaseMax }; enum RTVLayoutBase { eFullResViewDepthTextureRTV, eFullResViewDepthTexture2RTV, eFullResNormalTextureRTV, eQuarterResViewDepthTextureArrayRTV, eQuarterResAOTextureArrayRTV = eQuarterResViewDepthTextureArrayRTV + 1 + 16, eFullResAOZTextureRTV = eQuarterResAOTextureArrayRTV + 1 + 16, eFullResAOZTexture2RTV, eRTVLayoutBaseMax }; struct GFSDK_D3D12_DescriptorHeaps { GFSDK_D3D12_DescriptorHeap CBVSRVUAV; GFSDK_D3D12_DescriptorHeap RTV; void InitDescriptorHeaps(ID3D12Device* pDevice, const GFSDK_SSAO_DescriptorHeaps_D3D12& DescriptorHeaps) { CBVSRVUAV.InitDescriptorHeap(pDevice, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, &DescriptorHeaps.CBV_SRV_UAV, true); RTV.InitDescriptorHeap(pDevice, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, &DescriptorHeaps.RTV, false); } D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(CBVSRVUAVLayoutBase BaseOffset, UINT Index) { return CBVSRVUAV.GetGPUHandle(BaseOffset + Index); } void Release() { RTV.Release(); CBVSRVUAV.Release(); } }; inline void GFSDK_D3D12_SetResourceBarrier(ID3D12GraphicsCommandList* commandList, ID3D12Resource* res, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) { D3D12_RESOURCE_BARRIER desc = {}; desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; desc.Transition.pResource = res; desc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; desc.Transition.StateBefore = before; desc.Transition.StateAfter = after; desc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; commandList->ResourceBarrier(1, &desc); } struct GFSDK_D3D12_GraphicsContext { ID3D12Device* pDevice; GFSDK_D3D12_DescriptorHeaps DescHeaps; ID3D12GraphicsCommandList* pCmdList; ID3D12CommandQueue* pCmdQueue; ID3D12Fence* pFence; HANDLE hFenceEvent = 0; UINT64 FenceValue; UINT NodeMask; void Init(ID3D12Device* _pDevice, const GFSDK_SSAO_DescriptorHeaps_D3D12& DescriptorHeaps, UINT _NodeMask) { ASSERT(pDevice == NULL); ASSERT(pCmdList == NULL); ASSERT(pCmdQueue == NULL); pDevice = _pDevice; pCmdList = NULL; pCmdQueue = NULL; NodeMask = _NodeMask; DescHeaps.InitDescriptorHeaps(pDevice, DescriptorHeaps); THROW_IF_FAILED(pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&pFence))); #if _DEBUG pFence->SetName(L"SSAOFence"); #endif hFenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); FenceValue = 0; } // This should be called when the library ends void Release() { CloseHandle(hFenceEvent); SAFE_RELEASE(pFence); DescHeaps.Release(); } void IncrFenceValue() { FenceValue++; } void WaitGPUIdle() { // Schedule a Signal command in the queue. THROW_IF_FAILED(pCmdQueue->Signal(pFence, FenceValue)); THROW_IF_FAILED(pFence->SetEventOnCompletion(FenceValue, hFenceEvent)); WaitForSingleObjectEx(hFenceEvent, INFINITE, FALSE); } void AddResourceBarrier(ID3D12Resource* pResource, D3D12_RESOURCE_STATES OldState, D3D12_RESOURCE_STATES NewState) { if (OldState = NewState) { return; } D3D12_RESOURCE_BARRIER BarrierDesc = {}; BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; BarrierDesc.Transition.pResource = pResource; BarrierDesc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; BarrierDesc.Transition.StateBefore = OldState; BarrierDesc.Transition.StateAfter = NewState; pCmdList->ResourceBarrier(1, &BarrierDesc); } }; struct GFSDK_D3D12_RootParameter { D3D12_ROOT_PARAMETER RootParam; }; #endif // SUPPORT_D3D12