1// Copyright 2022-2024 The Khronos Group Inc. 2// 3// SPDX-License-Identifier: CC-BY-4.0 4 5= VK_EXT_depth_bias_control 6:toc: left 7:refpage: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/ 8:sectnums: 9 10This document details API design ideas for the `VK_EXT_depth_bias_control` extension, 11which provides functionality for finer control over the behaviour and representation 12of depth bias when rendering. 13 14== Problem Statement 15 16Some applications and API layering efforts, e.g., D3D9, need a way for depth bias to be represented in exact 17terms as if it were `depth = depth + depth_bias` in the shader, rather than being format-dependent. 18 19In some older APIs, applications can specify extreme depth bias values, such as 20`0.5f`, as a direct offset to be applied. Translation layers can attempt to 21simulate this behavior by multiplying the application-provided direct bias by 22`1/r` and passing the result as `depthBiasConstantFactor`. However, the current 23specification does not set a fixed value for `r` in fixed-point attachments, and 24its value can also vary per-primitive when using floating-point attachments. 25This leads to incorrect depth bias values being applied, and the error is larger 26the larger the fixed depth bias is. 27 28API layering efforts regularly need to emulate certain depth formats such as `VK_FORMAT_D24_UNORM_S8_UINT` using higher-precision formats 29such as `VK_FORMAT_D32_SFLOAT_S8_UINT`. This creates an additional problem as the minimum resolvable difference for `SFLOAT` formats is defined differently compared to `UNORM` formats. 30 31This means we need a way to prevent implementations from applying a 2x scaling 32factor to the value of `r` when using fixed-point attachments, and a way of 33treating the depth bias' minimum resolvable difference in linear terms (like 34`UNORM` formats) for `SFLOAT` formats. 35 36== Solution Space 37 38 . Solve from the application side by hardcoding `r * n` values for each driver 39 40 * This is problematic because it means an application must be aware of and hardcode implementation-specific 41 to work around the problem. 42 43 . Solve from the application side with `r * n` resolution 44 45 * The application could attempt to resolve the scaled `r * n` values by drawing a quad with a known depth bias value and reading back the depth. This is problematic because it does not solve the issue regarding the minimum resolvable difference being scaled differently for `SFLOAT` formats. 46 47 . Solve from the application side with shader-side biasing using `gl_FragDepth` 48 49 * Another option from the application side is to use a push constant and perform depth-bias manually in the shader. This is problematic as it can lead to reduced performance as this avoids early-z optimizations. 50 51 . Add a method of specifying the depth bias representation 52 53 * A Vulkan extension could be made to provide functionality to specify the representation and scaling of depth bias that is wanted. 54 55== Proposal 56 57Add a new function, `vkCmdSetDepthBias2EXT` that uses an extendable `VkDepthBiasInfoEXT`. 58 59Add a new structure, `VkDepthBiasRepresentationInfoEXT`, that can be added to the `pNext` chain of a pipeline's `VkPipelineRasterizationStateCreateInfo` state or `VkDepthBiasInfoEXT` in a `vkCmdSetDepthBias2EXT` call that allows setting the scaling and representation of depth bias for a pipeline. 60 61It will support specifying if the representation should be format-dependent, the behaviour of `UNORM` formats, and whether or not the depth bias should be scaled to ensure a minimum resolvable difference. 62 63```c 64struct VkDepthBiasInfoEXT { 65 VkStructureType sType; // VK_STRUCTURE_TYPE_DEPTH_BIAS_INFO_EXT 66 const void* pNext; 67 // Same as the params to vkCmdSetDepthBias. 68 float depthBiasConstantFactor; 69 float depthBiasClamp; 70 float depthBiasSlopeFactor; 71}; 72``` 73 74```c 75void vkCmdSetDepthBias2EXT( 76 VkCommandBuffer commandBuffer, 77 const VkDepthBiasInfoEXT* pInfo); 78``` 79 80```c 81enum VkDepthBiasRepresentationEXT { 82 // The default behaviour of Vulkan. 83 // Depth bias as a factor of `r`, format-dependent. 84 VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT = 0, 85 // Depth bias as a factor of constant `r` UNORM behaviour. 86 VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT = 1, 87 // Depth bias as a raw floating-point value, same effect as doing `gl_FragDepth = gl_FragCoord.z + d`. 88 VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT = 2, 89}; 90``` 91 92```c 93// Part of the pNext chain of a VkPipelineRasterizationStateCreateInfo. 94struct VkDepthBiasRepresentationInfoEXT { 95 VkStructureType sType; // VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT 96 const void* pNext; 97 VkDepthBiasRepresentationEXT depthBiasRepresentation; // The depth bias representation for the pipeline 98 VkBool32 depthBiasExact; // Whether or not the depth bias should be scaled to ensure a minimum resolvable difference 99}; 100``` 101 102== Issues 103 104None. 105