mirror of
https://github.com/GarrettGunnell/God-Machine.git
synced 2025-10-19 14:43:16 +00:00
Add dependencies
This commit is contained in:
parent
62d012f9c0
commit
8674f46fe0
8 changed files with 467 additions and 1 deletions
|
@ -1 +0,0 @@
|
||||||
Subproject commit 9a5aa6925481aa9db1428f7c7b93d80565807152
|
|
24
Packages/Acerola-Compute/Examples/exposure_example.acompute
Normal file
24
Packages/Acerola-Compute/Examples/exposure_example.acompute
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#kernel ExposureExample
|
||||||
|
|
||||||
|
|
||||||
|
layout(rgba16f, set = 0, binding = 0) uniform image2D _RenderTarget;
|
||||||
|
|
||||||
|
layout(binding = 1) uniform UniformBufferObject {
|
||||||
|
vec4 _Exposure;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(push_constant, std430) uniform Params {
|
||||||
|
vec2 raster_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
[numthreads(8, 8, 1)]
|
||||||
|
void ExposureExample() {
|
||||||
|
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
ivec2 size = ivec2(raster_size);
|
||||||
|
|
||||||
|
if (uv.x >= size.x || uv.y >= size.y) return;
|
||||||
|
|
||||||
|
vec3 color = imageLoad(_RenderTarget, uv).rgb * _Exposure.gba * _Exposure.r;
|
||||||
|
|
||||||
|
imageStore(_RenderTarget, uv, vec4(color, 1.0));
|
||||||
|
}
|
64
Packages/Acerola-Compute/Examples/exposure_shader.gd
Normal file
64
Packages/Acerola-Compute/Examples/exposure_shader.gd
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
@tool
|
||||||
|
extends CompositorEffect
|
||||||
|
class_name ExposureCompositorEffect
|
||||||
|
|
||||||
|
@export_group("Shader Settings")
|
||||||
|
@export var exposure = Vector4(2, 1, 1, 1)
|
||||||
|
|
||||||
|
var rd : RenderingDevice
|
||||||
|
var exposure_compute : ACompute
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
effect_callback_type = EFFECT_CALLBACK_TYPE_POST_TRANSPARENT
|
||||||
|
rd = RenderingServer.get_rendering_device()
|
||||||
|
|
||||||
|
# To make use of an existing ACompute shader we use its filename to access it, in this case, the example compute shader file is 'exposure_example.acompute'
|
||||||
|
exposure_compute = ACompute.new('exposure_example')
|
||||||
|
|
||||||
|
|
||||||
|
func _notification(what):
|
||||||
|
if what == NOTIFICATION_PREDELETE:
|
||||||
|
# ACompute will handle the freeing of any resources attached to it
|
||||||
|
exposure_compute.free()
|
||||||
|
|
||||||
|
|
||||||
|
func _render_callback(p_effect_callback_type, p_render_data):
|
||||||
|
if not enabled: return
|
||||||
|
if p_effect_callback_type != EFFECT_CALLBACK_TYPE_POST_TRANSPARENT: return
|
||||||
|
|
||||||
|
if not rd:
|
||||||
|
push_error("No rendering device")
|
||||||
|
return
|
||||||
|
|
||||||
|
var render_scene_buffers : RenderSceneBuffersRD = p_render_data.get_render_scene_buffers()
|
||||||
|
|
||||||
|
if not render_scene_buffers:
|
||||||
|
push_error("No buffer to render to")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
var size = render_scene_buffers.get_internal_size()
|
||||||
|
if size.x == 0 and size.y == 0:
|
||||||
|
push_error("Rendering to 0x0 buffer")
|
||||||
|
return
|
||||||
|
|
||||||
|
var x_groups = (size.x - 1) / 8 + 1
|
||||||
|
var y_groups = (size.y - 1) / 8 + 1
|
||||||
|
var z_groups = 1
|
||||||
|
|
||||||
|
# Vulkan has a feature known as push constants which are like uniform sets but for very small amounts of data
|
||||||
|
var push_constant : PackedFloat32Array = PackedFloat32Array([size.x, size.y, 0.0, 0.0])
|
||||||
|
|
||||||
|
for view in range(render_scene_buffers.get_view_count()):
|
||||||
|
var input_image = render_scene_buffers.get_color_layer(view)
|
||||||
|
|
||||||
|
# Pack the exposure vector into a byte array
|
||||||
|
var uniform_array = PackedFloat32Array([exposure.x, exposure.y, exposure.z, exposure.w]).to_byte_array()
|
||||||
|
|
||||||
|
# ACompute handles uniform caching under the hood, as long as the exposure value doesn't change or the render target doesn't change, these functions will only do work once
|
||||||
|
exposure_compute.set_texture(0, input_image)
|
||||||
|
exposure_compute.set_uniform_buffer(1, uniform_array)
|
||||||
|
exposure_compute.set_push_constant(push_constant.to_byte_array())
|
||||||
|
|
||||||
|
# Dispatch the compute kernel
|
||||||
|
exposure_compute.dispatch(0, x_groups, y_groups, z_groups)
|
1
Packages/Acerola-Compute/Examples/exposure_shader.gd.uid
Normal file
1
Packages/Acerola-Compute/Examples/exposure_shader.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://de55kuko5hepf
|
237
Packages/Acerola-Compute/acerola_shader_compiler.gd
Normal file
237
Packages/Acerola-Compute/acerola_shader_compiler.gd
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
@tool
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
var shader_file_regex = RegEx.new()
|
||||||
|
|
||||||
|
var shader_files : Array = Array()
|
||||||
|
var compute_shader_file_paths : Array = Array()
|
||||||
|
|
||||||
|
var rd : RenderingDevice
|
||||||
|
|
||||||
|
var shader_compilations = {}
|
||||||
|
var shader_code_cache = {}
|
||||||
|
|
||||||
|
var compute_shader_kernel_compilations = {}
|
||||||
|
|
||||||
|
func find_files(dir_name) -> void:
|
||||||
|
var dir = DirAccess.open(dir_name)
|
||||||
|
|
||||||
|
if dir:
|
||||||
|
dir.list_dir_begin()
|
||||||
|
var file_name = dir.get_next()
|
||||||
|
while file_name != "":
|
||||||
|
if dir.current_is_dir():
|
||||||
|
find_files(dir_name + '/' + file_name)
|
||||||
|
else:
|
||||||
|
# if file_name.get_extension() == 'glsl'and shader_file_regex.search(file_name):
|
||||||
|
# shader_files.push_back(dir_name + '/' + file_name)
|
||||||
|
|
||||||
|
if file_name.get_extension() == 'acompute':
|
||||||
|
compute_shader_file_paths.push_back(dir_name + '/' + file_name)
|
||||||
|
|
||||||
|
file_name = dir.get_next()
|
||||||
|
|
||||||
|
|
||||||
|
func get_shader_name(file_path: String) -> String:
|
||||||
|
return file_path.get_file().split(".")[0]
|
||||||
|
|
||||||
|
|
||||||
|
func compile_shader(shader_file_path) -> void:
|
||||||
|
var shader_name = shader_file_path.split("/")[-1].split(".glsl")[0]
|
||||||
|
|
||||||
|
if shader_compilations.has(shader_name):
|
||||||
|
if shader_compilations[shader_name].is_valid():
|
||||||
|
print("Freeing: " + shader_name)
|
||||||
|
rd.free_rid(shader_compilations[shader_name])
|
||||||
|
|
||||||
|
var shader_code = FileAccess.open(shader_file_path, FileAccess.READ).get_as_text()
|
||||||
|
shader_code_cache[shader_name] = shader_code
|
||||||
|
|
||||||
|
var shader_compilation = RID()
|
||||||
|
|
||||||
|
var shader_source : RDShaderSource = RDShaderSource.new()
|
||||||
|
shader_source.language = RenderingDevice.SHADER_LANGUAGE_GLSL
|
||||||
|
shader_source.source_compute = shader_code
|
||||||
|
var shader_spirv : RDShaderSPIRV = rd.shader_compile_spirv_from_source(shader_source)
|
||||||
|
|
||||||
|
if shader_spirv.compile_error_compute != "":
|
||||||
|
push_error(shader_spirv.compile_error_compute)
|
||||||
|
push_error("In: " + shader_code)
|
||||||
|
return
|
||||||
|
|
||||||
|
print("Compiling: " + shader_name)
|
||||||
|
shader_compilation = rd.shader_create_from_spirv(shader_spirv)
|
||||||
|
|
||||||
|
if not shader_compilation.is_valid():
|
||||||
|
return
|
||||||
|
|
||||||
|
shader_compilations[shader_name] = shader_compilation
|
||||||
|
|
||||||
|
|
||||||
|
func compile_compute_shader(compute_shader_file_path) -> void:
|
||||||
|
var compute_shader_name = get_shader_name(compute_shader_file_path)
|
||||||
|
|
||||||
|
print("Compiling Compute Shader: " + compute_shader_name)
|
||||||
|
|
||||||
|
var file = FileAccess.open(compute_shader_file_path, FileAccess.READ)
|
||||||
|
var raw_shader_code_string = file.get_as_text()
|
||||||
|
shader_code_cache[compute_shader_file_path] = raw_shader_code_string
|
||||||
|
|
||||||
|
var raw_shader_code = raw_shader_code_string.split("\n")
|
||||||
|
|
||||||
|
var kernel_names = Array()
|
||||||
|
|
||||||
|
# Strip out kernel names
|
||||||
|
while file.get_position() < file.get_length():
|
||||||
|
var line = file.get_line()
|
||||||
|
|
||||||
|
if line.begins_with("#kernel "):
|
||||||
|
var kernel_name = line.split("#kernel")[1].strip_edges()
|
||||||
|
# print("Kernel Found: " + kernel_name)
|
||||||
|
kernel_names.push_back(kernel_name)
|
||||||
|
raw_shader_code.remove_at(0)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# If no kernels defined at top of file, fail to compile
|
||||||
|
if kernel_names.size() == 0:
|
||||||
|
push_error("Failed to compile: " + compute_shader_file_path)
|
||||||
|
push_error("Reason: No kernels found")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# If no code after kernel definitions or if nothing in file at all, fail to compile
|
||||||
|
if file.get_position() >= file.get_length():
|
||||||
|
push_error("Failed to compile: " + compute_shader_file_path)
|
||||||
|
push_error("Reason: No shader code found")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Verify kernels exist
|
||||||
|
raw_shader_code_string = "\n".join(raw_shader_code)
|
||||||
|
for kernel_name in kernel_names:
|
||||||
|
if not raw_shader_code_string.contains(kernel_name):
|
||||||
|
push_error("Failed to compile: " + compute_shader_file_path)
|
||||||
|
push_error("Reason: " + kernel_name + " kernel not found!")
|
||||||
|
|
||||||
|
var kernel_to_thread_group_count = {}
|
||||||
|
|
||||||
|
# Find kernels and extract thread groups
|
||||||
|
for i in raw_shader_code.size():
|
||||||
|
var line = raw_shader_code[i]
|
||||||
|
|
||||||
|
for kernel_name in kernel_names:
|
||||||
|
if line.contains(kernel_name) and line.contains('void'):
|
||||||
|
# print("Found kernel " + kernel_name + " at line " + str(i + kernel_names.size() + 1))
|
||||||
|
|
||||||
|
# find thread group count by searching previous line of code from kernel function
|
||||||
|
var newLine = raw_shader_code[i - 1].strip_edges()
|
||||||
|
if newLine.contains('numthreads'):
|
||||||
|
var thread_groups = newLine.split('(')[-1].split(')')[0].split(',')
|
||||||
|
if thread_groups.size() != 3:
|
||||||
|
push_error("Failed to compile: " + compute_shader_file_path)
|
||||||
|
push_error("Reason: kernel thread group syntax error")
|
||||||
|
|
||||||
|
kernel_to_thread_group_count[kernel_name] = Array()
|
||||||
|
for n in thread_groups.size():
|
||||||
|
kernel_to_thread_group_count[kernel_name].push_back((thread_groups[n].strip_edges()))
|
||||||
|
|
||||||
|
raw_shader_code.set(i - 1, "")
|
||||||
|
|
||||||
|
# print(kernel_to_thread_group_count[kernel_name])
|
||||||
|
else:
|
||||||
|
push_error("Failed to compile: " + compute_shader_file_path)
|
||||||
|
push_error("Reason: kernel thread group count not found")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Compile kernels
|
||||||
|
compute_shader_kernel_compilations[compute_shader_name] = Array()
|
||||||
|
for kernel_name in kernel_names:
|
||||||
|
var shader_code = PackedStringArray(raw_shader_code)
|
||||||
|
|
||||||
|
# Insert GLSL thread group layout for the kernel
|
||||||
|
var thread_group = kernel_to_thread_group_count[kernel_name]
|
||||||
|
shader_code.insert(0, "layout(local_size_x = " + thread_group[0] + ", local_size_y = " + thread_group[1] + ", local_size_z = " + thread_group[2] + ") in;")
|
||||||
|
|
||||||
|
# Insert GLSL version at top of file
|
||||||
|
shader_code.insert(0, "#version 450")
|
||||||
|
|
||||||
|
# Replace kernel name with main
|
||||||
|
var shader_code_string = "\n".join(shader_code).replace(kernel_name, "main")
|
||||||
|
|
||||||
|
# Compile shader
|
||||||
|
|
||||||
|
var shader_compilation = RID()
|
||||||
|
|
||||||
|
var shader_source : RDShaderSource = RDShaderSource.new()
|
||||||
|
shader_source.language = RenderingDevice.SHADER_LANGUAGE_GLSL
|
||||||
|
shader_source.source_compute = shader_code_string
|
||||||
|
var shader_spirv : RDShaderSPIRV = rd.shader_compile_spirv_from_source(shader_source)
|
||||||
|
|
||||||
|
if shader_spirv.compile_error_compute != "":
|
||||||
|
push_error(shader_spirv.compile_error_compute)
|
||||||
|
push_error("In: " + shader_code_string)
|
||||||
|
return
|
||||||
|
|
||||||
|
print("- Compiling Kernel: " + kernel_name)
|
||||||
|
shader_compilation = rd.shader_create_from_spirv(shader_spirv)
|
||||||
|
|
||||||
|
if not shader_compilation.is_valid():
|
||||||
|
return
|
||||||
|
|
||||||
|
compute_shader_kernel_compilations[compute_shader_name].push_back(shader_compilation)
|
||||||
|
|
||||||
|
# print(shader_code_string)
|
||||||
|
|
||||||
|
# print("\n".join(raw_shader_code))
|
||||||
|
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
rd = RenderingServer.get_rendering_device()
|
||||||
|
|
||||||
|
find_files("res://")
|
||||||
|
|
||||||
|
for shader_file in shader_files:
|
||||||
|
compile_shader(shader_file)
|
||||||
|
|
||||||
|
for file_path in compute_shader_file_paths:
|
||||||
|
compile_compute_shader(file_path)
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
# Compare current shader code with cached shader code and recompile if changed
|
||||||
|
for file_path in compute_shader_file_paths:
|
||||||
|
if shader_code_cache[file_path] != FileAccess.open(file_path, FileAccess.READ).get_as_text():
|
||||||
|
var shader_name = get_shader_name(file_path)
|
||||||
|
|
||||||
|
# Free existing kernels
|
||||||
|
for kernel in compute_shader_kernel_compilations[shader_name]:
|
||||||
|
rd.free_rid(kernel)
|
||||||
|
|
||||||
|
compute_shader_kernel_compilations[shader_name].clear()
|
||||||
|
|
||||||
|
compile_compute_shader(file_path)
|
||||||
|
|
||||||
|
|
||||||
|
func _notification(what):
|
||||||
|
if what == NOTIFICATION_PREDELETE or what == NOTIFICATION_WM_CLOSE_REQUEST:
|
||||||
|
var shader_names = shader_compilations.keys()
|
||||||
|
|
||||||
|
for shader_name in shader_names:
|
||||||
|
var shader = shader_compilations[shader_name]
|
||||||
|
if shader.is_valid():
|
||||||
|
print("Freeing: " + shader_name)
|
||||||
|
rd.free_rid(shader)
|
||||||
|
|
||||||
|
for compute_shader in compute_shader_kernel_compilations.keys():
|
||||||
|
for kernel in compute_shader_kernel_compilations[compute_shader]:
|
||||||
|
rd.free_rid(kernel)
|
||||||
|
|
||||||
|
|
||||||
|
func get_shader_compilation(shader_name: String) -> RID:
|
||||||
|
return shader_compilations[shader_name]
|
||||||
|
|
||||||
|
func get_compute_kernel_compilation(shader_name, kernel_index):
|
||||||
|
return compute_shader_kernel_compilations[shader_name][kernel_index]
|
||||||
|
|
||||||
|
func get_compute_kernel_compilations(shader_name):
|
||||||
|
return compute_shader_kernel_compilations[shader_name]
|
1
Packages/Acerola-Compute/acerola_shader_compiler.gd.uid
Normal file
1
Packages/Acerola-Compute/acerola_shader_compiler.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://dad3g6godfma
|
139
Packages/Acerola-Compute/acompute.gd
Normal file
139
Packages/Acerola-Compute/acompute.gd
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
@tool
|
||||||
|
extends Object
|
||||||
|
class_name ACompute
|
||||||
|
|
||||||
|
|
||||||
|
var kernels = Array()
|
||||||
|
var rd : RenderingDevice
|
||||||
|
var shader_name : String
|
||||||
|
var shader_id : RID
|
||||||
|
var push_constant : PackedByteArray
|
||||||
|
var uniform_set_gpu_id : RID
|
||||||
|
var uniform_set_cache : Array
|
||||||
|
var current_bound_uniform_set_cpu_copy : Array
|
||||||
|
|
||||||
|
var refresh_uniforms = true
|
||||||
|
|
||||||
|
# Contains the contents of the uniform array itself
|
||||||
|
var uniform_buffer_cache = {}
|
||||||
|
# Contains the RIDs for the gpu versions of the uniform array
|
||||||
|
var uniform_buffer_id_cache = {}
|
||||||
|
|
||||||
|
func get_kernel(index: int) -> RID:
|
||||||
|
return kernels[index]
|
||||||
|
|
||||||
|
|
||||||
|
func set_push_constant(_push_constant: PackedByteArray) -> void:
|
||||||
|
push_constant = PackedByteArray(_push_constant)
|
||||||
|
|
||||||
|
|
||||||
|
func set_texture(binding: int, texture: RID) -> void:
|
||||||
|
var u : RDUniform = RDUniform.new()
|
||||||
|
u.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
|
||||||
|
u.binding = binding
|
||||||
|
u.add_id(texture)
|
||||||
|
|
||||||
|
cache_uniform(u)
|
||||||
|
|
||||||
|
|
||||||
|
func create_uniform_buffer(binding: int, uniform_array: PackedByteArray) -> void:
|
||||||
|
var uniform_buffer_id = rd.uniform_buffer_create(uniform_array.size(), uniform_array)
|
||||||
|
|
||||||
|
var u : RDUniform = RDUniform.new()
|
||||||
|
|
||||||
|
u.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
|
||||||
|
u.binding = binding
|
||||||
|
u.add_id(uniform_buffer_id)
|
||||||
|
|
||||||
|
uniform_buffer_id_cache[binding] = uniform_buffer_id
|
||||||
|
uniform_buffer_cache[binding] = PackedByteArray(uniform_array)
|
||||||
|
cache_uniform(u)
|
||||||
|
|
||||||
|
|
||||||
|
func set_uniform_buffer(binding: int, uniform_array: PackedByteArray) -> void:
|
||||||
|
# Instantiate GPU memory if first time setting uniform buffer
|
||||||
|
if not uniform_buffer_cache.has(binding):
|
||||||
|
create_uniform_buffer(binding, uniform_array)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Compare array contents with cache and skip update if nothing changed
|
||||||
|
if uniform_array == uniform_buffer_cache.get(binding):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# Update uniform buffer
|
||||||
|
rd.buffer_update(uniform_buffer_id_cache.get(binding), 0, uniform_array.size(), uniform_array)
|
||||||
|
|
||||||
|
# Cache array contents
|
||||||
|
uniform_buffer_cache[binding] = PackedByteArray(uniform_array)
|
||||||
|
|
||||||
|
|
||||||
|
func cache_uniform(u: RDUniform) -> void:
|
||||||
|
if uniform_set_cache.size() - 1 < u.binding:
|
||||||
|
refresh_uniforms = true
|
||||||
|
uniform_set_cache.resize(u.binding + 1)
|
||||||
|
|
||||||
|
# If uniform has had its info changed then set flag to refresh gpu side uniform data
|
||||||
|
if uniform_set_cache[u.binding]:
|
||||||
|
var old_uniform_ids = uniform_set_cache[u.binding].get_ids()
|
||||||
|
var new_uniform_ids = u.get_ids()
|
||||||
|
|
||||||
|
if old_uniform_ids.size() != new_uniform_ids.size():
|
||||||
|
refresh_uniforms = true
|
||||||
|
else:
|
||||||
|
for i in old_uniform_ids.size():
|
||||||
|
if old_uniform_ids[i].get_id() != new_uniform_ids[i].get_id():
|
||||||
|
refresh_uniforms = true
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
uniform_set_cache[u.binding] = u
|
||||||
|
|
||||||
|
|
||||||
|
func _init(_shader_name: String) -> void:
|
||||||
|
rd = RenderingServer.get_rendering_device()
|
||||||
|
|
||||||
|
uniform_set_cache = Array()
|
||||||
|
|
||||||
|
shader_name = _shader_name
|
||||||
|
|
||||||
|
shader_id = AcerolaShaderCompiler.get_compute_kernel_compilation(shader_name, 0)
|
||||||
|
|
||||||
|
for kernel in AcerolaShaderCompiler.get_compute_kernel_compilations(shader_name):
|
||||||
|
kernels.push_back(rd.compute_pipeline_create(kernel))
|
||||||
|
|
||||||
|
|
||||||
|
func dispatch(kernel_index: int, x_groups: int, y_groups: int, z_groups: int) -> void:
|
||||||
|
var global_shader_id = AcerolaShaderCompiler.get_compute_kernel_compilation(shader_name, 0)
|
||||||
|
|
||||||
|
# Recreate kernel pipelines if shader was recompiled
|
||||||
|
if shader_id != global_shader_id:
|
||||||
|
shader_id = global_shader_id
|
||||||
|
kernels.clear()
|
||||||
|
for kernel in AcerolaShaderCompiler.get_compute_kernel_compilations(shader_name):
|
||||||
|
kernels.push_back(rd.compute_pipeline_create(kernel))
|
||||||
|
|
||||||
|
uniform_set_gpu_id = rd.uniform_set_create(uniform_set_cache, global_shader_id, 0)
|
||||||
|
|
||||||
|
# Reallocate GPU memory if uniforms need updating
|
||||||
|
if refresh_uniforms:
|
||||||
|
if uniform_set_gpu_id.is_valid(): rd.free_rid(uniform_set_gpu_id)
|
||||||
|
uniform_set_gpu_id = rd.uniform_set_create(uniform_set_cache, global_shader_id, 0)
|
||||||
|
refresh_uniforms = false
|
||||||
|
|
||||||
|
var compute_list := rd.compute_list_begin()
|
||||||
|
rd.compute_list_bind_compute_pipeline(compute_list, kernels[kernel_index])
|
||||||
|
rd.compute_list_bind_uniform_set(compute_list, uniform_set_gpu_id, 0)
|
||||||
|
rd.compute_list_set_push_constant(compute_list, push_constant, push_constant.size())
|
||||||
|
rd.compute_list_dispatch(compute_list, x_groups, y_groups, z_groups)
|
||||||
|
rd.compute_list_end()
|
||||||
|
|
||||||
|
|
||||||
|
func free() -> void:
|
||||||
|
for kernel in kernels:
|
||||||
|
rd.free_rid(kernel)
|
||||||
|
|
||||||
|
for binding in uniform_buffer_id_cache.keys():
|
||||||
|
rd.free_rid(uniform_buffer_id_cache[binding])
|
||||||
|
|
||||||
|
if uniform_set_gpu_id.is_valid(): rd.free_rid(uniform_set_gpu_id)
|
1
Packages/Acerola-Compute/acompute.gd.uid
Normal file
1
Packages/Acerola-Compute/acompute.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://dmhdvw6cfhyac
|
Loading…
Add table
Add a link
Reference in a new issue