void ParticleEffect::Update(ComputeContext& CompContext, float timeDelta) { m_ElapsedTime += timeDelta; m_EffectProperties.EmitProperties.LastEmitPosW = m_EffectProperties.EmitProperties.EmitPosW; //m_EffectProperties.EmitProperties.EmitPosW = XMFLOAT3(ComputeConstants.EmitPosW.x + 1.0f * float(GameInput::IsPressed(GameInput::kBButton)), ComputeConstants.EmitPosW.y + 1.0f * float(GameInput::IsPressed(GameInput::kYButton)), ComputeConstants.EmitPosW.z - 1.0f * float(GameInput::IsPressed(GameInput::kAButton)));// //m_EffectProperties.EmitProperties.EmitPosW.x += m_EffectProperties.DirectionIncrement.x; //m_EffectProperties.EmitProperties.EmitPosW.y += m_EffectProperties.DirectionIncrement.y; //m_EffectProperties.EmitProperties.EmitPosW.z += m_EffectProperties.DirectionIncrement.z; //CPU side random num gen for (uint32_t i = 0; i < 64; i++) { UINT random = (UINT)s_RNG.NextInt(m_EffectProperties.EmitProperties.MaxParticles - 1); m_EffectProperties.EmitProperties.RandIndex[i].x = random; } CompContext.SetDynamicConstantBufferView(2, sizeof(EmissionProperties), &m_EffectProperties.EmitProperties); CompContext.TransitionResource(m_StateBuffers[m_CurrentStateBuffer], D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); CompContext.SetDynamicDescriptor(4, 0, m_RandomStateBuffer.GetSRV()); CompContext.SetDynamicDescriptor(4, 1, m_StateBuffers[m_CurrentStateBuffer].GetSRV()); m_CurrentStateBuffer ^= 1; CompContext.ResetCounter(m_StateBuffers[m_CurrentStateBuffer]); CompContext.SetPipelineState(s_ParticleUpdateCS); CompContext.TransitionResource(m_StateBuffers[m_CurrentStateBuffer], D3D12_RESOURCE_STATE_UNORDERED_ACCESS); CompContext.TransitionResource(m_DispatchIndirectArgs, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); CompContext.SetDynamicDescriptor(3, 2, m_StateBuffers[m_CurrentStateBuffer].GetUAV()); CompContext.DispatchIndirect(m_DispatchIndirectArgs, 0); // Why need a barrier here so long as we are artificially clamping particle count. This allows living // particles to take precedence over new particles. The current system always spawns a multiple of 64 // particles (To Be Fixed) until the total particle count reaches maximum. CompContext.InsertUAVBarrier(m_StateBuffers[m_CurrentStateBuffer]); // Spawn to replace dead ones CompContext.SetPipelineState(s_ParticleSpawnCS); CompContext.SetDynamicDescriptor(4, 0, m_RandomStateBuffer.GetSRV()); UINT NumSpawnThreads = (UINT)(m_EffectProperties.EmitRate * timeDelta); CompContext.Dispatch((NumSpawnThreads + 63) / 64, 1, 1); // Output number of thread groups into m_DispatchIndirectArgs CompContext.SetPipelineState(s_ParticleDispatchIndirectArgsCS); CompContext.TransitionResource(m_DispatchIndirectArgs, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); CompContext.TransitionResource(m_StateBuffers[m_CurrentStateBuffer], D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); CompContext.SetDynamicDescriptor(4, 0, m_StateBuffers[m_CurrentStateBuffer].GetCounterSRV(CompContext)); CompContext.SetDynamicDescriptor(3, 1, m_DispatchIndirectArgs.GetUAV()); CompContext.Dispatch(1, 1, 1); }
void TextureManager::ProcessGeneration(GenerateTextureInfo &generationInfo, RenderPassDescriptorHeap *srvHeap) { ComputeContext *computeContext = mDirect3DManager->GetContextManager()->GetComputeContext(); computeContext->SetDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, srvHeap->GetHeap()); computeContext->SetPipelineState(generationInfo.GenerationShader); computeContext->SetRootSignature(generationInfo.GenerationShader->GetRootSignature()); DescriptorHeapHandle generateTargetHandle = srvHeap->GetHeapHandleBlock(1); mDirect3DManager->GetDevice()->CopyDescriptorsSimple(1, generateTargetHandle.GetCPUHandle(), generationInfo.GenerateTarget->GetUnorderedAccessViewHandle().GetCPUHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); computeContext->SetDescriptorTable(0, generateTargetHandle.GetGPUHandle()); computeContext->Dispatch(generationInfo.GenerateTarget->GetWidth() / 8, generationInfo.GenerateTarget->GetHeight() / 8, 1); generationInfo.GenerationFence = computeContext->Flush(mDirect3DManager->GetContextManager()->GetQueueManager()); }
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())); }