KhronosGroup / KhronosGroup/Vulkan-Docs
[Roadmap Feedback] Function Pointers with some limitations
- Dominant language
- JavaScript
- Stars
- 3.3k
- Forks
- 549
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 2
Description
## Problem statement:
As we all know that many major GPU architectures have been able to perform actual function calls for a while now, and that GPUs which support `KHR_raytracing_pipeline` usually have this feature as its much more efficient to perform a function call/jump based on an address stored in a SBT than to do fully inlined megakernels with `switch` or `if-else` chains/trees to branch into the correct function call.
Now obviously this would have to be subject to certain restrictions such as recursion depth, therefore I'd like to propose function pointers but with certain limitations:
- function pointer used for a call has to be subgroup uniform (for now)
- shader declares the maximum stack size required (so maximum recursion depth), if it does not we default to depth=1 (only one call from the entry point) and stack equal necesasry to call "largest" function out of all reachable (by pointer) functions
- pointers of different function signatures cannot be casted to each other (similar limitations exist in WASM/Mono-WASM as well as strict-C etc., this would enable easy "compatibility" driver implementations using switches or better if-else binary search trees - Metal is actually an example here of a polyfill with a table+dispatcher)
- no pointer arithmetic on the function pointers, only assignments
SPIR-V already has a somewhat nice `SPV_INTEL_function_pointers` extension, but its not for the Vulkan environment.
Vulkan (and by extension OpenCL via clspv) would befit a lot from this being available as Metal and CUDA both have the feature.
EDIT 1: SPIR-V would probably benefit from explicit `OpSpill` and `OpRestore` for Variables the compiler determines to be live across the function pointer call site, such that the implementation's SPIR-V to ISA compiler doesn't need to perform it (it could, just to validate or optimize). This could benefit Raytracing Callables and Workgraphs too, especially the latter as its still an `AMDX` and I feel like live variable analysis could go a long way towards making a nice `KHR` or `EXT` version.
EDIT 2: Could `OpLifetimeStart` and `OpLifetimeEnd` be used for the same purpose if allowed in `Shader` environment and not only `Kernel`?
## Use Case Example(s):
Something like this in GLSL
```cpp
void doA();
void doB();
...
void(*)(void) p = cond ? doA:doB;
p();
```
If we support non-uniform function calls then
```cpp
nonuniformEXT(p)();
```
## (Optional) Suggested Solution(s) (via opening an MR on vulkan-docs repo and creating a Proposal Document) :
Allow functions in SPIR-V subject to the restrictions outlined above to be able to have their addresses taken and stored in a Pointer Function Storage class or a new Function Pointer type.
I can see 3 fields in the extension properties struct:
- maxStackSize, 0 would mean you can only do tail-calls, basically as part of `return` or as the last instruction in a void function
- returnAddressSize, this tells you how many bytes are needed just in order to be able to non-tail recurse without any arguments
- [optional] nonUniformFunctionPointerCallNative, would tell you whether the device has an Independent Program Counter and doesn't need to waterfall strip your calls
If this issue gets any traction I'll open the PR so CLA is signed.
An interesting read:
https://xol.io/blah/gpus-function-calls/
Contributor guide
Research direction
Start with proposals/Roadmap.adoc and proposals/template.adoc, then compare the requested restrictions with SPV_INTEL_function_pointers. Review the Vulkan Docs proposal process before deciding whether the feature belongs in a new proposal. Done means a concrete, signed proposal defining the SPIR-V and Vulkan changes.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, compilers, computer-graphics
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100