You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Image store parameters are invalid - Not a global variable #522
naga /../shader/path.spv (or use it in bevy_render)
I'm using rust-gpu main branch, spirv-unknown-vulkan1.4 as a target in build.rs, but the error is the same for any target as far as I can tell.
Not sure if bevy reproduction set up is needed, as it fails with same error naga validation does. Something makes me think it is related to incorrect spv gen
System Info
Rust: rustc 1.90.0-nightly (35f603652 2025-06-29)
OS: NixOS
GPU: AMD Radeon 890M
SPIR-V: SPIRV-Tools v2025.5 unknown hash
Backtrace
[2026-02-03T15:08:12Z INFO naga::front::spv] Generated by 983040 version 10600
[2026-02-03T15:08:12Z INFO naga::front::spv] Patching...
Function [0] '' is invalid:
Image store parameters are invalid
Not a global variable
Since spirv-val succeeds, it's more likely that naga is just failing to parse that spirv. Which is not surprising, there's quite a lot of spirv naga can't parse. (See pipelines in #493 failing cause naga can't understand some spirv)
You can try to use type=f32 instead of format = rgba32f, like in this alias?
Thanks for the fast response! I guess in bevy case (it uses naga) I should compile it to something naga understands. Using unknown format for texture and setting capabilities yields the same result (with couple of warnings about unrecognized caps):
[2026-02-03T15:36:47Z INFO naga::front::spv] Generated by 983040 version 10600
[2026-02-03T15:36:47Z WARN naga::front::spv] Unknown capability StorageImageReadWithoutFormat
[2026-02-03T15:36:47Z WARN naga::front::spv] Unknown capability StorageImageWriteWithoutFormat
[2026-02-03T15:36:47Z INFO naga::front::spv] Patching...
Function [0] '' is invalid:
Image store parameters are invalid
Not a global variable
Just double checked our compiletest, and while we have one that passes for texel fetches (just make sure to fetch with a lod level, don't use fetch until #490 is merged), none of the image write tests do actually pass for one reason or another. All of my use-cases with naga transpilation to wgsl were only fragment shaders, so never had to write texels either.
While I generally agree that this is technically a naga problem of not parsing valid spirv, I also like to look at the spirv we're emitting vs spirv emitted by glslc, to figure out what weird thing we're doing that may be breaking naga. And indeed, we are kinda weird.
Here I've transpiled the output of a compiletest just writing an image to glsl with spirv-cross -V:
First, it'll fail to compile cause our image is both read_only and write_only. Removing read_only, you'll notice that our imageStore does indeed not operate on a global variable but on a parameter passed to the function. If we inline that function call, it works.
So yea... the fix is to add #[inline] to all the image instrinsics on our side: #523
This is valid glsl according to glslc and spirv-val, but uses the OpCapability StorageImageWriteWithoutFormat which is not yet supported by naga.
Usually we can get rid of that capability by adding layout(..., rgba32f) to the image uniform declaration. If we manually inline the indirection function, it will also get rid of that capability. But due to that function passing an image without explicit format, the capability stays.
Now you say let's just add layout(rgba32f) to the paramter, but
image_write_fail.comp:11: error: '' : cannot use layout qualifiers on a function parameter
So you can't even declare images in function parameters to have an explicit image layout.
Even worse, the emitted spv is invalid, and glslc doesn't even verify it's own output:
error: line 71: OpFunctionCall Argument <id> '25[%image_0]'s type does not match Function <id> '8[%_ptr_UniformConstant_7]'s parameter type.
%43 = OpFunctionCall %void %indirection_I21_vi2_vf4_ %image_0 %param %param_0
So I can't even write glsl that generates spv similar to what we generate.
Activity
Firestar99 commentedon Feb 3, 2026
Since
spirv-valsucceeds, it's more likely that naga is just failing to parse that spirv. Which is not surprising, there's quite a lot of spirv naga can't parse. (See pipelines in #493 failing cause naga can't understand some spirv)You can try to use
type=f32instead offormat = rgba32f, like in this alias?rust-gpu/crates/spirv-std/src/image.rs
Line 68 in ba15d4c
You may also need these extra capabilities, set them via
SpirvBuilder.capability:pyranota commentedon Feb 3, 2026
Thanks for the fast response! I guess in
bevycase (it usesnaga) I should compile it to something naga understands. Using unknown format for texture and setting capabilities yields the same result (with couple of warnings about unrecognized caps):Firestar99 commentedon Feb 3, 2026
Just double checked our compiletest, and while we have one that passes for texel fetches (just make sure to fetch with a lod level, don't use
fetchuntil #490 is merged), none of the image write tests do actually pass for one reason or another. All of my use-cases with naga transpilation to wgsl were only fragment shaders, so never had to write texels either.pyranota commentedon Feb 3, 2026
Can confirm it has exactly the same error here: https://github.com/Rust-GPU/rust-gpu/actions/runs/20504878075/job/58917828710?pr=493#step:6:3598
I wonder if it's
nagas responsibility, as rust-gpu emits valid spir-v and naga strays to have first class support for it?LegNeato commentedon Feb 4, 2026
It does indeed sound like a
nagaissue..file one and link it here and we'll discuss?Firestar99 commentedon Feb 4, 2026
While I generally agree that this is technically a naga problem of not parsing valid spirv, I also like to look at the spirv we're emitting vs spirv emitted by glslc, to figure out what weird thing we're doing that may be breaking naga. And indeed, we are kinda weird.
Here I've transpiled the output of a compiletest just writing an image to glsl with
spirv-cross -V:First, it'll fail to compile cause our image is both
read_onlyandwrite_only. Removingread_only, you'll notice that ourimageStoredoes indeed not operate on a global variable but on a parameter passed to the function. If we inline that function call, it works.So yea... the fix is to add
#[inline]to all the image instrinsics on our side: #523Firestar99 commentedon Feb 4, 2026
Did some more digging to potentially file a naga bug report (probably won't) by translating it to glsl:
This is valid glsl according to
glslcandspirv-val, but uses theOpCapability StorageImageWriteWithoutFormatwhich is not yet supported by naga.Usually we can get rid of that capability by adding
layout(..., rgba32f)to the image uniform declaration. If we manually inline theindirectionfunction, it will also get rid of that capability. But due to that function passing an image without explicit format, the capability stays.Now you say let's just add
layout(rgba32f)to the paramter, butSo you can't even declare images in function parameters to have an explicit image layout.
Even worse, the emitted spv is invalid, and glslc doesn't even verify it's own output:
So I can't even write glsl that generates spv similar to what we generate.
pyranota commentedon Feb 8, 2026
Thank you @Firestar99 for looking into this!