Fast Forward

If you’ve read the article already and/or want to jump straight to profiling, go to the TL;DR section.

Context

WebGPU is not a native graphics API, as in no hardware vendor provides specific drivers for their GPUs targeting this API. Instead, WebGPU runtimes like web browsers must implement backends for WebGPU using modern native APIs such as DirectX12, Vulkan or Metal. Those APIs are widely used, in particular for video games, and hardware vendors have developed great profiling tools for them.

Sadly those GPU profilers don’t work out of the box with WebGPU workloads executed by Chrome. The main reason for this is that while Chrome does execute such workloads using the aformentioned graphics APIs, it doesn’t present the rendered content on screen using those APIs. There are good reasons for this and the technical details are not important here, the point is GPU profilers wouldn’t work and it made me sad.

The good news is I found a way to work around that limitation! It’s a terrible hack but in practice it works well. All you need to do is download a DLL I wrote and put it in the correct location to get both AMD’s Radeon GPU Profiler and Nvidia’s Nsight to work! See the details in the next section. Also, while this only works on Windows I have seen this gist floating around for Apple, but I have nothing for Linux :/.

If you are interested in what was missing, how I fixed it and what this mysterious DLL is doing, please read the following companion blog post Shimming d3d12.dll for fun and profit. I would also like to thank Marco Castorina and Ray Dey without whom this hack probably wouldn’t exist :).

How to use

Before anything else, please remember that this is a hacky solution and that you should not browse the open web with that DLL attached. It should only be used for a GPU profiling session and removed afterwards. It also conflicts with PIX, so you should remove it before attempting to take a capture. I would recommend adding that DLL to a specific flavor of Chrome ( Dev, Canary, etc. ) that you would only use for GPU profiling.

Getting the DLL

Go to the following repository and either download d3d12.dll from the release section or download the repository and build it yourself. Place the DLL in the Chrome folder where chrome.exe exists, for instance: C:\Program Files\Google\Chrome\Application

Chrome command line arguments

The way you should launch Chrome depends on the profiler you will be using. However, the command line arguments required are mostly the same as the ones used to capture a frame with PIX as described in Tojiro’s blog.

For reference, here are the arguments I use:

  1. --disable-gpu-sandbox --disable-gpu-watchdog
  2. --enable-dawn-features=emit_hlsl_debug_symbols,disable_symbol_renaming
  3. --no-sandbox
  4. --disable-direct-composition

The first arguments are the minimum required to capture a frame. The second ones are convenience arguments that let you inspect shader source with the original variable names. The third one is required by Nvidia Nsight to function properly, I have no idea why. The last argument used to be required to capture Chrome with PIX so I keep it around just in case.

Enabling debug markers

To enable debug markers, we’ll again refer to Tojiro’s blog. The gist of it is to copy WinPixEventRuntime.dll from https://www.nuget.org/packages/WinPixEventRuntime into <Chrome Dir>\<Version Number>.

Unfortunately, the Radeon tools don’t support PIX markers out of the box. No problem, I wrote a modified version of WinPixEventRuntime.dll that is supported by the Radeon tools. This DLL is hardware vendor agnostic and will only enhance the PIX markers on AMD hardware. The process to get it is exactly the same as getting the modified d3d12.dll. Simply go the following repository and either download WinPixEventRuntime.dll from the release section or clone the repository and build it yourself.

Capturing a frame with RDP

To profile with AMD’s Radeong GPU Profiler, you need to download the Radeon Developer Tool Suite from GPUOpen. Download the package and unzip it at any location you see fit, all the apps are portable.

Double-click on the Radeon Developer Panel’s exe to start it. If this is the first time you’re using it, you will likely need to select a feature you would like to use from the top left corner. In our case, we would like to profile the GPU so we will select Profiling.

An image showing the available features in RDP

Please note the green dot on left of the connection tab. If that dot is red, you might need to go to that tab and hit the connect button in the bottom right corner but normally it should connect automatically.

When the Radeon Developer Panel is open, connected and has the Profiling feature selected, any DirectX12, Vulkan, OpenCL or HIP application that you launch from now on will be automatically detected and attached to. This means we are now ready to launch Chrome.

