diff --git a/spec/index.bs b/spec/index.bs index 56e4d456f0..4655577668 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -75,6 +75,7 @@ spec: WGSL; urlPrefix: https://gpuweb.github.io/gpuweb/wgsl/# type: dfn text: f16; url: f16 text: location; url: input-output-locations + text: blend_src; url: input-output-locations text: interpolation; url: interpolation text: pipeline-overridable; url: pipeline-overridable text: pipeline constant ID; url: pipeline-constant-id @@ -114,6 +115,7 @@ spec: WGSL; urlPrefix: https://gpuweb.github.io/gpuweb/wgsl/# for: extension text: f16; url: extension-f16 text: clip_distances; url: extension-clip_distances + text: dual_source_blending; url: extension-dual_source_blending type: abstract-op text: SizeOf; url: sizeof spec: Internationalization Glossary; urlPrefix: https://www.w3.org/TR/i18n-glossary/# @@ -8239,20 +8241,30 @@ dictionary GPUFragmentState - [$validating GPUProgrammableStage$]({{GPUShaderStage/FRAGMENT}}, |descriptor|, |layout|) succeeds. - |descriptor|.{{GPUFragmentState/targets}}.length must be ≤ |device|.{{device/[[limits]]}}.{{supported limits/maxColorAttachments}}. + - Let |entryPoint| be [$get the entry point$]({{GPUShaderStage/FRAGMENT}}, |descriptor|). + - Let |usesDualSourceBlending| be `false`. - [=list/For each=] |index| of the [=list/indices=] of |descriptor|.{{GPUFragmentState/targets}} containing a non-`null` value |colorState|: - |colorState|.{{GPUColorTargetState/format}} must be listed in [[#plain-color-formats]] with {{GPUTextureUsage/RENDER_ATTACHMENT}} capability. + - |colorState|.{{GPUColorTargetState/writeMask}} must be < 16. - If |colorState|.{{GPUColorTargetState/blend}} is [=map/exist|provided=]: - The |colorState|.{{GPUColorTargetState/format}} must be [=blendable=]. - |colorState|.{{GPUColorTargetState/blend}}.{{GPUBlendState/color}} must be a [=valid GPUBlendComponent=]. - |colorState|.{{GPUColorTargetState/blend}}.{{GPUBlendState/alpha}} must be a [=valid GPUBlendComponent=]. - - |colorState|.{{GPUColorTargetState/writeMask}} must be < 16. - - If [$get the entry point$]({{GPUShaderStage/FRAGMENT}}, |descriptor|) has a - [=shader stage output=] value |output| with [=location=] attribute equal to |index|: - + - If |colorState|.{{GPUColorTargetState/blend}}.{{GPUBlendState/color}}.{{GPUBlendComponent/srcFactor}} or + |colorState|.{{GPUColorTargetState/blend}}.{{GPUBlendState/color}}.{{GPUBlendComponent/dstFactor}} or + |colorState|.{{GPUColorTargetState/blend}}.{{GPUBlendState/alpha}}.{{GPUBlendComponent/srcFactor}} or + |colorState|.{{GPUColorTargetState/blend}}.{{GPUBlendState/alpha}}.{{GPUBlendComponent/dstFactor}} + uses the second input of the corresponding blending unit (is any of + {{GPUBlendFactor/"src1"}}, {{GPUBlendFactor/"one-minus-src1"}}, + {{GPUBlendFactor/"src1-alpha"}}, {{GPUBlendFactor/"one-minus-src1-alpha"}}), then: + + - Set |usesDualSourceBlending| to `true`. + - For each [=shader stage output=] value |output| with [=location=] attribute equal to |index| + in |entryPoint|: - For each component in |colorState|.{{GPUColorTargetState/format}}, there must be a corresponding component in |output|. (That is, RGBA requires vec4, RGB requires vec3 or vec4, RG requires vec2 or vec3 or vec4.) @@ -8271,12 +8283,20 @@ dictionary GPUFragmentState |colorState|.{{GPUColorTargetState/blend}}.{{GPUBlendState/color}}.{{GPUBlendComponent/srcFactor}} or .{{GPUBlendComponent/dstFactor}} uses the source alpha (is any of {{GPUBlendFactor/"src-alpha"}}, {{GPUBlendFactor/"one-minus-src-alpha"}}, - or {{GPUBlendFactor/"src-alpha-saturated"}}), then: + {{GPUBlendFactor/"src-alpha-saturated"}}, {{GPUBlendFactor/"src1-alpha"}} or + {{GPUBlendFactor/"one-minus-src1-alpha"}}), then: - |output| must have an alpha channel (that is, it must be a vec4). - Otherwise, since there is no shader output for the attachment: - - - |colorState|.{{GPUColorTargetState/writeMask}} must be 0. + - If |colorState|.{{GPUColorTargetState/writeMask}} is not 0: + - |entryPoint| must have a [=shader stage output=] with [=location=] equal to |index| + and [=blend_src=] omitted or equal to 0. + - If |usesDualSourceBlending| is `true`: + - All the [=shader stage output=] values of |entryPoint| must have a [=blend_src=] attribute. + - |descriptor|.{{GPUFragmentState/targets}}.length must be 1. + - Let |colorState| be |descriptor|.{{GPUFragmentState/targets}}[0]. + - If |colorState|.{{GPUColorTargetState/writeMask}} is not 0: + - |entryPoint| must have a [=shader stage output=] with [=location=] equal to 0 + and [=blend_src=] equal to 1. - [$Validating GPUFragmentState's color attachment bytes per sample$](|device|, |descriptor|.{{GPUFragmentState/targets}}) succeeds. @@ -8407,6 +8427,12 @@ location: RGBAsrc Color output by the fragment shader for the color attachment. If the shader doesn't return an alpha channel, src-alpha blend factors cannot be used. + + RGBAsrc1 + Color output by the fragment shader for the color attachment with + "@blend_src" attribute + equal to `1`. + If the shader doesn't return an alpha channel, src1-alpha blend factors cannot be used. RGBAdst Color currently in the color attachment. @@ -8438,6 +8464,10 @@ enum GPUBlendFactor { "src-alpha-saturated", "constant", "one-minus-constant", + "src1", + "one-minus-src1", + "src1-alpha", + "one-minus-src1-alpha", }; @@ -8448,12 +8478,14 @@ enum GPUBlendFactor { GPUBlendFactor Blend factor RGBA components + [=Feature=] "zero" (0, 0, 0, 0) + "one" (1, 1, 1, 1) @@ -8490,6 +8522,19 @@ enum GPUBlendFactor { "one-minus-constant" (1 - Rconst, 1 - Gconst, 1 - Bconst, 1 - Aconst) + + "src1" + (Rsrc1, Gsrc1, Bsrc1, Asrc1) + {{GPUFeatureName/dual-source-blending}} + + "one-minus-src1" + (1 - Rsrc1, 1 - Gsrc1, 1 - Bsrc1, 1 - Asrc1) + + "src1-alpha" + (Asrc1, Asrc1, Asrc1, Asrc1) + + "one-minus-src1-alpha" + (1 - Asrc1, 1 - Asrc1, 1 - Asrc1, 1 - Asrc1) @@ -15620,6 +15665,23 @@ This feature adds the following [=optional API surfaces=]: - New WGSL extensions: - [=extension/clip_distances=] +

