Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Examples/exposure_shader.gd
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ 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()

# 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_image(0, input_image)
exposure_compute.set_uniform_buffer(1, uniform_array)
exposure_compute.set_push_constant(push_constant.to_byte_array())

Expand Down
42 changes: 39 additions & 3 deletions acompute.gd
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,50 @@ var uniform_buffer_cache = {}
# Binding -> RID
var uniform_buffer_id_cache = {}

var nearest_sampler : RID
var linear_sampler : RID

func get_kernel(index: int) -> RID:
return kernels[index]

func ensure_samplers():
if !nearest_sampler.is_valid():
var sampler_state : RDSamplerState = RDSamplerState.new()
sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_NEAREST
sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_NEAREST
nearest_sampler = rd.sampler_create(sampler_state)

if !linear_sampler.is_valid():
var sampler_state: RDSamplerState = RDSamplerState.new()
sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
linear_sampler = rd.sampler_create(sampler_state)

func set_push_constant(_push_constant: PackedByteArray) -> void:
push_constant = PackedByteArray(_push_constant)


func set_texture(binding: int, texture: RID) -> void:
func set_image(binding: int, image: RID) -> void:
var u : RDUniform = RDUniform.new()
u.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
u.binding = binding
u.add_id(texture)
u.add_id(image)

cache_uniform(u)

func set_texture(binding: int, texture: RID, linear: bool = true) -> void:
var u : RDUniform = RDUniform.new()
u.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
u.binding = binding

ensure_samplers()

if (linear):
u.add_id(linear_sampler)
else:
u.add_id(nearest_sampler)
u.add_id(texture)

cache_uniform(u)

func set_uniform_buffer(binding: int, uniform_array: PackedByteArray) -> void:
# Check if buffer exists already in this binding
Expand Down Expand Up @@ -105,6 +133,8 @@ func _init(_shader_name: String) -> void:
for kernel in AcerolaShaderCompiler.get_compute_kernel_compilations(shader_name):
kernels.push_back(rd.compute_pipeline_create(kernel))

ensure_samplers()


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)
Expand Down Expand Up @@ -142,3 +172,9 @@ func free() -> void:
rd.free_rid(uniform_buffer_id_cache[binding])

if uniform_set_gpu_id.is_valid(): rd.free_rid(uniform_set_gpu_id)

if nearest_sampler.is_valid():
rd.free_rid(nearest_sampler)

if linear_sampler.is_valid():
rd.free_rid(linear_sampler)