Skip to content

jenatali/PresentMon

 
 

Repository files navigation

PresentMon

PresentMon is a tool to capture and analyze ETW events related to swap chain presentation on Windows. It can be used to trace key performance metrics for graphics applications (e.g., CPU and Display frame durations and latencies) and works across all graphics APIs, including UWP applications.

While PresentMon itself is focused on lightweight collection and analysis, there are several other programs that build on its functionality and/or helps visualize the resulting data. For example, see

This readme contains the following sections:

License

Copyright 2017-2019 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Releases

Binaries for main release versions of PresentMon are provided on GitHub:

Please see CONTRIBUTING for information on how to request features, report issues, or contribute code changes.

Command line options

Capture target options:
  -captureall               Record all processes (default).
  -process_name [exe name]  Record only processes with the provided name. This
                            argument can be repeated to capture multiple
                            processes.
  -exclude [exe name]       Don't record specific process specified by name.
                            This argument can be repeated to exclude multiple
                            processes.
  -process_id [integer]     Record only the process specified by ID.
  -etl_file [path]          Consume events from an ETL file instead of running
                            processes.

Output options (see README for file naming defaults):
  -output_file [path]       Write CSV output to specified path.
  -output_stdout            Write CSV output to STDOUT.
  -multi_csv                Create a separate CSV file for each captured
                            process.
  -no_csv                   Do not create any output file.
  -no_top                   Don't display active swap chains in the console
                            window.
  -qpc_time                 Output present time as performance counter value
                            (see QueryPerformanceCounter()).

Recording options:
  -hotkey [key]             Use specified key to start and stop recording,
                            writing to a unique CSV file each time. 'key' is of
                            the form MODIFIER+KEY, e.g., alt+shift+f11. (See
                            README for subsequent file naming).
  -delay [seconds]          Wait for specified time before starting to record.
                            If using -hotkey, delay occurs each time recording
                            is started.
  -timed [seconds]          Stop recording after the specified amount of time.
  -exclude_dropped          Exclude dropped presents from the csv output.
  -scroll_indicator         Enable scroll lock while recording.
  -simple                   Disable GPU/display tracking.
  -verbose                  Adds additional data to output not relevant to
                            normal usage.

Execution options:
  -session_name [name]      Use the specified name to start a new realtime ETW
                            session, instead of the default "PresentMon". This
                            can be used to start multiple realtime capture
                            process at the same time (using distinct names). A
                            realtime PresentMon capture cannot start if there
                            are any existing sessions with the same name.
  -stop_existing_session    If a trace session with the same name is already
                            running, stop the existing session (to allow this
                            one to proceed).
  -dont_restart_as_admin    Don't try to elevate privilege.  Elevated privilege
                            isn't required to trace a process you started, but
                            PresentMon requires elevated privilege in order to
                            query processes started on another account. Without
                            it, these processes cannot be targetted by name and
                            will be listed as '<error>', and if they are
                            targetted -terminate_on_proc_exit won't work and
                            there may be tracking errors near process
                            termination.
  -terminate_on_proc_exit   Terminate PresentMon when all the target processes
                            have exited.
  -terminate_after_timed    When using -timed, terminate PresentMon after the
                            timed capture completes.

Beta options:
  -include_mixed_reality    Capture Windows Mixed Reality data to a CSV file
                            with "_WMR" suffix.

Comma-separated value (CSV) file output

CSV file names

By default, PresentMon creates a CSV file named PresentMon-TIME.csv, where TIME is the creation time in ISO 8601 format. To specify your own output location, use the -output_file PATH command line argument.

If -multi_csv is used, then one CSV is created for each process captured and -PROCESSNAME appended to the file name.

If -hotkey is used, then one CSV is created for each time recording is started and -INDEX appended to the file name.

CSV columns

Column Header Data Description Required argument
Application The name of the process that called Present (if known)
ProcessID The process ID of the process that called Present
SwapChainAddress The address of the swap chain that was presented into
Runtime The runtime used to present (e.g., D3D9 or DXGI)
SyncInterval Sync interval used in the Present call
PresentFlags Flags used in the Present call
PresentMode The presentation mode used by the system for this Present not -simple
AllowsTearing Whether tearing is possible (1) or not (0) not -simple
TimeInSeconds The time of the Present call, measured from when PresentMon recording started in seconds
QPCTime The time of the Present call, as a performance counter value (see QueryPerformanceCounter()) -qpc_time
MsInPresentAPI The time spent inside the Present call, in milliseconds
MsUntilRenderComplete The time between the Present call (TimeInSeconds) and when the GPU work completed, in milliseconds not -simple
MsUntilDisplayed The time between the Present call (TimeInSeconds) and when the frame was displayed, in milliseconds not -simple
Dropped Whether the frame was dropped (1) or displayed (0); if dropped, MsUntilDisplayed will be 0
MsBetweenPresents The time between this Present call and the previous one, in milliseconds
MsBetweenDisplayChange The time between when the previous frame was displayed and this frame was, in milliseconds not -simple
WasBatched Whether the frame was submitted by the driver on a different thread than the app (1) or not (0) -verbose
DwmNotified Whether the desktop compositor was notified about the frame (1) or not (0) -verbose

