This document attempts to describe the differences between pipeline states in the current generation of graphics APIs. It also touches some adjacent features like stencil reference values and blend factors. The investigation uses materials from https://github.com/jdashg/vulkan-portability/blob/master/pipeline-state.md.
InformationThe concept of a pipeline state is similar between Vulkan/D3D12/Metal. A graphics PSO (short for Pipeline State Object) is an opaque object encapsulating the following information:
Graphics and compute pipelines are represented with separate types and constructed from different states. We'll focus on the graphics one, considering the compute to use a subset of graphics states.
Differences between APIs are mostly laid out within the specification of render targets and the range of supported states within particular stages.
VulkanvkCreateGraphicsPipelineStates
creates multiple pipeline states at once, each from a separate VkGraphicsPipelineCreateInfo struct. Users can provide a pipeline cache object in order to re-use internal parts (opaque to the user) between pipelines.
Instead of specifying the formats of render targets, the pipeline state is created for a specific sub-pass of a render pass. A pipeline can then be used with any compatible render pass, according to the rules.
Vulkan allows certain states to be either baked into PSO or set independently during command encoding:
typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT = 0, VK_DYNAMIC_STATE_SCISSOR = 1, VK_DYNAMIC_STATE_LINE_WIDTH = 2, VK_DYNAMIC_STATE_DEPTH_BIAS = 3, VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, } VkDynamicState;
Vulkan multi-sampling state allows not only forcing sample shading on/off but also specifying the ratio of uniquely shaded samples. This is gated by sampleRateShading
feature of the device. Similarly, independent blending is supported behind the independentBlend
feature.
VkVertexInputRate
does not seem to support instance rate values higher than 1, although it seems trivial to extend the range of accepted values for this type.
CreateGraphicsPipelineState
creates a graphics PSO described by the D3D12_GRAPHICS_PIPELINE_STATE_DESC structure.
Color and depth render targets are described by their format.
The user can pass a cache blob of another PSO in order to re-use the internal compiled parts.
For multi-sampling, D3D12 exposes the DXGI_SAMPLE_DESC::Quality
value, the semantics of which is rather opaque but the exposed capabilities are similar to Vulkan's minSampleShading
. Comparing to Vulkan, various parts of multi-sampling state are spread over the rasterization state, blending, sample descriptors, and plain values in the PSO descriptor.
Limitations compared to Vulkan:
VK_CULL_MODE_FRONT_AND_BACK
VK_POLYGON_MODE_POINT
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN
Extra features compared to Vulkan:
InstanceDataStepRate
allows an advance of vertex attribute per N instancesA graphics PSO is created via makeRenderPipelineState
from MTLRenderPipelineDescriptor.
There is no notion of pipeline cache as well as pipeline layout (aka root signature).
States that are surprisingly out of PSO:
Limitations compared to Vulkan:
VK_CULL_MODE_FRONT_AND_BACK
VK_POLYGON_MODE_POINT
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN
Extra features compared to Vulkan:
MTLVertexBufferLayoutDescriptor::stepRate
allows to configure the rate of an instanced attributeIn both Vulkan and D3D12 there is a separate object describing resource binding layout and push/root constants, called VkPipelineLayout
and ID3D12RootSignature
correspondingly. It makes sense to have it in GPUWeb as well (related to #19).
Vulkan dynamic states are useful in order to match the PSO-baked states with D3D12 and Metal. Thus, we consider all of the dynamic states to be used at all times by the Vulkan backend of GPUWeb.
In terms of pipeline states, it seems reasonable to use the intersection of capabilities between the APIs, which happens to match D3D12 except for:
I find it rather unfortunate if we had to drop support for the sample mask, thus perhaps we could patch the shader code in order to apply the mask in the shader specifically for Metal and support it uniformly.
The question of whether render target formats are needed in the PSO depends on #23. If render sub-passes are accepted, I believe following Vulkan model (of providing the pass and sub-pass index) is straightforward.
TODO:
vitvakatu, jing-pei and star-emsiglreith and JohnColanduoni
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4