/VulkanRenderingAdvanced

Advanced rendering with Vulkan API

Primary LanguageCBSD 2-Clause "Simplified" LicenseBSD-2-Clause

VulkanRenderingAdvanced

Advanced rendering with Vulkan API


This project demonstrates how to use a vertex shader, a geometry shader and a fragment shader to render some graphics with Vulkan API. And it also shows the usage of timestamp query and occlusion query.

This project is built on Windows 11 with Visual Studio 2022 Community Edition and Vulkan SDK 1.3. If you want to generate the SPV files, just run glsl_builder.bat.

The official Vulkan SDK for Windows is here: https://vulkan.lunarg.com/sdk/home#windows

It is also convenient to be ported to other platforms, such as Android and other Linux operating systems. If GCC or Clang is used, just use -std=gnu2x option.


GTX 1650 Fragment Shading Rate Combiner Operation


Combining shading rate factors (width x height) with VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR

A/B 1x1 1x2 1x4 2x1 2x2 2x4 4x1 4x2 4x4
1x1 1x1 1x2 1x2 2x1 2x2 2x4 2x1 4x2 4x4
1x2 1x2 1x2 1x2 2x2 2x4 2x4 4x2 4x4 4x4
1x4 1x2 1x2 1x2 2x4 2x4 2x4 4x4 4x4 4x4
2x1 2x1 2x2 2x4 2x1 4x2 4x4 2x1 4x2 4x4
2x2 2x2 2x4 2x4 4x2 4x4 4x4 4x2 4x4 4x4
2x4 2x4 2x4 2x4 4x4 4x4 4x4 4x4 4x4 4x4
4x1 2x1 4x2 4x4 2x1 4x2 4x4 2x1 4x2 4x4
4x2 4x2 4x4 4x4 4x2 4x4 4x4 4x2 4x4 4x4
4x4 4x4 4x4 4x4 4x4 4x4 4x4 4x4 4x4 4x4

Algorithm

// [3:2] -- log2(FSR width)
// [1:0] -- log2(FSR height)
enum VK_SPV_SHADING_RATE
{
    fsrPixelSize1x1 = 0,
    fsrPixelSize1x2 = 1,
    fsrPixelSize1x4 = 2,
    fsrPixelSize2x1 = 4,
    fsrPixelSize2x2 = 5,
    fsrPixelSize2x4 = 6,
    fsrPixelSize4x1 = 8,
    fsrPixelSize4x2 = 9,
    fsrPixelSize4x4 = 10
};

VkExtent2D MULcombiner(VkExtent2D a, VkExtent2D b)
{
    VkExtent2D c;
    c.width = a.width * b.width;
    c.height = a.height * b.height;

    if (c.width > 4) {
        c.width = 4;
    }
    if (c.height > 4) {
        c.height = 4;
    }

    if (maxFragmentShadingRateAttachmentTexelSizeAspectRatio == 2)
    {
        // In this case, 4x1 will be clamped to 2x1, and 1x4 will be clamped to 1x2
        if (c.width == 4 && c.height == 1) {
            c.width = 2;
        }
        if (c.width == 1 && c.height == 4) {
            c.height = 2;
        }
    }

    return c;
}