Use 64bit pointers for global/constant/local memory
This series switches the compile target for CLC to spir64 instead of spir. That enables the language to understand that our pointers (for global/constant/local memory at least so far) are 64bit, meaning sizeof()
and friends work as expected. Global and constant pointers are then converted to 64bit (buffer ID << 32 | buffer offset) values, which are decomposed by nir_lower_explicit_io
. References to inline __local variables are converted to 32bit offsets, which are extended to 64bit for storage. All pointer ops are done directly on the 32bit values, which allows the optimizer to remove 64bit references most of the time, unless the 64bit value is really needed.
There's a few lowering passes in here to deal with some things that get promoted to 64bit that shouldn't be, just because 64bit isn't really the native pointer size in DXIL, and we want to avoid 64bit math when we don't need it - so invocation IDs and kernel arg offsets are lowered. There's a lowering pass to convert global
memory to ssbo
memory as well.
All existing clc tests pass after this, though I can write some new tests that hit corner cases (see jenatali/mesa@1decf008 - __private fails to translate).
As part of this change, I've reverted the offset-by-one logic for buffer indices. The "null pointer" constant for 64bit offset/size is considered by vtn to be 0xffffffffffffffff
, so we can use 0
as a valid reference to UAV 0. I've also removed unnecessary DXIL-specific versions of SSBO intrinsics, now that our semantics are really unified with SSBOs.