gpuweb
gpuweb copied to clipboard
Issue with type converting module scoped variables
With the switch to using the type constructor to allow conversions we can do things like vec3<f32>(vec3<i32>(1, 2, 3). This is fine at function scope as we can use the OpConvertSToF SPIR-V operation.
At module scope, this doesn't work. We don't have access to the OpConvertSToF method. I see 2 paths forward:
1- disallow the type conversions at module scope, they are only valid at function scope 2- jump through some hoops to initialize the module scoped variable at the start of the entry point where that variable is used.
A third option is to make the translators from WGSL to other languages do the conversion at "compile" time. This might be more complexity than we want. I don't know if raises floating point consistency/portability issues. I also don't have a good idea of how complex the constant evaluator would have to be.
My preference is option 1. Trying to get matching translations in the compilers seems like a lot of work.
What would this even look like "conversion at the module scope"?
You could see doing something like the following in the constants-and-globals section of SPIR-V:
%ivec2value = OpConstantComposite %v2int %int_0 %int_1
%converted = OpSpecConstantOp %v2float ConvertSToF %ivec2value
That works in Kernel SPIR-V (for OpenCL), but does not in Shader SPIR-V (for Vulkan and OpenGL) because the ConvertSToF sub-opcode is available to OpSpecConstantOp in Kernel but not Shader.
I guess the pattern was set that way because Glslang does the work to do conversions like that in the front end, before generating down to SPIR-V. As in, it does option 3 for GLSL. So it insulates downstream Vulkan drivers from having to do the work, so it doesn't have to show up in SPIR-V.
Other things in the same situation (look at the description of OpSpecConstantOp, in the "If the Kernel...." section):
- Bitcast
- FAdd, FSub, FNegate, FMul, FDiv, FRem, FMod
(The other ones don't apply to WGSL, because of various reasons).
But we've spec'd the const_expr as allowing only very limited abilities: literal, or type-constructor over other const_exprs. So the floating point math doesn't apply.
Resolved: Needs specification work to restrict what const_expr can do.