diff options
Diffstat (limited to 'demo/d3d12/NvCoDx12RenderTarget.cpp')
| -rw-r--r-- | demo/d3d12/NvCoDx12RenderTarget.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/demo/d3d12/NvCoDx12RenderTarget.cpp b/demo/d3d12/NvCoDx12RenderTarget.cpp new file mode 100644 index 0000000..2ce4d86 --- /dev/null +++ b/demo/d3d12/NvCoDx12RenderTarget.cpp @@ -0,0 +1,324 @@ + +#include "NvCoDx12RenderTarget.h" +#include "appD3D12Ctx.h" + +#include <external/D3D12/include/d3dx12.h> + +namespace nvidia { +namespace Common { + +Dx12RenderTarget::Dx12RenderTarget() +{ + memset(m_srvIndices, -1, sizeof(m_srvIndices)); +} + +int Dx12RenderTarget::init(AppGraphCtxD3D12* renderContext, const Desc& desc) +{ + ID3D12Device* device = renderContext->m_device; + + m_desc = desc; + + // set viewport + { + m_viewport.Width = float(desc.m_width); + m_viewport.Height = float(desc.m_height); + m_viewport.MinDepth = 0; + m_viewport.MaxDepth = 1; + m_viewport.TopLeftX = 0; + m_viewport.TopLeftY = 0; + } + + { + m_scissorRect.left = 0; + m_scissorRect.top = 0; + m_scissorRect.right = desc.m_width; + m_scissorRect.bottom = desc.m_height; + } + + if (desc.m_targetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; + heapDesc.NumDescriptors = 1; + heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + NV_RETURN_ON_FAIL(device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_descriptorHeapRtv))); + + DXGI_FORMAT resourceFormat = DxFormatUtil::calcResourceFormat(DxFormatUtil::USAGE_TARGET, m_desc.m_usageFlags, desc.m_targetFormat); + DXGI_FORMAT targetFormat = DxFormatUtil::calcFormat(DxFormatUtil::USAGE_TARGET, resourceFormat); + + D3D12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(resourceFormat, UINT(desc.m_width), UINT(desc.m_height), 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_TEXTURE_LAYOUT_UNKNOWN, 0); + D3D12_HEAP_PROPERTIES heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); + + // Depending on usage this format may not be right... + D3D12_CLEAR_VALUE clearValue; + clearValue.Format = targetFormat; + clearValue.Color[0] = FLT_MAX; + clearValue.Color[1] = FLT_MAX; + clearValue.Color[2] = FLT_MAX; + clearValue.Color[3] = FLT_MAX; + + NV_RETURN_ON_FAIL(m_renderTarget.initCommitted(device, heapProps, D3D12_HEAP_FLAG_NONE, resourceDesc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, &clearValue)); + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = targetFormat; + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = 0; + rtvDesc.Texture2D.PlaneSlice = 0; + device->CreateRenderTargetView(m_renderTarget, &rtvDesc, m_descriptorHeapRtv->GetCPUDescriptorHandleForHeapStart()); + } + + // Create the depth stencil descriptor heap + if (desc.m_depthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; + heapDesc.NumDescriptors = 1; + heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + NV_RETURN_ON_FAIL(device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_descriptorHeapDsv))); + + DXGI_FORMAT resourceFormat = DxFormatUtil::calcResourceFormat(DxFormatUtil::USAGE_DEPTH_STENCIL, m_desc.m_usageFlags, desc.m_depthStencilFormat); + DXGI_FORMAT depthStencilFormat = DxFormatUtil::calcFormat(DxFormatUtil::USAGE_DEPTH_STENCIL, resourceFormat); + + D3D12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(resourceFormat, UINT(desc.m_width), UINT(desc.m_height), 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN, 0); + D3D12_HEAP_PROPERTIES heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); + + D3D12_CLEAR_VALUE clearValue; + clearValue.Format = depthStencilFormat; + clearValue.DepthStencil.Depth = 1.0f; + clearValue.DepthStencil.Stencil = 0; + NV_RETURN_ON_FAIL(m_depthStencilBuffer.initCommitted(device, heapProps, D3D12_HEAP_FLAG_NONE, resourceDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue)); + + // Create the depth stencil view + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Format = depthStencilFormat; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.Flags = D3D12_DSV_FLAG_NONE; + device->CreateDepthStencilView(m_depthStencilBuffer, &dsvDesc, m_descriptorHeapDsv->GetCPUDescriptorHandleForHeapStart()); + } + + return NV_OK; +} + +/* static */DxFormatUtil::UsageType Dx12RenderTarget::getUsageType(BufferType type) +{ + switch (type) + { + case BUFFER_DEPTH_STENCIL: return DxFormatUtil::USAGE_DEPTH_STENCIL; + case BUFFER_TARGET: return DxFormatUtil::USAGE_TARGET; + default: return DxFormatUtil::USAGE_UNKNOWN; + } +} + +void Dx12RenderTarget::bind(AppGraphCtxD3D12* renderContext) +{ + ID3D12GraphicsCommandList* commandList = renderContext->m_commandList; + + // Work out what is bound + int numTargets = 0; + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {}; + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = {}; + + if (m_renderTarget) + { + rtvHandle = m_descriptorHeapRtv->GetCPUDescriptorHandleForHeapStart(); + numTargets = 1; + } + if (m_depthStencilBuffer) + { + dsvHandle = m_descriptorHeapDsv->GetCPUDescriptorHandleForHeapStart(); + commandList->OMSetRenderTargets(numTargets, &rtvHandle, FALSE, &dsvHandle); + } + else + { + commandList->OMSetRenderTargets(numTargets, &rtvHandle, FALSE, nullptr); + } + + commandList->RSSetViewports(1, &m_viewport); + commandList->RSSetScissorRects(1, &m_scissorRect); +} + + +void Dx12RenderTarget::clear(AppGraphCtxD3D12* renderContext) +{ + ID3D12GraphicsCommandList* commandList = renderContext->m_commandList; + D3D12_RECT rect = { 0, 0, m_desc.m_width, m_desc.m_height }; + + // Clear + if (m_renderTarget) + { + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = m_descriptorHeapRtv->GetCPUDescriptorHandleForHeapStart(); + commandList->ClearRenderTargetView(rtvHandle, m_desc.m_targetClearColor, 1, &rect); + } + if (m_depthStencilBuffer) + { + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = m_descriptorHeapDsv->GetCPUDescriptorHandleForHeapStart(); + commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, m_desc.m_depthStencilClearDepth, 0, 1, &rect); + } +} + +void Dx12RenderTarget::bindAndClear(AppGraphCtxD3D12* renderContext) +{ + ID3D12GraphicsCommandList* commandList = renderContext->m_commandList; + + // Work out what is bound + int numTargets = 0; + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {}; + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = {}; + + if (m_renderTarget) + { + rtvHandle = m_descriptorHeapRtv->GetCPUDescriptorHandleForHeapStart(); + numTargets = 1; + } + if (m_depthStencilBuffer) + { + dsvHandle = m_descriptorHeapDsv->GetCPUDescriptorHandleForHeapStart(); + commandList->OMSetRenderTargets(numTargets, &rtvHandle, FALSE, &dsvHandle); + } + else + { + commandList->OMSetRenderTargets(numTargets, &rtvHandle, FALSE, nullptr); + } + + commandList->RSSetViewports(1, &m_viewport); + commandList->RSSetScissorRects(1, &m_scissorRect); + + D3D12_RECT rect = { 0, 0, m_desc.m_width, m_desc.m_height }; + + // Clear + if (m_renderTarget) + { + commandList->ClearRenderTargetView(rtvHandle, m_desc.m_targetClearColor, 1, &rect); + } + if (m_depthStencilBuffer) + { + commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, m_desc.m_depthStencilClearDepth, 0, 1, &rect); + } +} + +void Dx12RenderTarget::setShadowDefaultLight(FXMVECTOR eye, FXMVECTOR at, FXMVECTOR up) +{ + float sizeX = 50.0f; + float sizeY = 50.0f; + float znear = -200.0f; + float zfar = 200.0f; + + setShadowLightMatrices(eye, at, up, sizeX, sizeY, znear, zfar); +} + +void Dx12RenderTarget::setShadowLightMatrices(FXMVECTOR eye, FXMVECTOR lookAt, FXMVECTOR up, float sizeX, float sizeY, float zNear, float zFar) +{ + m_shadowLightView = XMMatrixLookAtLH(eye, lookAt, up); + m_shadowLightProjection = XMMatrixOrthographicLH(sizeX, sizeY, zNear, zFar); + DirectX::XMMATRIX clip2Tex(0.5, 0, 0, 0, + 0, -0.5, 0, 0, + 0, 0, 1, 0, + 0.5, 0.5, 0, 1); + DirectX::XMMATRIX viewProjection = m_shadowLightView * m_shadowLightProjection; + m_shadowLightWorldToTex = viewProjection * clip2Tex; +} + +void Dx12RenderTarget::toWritable(AppGraphCtxD3D12* renderContext) +{ + Dx12BarrierSubmitter submitter(renderContext->m_commandList); + + m_renderTarget.transition(D3D12_RESOURCE_STATE_RENDER_TARGET, submitter); + m_depthStencilBuffer.transition(D3D12_RESOURCE_STATE_DEPTH_WRITE, submitter); +} + +void Dx12RenderTarget::toReadable(AppGraphCtxD3D12* renderContext) +{ + Dx12BarrierSubmitter submitter(renderContext->m_commandList); + + m_renderTarget.transition(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, submitter); + m_depthStencilBuffer.transition(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, submitter); +} + +DXGI_FORMAT Dx12RenderTarget::getSrvFormat(BufferType type) const +{ + return Dx12Resource::calcFormat(DxFormatUtil::USAGE_SRV, getResource(type)); +} + +DXGI_FORMAT Dx12RenderTarget::getTargetFormat(BufferType type) const +{ + return Dx12Resource::calcFormat(getUsageType(type), getResource(type)); +} + +D3D12_SHADER_RESOURCE_VIEW_DESC Dx12RenderTarget::calcDefaultSrvDesc(BufferType type) const +{ + ID3D12Resource* resource = getResource(type); + + D3D12_RESOURCE_DESC resourceDesc = resource->GetDesc(); + + D3D12_SHADER_RESOURCE_VIEW_DESC desc; + + desc.Format = getSrvFormat(type); + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + + desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + + desc.Texture2D.MipLevels = resourceDesc.MipLevels; + desc.Texture2D.MostDetailedMip = 0; + desc.Texture2D.PlaneSlice = 0; + desc.Texture2D.ResourceMinLODClamp = 0.0f; + return desc; +} + +int Dx12RenderTarget::allocateSrvView(BufferType type, ID3D12Device* device, Dx12DescriptorHeap& heap, const D3D12_SHADER_RESOURCE_VIEW_DESC* desc) +{ + if (m_srvIndices[type] >= 0) + { + printf("A srv index has already been associated!"); + return m_srvIndices[type]; + } + + if (!desc) + { + // If not set construct a default desc + D3D12_SHADER_RESOURCE_VIEW_DESC defaultDesc = calcDefaultSrvDesc(type); + return allocateSrvView(type, device, heap, &defaultDesc); + } + + // Create the srv for the shadow buffer + ID3D12Resource* resource = getResource(type); + int srvIndex = heap.allocate(); + + if (srvIndex < 0) + { + return srvIndex; + } + + // Create on the the heap + device->CreateShaderResourceView(resource, desc, heap.getCpuHandle(srvIndex)); + + m_srvIndices[type] = srvIndex; + // Return the allocated index + return srvIndex; +} + +void Dx12RenderTarget::setDebugName(BufferType type, const std::wstring& name) +{ + getResource(type).setDebugName(name); +} + +void Dx12RenderTarget::setDebugName(const std::wstring& name) +{ + std::wstring buf(name); + buf += L" [Target]"; + setDebugName(BUFFER_TARGET, buf); + buf = name; + buf += L" [DepthStencil]"; + setDebugName(BUFFER_DEPTH_STENCIL, buf); +} + + +void Dx12RenderTarget::createSrv(ID3D12Device* device, Dx12DescriptorHeap& heap, BufferType type, int descriptorIndex) +{ + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = calcDefaultSrvDesc(type); + ID3D12Resource* resource = getResource(type); + device->CreateShaderResourceView(resource, &srvDesc, heap.getCpuHandle(descriptorIndex)); +} + +} // namespace Common +} // namespace nvidia |