Profiler API updates (Recorders, CustomSamplers)

The blog post mentions updates to some profiler APIs: Unity Blog

The Sampler / Recorder APIs are not new from what i know - what is going to be updated in this release?
BTW: is this information available only in development builds ? or can we use it in our production builds as well?

Hi Lior,

The basic APIs aren’t new, what’s new is that Recorder API supports recording GPU timings via Recorder.gpuElapsedNanoseconds and Recorder.gpuSampleBlockCount. And yes, those are currently still only available in development builds. Allowing Profiling APIs to be available in Release and/or a Profiling build target is still something we have on our radar and are slowly working towards while e.g. stabilizing/reworking the Profiler Connection, adding a Counters API and the new low-level Profiling APIs etc. but no ETA yet, because there are too many moving parts under this whole thing. (See the Roadmap talk for the stuff we do have an ETA on)

For the ProfilerMarker API, what’s new is the ability to add dynamic custom meta data to a sample, see this page of the scripting documentation for an example. Now that’s not entirely pretty code yet but we’re going to ship a package with a ProfilerMarker extension API in 2020.2 that wraps around that to make it nicer to use and so that these calls can be conditionally compiled out in Release. (That’s just not possible for code in UnityEngine.dll) That said, as you can see from that documentation page, the low-level API IS still available in Release, there’s just nothing there yet to use the data with, so the data goes into a void. This is to avoid users having to wrap the calls in conditionals and to keep our options open for the future.

1 Like

BTW - just out of general curiosity - what is the advantage of splitting the API to a Sampler and a Recorder?
From what i can tell, there’s a 1-1 relationship between them (a Sampler holds exactly 1 Recorder), what is the benefit from doing this ?

Related question:
I’ve asked to expose render stats in Sep 2017 ( link ) and then again in May 2019 ( link ). Since last time I asked is about a year ago: any progress on that topic?

Sampler doesn’t technically hold a recorder. Sampler.GetRecorder just creates one for you the first time you ask for it. It’s just a convenience method, you could just as well use Recorder.Get . The relationship isn’t 1-1 either, it’s 1-[0-n] (though technically you’d be getting the same native recorder, just a different managed wrapper for each). holding a recorder to a sample adds a slight overhead for collecting and storing the timings information. You wouldn’t want this to be always on. Also there is Native Samplers, Managed Samplers and ProfilerMarker API… Recorders record any of these, you just need the name, which is then resolved to the MarkerId.

That’s the Counters mentioned in the Roadmap presentation, headed for 2020.2 Development players only for now.

3 Likes

Hey @MartinTilo ,

Thank you for your detailed replies.
There is one ting though which I couldn’t get running yet…

Could you please elaborate on this?

I just tried to check gpuElapsedNanoseconds in 2020.2.0a13 from enabled recorder which I got like this:
Recorder.Get(“PlayerLoop”)

But value is 0 in Play Mode every frame, while vanilla elapsedNanoseconds shows some numbers.
(SystemInfo.supportsGpuRecorder is true)

Am I misusing it?

I assume it should work for “PlayerLoop” since I see this label both in CPU and GPU profilers.

Hi @codestage ,
Sorry for the confusion around these, I am still not entirely up to speed on these myself. Status today is that not all GPU markers are emitting data in a way that Recorders can hook up to them. In fact, it’s only the ones created as
CustomSampler.Create(name, true) and added to CommandBuffers from C#, so all native markers are not supported, which includes the PlayerLoop. This also means that Recorders currently only work in the context of the SRPs, and not the built-in pipeline. HDRP has a Debug view (Window ->Render Pipeline ->Render Pipeline Debug) that, in Playmode, has a menu entry “Display Stats” that lists some of these GPU values using the Recorder API.

The discoverability of which samples are available to be recorded and which aren’t is quite obviously … sub optimal. We are planning to address this, one way or another but I fear that the most complete & up-to-date way to finding all of these for now is likely by searching through the SRP’s C# code bases for usages of CommandBuffer.BeginSample … :frowning:

2 Likes

Hey @MartinTilo ,

Thank you for all the details provided, now I see a whole picture!
Hope it will support built-in pipeline and most common native markers someday ^^

2 Likes

agreed. In the mean time we added a new ProfilerRecorder API in 2020.2 because we build ourselves into a corner a bit on the native side for the Recorder API and wanted to instead offer one such API to record both the samples created by ProfilerMarker APIs as well as Profiler Counters, such as the stats shown in the different Profiler Modules. This new API does not yet include the capabilities to record GPU but we’ll get there too.

We’re going to go over the different modules and convert them all to the new native Counters API (instead of the old “stats” way to record these values) and evaluate which one of these are near enough to no cost to be left in for Release Builds while we’re at it. For 2020.2 this has already happened for the Memory, Rendering and the new Virtual Texturing Profiler Module.

API to output your own Counter values is pending, an editor to slot any Counters together in a custom module is already added. Stay tuned for more details and documentation (including what counters there are and which ones are in Release) as we tie that all up during the alpha/beta cycle, but feel free to already give that a try :slight_smile:

2 Likes

Thank you for the super detailed update @MartinTilo !

Wow, looks very promising!
Is it possible to find anywhere all the possible currently supported standard values for the statName?

Currently, only the Profiler Window or through ProfilerRecorderHandle.GetAvailable(). As I said, final Documentation and all that is still pending.

1 Like

Thank you, totally works for me!

You are doing a great work out there guys thumbs up

1 Like

This seems like an old thread
but is there a way to get the time taken by the render thread ?

Answered in the other thread .