void ParticleEffects::Update(ComputeContext& Context, float timeDelta ) { if (!Enable || !s_InitComplete || ParticleEffectsActive.size() == 0) return; ScopedTimer _prof(L"Particle Update", Context); if (++TotalElapsedFrames == s_ReproFrame) PauseSim = true; if (PauseSim) return; Context.ResetCounter(SpriteVertexBuffer); if (ParticleEffectsActive.size() == 0) return; Context.SetRootSignature(RootSig); Context.SetConstants(0, timeDelta); Context.TransitionResource(SpriteVertexBuffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); Context.SetDynamicDescriptor(3, 0, SpriteVertexBuffer.GetUAV()); for (UINT i = 0; i < ParticleEffectsActive.size(); ++i) { ParticleEffectsActive[i]->Update(Context, timeDelta); if (ParticleEffectsActive[i]->GetLifetime() <= ParticleEffectsActive[i]->GetElapsedTime()) { //Erase from vector auto iter = ParticleEffectsActive.begin() + i; static std::mutex s_EraseEffectMutex; s_EraseEffectMutex.lock(); ParticleEffectsActive.erase(iter); s_EraseEffectMutex.unlock(); } } SetFinalBuffers(Context); }
void FXAA::Render( ComputeContext& Context, bool bUsePreComputedLuma ) { ScopedTimer _prof(L"FXAA", Context); if (ForceOffPreComputedLuma) bUsePreComputedLuma = false; ColorBuffer& Target = g_bTypedUAVLoadSupport_R11G11B10_FLOAT ? g_SceneColorBuffer : g_PostEffectsBuffer; Context.SetRootSignature(RootSig); Context.SetConstants(0, 1.0f / Target.GetWidth(), 1.0f / Target.GetHeight(), (float)ContrastThreshold, (float)SubpixelRemoval); { ScopedTimer _prof(L"Pass 1", Context); // Begin by analysing the luminance buffer and setting aside high-contrast pixels in // work queues to be processed later. There are horizontal edge and vertical edge work // queues so that the shader logic is simpler for each type of edge. Context.ResetCounter(g_FXAAWorkQueueH); Context.ResetCounter(g_FXAAWorkQueueV); Context.TransitionResource(Target, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); Context.TransitionResource(g_FXAAWorkQueueH, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); Context.TransitionResource(g_FXAAWorkQueueV, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); Context.TransitionResource(g_FXAAColorQueueH, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); Context.TransitionResource(g_FXAAColorQueueV, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); D3D12_CPU_DESCRIPTOR_HANDLE Pass1UAVs[] = { g_FXAAWorkQueueH.GetUAV(), g_FXAAColorQueueH.GetUAV(), g_FXAAWorkQueueV.GetUAV(), g_FXAAColorQueueV.GetUAV(), g_LumaBuffer.GetUAV() }; D3D12_CPU_DESCRIPTOR_HANDLE Pass1SRVs[] = { Target.GetSRV(), g_LumaBuffer.GetSRV() }; if (bUsePreComputedLuma) { Context.SetPipelineState(Pass1HdrCS); Context.TransitionResource(g_LumaBuffer, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); Context.SetDynamicDescriptors(1, 0, _countof(Pass1UAVs) - 1, Pass1UAVs); Context.SetDynamicDescriptors(2, 0, _countof(Pass1SRVs), Pass1SRVs); } else { Context.SetPipelineState(Pass1LdrCS); Context.TransitionResource(g_LumaBuffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); Context.SetDynamicDescriptors(1, 0, _countof(Pass1UAVs), Pass1UAVs); Context.SetDynamicDescriptors(2, 0, _countof(Pass1SRVs) - 1, Pass1SRVs); } Context.Dispatch2D(Target.GetWidth(), Target.GetHeight()); } { ScopedTimer _prof(L"Pass 2", Context); // The next phase involves converting the work queues to DispatchIndirect parameters. // The queues are also padded out to 64 elements to simplify the final consume logic. Context.SetPipelineState(ResolveWorkCS); Context.TransitionResource(IndirectParameters, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); Context.SetConstants(0, 1.0f / Target.GetWidth(), 1.0f / Target.GetHeight()); Context.SetDynamicDescriptor(1, 0, IndirectParameters.GetUAV()); Context.SetDynamicDescriptor(1, 1, g_FXAAWorkQueueH.GetUAV()); Context.SetDynamicDescriptor(1, 2, g_FXAAWorkQueueV.GetUAV()); Context.SetDynamicDescriptor(2, 0, g_FXAAWorkQueueH.GetCounterSRV(Context)); Context.SetDynamicDescriptor(2, 1, g_FXAAWorkQueueV.GetCounterSRV(Context)); Context.Dispatch(1, 1, 1); Context.TransitionResource(IndirectParameters, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); Context.TransitionResource(g_FXAAWorkQueueH, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); Context.TransitionResource(g_FXAAColorQueueH, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); Context.TransitionResource(g_FXAAWorkQueueV, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); Context.TransitionResource(g_FXAAColorQueueV, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); Context.TransitionResource(Target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); Context.SetDynamicDescriptor(1, 0, Target.GetUAV()); Context.SetDynamicDescriptor(2, 0, g_LumaBuffer.GetSRV()); Context.SetDynamicDescriptor(2, 1, g_FXAAWorkQueueH.GetSRV()); Context.SetDynamicDescriptor(2, 2, g_FXAAColorQueueH.GetSRV()); // The final phase involves processing pixels on the work queues and writing them // back into the color buffer. Because the two source pixels required for linearly // blending are held in the work queue, this does not require also sampling from // the target color buffer (i.e. no read/modify/write, just write.) Context.SetPipelineState(DebugDraw ? Pass2HDebugCS : Pass2HCS); Context.DispatchIndirect(IndirectParameters, 0); Context.SetDynamicDescriptor(2, 1, g_FXAAWorkQueueV.GetSRV()); Context.SetDynamicDescriptor(2, 2, g_FXAAColorQueueV.GetSRV()); Context.SetPipelineState(DebugDraw ? Pass2VDebugCS : Pass2VCS); Context.DispatchIndirect(IndirectParameters, 12); Context.InsertUAVBarrier(Target); } }
void TextureManager::ProcessCubeMapFiltering(CubeMapFilterInfo &cubeMapFilterInfo, RenderPassDescriptorHeap *srvHeap, RenderPassDescriptorHeap *samplerHeap) { Application::Assert(cubeMapFilterInfo.CubeMapToFilter->GetIsReady()); Vector4 targets[6] = { Vector4(1.0f, 0.0f, 0.0f, 0.0f), // +X Vector4(-1.0f, 0.0f, 0.0f, 0.0f), // -X Vector4(0.0f, 1.0f, 0.0f, 0.0f), // +Y Vector4(0.0f, -1.0f, 0.0f, 0.0f), // -Y Vector4(0.0f, 0.0f, 1.0f, 0.0f), // +Z Vector4(0.0f, 0.0f, -1.0f, 0.0f) // -Z }; Vector4 ups[6] = { Vector4(0.0f, 1.0f, 0.0f, 0.0f), // +X Vector4(0.0f, 1.0f, 0.0f, 0.0f), // -X Vector4(0.0f, 0.0f, -1.0f, 0.0f), // +Y Vector4(0.0f, 0.0f, 1.0f, 0.0f), // -Y Vector4(0.0f, 1.0f, 0.0f, 0.0f), // +Z Vector4(0.0f, 1.0f, 0.0f, 0.0f) // -Z }; ComputeContext *computeContext = mDirect3DManager->GetContextManager()->GetComputeContext(); computeContext->SetDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, srvHeap->GetHeap()); computeContext->SetDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, samplerHeap->GetHeap()); computeContext->SetPipelineState(cubeMapFilterInfo.EnvironmentFilterShader); computeContext->SetRootSignature(cubeMapFilterInfo.EnvironmentFilterShader->GetRootSignature()); DescriptorHeapHandle envMapHandle = srvHeap->GetHeapHandleBlock(1); DescriptorHeapHandle envMapSamplerHandle = samplerHeap->GetHeapHandleBlock(1); mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, envMapHandle.GetCPUHandle(), cubeMapFilterInfo.CubeMapToFilter->GetTextureResource()->GetShaderResourceViewHandle().GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, envMapSamplerHandle.GetCPUHandle(), cubeMapFilterInfo.EnvironmentSampler->GetSamplerHandle().GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); computeContext->SetDescriptorTable(0, envMapHandle.GetGPUHandle()); computeContext->SetDescriptorTable(1, envMapSamplerHandle.GetGPUHandle()); EnvironmentMapFilterTextureBuffer filterInfo; filterInfo.mipCount = (float)cubeMapFilterInfo.NumMips; for (uint32 cubeSideIndex = 0; cubeSideIndex < 6; cubeSideIndex++) { filterInfo.forwardDir = targets[cubeSideIndex]; filterInfo.upDir = ups[cubeSideIndex]; filterInfo.sourceDimensions = Vector2((float)cubeMapFilterInfo.DimensionSize, (float)cubeMapFilterInfo.DimensionSize); for (uint32 mipIndex = 0; mipIndex < cubeMapFilterInfo.NumMips; mipIndex++) { filterInfo.mipLevel = (float)(cubeMapFilterInfo.NumMips - mipIndex); DescriptorHeapHandle filterTargetHandle = srvHeap->GetHeapHandleBlock(1); mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, filterTargetHandle.GetCPUHandle(), cubeMapFilterInfo.FilterTarget->GetUnorderedAccessViewHandle(mipIndex, cubeSideIndex).GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); computeContext->SetDescriptorTable(2, filterTargetHandle.GetGPUHandle()); computeContext->SetConstants(3, 12, &filterInfo); computeContext->Dispatch((uint32)filterInfo.sourceDimensions.X / 8, (uint32)filterInfo.sourceDimensions.Y / 8, 1); filterInfo.sourceDimensions = Vector2(filterInfo.sourceDimensions.X / 2, filterInfo.sourceDimensions.Y / 2); } } cubeMapFilterInfo.FilterTarget->SetComputeFence(computeContext->Flush(mDirect3DManager->GetContextManager()->GetQueueManager())); }