From 784576c3fc974e33fa5625858343652af66c9e80 Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Fri, 29 Aug 2025 16:04:56 -0600 Subject: [PATCH] Compute shader experiments --- .../compute_shader_sandbox.gd | 74 +++++++++++++++++++ .../compute_shader_sandbox.gd.uid | 1 + .../compute_shader_sandbox.tscn | 8 ++ .../compute_shader_sandbox/compute_sum.glsl | 19 +++++ .../compute_sum.glsl.import | 14 ++++ 5 files changed, 116 insertions(+) create mode 100644 utilities/compute_shader_sandbox/compute_shader_sandbox.gd create mode 100644 utilities/compute_shader_sandbox/compute_shader_sandbox.gd.uid create mode 100644 utilities/compute_shader_sandbox/compute_shader_sandbox.tscn create mode 100644 utilities/compute_shader_sandbox/compute_sum.glsl create mode 100644 utilities/compute_shader_sandbox/compute_sum.glsl.import diff --git a/utilities/compute_shader_sandbox/compute_shader_sandbox.gd b/utilities/compute_shader_sandbox/compute_shader_sandbox.gd new file mode 100644 index 0000000..36c6f5e --- /dev/null +++ b/utilities/compute_shader_sandbox/compute_shader_sandbox.gd @@ -0,0 +1,74 @@ +extends Node + +@export var mask_texture: Texture2D + +var shader: RID +var pipeline: RID +var output_buffer: PackedByteArray + +var output_uniform: RDUniform +var texture_uniform: RDUniform + + +func _ready() -> void: + RenderingServer.call_on_render_thread(init_compute_shader) + + +func init_compute_shader() -> void: + # Rendering device handle + var rd := RenderingServer.get_rendering_device() + # Load shader + var shader_file: RDShaderFile = load("res://utilities/compute_shader_sandbox/compute_sum.glsl") + # Compile shader + shader = rd.shader_create_from_spirv(shader_file.get_spirv()) + # Create pipeline + pipeline = rd.compute_pipeline_create(shader) + + # Build output buffer uniform + output_buffer = PackedInt32Array([0]).to_byte_array() + var storage_buffer := rd.storage_buffer_create(output_buffer.size(), output_buffer) + output_uniform = RDUniform.new() + output_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER + output_uniform.binding = 0 + output_uniform.add_id(storage_buffer) + + # Build texture uniform + texture_uniform = RDUniform.new() + texture_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE + texture_uniform.binding = 1 + + var tex_view := RDTextureView.new() + var tex_fmt := RDTextureFormat.new() + tex_fmt.width = 64 + tex_fmt.height = 64 + tex_fmt.format = RenderingDevice.DATA_FORMAT_R8_UINT + tex_fmt.usage_bits = ( + RenderingDevice.TEXTURE_USAGE_STORAGE_BIT + RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT + ) + var image := mask_texture.get_image() + image.convert(Image.FORMAT_R8) + var texture := rd.texture_create(tex_fmt, tex_view, [image.get_data()]) + texture_uniform.add_id(texture) + + +func _process(_delta: float) -> void: + RenderingServer.call_on_render_thread(dispatch_compute) + + # Get result + var out_data := output_buffer.to_int32_array() + print(out_data) + + +func dispatch_compute() -> void: + # Rendering device handle + var rd := RenderingServer.get_rendering_device() + + # Prepare shader context + var uniform_set := rd.uniform_set_create([output_uniform, texture_uniform], shader, 0) + + # Bind context + 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, 32, 32, 1) + rd.compute_list_end() diff --git a/utilities/compute_shader_sandbox/compute_shader_sandbox.gd.uid b/utilities/compute_shader_sandbox/compute_shader_sandbox.gd.uid new file mode 100644 index 0000000..46ab463 --- /dev/null +++ b/utilities/compute_shader_sandbox/compute_shader_sandbox.gd.uid @@ -0,0 +1 @@ +uid://bpkwaloqvlvod diff --git a/utilities/compute_shader_sandbox/compute_shader_sandbox.tscn b/utilities/compute_shader_sandbox/compute_shader_sandbox.tscn new file mode 100644 index 0000000..382f1cc --- /dev/null +++ b/utilities/compute_shader_sandbox/compute_shader_sandbox.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=3 format=3 uid="uid://ywmbsmw2em5n"] + +[ext_resource type="Script" uid="uid://bpkwaloqvlvod" path="res://utilities/compute_shader_sandbox/compute_shader_sandbox.gd" id="1_0g1hn"] +[ext_resource type="Texture2D" uid="uid://wqqwtmtmp147" path="res://levels/ghost_ship/level/mess_hall/overhead_light_mask_C.png" id="2_ckeim"] + +[node name="ComputeShaderSandbox" type="Node"] +script = ExtResource("1_0g1hn") +mask_texture = ExtResource("2_ckeim") diff --git a/utilities/compute_shader_sandbox/compute_sum.glsl b/utilities/compute_shader_sandbox/compute_sum.glsl new file mode 100644 index 0000000..217855d --- /dev/null +++ b/utilities/compute_shader_sandbox/compute_sum.glsl @@ -0,0 +1,19 @@ +#[compute] +#version 450 + +layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in; + +layout(set = 0, binding = 0, std430) restrict buffer outputBuffer { + uint sum_value; +} out_data; + + +layout(set = 0, binding = 1, r8ui) uniform readonly uimage2D inputTexture; + + +void main() { + ivec2 uv = ivec2(gl_GlobalInvocationID.xy); + uint value = imageLoad(inputTexture, uv).r + 1; + out_data.sum_value = atomicAdd(out_data.sum_value, value); + //out_data.sum_value += value; +} diff --git a/utilities/compute_shader_sandbox/compute_sum.glsl.import b/utilities/compute_shader_sandbox/compute_sum.glsl.import new file mode 100644 index 0000000..0f1ebe6 --- /dev/null +++ b/utilities/compute_shader_sandbox/compute_sum.glsl.import @@ -0,0 +1,14 @@ +[remap] + +importer="glsl" +type="RDShaderFile" +uid="uid://bc34sy37cdf6k" +path="res://.godot/imported/compute_sum.glsl-65c025c095b2ca4b78b25d3c010d401d.res" + +[deps] + +source_file="res://utilities/compute_shader_sandbox/compute_sum.glsl" +dest_files=["res://.godot/imported/compute_sum.glsl-65c025c095b2ca4b78b25d3c010d401d.res"] + +[params] +