Last active
January 25, 2024 06:32
-
-
Save winston-yallow/aab20fa437bfa3dd80bfb0ed6605d28e to your computer and use it in GitHub Desktop.
Godot 4.x Compute Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Node | |
# Based on this tweet by Clay John: | |
# https://twitter.com/john_clayjohn/status/1306447928932753408 | |
func _ready() -> void: | |
# Create a local rendering device. | |
var rd := RenderingServer.create_local_rendering_device() | |
# Load GLSL shader | |
var shader_file := load("res://test.glsl") | |
var shader_spirv: RDShaderSPIRV = shader_file.get_spirv() | |
var shader := rd.shader_create_from_spirv(shader_spirv) | |
# Prepare our data. We use doubles in the shader, so we need 64 bit. | |
var input := PackedFloat64Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) | |
var input_bytes := input.to_byte_array() | |
# Create a storage buffer that can hold 10 double values. Each | |
# double has 8 byte (64 bit) so 10 x 8 = 80 bytes | |
var buffer := rd.storage_buffer_create(80, input_bytes) | |
var uniform := RDUniform.new() | |
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER | |
uniform.binding = 0 | |
uniform.add_id(buffer) | |
var uniform_set := rd.uniform_set_create([uniform], shader, 0) | |
# Create a compute pipeline | |
var pipeline := rd.compute_pipeline_create(shader) | |
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, 5, 1, 1) | |
rd.compute_list_end() | |
# Submit to GPU and wait for sync | |
rd.submit() | |
rd.sync() | |
# Read back the data from the buffers | |
var output_bytes := rd.buffer_get_data(buffer) | |
var output := output_bytes.to_float64_array() | |
print(output) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[compute] | |
#version 450 | |
// Based on this tweet by Clay John: | |
// https://twitter.com/john_clayjohn/status/1306447928932753408 | |
layout(local_size_x = 4) in; | |
layout(set = 0, binding = 0, std430) restrict buffer MyBuffer { | |
double data[]; | |
} | |
my_buffer; | |
void main() { | |
// gl_GlobalInvocationID.x uniquely identifies this invocation within the work group | |
my_buffer.data[gl_GlobalInvocationID.x] *= 2.0; | |
} |
@padreputativo The docs were updated to include a compute example, they are newer than this gist: Using compute shaders
For your question: I'm not sure, but it should be possible to do stuff repeatedly. You can even re-use the RD, buffers, shader and so on and don't need to recreate them each time.
¡Found it! I needed to start the loop from this line and not only submit and sync:
var compute_list := rd.compute_list_begin()
Yeah that should do since the compute list is basically the thing you submit. So when calling submit without doing that, then there is nothing to submit. Glad you got it working! 🎉
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm having lot of trouble trying to launch it in loop. I'm only able to launch it one time and the data do not seems to be updated anymore... Suggestions?