diff options
| author | lbavoil <[email protected]> | 2016-03-25 13:01:54 +0100 |
|---|---|---|
| committer | lbavoil <[email protected]> | 2016-03-25 13:01:54 +0100 |
| commit | 99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c (patch) | |
| tree | fbcd4260d6c953d569a887505336a1c3f202e10f /src/ConstantBuffers.h | |
| download | hbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.tar.xz hbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.zip | |
GFSDK_HBAO+_distro_r3.0_cl20573789
Diffstat (limited to 'src/ConstantBuffers.h')
| -rw-r--r-- | src/ConstantBuffers.h | 496 |
1 files changed, 496 insertions, 0 deletions
diff --git a/src/ConstantBuffers.h b/src/ConstantBuffers.h new file mode 100644 index 0000000..7fd9955 --- /dev/null +++ b/src/ConstantBuffers.h @@ -0,0 +1,496 @@ +/* +* 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. +*/ + +#pragma once +#include "Viewports.h" +#include "InputDepthInfo.h" +#include "MathUtil.h" +#include "RandomTexture.h" +#include "shaders/src/ConstantBuffers.hlsl" + +namespace GFSDK +{ +namespace SSAO +{ + +//-------------------------------------------------------------------------------- +class GlobalConstants +{ +public: + GlobalConstants() + { + ZERO_STRUCT(m_Data); + m_Data.iTrue = 1; + + // Can be useful for figuring out the HBAO+ version from an APIC or NSight capture + m_Data.u4BuildVersion = GFSDK_SSAO_Version(); + } + + void SetAOParameters(const GFSDK_SSAO_Parameters& Params, const InputDepthInfo& InputDepth); + void SetRenderMask(GFSDK_SSAO_RenderMask RenderMask); + void SetDepthData(const InputDepthInfo& InputDepth); + void SetResolutionConstants(const SSAO::Viewports &Viewports); + void SetNormalData(const GFSDK_SSAO_InputNormalData& NormalData); + +protected: + GlobalConstantBuffer m_Data; + + void SetDepthLinearizationConstants(const InputDepthInfo& InputDepth); + void SetProjectionConstants(const InputDepthInfo& InputDepth); + void SetViewportConstants(const InputDepthInfo& InputDepth); + + void SetBlurConstants(const GFSDK_SSAO_BlurParameters& Params, const InputDepthInfo& InputDepth); + void SetAORadiusConstants(const GFSDK_SSAO_Parameters& Params, const InputDepthInfo& InputDepth); + void SetDepthThresholdConstants(const GFSDK_SSAO_DepthThreshold& Params); +}; + +//-------------------------------------------------------------------------------- +class PerPassConstants +{ +public: + PerPassConstants() + { + ZERO_STRUCT(m_Data); + } + + void SetOffset(UINT OffsetX, UINT OffsetY) + { + m_Data.PerPassConstants.f2Offset.X = float(OffsetX) + 0.5f; + m_Data.PerPassConstants.f2Offset.Y = float(OffsetY) + 0.5f; + } + + void SetJitter(float4 Jitter) + { + m_Data.PerPassConstants.f4Jitter = Jitter; + } + + void SetSliceIndex(UINT SliceIndex) + { + m_Data.PerPassConstants.fSliceIndex = float(SliceIndex); + m_Data.PerPassConstants.uSliceIndex = SliceIndex; + } + +protected: + PerPassConstantBuffer m_Data; +}; + +//-------------------------------------------------------------------------------- +#if SUPPORT_D3D11 +namespace D3D11 +{ + +class BaseConstantBuffer +{ +public: + BaseConstantBuffer(UINT ByteWidth) + : m_ByteWidth(ByteWidth) + , m_pConstantBuffer(NULL) + { + } + + void Create(ID3D11Device* pD3DDevice, D3D11_SUBRESOURCE_DATA* pSubresourceData = NULL) + { + D3D11_BUFFER_DESC BufferDesc = + { + m_ByteWidth, //ByteWidth + D3D11_USAGE_DEFAULT, //Usage + D3D11_BIND_CONSTANT_BUFFER, //BindFlags + 0, //CPUAccessFlags + 0 //MiscFlags + }; + + // The D3D11 runtime requires constant buffer sizes to be multiple of 16 bytes + ASSERT(BufferDesc.ByteWidth % 16 == 0); + + ASSERT(!m_pConstantBuffer); + SAFE_D3D_CALL( pD3DDevice->CreateBuffer(&BufferDesc, pSubresourceData, &m_pConstantBuffer) ); + } + + void Release() + { + SAFE_RELEASE(m_pConstantBuffer); + } + + void UpdateCB(ID3D11DeviceContext* pDeviceContext, void* pData) + { + ASSERT(m_pConstantBuffer); + + pDeviceContext->UpdateSubresource(m_pConstantBuffer, 0, NULL, pData, 0, 0); + } + + ID3D11Buffer*& GetCB() + { + return m_pConstantBuffer; + } + +protected: + UINT m_ByteWidth; + ID3D11Buffer *m_pConstantBuffer; +}; + +//-------------------------------------------------------------------------------- +class GlobalConstantBuffer : public GlobalConstants, public D3D11::BaseConstantBuffer +{ +public: + GlobalConstantBuffer() + : GlobalConstants() + , D3D11::BaseConstantBuffer(sizeof(m_Data)) + { + } + void UpdateBuffer(ID3D11DeviceContext* pDeviceContext, GFSDK_SSAO_RenderMask RenderMask) + { + SetRenderMask(RenderMask); + UpdateCB(pDeviceContext, &m_Data); + } +}; + +//-------------------------------------------------------------------------------- +class PerPassConstantBuffer : public PerPassConstants, public D3D11::BaseConstantBuffer +{ +public: + PerPassConstantBuffer() + : PerPassConstants() + , D3D11::BaseConstantBuffer(sizeof(m_Data)) + { + } + void Create(ID3D11Device* pD3DDevice) + { + D3D11_SUBRESOURCE_DATA SubresourceData = { &m_Data }; + D3D11::BaseConstantBuffer::Create(pD3DDevice, &SubresourceData); + } +}; + +//-------------------------------------------------------------------------------- +class PerPassConstantBuffers +{ +public: + void Create(ID3D11Device* pD3DDevice) + { + for (UINT SliceIndex = 0; SliceIndex < SIZEOF_ARRAY(m_CBs); ++SliceIndex) + { + m_CBs[SliceIndex].SetOffset(SliceIndex % 4, SliceIndex / 4); + m_CBs[SliceIndex].SetJitter(m_RandomTexture.GetJitter(SliceIndex)); + m_CBs[SliceIndex].SetSliceIndex(SliceIndex); + m_CBs[SliceIndex].Create(pD3DDevice); + } + } + void Release() + { + for (UINT PassIndex = 0; PassIndex < SIZEOF_ARRAY(m_CBs); ++PassIndex) + { + m_CBs[PassIndex].Release(); + } + } + ID3D11Buffer*& GetCB(UINT PassIndex) + { + ASSERT(PassIndex < SIZEOF_ARRAY(m_CBs)); + return m_CBs[PassIndex].GetCB(); + } + +private: + PerPassConstantBuffer m_CBs[16]; + GFSDK::SSAO::RandomTexture m_RandomTexture; +}; + +} // namespace D3D11 +#endif // SUPPORT_D3D11 + +//-------------------------------------------------------------------------------- +#if SUPPORT_D3D12 +namespace D3D12 +{ + +//-------------------------------------------------------------------------------- +struct GFSDK_D3D12_ConstantBufferView +{ + ID3D12Resource* pResource; + D3D12_CONSTANT_BUFFER_VIEW_DESC Desc; + D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle; +}; + +//-------------------------------------------------------------------------------- +class BaseConstantBuffer +{ +public: + BaseConstantBuffer(UINT ByteWidth) + : m_ByteWidth(ByteWidth) + { + } + + void Create(GFSDK_D3D12_GraphicsContext* pContext, CBVSRVUAVLayoutBase Base, UINT BaseOffset) + { + ASSERT(!m_pConstantBuffer.pResource); + + // CB size is required to be 256-byte aligned. + const UINT AlignedByteWidth = ALIGNED_SIZE(m_ByteWidth, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT); + + THROW_IF_FAILED(pContext->pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD, pContext->NodeMask, pContext->NodeMask), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(AlignedByteWidth), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&m_pConstantBuffer.pResource))); + + D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; + cbvDesc.BufferLocation = m_pConstantBuffer.pResource->GetGPUVirtualAddress(); + cbvDesc.SizeInBytes = AlignedByteWidth; + + m_pConstantBuffer.CpuHandle = pContext->DescHeaps.CBVSRVUAV.GetCPUHandle((UINT)Base + BaseOffset); + pContext->pDevice->CreateConstantBufferView(&cbvDesc, m_pConstantBuffer.CpuHandle); + + m_pConstantBuffer.pResource->Map(0, nullptr, reinterpret_cast<void**>(&mCBUploadPtr)); + } + + void Release() + { + if (m_pConstantBuffer.pResource) + { + m_pConstantBuffer.pResource->Unmap(0, nullptr); + SAFE_RELEASE(m_pConstantBuffer.pResource); + } + } + + void UpdateCB(GFSDK_D3D12_GraphicsContext* pGraphicsContext, void* pData) + { + memcpy(mCBUploadPtr, pData, m_ByteWidth); + } + + GFSDK_D3D12_ConstantBufferView m_pConstantBuffer; + +protected: + UINT m_ByteWidth; + void* mCBUploadPtr; +}; + +//-------------------------------------------------------------------------------- +class GlobalConstantBuffer : public GlobalConstants, public D3D12::BaseConstantBuffer +{ +public: + GlobalConstantBuffer() + : GlobalConstants() + , D3D12::BaseConstantBuffer(sizeof(m_Data)) + { + } + void UpdateBuffer(GFSDK_D3D12_GraphicsContext* pGraphicsContext, GFSDK_SSAO_RenderMask RenderMask) + { + SetRenderMask(RenderMask); + UpdateCB(pGraphicsContext, &m_Data); + } +}; + +//-------------------------------------------------------------------------------- +class PerPassConstantBuffer : public PerPassConstants, public D3D12::BaseConstantBuffer +{ +public: + PerPassConstantBuffer() + : PerPassConstants() + , D3D12::BaseConstantBuffer(sizeof(m_Data)) + { + } + void UpdateBuffer(GFSDK_D3D12_GraphicsContext* pGraphicsContext) + { + UpdateCB(pGraphicsContext, &m_Data); + } +}; + +//-------------------------------------------------------------------------------- +class PerPassConstantBuffers +{ +public: + void Create(GFSDK_D3D12_GraphicsContext* pD3DDevice, CBVSRVUAVLayoutBase Base) + { + for (UINT SliceIndex = 0; SliceIndex < SIZEOF_ARRAY(m_CBs); ++SliceIndex) + { + m_CBs[SliceIndex].SetOffset(SliceIndex % 4, SliceIndex / 4); + m_CBs[SliceIndex].SetJitter(m_RandomTexture.GetJitter(SliceIndex)); + m_CBs[SliceIndex].SetSliceIndex(SliceIndex); + + m_CBs[SliceIndex].Create(pD3DDevice, Base, SliceIndex); + m_CBs[SliceIndex].UpdateBuffer(pD3DDevice); + } + } + void Release() + { + for (UINT PassIndex = 0; PassIndex < SIZEOF_ARRAY(m_CBs); ++PassIndex) + { + m_CBs[PassIndex].Release(); + } + } + +private: + PerPassConstantBuffer m_CBs[16]; + GFSDK::SSAO::RandomTexture m_RandomTexture; +}; + +} // namespace D3D12 +#endif // SUPPORT_D3D12 + +#if SUPPORT_GL +namespace GL +{ + +class BaseConstantBuffer +{ +public: + BaseConstantBuffer(UINT ByteWidth, GLuint BindingPoint) + : m_ByteWidth(ByteWidth) + , m_BufferId(0) + , m_BindingPoint(BindingPoint) + { + } + + void Create(const GFSDK_SSAO_GLFunctions& GL) + { + ASSERT(!m_BufferId); + GL.glGenBuffers(1, &m_BufferId); + + GL.glBindBuffer(GL_UNIFORM_BUFFER, m_BufferId); + GL.glBufferData(GL_UNIFORM_BUFFER, m_ByteWidth, NULL, GL_DYNAMIC_DRAW); + GL.glBindBuffer(GL_UNIFORM_BUFFER, 0); + ASSERT_GL_ERROR(GL); + } + + void Release(const GFSDK_SSAO_GLFunctions& GL) + { + GL.glDeleteBuffers(1, &m_BufferId); + m_BufferId = 0; + } + + void Unbind(const GFSDK_SSAO_GLFunctions& GL) + { + GL.glBindBufferBase(GL_UNIFORM_BUFFER, m_BindingPoint, 0); + ASSERT_GL_ERROR(GL); + } + + void UpdateCB(const GFSDK_SSAO_GLFunctions& GL, void* pData) + { + ASSERT(m_BufferId); + + GL.glBindBufferBase(GL_UNIFORM_BUFFER, m_BindingPoint, m_BufferId); + ASSERT_GL_ERROR(GL); + + // Do not use glMapBuffer for updating constant buffers (slow path on GL). + // glBufferSubData has a fast path for UBO. + GL.glBufferSubData(GL_UNIFORM_BUFFER, 0, m_ByteWidth, pData); + ASSERT_GL_ERROR(GL); + } + + GLuint GetBindingPoint() + { + return m_BindingPoint; + } + + GLuint GetBufferId() + { + return m_BufferId; + } + + enum BindingPoints + { + BINDING_POINT_GLOBAL_UBO = 0, + BINDING_POINT_NORMAL_UBO = 1, + BINDING_POINT_PER_PASS_UBO = 2, + }; + +protected: + UINT m_ByteWidth; + GLuint m_BufferId; + GLuint m_BindingPoint; +}; + +//-------------------------------------------------------------------------------- +class GlobalConstantBuffer : public GlobalConstants, public GL::BaseConstantBuffer +{ +public: + GlobalConstantBuffer() + : GlobalConstants() + , GL::BaseConstantBuffer(sizeof(m_Data), BINDING_POINT_GLOBAL_UBO) + { + } + void UpdateBuffer(const GFSDK_SSAO_GLFunctions& GL, GFSDK_SSAO_RenderMask RenderMask) + { + SetRenderMask(RenderMask); + UpdateCB(GL, &m_Data); + } +}; + +//-------------------------------------------------------------------------------- +class PerPassConstantBuffer : public PerPassConstants, public GL::BaseConstantBuffer +{ +public: + PerPassConstantBuffer() + : PerPassConstants() + , GL::BaseConstantBuffer(sizeof(m_Data), BINDING_POINT_PER_PASS_UBO) + { + } + void UpdateBuffer(const GFSDK_SSAO_GLFunctions& GL) + { + UpdateCB(GL, &m_Data); + } +}; + +//-------------------------------------------------------------------------------- +class PerPassConstantBuffers +{ +public: + void Create(const GFSDK_SSAO_GLFunctions& GL) + { + for (UINT SliceIndex = 0; SliceIndex < SIZEOF_ARRAY(m_CBs); ++SliceIndex) + { + m_CBs[SliceIndex].Create(GL); + + UINT JitterX = SliceIndex % 4; + UINT JitterY = SliceIndex / 4; + + m_CBs[SliceIndex].SetOffset(JitterX, JitterY); + m_CBs[SliceIndex].SetJitter(GetJitterVector(JitterX, JitterY)); + m_CBs[SliceIndex].SetSliceIndex(SliceIndex); + m_CBs[SliceIndex].UpdateBuffer(GL); + } + } + void Release(const GFSDK_SSAO_GLFunctions& GL) + { + for (UINT PassIndex = 0; PassIndex < SIZEOF_ARRAY(m_CBs); ++PassIndex) + { + m_CBs[PassIndex].Release(GL); + } + } + GLuint GetBufferId(UINT PassIndex) + { + ASSERT(PassIndex < SIZEOF_ARRAY(m_CBs)); + return m_CBs[PassIndex].GetBufferId(); + } + GLuint GetBindingPoint() + { + return m_CBs[0].GetBindingPoint(); + } + void Unbind(const GFSDK_SSAO_GLFunctions& GL) + { + m_CBs[0].Unbind(GL); + } + +private: + float4 GetJitterVector(UINT JitterX, UINT JitterY) + { + // To match the reference D3D11 implementation + JitterY = 3 - JitterY; + return m_RandomTexture.GetJitter(JitterY * 4 + JitterX); + } + + PerPassConstantBuffer m_CBs[16]; + GFSDK::SSAO::RandomTexture m_RandomTexture; +}; + +} // namespace GL +#endif // SUPPORT_GL + +} // namespace SSAO +} // namespace GFSDK |