Compute Shader binding issue

Godot Version

4.5

Question

I am trying to add a new buffer to my compute shader for boids, so i figured i would copy 1 array that was already made and update the binding. When i add the 10th binding in the main gd file, as well as the 10th binding in the file included by the shader, i get this error:

E 0:00:00:780 main.gd:379 @ _run_compute_shader(): Uniforms supplied for set (0):
Set: 0 Binding: 0 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 1 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 2 Type: Image Writable: Y Length: 1
Set: 0 Binding: 3 Type: Image Writable: Y Length: 1
Set: 0 Binding: 4 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 5 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 6 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 7 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 8 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 9 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 10 Type: StorageBuffer Writable: Y Length: 0
are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:
Set: 0 Binding: 0 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 1 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 2 Type: Image Writable: Y Length: 1
Set: 0 Binding: 3 Type: Image Writable: Y Length: 1
Set: 0 Binding: 4 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 5 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 6 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 7 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 8 Type: StorageBuffer Writable: Y Length: 0
Set: 0 Binding: 9 Type: StorageBuffer Writable: Y Length: 0
<C++ Error> Method/function failed.
<C++ Source> servers/rendering/rendering_device.cpp:5313 @ compute_list_dispatch()

What i can see from this is that it “doesn’t see” the 10th binding in the main method. However, when i reduce the bindings to the 9th one, the errors become:

All the shader bindings for the given set must be covered by the uniforms provided. Binding (10), set (0) was not provided. (this is from uniform_set_create())

E 0:00:00:776   main.gd:377 @ _run_compute_shader(): Parameter “uniform_set” is null.
<C++ Source>  servers/rendering/rendering_device.cpp:5221 @ compute_list_bind_uniform_set()

and

E 0:00:00:776   main.gd:378 @ _run_compute_shader(): Uniforms were never supplied for set (0) at the time of drawing, which are required by the pipeline.
<C++ Error>   Method/function failed.
<C++ Source>  servers/rendering/rendering_device.cpp:5310 @ compute_list_dispatch()

3 separate errors. The last thing that i think might be a good pointer is that if i delete the contents of the included file, nothing changes. Both errors persist regardless of the contents of the file OR if the contents are placed directly in the compute shader file.

My main hypotheses are:

  1. Something in the tscn file is not pointing correctly (as was the case for a gdshader file that broke one time)
  2. the included file isn’t being read by a shader. In this script, there are 4 compute shaders being ran, each drawing from the same include file, and aside from the main shader, the other 3 are failing. they all have the same #include line, though…

Let’s see that header and the script code that creates/binds the descriptors.

this?

func _update_boids_gpu(delta):
rd.free_rid(params_buffer)
rd.free_rid(obstacle_buffer)
obstacle_buffer = _generate_obstacle_buffer()
params_buffer = _generate_parameter_buffer(delta)
params_uniform.clear_ids()
params_uniform.add_id(params_buffer)
obstacle_uniform.clear_ids()
obstacle_uniform.add_id(obstacle_buffer)
uniform_set = rd.uniform_set_create(bindings, boid_compute_shader, 0)

_run_compute_shader(bin_sum_pipeline)
rd.sync()
_run_compute_shader(bin_prefix_sum_pipeline)
rd.sync()
_run_compute_shader(bin_reindex_pipeline)
rd.sync()
_run_compute_shader(boid_pipeline)

func _run_compute_shader(pipeline):
var compute_list := rd.compute_list_begin()
rd.compute_list_bind_compute_pipeline(compute_list, pipeline)
rd.compute_list_bind_uniform_set(compute_list, uniform_set, 0)
rd.compute_list_dispatch(compute_list, ceil(maxBoids/1024.), 1, 1)
rd.compute_list_end()
rd.submit()

Start with printing the bindings array to check if everything is there.

very cool, i didn’t think you could even do that. also didn’t try :confused:

[<RDUniform#-9223372003300342378>, 
<RDUniform#-9223372003266787942>, 
<RDUniform#-9223372003216456291>, 
<RDUniform#-9223372003166124641>, 
<RDUniform#-9223372002595699298>, 
<RDUniform#-9223372002578922080>, 
<RDUniform#-9223372002562144863>, 
<RDUniform#-9223372002545367646>, 
<RDUniform#-9223372002528590429>, 
<RDUniform#-9223372002511813212>, 
<RDUniform#-9223372003283565161>]

Results are above. Also, it recognizes there’s 11 bindings in the main, the issue is that it reads the shader as only requiring the 10 (up to 9). But again, it fails 3/4 of the shaders, not all of them :thinking:

Your error says that the shader expect 10 bindings but you’re sending 11 of them in the uniform set.

I’ve just tested it out and it’s an issue with the #include line at the top. I copy pasted the shared file into the main glsl and it still broke, but that was before i knew it was the other 3 that had broken. this time, i put the include’s file contents into the problem files and all errors are solved. now i just wonder why the #include is getting skipped on all files but 1 (especially since i’ve copy pasted the #include line 2-3 times…)

I’m.. thoroughly annoyed and confused… I undid the copy paste to see if it would error out on me again… and it didn’t… everything worked, presumably because the shader files didn’t actually update until i changed anything about their contents… I remembered there being a caveat in this regard earlier, such as just adding a space and saving or else it won’t see the changes… Thanks for your time, this was an issue on my end

1 Like