antonkudin

gpu timing

Oct 26th, 2025
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEditor;
  2. using UnityEngine;
  3. using UnityEngine.Profiling;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using UnityEngine.Rendering;
  7.  
  8. public class GpuTimingWindow : EditorWindow
  9. {
  10.     private const int SampleCount = 1;
  11.     private FrameTiming[] frameTimings = new FrameTiming[SampleCount];
  12.     private double gpuFrameTime;
  13.     private double cpuFrameTime;
  14.  
  15.     private const int HistorySize = 50;
  16.     private Queue<float> cpuHistory = new Queue<float>(HistorySize);
  17.     private Queue<float> gpuHistory = new Queue<float>(HistorySize);
  18.  
  19.     private Shader shaderToProfile;
  20.     private CustomSampler shaderSampler;
  21.  
  22.     [MenuItem("Window/Analysis/GPU Timing Viewer")]
  23.     public static void ShowWindow()
  24.     {
  25.         var window = GetWindow<GpuTimingWindow>("GPU Timing");
  26.         window.Show();
  27.     }
  28.  
  29.     private void OnEnable()
  30.     {
  31.         EditorApplication.update += UpdateTimings;
  32.     }
  33.  
  34.     private void OnDisable()
  35.     {
  36.         EditorApplication.update -= UpdateTimings;
  37.     }
  38.  
  39.     private void UpdateTimings()
  40.     {
  41.         // Capture frame timings from the last frame
  42.         FrameTimingManager.CaptureFrameTimings();
  43.         uint count = FrameTimingManager.GetLatestTimings((uint)frameTimings.Length, frameTimings);
  44.  
  45.         if (count > 0)
  46.         {
  47.             var timing = frameTimings[0];
  48.             gpuFrameTime = timing.gpuFrameTime;
  49.             cpuFrameTime = timing.cpuFrameTime;
  50.  
  51.             AddToHistory(cpuHistory, (float)cpuFrameTime);
  52.             AddToHistory(gpuHistory, (float)gpuFrameTime);
  53.  
  54.             Repaint();
  55.         }
  56.     }
  57.  
  58.     private void AddToHistory(Queue<float> queue, float value)
  59.     {
  60.         if (queue.Count >= HistorySize)
  61.             queue.Dequeue();
  62.         queue.Enqueue(value);
  63.     }
  64.  
  65.     private float GetAverage(Queue<float> queue)
  66.     {
  67.         if (queue.Count == 0) return 0f;
  68.         return queue.Average();
  69.     }
  70.  
  71.     private void OnGUI()
  72.     {
  73.         GUILayout.Label("GPU & CPU Frame Timing", EditorStyles.boldLabel);
  74.  
  75.         EditorGUILayout.LabelField("CPU Frame Time (ms):", cpuFrameTime.ToString("F2"));
  76.         EditorGUILayout.LabelField("GPU Frame Time (ms):", gpuFrameTime.ToString("F2"));
  77.  
  78.         float avgCpu = GetAverage(cpuHistory);
  79.         float avgGpu = GetAverage(gpuHistory);
  80.  
  81.         EditorGUILayout.Space();
  82.         EditorGUILayout.LabelField("CPU Avg (200 frames, ms):", avgCpu.ToString("F2"));
  83.         EditorGUILayout.LabelField("GPU Avg (200 frames, ms):", avgGpu.ToString("F2"));
  84.  
  85.         float targetFrameRate = 1000f / Mathf.Max(0.0001f, avgGpu);
  86.         EditorGUILayout.LabelField("Approx. Avg GPU FPS:", targetFrameRate.ToString("F1"));
  87.  
  88.         GUILayout.Space(10);
  89.         Rect rect = GUILayoutUtility.GetRect(100, 30);
  90.         DrawTimingBar(rect, (float)cpuFrameTime, (float)gpuFrameTime);
  91.  
  92.         GUILayout.Space(20);
  93.         GUILayout.Label("Frame Timing History (last 200 frames)", EditorStyles.boldLabel);
  94.         Rect graphRect = GUILayoutUtility.GetRect(position.width - 20, 100);
  95.         DrawGraph(graphRect, cpuHistory, gpuHistory);
  96.     }
  97.  
  98.     private void DrawTimingBar(Rect rect, float cpuMs, float gpuMs)
  99.     {
  100.         float maxMs = Mathf.Max(cpuMs, gpuMs, 16.67f); // baseline at ~60 FPS
  101.         float cpuWidth = Mathf.Clamp01(cpuMs / maxMs) * rect.width;
  102.         float gpuWidth = Mathf.Clamp01(gpuMs / maxMs) * rect.width;
  103.  
  104.         EditorGUI.DrawRect(new Rect(rect.x, rect.y, cpuWidth, rect.height / 2), new Color(0.3f, 0.6f, 1f));
  105.         EditorGUI.DrawRect(new Rect(rect.x, rect.y + rect.height / 2, gpuWidth, rect.height / 2), new Color(1f, 0.4f, 0.4f));
  106.  
  107.         EditorGUI.DropShadowLabel(rect, $"CPU {cpuMs:F2} ms | GPU {gpuMs:F2} ms");
  108.     }
  109.  
  110.     private void DrawGraph(Rect rect, Queue<float> cpuData, Queue<float> gpuData)
  111.     {
  112.         Handles.BeginGUI();
  113.         GUI.Box(rect, GUIContent.none);
  114.  
  115.         if (cpuData.Count > 1 && gpuData.Count > 1)
  116.         {
  117.             float[] cpuArray = cpuData.ToArray();
  118.             float[] gpuArray = gpuData.ToArray();
  119.             int count = Mathf.Min(cpuArray.Length, gpuArray.Length);
  120.  
  121.             float maxVal = 0f;
  122.             for (int i = 0; i < count; i++)
  123.                 maxVal = Mathf.Max(maxVal, Mathf.Max(cpuArray[i], gpuArray[i]));
  124.  
  125.             if (maxVal < 16.67f)
  126.                 maxVal = 16.67f; // ensure ~60 fps baseline is visible
  127.  
  128.             Vector3 prevCpu = Vector3.zero;
  129.             Vector3 prevGpu = Vector3.zero;
  130.             for (int i = 0; i < count; i++)
  131.             {
  132.                 float x = Mathf.Lerp(rect.x, rect.xMax, i / (float)(count - 1));
  133.                 float cpuY = Mathf.Lerp(rect.yMax, rect.y, cpuArray[i] / maxVal);
  134.                 float gpuY = Mathf.Lerp(rect.yMax, rect.y, gpuArray[i] / maxVal);
  135.  
  136.                 Vector3 cpuPoint = new Vector3(x, cpuY, 0);
  137.                 Vector3 gpuPoint = new Vector3(x, gpuY, 0);
  138.  
  139.                 if (i > 0)
  140.                 {
  141.                     Handles.color = new Color(0.3f, 0.6f, 1f);
  142.                     Handles.DrawLine(prevCpu, cpuPoint);
  143.  
  144.                     Handles.color = new Color(1f, 0.4f, 0.4f);
  145.                     Handles.DrawLine(prevGpu, gpuPoint);
  146.                 }
  147.  
  148.                 prevCpu = cpuPoint;
  149.                 prevGpu = gpuPoint;
  150.             }
  151.         }
  152.  
  153.         Handles.EndGUI();
  154.     }
  155. }
  156.  
Tags: Unity
Add Comment
Please, Sign In to add comment