Files
2026-11-01 23:39:55 +02:00

124 lines
5.5 KiB
C#

using System.Collections;
using UnityEngine.TestTools;
using NUnit.Framework;
#if ENABLE_VR && ENABLE_XR_MODULE
using UnityEngine.XR;
#endif
namespace UnityEngine.Rendering.Tests
{
class RuntimeProfilerTestBase
{
protected const int k_NumWarmupFrames = 10;
protected const int k_NumFramesToRender = 30;
protected DebugFrameTiming m_DebugFrameTiming;
protected GameObject m_ToCleanup;
[SetUp]
public void Setup()
{
if (!FrameTimingManager.IsFeatureEnabled())
Assert.Ignore("Frame timing stats are disabled in Player Settings, skipping test.");
if (Application.isBatchMode)
Assert.Ignore("Frame timing tests are not supported in batch mode, skipping test.");
if (GraphicsSettings.currentRenderPipeline == null)
Assert.Ignore("No active Render Pipeline is set, skipping test.");
// HACK #1 - really shouldn't have to do this here, but previous tests are leaking gameobjects
#pragma warning disable CS0618 // Type or member is obsolete
var objects = GameObject.FindObjectsByType<GameObject>(FindObjectsSortMode.InstanceID);
#pragma warning restore CS0618 // Type or member is obsolete
foreach (var o in objects)
{
// HACK #2 - must not destroy DebugUpdater
if (o.GetComponent<DebugUpdater>() == null)
CoreUtils.Destroy(o);
}
m_DebugFrameTiming = new DebugFrameTiming();
}
[TearDown]
public void TearDown()
{
if (m_ToCleanup != null)
CoreUtils.Destroy(m_ToCleanup);
}
protected IEnumerator Warmup()
{
for (int i = 0; i < k_NumWarmupFrames; i++)
yield return null;
m_DebugFrameTiming.Reset();
}
}
class RuntimeProfilerTests : RuntimeProfilerTestBase
{
[UnityTest]
public IEnumerator RuntimeProfilerGivesNonZeroOutput()
{
// GPU Frame Time support is partial (https://docs.unity3d.com/6000.6/Documentation/Manual/frame-timing-manager.html),
// so adding exceptions here.
bool supportsGpuFrameTime = true;
if ((Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxEditor) && SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore)
supportsGpuFrameTime = false; // Linux + OpenGLCore
if (Application.platform == RuntimePlatform.WebGLPlayer)
supportsGpuFrameTime = false; // WebGL/WebGPU
if ((Application.platform == RuntimePlatform.EmbeddedLinuxArm64 || Application.platform == RuntimePlatform.EmbeddedLinuxX64) && SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3)
supportsGpuFrameTime = false; // EmbeddedLinux GLES (no GL_EXT_disjoint_timer_query)
#if ENABLE_VR && ENABLE_XR_MODULE
if (XRSettings.enabled)
supportsGpuFrameTime = false; // XR
#endif
yield return Warmup();
m_ToCleanup = new GameObject();
var camera = m_ToCleanup.AddComponent<Camera>();
for (int i = 0; i < k_NumFramesToRender; i++)
{
m_DebugFrameTiming.UpdateFrameTiming();
var rr = new UnityEngine.Rendering.RenderPipeline.StandardRequest();
rr.destination = RenderTexture.GetTemporary(128, 128, 24, UnityEngine.Experimental.Rendering.GraphicsFormat.R8G8B8A8_SRGB);
rr.mipLevel = 0;
rr.slice = 0;
rr.face = CubemapFace.Unknown;
UnityEngine.Rendering.RenderPipeline.SubmitRenderRequest(camera, rr);
RenderTexture.ReleaseTemporary(rr.destination);
yield return null;
}
// After k_NumFramesToRender frames, we should have a valid average for every headline counter.
// A failure means the counter was zero on every captured frame. RenderThreadCPUFrameTime and
// MainThreadCPUPresentWaitTime are excluded because they can legitimately be zero (modes without
// a separate render thread; no vsync / no frame rate cap). GPUFrameTime is only asserted on
// platforms known to report it (see supportsGpuFrameTime above).
var avg = m_DebugFrameTiming.m_FrameHistory.SampleAverage;
var zeroAvg = new System.Collections.Generic.List<string>();
if (avg.FramesPerSecond <= 0f)
zeroAvg.Add(nameof(avg.FramesPerSecond));
if (avg.FullFrameTime <= 0f)
zeroAvg.Add(nameof(avg.FullFrameTime));
if (avg.MainThreadCPUFrameTime <= 0f)
zeroAvg.Add(nameof(avg.MainThreadCPUFrameTime));
if (supportsGpuFrameTime && avg.GPUFrameTime <= 0f)
zeroAvg.Add(nameof(avg.GPUFrameTime));
Assert.That(zeroAvg, Is.Empty,
$"After {k_NumFramesToRender} frames the following SampleAverage counters were zero: [{string.Join(", ", zeroAvg)}]. " +
$"All averages: FramesPerSecond={avg.FramesPerSecond}, FullFrameTime={avg.FullFrameTime}, " +
$"MainThreadCPUFrameTime={avg.MainThreadCPUFrameTime}, RenderThreadCPUFrameTime={avg.RenderThreadCPUFrameTime}, " +
$"GPUFrameTime={avg.GPUFrameTime} (asserted={supportsGpuFrameTime}), " +
$"MainThreadCPUPresentWaitTime={avg.MainThreadCPUPresentWaitTime}.");
}
}
}