/// <summary>
        /// Used the velocity buffer to move the nodes in the positions buffer
        /// </summary>
        /// <param name="RSetDesc">Position shader resource set</param>
        /// <param name="cl">Commandlist to run the commands on</param>
        /// <param name="plot">PlottedGraph to compute</param>
        /// <param name="delta">A float representing how much time has passed since the last frame. Higher values => bigger movements</param>
        private unsafe void RenderPosition(ResourceSetDescription RSetDesc, CommandList cl, PlottedGraph plot, float delta)
        {
            _timer.Restart();
            cl.Begin();

            ResourceSet resourceSet = _gd.ResourceFactory.CreateResourceSet(RSetDesc);
            //Debug.Assert(!VeldridGraphBuffers.DetectNaN(_gd, positions));
            //Debug.Assert(!VeldridGraphBuffers.DetectNaN(_gd, velocities));

            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderPosition  {this.EngineID}", Logging.LogFilterType.BulkDebugLogFile);

            PositionShaderParams parameters = new PositionShaderParams
            {
                delta     = delta,
                nodeCount = (uint)plot.RenderedNodeCount()
            };

            //Logging.WriteConsole($"RenderPosition Parambuffer Size is {(uint)Unsafe.SizeOf<PositionShaderParams>()}");

            cl.UpdateBuffer(_positionParamsBuffer, 0, parameters);
            cl.SetPipeline(_positionComputePipeline);
            cl.SetComputeResourceSet(0, resourceSet);
            cl.Dispatch((uint)Math.Ceiling(plot.LayoutState.PositionsVRAM1 !.SizeInBytes / (256.0 * sizeof(Vector4))), 1, 1);
            cl.End();
            _timer.Stop();
            PositionSetupTime = _timer.Elapsed.TotalMilliseconds;

            _timer.Restart();
            _gd !.SubmitCommands(cl);
            _gd !.WaitForIdle();
            _gd.DisposeWhenIdle(resourceSet);
            _timer.Stop();
            PositionTime = _timer.Elapsed.TotalMilliseconds;
        }
        /// <summary>
        /// Pass the graph plot through the velocity compute shader, to adjust the node velocity based on the positions of other nodes
        /// </summary>
        /// <param name="RSetDesc">Position shader resource set</param>
        /// <param name="cl">Commandlist to run the commands on</param>
        /// <param name="plot">PlottedGraph to compute</param>
        /// <param name="delta">A float representing how much time has passed since the last frame. Higher values => bigger movements</param>
        private void RenderVelocity(ResourceSetDescription RSetDesc, CommandList cl, PlottedGraph plot, float delta)
        {
            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocity  {this.EngineID}", Logging.LogFilterType.BulkDebugLogFile);

            _timer.Restart();
            cl.Begin();

            ResourceSet resourceSet = _gd.ResourceFactory.CreateResourceSet(RSetDesc);
            uint        nodeCount   = (uint)plot.RenderedNodeCount();
            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocityBlocks  {this.EngineID}", Logging.LogFilterType.BulkDebugLogFile);
            GraphLayoutState     layout     = plot.LayoutState;
            VelocityShaderParams parameters = new VelocityShaderParams
            {
                delta       = delta, //not used
                temperature = Math.Min(plot.Temperature, GlobalConfig.MaximumNodeTemperature),
                repulsionK  = GlobalConfig.RepulsionK,
                nodeCount   = nodeCount
            };

            Debug.Assert(nodeCount <= (layout.VelocitiesVRAM1 !.SizeInBytes / 16));
            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocity  {this.EngineID} submit", Logging.LogFilterType.BulkDebugLogFile);

            cl.UpdateBuffer(_velocityParamsBuffer, 0, parameters);
            cl.SetPipeline(_velocityComputePipeline);
            cl.SetComputeResourceSet(0, resourceSet);

            //16 == sizeof(Vector4)
            uint elemCount = layout.VelocitiesVRAM1 !.SizeInBytes / 16;
            uint grpSizeX  = (uint)Math.Ceiling(elemCount / 256.0);

            //Console.WriteLine($"VRAM Size: {layout.VelocitiesVRAM1!.SizeInBytes}bytes, WkX: {grpSizeX}, nodeCount: {nodeCount}, bufVel4Count: {layout.VelocitiesVRAM1!.SizeInBytes/16}");
            cl.Dispatch(grpSizeX, 1, 1);
            //_cl.Dispatch((uint)Math.Ceiling(layout.VelocitiesVRAM1!.SizeInBytes / (256.0 * 16)), 1, 1);
            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocity  {this.EngineID} done in {watch.ElapsedMilliseconds} MS", Logging.LogFilterType.BulkDebugLogFile);

            cl.End();
            _timer.Stop();
            VelocitySetupTime = _timer.Elapsed.TotalMilliseconds;

            _timer.Restart();
            _gd !.SubmitCommands(cl);
            _gd !.WaitForIdle();
            _gd.DisposeWhenIdle(resourceSet);

            _timer.Stop();
            VelocityTime = _timer.Elapsed.TotalMilliseconds;
        }
