• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2018-2020 NVIDIA Corporation
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5include::{generated}/meta/{refprefix}VK_NV_shading_rate_image.adoc[]
6
7=== Other Extension Metadata
8
9*Last Modified Date*::
10    2019-07-18
11*Interactions and External Dependencies*::
12  - This extension provides API support for
13    {GLSLregistry}/nv/GLSL_NV_shading_rate_image.txt[`GL_NV_shading_rate_image`]
14*Contributors*::
15  - Pat Brown, NVIDIA
16  - Carsten Rohde, NVIDIA
17  - Jeff Bolz, NVIDIA
18  - Daniel Koch, NVIDIA
19  - Mathias Schott, NVIDIA
20  - Matthew Netsch, Qualcomm Technologies, Inc.
21
22=== Description
23
24This extension allows applications to use a variable shading rate when
25processing fragments of rasterized primitives.
26By default, Vulkan will spawn one fragment shader for each pixel covered by
27a primitive.
28In this extension, applications can bind a _shading rate image_ that can be
29used to vary the number of fragment shader invocations across the
30framebuffer.
31Some portions of the screen may be configured to spawn up to 16 fragment
32shaders for each pixel, while other portions may use a single fragment
33shader invocation for a 4x4 block of pixels.
34This can be useful for use cases like eye tracking, where the portion of the
35framebuffer that the user is looking at directly can be processed at high
36frequency, while distant corners of the image can be processed at lower
37frequency.
38Each texel in the shading rate image represents a fixed-size rectangle in
39the framebuffer, covering 16x16 pixels in the initial implementation of this
40extension.
41When rasterizing a primitive covering one of these rectangles, the Vulkan
42implementation reads a texel in the bound shading rate image and looks up
43the fetched value in a palette to determine a base shading rate.
44
45In addition to the API support controlling rasterization, this extension
46also adds Vulkan support for the
47{spirv}/NV/SPV_NV_shading_rate.html[`SPV_NV_shading_rate`] extension to
48SPIR-V.
49That extension provides two fragment shader variable decorations that allow
50fragment shaders to determine the shading rate used for processing the
51fragment:
52
53  * code:FragmentSizeNV, which indicates the width and height of the set of
54    pixels processed by the fragment shader.
55  * code:InvocationsPerPixel, which indicates the maximum number of fragment
56    shader invocations that could be spawned for the pixel(s) covered by the
57    fragment.
58
59When using SPIR-V in conjunction with the OpenGL Shading Language (GLSL),
60the fragment shader capabilities are provided by the
61`GL_NV_shading_rate_image` language extension and correspond to the built-in
62variables code:gl_FragmentSizeNV and code:gl_InvocationsPerPixelNV,
63respectively.
64
65include::{generated}/interfaces/VK_NV_shading_rate_image.adoc[]
66
67=== Issues
68
69(1) When using shading rates specifying "`coarse`" fragments covering
70    multiple pixels, we will generate a combined coverage mask that combines
71    the coverage masks of all pixels covered by the fragment.
72    By default, these masks are combined in an implementation-dependent
73    order.
74    Should we provide a mechanism allowing applications to query or specify
75    an exact order?
76
77*RESOLVED*: Yes, this feature is useful for cases where most of the fragment
78shader can be evaluated once for an entire coarse fragment, but where some
79per-pixel computations are also required.
80For example, a per-pixel alpha test may want to kill all the samples for
81some pixels in a coarse fragment.
82This sort of test can be implemented using an output sample mask, but such a
83shader would need to know which bit in the mask corresponds to each sample
84in the coarse fragment.
85We are including a mechanism to allow applications to specify the orders of
86coverage samples for each shading rate and sample count, either as static
87pipeline state or dynamically via a command buffer.
88This portion of the extension has its own feature bit.
89
90We will not be providing a query to determine the implementation-dependent
91default ordering.
92The thinking here is that if an application cares enough about the coarse
93fragment sample ordering to perform such a query, it could instead just set
94its own order, also using custom per-pixel sample locations if required.
95
96(2) For the pipeline stage
97ename:VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV, should we specify a
98precise location in the pipeline the shading rate image is accessed (after
99geometry shading, but before the early fragment tests) or leave it
100under-specified in case there are other implementations that access the
101image in a different pipeline location?
102
103*RESOLVED* We are specifying the pipeline stage to be between the final
104<<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader
105stage>> (ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT) and before the first
106stage used for fragment processing
107(ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT), which seems to be the
108natural place to access the shading rate image.
109
110(3) How do centroid-sampled variables work with fragments larger than one
111pixel?
112
113*RESOLVED* For single-pixel fragments, fragment shader inputs decorated with
114code:Centroid are sampled at an implementation-dependent location in the
115intersection of the area of the primitive being rasterized and the area of
116the pixel that corresponds to the fragment.
117With multi-pixel fragments, we follow a similar pattern, using the
118intersection of the primitive and the *set* of pixels corresponding to the
119fragment.
120
121One important thing to keep in mind when using such "`coarse`" shading rates
122is that fragment attributes are sampled at the center of the fragment by
123default, regardless of the set of pixels/samples covered by the fragment.
124For fragments with a size of 4x4 pixels, this center location will be more
125than two pixels (1.5 * sqrt(2)) away from the center of the pixels at the
126corners of the fragment.
127When rendering a primitive that covers only a small part of a coarse
128fragment, sampling a color outside the primitive can produce overly bright
129or dark color values if the color values have a large gradient.
130To deal with this, an application can use centroid sampling on attributes
131where "`extrapolation`" artifacts can lead to overly bright or dark pixels.
132Note that this same problem also exists for multisampling with single-pixel
133fragments, but is less severe because it only affects certain samples of a
134pixel and such bright/dark samples may be averaged with other samples that
135do not have a similar problem.
136
137=== Version History
138
139  * Revision 3, 2019-07-18 (Mathias Schott)
140  ** Fully list extension interfaces in this appendix.
141  * Revision 2, 2018-09-13 (Pat Brown)
142  ** Miscellaneous edits preparing the specification for publication.
143  * Revision 1, 2018-08-08 (Pat Brown)
144  ** Internal revisions
145