Try G-SYNC Compatible with Direct3D12

Previously, we were able to freely change the refresh rate in full-screen mode, This time, we would like to check the operation of variable refresh rate.

I have two displays that I use, one of which is this display that I recently bought.

Dell AW2724DM 27-inch Alienware gaming monitor

  • NVIDIA G-SYNC Compatible
  • AMD FreeSync Premium Pro
  • VESA AdaptiveSync

It states that the product is compatible with

The other is a 28" display from iiyama. This one is older and does not support variable refresh rate.

First of all, what is the refresh rate of a display? If it says 60Hz, it means it displays images 60 times per second. How the image is displayed is by scanning image data one line at a time, starting from the top left corner, to light up the pixels of the LCD or OLED. Displaying that one image is repeated at an interval of once every1/60seconds.

So, what is a variable refresh rate? It is the ability to shift this1/60second interval, for example, from1/30seconds to1/60seconds at variable intervals. The variable refresh rate is a function that displays the screen at variable intervals from to seconds.

What it is for is, for example, in the case of a 60fps game, if the processing of one frame is heavy, the processing may not finish in1/60seconds (called “processing dropout”). In the case of a double buffer with a 60Hz refresh rate and VSync wait enabled, a 1ms processing overtime will cause the frame rate to drop by half to 30fps by having to wait until the next VSync timing. The frame rate will drop by half to 30 fps.

Variable refresh rate can reduce the frame rate drop by shifting the timing of screen display during such a processing delay. For example, if the screen is only 1 ms over the previous time, the screen display will only change from60fps(16.6ms)to56fps(17.6ms).

Although this feature has no effect on games that do not suffer from processing slowdowns, it is very attractive from the point of view of game programmers who are plagued by processing slowdowns.

So, here’s how to check it in Direct3D12.

It seems that the variable refresh rate function is working without any particular settings, so I would like to check it by making an application that displays only one triangle, which I have been running recently, crash.

First, we will add a for loop to the triangle drawing to make the process slow down.

        for (int i = 0; i < mTestLoop ; ++i)
        {
            commandList->DrawInstanced(3, 1, 0, 0);
        }

This can be changed in the imgui UI to change the number of loops.

        static int loop_index = -1;
        const char* loop_data[] = {"1", "100", "1000", "2000", "3000", "4000", "5000", "6000", "7000", "8000", "9000","10000", "50000"};
        if (ImGui::Combo("LoopMode", &loop_index, loop_data, _countof(loop_data)))
        {
            if (loop_index > 0) {
                mTestLoop = atoi(loop_data[loop_index]);
            }
        }

Now you can run the application with the following conditions

  • Double buffer, VSync wait enabled
  • Full screen

We checked the fps while changing the number of loops and increasing the processing load. The results are as follows

  • Displays supporting variable refresh rate
    • Change in fps : 60fps →50fps →40fps → 30fps
  • Displays that do not support variable refresh rate
    • Change in fps : 60fps →30fps →30fps → 30fps

We have confirmed that the variable refresh rate is working.

Finally, to note how variable refresh rate works, if there is no change in the image to be displayed, the scanning process to display the screen is waiting to start. For example, at 60 Hz, if the image is being refreshed, scanning would start at1/60second intervals, If the screen has not been updated, it waits until1/30seconds later for the image to be updated. When the image is updated, scanning starts immediately after that. Even if there is no image update, scanning starts after1/30seconds. By doing so, the image can be displayed at a variable refresh rate of30-60Hz.