Beispiel #3
0
        /// <summary>
        /// Pass the graph plot through the velocity compute shader, to adjust the node velocity based on the positions of other nodes
        /// </summary>
        /// <param name="RSetDesc">Position shader resource set</param>
        /// <param name="cl">Commandlist to run the commands on</param>
        /// <param name="plot">PlottedGraph to compute</param>
        /// <param name="delta">A float representing how much time has passed since the last frame. Higher values => bigger movements</param>
        private void RenderVelocity(ResourceSetDescription RSetDesc, CommandList cl, PlottedGraph plot, float delta)
        {
            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocity  {this.EngineID}", Logging.LogFilterType.BulkDebugLogFile);

            _timer.Restart();
            cl.Begin();

            ResourceSet resourceSet = _gd.ResourceFactory.CreateResourceSet(RSetDesc);

            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocityBlocks  {this.EngineID}", Logging.LogFilterType.BulkDebugLogFile);
            GraphLayoutState     layout     = plot.LayoutState;
            VelocityShaderParams parameters = new VelocityShaderParams
            {
                nodeCount    = (uint)plot.RenderedNodeCount(),
                speedDivisor = GlobalConfig.PresetSpeedDivisor
            };

            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocity  {this.EngineID} submit", Logging.LogFilterType.BulkDebugLogFile);

            cl.UpdateBuffer(_velocityParamsBuffer, 0, parameters);
            cl.SetPipeline(_velocityComputePipeline);
            cl.SetComputeResourceSet(0, resourceSet);

            //16 == sizeof(Vector4)
            cl.Dispatch((uint)Math.Ceiling(layout.VelocitiesVRAM1 !.SizeInBytes / (256.0 * 16)), 1, 1);
            //if (GlobalConfig.Settings.Logs.BulkLogging) Logging.RecordLogEvent($"RenderVelocity  {this.EngineID} done in {watch.ElapsedMilliseconds} MS", Logging.LogFilterType.BulkDebugLogFile);

            cl.End();
            _timer.Stop();
            VelocitySetupTime = _timer.Elapsed.TotalMilliseconds;

            _timer.Restart();
            _gd !.SubmitCommands(cl);
            _gd !.WaitForIdle();
            _gd.DisposeWhenIdle(resourceSet);

            _timer.Stop();
            VelocityTime = _timer.Elapsed.TotalMilliseconds;
        }
