From 03b1084a6212042eb747317f8c6fe720f278e2d7 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Mon, 14 Dec 2020 18:30:53 -0500 Subject: [PATCH 1/7] Refactor GPURenderPipelineDescriptor API --- samples/hello-cube.html | 1 - spec/index.bs | 232 ++++++++++++++++++++++------------------ 2 files changed, 129 insertions(+), 104 deletions(-) diff --git a/samples/hello-cube.html b/samples/hello-cube.html index 10e5974d1c..b3e0814357 100644 --- a/samples/hello-cube.html +++ b/samples/hello-cube.html @@ -189,7 +189,6 @@ vertexStage: vertexStageDescriptor, fragmentStage: fragmentStageDescriptor, - primitiveTopology: "triangle-list", colorStates: [colorState], depthStencilState: depthStateDescriptor, vertexInput: vertexInputDescriptor diff --git a/spec/index.bs b/spec/index.bs index a4d8bcd885..05e7aaa844 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -3691,7 +3691,7 @@ Render [=pipeline=] outputs are: Stages of a render [=pipeline=]: 1. Vertex fetch, controlled by {{GPUVertexStateDescriptor}} 2. Vertex shader - 3. Primitive assembly, controlled by {{GPUPrimitiveTopology}} + 3. Primitive assembly - [[#primitive-assembly]] 4. Rasterization, controlled by {{GPURasterizationStateDescriptor}} 5. Fragment shader 6. Stencil test and operation, controlled by {{GPUDepthStencilStateDescriptor}} @@ -3726,18 +3726,13 @@ GPURenderPipeline includes GPUPipelineBase; @@ -3745,8 +3740,6 @@ dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { the vertex shader entry point of the [=pipeline=] - {{GPURenderPipelineDescriptor/fragmentStage}} describes the fragment shader entry point of the [=pipeline=]. If it's `null`, the [[#no-color-output]] mode is enabled. -- {{GPURenderPipelineDescriptor/primitiveTopology}} configures - the primitive assembly stage of the [=pipeline=]. - {{GPURenderPipelineDescriptor/rasterizationState}} configures the rasterization stage of the [=pipeline=]. - {{GPURenderPipelineDescriptor/colorStates}} describes @@ -3755,11 +3748,6 @@ dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { the optional depth-stencil attachment that is written by the [=pipeline=]. - {{GPURenderPipelineDescriptor/vertexState}} configures the vertex fetch stage of the [=pipeline=]. -- {{GPURenderPipelineDescriptor/sampleCount}} is - the number of MSAA samples that each attachment has to have. -- {{GPURenderPipelineDescriptor/sampleMask}} is - a binary mask of MSAA samples, according to [[#sample-masking]]. -- {{GPURenderPipelineDescriptor/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode. Issue(https://github.com/gpuweb/gpuweb/issues/936): Refactor the shape of the render pipeline descriptor to clearly enumerate the @@ -3773,44 +3761,6 @@ and the {{GPURenderPipelineDescriptor/colorStates}} is expected to be empty. The [=pipeline=] still performs rasterization and produces depth values based on the vertex position output. The depth testing and stencil operations can still be used. -### Alpha to Coverage ### {#alpha-to-coverage} - -In alpha-to-coverage mode, an additional alpha-to-coverage mask -of MSAA samples is generated based on the |alpha| component of the -fragment shader output value of the {{GPURenderPipelineDescriptor/colorStates}}[0]. - -The algorithm of producing the extra mask is platform-dependent and can vary for different pixels. -It guarantees that: - - if |alpha| is 0.0 or less, the result is 0x0 - - if |alpha| is 1.0 or greater, the result is 0xFFFFFFFF - - if |alpha| is greater than some other |alpha1|, - then the produced sample mask has at least as many bits set to 1 as the mask for |alpha1| - -### Sample Masking ### {#sample-masking} - -The final sample mask for a pixel is computed as: -[=rasterization mask=] & {{GPURenderPipelineDescriptor/sampleMask}} & [=shader-output mask=]. - -Only the lower {{GPURenderPipelineDescriptor/sampleCount}} bits of the mask are considered. - -If the least-significant bit at position |N| of the [=final sample mask=] has value of "0", -the sample color outputs (corresponding to sample |N|) to all attachments of the fragment shader are discarded. -Also, no depth test or stencil operations are executed on the relevant samples of the depth-stencil attachment. - -Note: the color output for sample |N| is produced by the fragment shader execution -with SV_SampleIndex == |N| for the current pixel. -If the fragment shader doesn't use this semantics, it's only executed once per pixel. - -The rasterization mask is produced by the rasterization stage, -based on the shape of the rasterized polygon. The samples incuded in the shape get the relevant -bits 1 in the mask. - -The shader-output mask takes the output value of SV_Coverage semantics in the fragment shader. -If the semantics is not [=statically used=] by the shader, and {{GPURenderPipelineDescriptor/alphaToCoverageEnabled}} -is enabled, the [=shader-output mask=] becomes the [=alpha-to-coverage mask=]. Otherwise, it defaults to 0xFFFFFFFF. - -Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. -
: createRenderPipeline(descriptor) :: @@ -3842,10 +3792,8 @@ Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. 1. Make |pipeline| [=invalid=]. 1. Set |pipeline|.{{GPURenderPipeline/[[descriptor]]}} to |descriptor|. - 1. If |descriptor|.{{GPURenderPipelineDescriptor/primitiveTopology}} is - {{GPUPrimitiveTopology/"line-strip"}} or {{GPUPrimitiveTopology/"triangle-strip"}}: - 1. Set |pipeline|.{{GPURenderPipeline/[[strip_index_format]]}} to - |descriptor|.{{GPURenderPipelineDescriptor/vertexState}}.{{GPUVertexStateDescriptor/indexFormat}}. + 1. Set |pipeline|.{{GPURenderPipeline/[[strip_index_format]]}} to + |descriptor|.{{GPURenderPipelineDescriptor/primitiveAssemblyState}}.{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}}. 1. Return |pipeline|. @@ -3940,7 +3888,19 @@ Issue: define what "compatible" means for render target formats. Issue: need a proper limit for the maximum number of color targets. -### Primitive Topology ### {#primitive-topology} +### Primitive Assembly ### {#primitive-assembly} + + + +- {{GPUPrimitiveAssemblyStateDescriptor/topology}} defines what kind of + primitives are constructed by the [=pipeline=]. +- {{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} defines the supported + index format for strip topologies. + +
+ validating GPUPrimitiveAssemblyStateDescriptor(|descriptor|) + Return `true` if all of the following conditions are met: + - If |descriptor|.{{GPUPrimitiveAssemblyStateDescriptor/topology}} is: +
+ : {{GPUPrimitiveTopology/"line-strip"}} or + {{GPUPrimitiveTopology/"triangle-strip"}} + :: |descriptor|.{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} is not `undefined` + : Otherwise + :: |descriptor|.{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} is `undefined` +
+
+ +### Index Format ### {#index-format} + + +The index format determines both the data type of index values in a buffer and, when used with +strip primitive topologies ({{GPUPrimitiveTopology/"line-strip"}} or +{{GPUPrimitiveTopology/"triangle-strip"}}) also specifies the primitive restart value. The +primitive restart value indicates which index value indicates that a new primitive +should be started rather than continuing to construct the triangle strip with the prior indexed +vertices. + +{{GPUPrimitiveAssemblyStateDescriptor}}s that specify a strip primitive topology must not have the +{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} set to `undefined` +so that the [=primitive restart value=] that will be used is known at pipline creation time. + + + + + + + + + + + + + + + + + + +
Index formatPrimitive restart value
{{GPUIndexFormat/"uint16"}}0xFFFF
{{GPUIndexFormat/"uint32"}}0xFFFFFFFF
+ + ### Rasterization State ### {#rasterization-state} +- {{GPURasterizationStateDescriptor/sampleCount}} is + the number of MSAA samples that each attachment has to have. +- {{GPURasterizationStateDescriptor/sampleMask}} is + a binary mask of MSAA samples, according to [[#sample-masking]]. +- {{GPURasterizationStateDescriptor/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode. +
- validating GPURasterizationStateDescriptor(|descriptor|, |features|) - 1. If |descriptor|.{{GPURasterizationStateDescriptor/clampDepth}} is `true` and |features| - doesn't [=list/contain=] {{GPUFeatureName/"depth-clamping"}}, return `false`. - 1. Return `true`. + validating GPURasterizationStateDescriptor(|device|, |descriptor|) + Return `true` if all of the following conditions are met: + - |descriptor|.{{GPURasterizationStateDescriptor/clampDepth}} is `false`, + or |device|.{{device/[[features]]}} [=list/contain=] {{GPUFeatureName/"depth-clamping"}}. + - |descriptor|.{{GPURasterizationStateDescriptor/alphaToCoverageEnabled}} is `false`, + or |descriptor|.{{GPURasterizationStateDescriptor/sampleCount}} is greater than 1.
+#### Alpha to Coverage #### {#alpha-to-coverage} + +In alpha-to-coverage mode, which is enabled by {{GPURasterizationStateDescriptor/alphaToCoverageEnabled}}, +an additional alpha-to-coverage mask +of MSAA samples is generated based on the |alpha| component of the +fragment shader output value of the {{GPURenderPipelineDescriptor/colorStates}}[0]. + +The algorithm of producing the extra mask is platform-dependent and can vary for different pixels. +It guarantees that: + - if |alpha| is 0.0 or less, the result is 0x0 + - if |alpha| is 1.0 or greater, the result is 0xFFFFFFFF + - if |alpha| is greater than some other |alpha1|, + then the produced sample mask has at least as many bits set to 1 as the mask for |alpha1| + +#### Sample Masking #### {#sample-masking} + +The final sample mask for a pixel is computed as: +[=rasterization mask=] & {{GPURasterizationStateDescriptor/sampleMask}} & [=shader-output mask=]. + +Only the lower {{GPURasterizationStateDescriptor/sampleCount}} bits of the mask are considered. + +If the least-significant bit at position |N| of the [=final sample mask=] has value of "0", +the sample color outputs (corresponding to sample |N|) to all attachments of the fragment shader are discarded. +Also, no depth test or stencil operations are executed on the relevant samples of the depth-stencil attachment. + +Note: the color output for sample |N| is produced by the fragment shader execution +with SV_SampleIndex == |N| for the current pixel. +If the fragment shader doesn't use this semantics, it's only executed once per pixel. + +The rasterization mask is produced by the rasterization stage, +based on the shape of the rasterized polygon. The samples incuded in the shape get the relevant +bits 1 in the mask. + +The shader-output mask takes the output value of SV_Coverage semantics in the fragment shader. +If the semantics is not [=statically used=] by the shader, and {{GPURasterizationStateDescriptor/alphaToCoverageEnabled}} +is enabled, the [=shader-output mask=] becomes the [=alpha-to-coverage mask=]. Otherwise, it defaults to 0xFFFFFFFF. + +Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. + ### Color State ### {#color-state} - -The index format determines both the data type of index values in a buffer and, when used with -strip primitive topologies ({{GPUPrimitiveTopology/"line-strip"}} or -{{GPUPrimitiveTopology/"triangle-strip"}}) also specifies the primitive restart value. The -primitive restart value indicates which index value indicates that a new primitive -should be started rather than continuing to construct the triangle strip with the prior indexed -vertices. - -{{GPURenderPipelineDescriptor}}s that specify a strip primitive topology must not have the -{{GPUVertexStateDescriptor/indexFormat}} set to `undefined` so that the [=primitive restart value=] -that will be used is known at pipline creation time. - - - - - - - - - - - - - - - - - - -
Index formatPrimitive restart value
{{GPUIndexFormat/"uint16"}}0xFFFF
{{GPUIndexFormat/"uint32"}}0xFFFFFFFF
- #### Vertex Formats #### {#vertex-formats} The name of the format specifies the data type of the component, the number of @@ -4232,7 +4259,6 @@ enum GPUInputStepMode { From abdea22831d9e580e2d18dccfaa6fb010a068531 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 16 Dec 2020 11:42:12 -0500 Subject: [PATCH 2/7] Separate output merger state --- samples/hello-cube.html | 6 +- spec/index.bs | 145 +++++++++++++++++++++------------------- 2 files changed, 82 insertions(+), 69 deletions(-) diff --git a/samples/hello-cube.html b/samples/hello-cube.html index b3e0814357..5a9b5bc0bf 100644 --- a/samples/hello-cube.html +++ b/samples/hello-cube.html @@ -183,13 +183,17 @@ }, writeMask: GPUColorWriteBits.ALL }; + const outputMergerStateDescriptor = { + colorStates: [colorState] + }; const pipelineDescriptor = { layout: pipelineLayout, vertexStage: vertexStageDescriptor, fragmentStage: fragmentStageDescriptor, - colorStates: [colorState], + + outputMerger: outputMergerStateDescriptor, depthStencilState: depthStateDescriptor, vertexInput: vertexInputDescriptor }; diff --git a/spec/index.bs b/spec/index.bs index 05e7aaa844..a8dbb5db86 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -3692,11 +3692,11 @@ Stages of a render [=pipeline=]: 1. Vertex fetch, controlled by {{GPUVertexStateDescriptor}} 2. Vertex shader 3. Primitive assembly - [[#primitive-assembly]] - 4. Rasterization, controlled by {{GPURasterizationStateDescriptor}} + 4. Rasterization, controlled by {{GPURasterizerStateDescriptor}} 5. Fragment shader 6. Stencil test and operation, controlled by {{GPUDepthStencilStateDescriptor}} 7. Depth test and write, controlled by {{GPUDepthStencilStateDescriptor}} - 8. Output merging, controlled by {{GPUColorStateDescriptor}} + 8. Output merging - [[#output-merger]] Issue: we need a deeper description of these stages @@ -3729,10 +3729,10 @@ dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { GPUVertexStateDescriptor vertexState = {}; required GPUProgrammableStageDescriptor vertexStage; GPUPrimitiveAssemblyStateDescriptor primitiveAssemblyState = {}; - GPURasterizationStateDescriptor rasterizationState = {}; + GPURasterizerStateDescriptor rasterizerState = {}; GPUProgrammableStageDescriptor fragmentStage; GPUDepthStencilStateDescriptor depthStencilState; - required sequence colorStates; + required GPUOutputMergerStateDescriptor outputMergerState; }; @@ -3740,10 +3740,8 @@ dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { the vertex shader entry point of the [=pipeline=] - {{GPURenderPipelineDescriptor/fragmentStage}} describes the fragment shader entry point of the [=pipeline=]. If it's `null`, the [[#no-color-output]] mode is enabled. -- {{GPURenderPipelineDescriptor/rasterizationState}} configures +- {{GPURenderPipelineDescriptor/rasterizerState}} configures the rasterization stage of the [=pipeline=]. -- {{GPURenderPipelineDescriptor/colorStates}} describes - the color attachments that are written by the [=pipeline=]. - {{GPURenderPipelineDescriptor/depthStencilState}} describes the optional depth-stencil attachment that is written by the [=pipeline=]. - {{GPURenderPipelineDescriptor/vertexState}} configures @@ -3756,7 +3754,7 @@ Refactor the shape of the render pipeline descriptor to clearly enumerate the ### No Color Output ### {#no-color-output} In no-color-output mode, [=pipeline=] does not produce any color attachment outputs, -and the {{GPURenderPipelineDescriptor/colorStates}} is expected to be empty. +and the {{GPUOutputMergerStateDescriptor/colorStates}} is expected to be empty. The [=pipeline=] still performs rasterization and produces depth values based on the vertex position output. The depth testing and stencil operations can still be used. @@ -3842,42 +3840,25 @@ based on the vertex position output. The depth testing and stencil operations ca Return `true` if all of the following conditions are satisfied: + - [$validating GPUVertexStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/vertexState}}, + |descriptor|.{{GPURenderPipelineDescriptor/vertexStage}}) succeeds. - [$validating GPUProgrammableStageDescriptor$]({{GPUShaderStage/VERTEX}}, |descriptor|.{{GPURenderPipelineDescriptor/vertexStage}}, |descriptor|.{{GPUPipelineDescriptorBase/layout}}) succeeds. + - [$validating GPUPrimitiveAssemblyStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/primitiveAssemblyState}}, + |features|) succeeds. + - [$validating GPURasterizerStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/rasterizerState}}, + |features|) succeeds. + - If |descriptor|.{{GPURenderPipelineDescriptor/rasterizerState}}.{{GPURasterizerStateDescriptor/sampleCount}} is 1: + - |descriptor|.{{GPURenderPipelineDescriptor/outputMergerState}}.{{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} is `false`, - If |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}} is not `null`: - [$validating GPUProgrammableStageDescriptor$]({{GPUShaderStage/FRAGMENT}}, |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}, |descriptor|.{{GPUPipelineDescriptorBase/layout}}) succeeds. - - If |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}} is `null`: - - |descriptor|.{{GPURenderPipelineDescriptor/colorStates}} is empty. - - |descriptor|.{{GPURenderPipelineDescriptor/colorStates}}.length is less than - or equal to 4. - - For each |colorState| layout descriptor in the list - |descriptor|.{{GPURenderPipelineDescriptor/colorStates}}: - - [$validating GPUColorStateDescriptor$](|colorState|, - |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}) succeeds. - - [$validating GPURasterizationStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/rasterizationState}}, - |features|) succeeds. - if |descriptor|.{{GPURenderPipelineDescriptor/depthStencilState}} is not `null`: - [$validating GPUDepthStencilStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/depthStencilState}}) succeeds. - - [$validating GPUVertexStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/vertexState}}, - |descriptor|.{{GPURenderPipelineDescriptor/vertexStage}}) succeeds. - - If |descriptor|.{{GPURenderPipelineDescriptor/alphaToCoverageEnabled}} is `true`: - - |descriptor|.{{GPURenderPipelineDescriptor/sampleCount}} is greater than 1. - - If the output SV_Coverage semantics is [=statically used=] by - |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}: - - |descriptor|.{{GPURenderPipelineDescriptor/alphaToCoverageEnabled}} is `false`. - - If |descriptor|.{{GPURenderPipelineDescriptor/primitiveTopology}} is: -
- : {{GPUPrimitiveTopology/"line-strip"}} or - {{GPUPrimitiveTopology/"triangle-strip"}} - :: |descriptor|.{{GPURenderPipelineDescriptor/vertexState}}.{{GPUVertexStateDescriptor/indexFormat}} - is not `undefined` - : Otherwise - :: |descriptor|.{{GPURenderPipelineDescriptor/vertexState}}.{{GPUVertexStateDescriptor/indexFormat}} - is `undefined` -
+ - [$validating GPUOutputMergerStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/outputMergerState}}, + |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}) succeeds. Issue: validate interface matching rules between VS and FS. @@ -3968,7 +3949,7 @@ so that the [=primitive restart value=] that will be used is known at pipline cr ### Rasterization State ### {#rasterization-state} -- {{GPURasterizationStateDescriptor/sampleCount}} is +- {{GPURasterizerStateDescriptor/sampleCount}} is the number of MSAA samples that each attachment has to have. -- {{GPURasterizationStateDescriptor/sampleMask}} is +- {{GPURasterizerStateDescriptor/sampleMask}} is a binary mask of MSAA samples, according to [[#sample-masking]]. -- {{GPURasterizationStateDescriptor/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode.
- validating GPURasterizationStateDescriptor(|device|, |descriptor|) + validating GPURasterizerStateDescriptor(|device|, |descriptor|) Return `true` if all of the following conditions are met: - - |descriptor|.{{GPURasterizationStateDescriptor/clampDepth}} is `false`, + - |descriptor|.{{GPURasterizerStateDescriptor/clampDepth}} is `false`, or |device|.{{device/[[features]]}} [=list/contain=] {{GPUFeatureName/"depth-clamping"}}. - - |descriptor|.{{GPURasterizationStateDescriptor/alphaToCoverageEnabled}} is `false`, - or |descriptor|.{{GPURasterizationStateDescriptor/sampleCount}} is greater than 1.
-#### Alpha to Coverage #### {#alpha-to-coverage} - -In alpha-to-coverage mode, which is enabled by {{GPURasterizationStateDescriptor/alphaToCoverageEnabled}}, -an additional alpha-to-coverage mask -of MSAA samples is generated based on the |alpha| component of the -fragment shader output value of the {{GPURenderPipelineDescriptor/colorStates}}[0]. - -The algorithm of producing the extra mask is platform-dependent and can vary for different pixels. -It guarantees that: - - if |alpha| is 0.0 or less, the result is 0x0 - - if |alpha| is 1.0 or greater, the result is 0xFFFFFFFF - - if |alpha| is greater than some other |alpha1|, - then the produced sample mask has at least as many bits set to 1 as the mask for |alpha1| - #### Sample Masking #### {#sample-masking} The final sample mask for a pixel is computed as: -[=rasterization mask=] & {{GPURasterizationStateDescriptor/sampleMask}} & [=shader-output mask=]. +[=rasterization mask=] & {{GPURasterizerStateDescriptor/sampleMask}} & [=shader-output mask=]. -Only the lower {{GPURasterizationStateDescriptor/sampleCount}} bits of the mask are considered. +Only the lower {{GPURasterizerStateDescriptor/sampleCount}} bits of the mask are considered. If the least-significant bit at position |N| of the [=final sample mask=] has value of "0", the sample color outputs (corresponding to sample |N|) to all attachments of the fragment shader are discarded. @@ -4048,12 +4011,61 @@ based on the shape of the rasterized polygon. The samples incuded in the shape g bits 1 in the mask. The shader-output mask takes the output value of SV_Coverage semantics in the fragment shader. -If the semantics is not [=statically used=] by the shader, and {{GPURasterizationStateDescriptor/alphaToCoverageEnabled}} +If the semantics is not [=statically used=] by the shader, and {{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} is enabled, the [=shader-output mask=] becomes the [=alpha-to-coverage mask=]. Otherwise, it defaults to 0xFFFFFFFF. Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. -### Color State ### {#color-state} +### Output Merger State ### {#output-merger} + + + +- {{GPUOutputMergerStateDescriptor/colorStates}} describes + the color attachments that are written by the [=pipeline=]. +- {{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode. + +
+ validating GPUOutputMergerStateDescriptor(descriptor, fragmentStage) + **Arguments:** + - {{GPUColorStateDescriptor}} |descriptor| + - {{GPUProgrammableStageDescriptor}} |fragmentStage| + + Return `true`, if and only if, all of the following conditions are satisfied: + + - For each |colorState| at |index| in |descriptor|.{{GPUOutputMergerStateDescriptor/colorStates}}: + - [$validating GPUColorStateDescriptor$](|colorState|) succeeds. + - |fragmentStage| contains an output variable [=statically used=]: + - with `location` annotation equal to |index| + - with a type that is compatible with |colorState|.{{GPUColorStateDescriptor/format}}. + with {{GPUTextureUsage/RENDER_ATTACHMENT}} capability. + - If the output `SV_Coverage` semantics is [=statically used=] by |fragmentStage|: + - |descriptor|.{{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} is `false`. + - If |fragmentStage| is `null`: + - |descriptor|.{{GPUOutputMergerStateDescriptor/colorStates}} is empty. + - |descriptor|.{{GPUOutputMergerStateDescriptor/colorStates}}.length is less than + or equal to 4. +
+ +#### Alpha to Coverage #### {#alpha-to-coverage} + +In alpha-to-coverage mode, which is enabled by {{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}}, +an additional alpha-to-coverage mask +of MSAA samples is generated based on the |alpha| component of the +fragment shader output value of the {{GPUOutputMergerStateDescriptor/colorStates}}[0]. + +The algorithm of producing the extra mask is platform-dependent and can vary for different pixels. +It guarantees that: + - if |alpha| is 0.0 or less, the result is 0x0 + - if |alpha| is 1.0 or greater, the result is 0xFFFFFFFF + - if |alpha| is greater than some other |alpha1|, + then the produced sample mask has at least as many bits set to 1 as the mask for |alpha1| + +#### Color State #### {#color-state}
- validating GPUColorStateDescriptor(descriptor, fragmentStage) + validating GPUColorStateDescriptor(descriptor) **Arguments:** - {{GPUColorStateDescriptor}} |descriptor| - - {{GPUProgrammableStageDescriptor}} |fragmentStage| Return `true`, if and only if, all of the following conditions are satisfied: @@ -4134,8 +4145,6 @@ enum GPUBlendOperation { or the |descriptor|.{{GPUColorStateDescriptor/format}} is filterable according to the {#plain-color-formats} table. - |descriptor|.{{GPUColorStateDescriptor/writeMask}} is less than 16. - - |fragmentStage| contains an output variable with a type that is compatible with - |descriptor|.{{GPUColorStateDescriptor/format}}.
### Depth/Stencil State ### {#depth-stencil-state} @@ -7253,9 +7262,9 @@ The following dictionary values are supported if and only if the {{GPUFeatureNam [=feature=] is enabled, otherwise they must be set to their default values:
- : {{GPURasterizationStateDescriptor}} + : {{GPURasterizerStateDescriptor}} :: - * {{GPURasterizationStateDescriptor/clampDepth}} + * {{GPURasterizerStateDescriptor/clampDepth}}
## depth24unorm-stencil8 ## {#depth24unorm-stencil8} From 09fa9d063527515b3b32b9d8ef91b0307beb9831 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 16 Dec 2020 14:35:22 -0500 Subject: [PATCH 3/7] Rename all the non-root descriptor structs --- spec/index.bs | 194 +++++++++++++++++++++++++------------------------- 1 file changed, 97 insertions(+), 97 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index a8dbb5db86..87e8bc14b5 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -1049,14 +1049,14 @@ a better limit is not specified. maxVertexBuffers {{GPUSize32}} Higher 8 - The maximum number of {{GPUVertexStateDescriptor/vertexBuffers}} + The maximum number of {{GPUVertexInputState/vertexBuffers}} when creating a {{GPURenderPipeline}}. maxVertexAttributes {{GPUSize32}} Higher 16 The maximum number of {{GPUVertexBufferLayoutDescriptor/attributes}} - in total across {{GPUVertexStateDescriptor/vertexBuffers}} + in total across {{GPUVertexInputState/vertexBuffers}} when creating a {{GPURenderPipeline}}. maxVertexBufferArrayStride @@ -3359,7 +3359,7 @@ has a default layout created and used instead. 1. Set |groupDesc|.{{GPUBindGroupLayoutDescriptor/entries}} to an empty sequence. - 1. For each {{GPUProgrammableStageDescriptor}} |stageDesc| in the descriptor used to create the pipeline: + 1. For each {{GPUProgrammableStage}} |stageDesc| in the descriptor used to create the pipeline: 1. Let |stageInfo| be the "reflection information" for |stageDesc|. @@ -3367,8 +3367,8 @@ has a default layout created and used instead. spec and get information what the interface is for a {{GPUShaderModule}} for a specific entrypoint. - 1. Let |shaderStage| be the {{GPUShaderStageFlags}} for |stageDesc|.{{GPUProgrammableStageDescriptor/entryPoint}} - in |stageDesc|.{{GPUProgrammableStageDescriptor/module}}. + 1. Let |shaderStage| be the {{GPUShaderStageFlags}} for |stageDesc|.{{GPUProgrammableStage/entryPoint}} + in |stageDesc|.{{GPUProgrammableStage/module}}. 1. For each resource |resource| in |stageInfo|'s resource interface: 1. Let |group| be |resource|'s "group" decoration. @@ -3467,30 +3467,30 @@ has a default layout created and used instead. -### GPUProgrammableStageDescriptor ### {#GPUProgrammableStageDescriptor} +### GPUProgrammableStage ### {#GPUProgrammableStage} -A {{GPUProgrammableStageDescriptor}} describes the entry point in the user-provided +A {{GPUProgrammableStage}} describes the entry point in the user-provided {{GPUShaderModule}} that controls one of the programmable stages of a [=pipeline=].
- validating GPUProgrammableStageDescriptor(stage, descriptor, layout) + validating GPUProgrammableStage(stage, descriptor, layout) **Arguments:** - {{GPUShaderStage}} |stage| - - {{GPUProgrammableStageDescriptor}} |descriptor| + - {{GPUProgrammableStage}} |descriptor| - {{GPUPipelineLayout}} |layout| Return `true` if all of the following conditions are satisfied: - - The |descriptor|.{{GPUProgrammableStageDescriptor/module}} is [=valid=] {{GPUShaderModule}}. - - The |descriptor|.{{GPUProgrammableStageDescriptor/module}} contains - an entry point at |stage| named |descriptor|.{{GPUProgrammableStageDescriptor/entryPoint}}. + - The |descriptor|.{{GPUProgrammableStage/module}} is [=valid=] {{GPUShaderModule}}. + - The |descriptor|.{{GPUProgrammableStage/module}} contains + an entry point at |stage| named |descriptor|.{{GPUProgrammableStage/entryPoint}}. - For each |binding| that is [=statically used=] by the shader entry point, the [$validating shader binding$](|binding|, |layout|) returns `true`. - For each texture sampling shader call that is [=statically used=] by the entry point: @@ -3604,7 +3604,7 @@ GPUComputePipeline includes GPUPipelineBase; @@ -3627,7 +3627,7 @@ dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
- |this| is a [=valid=] {{GPUDevice}}. - |descriptor|.{{GPUPipelineDescriptorBase/layout}} is [$valid to use with$] |this|. - - [$validating GPUProgrammableStageDescriptor$]({{GPUShaderStage/COMPUTE}}, + - [$validating GPUProgrammableStage$]({{GPUShaderStage/COMPUTE}}, |descriptor|.{{GPUComputePipelineDescriptor/computeStage}}, |descriptor|.{{GPUPipelineDescriptorBase/layout}}) succeeds.
@@ -3678,24 +3678,24 @@ as well as {{GPURenderBundleEncoder}}. Render [=pipeline=] inputs are: - bindings, according to the given {{GPUPipelineLayout}} - - vertex and index buffers, described by {{GPUVertexStateDescriptor}} + - vertex and index buffers, described by {{GPUVertexInputState}} - the color attachments, described by {{GPUColorStateDescriptor}} - - optionally, the depth-stencil attachment, described by {{GPUDepthStencilStateDescriptor}} + - optionally, the depth-stencil attachment, described by {{GPUDepthStencilState}} Render [=pipeline=] outputs are: - {{GPUBindGroupLayoutEntry/buffer}} bindings with a {{GPUBufferBindingLayout/type}} of {{GPUBufferBindingType/"storage"}} - {{GPUBindGroupLayoutEntry/storageTexture}} bindings with a {{GPUStorageTextureBindingLayout/access}} of {{GPUStorageTextureAccess/"write-only"}} - the color attachments, described by {{GPUColorStateDescriptor}} - - optionally, depth-stencil attachment, described by {{GPUDepthStencilStateDescriptor}} + - optionally, depth-stencil attachment, described by {{GPUDepthStencilState}} Stages of a render [=pipeline=]: - 1. Vertex fetch, controlled by {{GPUVertexStateDescriptor}} + 1. Vertex fetch, controlled by {{GPUVertexInputState}} 2. Vertex shader 3. Primitive assembly - [[#primitive-assembly]] - 4. Rasterization, controlled by {{GPURasterizerStateDescriptor}} + 4. Rasterization, controlled by {{GPURasterizerState}} 5. Fragment shader - 6. Stencil test and operation, controlled by {{GPUDepthStencilStateDescriptor}} - 7. Depth test and write, controlled by {{GPUDepthStencilStateDescriptor}} + 6. Stencil test and operation, controlled by {{GPUDepthStencilState}} + 7. Depth test and write, controlled by {{GPUDepthStencilState}} 8. Output merging - [[#output-merger]] Issue: we need a deeper description of these stages @@ -3726,13 +3726,13 @@ GPURenderPipeline includes GPUPipelineBase; @@ -3740,11 +3740,11 @@ dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { the vertex shader entry point of the [=pipeline=] - {{GPURenderPipelineDescriptor/fragmentStage}} describes the fragment shader entry point of the [=pipeline=]. If it's `null`, the [[#no-color-output]] mode is enabled. -- {{GPURenderPipelineDescriptor/rasterizerState}} configures +- {{GPURenderPipelineDescriptor/rasterizer}} configures the rasterization stage of the [=pipeline=]. -- {{GPURenderPipelineDescriptor/depthStencilState}} describes +- {{GPURenderPipelineDescriptor/depthStencil}} describes the optional depth-stencil attachment that is written by the [=pipeline=]. -- {{GPURenderPipelineDescriptor/vertexState}} configures +- {{GPURenderPipelineDescriptor/vertexInput}} configures the vertex fetch stage of the [=pipeline=]. Issue(https://github.com/gpuweb/gpuweb/issues/936): @@ -3754,7 +3754,7 @@ Refactor the shape of the render pipeline descriptor to clearly enumerate the ### No Color Output ### {#no-color-output} In no-color-output mode, [=pipeline=] does not produce any color attachment outputs, -and the {{GPUOutputMergerStateDescriptor/colorStates}} is expected to be empty. +and the {{GPUOutputMergerState/colorStates}} is expected to be empty. The [=pipeline=] still performs rasterization and produces depth values based on the vertex position output. The depth testing and stencil operations can still be used. @@ -3791,7 +3791,7 @@ based on the vertex position output. The depth testing and stencil operations ca 1. Set |pipeline|.{{GPURenderPipeline/[[descriptor]]}} to |descriptor|. 1. Set |pipeline|.{{GPURenderPipeline/[[strip_index_format]]}} to - |descriptor|.{{GPURenderPipelineDescriptor/primitiveAssemblyState}}.{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}}. + |descriptor|.{{GPURenderPipelineDescriptor/primitiveAssembler}}.{{GPUPrimitiveAssemblerState/stripIndexFormat}}.
1. Return |pipeline|. @@ -3840,24 +3840,24 @@ based on the vertex position output. The depth testing and stencil operations ca Return `true` if all of the following conditions are satisfied: - - [$validating GPUVertexStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/vertexState}}, + - [$validating GPUVertexInputState$](|descriptor|.{{GPURenderPipelineDescriptor/vertexInput}}, |descriptor|.{{GPURenderPipelineDescriptor/vertexStage}}) succeeds. - - [$validating GPUProgrammableStageDescriptor$]({{GPUShaderStage/VERTEX}}, + - [$validating GPUProgrammableStage$]({{GPUShaderStage/VERTEX}}, |descriptor|.{{GPURenderPipelineDescriptor/vertexStage}}, |descriptor|.{{GPUPipelineDescriptorBase/layout}}) succeeds. - - [$validating GPUPrimitiveAssemblyStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/primitiveAssemblyState}}, + - [$validating GPUPrimitiveAssemblerState$](|descriptor|.{{GPURenderPipelineDescriptor/primitiveAssembler}}, |features|) succeeds. - - [$validating GPURasterizerStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/rasterizerState}}, + - [$validating GPURasterizerState$](|descriptor|.{{GPURenderPipelineDescriptor/rasterizer}}, |features|) succeeds. - - If |descriptor|.{{GPURenderPipelineDescriptor/rasterizerState}}.{{GPURasterizerStateDescriptor/sampleCount}} is 1: - - |descriptor|.{{GPURenderPipelineDescriptor/outputMergerState}}.{{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} is `false`, + - If |descriptor|.{{GPURenderPipelineDescriptor/rasterizer}}.{{GPURasterizerState/sampleCount}} is 1: + - |descriptor|.{{GPURenderPipelineDescriptor/outputMerger}}.{{GPUOutputMergerState/alphaToCoverageEnabled}} is `false`, - If |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}} is not `null`: - - [$validating GPUProgrammableStageDescriptor$]({{GPUShaderStage/FRAGMENT}}, + - [$validating GPUProgrammableStage$]({{GPUShaderStage/FRAGMENT}}, |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}, |descriptor|.{{GPUPipelineDescriptorBase/layout}}) succeeds. - - if |descriptor|.{{GPURenderPipelineDescriptor/depthStencilState}} is not `null`: - - [$validating GPUDepthStencilStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/depthStencilState}}) succeeds. - - [$validating GPUOutputMergerStateDescriptor$](|descriptor|.{{GPURenderPipelineDescriptor/outputMergerState}}, + - if |descriptor|.{{GPURenderPipelineDescriptor/depthStencil}} is not `null`: + - [$validating GPUDepthStencilState$](|descriptor|.{{GPURenderPipelineDescriptor/depthStencil}}) succeeds. + - [$validating GPUOutputMergerState$](|descriptor|.{{GPURenderPipelineDescriptor/outputMerger}}, |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}) succeeds. @@ -3872,15 +3872,15 @@ Issue: need a proper limit for the maximum number of color targets. ### Primitive Assembly ### {#primitive-assembly} -- {{GPUPrimitiveAssemblyStateDescriptor/topology}} defines what kind of +- {{GPUPrimitiveAssemblerState/topology}} defines what kind of primitives are constructed by the [=pipeline=]. -- {{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} defines the supported +- {{GPUPrimitiveAssemblerState/stripIndexFormat}} defines the supported index format for strip topologies.
- validating GPUPrimitiveAssemblyStateDescriptor(|descriptor|) + validating GPUPrimitiveAssemblerState(|descriptor|) Return `true` if all of the following conditions are met: - - If |descriptor|.{{GPUPrimitiveAssemblyStateDescriptor/topology}} is: + - If |descriptor|.{{GPUPrimitiveAssemblerState/topology}} is:
: {{GPUPrimitiveTopology/"line-strip"}} or {{GPUPrimitiveTopology/"triangle-strip"}} - :: |descriptor|.{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} is not `undefined` + :: |descriptor|.{{GPUPrimitiveAssemblerState/stripIndexFormat}} is not `undefined` : Otherwise - :: |descriptor|.{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} is `undefined` + :: |descriptor|.{{GPUPrimitiveAssemblerState/stripIndexFormat}} is `undefined`
@@ -3922,8 +3922,8 @@ strip primitive topologies ({{GPUPrimitiveTopology/"line-strip"}} or should be started rather than continuing to construct the triangle strip with the prior indexed vertices. -{{GPUPrimitiveAssemblyStateDescriptor}}s that specify a strip primitive topology must not have the -{{GPUPrimitiveAssemblyStateDescriptor/stripIndexFormat}} set to `undefined` +{{GPUPrimitiveAssemblerState}}s that specify a strip primitive topology must not have the +{{GPUPrimitiveAssemblerState/stripIndexFormat}} set to `undefined` so that the [=primitive restart value=] that will be used is known at pipline creation time. @@ -3949,7 +3949,7 @@ so that the [=primitive restart value=] that will be used is known at pipline cr ### Rasterization State ### {#rasterization-state} -- {{GPURasterizerStateDescriptor/sampleCount}} is +- {{GPURasterizerState/sampleCount}} is the number of MSAA samples that each attachment has to have. -- {{GPURasterizerStateDescriptor/sampleMask}} is +- {{GPURasterizerState/sampleMask}} is a binary mask of MSAA samples, according to [[#sample-masking]].
- validating GPURasterizerStateDescriptor(|device|, |descriptor|) + validating GPURasterizerState(|device|, |descriptor|) Return `true` if all of the following conditions are met: - - |descriptor|.{{GPURasterizerStateDescriptor/clampDepth}} is `false`, + - |descriptor|.{{GPURasterizerState/clampDepth}} is `false`, or |device|.{{device/[[features]]}} [=list/contain=] {{GPUFeatureName/"depth-clamping"}}.
@@ -3994,9 +3994,9 @@ enum GPUCullMode { #### Sample Masking #### {#sample-masking} The final sample mask for a pixel is computed as: -[=rasterization mask=] & {{GPURasterizerStateDescriptor/sampleMask}} & [=shader-output mask=]. +[=rasterization mask=] & {{GPURasterizerState/sampleMask}} & [=shader-output mask=]. -Only the lower {{GPURasterizerStateDescriptor/sampleCount}} bits of the mask are considered. +Only the lower {{GPURasterizerState/sampleCount}} bits of the mask are considered. If the least-significant bit at position |N| of the [=final sample mask=] has value of "0", the sample color outputs (corresponding to sample |N|) to all attachments of the fragment shader are discarded. @@ -4011,7 +4011,7 @@ based on the shape of the rasterized polygon. The samples incuded in the shape g bits 1 in the mask. The shader-output mask takes the output value of SV_Coverage semantics in the fragment shader. -If the semantics is not [=statically used=] by the shader, and {{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} +If the semantics is not [=statically used=] by the shader, and {{GPUOutputMergerState/alphaToCoverageEnabled}} is enabled, the [=shader-output mask=] becomes the [=alpha-to-coverage mask=]. Otherwise, it defaults to 0xFFFFFFFF. Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. @@ -4019,44 +4019,44 @@ Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. ### Output Merger State ### {#output-merger} -- {{GPUOutputMergerStateDescriptor/colorStates}} describes +- {{GPUOutputMergerState/colorStates}} describes the color attachments that are written by the [=pipeline=]. -- {{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode. +- {{GPUOutputMergerState/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode.
- validating GPUOutputMergerStateDescriptor(descriptor, fragmentStage) + validating GPUOutputMergerState(descriptor, fragmentStage) **Arguments:** - {{GPUColorStateDescriptor}} |descriptor| - - {{GPUProgrammableStageDescriptor}} |fragmentStage| + - {{GPUProgrammableStage}} |fragmentStage| Return `true`, if and only if, all of the following conditions are satisfied: - - For each |colorState| at |index| in |descriptor|.{{GPUOutputMergerStateDescriptor/colorStates}}: + - For each |colorState| at |index| in |descriptor|.{{GPUOutputMergerState/colorStates}}: - [$validating GPUColorStateDescriptor$](|colorState|) succeeds. - |fragmentStage| contains an output variable [=statically used=]: - with `location` annotation equal to |index| - with a type that is compatible with |colorState|.{{GPUColorStateDescriptor/format}}. with {{GPUTextureUsage/RENDER_ATTACHMENT}} capability. - If the output `SV_Coverage` semantics is [=statically used=] by |fragmentStage|: - - |descriptor|.{{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}} is `false`. + - |descriptor|.{{GPUOutputMergerState/alphaToCoverageEnabled}} is `false`. - If |fragmentStage| is `null`: - - |descriptor|.{{GPUOutputMergerStateDescriptor/colorStates}} is empty. - - |descriptor|.{{GPUOutputMergerStateDescriptor/colorStates}}.length is less than + - |descriptor|.{{GPUOutputMergerState/colorStates}} is empty. + - |descriptor|.{{GPUOutputMergerState/colorStates}}.length is less than or equal to 4.
#### Alpha to Coverage #### {#alpha-to-coverage} -In alpha-to-coverage mode, which is enabled by {{GPUOutputMergerStateDescriptor/alphaToCoverageEnabled}}, +In alpha-to-coverage mode, which is enabled by {{GPUOutputMergerState/alphaToCoverageEnabled}}, an additional alpha-to-coverage mask of MSAA samples is generated based on the |alpha| component of the -fragment shader output value of the {{GPUOutputMergerStateDescriptor/colorStates}}[0]. +fragment shader output value of the {{GPUOutputMergerState/colorStates}}[0]. The algorithm of producing the extra mask is platform-dependent and can vary for different pixels. It guarantees that: @@ -4150,7 +4150,7 @@ enum GPUBlendOperation { ### Depth/Stencil State ### {#depth-stencil-state}
- validating GPUDepthStencilStateDescriptor(descriptor) + validating GPUDepthStencilState(descriptor) **Arguments:** - - {{GPUDepthStencilStateDescriptor}} |descriptor| + - {{GPUDepthStencilState}} |descriptor| Return `true`, if and only if, all of the following conditions are satisfied: - - |descriptor|.{{GPUDepthStencilStateDescriptor/format}} is listed in {#depth-formats}. - - if |descriptor|.{{GPUDepthStencilStateDescriptor/depthWriteEnabled}} is `true` or - |descriptor|.{{GPUDepthStencilStateDescriptor/depthCompare}} is not {{GPUCompareFunction/"always"}}: - - |descriptor|.{{GPUDepthStencilStateDescriptor/format}} must have a depth component. - - if |descriptor|.{{GPUDepthStencilStateDescriptor/stencilFront}} or - |descriptor|.{{GPUDepthStencilStateDescriptor/stencilBack}} are not default values: - - |descriptor|.{{GPUDepthStencilStateDescriptor/format}} must have a stencil component. + - |descriptor|.{{GPUDepthStencilState/format}} is listed in {#depth-formats}. + - if |descriptor|.{{GPUDepthStencilState/depthWriteEnabled}} is `true` or + |descriptor|.{{GPUDepthStencilState/depthCompare}} is not {{GPUCompareFunction/"always"}}: + - |descriptor|.{{GPUDepthStencilState/format}} must have a depth component. + - if |descriptor|.{{GPUDepthStencilState/stencilFront}} or + |descriptor|.{{GPUDepthStencilState/stencilBack}} are not default values: + - |descriptor|.{{GPUDepthStencilState/format}} must have a stencil component. Issue: how can this algorithm support depth/stencil formats that are added in extensions?
@@ -4267,7 +4267,7 @@ enum GPUInputStepMode { @@ -4283,7 +4283,7 @@ Each {{GPUVertexAttributeDescriptor}} describes its Each attribute appears as a separate input in a vertex shader, each bound by a numeric *location*, which is specified by {{GPUVertexAttributeDescriptor/shaderLocation}}. -Every location must be unique within the {{GPUVertexStateDescriptor}}. +Every location must be unique within the {{GPUVertexInputState}}. -- {{GPUOutputMergerState/colorStates}} describes - the color attachments that are written by the [=pipeline=]. +- {{GPUOutputMergerState/colors}} describes + the color outputs that are written by the [=pipeline=]. - {{GPUOutputMergerState/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode.
validating GPUOutputMergerState(descriptor, fragmentStage) **Arguments:** - - {{GPUColorStateDescriptor}} |descriptor| + - {{GPUColorOutputState}} |descriptor| - {{GPUProgrammableStage}} |fragmentStage| Return `true`, if and only if, all of the following conditions are satisfied: - - For each |colorState| at |index| in |descriptor|.{{GPUOutputMergerState/colorStates}}: - - [$validating GPUColorStateDescriptor$](|colorState|) succeeds. + - For each |colorState| at |index| in |descriptor|.{{GPUOutputMergerState/colors}}: + - [$validating GPUColorOutputState$](|colorState|) succeeds. - |fragmentStage| contains an output variable [=statically used=]: - with `location` annotation equal to |index| - - with a type that is compatible with |colorState|.{{GPUColorStateDescriptor/format}}. + - with a type that is compatible with |colorState|.{{GPUColorOutputState/format}}. with {{GPUTextureUsage/RENDER_ATTACHMENT}} capability. - If the output `SV_Coverage` semantics is [=statically used=] by |fragmentStage|: - |descriptor|.{{GPUOutputMergerState/alphaToCoverageEnabled}} is `false`. - If |fragmentStage| is `null`: - - |descriptor|.{{GPUOutputMergerState/colorStates}} is empty. - - |descriptor|.{{GPUOutputMergerState/colorStates}}.length is less than + - |descriptor|.{{GPUOutputMergerState/colors}} is empty. + - |descriptor|.{{GPUOutputMergerState/colors}}.length is less than or equal to 4.
@@ -4056,7 +4056,7 @@ dictionary GPUOutputMergerState { In alpha-to-coverage mode, which is enabled by {{GPUOutputMergerState/alphaToCoverageEnabled}}, an additional alpha-to-coverage mask of MSAA samples is generated based on the |alpha| component of the -fragment shader output value of the {{GPUOutputMergerState/colorStates}}[0]. +fragment shader output value of the {{GPUOutputMergerState/colors}}[0]. The algorithm of producing the extra mask is platform-dependent and can vary for different pixels. It guarantees that: @@ -4068,7 +4068,7 @@ It guarantees that: #### Color State #### {#color-state}
- validating GPUColorStateDescriptor(descriptor) + validating GPUColorOutputState(descriptor) **Arguments:** - - {{GPUColorStateDescriptor}} |descriptor| + - {{GPUColorOutputState}} |descriptor| Return `true`, if and only if, all of the following conditions are satisfied: - - |descriptor|.{{GPUColorStateDescriptor/format}} is listed in {#plain-color-formats} + - |descriptor|.{{GPUColorOutputState/format}} is listed in {#plain-color-formats} with {{GPUTextureUsage/RENDER_ATTACHMENT}} capability. - - |descriptor|.{{GPUColorStateDescriptor/blend}} is either `undefined`, - or the |descriptor|.{{GPUColorStateDescriptor/format}} is filterable + - |descriptor|.{{GPUColorOutputState/blend}} is either `undefined`, + or the |descriptor|.{{GPUColorOutputState/format}} is filterable according to the {#plain-color-formats} table. - - |descriptor|.{{GPUColorStateDescriptor/writeMask}} is less than 16. + - |descriptor|.{{GPUColorOutputState/writeMask}} is less than 16.
### Depth/Stencil State ### {#depth-stencil-state} @@ -4268,33 +4268,33 @@ enum GPUInputStepMode { A vertex buffer is, conceptually, a view into buffer memory as an *array of structures*. -{{GPUVertexBufferLayoutDescriptor/arrayStride}} is the stride, in bytes, between *elements* of that array. +{{GPUVertexBufferLayout/arrayStride}} is the stride, in bytes, between *elements* of that array. Each element of a vertex buffer is like a *structure* with a memory layout defined by its -{{GPUVertexBufferLayoutDescriptor/attributes}}, which describe the *members* of the structure. +{{GPUVertexBufferLayout/attributes}}, which describe the *members* of the structure. -Each {{GPUVertexAttributeDescriptor}} describes its -{{GPUVertexAttributeDescriptor/format}} and its -{{GPUVertexAttributeDescriptor/offset}}, in bytes, within the structure. +Each {{GPUVertexAttribute}} describes its +{{GPUVertexAttribute/format}} and its +{{GPUVertexAttribute/offset}}, in bytes, within the structure. Each attribute appears as a separate input in a vertex shader, each bound by a numeric *location*, -which is specified by {{GPUVertexAttributeDescriptor/shaderLocation}}. +which is specified by {{GPUVertexAttribute/shaderLocation}}. Every location must be unique within the {{GPUVertexInputState}}.
- validating GPUVertexBufferLayoutDescriptor(descriptor, vertexStage) + validating GPUVertexBufferLayout(descriptor, vertexStage) **Arguments:** - - {{GPUVertexBufferLayoutDescriptor}} |descriptor| + - {{GPUVertexBufferLayout}} |descriptor| - {{GPUProgrammableStage}} |vertexStage| Return `true`, if and only if, all of the following conditions are satisfied: - 1. |descriptor|.{{GPUVertexBufferLayoutDescriptor/arrayStride}} is less than or equal to + 1. |descriptor|.{{GPUVertexBufferLayout/arrayStride}} is less than or equal to {{GPULimits/maxVertexBufferArrayStride|GPULimits.maxVertexBufferArrayStride}}. - 1. Any attribute |at| in the list |descriptor|.{{GPUVertexBufferLayoutDescriptor/attributes}} has - |at|.{{GPUVertexAttributeDescriptor/offset}} + sizeOf(|at|.{{GPUVertexAttributeDescriptor/format}}) less or equal to - |descriptor|.{{GPUVertexBufferLayoutDescriptor/arrayStride}}. + 1. Any attribute |at| in the list |descriptor|.{{GPUVertexBufferLayout/attributes}} has + |at|.{{GPUVertexAttribute/offset}} + sizeOf(|at|.{{GPUVertexAttribute/format}}) less or equal to + |descriptor|.{{GPUVertexBufferLayout/arrayStride}}. 1. For every vertex attribute in the shader reflection of |vertexStage|.{{GPUProgrammableStage/module}} that is know to be [=statically used=] by |vertexStage|.{{GPUProgrammableStage/entryPoint}}, - there is a corresponding |at| element of |descriptor|.{{GPUVertexBufferLayoutDescriptor/attributes}} that: - 1. The shader format is |at|.{{GPUVertexAttributeDescriptor/format}}. - 2. The shader location is |at|.{{GPUVertexAttributeDescriptor/shaderLocation}}. + there is a corresponding |at| element of |descriptor|.{{GPUVertexBufferLayout/attributes}} that: + 1. The shader format is |at|.{{GPUVertexAttribute/format}}. + 2. The shader location is |at|.{{GPUVertexAttribute/shaderLocation}}.
@@ -4333,13 +4333,13 @@ dictionary GPUVertexAttributeDescriptor { 1. |descriptor|.{{GPUVertexInputState/vertexBuffers}}.length is less than or equal to {{GPULimits/maxVertexBuffers|GPULimits.maxVertexBuffers}} 1. Each |vertexBuffer| layout descriptor in the list |descriptor|.{{GPUVertexInputState/vertexBuffers}} - passes [$validating GPUVertexBufferLayoutDescriptor$](|vertexBuffer|, |vertexStage|) - 1. The sum of |vertexBuffer|.{{GPUVertexBufferLayoutDescriptor/attributes}}.length, + passes [$validating GPUVertexBufferLayout$](|vertexBuffer|, |vertexStage|) + 1. The sum of |vertexBuffer|.{{GPUVertexBufferLayout/attributes}}.length, over every |vertexBuffer| in |descriptor|.{{GPUVertexInputState/vertexBuffers}}, is less than or equal to {{GPULimits/maxVertexAttributes|GPULimits.maxVertexAttributes}}. - 1. Each |at| in the union of all {{GPUVertexAttributeDescriptor}} + 1. Each |at| in the union of all {{GPUVertexAttribute}} across |descriptor|.{{GPUVertexInputState/vertexBuffers}} has a distinct - |at|.{{GPUVertexAttributeDescriptor/shaderLocation}} value. + |at|.{{GPUVertexAttribute/shaderLocation}} value.
# Command Buffers # {#command-buffers} From 49eee6f540fd77f9b5484f39ade1e6d245859d0c Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 16 Dec 2020 14:42:24 -0500 Subject: [PATCH 5/7] Update the example hello-cube --- samples/hello-cube.html | 55 +++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/samples/hello-cube.html b/samples/hello-cube.html index 5a9b5bc0bf..dffc065968 100644 --- a/samples/hello-cube.html +++ b/samples/hello-cube.html @@ -123,47 +123,48 @@ verticesWriteArray.set(verticesArray); verticesBuffer.unmap(); + // Bind group binding layout + const transformBufferBindGroupLayoutEntry = { + binding: transformBindingNum, // id[[(0)]] + visibility: GPUShaderStageBit.VERTEX, + type: "uniform-buffer" + }; + + const bindGroupLayoutDescriptor = { entries: [transformBufferBindGroupLayoutEntry] }; + bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); + + const pipelineLayoutDescriptor = { bindGroupLayouts: [bindGroupLayout] }; + const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); + // Vertex Input - const positionAttributeDescriptor = { + const positionAttribute = { shaderLocation: positionAttributeNum, // [[attribute(0)]] offset: 0, format: "float4" }; - const colorAttributeDescriptor = { + const colorAttribute = { shaderLocation: colorAttributeNum, offset: colorOffset, format: "float4" } - const vertexBufferDescriptor = { - attributeSet: [positionAttributeDescriptor, colorAttributeDescriptor], + const vertexBufferLayout = { + attributeSet: [positionAttributeDescriptor, colorAttribute], stride: vertexSize, stepMode: "vertex" }; - const vertexInputDescriptor = { vertexBuffers: [vertexBufferDescriptor] }; - - // Bind group binding layout - const transformBufferBindGroupLayoutEntry = { - binding: transformBindingNum, // id[[(0)]] - visibility: GPUShaderStageBit.VERTEX, - type: "uniform-buffer" - }; - - const bindGroupLayoutDescriptor = { entries: [transformBufferBindGroupLayoutEntry] }; - bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); + const vertexInputState = { vertexBuffers: [vertexBufferLayout] }; // Pipeline - const depthStateDescriptor = { + const depthState = { depthWriteEnabled: true, depthCompare: "less" }; - const pipelineLayoutDescriptor = { bindGroupLayouts: [bindGroupLayout] }; - const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor); - const vertexStageDescriptor = { + const vertexStage = { module: shaderModule, entryPoint: "vertex_main" }; - const fragmentStageDescriptor = { + const fragmentStage = { module: shaderModule, entryPoint: "fragment_main" }; @@ -183,19 +184,19 @@ }, writeMask: GPUColorWriteBits.ALL }; - const outputMergerStateDescriptor = { - colorStates: [colorState] + const outputMergerState = { + colors: [colorState] }; const pipelineDescriptor = { layout: pipelineLayout, - vertexStage: vertexStageDescriptor, - fragmentStage: fragmentStageDescriptor, + vertexStage: vertexStage, + fragmentStage: fragmentStage, - outputMerger: outputMergerStateDescriptor, - depthStencilState: depthStateDescriptor, - vertexInput: vertexInputDescriptor + outputMerger: outputMergerState, + depthStencilState: depthState, + vertexInput: vertexInputState }; pipeline = device.createRenderPipeline(pipelineDescriptor); From 0de1e7251ae9c252ac04ed2a9c9fb6b890ee94eb Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 17 Dec 2020 12:11:21 -0500 Subject: [PATCH 6/7] Rename output merger to color write --- samples/hello-cube.html | 9 ++++----- spec/index.bs | 40 ++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/samples/hello-cube.html b/samples/hello-cube.html index dffc065968..5d72fb2a27 100644 --- a/samples/hello-cube.html +++ b/samples/hello-cube.html @@ -184,8 +184,8 @@ }, writeMask: GPUColorWriteBits.ALL }; - const outputMergerState = { - colors: [colorState] + const colorWriteState = { + output: [colorState] }; const pipelineDescriptor = { layout: pipelineLayout, @@ -193,10 +193,9 @@ vertexStage: vertexStage, fragmentStage: fragmentStage, - - outputMerger: outputMergerState, - depthStencilState: depthState, vertexInput: vertexInputState + depthStencilState: depthState, + colorWrite: colorWriteState, }; pipeline = device.createRenderPipeline(pipelineDescriptor); diff --git a/spec/index.bs b/spec/index.bs index 4e955ac352..f59c8e7db6 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -185,7 +185,7 @@ thead.stickyheader th, th.stickyheader { } /* - * Darkmode colors + * Darkmode outputs */ :root { --watermark-text: rgba(0, 0, 0, 15%); @@ -3275,7 +3275,7 @@ integration such as source-language debugging. A pipeline, be it {{GPUComputePipeline}} or {{GPURenderPipeline}}, represents the complete function done by a combination of the GPU hardware, the driver, and the user agent, that process the input data in the shape of bindings and vertex buffers, -and produces some output, like the colors in the output render targets. +and produces some output, like the outputs in the output render targets. Structurally, the [=pipeline=] consists of a sequence of programmable stages (shaders) and fixed-function states, such as the blending modes. @@ -3732,7 +3732,7 @@ dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { GPURasterizerState rasterizer = {}; GPUProgrammableStage fragmentStage; GPUDepthStencilState depthStencil; - required GPUOutputMergerState outputMerger; + required GPUColorWriteState colorWrite; }; @@ -3754,7 +3754,7 @@ Refactor the shape of the render pipeline descriptor to clearly enumerate the ### No Color Output ### {#no-color-output} In no-color-output mode, [=pipeline=] does not produce any color attachment outputs, -and the {{GPUOutputMergerState/colors}} is expected to be empty. +and the {{GPUColorWriteState/outputs}} is expected to be empty. The [=pipeline=] still performs rasterization and produces depth values based on the vertex position output. The depth testing and stencil operations can still be used. @@ -3850,14 +3850,14 @@ based on the vertex position output. The depth testing and stencil operations ca - [$validating GPURasterizerState$](|descriptor|.{{GPURenderPipelineDescriptor/rasterizer}}, |features|) succeeds. - If |descriptor|.{{GPURenderPipelineDescriptor/rasterizer}}.{{GPURasterizerState/sampleCount}} is 1: - - |descriptor|.{{GPURenderPipelineDescriptor/outputMerger}}.{{GPUOutputMergerState/alphaToCoverageEnabled}} is `false`, + - |descriptor|.{{GPURenderPipelineDescriptor/colorWrite}}.{{GPUColorWriteState/alphaToCoverageEnabled}} is `false`, - If |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}} is not `null`: - [$validating GPUProgrammableStage$]({{GPUShaderStage/FRAGMENT}}, |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}, |descriptor|.{{GPUPipelineDescriptorBase/layout}}) succeeds. - if |descriptor|.{{GPURenderPipelineDescriptor/depthStencil}} is not `null`: - [$validating GPUDepthStencilState$](|descriptor|.{{GPURenderPipelineDescriptor/depthStencil}}) succeeds. - - [$validating GPUOutputMergerState$](|descriptor|.{{GPURenderPipelineDescriptor/outputMerger}}, + - [$validating GPUColorWriteState$](|descriptor|.{{GPURenderPipelineDescriptor/colorWrite}}, |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}) succeeds. @@ -4011,7 +4011,7 @@ based on the shape of the rasterized polygon. The samples incuded in the shape g bits 1 in the mask. The shader-output mask takes the output value of SV_Coverage semantics in the fragment shader. -If the semantics is not [=statically used=] by the shader, and {{GPUOutputMergerState/alphaToCoverageEnabled}} +If the semantics is not [=statically used=] by the shader, and {{GPUColorWriteState/alphaToCoverageEnabled}} is enabled, the [=shader-output mask=] becomes the [=alpha-to-coverage mask=]. Otherwise, it defaults to 0xFFFFFFFF. Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. @@ -4019,44 +4019,44 @@ Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. ### Output Merger State ### {#output-merger} -- {{GPUOutputMergerState/colors}} describes +- {{GPUColorWriteState/outputs}} describes the color outputs that are written by the [=pipeline=]. -- {{GPUOutputMergerState/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode. +- {{GPUColorWriteState/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode.
- validating GPUOutputMergerState(descriptor, fragmentStage) + validating GPUColorWriteState(descriptor, fragmentStage) **Arguments:** - {{GPUColorOutputState}} |descriptor| - {{GPUProgrammableStage}} |fragmentStage| Return `true`, if and only if, all of the following conditions are satisfied: - - For each |colorState| at |index| in |descriptor|.{{GPUOutputMergerState/colors}}: + - For each |colorState| at |index| in |descriptor|.{{GPUColorWriteState/outputs}}: - [$validating GPUColorOutputState$](|colorState|) succeeds. - |fragmentStage| contains an output variable [=statically used=]: - with `location` annotation equal to |index| - - with a type that is compatible with |colorState|.{{GPUColorOutputState/format}}. + - with a type that is compatible with |colorState|.{{GPUColorOutputState/format}} with {{GPUTextureUsage/RENDER_ATTACHMENT}} capability. - If the output `SV_Coverage` semantics is [=statically used=] by |fragmentStage|: - - |descriptor|.{{GPUOutputMergerState/alphaToCoverageEnabled}} is `false`. + - |descriptor|.{{GPUColorWriteState/alphaToCoverageEnabled}} is `false`. - If |fragmentStage| is `null`: - - |descriptor|.{{GPUOutputMergerState/colors}} is empty. - - |descriptor|.{{GPUOutputMergerState/colors}}.length is less than + - |descriptor|.{{GPUColorWriteState/outputs}} is empty. + - |descriptor|.{{GPUColorWriteState/outputs}}.length is less than or equal to 4.
#### Alpha to Coverage #### {#alpha-to-coverage} -In alpha-to-coverage mode, which is enabled by {{GPUOutputMergerState/alphaToCoverageEnabled}}, +In alpha-to-coverage mode, which is enabled by {{GPUColorWriteState/alphaToCoverageEnabled}}, an additional alpha-to-coverage mask of MSAA samples is generated based on the |alpha| component of the -fragment shader output value of the {{GPUOutputMergerState/colors}}[0]. +fragment shader output value of the {{GPUColorWriteState/outputs}}[0]. The algorithm of producing the extra mask is platform-dependent and can vary for different pixels. It guarantees that: @@ -7158,7 +7158,7 @@ typedef [EnforceRange] long GPUSignedOffset32; typedef unsigned long GPUFlagsConstant; -## Colors & Vectors ## {#colors-and-vectors} +## Colors & Vectors ## {#outputs-and-vectors} -- {{GPUPrimitiveAssemblerState/topology}} defines what kind of +- {{GPUPrimitiveAssemblyState/topology}} defines what kind of primitives are constructed by the [=pipeline=]. -- {{GPUPrimitiveAssemblerState/stripIndexFormat}} defines the supported +- {{GPUPrimitiveAssemblyState/stripIndexFormat}} defines the supported index format for strip topologies.
- validating GPUPrimitiveAssemblerState(|descriptor|) + validating GPUPrimitiveAssemblyState(|descriptor|) Return `true` if all of the following conditions are met: - - If |descriptor|.{{GPUPrimitiveAssemblerState/topology}} is: + - If |descriptor|.{{GPUPrimitiveAssemblyState/topology}} is:
: {{GPUPrimitiveTopology/"line-strip"}} or {{GPUPrimitiveTopology/"triangle-strip"}} - :: |descriptor|.{{GPUPrimitiveAssemblerState/stripIndexFormat}} is not `undefined` + :: |descriptor|.{{GPUPrimitiveAssemblyState/stripIndexFormat}} is not `undefined` : Otherwise - :: |descriptor|.{{GPUPrimitiveAssemblerState/stripIndexFormat}} is `undefined` + :: |descriptor|.{{GPUPrimitiveAssemblyState/stripIndexFormat}} is `undefined`
@@ -3922,8 +3914,8 @@ strip primitive topologies ({{GPUPrimitiveTopology/"line-strip"}} or should be started rather than continuing to construct the triangle strip with the prior indexed vertices. -{{GPUPrimitiveAssemblerState}}s that specify a strip primitive topology must not have the -{{GPUPrimitiveAssemblerState/stripIndexFormat}} set to `undefined` +{{GPUPrimitiveAssemblyState}}s that specify a strip primitive topology must not have the +{{GPUPrimitiveAssemblyState/stripIndexFormat}} set to `undefined` so that the [=primitive restart value=] that will be used is known at pipline creation time.
@@ -3946,10 +3938,10 @@ so that the [=primitive restart value=] that will be used is known at pipline cr
-### Rasterization State ### {#rasterization-state} +### Rasterizer State ### {#rasterization} -- {{GPURasterizerState/sampleCount}} is +- {{GPURasterizationState/sampleCount}} is the number of MSAA samples that each attachment has to have. -- {{GPURasterizerState/sampleMask}} is +- {{GPURasterizationState/sampleMask}} is a binary mask of MSAA samples, according to [[#sample-masking]].
- validating GPURasterizerState(|device|, |descriptor|) + validating GPURasterizationState(|device|, |descriptor|) Return `true` if all of the following conditions are met: - - |descriptor|.{{GPURasterizerState/clampDepth}} is `false`, + - |descriptor|.{{GPURasterizationState/clampDepth}} is `false`, or |device|.{{device/[[features]]}} [=list/contain=] {{GPUFeatureName/"depth-clamping"}}.
@@ -3994,9 +3986,9 @@ enum GPUCullMode { #### Sample Masking #### {#sample-masking} The final sample mask for a pixel is computed as: -[=rasterization mask=] & {{GPURasterizerState/sampleMask}} & [=shader-output mask=]. +[=rasterization mask=] & {{GPURasterizationState/sampleMask}} & [=shader-output mask=]. -Only the lower {{GPURasterizerState/sampleCount}} bits of the mask are considered. +Only the lower {{GPURasterizationState/sampleCount}} bits of the mask are considered. If the least-significant bit at position |N| of the [=final sample mask=] has value of "0", the sample color outputs (corresponding to sample |N|) to all attachments of the fragment shader are discarded. @@ -4016,7 +4008,7 @@ is enabled, the [=shader-output mask=] becomes the [=alpha-to-coverage mask=]. O Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec. -### Output Merger State ### {#output-merger} +### Color Write State ### {#color-write}