`"dual-source-blending"` +

+ +Allows the use of [=blend_src=] in WGSL and simultaneously using both pixel shader outputs +(`@blend_src(0)` and `@blend_src(1)`) as inputs to a blending operation with the single color +attachment at [=location=] `0`. + +This feature adds the following [=optional API surfaces=]: +- Allows the use of the below {{GPUBlendFactor}}s: + - {{GPUBlendFactor/"src1"}} + - {{GPUBlendFactor/"one-minus-src1"}} + - {{GPUBlendFactor/"src1-alpha"}} + - {{GPUBlendFactor/"one-minus-src1-alpha"}} + +- New WGSL extensions: + - [=extension/dual_source_blending=] + # Appendices # {#appendices} ## Texture Format Capabilities ## {#texture-format-caps} diff --git a/wgsl/index.bs b/wgsl/index.bs index 665f9fe400..9d7666b64a 100644 --- a/wgsl/index.bs +++ b/wgsl/index.bs @@ -1335,6 +1335,7 @@ The [=syntax/attribute=] names are: * `'interpolate'` * `'invariant'` * `'location'` +* `'blend_src'` * `'must_use'` * `'size'` * `'vertex'` @@ -1758,6 +1759,10 @@ The valid [=enable-extensions=] are listed in the following table. The built-in variable [=built-in values/clip_distances=] is valid to use in the WGSL module. Otherwise, using [=built-in values/clip_distances=] will result in a [=shader-creation error=]. + `dual_source_blending` + `"dual_source_blending"` + The attribute [=attribute/blend_src=] is valid to use in the WGSL module. Otherwise, using + [=attribute/blend_src=] will result in a [=shader-creation error=].
@@ -3106,12 +3111,13 @@ The following attributes can be applied to structure members: * [=attribute/align=] * [=attribute/builtin=] * [=attribute/location=] + * [=attribute/blend_src=] * [=attribute/interpolate=] * [=attribute/invariant=] * [=attribute/size=] -Attributes [=attribute/builtin=], [=attribute/location=], [=attribute/interpolate=], and [=attribute/invariant=] -are [=IO attributes=]. +Attributes [=attribute/builtin=], [=attribute/location=], [=attribute/blend_src=], +[=attribute/interpolate=], and [=attribute/invariant=] are [=IO attributes=]. An [=IO attribute=] on a member of a structure *S* has effect only when *S* is used as the type of a [=formal parameter=] or [=return type=] of an [=entry point=]. See [[#stage-inputs-outputs]]. @@ -8020,6 +8026,7 @@ WGSL defines the following attributes that can be applied to function parameters and return types: * [=attribute/builtin=] * [=attribute/location=] + * [=attribute/blend_src=] * [=attribute/interpolate=] * [=attribute/invariant=] @@ -8411,6 +8418,33 @@ path: syntax/binding_attr.syntax.bs.include +## `blend_src` ## {#blend-src-attr} + +
+path: syntax/blend_src_attr.syntax.bs.include
+
+ + + + + +
`blend_src` Attribute
Description + + Specifies a part of the [=fragment=] output when the feature [=extension/dual_source_blending=] + is enabled. + See [[#input-output-locations]]. + + [=shader-creation error|Must=] only be applied to a member of a [=structure=] type with a + [=attribute/location=] attribute. + [=shader-creation error|Must=] only be applied to declarations of objects with [=numeric scalar=] + or [=numeric vector=] type. + [=shader-creation error|Must=] only be used as an output of the [=fragment=] shader stage. + +
Parameters + [=shader-creation error|Must=] be a [=const-expression=] that [=resolves=] to an [=i32=] or [=u32=] with value of `0` or `1`. + +
+ ## `builtin` ## {#builtin-attr}
@@ -8922,6 +8956,7 @@ or to further describe the properties of an input or output.
 The IO attributes are:
 * [=attribute/builtin=]
 * [=attribute/location=]
+* [=attribute/blend_src=]
 * [=attribute/interpolate=]
 * [=attribute/invariant=]
 
@@ -9429,11 +9464,21 @@ Each user-defined [=user-defined input datum|input=] and [=user-defined output d
 Each structure member in the entry point IO [=shader-creation error|must=] be one of either a built-in value
 (see [[#builtin-inputs-outputs]]), or assigned a location.
 
-Locations [=shader-creation error|must not=] overlap within each of the following sets:
-* Members within a structure type.
-    This applies to any structure, not just those used in shader stage inputs or outputs.
-* An entry point's shader stage inputs,
-    i.e. locations for its formal parameters, or for the members of its formal parameters of structure type.
+
+
+ For each entry point defined in a WGSL module, let |inputs| be its set of shader stage inputs + (i.e. locations for its formal parameters, or for the members of its formal parameters of structure type). + - |inputs| [=shader-creation error|must not=] contain two entries with the same [=attribute/location=] value. +
+
+ For each structure type |S| defined in a WGSL module (not just those used in shader stage inputs or outputs), + let |members| be the set of members of |S| that have [=attribute/location=] attributes. + - If any entry in |members| specifies a [=attribute/blend_src=] attribute: + - |members| [=shader-creation error|must=] contain exactly `2` entries, + one with `@location(0) @blend_src(0)` and one with `@location(0) @blend_src(1)`. + - All the |members| [=shader-creation error|must=] have same data type. + - Otherwise, |members| [=shader-creation error|must not=] contain two entries with the same [=attribute/location=] value. +
Note: Location numbering is distinct between inputs and outputs: Location numbers for an entry point's shader stage inputs do not conflict with location numbers for the entry point's shader stage outputs. diff --git a/wgsl/syntax.bnf b/wgsl/syntax.bnf index cfdf33f7e4..42c64a9c15 100644 --- a/wgsl/syntax.bnf +++ b/wgsl/syntax.bnf @@ -109,6 +109,10 @@ binding_attr : '@' 'binding' '(' expression ',' ? ')' ; +blend_src_attr : + '@' 'blend_src' '(' expression ',' ? ')' +; + builtin_attr : '@' 'builtin' '(' builtin_value_name ',' ? ')' ; @@ -184,6 +188,7 @@ attribute : '@' ident_pattern_token argument_expression_list ? | align_attr | binding_attr +| blend_src_attr | builtin_attr | const_attr | diagnostic_attr diff --git a/wgsl/syntax/attribute.syntax.bs.include b/wgsl/syntax/attribute.syntax.bs.include index f920f354b8..044e1b1a4d 100644 --- a/wgsl/syntax/attribute.syntax.bs.include +++ b/wgsl/syntax/attribute.syntax.bs.include @@ -7,6 +7,8 @@ | [=syntax/binding_attr=] + | [=syntax/blend_src_attr=] + | [=syntax/builtin_attr=] | [=syntax/const_attr=] diff --git a/wgsl/syntax/blend_src_attr.syntax.bs.include b/wgsl/syntax/blend_src_attr.syntax.bs.include new file mode 100644 index 0000000000..1a60f36175 --- /dev/null +++ b/wgsl/syntax/blend_src_attr.syntax.bs.include @@ -0,0 +1,5 @@ +
+ blend_src_attr : + + `'@'` `'blend_src'` `'('` [=syntax/expression=] `','` ? `')'` +
diff --git a/wgsl/wgsl.recursive.bs.include b/wgsl/wgsl.recursive.bs.include index 5027ed9b23..d8ffdda1ac 100644 --- a/wgsl/wgsl.recursive.bs.include +++ b/wgsl/wgsl.recursive.bs.include @@ -45,6 +45,8 @@ | `'@'` `'binding'` `'('` [=recursive descent syntax/expression=] `','` ? `')'` + | `'@'` `'blend_src'` `'('` [=recursive descent syntax/expression=] `','` ? `')'` + | `'@'` `'builtin'` `'('` [=syntax/ident_pattern_token=] `','` ? `')'` | `'@'` `'diagnostic'` [=recursive descent syntax/diagnostic_control=]