-
Notifications
You must be signed in to change notification settings - Fork 303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add optional feature dual_source_blending #4621
base: main
Are you sure you want to change the base?
Conversation
Previews, as seen when this build job started (0f7d944): |
wgsl/index.bs
Outdated
inputs to the blend equation. By default the value of the [=attribute/blend_src=] attribute for a | ||
[=fragment=] shader [=user-defined output datum|output=] is `0` when the [=attribute/blend_src=] | ||
attribute is not specified in the shader. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there value to having this default? Is there some code generation concern that makes this desirable? It seems like it would be clearer to not have it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I just refer the statement in
- Metal (Page 109): If
index(i)
is not specified in the attribute, the default is an index of 0 - Vulkan: variables declared without an Index decoration are considered to have an
Index
decoration of zero
Setting a default value can also make us be able to avoid saying something like The [=blend_src=] attribute of |output| is omitted or 0
(we can directly say The [=blend_src=] attribute of |output| is 0
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm misunderstanding how this is used. Here is my understanding, please correct me if it's wrong.
- Non-dual source blending shader
- Same as today. No new attributes, just location on outputs.
- Don't think about
blend_src
at all
- Dual source blending shader
blend_src(1)
must be specified on output location 0- The must only be two outputs at location 0
- Therefore, omitting
blend_src(0)
is saving a bit of typing, but resulting is less clarity
Is there a case where you could specify blend_src(0)
, but not blend_src(1)
? If not then the only other reason I could see for the default would be to aid code generation, but I'm having trouble envisioning that scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your explanation and now I fully understand your meaning. I think you are right and I agree with you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if we decide to omit blend_src(0)
, then I think we can just use blend_src1
instead of the pattern blend_src1(num)
. The shader will look like:
struct FragOut {
@location(0) color : vec4<f32>,
@location(0) @blend_src1 blend : vec4<f32>,
}
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@blend_src1
seems a lot less consistent with the rest of WGSL. @blend_src(1)
matches up with the @location(0)
much nicer. It also means we can have other blend numbers if the need ever arose in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the default value of blend_src
. PTAL, thanks!
wgsl/index.bs
Outdated
@@ -9397,6 +9437,15 @@ Locations [=shader-creation error|must not=] overlap within each of the followin | |||
* 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. | |||
|
|||
When [=attribute/blend_src=] attribute is specified: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs reworked. Above we stated that locations must not overlap in a structure. Maybe add to the structure bullet "unless the blend_source attribute is specified".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I try to fix this issue by specifying a location
with either a [=attribute/location=]
or both [=attribute/location=]
and [=attribute/blend_src=]
. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still some issues in the validation algorithm; it was too complicated to try to explain what should be done so I've pushed a commit. Please review my changes!
Thanks @kainino0x and @alan-baker ! I've merged the main branch into the PR and fixed several nits in Kai's comment. PTAL ,thanks! |
Thanks for the fixes! API text LGTM (except that I wrote part of it) but I haven't checked if it matches the validation in the backends. Will need tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One request for the WebGPU spec, but overall it's looking good! I'm not in a good position to evaluate the WGSL spec changes.
Thanks for adding the feature column to the blend factor table! LGTM, though I'll wait for someone on the WGSL spec side to give final approval. |
GPU Web WG 2024-05-08 Pacific-time
|
WGSL 2024-05-14 Minutes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The attribute just needs reordered in the overall list, but otherwise LGTM.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WGSL changes LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API spec LGTM. Not sure about WGSL spec though
wgsl/index.bs
Outdated
|
||
For each set of outputs |outputs| in 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. | ||
|
||
The following [=shader-creation error|must=] be `true`: | ||
- |outputs| [=shader-creation error|must not=] contain two outputs with the same location and without a given [=attribute/blend_src=] attribute. | ||
- If any output in |outputs| specifies a [=attribute/blend_src=] attribute: | ||
|outputs| must contain exactly 2 outputs, one with `@location(0) @blend_src(0)` and one with `@location(0) @blend_src(1)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
algorithm
is required to make variables work nicely. Also it's clearer to associate these two paragraphs together.
However, apologies, I'm rereading this (and the text I suggested) and realizing that I totally misunderstood what the second bullet is about - it's about inputs, not outputs. I guess just looking at structs is good enough for outputs (since a struct is the only way to have more than one output of an entry point, currently, I think).
For each set of outputs |outputs| in 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. | |
The following [=shader-creation error|must=] be `true`: | |
- |outputs| [=shader-creation error|must not=] contain two outputs with the same location and without a given [=attribute/blend_src=] attribute. | |
- If any output in |outputs| specifies a [=attribute/blend_src=] attribute: | |
|outputs| must contain exactly 2 outputs, one with `@location(0) @blend_src(0)` and one with `@location(0) @blend_src(1)`. | |
<div algorithm="locations in entry point inputs"> | |
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. | |
</div> | |
<div algorithm="locations in structs"> | |
For each structure type defined in a WGSL module (not just those used in shader stage inputs or outputs), | |
let |members| be the set of struct members with [=attribute/location=] attributes. | |
- |members| [=shader-creation error|must not=] contain two entries without [=attribute/blend_src=] | |
attributes that have the same with the same [=attribute/location=] value. | |
- 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)`. | |
</div> |
@alan-baker WDYT, does this seem correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would be better flipping the structs algorithm bullets ordering:
- If any entry in |members| specifies a blend src attribute:
- members must contain exactly two entries ...
- Otherwise, members not contain two entries with the same location value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
As is required by Metal Shading Language: ``` 5.2.3.5 Fragment Function Output Attributes Multiple elements in the fragment function return type that use the same color attachment index for blending needs to be declared with the same data type. ```
@@ -8210,20 +8212,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`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current validation code will check that if the pipeline is expecting dual-source blending, the shader should as well but we should also check that if the shader expects dual-source blending, the pipeline does as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we should also check that if the shader expects dual-source blending, the pipeline does as well.
Actually according to our tests we can write outputs to @blend_src(1)
in shader while on the API side the blend factor doesn't use Src1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was concerned about it because HLSL just reuses SV_Target1
for the 2nd blend src of target 0 (there is no distinction between the blend src and render target index).
But it seems it doesn't matter, it will get ignored either way.
This patch adds
dual_source_blending
to WebGPU and WGSL SPEC.dual_source_blending
as an optional feature in both WebGPU and WGSL.@blend_src
in WGSL whendual_source_blending
is enabled.src1
to WebGPU SPEC.Fixed: #4283