Skip to content

entry point fn with too many params fails #608

Open

Description

@galop1n

I am trying to convert a project of mine from wgsl to rust-gpu. I got the basics done, but I have a shader I can't get to compile

This is the entry point

#[spirv(compute(threads(8, 8, 1)))]
pub fn cs_main(
    #[spirv(global_invocation_id)] gid: UVec3,
    #[spirv(uniform, descriptor_set = 1, binding = 0)] globals: &SBGlobalData,
    #[spirv(uniform, descriptor_set = 2, binding = 0)] camera: &SBCameraData,
    #[spirv(storage_buffer, descriptor_set = 3, binding = 0)] tlas_nodes: &[BvhNode],
    #[spirv(storage_buffer, descriptor_set = 3, binding = 1)] tlas_instances: &[TlasInstance],
    #[spirv(storage_buffer, descriptor_set = 3, binding = 2)] blas_nodes: &[BvhNode],
    #[spirv(storage_buffer, descriptor_set = 3, binding = 3)] blas_tris: &[Triangle],
    #[spirv(descriptor_set = 3, binding = 4)] rt_out: &Image!(2D, format = rgba16f, sampled = false, arrayed = false, multisampled = false),
    #[spirv(uniform, descriptor_set = 3, binding = 5)] rt_consts: &RaytracerConsts,
    #[spirv(uniform, descriptor_set = 3, binding = 6)] mat_consts: &RtLightConsts,
    #[spirv(storage_buffer, descriptor_set = 3, binding = 7)] rt_materials: &[RtMaterialEntry],
    #[spirv(descriptor_set = 3, binding = 8)] albedo_sampler: &Sampler,
    #[spirv(descriptor_set = 4, binding = 0)] albedo_tex_table: &RuntimeArray<Image!(2D, type = f32, sampled = true, arrayed = false, multisampled = false)>,
) {

Expected Behaviour

Shader compiles fine

Example & Steps To Reproduce

This is the errors I am getting

info: latest update on 2026-04-11 for version 1.96.0-nightly (02c7f9bec 2026-04-10)
info: component rust-src is up to date
warn: skipping unavailable component rust-std for target spirv-unknown-vulkan1.2
   Compiling shader-bench-rsgpu-user v0.1.0 (F:\rust\ideas\shader-bench\projects\raytracer-rs\.shader-bench\shader-cache\rust-gpu-build\ce910f26f4188d71)
warning: an unknown error occurred
  |
  = note: spirv-opt failed, leaving as unoptimized
error: [VUID-StandaloneSpirv-OpTypeRuntimeArray-04680] OpVariable, <id> '14[%albedo_tex_table]', is attempting to create memory for an illegal type, OpTypeRuntimeArray.

For Vulkan OpTypeRuntimeArray can only appear as the final member of an OpTypeStruct, thus cannot be instantiated via OpVariable
         %albedo_tex_table = OpVariable %_ptr_UniformConstant__runtimearr_94 UniformConstant

Bonus: u32.saturated_sub is not implemented btw

System Info

Windows + custom compiler wrap to compile rust-gpu shader at runtime without having my whole workspace on the specific nightly toolchain

Activity

  1. Firestar99 commented on Jun 3, 2026

    @Firestar99
    Member

    For Vulkan OpTypeRuntimeArray can only appear as the final member of an OpTypeStruct, thus cannot be instantiated via OpVariable

    So usually this is indicative of you declaring a struct containing a slice or RuntimeArray, which we currently don't properly support for silly reasons. Now I don't believe based on your screenshot in discord that you're doing that.

    I've seen rustc rewriting function ABI from passing each argument individually to putting all arguments into a struct and changing the function ABI to just passing a ptr to that struct, when a function has a lot of arguments. I suspect this is happening to your entry point function, which I haven't seen happen yet. Unfortunately this won't be an easy fix...

    Some months ago I've been investigating using inline assembly for declaring inputs, outputs, built-ins and storage buffer declarations, which are an alternative way to declare entry points and shouldn't suffer from function ABI limitations. I want to eventually make a new entry point systen to use inline asm like that, but haven't gotten around to finishing it off.

  2. changed the title [-](my bug report)[/-] [+]entry point fn with too many params fails[/+] on Jun 3, 2026
  3. galop1n commented on Jun 3, 2026

    @galop1n
    Author

    I can close the bug for now, I found a fix! I needed to set Capability::RuntimeDescriptorArray on the spirv build object. Coming from HLSL+PSSL shader compilers. I find very unintuitive and cumbersome that you have to set dozens of flags for every single little GPU feature your shader may use ! Be it with NAGA/WGSL or now rust-gpu !

    Is there a reason for it to be so granular, rather than let's say, a more general feature tier. Example, in HLSL you build for a given shader model, like 6.7, and you get all it encompass. Most features been mandatory for that tier, and optional feature uses just set flags in the reflection data you can compare to your device capabilities ( ex: u64 atomic )

  4. Firestar99 commented on Jun 4, 2026

    @Firestar99
    Member

    The SPIR-V grammar is sufficiently detailed that you can even resolve the features you need to enable from the instructions and operands you use. Which will hopefully be a thing eventually, see #388

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions