-
Notifications
You must be signed in to change notification settings - Fork 344
Description
This is spawned from #889, related to #644
The issue is split into 3 sections: problem statement, investigation, and proposal. Please consider these parts to be separate when reviewing.
Problem
Main question is, what can we validate at createShaderModule ("compiling"), and what should we put in the spec, versus what we validate at createXxxPipeline ("linking").
The question has 2 sides:
- where/when the validation happens (i.e. "compiling" vs "linking")
- what is validated (do we allow bad entry points that aren't used?)
Investigation
I can think of splitting all the shader work in 3 stages.
(1) Things we can do at compilation for the module as a whole:
- parsing the module
- syntax checks, tokenization, reserved words, etc
- type checking all variables, constants, and functions in the module
- this includes things like calling
texture_sample([wgsl] Adding textures to the spec. #909) with wrong number of texture coordinates
- this includes things like calling
(2) Things we can do at compilation for any function:
- check if it's (statically) recursive
- determine if calling it breaks uniformity of the context (e.g. it discards pixels)
- determine if it expects the context to be uniform (e.g. it samples from a texture with an implicit LOD)
- figure out the interface: all inputs, outputs, samplers, uniform and storage resources, that the function statically uses
- figure out what device features does a function require
For entry points specifically, we can detect binding collisions (#889) here.
(3) Things that we have to do at link time:
- check for required device features
- match the interface between programmable stages (Interface matching rules #644), e.g. varyings
- match the interface with fixed-function hardware. This includes vertex attributes, output colors, multisampling, etc
- match the binding with the pipeline layout
- generate platform-dependent shader code. This stage should expect no errors, with an exception of unforeseen things, like the driver refusing to link a program that uses too many registers.
Proposal
We should check for shader validity early (i.e. (1) and (2) at shader compilation time), and report errors eagerly. Letting invalid code to be dead weight is only going to serve as a footgun, and I don't see how this would make our implementors life easier either.
The only things we have to validate at linking (e.g. createRenderPipeline) are basically interface matching rules, plus device features.
Whether or not we allow the implementations to defer the work to linking is something we can compromise on. However, forcing the implementations to be silent at shader compilation time is something I feel strongly against.