Beispiel #4
0
        /// <summary>
        /// Update the node attributes compute VRAM buffer (alpha, node size, mouseover details)
        /// </summary>
        /// <param name="cl">Thread-specific CommandList</param>
        /// <param name="graph">ProtoGraph being drawn</param>
        /// <param name="inputAttributes">Attributes buffer being updated</param>
        /// <param name="resources">Shader resources ResourceSet</param>
        /// <param name="delta">Time-delta from the last update</param>
        /// <param name="mouseoverNodeID">Index of the node the mouse is over</param>
        /// <param name="useAnimAttribs">Flag to specify the graph is in animated-alpha mode</param>
        private unsafe void RenderNodeAttribs(CommandList cl, PlottedGraph graph, DeviceBuffer inputAttributes,
                                              ResourceSet resources, float delta, int mouseoverNodeID, bool useAnimAttribs)
        {
            if (GlobalConfig.Settings.Logs.BulkLogging)
            {
                Logging.RecordLogEvent($"RenderNodeAttribs  {this.EngineID}", Logging.LogFilterType.BulkDebugLogFile);
            }
            AttribShaderParams parms = new AttribShaderParams
            {
                delta         = delta,
                hoveredNodeID = mouseoverNodeID,
                nodeCount     = (uint)Math.Min(graph.RenderedNodeCount(), graph.LayoutState.AttributesVRAM1 !.SizeInBytes / 16),
                MinimumAlpha  = GlobalConfig.AnimatedFadeMinimumAlpha,
                hoverMode     = (mouseoverNodeID != -1) ? 1 : 0,
                isAnimated    = useAnimAttribs ? 1: 0
            };


            graph.GetActiveNodeIndexes(out List <uint> pulseNodes, out List <uint> lingerNodes, out uint[] deactivatedNodes);

            if (GlobalConfig.Settings.Logs.BulkLogging)
            {
                Logging.RecordLogEvent($"RenderNodeAttribs {this.EngineID} updating attribsbuf {inputAttributes.Name}", Logging.LogFilterType.BulkDebugLogFile);
            }

            cl.UpdateBuffer(_attribsParamsBuffer, 0, parms);

            float currentPulseAlpha = Math.Max(GlobalConfig.AnimatedFadeMinimumAlpha, GraphicsMaths.getPulseAlpha());

            //todo - merge contiguous regions to reduce command count
            float[] valArray = new float[3];
            foreach (uint idx in pulseNodes)
            {
                if (idx >= graph.RenderedNodeCount())
                {
                    break;
                }

                if (inputAttributes.SizeInBytes <= idx * 4 * sizeof(float) + (2 * sizeof(float)))
                {
                    break;
                }

                valArray[0] = GlobalConfig.NodeSize; //start big
                valArray[1] = 1.0f;                  //full alpha
                valArray[2] = 1.0f;                  //pulse
                fixed(float *dataPtr = valArray)
                {
                    Debug.Assert((idx * 4 * sizeof(float) + valArray.Length * sizeof(float)) < inputAttributes.SizeInBytes);
                    cl.UpdateBuffer(inputAttributes, idx * 4 * sizeof(float), (IntPtr)dataPtr, (uint)valArray.Length * sizeof(float));
                }
            }

            //make the active node pulse
            if (graph.IsAnimated)
            {
                uint activeNodeIdx = graph.LastAnimatedVert;
                if (!lingerNodes.Contains(activeNodeIdx))
                {
                    valArray[0] = currentPulseAlpha;
                    fixed(float *dataPtr = valArray)
                    {
                        uint nodeAlphaOffset = (activeNodeIdx * 4 * sizeof(float)) + (2 * sizeof(float));

                        if (nodeAlphaOffset + sizeof(float) <= inputAttributes.SizeInBytes)
                        {
                            cl.UpdateBuffer(inputAttributes, nodeAlphaOffset, (IntPtr)dataPtr, sizeof(float));
                        }
                    }
                }
            }

            foreach (uint idx in lingerNodes)
            {
                if (idx >= graph.RenderedNodeCount())
                {
                    break;
                }

                if (inputAttributes.SizeInBytes <= idx * 4 * sizeof(float) + (2 * sizeof(float)))
                {
                    break;
                }

                valArray[0] = 2.0f + currentPulseAlpha;
                fixed(float *dataPtr = valArray)
                {
                    Debug.Assert((idx * 4 * sizeof(float) + (2 * sizeof(float)) + sizeof(float)) < inputAttributes.SizeInBytes);
                    cl.UpdateBuffer(inputAttributes, idx * 4 * sizeof(float) + (2 * sizeof(float)), (IntPtr)dataPtr, sizeof(float));
                }
            }

            foreach (uint idx in deactivatedNodes)
            {
                if (idx >= graph.RenderedNodeCount())
                {
                    break;
                }

                if (inputAttributes.SizeInBytes <= idx * 4 * sizeof(float) + (2 * sizeof(float)))
                {
                    break;
                }

                valArray[0] = 0.8f;
                fixed(float *dataPtr = valArray)
                {
                    Debug.Assert((idx * 4 * sizeof(float) + (2 * sizeof(float)) + sizeof(float)) < inputAttributes.SizeInBytes);
                    cl.UpdateBuffer(inputAttributes, idx * 4 * sizeof(float) + (2 * sizeof(float)), (IntPtr)dataPtr, sizeof(float));
                }
            }

            if (graph.HighlightsChanged)
            {
                ApplyHighlightAttributes(cl, graph, inputAttributes);
            }

            cl.SetPipeline(_nodeAttribComputePipeline);
            cl.SetComputeResourceSet(0, resources);

            cl.Dispatch((uint)Math.Ceiling(inputAttributes.SizeInBytes / (256.0 * sizeof(Vector4))), 1, 1);
        }