Skip to content
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

Adjust fragment state blend factor and write mask validation #3217

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/webgpu/api/validation/render_pipeline/fragment_state.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ g.test('pipeline_output_targets')
g.test('pipeline_output_targets,blend')
.desc(
`On top of requirements from pipeline_output_targets, when blending is enabled and alpha channel is read indicated by any blend factor, an extra requirement is added:
- fragment output must be vec4.
- fragment output must have an alpha channel (i.e. it must be vec4), otherwise writeMask must be 0.
`
)
.params(u =>
Expand All @@ -382,6 +382,14 @@ g.test('pipeline_output_targets,blend')
...u.combine('alphaSrcFactor', kBlendFactors),
...u.combine('alphaDstFactor', kBlendFactors),
] as const)
.expand('writeMask', function* (p) {
yield 0;
for (let i = 0; i < p.componentCount; i++) {
yield 1 << i;
}
// default full mask
yield 0xf;
})
)
.beforeAllSubcases(t => {
const { format } = t.params;
Expand All @@ -398,6 +406,7 @@ g.test('pipeline_output_targets,blend')
colorDstFactor,
alphaSrcFactor,
alphaDstFactor,
writeMask,
} = t.params;
const info = kTextureFormatInfo[format];

Expand All @@ -409,6 +418,7 @@ g.test('pipeline_output_targets,blend')
color: { srcFactor: colorSrcFactor, dstFactor: colorDstFactor },
alpha: { srcFactor: alphaSrcFactor, dstFactor: alphaDstFactor },
},
writeMask,
},
],
fragmentShaderCode: getFragmentShaderCodeWithOutput([
Expand All @@ -422,6 +432,6 @@ g.test('pipeline_output_targets,blend')
const _success =
info.color.type === sampleType &&
componentCount >= kTexelRepresentationInfo[format].componentOrder.length &&
meetsExtraBlendingRequirement;
(meetsExtraBlendingRequirement || writeMask === 0);
Copy link
Collaborator

@kainino0x kainino0x Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I just reread the spec and I think I misinterpreted this the other day.
IIUC actually the only case where writeMask=0 makes it valid is when the fragment shader has no output to that location. If it has output to that location, then the writeMask isn't checked by the validation in the spec.
https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-gpufragmentstate

I do believe we could loosen the validation in the way that you've done here, but it would require a spec change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are right. The "Otherwise..." is at the same level as

"If get the entry point(FRAGMENT, descriptor) has a shader stage output value output with location attribute equal to index:"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do believe we could loosen the validation in the way that you've done here, but it would require a spec change.

For reference the spec issue was gpuweb/gpuweb#2013

t.doCreateRenderPipelineTest(isAsync, _success, descriptor);
});