12 : m_config(shader_path)
20 : m_config(
std::move(config))
37 auto vk_buffer = std::dynamic_pointer_cast<VKBuffer>(buffer);
40 "ShaderProcessor can only process VKBuffers");
67 auto vk_buffer = std::dynamic_pointer_cast<VKBuffer>(buffer);
76 "ShaderProcessor attached to VKBuffer (size: {} bytes, modality: {})",
77 vk_buffer->get_size_bytes(),
78 static_cast<int>(vk_buffer->get_modality()));
83 auto vk_buffer = std::dynamic_pointer_cast<VKBuffer>(buffer);
88 if (it->second == vk_buffer) {
99 return std::dynamic_pointer_cast<VKBuffer>(buffer) !=
nullptr;
110 "Cannot bind null buffer to descriptor '{}'", descriptor_name);
116 default_binding.
set = 0;
118 default_binding.
type = vk::DescriptorType::eStorageBuffer;
151 std::string descriptor_name;
153 descriptor_name =
"input";
155 descriptor_name =
"output";
191 "Shader hot-reloaded successfully (ID: {})",
m_shader_id);
227 std::function<std::array<uint32_t, 3>(
const std::shared_ptr<VKBuffer>&)> calculator)
248 "Push constant data size {} exceeds configured size {}",
297 if (descriptor_name ==
"input")
299 if (descriptor_name ==
"output")
317 std::vector<std::string> names;
320 names.push_back(name);
352 case DispatchMode::MANUAL:
355 case DispatchMode::ELEMENT_COUNT: {
356 uint64_t element_count = 0;
357 const auto& dimensions = buffer->get_dimensions();
359 if (!dimensions.empty()) {
360 element_count = dimensions[0].size;
362 element_count = buffer->get_size_bytes() /
sizeof(float);
365 auto groups_x =
static_cast<uint32_t
>(
367 return { groups_x, 1, 1 };
370 case DispatchMode::BUFFER_SIZE: {
371 uint64_t size_bytes = buffer->get_size_bytes();
372 auto groups_x =
static_cast<uint32_t
>(
374 return { groups_x, 1, 1 };
377 case DispatchMode::CUSTOM:
415 "Cannot create pipeline without shader");
421 std::map<uint32_t, std::vector<std::pair<std::string, ShaderBinding>>> bindings_by_set;
423 bindings_by_set[binding.set].emplace_back(name, binding);
426 std::vector<std::vector<Portal::Graphics::DescriptorBindingConfig>> descriptor_sets;
427 for (
const auto& [set_index, set_bindings] : bindings_by_set) {
428 std::vector<Portal::Graphics::DescriptorBindingConfig>
set_config;
429 for (
const auto& [name, binding] : set_bindings) {
430 set_config.emplace_back(binding.set, binding.binding, binding.type);
442 "Failed to create compute pipeline");
449 "Compute pipeline created (ID: {}, {} descriptor sets, {} bytes push constants)",
457 "Cannot allocate descriptor sets without pipeline");
469 "Failed to allocate descriptor sets");
494 const auto& binding = binding_it->second;
498 "Invalid descriptor set index {} for binding '{}'",
499 binding.set, descriptor_name);
503 foundry.update_descriptor_buffer(
507 buffer->get_buffer(),
509 buffer->get_size_bytes());
517 "Cannot dispatch without pipeline and descriptors");
534 compute_press.push_constants(
544 compute_press.dispatch(cmd_id, dispatch_size[0], dispatch_size[1], dispatch_size[2]);
548 foundry.buffer_barrier(
550 buffer->get_buffer(),
551 vk::AccessFlagBits::eShaderWrite,
552 vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eTransferRead,
553 vk::PipelineStageFlagBits::eComputeShader,
554 vk::PipelineStageFlagBits::eComputeShader | vk::PipelineStageFlagBits::eTransfer);
556 foundry.submit_and_wait(cmd_id);
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void execute_dispatch(const std::shared_ptr< VKBuffer > &buffer)
void update_descriptors()
Portal::Graphics::CommandBufferID m_last_command_buffer
bool are_bindings_complete() const
Check if all required bindings are satisfied.
std::unordered_map< std::string, std::shared_ptr< VKBuffer > > m_bound_buffers
virtual void on_before_dispatch(Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer)
Called before each dispatch.
void unbind_buffer(const std::string &descriptor_name)
Unbind a buffer from a descriptor.
Portal::Graphics::ShaderID m_shader_id
std::vector< uint8_t > m_push_constant_data
bool is_compatible_with(std::shared_ptr< Buffer > buffer) const override
Checks if this processor can handle the specified buffer type.
virtual void on_descriptors_created()
Called after descriptor sets are created.
bool m_needs_descriptor_rebuild
std::shared_ptr< VKBuffer > get_bound_buffer(const std::string &descriptor_name) const
Get bound buffer for a descriptor name.
void initialize_descriptors()
void processing_function(std::shared_ptr< Buffer > buffer) override
The core processing function that must be implemented by derived classes.
void set_workgroup_size(uint32_t x, uint32_t y=1, uint32_t z=1)
Set workgroup size (should match shader local_size)
void set_dispatch_mode(ShaderDispatchConfig::DispatchMode mode)
Set dispatch mode.
virtual void on_before_compile(const std::string &shader_path)
Called before shader compilation.
void auto_bind_buffer(const std::shared_ptr< VKBuffer > &buffer)
Auto-bind buffer based on attachment order.
void set_manual_dispatch(uint32_t x, uint32_t y=1, uint32_t z=1)
Set manual dispatch group counts.
bool has_binding(const std::string &descriptor_name) const
Check if a descriptor binding exists.
void on_detach(std::shared_ptr< Buffer > buffer) override
Called when this processor is detached from a buffer.
void set_push_constant_size()
Set push constant size from type.
Portal::Graphics::ComputePipelineID m_pipeline_id
virtual std::array< uint32_t, 3 > calculate_dispatch_size(const std::shared_ptr< VKBuffer > &buffer)
Calculate dispatch size from buffer.
virtual void on_pipeline_created(Portal::Graphics::ComputePipelineID pipeline_id)
Called after pipeline is created.
~ShaderProcessor() override
ShaderProcessorConfig m_config
virtual bool is_in_place_operation(const std::string &descriptor_name) const
Check if shader modifies a specific buffer in-place.
virtual void on_shader_loaded(Portal::Graphics::ShaderID shader_id)
Called after shader is loaded.
std::shared_ptr< VKBuffer > m_last_processed_buffer
void add_binding(const std::string &descriptor_name, const ShaderBinding &binding)
Add descriptor binding configuration.
bool hot_reload_shader()
Hot-reload shader from ShaderFoundry.
virtual void on_before_descriptors_create()
Called before descriptor sets are created.
void set_shader(const std::string &shader_path)
Update shader path and reload.
virtual void on_after_dispatch(Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr< VKBuffer > &buffer)
Called after each dispatch.
void set_config(const ShaderProcessorConfig &config)
Update entire configuration.
virtual BufferUsageHint get_buffer_usage_hint(const std::string &descriptor_name) const
Get buffer usage hint for a descriptor.
BufferUsageHint
Get buffer usage characteristics needed for safe data flow.
@ OUTPUT_WRITE
Shader writes output (modifies)
@ INPUT_READ
Shader reads input.
std::vector< std::string > get_binding_names() const
Get all configured descriptor names.
void set_specialization_constant(uint32_t constant_id, uint32_t value)
Set specialization constant.
void on_attach(std::shared_ptr< Buffer > buffer) override
Called when this processor is attached to a buffer.
bool m_needs_pipeline_rebuild
void set_custom_dispatch(std::function< std::array< uint32_t, 3 >(const std::shared_ptr< VKBuffer > &)> calculator)
Set custom dispatch calculator.
void bind_buffer(const std::string &descriptor_name, const std::shared_ptr< VKBuffer > &buffer)
Bind a VKBuffer to a named shader descriptor.
virtual void initialize_pipeline(const std::shared_ptr< Buffer > &buffer)
std::vector< Portal::Graphics::DescriptorSetID > m_descriptor_set_ids
void clear_specialization_constants()
Clear all specialization constants.
ShaderProcessor(const std::string &shader_path, uint32_t workgroup_x=256)
Construct processor with shader path.
void set_push_constant_data_raw(const void *data, size_t size)
Update push constant data (raw bytes)
void initialize_compute_service()
void initialize_buffer_service()
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
uint64_t ComputePipelineID
constexpr ShaderID INVALID_SHADER
MAYAFLUX_API ShaderFoundry & get_shader_foundry()
Get the global shader compiler instance.
constexpr ComputePipelineID INVALID_COMPUTE_PIPELINE
MAYAFLUX_API ComputePress & get_compute_press()
uint32_t binding
Binding point within set.
uint32_t set
Descriptor set index.
Describes how a VKBuffer binds to a shader descriptor.
enum MayaFlux::Buffers::ShaderDispatchConfig::DispatchMode mode
std::function< std::array< uint32_t, 3 >(const std::shared_ptr< VKBuffer > &)> custom_calculator
@ CUSTOM
User-provided calculation function.
@ MANUAL
Use explicit group counts.
uint32_t workgroup_x
Workgroup size X (should match shader)
ShaderDispatchConfig dispatch
std::unordered_map< uint32_t, uint32_t > specialization_constants
size_t push_constant_size
std::unordered_map< std::string, ShaderBinding > bindings
Portal::Graphics::ShaderStage stage
std::string shader_path
Path to shader file.
Complete configuration for shader processor.