Expose hardware support for Rasterizer Ordered Views (ROVs), which allow Pixel Shader code to mark UAV bindings with a declaration that alters the requirements of Section 4.2 Fixed Order of Pipeline Results for UAVs, guaranteeing order of UAV accesses for any pair of overlapping Pixel Shader invocations.
Term | Definition |
---|---|
UAV | Unordered Access View |
ROV | Rasterizer Ordered View |
Rasterizer Ordered Views (ROVs) allow Pixel Shader code to mark UAV bindings with a declaration that alters the requirements of the D3D11 spec section “Fixed Order of Pipeline Results for UAVs”, guaranteeing order of UAV accesses for any pair of overlapping Pixel Shader invocations. “Overlapping” means that the invocations are generated by the same Draw* API call and share the same pixel coordinate when in pixel-frequency execution mode, and same pixel and sample coordinate in sample-frequency mode. The order in which overlapping Pixel Shader invocations’ ROV accesses are executed must be the order in which the geometry was submitted (see the D3D11 spec section “Fixed Order of Pipeline Results”). This means that, for overlapping Pixel Shader invocations, ROV writes performed by a Pixel Shader invocation must be available to read by a subsequent invocation and must not affect reads by a previous invocation, and ROV reads performed by a Pixel Shader invocation must reflect writes by a previous invocation and must not reflect writes by a subsequent invocation. This is important for UAVs because they are explicitly omitted from the output-invariance guarantees provided by “Fixed order Of Pipeline Results”.
ROVs is an optional feature. It will only be supported on WDDM 2.0 or newer UMDs that support FL11.1+. Its runtime implementation fits well into our existing code:
WDDM 2.0+, D3D FL11.1+ is required to support this feature.
Support for this new format feature will fit into the existing format support structures, data, and logic.
ID3D11Device CheckFeatureSupport API is used to determine support. This will be implemented much like the design of Buffer Map Default, so the implementation of that and CheckFeatureSupport() for D3D11_FEATURE_D3D11_OPTIONS1 can be referenced.
This feature support information should be grouped with the other features being added to the runtimes (e.g. ASTC Profile) into something like D3D11_FEATURE_D3D11_OPTIONS2.
Only FL11.1+ WDDM 2.0+ drivers will have the ability to support ROVs, and must support a shader cap query for it. Drivers that don’t meet the FL and WDDM requirement will default to no support.
The relevant new D3D11_FEATURE:
D3D11_FEATURE_D3D11_OPTIONS2 = ( D3D11_FEATURE_MARKER_SUPPORT + 1)
Associated Structure and Capability member:
typedef struct D3D11_FEATURE_DATA_D3D11_OPTIONS2 {
// other caps...
BOOL ROVSupported;
} D3D11_FEATURE_DATA_D3D11_OPTIONS2;
This BOOL will only be set when the driver specifies support via the D3D11DDI_SHADER_CAPS, much like shader double support is set currently. To be more specific, ROVSupported defaults to FALSE, and is only set to TRUE when:
None.
CreatePixelShader() validation will mimic SHADER_FEATURE_DOUBLES/m_bDoublePrecisionFloatShaderOpsSupported validation. A new Shader Feature flag must be added to the SShaderFeatureInfo FeatureFlags in order for runtime to properly validate. If that new Shader Feature flag is set for a given Pixel Shader, then the driver must have set support for D3D11DDICAPS_SHADER_ROVS.
CreatePixelShader() validation will be very similar D3D11’s.
A new cap for this feature will be added to the existing shader caps query for the GetCaps DDI:
D3D12DDICAPS_SHADER_ROVS
Setting this flag means that the driver/hardware supports ROVs.
CheckFeatureSupport will be updated to handle a query for D3D11_FEATURE_D3D11_OPTIONS2.
D3D11 and D3D12 HLSL support is required.
The Raster Ordered Views are declared with the following new HLSL Objects, and are only allowed in the Pixel Shader:
RasterizerOrderedBuffer
RasterizerOrderedByteAddressBuffer
RasterizerOrderedStructuredBuffer
RasterizerOrderedTexture1D
RasterizerOrderedTexture1DArray
RasterizerOrderedTexture2D
RasterizerOrderedTexture2DArray
RasterizerOrderedTexture3D
Rasterizer Ordered Views are represented in Shader IL using a new “rasterizer ordered” type declaration flag, ‘_rov’ (similar to the _glc, i.e. globally coherent, flag):
dcl_uav_typed_buffer_rov
dcl_uav_raw_rov
dcl_uav_structured_rov
dcl_uav_typed_texture1d_rov
dcl_uav_typed_texture1darray_rov
dcl_uav_typed_texture2d_rov
dcl_uav_typed_texture2darray_rov
dcl_uav_typed_texture3d_rov
All operations on any register(s) declared as “rasterizer ordered” must honor the ordering semantics specified in this document.
Functional unit tests will be designed to verify all runtime validation and expected DDI calling behavior. These will need to fully cover the feature surface area because there will be no D3DTest-provided functional testing. D3D11 API should be used and run on D3D11on12 to test D3D12 functionality, but D3D12 tests for failures will need to be written as well. These tests will be integrated into CIS automatically based on their directory location.
The D3D Proxy Driver will be used as the underlying driver for unit testing. It will only mock support this feature since the driver conformance testing will cover the actual shader execution behavior. We only need to verify caps reporting and create pixel shader validation.
Ref will not be updated to support this feature.
New HCK test will be implemented to validate driver and hardware conformance.
The functional unit tests will be written in TAEF. Because negatives must be tested, we need D3D11 and D3D12 API tests. We must also ensure D3D11on12 works for positives. D3DDriver will be used for D3D11 DDI call verification, DDIFilter and WARP will be used for D3D12 and D3D11on12.
Functional unit tests will cover CheckFeatureSupport, and CreatePixelShader validation:
The TAEF unit test to unblock IHV development will be designed to verify that two overlapping Pixel Shader invocations are correctly ordered when RasterizerOrderedBuffer is used. This test must run on D3D11 and D3D11on12 to cover D3D11 and D3D12.
To accomplish this, the following is required:
1) Pixel Shader that uses RasterizerOrderedBuffer 2) UAV bound to Pixel Shader RasterizerOrderedBuffer with a UINT value of 1 3) Draw two overlapping primitives that both cover the center of a 1x1 RT: T1 and T2. 4) When Pixel Shader is drawing T1 it must stall and then multiply the value in the RasterizerOrderedBuffer by 2. a. To stall the Pixel Shader execution, a (UAV) input value should be read and used as the termination condition of a for-loop that will decrement a shader literal down to 2, to be used as the value in the multiplication. This complexity is required to avoid optimizing the stall out of the shader assembly. 5) When Pixel Shader is drawing T2 it must subtract 1 from the value in the RasterizerOrderedBuffer. 6) Verify the value in the UAV is 1 (not 0, which would be the case if the order was wrong)
In this way, the math should be execute as:
1) 1*2 = 2
2) 2-1 = 1
If the order is not honored, the math executes as:
1) 1-1 = 0
2) 0 * 2 = 0
The IHV-Bring-up test will be extended to operate on all RO-types (i.e. RasterizerOrderedBuffer, RasterizerOrderedTexture1D, RasterizerOrderedTexture2D, etc.).
All HCK Tests will cover D3D12 via D3D11on12.