Since RDP doesn’t need to launch the app for you, feel free to open your favorite terminal and to launch Chrome from there using the previously mentioned CLI arguments. The overall command line should look something like this:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --no-sandbox --disable-gpu-sandbox --disable-gpu-watchdog --disable-direct-composition --enable-dawn-features=emit_hlsl_debug_symbols,disable_symbol_renaming

Now open a WebGPU app in a tab and if everything is working properly you should see RDP’s Profiling tab change from Status: Offline to Status: Ready.

An image showing what the profiling tab of RDP should look like when connected.

You can now hit the Capture profile button or use the configurable hot key Ctrl+Alt+C to capture your WebGPU app. The profile should appear on the right side of the app under Recently collected profiles.

An image showing the recently collected profile table in RDP

Simply double-click any of the files to open the Radeon GPU profiler. If that doesn’t work, you might need to configure that path manually by hitting the cog-wheel in the top right hand corner of your screen.

An image showing the events tab of a RGP capture.

And voila, you are ready to explore the performance of your app using RGP. How to use RGP itself is outside the scope of this post but another one might follow ;). In the meantime, feel free to explore the following resources.

Capturing a frame with Nsight

To profile with Nvidia hardware, first download and install Nsight Graphics. Much like PIX, Nsight must launch an app itself to be able to profile it. So open Nsight, click the connect button in the top left corner and select GPU Trace Profiler from the Activity tab.

An image showing how to setup the GPU trace mode of Nsight

Select your Chrome executable in the Application Executable field, the path should look something like C:\Program Files\Google\Chrome\Application\chrome.exe. Don’t forget to fill the Command Line Arguments field with the relevant arguments, including the required --no-sandbox. The field should look something like --no-sandbox --disable-gpu-sandbox --disable-gpu-watchdog --disable-direct-composition --enable-dawn-features=emit_hlsl_debug_symbols,disable_symbol_renaming.

Once those fields are filled, just hit the Launch GPU Trace button in the bottom right corner and watch Chrome start. Open a tab with a WebGPU workload to make Nsight connect automatically. If the operation succeeded the app’s layout should change and a new Collect GPU Trace button should appear.

An image showing where the capture button is in the Nsight interface

Once you’ve hit that button, a message box should inform you that the capture succeeded. Just press the Open button to access the capture.

An image showing the message box after Nsight finished capturing a frame.

You should now see the following view and should be able to explore the performance of your app.

An image showing the main interface of Nsight

How to use Nsight itself is outside the scope of this post but feel free to explore the following resources.

Closing Remarks

The solution provided here is a terrible hack that happens to trigger both RDP and Nsight at the time of writing this article. It’s entirely possible that this breaks tomorrow and there isn’t much I can do about it.

That being said, at this time it is also the only available option to properly profile the GPU for WebGPU on Windows / Chrome. This was my biggest pain point when working daily with WebGL, along with the lack of a proper graphics debugger. Now WebGPU has both through PIX and RGP/Nsight. To me that makes it a much more viable option for serious graphics programming. Performance doesn’t have to be about mythical knowledge and voodoo optimizing blindfolded with both hands tied in the back anymore. Fire up that profiler and look at some actual metrics!

TL;DR

Before anything else, please remember that this is a hacky solution and that you should not browse the open web with that DLL attached. It should only be used for a GPU profiling session and removed afterwards. It also conflicts with PIX, so you should remove it before attempting to take a capture. I would recommend adding that DLL to a specific flavor of Chrome ( Dev, Canary, etc. ) that you would only use for GPU profiling.

Instructions

  1. Download d3d12.dll from the release section of this repository.
    • Place the DLL into the \Google\Chrome\Application folder.
  2. On AMD, download WinPixEventRuntime.dll from the release section of that repository.
    • Place it into the \Google\Chrome\Application\<Version Number> folder.
  3. When launching Chrome, use the following command line arguments:
    • --no-sandbox --disable-gpu-sandbox --disable-gpu-watchdog --disable-direct-composition --enable-dawn-features=emit_hlsl_debug_symbols,disable_symbol_renaming
  4. Use your favorite GPU profiler as usual.