I am in the process of writing a binary processing module for SPIR-V shaders to fix alignment issues with float4x3[6] matrices because of driver bugs. Right now i have:
- injected necessary appropriate OpTypes and OpTypePointers.
- processed the binary to change constant buffer members from float4x3[6] to vec4[18]
- injected function properly unpacking vec4[18] into float4x3[6] accepting vec4[18] as a pointer to Uniform array 18.
- created Private storage qualifier matrix unpack targets as OpVariables.(Private in SPIR-V just means invocation-level global...).
- injected preambles about composite extraction and construction to call my new function. (since from what im seeing we need to copy arguments from constant buffers to functions always, so thats what I do).
- called the function from entrypoint, for every float4x3[6] member to have ready unpacked matrices when main() starts.
- changed OpAccessChain operations that referenced given members in constant buffers and swapped them with access chains referencing my new Private targets.
But now i ran into trouble. It looks like a function in SPIR-V can either accept Private or Function storage qualifier pointers. Not both. Is there any way i can tell SPIR-V "Yeah, you can dump both of those storage classes here as arguments"?
Or do i need to rework my solution to utilize Function storage class matrix targets, and inject them and calls to unpack them every single time they are used in a new function? This seems much less elegant since there might be way more unpack operations then. And much less hassle-free, since i would have to scan every OpFunction block separately and inject OpVariables with Function storage into every block that uses the matrices.
My problem is, after all this machinery is done my targets are living as OpTypePointer of Private Storage Duration. Therefore i cannot use them in ANY SPIR-V function generated from HLSL, since they take OpTypePointers of Function duration. My unpack function is sole exception to this since i injected it directly in SPIR-V asm, byte by byte and was able to precisely tune OpFunctionParameters in header.