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;
}