可变速率底纹 (VRS)
VRS 的动机
由于性能限制,图形呈现器并不总是能够向输出图像的每个部分提供相同的质量级别。 可变速率底纹(或粗糙像素底纹)是一种机制,允许你以不同渲染图像的速率分配渲染性能/功率。
在某些情况下,底纹速率可以降低,几乎不会降低可感知的输出质量:导致性能改进基本上是免费的。
没有 VRS - 使用超级采样的多样本抗锯齿
如果没有可变速率底纹,控制着色速率的唯一手段是使用基于样本的执行的多样本抗锯齿(MSAA)(也称为超级采样)。
MSAA 是一种减少几何别名的机制,与不使用 MSAA 相比,提高了图像的呈现质量。 MSAA 样本计数(可以是 1x、2x、4x、8x 或 16x)控制每个呈现目标像素分配的样本数。 分配目标后,必须提前知道 MSAA 示例计数,并且以后无法更改。
超采样会导致每个样本调用像素着色器一次,其质量更高,但性能成本也高于每像素执行。
应用程序可以通过选择基于像素的执行或具有超采样的 MSAA 来控制其底纹速率。 这两个选项不提供非常精细的控制。 此外,与图像的其余部分相比,你可能希望特定类对象的底纹率较低。 此类对象可能包括 HUD 元素后面的对象,或透明度、模糊(场深度、运动等)或 VR 光学导致的光学失真。 但这是不可能的,因为整个图像上固定了底纹质量和成本。
使用可变速率底纹 (VRS)
可变速率底纹(VRS)模型通过添加粗着色的概念,将超采样与 MSAA 扩展到相反的“粗糙像素”方向。 这是可以在比像素更粗糙的频率上执行底纹的地方。 换句话说,可以将一组像素着色为单个单元,然后结果将广播到组中的所有样本。
粗糙底纹 API 允许应用程序指定属于着色组的像素数,或 粗像素。 分配呈现器目标后,可以改变粗糙像素大小。 因此,屏幕的不同部分或不同的绘制通道可以有不同的底纹速率。
下表描述了支持粗略像素大小的平台的 MSAA 级别:
- 对于标记为 Y的单元格,将启用该组合。
- 对于标记为“Cap ”的单元格,将根据上限(AdditionalShadingRatesSupported)有条件地启用该组合。
- 对于空白单元格,不支持该组合。
- 对于半色调着色的单元格,该组合不受支持、和 它涉及跟踪每个像素着色器调用的 16 个以上的样本。 对于跟踪超过 16 个样本,与其他情况相比,还有额外的硬件对齐屏障支持。
粗像素大小
功能层
VRS 实现有两个层,以及可以查询的两个功能。 每个层在表后面进行了更详细的描述。
第 1 层
- 底纹速率只能按绘制指定;没有比这更精细的粒度。
- 着色速率统一应用于独立于它位于呈现目标内的位置绘制的内容。
第 2 层
- 可以按绘制指定底纹速率,如第 1 层所示。 还可以通过按绘制依据的组合来指定它,以及:
- 每个挑衅顶点的语义,以及
- 屏幕空间图像。
- 三个源中的底纹速率使用一组组合器进行组合。
- 屏幕空间图像磁贴大小为 16x16 或更小。
- 保证完全交付应用程序请求的底纹速率(用于临时和其他重建筛选器的精度)。
- 支持SV_ShadingRate PS 输入。
- 使用一个视区且不写入
SV_ViewportArrayIndex
时,按挑衅顶点(也称为每基元)底纹速率有效。 - 如果 SupportsPerVertexShadingRateWithMultipleViewports 功能设置为
true
,则每个挑衅顶点速率可以与多个视区一起使用。 此外,在这种情况下,在写入SV_ViewportArrayIndex
时可以使用该速率。
功能列表
-
AdditionalShadingRatesSupported
- 布尔类型。
- 指示单采样呈现是否支持 2x4、4x2 和 4x4 粗像素大小;以及 2x MSAA 是否支持粗糙像素大小 2x4。
-
SupportsPerVertexShadingRateWithMultipleViewports
- 布尔类型。
- 指示是否可以将多个视区与每个顶点(也称为每基元)底纹速率一起使用。
指定底纹速率
对于应用程序的灵活性,提供了多种机制来控制底纹速率。 根据硬件功能层,可以使用不同的机制。
命令列表
这是设置底纹速率的最简单机制。 它在所有层上都可用。
应用程序可以使用 ID3D12GraphicsCommandList5::RSSetShadingRate 方法指定粗糙像素大小。 该 API 采用单个枚举参数。 该 API 提供对呈现质量级别的全面控制-能够按绘制设置底纹速率。
此状态的值通过 D3D12_SHADING_RATE 枚举表示。
粗糙像素大小支持
所有层都支持底纹速率 1x1、1x2、2x1 和 2x2。
AdditionalShadingRatesSupported,用于指示设备上是否支持 2x4、4x2 和 4x4 的功能。
屏幕空间图像(基于图像)
在第 2 层及更高层上,可以使用屏幕空间图像指定像素底纹速率。
屏幕空间图像允许应用程序创建“细节级别(LOD)掩码”图像,该图像指示不同质量的区域,例如将覆盖运动模糊、深度字段模糊、透明对象或 HUD UI 元素的区域。 图像的分辨率在宏块中;它不在呈现目标的分辨率中。 换句话说,着色速率数据以 8x8 或 16x16 像素磁贴的粒度指定,如 VRS 磁贴大小所示。
磁贴大小
应用程序可以查询 API,以检索其设备支持的 VRS 磁贴大小。
平铺是正方形的,大小是指图块的宽度或高度(以纹素表示)。
如果硬件不支持第 2 层可变速率底纹,则磁贴大小的功能查询将返回 0。
如果硬件 确实 支持第 2 层可变速率底纹,则磁贴大小就是这些值之一。
- 8
- 16
- 32
屏幕空间图像大小
对于大小为 {rtWidth, rtHeight} 的呈现目标,使用名为 VRSTileSize的给定磁贴大小,将覆盖它的屏幕空间图像就是这些维度。
{ ceil((float)rtWidth / VRSTileSize), ceil((float)rtHeight / VRSTileSize) }
屏幕空间图像的左上角(0,0)锁定在呈现目标左上角(0,0)。
若要查找与呈现目标中的特定位置相对应的磁贴的 (x,y) 坐标,请按图块大小划分 (x, y) 的窗口空间坐标,忽略小数位数。
如果屏幕空间图像大于给定的呈现目标,则不会使用右侧和/或底部的额外部分。
如果屏幕空间图像对于给定的呈现目标来说太小,则从图像中读取的任何尝试均超出其实际范围,则默认底纹速率为 1x1。 这是因为屏幕空间图像的左上角(0,0)锁定在呈现目标左上角(0,0)和“超出呈现目标范围读取”意味着读取 x 和 y 的值太大。
格式、布局、资源属性
此图面的格式是单通道 8 位图面(DXGI_FORMAT_R8_UINT)。
资源是维度 TEXTURE2D。
无法对它进行数组化或误导。 它必须显式具有一个 mip 级别。
它具有样本计数 1 和样本质量 0。
它具有纹理布局 未知。 它隐式不能是行主布局,因为不允许跨适配器。
填充屏幕空间图像数据的预期方式是任一
- 使用计算着色器写入数据;屏幕空间图像绑定为 UAV,或
- 将数据复制到屏幕空间图像。
创建屏幕空间图像时,允许这些标志。
- 没有
- ALLOW_UNORDERED_ACCESS
- DENY_SHADER_RESOURCE
不允许这些标志。
- ALLOW_RENDER_TARGET
- ALLOW_DEPTH_STENCIL
- ALLOW_CROSS_ADAPTER
- ALLOW_SIMULTANEOUS_ACCESS
- VIDEO_DECODE_REFERENCE_ONLY
资源的堆类型不能为 UPLOAD 或 READBACK。
资源无法SIMULTANEOUS_ACCESS。 不允许将资源交叉适配器。
数据
屏幕空间图像的每个字节对应于 D3D12_SHADING_RATE 枚举的值。
资源状态
当用作屏幕空间图像时,资源需要转换为只读状态。 为此定义了只读状态 D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE。
图像资源已从该状态转换,以再次变为可写状态。
设置映像
用于指定着色器速率的屏幕空间图像在命令列表中设置。
已设置为底纹速率源的资源无法从任何着色器阶段读取或写入。
可以设置用于指定着色器速率的 null
屏幕空间图像。 这具有 1x1 作为屏幕空间图像的贡献效果。 屏幕空间图像最初可以被视为设置为 null
。
提升和衰减
屏幕空间图像资源对提升或衰减没有任何特殊影响。
按基元属性
每个基元属性增加了将底纹速率术语指定为引发顶点的属性的功能。 此属性是平面着色的,也就是说,它传播到当前三角形或线条基元中的所有像素。 与其他着色速率说明符相比,使用每基元属性可以实现图像质量的精细控制。
每个基元属性是一个名为 SV_ShadingRate
的可设置语义。
SV_ShadingRate
作为 HLSL 着色器模型 6.4的一部分存在。
如果 VS 或 GS 设置 SV_ShadingRate
,但未启用 VRS,则语义设置不起作用。 如果未为每个基元指定 SV_ShadingRate
值,则假定底纹速率值为 1x1 作为每基元的贡献。
组合底纹速率因子
使用此关系图按顺序应用着色速率的各种源。
每对 A 和 B 都使用组合器进行组合。
* 按顶点属性指定着色器速率时。
- 如果使用几何着色器,可以通过该着色器指定着色速率。
- 如果未使用几何着色器,则着色速率由引发顶点指定。
组合器列表
支持以下组合器。 使用组合器(C)和两个输入(A 和 B)。
- 直通。 C.xy = A.xy。
- 替代。 C.xy = B.xy。
- 高质量。 C.xy = min(A.xy、B.xy)。
- 质量较低的。 C.xy = max(A.xy、B.xy)。
- 将成本 B 应用于 A。C.xy = min(maxRate,A.xy + B.xy)。
其中,maxRate
是设备上粗像素的最大允许尺寸。 这将是
- 如果 AdditionalShadingRatesSupported 为
false
,则 D3D12_AXIS_SHADING_RATE_2X(即值 1)。 - 如果 AdditionalShadingRatesSupported 为
true
,则 D3D12_AXIS_SHADING_RATE_4X(即值 2)。
通过 ID3D12GraphicsCommandList5::RSSetShadingRate在命令列表中设置组合器选择可变速率底纹。
如果未设置组合器,则它们将保留在默认值中,即 PASSTHROUGH。
如果组合器源是支持表中不允许的 D3D12_AXIS_SHADING_RATE,则输入将被清理为 支持的底纹速率。
如果组合器输出与平台上支持的底纹速率不对应,则结果将清理为 支持的底纹速率。
默认状态和状态清除
所有底纹速率源,即
- 管道状态指定的速率(在命令列表中指定)
- 屏幕空间图像指定的速率,以及
- 每个基元属性
默认值为 D3D12_SHADING_RATE_1X1。 默认组合器为 {PASSTHROUGH, PASSTHROUGH}。
如果未指定屏幕空间图像,则会从该源推断出 1x1 的底纹速率。
如果未指定每基元属性,则从该源推断 1x1 的底纹速率。
ID3D12CommandList::ClearState 将管道状态指定的速率重置为默认值,并将屏幕空间图像的选择设置为默认的“无屏幕空间图像”。
使用 SV_ShadingRate 查询着色速率
了解硬件在任何给定像素着色器调用中选择的底纹率非常有用。 这可以在 PS 代码中启用各种优化。 仅限 PS 的系统变量 SV_ShadingRate
提供有关底纹速率的信息。
类型
此语义的类型为 uint。
数据解释
数据被解释为 D3D12_SHADING_RATE 枚举的值。
如果未使用 VRS
如果未使用粗糙像素底纹,则 SV_ShadingRate
将读回值 1x1,表示精细像素。
基于样本的执行下的行为
如果像素着色器输入 SV_ShadingRate
并且还使用基于样本的执行(例如,输入 SV_SampleIndex
或使用示例内插关键字),则像素着色器将失败。
有关延迟底纹的备注
延迟底纹应用程序的照明通道可能需要知道屏幕哪个区域的底纹速率。 这样,照明通道调度就可以以更粗糙的速度启动。 如果将
SV_ShadingRate
变量写出到 gbuffer,则可以使用它来实现此目的。
深度和模具
使用粗糙像素底纹时,始终在完整的样本分辨率下计算和发出深度和模具和覆盖范围。
使用请求的底纹速率
对于所有层,如果请求着色速率,并且设备与 MSAA 级别组合支持,则表示硬件提供的底纹速率。
请求的底纹速率表示作为组合器的输出计算的底纹速率(请参阅本主题中的 组合着色速率因子 部分)。
在采样计数小于或等于 4 的呈现作中,支持的底纹速率为 1x1、1x2、2x1 或 2x2。 如果 AdditionalShadingRatesSupported 功能 true
,则某些样本计数也支持 2x4、4x2 和 4x4 的底纹速率(请参阅本主题中 “带可变速率着色(VRS) 部分的表)。
屏幕空间衍生产品
像素到相邻像素渐变的计算受粗糙像素底纹的影响。 例如,使用 2x2 粗糙像素时,与不使用粗糙像素相比,渐变的大小将是两倍。 应用程序可能需要调整着色器来补偿此情况,具体取决于所需的功能。
由于 mip 是基于屏幕空间派生选择的,因此粗像素着色的使用会影响 mip 选择。 与不使用粗糙像素相比,使用粗糙像素着色会导致选择不太详细的 mips。
属性内插
对像素着色器的输入可能会根据其源顶点进行内插。 由于可变速率底纹会影响每个像素着色器调用所写入的目标区域,因此它与属性内插交互。 这三种类型的内插是中心、质心和样本。
中心
粗像素的中心内插位置是全粗糙像素区域的几何中心。
SV_Position
始终在粗糙像素区域的中心内插。
质心
当粗像素底纹与 MSAA 一起使用时,对于每个细像素,仍将写入为目标 MSAA 级别分配的样本总数。 因此,质心内插位置将考虑粗像素内细像素的所有样本。 也就是说,质心内插位置定义为第一个覆盖样本,以增加样本索引的顺序。 样本的有效覆盖范围是使用光栅器状态 SampleMask 的相应位进行 AND 处理。
注意
在第 1 层上使用粗糙像素底纹时,SampleMask 始终是完整掩码。 如果 SampleMask 配置为不是完整掩码,则会在第 1 层上禁用粗像素底纹。
基于示例的执行
基于样本的执行,或 超级采样(使用样本内插功能)可用于粗糙像素着色,并导致每个样本调用像素着色器。 对于样本计数 N 的目标,每个细像素调用像素着色器 N 次。
EvaluateAttributeSnapped
拉取模型内部函数与第 1 层上的粗糙像素底纹不兼容。 如果尝试在第 1 层上使用带有粗糙像素底纹的拉取模型内部函数,则会自动禁用粗糙像素底纹。
允许将内部 EvaluateAttributeSnapped
与第 2 层上的粗糙像素底纹一起使用。 它的语法与它一直相同。
numeric EvaluateAttributeSnapped(
in attrib numeric value,
in int2 offset);
对于上下文,EvaluateAttributeSnapped
具有两个字段的偏移参数。 在没有粗糙像素底纹的情况下使用时,使用完整三十二位中的低阶四位。 这四位表示范围 [-8, 7]。 此范围跨像素内的 16x16 网格。 范围使像素的上边缘和左边缘包括在内,并且底部和右边缘不是。 偏移量(-8,-8)位于左上角,偏移量(7,7)由右下角。 偏移量(0,0)是像素的中心。
与粗糙像素底纹一起使用时,EvaluateAttributeSnapped
的偏移参数能够指定更广泛的位置。 偏移参数为每个细像素选择 16x16 网格,并且有多个细像素。 使用的可表达范围和随后使用的位数取决于粗像素大小。 包括粗糙像素的上边缘和左边缘,底部和右边缘不包括在内。
下表描述了每个粗糙像素大小的 EvaluateAttributeSnapped
偏移参数的解释。
EvaluateAttributeSnapped 的偏移范围
粗糙像素大小 | 可索引范围 | 可表示的范围大小 | 所需的位数 {x, y} | 可用位的二进制掩码 |
---|---|---|---|---|
1x1 (罚款) | {[-8, 7], [-8, 7]} | {16, 16} | {4, 4} | {000000000000xxxx, 000000000000xxxx} |
1x2 | {[-8, 7], [-16, 15]} | {16, 32} | {4, 5} | {000000000000xxxx, 00000000000xxxxx} |
2x1 | {[-16, 15], [-8, 7]} | {32, 16} | {5, 4} | {00000000000xxxxx, 000000000000xxxx} |
2x2 | {[-16, 15], [-16, 15]} | {32, 32} | {5, 5} | {00000000000xxxxx, 00000000000xxxxx} |
2x4 | {[-16, 15], [-32, 31]} | {32, 64} | {5, 6} | {00000000000xxxxx, 0000000000xxxxxx} |
4x2 | {[-32, 31], [-16, 15]} | {64, 32} | {6, 5} | {0000000000xxxxxx, 0000000000xxxxx} |
4x4 | {[-32, 31], [-32, 31]} | {64, 64} | {6, 6} | {0000000000xxxxxx, 000000000xxxxxx} |
下表是从固定点转换为十进制和小数表示形式的指南。 二进制掩码中的第一个可用位是符号位,二进制掩码的其余部分包括数字部分。
传入 EvaluateAttributeSnapped
的四位值的数字方案不特定于可变速率底纹。 这是为了完整性在这里重申的。
对于四位值。
二进制值 | 十进制 | 分数 |
---|---|---|
1000 | -0.5f | -8 / 16 |
1001 | -0.4375f | -7 / 16 |
1010 | -0.375f | -6 / 16 |
1011 | -0.3125f | -5 / 16 |
1100 | -0.25f | -4 / 16 |
1101 | -0.1875f | -3 / 16 |
1110 | -0.125f | -2 / 16 |
1111 | -0.0625f | -1 /16 |
0000 | 0.0f | 0 / 16 |
0001 | -0.0625f | 1 / 16 |
0010 | -0.125f | 2 / 16 |
0011 | -0.1875f | 3 / 16 |
0100 | -0.25f | 4 / 16 |
0101 | -0.3125f | 5 / 16 |
0110 | -0.375f | 6 / 16 |
0111 | -0.4375f | 7 / 16 |
对于五位值。
二进制值 | 十进制 | 分数 |
---|---|---|
10000 | -1 | -16 / 16 |
10001 | -0.9375 | -15 / 16 |
10010 | -0.875 | -14 / 16 |
10011 | -0.8125 | -13 / 16 |
10100 | -0.75 | -12 / 16 |
10101 | -0.6875 | -11 / 16 |
10110 | -0.625 | -10 / 16 |
10111 | -0.5625 | -9 / 16 |
11000 | -0.5 | -8 / 16 |
11001 | -0.4375 | -7 / 16 |
11010 | -0.375 | -6 / 16 |
11011 | -0.3125 | -5 / 16 |
11100 | -0.25 | -4 / 16 |
11101 | -0.1875 | -3 / 16 |
11110 | -0.125 | -2 / 16 |
11111 | -0.0625 | -1 / 16 |
00000 | 0 | 0 / 16 |
00001 | 0.0625 | 1 / 16 |
00010 | 0.125 | 2 / 16 |
00011 | 0.1875 | 3 / 16 |
00100 | 0.25 | 4 / 16 |
00101 | 0.3125 | 5 / 16 |
00110 | 0.375 | 6 / 16 |
00111 | 0.4375 | 7 / 16 |
01000 | 0.5 | 8 / 16 |
01001 | 0.5625 | 9 / 16 |
01010 | 0.625 | 10 / 16 |
01011 | 0.6875 | 11 / 16 |
01100 | 0.75 | 12 / 16 |
01101 | 0.8125 | 13 / 16 |
01110 | 0.875 | 14 / 16 |
01111 | 0.9375 | 15 / 16 |
对于六位值。
二进制值 | 十进制 | 分数 |
---|---|---|
100000 | -2 | -32 / 16 |
100001 | -1.9375 | -31 / 16 |
100010 | -1.875 | -30 / 16 |
100011 | -1.8125 | -29 / 16 |
100100 | -1.75 | -28 / 16 |
100101 | -1.6875 | -27 / 16 |
100110 | -1.625 | -26 / 16 |
100111 | -1.5625 | -25 / 16 |
101000 | -1.5 | -24 / 16 |
101001 | -1.4375 | -23 / 16 |
101010 | -1.375 | -22 / 16 |
101011 | -1.3125 | -21 / 16 |
101100 | -1.25 | -20 / 16 |
101101 | -1.1875 | -19 / 16 |
101110 | -1.125 | -18 / 16 |
101111 | -1.0625 | -17 / 16 |
110000 | -1 | -16 / 16 |
110001 | -0.9375 | -15 / 16 |
110010 | -0.875 | -14 / 16 |
110011 | -0.8125 | -13 / 16 |
110100 | -0.75 | -12 / 16 |
110101 | -0.6875 | -11 / 16 |
110110 | -0.625 | -10 / 16 |
110111 | -0.5625 | -9 / 16 |
111000 | -0.5 | -8 / 16 |
111001 | -0.4375 | -7 / 16 |
111010 | -0.375 | -6 / 16 |
111011 | -0.3125 | -5 / 16 |
111100 | -0.25 | -4 / 16 |
111101 | -0.1875 | -3 / 16 |
111110 | -0.125 | -2 / 16 |
111111 | -0.0625 | -1 / 16 |
000000 | 0 | 0 / 16 |
000001 | 0.0625 | 1 / 16 |
000010 | 0.125 | 2 / 16 |
000011 | 0.1875 | 3 / 16 |
000100 | 0.25 | 4 / 16 |
000101 | 0.3125 | 5 / 16 |
000110 | 0.375 | 6 / 16 |
000111 | 0.4375 | 7 / 16 |
001000 | 0.5 | 8 / 16 |
001001 | 0.5625 | 9 / 16 |
001010 | 0.625 | 10 / 16 |
001011 | 0.6875 | 11 / 16 |
001100 | 0.75 | 12 / 16 |
001101 | 0.8125 | 13 / 16 |
001110 | 0.875 | 14 / 16 |
001111 | 0.9375 | 15 / 16 |
010000 | 1 | 16 / 16 |
010001 | 1.0625 | 17 / 16 |
010010 | 1.125 | 18 / 16 |
010011 | 1.1875 | 19 / 16 |
010100 | 1.25 | 20 / 16 |
010101 | 1.3125 | 21 / 16 |
010110 | 1.375 | 22 / 16 |
010111 | 1.4375 | 23 / 16 |
011000 | 1.5 | 24 / 16 |
011001 | 1.5625 | 25 / 16 |
011010 | 1.625 | 26 / 16 |
011011 | 1.6875 | 27 / 16 |
011100 | 1.75 | 28 / 16 |
011101 | 1.8125 | 29 / 16 |
011110 | 1.875 | 30 / 16 |
011111 | 1.9375 | 31 / 16 |
与使用精细像素的方式相同,EvaluateAttributeSnapped
的可评估位置网格在使用粗糙像素底纹时居中位于粗糙像素中心。
SetSamplePositions
当 API ID3D12GraphicsCommandList1::SetSamplePositions 与粗糙底纹一起使用时,API 会设置精细像素的示例位置。
SV_Coverage
如果 SV_Coverage
在第 1 层上声明为着色器输入或输出,则会禁用粗像素底纹。
可以在第 2 层上将 SV_Coverage
语义与粗糙像素底纹一起使用,并反映正在写入 MSAA 目标的示例。
使用粗糙像素底纹(允许多个源像素构成磁贴)时,覆盖掩码表示来自该磁贴的所有样本。
给定粗糙像素底纹与 MSAA 的兼容性,需要指定的覆盖位数可能会有所不同。 例如,对于使用 D3D12_SHADING_RATE_2x2的 4x MSAA 资源,每个粗糙像素写入到四个精细像素,每个细像素都有四个样本。 这意味着每个粗糙像素总共写入 4 * 4 = 16 个样本。
所需的覆盖率位数
下表指示每个粗像素大小和 MSAA 级别的组合需要多少个覆盖位。
如表中所示,使用通过 Direct3D 12 公开的可变速率底纹功能,一次无法使用粗糙像素写入 16 个以上的样本。 此限制是由于 Direct3D 12 关于允许哪些 MSAA 级别具有哪些粗糙像素大小的约束(请参阅本主题中 “带可变速率底纹(VRS) 部分的表)。
覆盖掩码中的位排序和格式
覆盖掩码的位遵循定义完善的顺序。 掩码由从左到右的像素、从上到下(列主要)顺序的覆盖率组成。 覆盖率位是覆盖语义的低序位,并密集打包在一起。
下表显示了粗糙像素大小和 MSAA 级别的受支持组合的覆盖掩码格式。
下表描绘了 2x MSAA 像素,其中每个像素都有两个索引 0 和 1 样本。
像素上样本标签的定位是为了说明目的,不一定传达该像素上样本的空间 {X, Y} 位置;特别是考虑到可以编程方式更改示例位置。 示例由其基于 0 的索引引用。
下表显示了 4x MSAA 像素,其中每个像素有四个索引样本 0、1、2 和 3。
丢弃
当 HLSL 语义 discard
与粗糙像素着色一起使用时,将丢弃粗像素。
与目标无关的光栅化 (TIR)
使用粗糙像素底纹时不支持 TIR。
光栅顺序视图 (ROV)
ROV 互锁指定为以精细像素粒度运行。 如果按样本执行底纹,则互锁以样本粒度运行。
保守光栅化
可以将保守光栅化与可变速率底纹结合使用。 当保守光栅化与粗糙像素底纹一起使用时,粗糙像素内的精细像素通过获得全覆盖来保守地光栅化。
覆盖
使用保守光栅化时,覆盖语义包含覆盖的精细像素的完整掩码,对于未覆盖的精细像素,则为 0。
束
可以在捆绑包上调用可变速率着色 API。
呈现通道
可以在 呈现器传递中调用可变速率着色 API。
调用 VRS API
下一部分介绍通过 Direct3D 12 访问应用程序可变速率着色的方式。
功能查询
若要查询适配器的可变速率着色功能,请使用 D3D12_FEATURE::D 3D12_FEATURE_D3D12_OPTIONS6调用 ID3D12Device::CheckFeatureSupport,并提供 D3D12_FEATURE_DATA_D3D12_OPTIONS6 结构 供函数填充。 D3D12_FEATURE_DATA_D3D12_OPTIONS6 结构包含多个成员,包括枚举类型 D3D12_VARIABLE_SHADING_RATE_TIER(D3D12_FEATURE_DATA_D3D12_OPTIONS6::VariableShadingRateTier)的成员,以及一个成员指示是否支持后台处理(D3D12_FEATURE_DATA_D3D12_OPTIONS6::BackgroundProcessingSupported)。
例如,若要查询第 1 层功能,可以执行此作。
D3D12_FEATURE_DATA_D3D12_OPTIONS6 options;
return
SUCCEEDED(m_device->CheckFeatureSupport(
D3D12_FEATURE_D3D12_OPTIONS6,
&options,
sizeof(options))) &&
options.ShadingRateTier == D3D12_VARIABLE_SHADING_RATE_TIER_1;
底纹速率
D3D12_SHADING_RATE 枚举 中的值进行组织,以便将底纹率轻松分解为两个轴,其中每个轴的值根据 D3D12_AXIS_SHADING_RATE 枚举在对数空间中紧凑表示。
可以创作一个宏,将两个轴底纹速率组合成如下所示的底纹速率。
#define D3D12_MAKE_COARSE_SHADING_RATE(x,y) ((x) << 2 | (y))
D3D12_MAKE_COARSE_SHADING_RATE(
D3D12_AXIS_SHADING_RATE_2X,
D3D12_AXIS_SHADING_RATE_1X)
该平台还提供在 d3d12.h
中定义的这些宏。
#define D3D12_GET_COARSE_SHADING_RATE_X_AXIS(x) ((x) >> 2 )
#define D3D12_GET_COARSE_SHADING_RATE_Y_AXIS(y) ((y) & 3 )
这些可用于剖析和理解 SV_ShaderRate
。
注意
此数据解释旨在描述屏幕空间图像,该图像可由着色器作。 上述各节对此进行了进一步讨论。 但是,没有理由不对在任何地方使用的粗糙像素大小进行一致的定义,包括在设置命令级底纹速率时。
设置命令级底纹速率和组合器
着色速率(可选)通过 ID3D12GraphicsCommandList5::RSSetShadingRate 方法指定组合器。 为基本底纹速率传递 D3D12_SHADING_RATE 值,以及 D3D12_SHADING_RATE_COMBINER 值的可选数组。
准备屏幕空间图像
指定可用着色速率图像的只读资源状态定义为 D3D12_RESOURCE_STATES::D 3D12_RESOURCE_STATE_SHADING_RATE_SOURCE。
设置屏幕空间图像
通过 ID3D12GraphicsCommandList5::RSSetShadingRateImage 方法指定屏幕空间图像。
m_commandList->RSSetShadingRateImage(screenSpaceImage);
查询磁贴大小
可以从 D3D12_FEATURE_DATA_D3D12_OPTIONS6::ShadingRateImageTileSize 成员查询磁贴大小。 请参阅上面的 功能查询。
检索一个维度,因为水平和垂直维度始终相同。 如果系统的功能 D3D12_SHADING_RATE_TIER_NOT_SUPPORTED,则返回的磁贴大小为 0。