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