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
Fragment output <-> attachment interface matching rules def #2013
Comments
FWIW, reading the Vulkan spec I just realized why it's always allowed to output too many components: fragment outputs don't go directly into the attachment, they go to the blending unit. The blending unit may use the output alpha value even if the attachment doesn't have an alpha channel. We need to determine what the blending unit sees in the alpha channel if the shader doesn't output it.
Aside: I found this in the Vulkan spec section you linked:
I guess this means there are technically undefined values if you write outside of the range of a unorm/snorm attachment type. That seems like a pretty minor hazard but I'm surprised by it. |
Oh, finally found the relevant sentence in Vulkan (emphasis added):
|
Injecting shader code is always extra work, and also incompatible with the idea of generating
|
note: I don't think it's incompatible with generating ahead of time. We don't have to pad to the size of the format, we can always pad to vec4 unconditionally. |
Resolution: Add the precise validation rules (option 5, the one kvark described just above) |
Adding to editor agenda to clarify a corner case: what if the format has alpha, but blending is used and the fragment output alpha actually isn't used? |
Editors: That should also be valid. Unless the validation layers complain about that. Buuut then what if the write mask prevents any actual undefined values? Then we should also allow that. Unless the validation layers complain about that. @shrekshao do you have things set up so you could check what the Metal and d3d12 debug layers think about these things? |
With fragment output set to So seems that we don't have to consider write mask state at validation |
Good to know! Could you also check if D3D12 considers the blend factors in its debug layer? |
For blending, at least D3D12 doesn't care if blending is null, or enabled but srcFactor/dstFactor doesn't include
|
Hmm, that seems like there might be a deficiency in the D3D12 debug layer. Am I correct in understanding it allows the following case? Which should be invalid.
In any case, we will make that invalid, because it's undefined according to the Vulkan spec. So I think the rules might be:
Plus whatever is needed for #2025. |
(Sorry I misunderstood here. I tested against attachment format For
D3D12 debug layer (--enable-backend-validation in dawn) let it passed. We should validate this since the alpha channel would be undefined value. The conclusion seems good. |
No misunderstanding, I just thought of this when I read your latest result at the time. :) |
Realized this is wrong, I think it should say
|
reading/thinking about this YET FURTHER, this may also be wrong. If src.alpha is undefined, then multiplying it by zero is still undefined, e.g. if src.alpha was NaN. Unfortunately I can't find a concrete answer to either issue (#2013 or #2025) in the D3D11 functional spec - all language seems to ignore the possibility that the blend factor uses an alpha value that wasn't output by the shader. However I did find some interesting sections that very explicitly call out the use of write masks to protect against undefined results:
https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#OutputWrites
|
Ahh the addition I made to the rules earlier (rule 3) is actually redundant: For any format that has an alpha channel, the shader must output vec4 anyway due to rule 1. (edited) So the first 2 rules in #2013 (comment) were correct, but revising rule 1 here for generality/preciseness: Shader output must:
|
Does the revised rule without rule 3 covers this case: The attachment doesn't actually have an alpha channel, so the So seems the revised rule is correct... |
My mental model from reading the D3D spec is that blending for all 4 channels always runs, what matters is whether undefined values make it into the output. So in this case, the alpha channel blending reads dst=undef, multiplies it with dstFactor=undef, resulting in a final value of undef, but that doesn't get written so it doesn't matter. |
Ohh yes sorry, the revised rules I posted aren't actually the original 2 rules. They are still changed to say "color blend factors" instead of "blend factors" |
What still needs to happen to be able to close this issue? |
I think we figured out what the spec needs to say, so just spec work. |
Right now the WebGPU spec and WGSL spec are vague about the fragment output and attachment interface matching rules.
https://www.w3.org/TR/webgpu/#fragment-state
The rule should have two parts.
f32
,i32
, oru32
) must match the sample type of the format. (Pretty clear).vec4<f32>
<->R8Unorm
f32
<->RGBA8Unorm
✔️(seems happy, pad with 0)Here are some related spec text I found (please help add refs)
We have 2 options here:
colorState.format
. The extra components are discarded. Otherwise there would be a validation error.vec4<T>
, without validating the componentCount.WDYT
The text was updated successfully, but these errors were encountered: