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
RGBAsrc1
+ RGBAdst
(0, 0, 0, 0)
+ (1, 1, 1, 1)
@@ -8490,6 +8522,19 @@ enum GPUBlendFactor {
(1 - Rconst, 1 - Gconst, 1 - Bconst, 1 - Aconst)
+ (Rsrc1, Gsrc1, Bsrc1, Asrc1)
+ (1 - Rsrc1, 1 - Gsrc1, 1 - Bsrc1, 1 - Asrc1)
+ (Asrc1, Asrc1, Asrc1, Asrc1)
+ (1 - Asrc1, 1 - Asrc1, 1 - Asrc1, 1 - Asrc1)
+path: syntax/blend_src_attr.syntax.bs.include ++ +
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`. + + |
@@ -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 @@ + 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=]