Create uniform buffer automatically with ACompute

This commit is contained in:
Garrett Gunnell 2025-01-21 22:00:50 -08:00
parent 1503920c57
commit fb2aa42e67
5 changed files with 38 additions and 21 deletions

View file

@ -52,13 +52,9 @@ func _render_callback(p_effect_callback_type, p_render_data):
var uniform_array = PackedInt32Array([kernel_size, 0, 0, 0]).to_byte_array()
var uniform_buffer = rd.uniform_buffer_create(uniform_array.size(), uniform_array)
blur_compute.set_texture(0, input_image)
blur_compute.set_uniform_buffer(1, uniform_buffer)
blur_compute.set_uniform_buffer(1, uniform_array)
blur_compute.set_push_constant(push_constant.to_byte_array())
blur_compute.dispatch(0, x_groups, y_groups, z_groups)
blur_compute.dispatch(1, x_groups, y_groups, z_groups)
rd.free_rid(uniform_buffer)

View file

@ -52,12 +52,8 @@ func _render_callback(p_effect_callback_type, p_render_data):
var uniform_array = PackedFloat32Array([exposure.x, exposure.y, exposure.z, exposure.w]).to_byte_array()
var uniform_buffer = rd.uniform_buffer_create(uniform_array.size(), uniform_array)
color_correct_compute.set_texture(0, input_image)
color_correct_compute.set_uniform_buffer(1, uniform_buffer)
color_correct_compute.set_uniform_buffer(1, uniform_array)
color_correct_compute.set_push_constant(push_constant.to_byte_array())
color_correct_compute.dispatch(0, x_groups, y_groups, z_groups)
rd.free_rid(uniform_buffer)

View file

@ -51,12 +51,8 @@ func _render_callback(p_effect_callback_type, p_render_data):
var uniform_array = PackedFloat32Array([gamma, 0, 0, 0]).to_byte_array()
var uniform_buffer = rd.uniform_buffer_create(uniform_array.size(), uniform_array)
gamma_compute.set_texture(0, input_image)
gamma_compute.set_uniform_buffer(1, uniform_buffer)
gamma_compute.set_uniform_buffer(1, uniform_array)
gamma_compute.set_push_constant(push_constant.to_byte_array())
gamma_compute.dispatch(0, x_groups, y_groups, z_groups)
rd.free_rid(uniform_buffer)

View file

@ -172,7 +172,7 @@ func compile_compute_shader(compute_shader_file_path) -> void:
push_error("In: " + shader_code_string)
return
print("Compiling Kernel: " + kernel_name)
print("- Compiling Kernel: " + kernel_name)
shader_compilation = rd.shader_create_from_spirv(shader_spirv)
if not shader_compilation.is_valid():

View file

@ -8,8 +8,14 @@ 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
# 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]
@ -27,11 +33,26 @@ func set_texture(binding: int, texture: RID) -> void:
cache_uniform(u)
func set_uniform_buffer(binding: int, uniform_buffer: RID) -> void:
func set_uniform_buffer(binding: int, uniform_array: PackedByteArray) -> void:
# Check if buffer exists already and hasn't changed
if uniform_buffer_cache.has(binding):
if uniform_array == uniform_buffer_cache.get(binding):
return
# Check if buffer exists in gpu memory and release
if uniform_buffer_id_cache.has(binding):
rd.free_rid(uniform_buffer_id_cache.get(binding))
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)
u.add_id(uniform_buffer_id)
# Cache array contents and RID
uniform_buffer_cache[binding] = PackedByteArray(uniform_array)
uniform_buffer_id_cache[binding] = uniform_buffer_id
cache_uniform(u)
@ -57,14 +78,19 @@ func _init(_shader_name: String) -> void:
func dispatch(kernel_index: int, x_groups: int, y_groups: int, z_groups: int) -> void:
var current_shader_id = AcerolaShaderCompiler.get_compute_kernel_compilation(shader_name, 0)
var global_shader_id = AcerolaShaderCompiler.get_compute_kernel_compilation(shader_name, 0)
if shader_id != current_shader_id:
shader_id = current_shader_id
# 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))
# Reallocate GPU memory if uniforms need updating
if uniform_set_cache != current_bound_uniform_set_cpu_copy:
print("Uniforms changed")
var uniform_set = UniformSetCacheRD.get_cache(shader_id, 0, uniform_set_cache)
var compute_list := rd.compute_list_begin()
@ -78,3 +104,6 @@ func dispatch(kernel_index: int, x_groups: int, y_groups: int, z_groups: int) ->
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])