-
-
Save winston-yallow/aab20fa437bfa3dd80bfb0ed6605d28e to your computer and use it in GitHub Desktop.
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) | |
#[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; | |
} |
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?
@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! 🎉
I was testing to see how it works and I use c#, so here is the converted code.