|
MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
|
Compute pass that applies a GpuFieldOperator's generated shader to a range of vertex records in the attached buffer. More...
#include <VertexFieldProcessor.hpp>
Inheritance diagram for MayaFlux::Buffers::VertexFieldProcessor:
Collaboration diagram for MayaFlux::Buffers::VertexFieldProcessor:Classes | |
| struct | RangeParams |
| Push constant block matching the prefix GpuFieldOperator declares. More... | |
Public Member Functions | |
| void | clear_vertex_range () |
| Drop an explicit range and cover the whole buffer again. | |
| std::shared_ptr< Nodes::Network::GpuFieldOperator > | get_field_operator () const |
| The operator this processor dispatches for. | |
| void | set_vertex_range (uint32_t first_vertex, uint32_t vertex_count) |
| Restrict the dispatch to a slice of the buffer. | |
| VertexFieldProcessor (std::shared_ptr< Nodes::Network::GpuFieldOperator > field_operator) | |
| ~VertexFieldProcessor () override=default | |
Public Member Functions inherited from MayaFlux::Buffers::ComputeProcessor | |
| ComputeProcessor (const Portal::Graphics::ShaderSpec &spec) | |
| Construct processor from a generated ShaderSpec. | |
| ComputeProcessor (const std::string &shader_path, uint32_t workgroup_x=256) | |
| Construct processor with shader path. | |
| const ShaderDispatchConfig & | get_dispatch_config () const |
| Get current dispatch configuration. | |
| uint32_t | get_iteration_count () const |
| Dispatches recorded per execute cycle. | |
| bool | is_pipeline_ready () const |
| Check if pipeline is created. | |
| void | set_custom_dispatch (std::function< std::array< uint32_t, 3 >(const std::shared_ptr< VKBuffer > &)> calculator) |
| Set custom dispatch calculator. | |
| void | set_dispatch_mode (ShaderDispatchConfig::DispatchMode mode) |
| Set dispatch mode. | |
| void | set_iteration_count (uint32_t count) |
| Set how many dispatches are recorded per execute cycle. | |
| void | set_manual_dispatch (uint32_t x, uint32_t y=1, uint32_t z=1) |
| Set manual dispatch group counts. | |
| void | set_workgroup_size (uint32_t x, uint32_t y=1, uint32_t z=1) |
| Set workgroup size (should match shader local_size) | |
Public Member Functions inherited from MayaFlux::Buffers::ShaderProcessor | |
| void | add_binding (const std::string &descriptor_name, const ShaderBinding &binding) |
| Add descriptor binding configuration. | |
| bool | are_bindings_complete () const |
| Check if all required bindings are satisfied. | |
| bool | are_descriptors_ready () const |
| Check if descriptors are initialized. | |
| void | auto_bind_buffer (const std::shared_ptr< VKBuffer > &buffer) |
| Auto-bind buffer based on attachment order. | |
| void | bind_buffer (const std::string &descriptor_name, const std::shared_ptr< VKBuffer > &buffer) |
| Bind a VKBuffer to a named shader descriptor. | |
| void | clear_specialization_constants () |
| Clear all specialization constants. | |
| template<typename T > | |
| bool | download_bound (const std::string &descriptor_name, std::vector< T > &data) const |
| bool | download_bound (const std::string &descriptor_name, void *data, size_t size, const std::shared_ptr< VKBuffer > &staging=nullptr) const |
| Download the buffer currently bound to a named descriptor. | |
| void | feed (const std::string &name, FeedSource source) |
| Supply a shader input from a callable, resolved by name. | |
| void | feed (const std::string &name, FeedSource source, uint32_t offset, size_t size=sizeof(float)) |
| Supply a push constant from a callable at an explicit offset. | |
| std::vector< std::string > | get_binding_names () const |
| Get all configured descriptor names. | |
| std::shared_ptr< VKBuffer > | get_bound_buffer (const std::string &descriptor_name) const |
| Get bound buffer for a descriptor name. | |
| size_t | get_bound_buffer_count () const |
| Get number of bound buffers. | |
| virtual BufferUsageHint | get_buffer_usage_hint (const std::string &descriptor_name) const |
| Get buffer usage hint for a descriptor. | |
| const ShaderConfig & | get_config () const |
| Get current configuration. | |
| std::vector< std::string > | get_feed_names () const |
| Names of every registered feed. | |
| virtual std::shared_ptr< VKBuffer > | get_output_buffer () const |
| Get the output buffer after compute dispatch. | |
| std::vector< uint8_t > & | get_push_constant_data () |
| const std::vector< uint8_t > & | get_push_constant_data () const |
| Get current push constant data. | |
| const std::string & | get_shader_path () const |
| Get current shader path. | |
| bool | has_binding (const std::string &descriptor_name) const |
| Check if a descriptor binding exists. | |
| virtual bool | has_executed () const |
| Check if compute has been executed at least once. | |
| bool | has_feed (const std::string &name) const |
| Whether a feed of this name is registered. | |
| bool | hot_reload_shader () |
| Hot-reload shader from ShaderFoundry. | |
| bool | is_compatible_with (const std::shared_ptr< Buffer > &buffer) const override |
| Checks if this processor can handle the specified buffer type. | |
| bool | is_deferred_submission () const |
| Whether this processor submits asynchronously. | |
| bool | is_dispatch_pending () const |
| True while an asynchronous submission is outstanding. | |
| virtual bool | is_in_place_operation (const std::string &descriptor_name) const |
| Check if shader modifies a specific buffer in-place. | |
| bool | is_shader_loaded () const |
| Check if shader is loaded. | |
| void | on_detach (const std::shared_ptr< Buffer > &buffer) override |
| Called when this processor is detached from a buffer. | |
| void | processing_function (const std::shared_ptr< Buffer > &buffer) override |
| The core processing function that must be implemented by derived classes. | |
| void | remove_feed (const std::string &name) |
| Remove a feed. | |
| bool | resolve_pending_dispatch (bool block) |
| Resolve an outstanding asynchronous submission. | |
| void | set_config (const ShaderConfig &config) |
| Update entire configuration. | |
| void | set_deferred_submission (bool deferred) |
| Submit asynchronously and resolve at the top of a later cycle. | |
| template<typename T > | |
| void | set_push_constant_data (const T &data) |
| Update push constant data (type-safe) | |
| virtual void | set_push_constant_data_raw (const void *data, size_t size) |
| Update push constant data (raw bytes) | |
| template<typename T > | |
| void | set_push_constant_size () |
| Set push constant size from type. | |
| void | set_push_constant_size (size_t size) |
| Set push constant size. | |
| void | set_shader (const std::string &shader_path) |
| Update shader path and reload. | |
| void | set_specialization_constant (uint32_t constant_id, uint32_t value) |
| Set specialization constant. | |
| ShaderProcessor (const std::string &shader_path) | |
| Construct processor with shader path. | |
| ShaderProcessor (ShaderConfig config) | |
| Construct processor with full configuration. | |
| void | unbind_buffer (const std::string &descriptor_name) |
| Unbind a buffer from a descriptor. | |
| ~ShaderProcessor () override | |
Public Member Functions inherited from MayaFlux::Buffers::BufferProcessor | |
| virtual ProcessingToken | get_processing_token () const |
| Gets the current processing token for this buffer. | |
| void | process (const std::shared_ptr< Buffer > &buffer) |
| Applies a computational transformation to the data in the provided buffer. | |
| virtual void | set_processing_token (ProcessingToken token) |
| Gets the preferred processing backend for this processor. | |
| virtual | ~BufferProcessor ()=default |
| Virtual destructor for proper cleanup of derived classes. | |
Protected Member Functions | |
| std::array< uint32_t, 3 > | calculate_dispatch_size (const std::shared_ptr< VKBuffer > &buffer) override |
| One thread per record in the resolved range. | |
| void | on_attach (const std::shared_ptr< Buffer > &buffer) override |
| Called when this processor is attached to a buffer. | |
| bool | on_before_execute (Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer) override |
| Rebuild on a stale revision, resolve the range, write push constants. | |
| void | on_descriptors_created () override |
| Write the cluster_id descriptor when the operator needs one. | |
Protected Member Functions inherited from MayaFlux::Buffers::ComputeProcessor | |
| void | cleanup () override |
| void | initialize_descriptors (const std::shared_ptr< VKBuffer > &buffer) override |
| void | initialize_pipeline (const std::shared_ptr< VKBuffer > &buffer) override |
| virtual bool | on_iteration (Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer, uint32_t index) |
| Called before each iteration's push constants and dispatch. | |
| virtual void | on_iteration_barrier (Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer, uint32_t index) |
| Called after each iteration except the last. | |
Protected Member Functions inherited from MayaFlux::Buffers::ShaderProcessor | |
| virtual void | on_after_execute (Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer) |
| Called after each process callback. | |
| virtual void | on_before_compile (const std::string &shader_path) |
| Called before shader compilation. | |
| virtual void | on_before_descriptors_create () |
| Called before descriptor sets are created. | |
| virtual void | on_before_pipeline_create (Portal::Graphics::ComputePipelineID pipeline_id) |
| Called before pipeline creation. | |
| virtual void | on_dispatch_complete (const std::shared_ptr< VKBuffer > &buffer) |
| Called once when an asynchronous submission is observed complete. | |
| virtual void | on_pipeline_created (Portal::Graphics::ComputePipelineID pipeline_id) |
| Called after pipeline is created. | |
| virtual void | on_shader_loaded (Portal::Graphics::ShaderID shader_id) |
| Called after shader is loaded. | |
| void | pump_feeds () |
| Pull every feed and write its result. | |
| std::optional< uint32_t > | resolve_ds_index (uint32_t set) const |
| Resolve logical descriptor set index to actual index. | |
| size_t | resolve_push_constant_size (const std::shared_ptr< VKBuffer > &buffer) const |
| Byte width of this processor's push constant block, extended to cover any fragment staged on the buffer. | |
| std::vector< uint8_t > | resolve_push_constants (const std::shared_ptr< VKBuffer > &buffer) const |
| This processor's push constant data with buffer-staged fragments overlaid at their declared offsets. | |
| void | submit_recorded (Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer) |
| Submit a recorded command buffer honoring the submission mode. | |
| virtual void | update_descriptors (const std::shared_ptr< VKBuffer > &buffer) |
Protected Member Functions inherited from MayaFlux::Buffers::VKBufferProcessor | |
| void | ensure_initialized (const std::shared_ptr< VKBuffer > &buffer) |
| void | initialize_buffer_service () |
| void | initialize_compute_service () |
Private Member Functions | |
| uint32_t | buffer_capacity (const std::shared_ptr< VKBuffer > &buffer) const |
| Records the buffer can hold at the operator's stride. | |
| float | elapsed () const |
| Seconds since construction, the value bound to the time parameter. | |
| bool | ensure_cluster_binding () |
| Ensure the backing hash_cluster_id state field exists, when m_needs_cluster_id is true. | |
| bool | sync_revision () |
| Recompile and rebuild the pipeline when the operator has changed. | |
Private Attributes | |
| uint64_t | m_built_revision {} |
| std::chrono::steady_clock::time_point | m_epoch { std::chrono::steady_clock::now() } |
| uint32_t | m_explicit_count {} |
| uint32_t | m_explicit_first {} |
| bool | m_needs_cluster_id {} |
| std::shared_ptr< NetworkGeometryBuffer > | m_network_buffer |
| std::shared_ptr< Nodes::Network::GpuFieldOperator > | m_operator |
| RangeParams | m_params |
| bool | m_range_set {} |
Compute pass that applies a GpuFieldOperator's generated shader to a range of vertex records in the attached buffer.
The general case of UVFieldProcessor. Where that one hardcodes four projections writing two fixed byte offsets, this one dispatches whatever GpuFieldOperator::build_spec() emitted: arbitrary Tendency fields written to arbitrary attributes of a layout the operator was constructed against.
Runs after the producing processor has uploaded vertex data and before RenderProcessor draws, so it belongs in the chain as a postprocessor. The attached VKBuffer is bound as an SSBO under the name "vertices"; Usage::VERTEX already carries eShaderStorageBuffer, so no separate allocation exists and nothing crosses the bus.
A NetworkGeometryBuffer aggregates one vertex slice per producing operator, so this processor addresses a range rather than the whole buffer. set_vertex_range() supplies it; left unset, the range covers every record the buffer can hold at the operator's stride, which is correct only when a single producer owns the buffer.
The dispatch is unconditional. Whatever uploaded the records overwrote last cycle's result, so the pass must re-run every cycle to stay visible. If the producing processor gains a dirty gate, this one follows the same flag rather than inventing its own: the operator holds no data and has nothing to be dirty about.
Rebinding a field at runtime changes the operator's revision. This processor notices before the next dispatch and rebuilds its pipeline from the new spec, which is what makes fields editable from Lila without tearing down the chain.
Push constant block, written here and never by the caller (16 bytes): offset 0 uint first_vertex offset 4 uint vertex_count offset 8 uint stride_words offset 12 float time
time is seconds since the processor was constructed, and it is the only varying input a field has. MF_FIELD bakes every literal into the shader text, and the producing operator re-uploads identical records each cycle, so a field of position alone evaluates to the same result forever and draws a still image. Motion comes from a field that takes time as a second argument.
Cluster-scoped bindings (GpuFieldOperator::bind's cluster argument) need a per-vertex cluster id at dispatch time. When the operator reports needs_cluster_id(), on_attach resolves the target buffer as a NetworkGeometryBuffer and calls its ensure_cluster_ids(), which declares and populates hash_cluster_id from whatever the network's own primary GraphicsOperator reports (all zero unless that operator overrides GraphicsOperator::build_cluster_ids(), which today only PhysicsOperator does) if nothing else – NetworkGeometryBuffer's own hash wiring, most commonly – has already done so. This is not particle-specific: a cluster-scoped bind() against a PointCloudNetwork or any other GraphicsOperator-backed network resolves through the same base-class default rather than silently assuming PhysicsOperator. An operator that never uses cluster-scoped bind() pays none of this: needs_cluster_id() is false, nothing here runs, and build_spec() emits exactly the shader it always has.
Definition at line 82 of file VertexFieldProcessor.hpp.