Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Official Update for Frame Timing Manager

Discussion in 'Profiler Previews' started by antonk-unity, Nov 2, 2021.

  1. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    FrameTimingManager

    The FrameTimingManager enables you to capture and access frame timing data for multiple frames. Frame timing data includes timestamps for different phases of the frame and the duration of work done on the main and render threads. You can use this information to make adjustments to your application where performance is below your target level.

    The FrameTimingManager isn’t enabled by default. To enable this feature, go to Edit > Project Settings > Player and enable the Frame Timing Stats checkbox.


    Note: Enabling Frame Timing Manager has a noticeable performance impact.
    Note that FrameTimingManager is a part of Dynamic Resolution feature and is required to be enabled for it to work.

    What’s changed
    • Added support for DirectX 11
    • GPU time measurements now work in Editor too for most platforms
    • Added Main Thread Central Processing Unit (CPU) Frame time
    • Added Main Thread CPU Present Wait time
    • Added Render Thread CPU Frame time
    • Added First Submit timestamp
    • Added Frame Start timestamp
    • Exposed "CPU Total Frame Time" profiler counter
    • Exposed "CPU Main Thread Frame Time" profiler counter
    • Exposed "CPU Render Thread Frame Time" profiler counter
    • Exposed "Graphics Processing Unit (GPU) Frame Time" profiler counter

    More details on each added field are provided below in “Measurements” section.

    Measurements
    The FrameTimingManager measures a set of important time metrics of a frame, including the following:
    • cpuFrameTime - the total CPU frame time calculated as the time between the ends of two frames, which includes all waiting time and overheads, in ms.
    • cpuMainThreadFrameTime - the total time between the start of the frame and the time when the Main Thread finished the job, in ms.
    • cpuRenderThreadFrameTime - The time between the start of the work on the Render Thread and when the Present() function was called, in ms.
    • cpuMainThreadPresentWaitTime - The CPU time spent in waiting for Present() during the last frame, in ms
    • gpuFrameTime - The GPU time for a given frame, in ms.
    • frameStartTimestamp - The CPU clock time when the frame was started.
    • firstSubmitTimestamp - The CPU clock time when the first job was submitted to the GPU.
    • cpuTimePresentCalled - The CPU clock time at the point Present() was called for the current frame.
    • cpuTimeFrameComplete - The CPU clock time at the point when the GPU finished rendering the frame and interrupted the CPU.

    The following diagram explains how each measured time and timestamp maps to a frame.
    upload_2021-11-2_15-11-31.png

    Important notes:
    • The FrameTimingManager produces results with a fixed delay of four frames because GPU timing results aren’t available immediately.
    • Frame Timing Manager doesn’t guarantee that the GPU has time available. The GPU might fail to return results in time, or might fail to return any results at all. In these cases, the `gpuFrameTime` is reported as zero.
    • On platforms that don’t allow GPU timestamping, Unity computes the FrameCompleteTime value rather than measure it. Unity computes FrameCompleteTime as FirstSubmitTimestamp + GPU Time. If the GPU fails to provide GPU time, FrameCompleteTime is automatically set to be equal to Present Timestamp.
    • On GPUs which use tile-based deferred rendering architecture (such as mobile platforms), results are less precise because GPU execution is deferred and the execution of rendering phases might be done separately. The FrameTimingManager can only measure overall duration.

    Profiler Counters
    Instead of the FrameTimingManager C# API, you can read FrameTimingManager values using the ProfilerRecorder API. The benefit of the ProfilerRecorder API is that the FrameTimingManager measurements are only taken when you attach a recorder to the counter and you have control over potential overhead.

    Code (CSharp):
    1. using Unity.Profiling;
    2. using UnityEngine;
    3.  
    4. public class ExampleScript : MonoBehaviour
    5. {
    6.     string statsText;
    7.     ProfilerRecorder mainThreadTimeRecorder;
    8.  
    9.     void OnEnable()
    10.     {
    11.         mainThreadTimeRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Internal, "CPU Main Thread Frame Time");
    12.     }
    13.  
    14.     void OnDisable()
    15.     {
    16.         mainThreadTimeRecorder.Dispose();
    17.     }
    18.  
    19.     void Update()
    20.     {
    21.         var frameTime = mainThreadTimeRecorder.LastValue;
    22.         // Your code logic here
    23.     }
    24. }
    Setup
    FrameTimingManager is available for Development and Release Unity players. In the Development player, the FrameTimingManager is always enabled.

    In a Release player, you must enable the FrameTimingManager in the Player Settings. To do this, go to Edit > Project Settings > Player and enable the Frame Timing Stats checkbox.

    Platform support

    upload_2021-11-2_15-14-7.png


    Metal
    In some cases, under heavy load or GPU pipeline saturation, reported GPU Time might be bigger than the reported frame time while using the Metal API. For example, reported GPU time might be 40ms with stable 50fps with which you would expect GPU time can’t be higher than 20ms.

    Why does it happen? The Metal API allows us to measure time at the beginning and end of command buffer execution, which in Unity case near matches frame boundaries. Since tile-based deferred rendering architecture GPUs execute rendering in phases (jobs) instead of doing it immediately, there might be a gap between the execution of different phases depending on GPU resource availability. For example, if the GPU is under a high load, there might be a gap when a job is passed from the Vertex queue to the Fragment queue inside the GPU. That results in the situation when jobs activity time (which defines the frame rate) and the total measured wall clock time are significantly different.

     
    Last edited: Nov 2, 2021
  2. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    sold!

    love the amount of low level detail here but, since you know the internals so well, what i'd like to see in the future is pre-chewed metrics in term of pressure. and ideally the total of these numbers = 1
    .cpuPressure
    .bandwidthPressure
    .gpuFillratePressure
    .gpuGeometryPressure

    no point in scaling down the frame buffer if .gpuGeometryPressure is higher than .gpuFillratePressure
    no point in throttling math heavy stuff if .bandwidthPressure is higher than .cpuPressure
     
  3. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    * "Add FrameTimingManager support to the Advanced FPS Counter" issue AFPS-62 created *
     
    MartinTilo and antonk-unity like this.
  4. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey @antonk-unity, thanks for bringing such a powerful tooling to our hands!
    I'm having a few questions about it.

    Could you please share plans on releasing those, which Unity versions are going to get them, as I'm not seeing 'em in the current public alpha yet? ^^

    Another question is those new counters' availability in the release builds: do we need to have Frame Timing Stats option enabled + active Camera with enabled Dynamic Resolution in scene in order to read those counters in release players?

    And last one: is "CPU Main Thread Frame Time" or "CPU Total Frame Time" going to replace existing "Main Thread" ProfilerRecorder in the Internal Category, or they are calculated differently?
     
    alexeyzakharov likes this.
  5. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    Yes, unfortunately, it hasn't made it to 2022.1.0a13 for some reason.
    Any public alpha after that should have it available.

    Enabling "Frame Timing Stats option" is enough. It's recommended to use Frame Timing for control logic of Dynamic Resolution but both features can be used independently.

    "Main Thread" is a marker and you're free to continue using it.
    The downside of "Main Thread" marker is that it might include gfx present wait time (if gfx sync point is set to AfterScriptUpdate) and editor overheads if measured in the Editor. FrameTimingManager MT time tries to exclude most of sync waits to get a time closer to actual execution time.

    Slightly unrelated to Frame Timing Manager, just FYI. If you're using ProfilerRecorder with "Render Thread" marker, we might deprecate & remove it. It was kind of faked and produces wrong results sometimes. More in the ticket - https://issuetracker.unity3d.com/product/unity/issues/guid/1339387/
    In this case, using FrameTimingManager is advised.
     
    MartinTilo and codestage like this.
  6. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thank you for the detailed reply, @antonk-unity !

    That's great to know!
    Do you have any plans on back porting it to the 2021 LTS by chance?

    Thanks, that's what I hoped to hear ^^

    Got it, now I see the difference.

    Regarding "Render Thread" marker - it's good to know, I've seen it in the dev builds only, and the new CPU Render Thread counter looks much more interesting to me as it allows gathering data in release builds.

    One more possibly confusing marker I've seen in Release builds is Camera.Render from the Render Category.
    It's available in Release builds starting from the 2021.1.0f1, and now I wonder if it's something we could use as a fallback instead of Render Thread marker or instead of upcoming "CPU Render Thread Frame Time" counter if user didn't enable Frame Timing Stats option.
     
  7. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    That's very unlikely. Our release managers view on it is that we backport bugfixes only, as any new feature is a potential instability that we don't want to introduce in a stable build.


    `Camera.Render` is a tricky marker as it doesn't measure anything on URP/HDRP. URP/HDRP have their own markers for cameras & render loop. So I don't think you can rely on it much.

    Currently, FrameTimingManager allows you to read data without enabling it in Player settings. If you attach recorder "CPU Render Thread Frame Time" - that will force-enable FrameTimingManager. Although, that's the part I have mixed feelings about. On one hand, it gives you better control over the feature state, on the other, it means it can be silently enabled by someone and you'll be paying the overhead without realizing it. Would be interesting to hear community feedback on it.
     
    codestage likes this.
  8. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Totally understandable, but as plugin dev I'm sad about this %)

    Got it, thanks!

    I'm glad we can enable it at Runtime even if it was disabled in Player Settings, and I'd prefer to keep it so, as this reduces friction and allows straightforward usage scenarios.

    Although, to make it more clear for everyone how and when it's used, I'd be glad to discuss these points:
    1. Explicit API to activate FrameTimingManager from the code (API just duplicates setting in Player Settings)
    2. Prevent FrameTimingManager from working if it wasn't explicitly activated either in Player Settings or through the API (i.e. you'll not get a valid recorder or will always get zero values for "CPU Render Thread Frame Time" and other FrameTimingManager counters unless you activate it through the Player Settings or API call).
    3. Add log on FrameTimingManager activation (both when build starts with activated toggle in Player Settings and when explicitly activating it through the API) explaining this system is now active and do introduce overhead.
    4. Keep all FrameTimingManager counters always visible in Sampler.GetNames() and ProfilerRecorderHandle.GetAvailable() regardless activation state.
     
  9. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Two tiny questions about this:

    - will it require passing a
    ProfilerRecorderOptions.GpuRecorder
    option when starting or creating the
    ProfilerRecorder
    for this counter?

    - will it have a
    MarkerFlags.SampleGpu
    set in the
    ProfilerRecorderDescription.flags
    ?

    Cheers!
     
    Last edited: Nov 14, 2021
  10. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    No for both. It isn't GPU recorder, these are reported by FTM itself.
    There is "FrameTime.GPU" marker which is GPU recorder and used to measure GPU time on some platforms. However, it's better not to subscribe to it as not all platforms use it. For performance reasons, some platforms have custom implementations to exploit native extensions where available - for example, we use `kEGL_ANDROID_get_frame_timestamps` because it's much faster than timer queries used by GPU recorders.
     
  11. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks, that's clear now.

    Now I see how FrameTimingManager is going to make our lives easier =)
    Thanks for the warn about FrameTime.GPU, seems to be something new in yet unreleased alpha / beta, as I'm not finding it in 2021.2.2 or 2022.1.0a13 among other available markers (even after 5+ frame delay).

    From how I feel the concept, it seems ProfilerCounters are more stable and user-friendly rather than ProfilerMarkers and markers recording is somewhat more risky, kind of "low-level, only when you really know what you're doing".
     
  12. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    It's here!

    2022.1.0a15:
    • Profiler: FrameTimingManager platform reach and frame timing information expanded.
     
    MartinTilo likes this.
  13. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey @antonk-unity ,

    I've just gave a spin to the FrameTimingManager update and here is my feedback so far:

    1. Yay, new juicy counters are available now in Editor, Dev and Release builds!

    2021.11.22.gif

    2. New counters work in release builds on my hardware, and I like the fact FTM initializes at runtime even with Frame Timing Stats option disabled, hope this "on-demand" initialization will stay or will be replaced with explicit API call to keep it available!

    3. While tackling a bit with existing FrameTimingManager C# APIs I noticed it does capture all possible stats and there is no way to capture only few of them. Hence, I wonder if recording only few FTM counters using ProfilerRecorders still captures all possible stats under the hood, or it does captures only those which are recorded?

    4. One more kind of confusing part: FTM C# APIs do not allow figuring out how many frames can be captured in the given environment.
    From the docs for GetLatestTimings() numFrames argument: "This should be equal to or less than the maximum FrameTimings the platform can capture." but how to figure out how much platform can capture?
    Without knowing maximum allowed frames to capture, it seems one of the common scenario would be just passing 1-element array to get the latest frame, so it could be worth adding GetLatestTiming() API to get only 1 last timing capture.

    5. I'm seeing strangely high numbers when trying to record "CPU Total Frame Time" and "CPU Main Thread Frame Time" with ProfilerRecorderOptions.CollectOnlyOnCurrentThread option, like 150ms instead of usual 4-5. That seemed strange for me as I expected values from CollectOnlyOnCurrentThread recorder to be lower.

    6. Just a minor possible confusion I've spotted: in my test scene, "CPU Main Thread Frame Time" counter and "CPU Render Thread Frame Time" do not match the Game View Stats panel "CPU main" and "render thread" timings and even showing kind of opposite =D

    upload_2021-11-23_15-29-55.png

    I'm guessing that's because those are calculated way too differently, but similar wording used for counters and stats panel could confuse at the first glance.
     
    alexeyzakharov and antonk-unity like this.
  14. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    Currently, all of them. We'll separate GPU and CPU counters activation in the future as GPU is the most expensive part.

    The original idea of C# API is that you pass N-sized array and the function returns you how many samples you can actually get. This assumes if you want to do some kind of filtering you know how many results you want to handle and API tells you how many it can actually return :)

    Looks like a bug. Could you please report it as a ticket with the example of code that causes this?

    FTM counters return results with 4-frame delay to accommodate GPU results delay and provide CPU and GPU timing for the same frame. Frame stats shows immediate results. However, in the future, we plan to switch everything to use the new FTM.
     
  15. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks for making this clear, looking forward to any news on counters activation separation!

    Thank you for the explanation, but it still sounds a bit clunky..

    Following your comments, to capture averages from i.e. 100 frames I should:
    1. Allocate array of the desired size (100) and pass it along with desired numFrames (100, again).
    2. Take a look at how much array slots were actually filled and cap initial 100 value if necessary.
    3. Resize initial array if 100 was capped to the lower value.

    i.e.:

    Code (CSharp):
    1. FrameTiming[] reusableFramesData; // class field
    2.  
    3. void InitFramesData()
    4. {
    5.     var desiredFrames = 100;
    6.     reusableFramesData = new FrameTiming[desiredFrames];
    7.     FrameTimingManager.GetLatestTimings(desiredFrames, reusableFramesData);
    8.  
    9.     var actualFrames = GetFilledItemsCount(reusableFramesData);
    10.     if (actualFrames < desiredFrames)
    11.         Array.Resize(ref reusableFramesData, actualFrames);
    12.  
    13.     // can finally use / reuse reusableFramesData
    14. }
    What would be great to see is an API which just could return numFrames for the current platform, so this could be reduced to:

    Code (CSharp):
    1. FrameTiming[] reusableFramesData; // class field
    2.  
    3. void InitFramesData()
    4. {
    5.     var actualFrames = FrameTimingManager.GetMaxNumFrames();
    6.     reusableFramesData = new FrameTiming[actualFrames];
    7.     FrameTimingManager.GetLatestTimings(reusableFramesData); // overload with 1 argument, uses passed array size
    8.  
    9.     // can finally use / reuse reusableFramesData
    10. }
    Please let me know if I misunderstood something here %)

    Sorry that was my bad as I passed
    ProfilerRecorderOptions.CollectOnlyOnCurrentThread
    instead of
    ProfilerRecorderOptions.CollectOnlyOnCurrentThread | ProfilerRecorderOptions.Default
    :oops:
    So it works just fine now!

    Understood, but that opposite difference from the screenshot is constant, i.e. I always see higher value in FTM's "CPU Render Thread Frame Time" counter comparing to "render thread" from the stats' panel while running my test scene.

    That's great to hear, it will eliminate any possible confusion.
     
  16. mirmir1712

    mirmir1712

    Joined:
    Feb 7, 2021
    Posts:
    1
    Hi,
    I am trying to take timestamps of frames being display and I thought about using FrameTiming.cpuTimeFrameComplete, it works fine on windows but, on oculus quest (1 and 2) it returns 0. I would like to know if it is a problem with all oculus headsets or in my code and if it will be fixed?
    * The build for the oculus is an android build.

    The code below attached to the main camera.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using TMPro;
    4. using UnityEngine;
    5. using System.Text;
    6.  
    7. public class Timing : MonoBehaviour
    8. {
    9.     public TMP_Text screenText;
    10.  
    11.     FrameTiming[] frameTimings = new FrameTiming[1];
    12.  
    13.  
    14.  
    15.     uint m_frameCount = 0;
    16.  
    17.     const uint kNumFrameTimings = 2;
    18.  
    19.  
    20.  
    21.     // Update is called once per frame
    22.     void Update()
    23.     {
    24.         ++m_frameCount;
    25.         if (m_frameCount <= kNumFrameTimings)
    26.         {
    27.             return;
    28.         }
    29.         FrameTimingManager.CaptureFrameTimings();
    30.         uint res = FrameTimingManager.GetLatestTimings(1, frameTimings);
    31.         if (res < 1)
    32.         {
    33.             UnityEngine.Debug.LogErrorFormat("Skipping frame {0}, didn't get enough frame timings.",
    34.                 m_frameCount);
    35.             screenText.text = string.Format("error frame {0}",
    36.             m_frameCount);
    37.  
    38.             return;
    39.         }
    40.  
    41.  
    42.         screenText.text = string.Format("cpu frame time: {0}\ncpu time frame complete: {1}\ncpu time present called: {2}\ngpu frame time: {3}\nheight scale: {4}\nsync interval: {5} \nwidth scale: {6}\n{7}\n{8}\n{9}\n{10}\n{11}",
    43.             frameTimings[0].cpuFrameTime,
    44.             frameTimings[0].cpuTimeFrameComplete,
    45.             frameTimings[0].cpuTimePresentCalled,
    46.             frameTimings[0].gpuFrameTime,
    47.             frameTimings[0].heightScale,
    48.             frameTimings[0].syncInterval,
    49.             frameTimings[0].widthScale,
    50.             frameTimings[0].cpuMainThreadFrameTime,
    51.             frameTimings[0].cpuRenderThreadFrameTime,
    52.             frameTimings[0].cpuMainThreadPresentWaitTime,
    53.             frameTimings[0].frameStartTimestamp,
    54.             frameTimings[0].firstSubmitTimestamp);
    55.     }
    56. }
    57.  
    In addition, is there a way to access the CPU clock time to compare the FrameTiming.cpuTimeFrameComplete with the current time?
     
  17. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    The code looks fine, could you please file a ticket? We'll take a look
    Please include information about the exact model, and firmware of the Oculus device. Also, if you could include logcat logs captured while running the app, that might help a lot.
     
  18. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    I would rather store a number of frames captured separately instead of resizing the array.
    The number of frames returned is not the maximum number, but currently available number of frames. So it might be different the next time you capture. It might vary for different reasons - for example, something has failed during the capturing process (whenever FTM relies on platform-specific API it might happen)

    Thanks, I've noted to take a look. Editor's gfx part is a bit wonky :)
     
    codestage likes this.
  19. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Ah, that's clear now, thanks!

    Still, if it's a low-hanging fruit under the hood (and already calculated or stored somewhere), it would be great to somehow figure out "the maximum FrameTimings the platform can capture" to allocate for FrameTiming[] not more than the platform can actually capture ^^
     
  20. deep_deep

    deep_deep

    Joined:
    Aug 10, 2019
    Posts:
    16
    I am a simple man. I want to know the time taken to do work on the cpu (main + render thread) and the time spent by the gpu to present the frame. The end goal is to have a normalized quantity of whether the cpu or the gpu is performing better. How do I get this?

    It has been said time and again, but the docs don't actually provide a good example of how to scale dynamic buffers with FrameTimingManager.
     
    djarcas, xBoxRedDot and Gamba04 like this.
  21. pixelsplit

    pixelsplit

    Joined:
    Sep 16, 2013
    Posts:
    173
    Hi,

    there is a little confusion on our side. We use latest 2021.2, DX11 and the FrameTimeManager just returns zeros (tested on different PCs). Is this a 2022.x feature?

    Best regards
    Bennet
     
  22. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    Yes, unfortunately, 2022.1.0a13 is the earliest version where it's available.
     
    pixelsplit likes this.
  23. pixelsplit

    pixelsplit

    Joined:
    Sep 16, 2013
    Posts:
    173
    Thanks for the clarification. One further question: You wrote that enabling the Frame Time Manager costs performance. Even if it is not used in code? Is there any way to disable it at runtime? We'd just need it for our Dynamic Resolution system and if someone would disable Dynamic Res in our settings it'd be nice to disable the Frame Time Manager too.
     
  24. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    Yes, if FTM is active, it'll add overhead even if unused.

    You can control FTM activation with ProfilerRecorder. If you uncheck the Frame Timing Manager option in Player settings and use ProfilerRecorder - FTM will be active only when ProfilerRecorder is attached to any counters FTM exposes.
     
  25. pixelsplit

    pixelsplit

    Joined:
    Sep 16, 2013
    Posts:
    173
    Thanks for explanation! That sounds useful. Now we only have to wait for an official 2022.1 release.
     
  26. matt_cauldron

    matt_cauldron

    Joined:
    Dec 17, 2021
    Posts:
    48
    Hi there, thanks for the detailed update! Curious as to whether being unable to capture GPU timing states from WebGL targets is likely to ever be possible? Is it just an inherent limitation from way in which it's run in browser?
     
  27. SevenPointRed

    SevenPointRed

    Joined:
    Feb 3, 2016
    Posts:
    218
    The example code on the blog doesnt compile.

    Code (CSharp):
    1. static PerformanceBottleneck DetermineBottleneck(FrameTimeSample s)
    2.  
    FrameTimeSample Doesnt exist.
     
  28. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    Hi. Thanks for the feedback, I'll correct it. Just in case it isn't much different from FrameTiming structure and is a convenience wrapper. You can find the full source in SRP repo.

    Graphics/Packages/com.unity.render-pipelines.core/Runtime/Debugging/FrameTiming at master · Unity-Technologies/Graphics (github.com)
     
    codestage likes this.
  29. Sabrino

    Sabrino

    Joined:
    Aug 8, 2015
    Posts:
    35
    How can one get gpu frame time on directx 11 in 2021 lts? Dx12 is not in a usable state on PC, and without it I see no way to dynamically tune performance.
     
  30. MiFrilke

    MiFrilke

    Joined:
    Dec 14, 2016
    Posts:
    41
    I'll add one more question here for clarification:
    FTM only works in 2022.1.0a13 and later versions, ok. But 2021.3 still has the flag in Player Settings to enable Frame Timing Stats gathering (and the FrameTimingManager API that returns nothing of value...). Will enabling this setting cause overhead even though FTM API isn't even usable in 2021.3? If so, I feel like this is a pretty big flaw in 2021.3 and the option should be removed and forced off.
     
  31. Jelmer123

    Jelmer123

    Joined:
    Feb 11, 2019
    Posts:
    243
    The screen at the bottom of the post looks like what I want. However, where do I find it? :D
     
    morepixels likes this.
  32. peci_scx

    peci_scx

    Joined:
    Sep 7, 2015
    Posts:
    3
    FrameTimingManager still not working for me.
    windows, dx11. neither editor nor on a build. (dev build).
    enabled frame time stats.
    updated unity to latest 2021.3.18f

    still the same.
    FrameTimingManager.GetLatestTimings(...) always returns 0 and does not give any data.

    Even the FrameTimingsHUDDisplay sample does not work. same issue.

    note that SystemInfo.supportsGpuRecorder returns true.

    also tried the ProfilerRecorder:
    GPURecorder = ProfilerRecorder.StartNew(ProfilerCategory.Internal, "GPU Frame Time (ms)", 100, ProfilerRecorderOptions.GpuRecorder| ProfilerRecorderOptions.SumAllSamplesInFrame);

    its always Invalid and returns 0 values.

    when i open the profiler i see GPU and CPU timings. its just that i want to view them like a FPS counter in realtime in game.

    Am i doing something wrong? is the FrameTimingManager removed/disabled for dx 11 in 2021.3.18f?
    if so which version should i downgrade to have it working?
     
  33. MiFrilke

    MiFrilke

    Joined:
    Dec 14, 2016
    Posts:
    41
    As stated above by @antonk-unity : FrameTimingManager only produces usable data in Unity 2022.1.0a13 and later versions.

    Unity 2021.3.x seems to be some kind of forgotten child that has the API exposed but doesn't know what to do with it :(
     
  34. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Hi what happened to FullFrameTime? This is a property used in the blogpost, but this doesnt appear to be available anymore?
     
  35. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    It isn't forgotten, but Unity's policy is not to backport features, as it might be a breaking change and affect the stability of existing projects. We only backport bug fixes. These changes to Frame Timing Manager were much wider than just bug fixes, so they were restricted to the latest version of Unity only.
     
  36. antonk-unity

    antonk-unity

    Unity Technologies

    Joined:
    Oct 4, 2016
    Posts:
    50
    Sorry, which "FullFrameTime"? cpuFrameTime?
    It's available, but you need Unity version 2022.1 or older.

    Unity - Scripting API: FrameTiming (unity3d.com)
     
  37. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Sorry my bad, the blogpost uses `FullFrameTime`. What is the newer equivalent? I'm unsure how to upgrade the bottleneck detection you posted on the blog.
     
    Last edited: Apr 1, 2023
    firelight_jaden likes this.
  38. baggyg

    baggyg

    Joined:
    Nov 21, 2013
    Posts:
    30
    Is this available in 2021.3? When I try:
    if (FrameTimingManager.GetCpuTimerFrequency() == 0 || FrameTimingManager.GetGpuTimerFrequency() == 0)

    In 2021.3 / HDRP / OpenXR its always 0. I was hoping to enable DSR.
     
  39. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,456
    No, unfortunately this only landed in 2022.1.0a14 and could not be backported.
     
  40. baggyg

    baggyg

    Joined:
    Nov 21, 2013
    Posts:
    30
    So basically Dynamic Resolution Scaling is not possible in 2021.3?
     
  41. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,456
    Not on all platforms via FrameTimingManager. There may be workarounds with costum heuristics and e.g. native plugins to get some platform specific counters to make up for the lack of FTM. I.e. not trivially and in general, no.
     
  42. shihab37

    shihab37

    Joined:
    Jul 7, 2015
    Posts:
    28
    I'm seeing this weird behavior on Android.
    In an empty test scene, the average GPU frame time remains roughly around 3.5ms at any FPS below 60 (I tested 5, 10, 15, 20 & 30). At 60 FPS, the GPU frame time jumps up to 10ms.

    Could it be device specific? I tested it on a different Samsung device as well and the behavior was very similar but a bit delayed.

    Unity 23.1.2f1 - Graphics API Vulkan
     
    Last edited: Jul 9, 2023
  43. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,456
    I feel like that's not really a FrameTimingManager thing but something you should check out with a platform specific profiler, like one from your specific device's GPU Manufacturer/Designer(e.g. Arm Mobile Studio), for more concrete confirmation, but: Mobile devices have a limited power budget and they have heat build-ups to consider. So the higher the FPS, the more power will be needed by both the CPU and the GPU and more of that at the same time, as there is less idle time on the CPU. The screen may also need extra power for that. All of that means that less power is available at any point in the frame time, more heat is building up and the device is likely to down-clock the GPU as a consequence
     
  44. shihab37

    shihab37

    Joined:
    Jul 7, 2015
    Posts:
    28
    That makes a lot of sense. This actually explains why the newer device took some time before thermal throttling the GPU.
    Thank you. I will profile with Arm Mobile Studio (and other tools mentioned in ultimate profiling guide) for a more detailed analysis if the need arises.
     
    MartinTilo likes this.
  45. djarcas

    djarcas

    Joined:
    Nov 15, 2012
    Posts:
    246
    I might be being really stupid, but on DX11/DX12, the frametiming stuff works wonderfully in editor, but not in a Windows build. I ticked the box under Player settings. Why is everything coming back as 0? 2022.3.3f1.
     
  46. morepixels

    morepixels

    Joined:
    May 21, 2014
    Posts:
    18
    Google shows this page for many GPU profiling queries. Can you please elaborate on how to open this window, or at least point to a page that explains it?

     
  47. tcmicka

    tcmicka

    Joined:
    Aug 2, 2017
    Posts:
    9
    Is it possible to get the gpuFrameTime on Quest 2 using OpenGLES3 and OpenXR?

    This post might hint that it's not supported yet?
     
  48. thomas-soba

    thomas-soba

    Joined:
    Jul 11, 2023
    Posts:
    4
    Can somebody help me understand the values a bit better. I have tested a build on a Samsung S10 (OpenGLES3). It's running at 60fps. Frame time is 16ms, as expected. CPU time is 11ms which is understandable. GPU frame time is reported as 20ms. How can that be explained? As far as I understood this thread, only Metal could potentially report a higher GPU time than general frame time. Am I missing something? (2022.2.17, URP 14.0.7)
     
  49. paulatwarp

    paulatwarp

    Joined:
    May 17, 2018
    Posts:
    135
    If it's only available in 2022 why is it in the documentation for 2021. With examples. This is just wasting people's time.
     
  50. paulatwarp

    paulatwarp

    Joined:
    May 17, 2018
    Posts:
    135
    If you're on Unity 2021, what options do you have for getting GPU frame timings?