Windows Mixed Reality

Note: Windows Mixed Reality support is in beta, with limited OS support.

If -include_mixed_reality is used, a second CSV file will be generated with _WMR appended to the filename with the following columns:

Column Header Data Description Required argument
Application Process name (if known) -include_mixed_reality
ProcessID Process ID -include_mixed_reality
DwmProcessID Compositor Process ID -include_mixed_reality
TimeInSeconds Time since PresentMon recording started -include_mixed_reality
MsBetweenLsrs Time between this Lsr CPU start and the previous one -include_mixed_reality
AppMissed Whether Lsr is reprojecting a new (0) or old (1) App frame (App GPU work must complete before Lsr CPU start) -include_mixed_reality
LsrMissed Whether Lsr displayed a new frame (0) or not (1+) at the intended V-Sync (Count V-Syncs with no display change) -include_mixed_reality
MsAppPoseLatency Time between App's pose sample and the intended mid-photon frame display -include_mixed_reality
MsLsrPoseLatency Time between Lsr's pose sample and the intended mid-photon frame display -include_mixed_reality
MsActualLsrPoseLatency Time between Lsr's pose sample and mid-photon frame display -include_mixed_reality
MsTimeUntilVsync Time between Lsr CPU start and the intended V-Sync -include_mixed_reality
MsLsrThreadWakeupToGpuEnd Time between Lsr CPU start and GPU work completion -include_mixed_reality
MsLsrThreadWakeupError Time between intended Lsr CPU start and Lsr CPU start -include_mixed_reality
MsLsrPreemption Time spent preempting the GPU with Lsr GPU work -include_mixed_reality
MsLsrExecution Time spent executing the Lsr GPU work -include_mixed_reality
MsCopyPreemption Time spent preempting the GPU with Lsr GPU cross-adapter copy work (if required) -include_mixed_reality
MsCopyExecution Time spent executing the Lsr GPU cross-adapter copy work (if required) -include_mixed_reality
MsGpuEndToVsync Time between Lsr GPU work completion and V-Sync -include_mixed_reality
MsBetweenAppPresents Time between App's present and the previous one -include_mixed_reality and not -simple
MsAppPresentToLsr Time between App's present and Lsr CPU start -include_mixed_reality and not -simple
HolographicFrameID App's Holographic Frame ID -include_mixed_reality -verbose
MsSourceReleaseFromRenderingToLsrAcquire Time between composition end and Lsr acquire -include_mixed_reality -verbose
MsAppCpuRenderFrame Time between App's CreateNextFrame() API call and PresentWithCurrentPrediction() API call -include_mixed_reality -verbose
MsAppMisprediction Time between App's intended pose time and the intended mid-photon frame display -include_mixed_reality -verbose
MsLsrCpuRenderFrame Time between Lsr CPU render start and GPU work submit -include_mixed_reality -verbose
MsLsrThreadWakeupToCpuRenderFrameStart Time between Lsr CPU start and CPU render start -include_mixed_reality -verbose
MsCpuRenderFrameStartToHeadPoseCallbackStart Time between Lsr CPU render start and pose sample -include_mixed_reality -verbose
MsGetHeadPose Time between Lsr pose sample start and pose sample end -include_mixed_reality -verbose
MsHeadPoseCallbackStopToInputLatch Time between Lsr pose sample end and input latch -include_mixed_reality -verbose
MsInputLatchToGpuSubmission Time between Lsr input latch and GPU work submit -include_mixed_reality -verbose

Known issues

See GitHub Issues for a complete list of reported issues.

Analyzing OpenGL and Vulkan applications

Applications that do not use D3D9 or DXGI APIs for presenting frames (e.g., as is typical with OpenGL or Vulkan applications) will report the following:

  • Runtime = Other.
  • SwapChainAddress = 0
  • SyncInterval = -1
  • PresentFlags = 0
  • MsInPresentAPI = 0

In this case, TimeInSeconds will represent the first time the present is observed in the kernel, as opposed to the runtime, and therefore will be sometime after the application presented the frame (typically ~0.5ms). Since MsUntilRenderComplete and MsUntilDisplayed are deltas from TimeInSeconds, they will be correspondingly smaller then they would have been if measured from application present. MsBetweenDisplayChange will still be correct, and MsBetweenPresents should be correct on average.

Measuring application latency

PresentMon doesn't directly measure the latency from a user's input to the display of that frame because it doesn't have insight into when the application collects and applies user input. A potential approximation is to assume that the application collects user input immediately after presenting the previous frame. To compute this, search for the previous row that uses the same swap chain and then:

LatencyMs =~ 1000 * MsBetweenPresents + MsUntilDisplayed - previous(MsInPresentAPI)

Shutting down PresentMon on Windows 7

Some users have observed system stability issues when forcibly shutting down PresentMon on Windows 7. PresentMon shutdown code was rewritten to address this, but if you are having similar issues shutting PresentMon down using Ctrl+C in its window may be a workaround.

About

ETW based FPS monitor

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 97.8%
  • Batchfile 2.2%