Created
October 20, 2019 19:23
-
-
Save apkd/b0c311ad42ac76f9e75355fa6918eafc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics.CodeAnalysis; | |
using UnityEngine.Profiling; | |
using UnityEngine.Rendering; | |
namespace UnityEngine.Experimental.Rendering | |
{ | |
public sealed class BatchingInfo : MonoBehaviour | |
{ | |
public bool Enable = true; | |
const float AverageStatDuration = 1.0f; // stats refresh each second | |
int frameCount; | |
float accDeltaTime; | |
string statsLabel; | |
GUIStyle style; | |
bool oldBatcherEnable; | |
sealed class RecorderEntry | |
{ | |
public string name; | |
public string oldName; | |
public int callCount; | |
public float accTime; | |
public Recorder recorder; | |
}; | |
enum SRPBMarkers | |
{ | |
kStdRenderDraw, | |
kStdShadowDraw, | |
kSRPBRenderDraw, | |
kSRPBShadowDraw, | |
kRenderThreadIdle, | |
kStdRenderApplyShader, | |
kStdShadowApplyShader, | |
kSRPBRenderApplyShader, | |
kSRPBShadowApplyShader, | |
kPrepareBatchRendererGroupNodes, | |
}; | |
readonly RecorderEntry[] recordersList = | |
{ | |
// Warning: Keep that list in the exact same order than SRPBMarkers enum | |
new RecorderEntry() {name = "RenderLoop.Draw"}, | |
new RecorderEntry() {name = "Shadows.Draw"}, | |
new RecorderEntry() {name = "SRPBatcher.Draw", oldName = "RenderLoopNewBatcher.Draw"}, | |
new RecorderEntry() {name = "SRPBatcherShadow.Draw", oldName = "ShadowLoopNewBatcher.Draw"}, | |
new RecorderEntry() {name = "RenderLoopDevice.Idle"}, | |
new RecorderEntry() {name = "StdRender.ApplyShader"}, | |
new RecorderEntry() {name = "StdShadow.ApplyShader"}, | |
new RecorderEntry() {name = "SRPBRender.ApplyShader"}, | |
new RecorderEntry() {name = "SRPBShadow.ApplyShader"}, | |
new RecorderEntry() {name = "PrepareBatchRendererGroupNodes"}, | |
}; | |
void Awake() | |
{ | |
foreach (var recorder in recordersList) | |
{ | |
var sampler = Sampler.Get(recorder.name); | |
if (sampler.isValid) | |
{ | |
recorder.recorder = sampler.GetRecorder(); | |
} | |
else if (recorder.oldName != null) | |
{ | |
sampler = Sampler.Get(recorder.oldName); | |
if (sampler.isValid) | |
recorder.recorder = sampler.GetRecorder(); | |
} | |
} | |
style = new GUIStyle {fontSize = 15, normal = {textColor = Color.white}}; | |
oldBatcherEnable = Enable; | |
ResetStats(); | |
} | |
void RazCounters() | |
{ | |
accDeltaTime = 0.0f; | |
frameCount = 0; | |
foreach (var recorder in recordersList) | |
{ | |
recorder.accTime = 0.0f; | |
recorder.callCount = 0; | |
} | |
} | |
void ResetStats() | |
{ | |
statsLabel = "Gathering data..."; | |
RazCounters(); | |
} | |
void ToggleStats() | |
{ | |
Enable = !Enable; | |
ResetStats(); | |
} | |
[SuppressMessage("ReSharper", "HeapView.BoxingAllocation")] | |
void Update() | |
{ | |
if (Input.GetKeyDown(KeyCode.F9)) | |
GraphicsSettings.useScriptableRenderPipelineBatching = !GraphicsSettings.useScriptableRenderPipelineBatching; | |
if (GraphicsSettings.useScriptableRenderPipelineBatching != oldBatcherEnable) | |
{ | |
ResetStats(); | |
oldBatcherEnable = GraphicsSettings.useScriptableRenderPipelineBatching; | |
} | |
if (Input.GetKeyDown(KeyCode.F8)) | |
ToggleStats(); | |
if (!Enable) | |
return; | |
bool SRPBatcher = GraphicsSettings.useScriptableRenderPipelineBatching; | |
accDeltaTime += Time.unscaledDeltaTime; | |
frameCount++; | |
// get timing & update average accumulators | |
foreach (var recorder in recordersList) | |
{ | |
if (recorder.recorder == null) | |
continue; | |
recorder.accTime += recorder.recorder.elapsedNanoseconds / 1000000.0f; // acc time in ms | |
recorder.callCount += recorder.recorder.sampleBlockCount; | |
} | |
if (accDeltaTime < AverageStatDuration) | |
return; | |
float ooFrameCount = 1.0f / frameCount; | |
float avgStdRender = recordersList[(int)SRPBMarkers.kStdRenderDraw].accTime * ooFrameCount; | |
float avgStdShadow = recordersList[(int)SRPBMarkers.kStdShadowDraw].accTime * ooFrameCount; | |
float avgSRPBRender = recordersList[(int)SRPBMarkers.kSRPBRenderDraw].accTime * ooFrameCount; | |
float avgSRPBShadow = recordersList[(int)SRPBMarkers.kSRPBShadowDraw].accTime * ooFrameCount; | |
float RTIdleTime = recordersList[(int)SRPBMarkers.kRenderThreadIdle].accTime * ooFrameCount; | |
float avgPIRPrepareGroupNodes = recordersList[(int)SRPBMarkers.kPrepareBatchRendererGroupNodes].accTime * ooFrameCount; | |
statsLabel = $"Accumulated time for RenderLoop.Draw and ShadowLoop.Draw (all threads)\n{avgStdRender + avgStdShadow + avgSRPBRender + avgSRPBShadow + avgPIRPrepareGroupNodes:F2}ms CPU Rendering time ( incl {RTIdleTime:F2}ms RT idle )\n"; | |
if (SRPBatcher) | |
{ | |
statsLabel += $" {avgSRPBRender + avgSRPBShadow:F2}ms SRP Batcher code path\n"; | |
statsLabel += $" {avgSRPBRender:F2}ms All objects ( {recordersList[(int)SRPBMarkers.kSRPBRenderApplyShader].callCount / frameCount} ApplyShader calls )\n"; | |
statsLabel += $" {avgSRPBShadow:F2}ms Shadows ( {recordersList[(int)SRPBMarkers.kSRPBShadowApplyShader].callCount / frameCount} ApplyShader calls )\n"; | |
} | |
statsLabel += $" {avgStdRender + avgStdShadow:F2}ms Standard code path\n"; | |
statsLabel += $" {avgStdRender:F2}ms All objects ( {recordersList[(int)SRPBMarkers.kStdRenderApplyShader].callCount / frameCount} ApplyShader calls )\n"; | |
statsLabel += $" {avgStdShadow:F2}ms Shadows ( {recordersList[(int)SRPBMarkers.kStdShadowApplyShader].callCount / frameCount} ApplyShader calls )\n"; | |
statsLabel += $" {avgPIRPrepareGroupNodes:F2}ms PIR Prepare Group Nodes ( {recordersList[(int)SRPBMarkers.kPrepareBatchRendererGroupNodes].callCount / frameCount} calls )\n"; | |
statsLabel += $"Global Main Loop: {accDeltaTime * 1000.0f * ooFrameCount:F2}ms ({(int)(((float)frameCount) / accDeltaTime)} FPS)\n"; | |
RazCounters(); | |
} | |
void OnGUI() | |
{ | |
if (!Enable) | |
return; | |
bool SRPBatcher = GraphicsSettings.useScriptableRenderPipelineBatching; | |
GUI.color = new Color(1, 1, 1, 1); | |
GUILayout.BeginArea(new Rect(32, 50, 700, 256), SRPBatcher ? "SRP batcher ON (F9)" : "SRP batcher OFF (F9)", GUI.skin.window); | |
GUILayout.Label(statsLabel, style); | |
GUILayout.EndArea(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment