As you may know in the Windows world, DirectX is often used for drawing graphics. In recent versions (10, 11.x), the library has seriously stepped forward and it is on them that the engines of many modern games are built. In addition, DirectX is used not only in games - the Windows OS interface itself also doesn’t remember which version (Vista?) Is drawn through it, and it would seem that the programs that are not strongly connected with graphics, wanting to increase the performance and smoothness of the zoom / scrolling, are latest version of directx. So some time ago, the Google Chrome render went to DirectX11 (seemingly from version 36).
Sometime during the days of Windows 95 and Pentium II there was such a joke that the slower a computer is - the better you can understand the operation of the operating system - you can see with the naked eye the order in which the window elements are drawn, events are processed. Today, for such purposes, there are separate tools for DirectX - graphical debuggers that allow you to understand exactly how each pixel of each frame is drawn, what operations the DirectX engine performs, what resources it uses, how quickly and correctly everything works. One of these tools -
RenderDoc from the company Crytek today we will consider. And as an example, let's analyze the already mentioned above new render of Google Chrome.

')
First of all - why am I talking about RenderDoc? There are many similar tools:
All of them are very good. But:
- PIX - is already outdated, does not develop and does not work on the latest OS
- Intel \ AMD \ Nvidia tools - made in the spirit of "with these utilities you can see how DirectX works with awesome cool and fast work on our video cards", while some applied, routine debugging tasks are not very convenient to do in them
- Visual Studio - sharpened specifically for the development of its software, and not the analysis of someone else's
As for RenderDoc, this is:
- opensource , actively developing
- sharpened on the latest versions of Windows and DirectX11
- product from 3D development professionals - the company that created the CryEngine engine with all the associated strapping
- imbued with a practical approach to development and debugging - I don’t know how to explain it better, but for example, when you just think about the fact that “hm, it would be nice to see this information in this form here”, that RenderDoc shows exactly this information, precisely in this call and in the right form. It can be seen that the tool lives and polishes in the hands of Crytek.
- In general, the only product that I understand from me is that I want to debug drawing graphics in a Chrome child process running from the parent, in which there is no graphics at all. It would seem that the launcher is the simplest thing, used in many games, but RenderDoc only came to the need to support it in the debugger.
So,
download RenderDoc , install. Run, see the main window. Open the Tools-> Options menu and specify the folder into which the temporary files (dumps) will be added.

Now we need to launch the application we want to debug under the RenderDoc debugger. To do this, on the tab "
Capture Executable " enter the path to Chrome, its working folder. Here are some interesting points. Graphics in Chrome is drawn in a separate child process, it can be determined by running Process Hacker and finding the one among all the running processes chrome.exe that has the
--type = gpu-process flag among the command line parameters.

We cannot start this process directly, so we have to start the main Chrome process, indicating in RenderDoc that we want to track calls to DirectX functions, including among the child processes (
Hook Into Children checkbox)
By default, Chrome child processes “live” in the sandbox — they have a low Integrity Level, which prevents them from interacting with the file system, other processes, and common OS resources. Thus, if we just run Chrome, then RenderDoc will not be able to interact with the process in which the graphics are drawn. To do this, there is a hack - Chrome needs to be run with a special flag
--no-sandbox , which disables the Chrome sandbox.
Since we are interested in everything that happens in the course of drawing graphics, we include more useful checkboxes. We can also immediately indicate which frame we want to capture (for this there is a
Queue Capture Of Frame # checkbox), or we can press the PrintScreen button in the application to create a dump for the current frame
As a result, the Capture Executable tab will look like this:

We press the Capture button, Chrome starts.

At the top of the window, we see some kind of debugging information that tells us at least a few things:
- Chrome actually uses DirectX11 to draw its own window (and the whole window: title, toolbars, and page content)
- RenderDoc successfully "hooked" to Chrome
Now you can open something in Chrome and click PrintScreen. At the top of the Chrome window will appear on the created screenshot. Everything, Chrome can be closed, and in the folder that you specified in the settings there should be a file with the rdc extension. This is our dump. Open it through "
File-> Open Log " and see something like this:

In the upper part of the window there is a “timeline” - a time line on which the stages of drawing this frame are marked. There may be up to several dozen (if you don’t see them, click on the plus sign in the upper left corner of the Timeline window). The same steps are marked in the "
Event Browser " on the left side of the window. By clicking on the timeline or on the events in the "Event Browser" we can go to different points in the course of drawing the frame.
The root node of the event tree is called "
Frame #N " and shows which frame it is from when DirectX was initialized in the application. Next comes the meta-node "
Frame start " indicating the start of drawing this frame (no real calls to DirectX methods are attached to it). Next we see three nodes: "
Color Pass # 1 (1 Targets) ", "
Draw (4) " and "
Present () ". From this we can understand that all the drawing of the chrome window content goes through several stages:
- First, everything is drawn into some kind of intermediate texture (stage " Color Pass # 1 (1 Targets) ")
- Then the call to the " Draw (4) " method transfers the contents of this texture to the Swap Chain Backbuffer
- Finally, the Present method causes the backbuffer to be displayed on the screen.
As you can see, the drawing stage in the intermediate texture in the tree can be expanded and we will see the moments of drawing individual elements of the Chrome window.

First, the texture is cleared (call
ClearRenderTargetView ). Then there are many stages called "
DrawIndexed (6) ". 6 is the number of points bounding the area drawn at this stage. The fact that there are 6 of them suggests the idea that these are 2 triangles that make up a rectangle. Let's select one of the stages "
DrawIndexed (6) " (not the first, but not the last) and consider it more closely.
Let's start with the tab "
Pipeline State "

As you may know, the concept of "
Pipeline " is used in DirectX11 - it is a set of several sequential operations designed to form the final frame. The pipeline starts with the
Input Assembler stage - here we provide all the necessary input data for vertex, index and constant buffers, which may later be needed to calculate what and where to draw. Next are the stages of processing input data by different types of shaders and the last phase,
Output Merger , in which the graphics are assembled and output to where they should be output.
In the
Pipeline State window, we can click on any stage of the pipeline and see:
- What came to the input stage (buffer, shader, texture), general information about this object
- Clicking on the green arrow to the right of the input parameter, we can open a window with more complete information. For a buffer, this is its full content, for a texture, its picture, for a shader, its compiled bytecode.
- For the Input Assembler stage, we can also click on the large " Mesh " button and see the coordinates of the points forming the region drawn at this stage. Here again, you can make sure that we draw exactly a rectangle.
Turning to the texture window, we can see the textures used when drawing this frame:

In the "
PS Resources " toolbar, we see the texture (s) that will be drawn at this stage, and in the "
OM Targets " toolbar, the texture where the drawing will take place. Staying in the texture window, you can click on the drawing stages from the top or from the left - and we will see that Chrome draws its window with textures of 256x256 pixels. It starts from the bottom of the window, then draws the side edges and then the window title with toolbars. After that, Chrome proceeds to draw the content of the tab (again, slices of 256x256 pixels). Then objects lying “on top of” the content are drawn - video, flash banners, tooltips. In the last stages, the scrollbar and its slider are drawn. Now the texture is ready for drawing into the back buffer.
What else interesting can RenderDoc
Show API called DirectX-methods for each stage of drawing
Incredibly useful thing. And given that not only the names of the methods are visible, but also their parameters - this is generally beauty.
Show the stick (from which one or another DirectX method was called in the code)However, for this you need to slip the program pdb-file (which you only have if you yourself are the author of the code being debugged). Very useful for debugging their programs, completely useless for analyzing others.
Debuff shadersFor vertex shaders, debugging begins in the
Mesh Output window with a right-click on the vertex of interest.

For pixels - in the texture window, where on the pixel of interest you need to click the right mouse button and click in the "
Pixel Content " toolbar the "
Debug this Pixel " button

Here is such a useful tool RenderDoc.
Good luck debugging graphics.