Allow constant references (to constant data), when they're valid SPIR-V.#586
Allow constant references (to constant data), when they're valid SPIR-V.#586eddyb merged 5 commits intoEmbarkStudios:mainfrom LykenSol:const-data
Conversation
khyperia
left a comment
There was a problem hiding this comment.
what the fuck
[OpVariable instruction spec]: Initializer is optional. If Initializer is present, it will be the initial value of the variable’s memory content. Initializer must be an from a constant instruction or a global (module scope) OpVariable instruction.
| self.constant_composite( | ||
| ty.clone().def(self.span(), self), | ||
| vec![elem_pat; count as usize], | ||
| iter::repeat(elem_pat).take(count as usize), |
| // FIXME(eddyb) materialize this at runtime, using | ||
| // `OpCompositeConstruct` (transitively, i.e. after | ||
| // putting every field through `SpirvValue::def`), | ||
| // if we have a `Builder` to do that in. |
There was a problem hiding this comment.
yeah gosh, this would be nice, been dreaming about this possibility for ages, haha - seems like with this system, we're actually kind of close to being able to do so
| Ok(()) | ||
| } | ||
| SpirvConst::Undef => { | ||
| // FIXME(eddyb) check that the type supports `OpUndef`. |
There was a problem hiding this comment.
Just curious, are there any types that cannot be made by OpUndef? Intuitively, there absolutely should be, but I don't think the spec actually mentions anything.
| // Bidirectional maps between `SpirvConst` and the ID of the defined global | ||
| // (e.g. `OpConstant...`) instruction. | ||
| // NOTE(eddyb) both maps have `WithConstLegality` around their keys, which | ||
| // allows getting that legality information without additional lookups. |
There was a problem hiding this comment.
nit: around their values?
This is trickier than it should reasonably be, because of some SPIR-V limitations.
A constant like
&&123is valid in SPIR-V and generates something like this (types omitted for brevity):But a constant like
&(&1, &2)isn't - its SPIR-V would have to be this, which doesn't pass validation:The problem isn't even
%ref_pair, but%pairitself:OpConstantCompositemust haveOpConstant...fields, but not (global, i.e. module-scoped)OpVariablefields (even if the storage class isPrivate).This is pretty bizarre IMO, and I'm not 100% convinced it's intentional - it's possible the first case (with the nested
OpVariables) was never meant to be legal either.Regardless of whether the rules make sense or not, this PR accounts for them, and you can see in the UI tests some simple examples what is allowed and what isn't (the
==examples were the original motivation for this PR).I've even tested that adding multiple extraneous references to the color constants in
mouse-shaderstill works, but I suspect the loads get constant-folded anyway, so it's not much of a test.