// IMPORTANT: This method can be called only once per frame. If it is not, it will stall CPU for quite long time // Helper function to read atomic UAV counters back onto the CPU. // The method reads in the current frame the value from the previous frame private static int ReadCounter(IUavBindable uav) { int count = 0; if (VRage.MyCompilationSymbols.DX11Debug) { // Copy the UAV counter to a staging resource RC.CopyStructureCount(m_debugCounterBuffers[m_debugCounterBuffersIndex], 0, uav); m_debugCounterBuffersIndex = m_debugCounterBuffersIndex == 1 ? 0 : 1; var mapping = MyMapping.MapRead(m_debugCounterBuffers[m_debugCounterBuffersIndex]); mapping.ReadAndPosition(ref count); mapping.Unmap(); } return(count); }
internal static void Run(ISrvBindable depthRead, ISrvBindable gbufferNormalsRead) { // The maximum number of supported GPU particles ISrvBindable textureArraySrv; int emitterCount = MyGPUEmitters.Gather(m_emitterData, out textureArraySrv); if (emitterCount == 0) { return; } // Unbind current targets while we run the compute stages of the system //RC.DeviceContext.OutputMerger.SetTargets(null); // global GPU particles setup RC.SetDepthStencilState(MyDepthStencilStateManager.DefaultDepthState); RC.SetRasterizerState(MyRasterizerStateManager.NocullRasterizerState); RC.SetInputLayout(null); RC.ComputeShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.ComputeShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); RC.AllShaderStages.SetConstantBuffer(4, MyRender11.DynamicShadows.ShadowCascades.CascadeConstantBuffer); RC.VertexShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MySamplerStateManager.Shadowmap); RC.VertexShader.SetSrv(MyCommon.CASCADES_SM_SLOT, MyRender11.DynamicShadows.ShadowCascades.CascadeShadowmapArray); RC.VertexShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); // If we are resetting the particle system, then initialize the dead list if (m_resetSystem) { ResetInternal(); m_resetSystem = false; } MyGpuProfiler.IC_BeginBlock("Emit"); // Emit particles into the system Emit(emitterCount, m_emitterData, depthRead); MyGpuProfiler.IC_EndBlock(); // Run the simulation for this frame MyGpuProfiler.IC_BeginBlock("Simulate"); Simulate(depthRead, gbufferNormalsRead); MyGpuProfiler.IC_EndBlock(); // Copy the atomic counter in the alive list UAV into a constant buffer for access by subsequent passes RC.CopyStructureCount(m_activeListConstantBuffer, 0, m_aliveIndexBuffer); // Only read number of alive and dead particle back to the CPU in debug as we don't want to stall the GPU in release code ProfilerShort.Begin("Debug - ReadCounter"); MyGpuProfiler.IC_BeginBlock("Debug - ReadCounter"); int numActiveParticlesAfterSimulation = ReadCounter(m_aliveIndexBuffer); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); MyGpuProfiler.IC_BeginBlock("Render"); Render(textureArraySrv, depthRead); MyGpuProfiler.IC_EndBlock(); RC.ComputeShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); MyStatsDisplay.Write("GPU particles", "Live #", numActiveParticlesAfterSimulation); }