75 lines
2.5 KiB
GDScript
75 lines
2.5 KiB
GDScript
## Represents a Compute Shader as an Observable Sequence.
|
|
## [br][br]
|
|
## Please note: This is a [b]cold[/b] [Observable]. It transfers data to GPU
|
|
## on subscribe. Thus, each subscription causes one computational step.
|
|
## When the compute shader finishes, the [RenderingDevice] is emitted as item.
|
|
## Afterwards the stream completes.
|
|
## [br][br]
|
|
## [b]Args:[/b]
|
|
## [br]
|
|
## [code]shader_path[/code] the path to the GLSL file with the shader source
|
|
## [br]
|
|
## [code]rd[/code] The current instance of [RenderingDevice]
|
|
## [br]
|
|
## [code]work_groups[/code]: Set x, y and z dimensions of work groups.
|
|
## [br]
|
|
## [code]uniform_sets[/code]: A list containing lists of [RDUniform]
|
|
## representing n uniform sets starting with [code]set = 0[/code] going
|
|
## upwards.
|
|
## [br]
|
|
## [code]scheduler[/code]: Schedules the CPU side of the shader computation
|
|
## [br][br]
|
|
## [b]Return:[/b]
|
|
## An observable sequence which performs a new computation on the device,
|
|
## each time an [Observer] subscribes.
|
|
static func from_compute_shader_(
|
|
shader_path : String,
|
|
rd : RenderingDevice,
|
|
work_groups : Vector3i,
|
|
uniform_sets : Array = [],
|
|
scheduler : SchedulerBase = null
|
|
) -> Observable:
|
|
|
|
# Create shader and pipeline
|
|
var shader_file = load(shader_path)
|
|
var shader_spirv = shader_file.get_spirv()
|
|
var shader = rd.shader_create_from_spirv(shader_spirv)
|
|
var pipeline = rd.compute_pipeline_create(shader)
|
|
|
|
var uniform_sets_rids = []
|
|
for sid in range(uniform_sets.size()):
|
|
uniform_sets_rids.append(
|
|
rd.uniform_set_create(uniform_sets[sid], shader, sid)
|
|
)
|
|
|
|
var subscribe = func(
|
|
observer : ObserverBase,
|
|
scheduler_ : SchedulerBase = null
|
|
) -> DisposableBase:
|
|
|
|
var _scheduler
|
|
if scheduler != null: _scheduler = scheduler
|
|
elif scheduler_ != null: _scheduler = scheduler_
|
|
else: _scheduler = CurrentThreadScheduler.singleton()
|
|
|
|
var action = func(_scheduler = null, _state = null):
|
|
# Setup compute pipeline and uniforms
|
|
var compute_list = rd.compute_list_begin()
|
|
rd.compute_list_bind_compute_pipeline(compute_list, pipeline)
|
|
for sid in range(uniform_sets_rids.size()):
|
|
rd.compute_list_bind_uniform_set(compute_list, uniform_sets_rids[sid], sid)
|
|
rd.compute_list_dispatch(compute_list, work_groups.x, work_groups.y, work_groups.z)
|
|
rd.compute_list_end()
|
|
|
|
# Send to GPU
|
|
rd.submit()
|
|
# Sync with CPU
|
|
rd.sync()
|
|
|
|
observer.on_next(rd)
|
|
observer.on_completed()
|
|
|
|
return _scheduler.schedule(action)
|
|
|
|
return Observable.new(subscribe)
|