diff --git a/samples/hello-cube.html b/samples/hello-cube.html
index 10e5974d1c..d62521445e 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,16 +184,18 @@
},
writeMask: GPUColorWriteBits.ALL
};
+ const colorWriteState = {
+ outputs: [colorState]
+ };
const pipelineDescriptor = {
layout: pipelineLayout,
- vertexStage: vertexStageDescriptor,
- fragmentStage: fragmentStageDescriptor,
+ vertexStage: vertexStage,
+ fragmentStage: fragmentStage,
- primitiveTopology: "triangle-list",
- colorStates: [colorState],
- depthStencilState: depthStateDescriptor,
- vertexInput: vertexInputDescriptor
+ vertexInput: vertexInputState
+ depthStencilState: depthState,
+ colorWrite: colorWriteState,
};
pipeline = device.createRenderPipeline(pipelineDescriptor);
diff --git a/spec/index.bs b/spec/index.bs
index a4d8bcd885..96eff2e941 100644
--- a/spec/index.bs
+++ b/spec/index.bs
@@ -1049,20 +1049,20 @@ a better limit is not specified.
- The maximum allowed {{GPUVertexBufferLayoutDescriptor/arrayStride}}
+ The maximum allowed {{GPUVertexBufferLayout/arrayStride}}
when creating a {{GPURenderPipeline}}.
@@ -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,25 +3678,25 @@ as well as {{GPURenderBundleEncoder}}.
Render [=pipeline=] inputs are:
- bindings, according to the given {{GPUPipelineLayout}}
- - vertex and index buffers, described by {{GPUVertexStateDescriptor}}
- - the color attachments, described by {{GPUColorStateDescriptor}}
- - optionally, the depth-stencil attachment, described by {{GPUDepthStencilStateDescriptor}}
+ - vertex and index buffers, described by {{GPUVertexInputState}}
+ - the color attachments, described by {{GPUColorOutputState}}
+ - 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}}
+ - the color attachments, described by {{GPUColorOutputState}}
+ - 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, controlled by {{GPUPrimitiveTopology}}
- 4. Rasterization, controlled by {{GPURasterizationStateDescriptor}}
+ 3. Primitive assembly - [[#primitive-assembly]]
+ 4. Rasterization - [[#rasterization]]
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}}
+ 6. Stencil test and operation, controlled by {{GPUDepthStencilState}}
+ 7. Depth test and write, controlled by {{GPUDepthStencilState}}
+ 8. Color write - [[#color-write]]
Issue: we need a deeper description of these stages
@@ -3726,18 +3726,13 @@ GPURenderPipeline includes GPUPipelineBase;
@@ -3745,72 +3740,17 @@ 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
+- {{GPURenderPipelineDescriptor/rasterization}} configures
the rasterization stage of the [=pipeline=].
-- {{GPURenderPipelineDescriptor/colorStates}} describes
- the color attachments that are written by 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=].
-- {{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
(ordered) list of pipeline stages. And start formalizing the spec text.
-### 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.
-
-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 +3782,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/primitiveAssembly}}.{{GPUPrimitiveAssemblyState/stripIndexFormat}}.
1. Return |pipeline|.
@@ -3894,42 +3832,25 @@ Issue: link to the semantics of SV_SampleIndex and SV_Coverage in WGSL spec.
Return `true` if all of the following conditions are satisfied:
- - [$validating GPUProgrammableStageDescriptor$]({{GPUShaderStage/VERTEX}},
+ - [$validating GPUVertexInputState$](|descriptor|.{{GPURenderPipelineDescriptor/vertexInput}},
+ |descriptor|.{{GPURenderPipelineDescriptor/vertexStage}}) succeeds.
+ - [$validating GPUProgrammableStage$]({{GPUShaderStage/VERTEX}},
|descriptor|.{{GPURenderPipelineDescriptor/vertexStage}},
|descriptor|.{{GPUPipelineDescriptorBase/layout}}) succeeds.
+ - [$validating GPUPrimitiveAssemblyState$](|descriptor|.{{GPURenderPipelineDescriptor/primitiveAssembly}},
+ |features|) succeeds.
+ - [$validating GPURasterizationState$](|descriptor|.{{GPURenderPipelineDescriptor/rasterization}},
+ |features|) succeeds.
+ - If |descriptor|.{{GPURenderPipelineDescriptor/rasterization}}.{{GPURasterizationState/sampleCount}} is 1:
+ - |descriptor|.{{GPURenderPipelineDescriptor/colorWrite}}.{{GPUColorWriteState/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/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`
-
+ - if |descriptor|.{{GPURenderPipelineDescriptor/depthStencil}} is not `null`:
+ - [$validating GPUDepthStencilState$](|descriptor|.{{GPURenderPipelineDescriptor/depthStencil}}) succeeds.
+ - [$validating GPUColorWriteState$](|descriptor|.{{GPURenderPipelineDescriptor/colorWrite}},
+ |descriptor|.{{GPURenderPipelineDescriptor/fragmentStage}}) succeeds.
Issue: validate interface matching rules between VS and FS.
@@ -3940,7 +3861,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 State ### {#primitive-assembly}
+
+
+
+- {{GPUPrimitiveAssemblyState/topology}} defines what kind of
+ primitives are constructed by the [=pipeline=].
+- {{GPUPrimitiveAssemblyState/stripIndexFormat}} defines the supported
+ index format for strip topologies.
-### Rasterization State ### {#rasterization-state}
+
+ validating GPUPrimitiveAssemblyState(|descriptor|)
+ Return `true` if all of the following conditions are met:
+ - If |descriptor|.{{GPUPrimitiveAssemblyState/topology}} is:
+
+ : {{GPUPrimitiveTopology/"line-strip"}} or
+ {{GPUPrimitiveTopology/"triangle-strip"}}
+ :: |descriptor|.{{GPUPrimitiveAssemblyState/stripIndexFormat}} is not `undefined`
+ : Otherwise
+ :: |descriptor|.{{GPUPrimitiveAssemblyState/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.
+
+{{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.
+
+
+
+
+ Index format |
+ Primitive restart value |
+
+
+
+
+ {{GPUIndexFormat/"uint16"}} |
+ 0xFFFF |
+
+
+ {{GPUIndexFormat/"uint32"}} |
+ 0xFFFFFFFF |
+
+
+
+
+
+### Rasterizer State ### {#rasterization}
+
+
+- {{GPURasterizationState/sampleCount}} is
+ the number of MSAA samples that each attachment has to have.
+- {{GPURasterizationState/sampleMask}} is
+ a binary mask of MSAA samples, according to [[#sample-masking]].
+
- 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 GPURasterizationState(|device|, |descriptor|)
+ Return `true` if all of the following conditions are met:
+ - |descriptor|.{{GPURasterizationState/clampDepth}} is `false`,
+ or |device|.{{device/[[features]]}} [=list/contain=] {{GPUFeatureName/"depth-clamping"}}.
-### Color State ### {#color-state}
+#### Sample Masking #### {#sample-masking}
+
+The final sample mask for a pixel is computed as:
+[=rasterization mask=] & {{GPURasterizationState/sampleMask}} & [=shader-output mask=].
+
+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.
+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 {{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.
+
+### Color Write State ### {#color-write}
+
+- {{GPUColorWriteState/outputs}} describes
+ the color outputs that are written by the [=pipeline=].
+- {{GPUColorWriteState/alphaToCoverageEnabled}} enables the [[#alpha-to-coverage]] mode.
+
+
+ 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|.{{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 {{GPUTextureUsage/RENDER_ATTACHMENT}} capability.
+ - If the output `SV_Coverage` semantics is [=statically used=] by |fragmentStage|:
+ - |descriptor|.{{GPUColorWriteState/alphaToCoverageEnabled}} is `false`.
+ - If |fragmentStage| is `null`:
+ - |descriptor|.{{GPUColorWriteState/outputs}} is empty.
+ - |descriptor|.{{GPUColorWriteState/outputs}}.length is less than
+ or equal to 4.
+
+
+#### No Color Output #### {#no-color-output}
+
+In no-color-output mode, [=pipeline=] does not produce any color attachment outputs,
+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.
+
+#### Alpha to Coverage #### {#alpha-to-coverage}
+
+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 {{GPUColorWriteState/outputs}}[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 Output State #### {#color-output-state}
+
+
- validating GPUColorStateDescriptor(descriptor, fragmentStage)
+ validating GPUColorOutputState(descriptor)
**Arguments:**
- - {{GPUColorStateDescriptor}} |descriptor|
- - {{GPUProgrammableStageDescriptor}} |fragmentStage|
+ - {{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.
- - |fragmentStage| contains an output variable with a type that is compatible with
- |descriptor|.{{GPUColorStateDescriptor/format}}.
+ - |descriptor|.{{GPUColorOutputState/writeMask}} is less than 16.
### 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?
### Vertex State ### {#vertex-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 format |
- Primitive 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
@@ -4231,35 +4267,34 @@ 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}}.
-Every location must be unique within the {{GPUVertexStateDescriptor}}.
+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|
- - {{GPUProgrammableStageDescriptor}} |vertexStage|
+ - {{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. For every vertex attribute in the shader reflection of |vertexStage|.{{GPUProgrammableStageDescriptor/module}}
- that is know to be [=statically used=] by |vertexStage|.{{GPUProgrammableStageDescriptor/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}}.
+ 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|.{{GPUVertexBufferLayout/attributes}} that:
+ 1. The shader format is |at|.{{GPUVertexAttribute/format}}.
+ 2. The shader location is |at|.{{GPUVertexAttribute/shaderLocation}}.
- validating GPUVertexStateDescriptor(descriptor, vertexStage)
+ validating GPUVertexInputState(descriptor, vertexStage)
**Arguments:**
- - {{GPUVertexStateDescriptor}} |descriptor|
- - {{GPUProgrammableStageDescriptor}} |vertexStage|
+ - {{GPUVertexInputState}} |descriptor|
+ - {{GPUProgrammableStage}} |vertexStage|
Return `true`, if and only if, all of the following conditions are satisfied:
- 1. |descriptor|.{{GPUVertexStateDescriptor/vertexBuffers}}.length is less than or equal to
+ 1. |descriptor|.{{GPUVertexInputState/vertexBuffers}}.length is less than or equal to
{{GPULimits/maxVertexBuffers|GPULimits.maxVertexBuffers}}
- 1. Each |vertexBuffer| layout descriptor in the list |descriptor|.{{GPUVertexStateDescriptor/vertexBuffers}}
- passes [$validating GPUVertexBufferLayoutDescriptor$](|vertexBuffer|, |vertexStage|)
- 1. The sum of |vertexBuffer|.{{GPUVertexBufferLayoutDescriptor/attributes}}.length,
- over every |vertexBuffer| in |descriptor|.{{GPUVertexStateDescriptor/vertexBuffers}},
+ 1. Each |vertexBuffer| layout descriptor in the list |descriptor|.{{GPUVertexInputState/vertexBuffers}}
+ 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}}
- across |descriptor|.{{GPUVertexStateDescriptor/vertexBuffers}} has a distinct
- |at|.{{GPUVertexAttributeDescriptor/shaderLocation}} value.
+ 1. Each |at| in the union of all {{GPUVertexAttribute}}
+ across |descriptor|.{{GPUVertexInputState/vertexBuffers}} has a distinct
+ |at|.{{GPUVertexAttribute/shaderLocation}} value.
# Command Buffers # {#command-buffers}
@@ -6200,7 +6235,7 @@ enum GPUStoreOp {
- Let |pipelineDescriptor| be |encoder|.{{GPURenderEncoderBase/[[pipeline]]}}.{{GPURenderPipeline/[[descriptor]]}}.
- For each {{GPUIndex32}} |slot| `0` to
- |pipelineDescriptor|.{{GPURenderPipelineDescriptor/vertexState}}.{{GPUVertexStateDescriptor/vertexBuffers}}.length:
+ |pipelineDescriptor|.{{GPURenderPipelineDescriptor/vertexInput}}.{{GPUVertexInputState/vertexBuffers}}.length:
- |encoder|.{{GPURenderEncoderBase/[[vertex_buffers]]}}[|slot|] must not be `null`.
@@ -7123,7 +7158,7 @@ typedef [EnforceRange] long GPUSignedOffset32;
typedef unsigned long GPUFlagsConstant;
-## Colors & Vectors ## {#colors-and-vectors}
+## Colors & Vectors ## {#outputs-and-vectors}
|