• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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