.. _program_listing_file_Source_Azura_RenderSystem_Src_D3D12_D3D12ScopedRenderPass.cpp: Program Listing for File D3D12ScopedRenderPass.cpp ================================================== |exhale_lsh| :ref:`Return to documentation for file ` (``Source\Azura\RenderSystem\Src\D3D12\D3D12ScopedRenderPass.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "D3D12/D3D12ScopedRenderPass.h" #include "D3D12/D3D12Macros.h" #include "Memory/MonotonicAllocator.h" #include "Memory/MemoryFactory.h" #include "D3D12/D3D12TypeMapping.h" #include "D3D12/D3D12ScopedSwapChain.h" #include "D3D12/D3D12ScopedImage.h" #include "D3D12/D3D12ScopedShader.h" using namespace Microsoft::WRL; // NOLINT using namespace Azura::Containers; // NOLINT namespace Azura { namespace D3D12 { D3D12ScopedRenderPass::D3D12ScopedRenderPass(U32 idx, U32 internalId, const D3D12ScopedSwapChain& swapChain, Memory::Allocator& mainAllocator, Log logger) : log_D3D12RenderSystem(std::move(logger)), m_id(idx), m_internalId(internalId), m_swapChainRef(swapChain), m_rootSignatureTable(mainAllocator), m_renderOutputInfo(mainAllocator), m_passShaders(mainAllocator), m_passInputs(mainAllocator), m_allRenderInputs(mainAllocator) { } void D3D12ScopedRenderPass::Create(const Microsoft::WRL::ComPtr& device, const PipelinePassCreateInfo& createInfo, const Containers::Vector& pipelineBuffers, const Containers::Vector& pipelineBufferImages, const Containers::Vector& descriptorSlots, const Containers::Vector& descriptorSetTable, const Containers::Vector& allShaders, UINT rtvDescriptorSize, UINT dsvDescriptorSize) { CreateBase(device, createInfo, descriptorSlots, descriptorSetTable, pipelineBuffers, pipelineBufferImages, allShaders); U32 numDSV = 0; U32 numRTV = 0; for (const auto& output : createInfo.m_outputTargets) { const auto& targetBuffer = pipelineBuffers[output]; if (HasDepthOrStencilComponent(targetBuffer.m_format)) { ++numDSV; continue; } ++numRTV; } D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; rtvHeapDesc.NumDescriptors = numRTV; rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)), "Failed to create RTV Heap for Render Pass"); D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {}; dsvHeapDesc.NumDescriptors = numDSV; dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)), "Failed to create DSV Heap for Render Pass"); CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); for (const auto& output : createInfo.m_outputTargets) { const auto& targetBuffer = pipelineBuffers[output]; auto& gpuTexture = pipelineBufferImages[output]; if (HasDepthOrStencilComponent(targetBuffer.m_format)) { const auto dsvDesc = D3D12ScopedImage::GetDSV(targetBuffer.m_format, ImageViewType::ImageView2D, log_D3D12RenderSystem); device->CreateDepthStencilView(gpuTexture.Real(), &dsvDesc, dsvHandle); dsvHandle.Offset(1, dsvDescriptorSize); m_hasDepth = true; m_depthOutputs.push_back(gpuTexture); continue; } m_renderOutputs.push_back(gpuTexture); const auto rtvDesc = D3D12ScopedImage::GetRTV(targetBuffer.m_format, ImageViewType::ImageView2D, log_D3D12RenderSystem); device->CreateRenderTargetView(gpuTexture.Real(), &rtvDesc, rtvHandle); rtvHandle.Offset(1, rtvDescriptorSize); } D3D12ScopedCommandBuffer primaryCmdBuffer = D3D12ScopedCommandBuffer(device, D3D12_COMMAND_LIST_TYPE_DIRECT, log_D3D12RenderSystem); primaryCmdBuffer.CreateGraphicsCommandList(device, nullptr, log_D3D12RenderSystem); m_commandBuffers.push_back(primaryCmdBuffer); } void D3D12ScopedRenderPass::CreateForSwapChain(const Microsoft::WRL::ComPtr& device, const PipelinePassCreateInfo& createInfo, const Containers::Vector& pipelineBuffers, const Containers::Vector& pipelineBufferImages, const D3D12ScopedImage& depthImage, const Containers::Vector& descriptorSlots, const Containers::Vector& descriptorSetTable, const Containers::Vector& allShaders, UINT rtvDescriptorSize, UINT dsvDescriptorSize) { UNUSED(dsvDescriptorSize); CreateBase(device, createInfo, descriptorSlots, descriptorSetTable, pipelineBuffers, pipelineBufferImages, allShaders); m_hasDepth = false; m_isTargetSwapChain = true; D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; rtvHeapDesc.NumDescriptors = GLOBAL_INFLIGHT_FRAMES; rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)), "Failed to create RTV Heap for Swap Chain"); // Create Frame buffers CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); // Create a RTV for each frame. for (U32 idx = 0; idx < GLOBAL_INFLIGHT_FRAMES; idx++) { Microsoft::WRL::ComPtr renderTarget = {}; VERIFY_D3D_OP(log_D3D12RenderSystem, m_swapChainRef.get().RealComPtr()->GetBuffer(idx, IID_PPV_ARGS(&renderTarget)), "Failed to get swapchain buffer"); m_swapChainImageResources.push_back(renderTarget.Get()); device->CreateRenderTargetView(renderTarget.Get(), nullptr, rtvHandle); rtvHandle.Offset(1, rtvDescriptorSize); } for (U32 idx = 0; idx < GLOBAL_INFLIGHT_FRAMES; ++idx) { D3D12ScopedCommandBuffer primaryCmdBuffer = D3D12ScopedCommandBuffer(device, D3D12_COMMAND_LIST_TYPE_DIRECT, log_D3D12RenderSystem); primaryCmdBuffer.CreateGraphicsCommandList(device, nullptr, log_D3D12RenderSystem); m_commandBuffers.push_back(primaryCmdBuffer); } // Create Depth View for Swapchain if Requested if (depthImage.GetFormat() != RawStorageFormat::UNKNOWN) { D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {}; dsvHeapDesc.NumDescriptors = 1; dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)), "Failed to create DSV Heap for Swap Chain"); const CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); const auto dsvDesc = D3D12ScopedImage::GetDSV(depthImage.GetFormat(), ImageViewType::ImageView2D, log_D3D12RenderSystem); device->CreateDepthStencilView(depthImage.Real(), &dsvDesc, dsvHandle); m_hasDepth = true; } } U32 D3D12ScopedRenderPass::GetId() const { return m_id; } U32 D3D12ScopedRenderPass::GetInternalId() const { return m_internalId; } ID3D12GraphicsCommandList* D3D12ScopedRenderPass::GetPrimaryGraphicsCommandList(U32 idx) const { return m_commandBuffers[idx].GetGraphicsCommandList(); } const DescriptorCount& D3D12ScopedRenderPass::GetDescriptorCount() const { return m_descriptorCount; } ID3D12RootSignature* D3D12ScopedRenderPass::GetRootSignature() const { return m_rootSignature.Get(); } void D3D12ScopedRenderPass::RecordImageAcquireBarrier(ID3D12GraphicsCommandList* commandList, U32 idx) const { CD3DX12_RESOURCE_BARRIER startBarrier = CD3DX12_RESOURCE_BARRIER::Transition( m_swapChainImageResources[idx], D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); commandList->ResourceBarrier(1, &startBarrier); } void D3D12ScopedRenderPass::RecordPresentBarrier(ID3D12GraphicsCommandList* commandList, U32 idx) const { CD3DX12_RESOURCE_BARRIER endBarrier = CD3DX12_RESOURCE_BARRIER::Transition( m_swapChainImageResources[idx], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); commandList->ResourceBarrier(1, &endBarrier); } void D3D12ScopedRenderPass::SetRenderTargets(ID3D12GraphicsCommandList* commandList, U32 cBufferIdx, UINT rtvDescriptorSize) const { CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), cBufferIdx, rtvDescriptorSize); const U32 numRTV = m_isTargetSwapChain ? 1u : U32(m_renderOutputs.size()); // Set Both Depth & RTV if (m_hasDepth) { CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); commandList->OMSetRenderTargets(numRTV, &rtvHandle, 1, &dsvHandle); commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, m_clearData.m_depth, m_clearData.m_stencil, 0, nullptr); } // Set Only RTV else { commandList->OMSetRenderTargets(numRTV, &rtvHandle, 1, nullptr); } commandList->ClearRenderTargetView(rtvHandle, m_clearData.m_color, 0, nullptr); // NOLINT } const Containers::Vector>& D3D12ScopedRenderPass::GetShaders() const { return m_passShaders; } const Vector>& D3D12ScopedRenderPass:: GetInputInfo() const { return m_passInputs; } const Vector>& D3D12ScopedRenderPass::GetInputImages() const { return m_allRenderInputs; } const Containers::Vector& D3D12ScopedRenderPass::GetRootSignatureTable() const { return m_rootSignatureTable; } void D3D12ScopedRenderPass::RecordResourceBarriersForOutputsStart(ID3D12GraphicsCommandList* commandList) const { for (auto& rtv : m_renderOutputs) { rtv.get().Transition(commandList, D3D12_RESOURCE_STATE_RENDER_TARGET, log_D3D12RenderSystem); } for (auto& dsv : m_depthOutputs) { dsv.get().Transition(commandList, D3D12_RESOURCE_STATE_DEPTH_WRITE, log_D3D12RenderSystem); } } void D3D12ScopedRenderPass::RecordResourceBarriersForOutputsEnd(ID3D12GraphicsCommandList* commandList) const { for (auto& rtv : m_renderOutputs) { rtv.get().Transition(commandList, D3D12_RESOURCE_STATE_COMMON, log_D3D12RenderSystem); } for (auto& dsv : m_depthOutputs) { dsv.get().Transition(commandList, D3D12_RESOURCE_STATE_COMMON, log_D3D12RenderSystem); } } void D3D12ScopedRenderPass::RecordResourceBarriersForInputsStart(ID3D12GraphicsCommandList* commandList) const { for (auto& rtv : m_renderInputs) { rtv.get().Transition(commandList, D3D12_RESOURCE_STATE_GENERIC_READ, log_D3D12RenderSystem); } for (auto& dsv : m_depthInputs) { dsv.get().Transition(commandList, D3D12_RESOURCE_STATE_GENERIC_READ, log_D3D12RenderSystem); } } void D3D12ScopedRenderPass::RecordResourceBarriersForInputsEnd(ID3D12GraphicsCommandList* commandList) const { for (auto& rtv : m_renderInputs) { rtv.get().Transition(commandList, D3D12_RESOURCE_STATE_COMMON, log_D3D12RenderSystem); } for (auto& dsv : m_depthInputs) { dsv.get().Transition(commandList, D3D12_RESOURCE_STATE_COMMON, log_D3D12RenderSystem); } } void D3D12ScopedRenderPass::RecordResourceBarriersForWritingInputs(ID3D12GraphicsCommandList* commandList) const { for (auto& rtv : m_renderInputs) { rtv.get().Transition(commandList, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET, log_D3D12RenderSystem); } for (auto& dsv : m_depthInputs) { dsv.get().Transition(commandList, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE, log_D3D12RenderSystem); } } void D3D12ScopedRenderPass::WaitForGPU(ID3D12CommandQueue* commandQueue) { const U32 fence = m_fenceValue; VERIFY_D3D_OP(log_D3D12RenderSystem, commandQueue->Signal(m_signalFence.Get(), m_fenceValue), "Fence wait failed"); m_fenceValue++; // Wait until the previous frame is finished. if (m_signalFence->GetCompletedValue() < fence) { VERIFY_D3D_OP(log_D3D12RenderSystem, m_signalFence->SetEventOnCompletion(fence, m_fenceEvent), "Failed to set event completion on Fence"); WaitForSingleObject(m_fenceEvent, INFINITE); } } U32 D3D12ScopedRenderPass::GetCommandBufferCount() const { return U32(m_commandBuffers.size()); } void D3D12ScopedRenderPass::ApplyBlendToPSO(D3D12_GRAPHICS_PIPELINE_STATE_DESC& psoDesc, U32 id) const { if (!m_blendState.m_enable) { return; } const auto colorBlendOp = ToD3D12_BLEND_OP(m_blendState.m_color.m_op); VERIFY_OPT(log_D3D12RenderSystem, colorBlendOp, "Unknown Blend Op For Color in Pipeline Render Target"); const auto alphaBlendOp = ToD3D12_BLEND_OP(m_blendState.m_alpha.m_op); VERIFY_OPT(log_D3D12RenderSystem, alphaBlendOp, "Unknown Blend Op For Alpha in Pipeline Render Target"); const auto colorSrcFactor = ToD3D12_BLEND(m_blendState.m_color.m_srcFactor); VERIFY_OPT(log_D3D12RenderSystem, colorSrcFactor, "Unknown Source Color Factor for Blend in Pipeline Render Target" ); const auto colorDstFactor = ToD3D12_BLEND(m_blendState.m_color.m_dstFactor); VERIFY_OPT(log_D3D12RenderSystem, colorDstFactor, "Unknown Dest Color Factor for Blend in Pipeline Render Target"); const auto alphaSrcFactor = ToD3D12_BLEND(m_blendState.m_alpha.m_srcFactor); VERIFY_OPT(log_D3D12RenderSystem, alphaSrcFactor, "Unknown Source Alpha Factor for Blend in Pipeline Render Target" ); const auto alphaDstFactor = ToD3D12_BLEND(m_blendState.m_alpha.m_dstFactor); VERIFY_OPT(log_D3D12RenderSystem, alphaDstFactor, "Unknown Dest Alpha Factor for Blend in Pipeline Render Target"); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.BlendState.RenderTarget[id].BlendEnable = static_cast(true); // NOLINT psoDesc.BlendState.RenderTarget[id].BlendOp = colorBlendOp.value(); // NOLINT psoDesc.BlendState.RenderTarget[id].BlendOpAlpha = alphaBlendOp.value(); // NOLINT psoDesc.BlendState.RenderTarget[id].SrcBlend = colorSrcFactor.value(); // NOLINT psoDesc.BlendState.RenderTarget[id].DestBlend = colorDstFactor.value(); // NOLINT psoDesc.BlendState.RenderTarget[id].SrcBlendAlpha = alphaSrcFactor.value(); // NOLINT psoDesc.BlendState.RenderTarget[id].DestBlendAlpha = alphaDstFactor.value(); // NOLINT } void D3D12ScopedRenderPass::UpdatePipelineInfo(D3D12_GRAPHICS_PIPELINE_STATE_DESC& psoDesc) { if (m_isTargetSwapChain) { const auto format = ToDXGI_FORMAT(m_swapChainRef.get().GetFormat()); VERIFY_OPT(log_D3D12RenderSystem, format, "Unknown Format - Swap Chain - For Pipeline Render Target Format"); if (m_hasDepth) { const auto depthFormat = ToDXGI_FORMAT(m_swapChainRef.get().GetDepthFormat()); VERIFY_OPT(log_D3D12RenderSystem, depthFormat, "Unknown Depth Format - Swap Chain - For Pipeline Render Target Format"); psoDesc.DSVFormat = depthFormat.value(); } psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); ApplyBlendToPSO(psoDesc, 0); psoDesc.RTVFormats[0] = format.value(); psoDesc.NumRenderTargets = 1; return; } U32 rtvIdx = 0; for (const auto& outputInfo : m_renderOutputInfo) { const auto format = ToDXGI_FORMAT(outputInfo.m_format); VERIFY_OPT(log_D3D12RenderSystem, format, "Unknown Format For Pipeline Render Target Format"); if (HasDepthOrStencilComponent(outputInfo.m_format)) { psoDesc.DSVFormat = format.value(); psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); continue; } ApplyBlendToPSO(psoDesc, rtvIdx); psoDesc.RTVFormats[rtvIdx] = format.value(); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index) ++rtvIdx; } psoDesc.NumRenderTargets = m_renderOutputInfo.GetSize(); } void D3D12ScopedRenderPass::CreateBase( const Microsoft::WRL::ComPtr& device, const PipelinePassCreateInfo& createInfo, const Containers::Vector& descriptorSlots, const Containers::Vector& descriptorSetTable, const Containers::Vector& pipelineBuffers, const Containers::Vector& pipelineBufferImages, const Containers::Vector& allShaders) { STACK_ALLOCATOR(Temporary, Memory::MonotonicAllocator, 2048); VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_signalFence)), "Failed to create fence"); m_blendState = createInfo.m_blendState; m_clearData = createInfo.m_clearData; // Create an event handle to use for frame synchronization. m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (m_fenceEvent == nullptr) { VERIFY_D3D_OP(log_D3D12RenderSystem, HRESULT_FROM_WIN32(GetLastError()), "Fence Event Null"); } m_passShaders.Reserve(U32(createInfo.m_shaders.size())); m_passInputs.Reserve(U32(createInfo.m_inputTargets.size())); m_renderOutputInfo.Reserve(U32(createInfo.m_outputTargets.size())); m_allRenderInputs.Reserve(U32(createInfo.m_inputTargets.size())); for (const auto& outputId : createInfo.m_outputTargets) { const auto& targetBufferRef = pipelineBuffers[outputId]; m_renderOutputInfo.PushBack({targetBufferRef.m_format}); } for (const auto& shaderId : createInfo.m_shaders) { const auto& shaderRef = allShaders[shaderId]; m_passShaders.PushBack(shaderRef); } for (const auto& inputId : createInfo.m_inputTargets) { // TODO(vasumahesh1):[?]: Respect shader stages here for correct binding const auto& targetBufferRef = pipelineBuffers[inputId.m_id]; m_passInputs.PushBack(targetBufferRef); if (HasDepthOrStencilComponent(targetBufferRef.m_format)) { m_depthInputs.push_back(pipelineBufferImages[inputId.m_id]); } else { m_renderInputs.push_back(pipelineBufferImages[inputId.m_id]); } m_allRenderInputs.PushBack(pipelineBufferImages[inputId.m_id]); } LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "======== D3D12 Render Pass: Root Signature ========"); Vector descriptorTables(U32(createInfo.m_descriptorSets.size() + 1), allocatorTemporary); m_rootSignatureTable.Reserve(U32(createInfo.m_descriptorSets.size())); U32 cbvOffset = 0; U32 srvOffset = 0; U32 samplerOffset = 0; for (const auto& setId : createInfo.m_descriptorSets) { const auto& tableEntry = descriptorSetTable[setId]; LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: Generating for Set Position: %d", m_rootSignatureTable .GetSize()); LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: Original Set Position: %d", setId); m_rootSignatureTable.PushBack(tableEntry); Vector currentRanges(tableEntry.m_count, allocatorTemporary); for (const auto& slot : descriptorSlots) { if (slot.m_setIdx != setId) { continue; } CD3DX12_DESCRIPTOR_RANGE rangeData; switch (slot.m_type) { case DescriptorType::UniformBuffer: LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: [%d] Applying Uniform Buffer at Register b(%d)", setId, cbvOffset); rangeData.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, cbvOffset); currentRanges.PushBack(rangeData); ++cbvOffset; ++m_descriptorCount.m_numUniformSlots; break; case DescriptorType::Sampler: LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: [%d] Applying Sampler Buffer at Register s(%d)", setId, samplerOffset); rangeData.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, samplerOffset); currentRanges.PushBack(rangeData); ++samplerOffset; ++m_descriptorCount.m_numSamplerSlots; break; case DescriptorType::SampledImage: LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: [%d] Applying Texture Image at Register t(%d)", setId, srvOffset); rangeData.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, srvOffset); currentRanges.PushBack(rangeData); ++srvOffset; ++m_descriptorCount.m_numSampledImageSlots; break; case DescriptorType::PushConstant: case DescriptorType::CombinedImageSampler: case DescriptorType::UnorderedView: default: LOG_ERR(log_D3D12RenderSystem, LOG_LEVEL, "Unsupported Descriptor Type for D3D12"); break; } } CD3DX12_ROOT_PARAMETER rootParameter; rootParameter.InitAsDescriptorTable(currentRanges.GetSize(), currentRanges.Data(), D3D12_SHADER_VISIBILITY_ALL); descriptorTables.PushBack(rootParameter); } CD3DX12_ROOT_PARAMETER inputsRootParameter; CD3DX12_DESCRIPTOR_RANGE inputRangeData; // Have some inputs if (!createInfo.m_inputTargets.empty()) { LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: Generating for Set Position: %d", descriptorTables. GetSize()); LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: [Attachments] Applying %d Image Attachments as register t(%d) to t(%d)", createInfo. m_inputTargets.size(), srvOffset, srvOffset + createInfo.m_inputTargets.size() - 1); inputRangeData.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, UINT(createInfo.m_inputTargets.size()), srvOffset); inputsRootParameter.InitAsDescriptorTable(1, &inputRangeData, D3D12_SHADER_VISIBILITY_ALL); descriptorTables.PushBack(inputsRootParameter); } CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(descriptorTables.GetSize(), descriptorTables.Data(), 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr signature; ComPtr error; VERIFY_D3D_OP(log_D3D12RenderSystem, D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, & signature, &error), "Failed to serialize D3D12 Root Signature"); VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateRootSignature(0, signature->GetBufferPointer(), signature-> GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)), "Failed to create Root Signature"); LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Render Pass: Completed Root Signature"); } } // namespace D3D12 } // namespace Azura