void Initialize_Upload() { for(uint64 i = 0; i < MaxUploadSubmissions; ++i) DXCall(Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&UploadSubmissions[i].CmdAllocator))); DXCall(Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, UploadSubmissions[0].CmdAllocator, nullptr, IID_PPV_ARGS(&UploadCmdList))); DXCall(UploadCmdList->Close()); D3D12_COMMAND_QUEUE_DESC queueDesc = { }; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; DXCall(Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&UploadCmdQueue))); UploadFence.Init(0); D3D12_RESOURCE_DESC resourceDesc = { }; resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; resourceDesc.Width = uint32(UploadBufferSize); resourceDesc.Height = 1; resourceDesc.DepthOrArraySize = 1; resourceDesc.MipLevels = 1; resourceDesc.Format = DXGI_FORMAT_UNKNOWN; resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE; resourceDesc.SampleDesc.Count = 1; resourceDesc.SampleDesc.Quality = 0; resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; resourceDesc.Alignment = 0; DXCall(Device->CreateCommittedResource(DX12::GetUploadHeapProps(), D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&UploadBuffer))); D3D12_RANGE readRange = { }; DXCall(UploadBuffer->Map(0, &readRange, reinterpret_cast<void**>(&UploadBufferCPUAddr))); // Temporary buffer memory that swaps every frame resourceDesc.Width = uint32(TempBufferSize); for(uint64 i = 0; i < RenderLatency; ++i) { DXCall(Device->CreateCommittedResource(DX12::GetUploadHeapProps(), D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&TempFrameBuffers[i]))); DXCall(TempFrameBuffers[i]->Map(0, &readRange, reinterpret_cast<void**>(&TempFrameCPUMem[i]))); TempFrameGPUMem[i] = TempFrameBuffers[i]->GetGPUVirtualAddress(); } // Texture conversion resources DXCall(Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COMPUTE, IID_PPV_ARGS(&convertCmdAllocator))); DXCall(Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COMPUTE, convertCmdAllocator, nullptr, IID_PPV_ARGS(&convertCmdList))); DXCall(convertCmdList->Close()); DXCall(convertCmdList->Reset(convertCmdAllocator, nullptr)); D3D12_COMMAND_QUEUE_DESC convertQueueDesc = {}; convertQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; convertQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE; DXCall(Device->CreateCommandQueue(&convertQueueDesc, IID_PPV_ARGS(&convertCmdQueue))); CompileOptions opts; opts.Add("TGSize_", convertTGSize); const std::wstring shaderPath = SampleFrameworkDir() + L"Shaders\\DecodeTextureCS.hlsl"; convertCS = CompileFromFile(shaderPath.c_str(), "DecodeTextureCS", ShaderType::Compute, ShaderProfile::SM51, opts); convertArrayCS = CompileFromFile(shaderPath.c_str(), "DecodeTextureArrayCS", ShaderType::Compute, ShaderProfile::SM51, opts); { D3D12_DESCRIPTOR_RANGE ranges[2] = {}; ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; ranges[0].NumDescriptors = 1; ranges[0].BaseShaderRegister = 0; ranges[0].RegisterSpace = 0; ranges[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; ranges[1].NumDescriptors = 1; ranges[1].BaseShaderRegister = 0; ranges[1].RegisterSpace = 0; ranges[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; D3D12_ROOT_PARAMETER rootParameters[1] = {}; rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; rootParameters[0].DescriptorTable.pDescriptorRanges = ranges; rootParameters[0].DescriptorTable.NumDescriptorRanges = ArraySize_(ranges); D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = {}; rootSignatureDesc.NumParameters = ArraySize_(rootParameters); rootSignatureDesc.pParameters = rootParameters; rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; DX12::CreateRootSignature(&convertRootSignature, rootSignatureDesc); } { D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = { }; psoDesc.CS = convertCS.ByteCode(); psoDesc.pRootSignature = convertRootSignature; psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; Device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&convertPSO)); psoDesc.CS = convertArrayCS.ByteCode(); Device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&convertArrayPSO)); } convertFence.Init(0); // Readback resources DXCall(Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&readbackCmdAllocator))); DXCall(Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, readbackCmdAllocator, nullptr, IID_PPV_ARGS(&readbackCmdList))); DXCall(readbackCmdList->Close()); DXCall(readbackCmdList->Reset(readbackCmdAllocator, nullptr)); readbackFence.Init(0); }
void PostProcessHelper::PostProcess(CompiledShaderPtr pixelShader, const char* name, const uint32* inputs, uint64 numInputs, const RenderTexture*const* outputs, uint64 numOutputs) { Assert_(cmdList != nullptr); Assert_(numOutputs > 0); Assert_(outputs != nullptr); Assert_(numInputs == 0 || inputs != nullptr); Assert_(numInputs <= MaxInputs); PIXMarker marker(cmdList, name); HashSource hashSource; for(uint64 i = 0; i < numOutputs; ++i) { hashSource.OutputFormats[i] = outputs[i]->Texture.Format; hashSource.MSAASamples = outputs[i]->MSAASamples; } Hash psoHash = GenerateHash(&hashSource, sizeof(HashSource)); psoHash = CombineHashes(psoHash, pixelShader->ByteCodeHash); ID3D12PipelineState* pso = nullptr; // The most linear of searches! const uint64 numPSOs = pipelineStates.Count(); for(uint64 i = 0; i < numPSOs; ++i) { if(pipelineStates[i].Hash == psoHash) { pso = pipelineStates[i].PSO; break; } } if(pso == nullptr) { D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.pRootSignature = rootSignature; psoDesc.VS = fullScreenTriVS.ByteCode(); psoDesc.PS = pixelShader.ByteCode(); psoDesc.RasterizerState = DX12::GetRasterizerState(RasterizerState::NoCull); psoDesc.BlendState = DX12::GetBlendState(BlendState::Disabled); psoDesc.DepthStencilState = DX12::GetDepthState(DepthState::Disabled); psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = uint32(numOutputs); for(uint64 i = 0; i < numOutputs; ++i) psoDesc.RTVFormats[i] = hashSource.OutputFormats[i]; psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; psoDesc.SampleDesc.Count = uint32(hashSource.MSAASamples); DXCall(DX12::Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pso))); CachedPSO cachedPSO; cachedPSO.Hash = psoHash; cachedPSO.PSO = pso; pipelineStates.Add(cachedPSO); } D3D12_CPU_DESCRIPTOR_HANDLE rtvHandles[8] = { }; for(uint64 i = 0; i < numOutputs; ++i) rtvHandles[i] = outputs[i]->RTV; cmdList->OMSetRenderTargets(uint32(numOutputs), rtvHandles, false, nullptr); cmdList->SetGraphicsRootSignature(rootSignature); cmdList->SetPipelineState(pso); DX12::BindStandardDescriptorTable(cmdList, RootParam_StandardDescriptors, CmdListMode::Graphics); AppSettings::BindCBufferGfx(cmdList, RootParam_AppSettings); uint32 srvIndices[MaxInputs] = { }; for(uint64 i = 0; i < numInputs; ++i) srvIndices[i] = inputs[i]; for(uint64 i = numInputs; i < MaxInputs; ++i) srvIndices[i] = DX12::NullTexture2DSRV; DX12::BindTempConstantBuffer(cmdList, srvIndices, RootParam_SRVIndices, CmdListMode::Graphics); DX12::SetViewport(cmdList, outputs[0]->Texture.Width, outputs[0]->Texture.Height); cmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); cmdList->DrawInstanced(3, 1, 0, 0); }