Skip to content

Conversation

@Firestar99
Copy link
Member

This is a prototype for adding functions within spirv_std to query SPIR-V builtin read-only global variables. This is the very first part of #449.

Currently, the prototype in this PR adds the function spirv_std::builtin::compute::local_invocation_id() -> UVec3 to query the local_invocation_id without having to pass it through from the entry point declaration. Interestingly, the linker infrastructure for this to work was already in place for other reasons (dynamically adding OpVariables during codegen), so this PR just needs to adds the function with the correct inline assembly.

More functions to come.

@nazar-pc
Copy link
Contributor

nazar-pc commented Nov 3, 2025

Will using such functions instead of arguments mean lower register usage overall, or how do those things interact with each other across function calls?

@Firestar99
Copy link
Member Author

It emits semantically the same spirv code as previously: define a builtin global variable and read it. Just that you can now do this anywhere in your codebase, rather than having to pass it down from the entry point and have to hope noone accidentally passes the wrong thing.
Register usage heavily depends on the target platform. See AMD RDNA3 ISA pdf on "3.5. Initial Wave State", there you'll see compute shaders use 4 scalar registers (SGPR, once per workgroup) for workgroup_id plus some bitflags. For local_invocation_id they seem to have been changes in RDNA3, it seems like it only uses 1 vector register (VGPR, once per invocation / thread) now (even though the table in the pdf defines it for GS (eg. mesh shaders) not CS, I assume it's the same), whereas RDNA2 used 3 VGPRs, one for each axis (see "3.12.2. SGPR Initialization").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants