15 "ComputePress already initialized (static flag)");
22 "Cannot initialize ComputePress: ShaderFoundry not initialized");
32 "ComputePress initialized");
43 "ComputePress stopped");
53 "Shutting down ComputePress...");
57 "Cannot shutdown ComputePress: ShaderFoundry not initialized");
65 "Cannot shutdown ComputePress: Vulkan device is null");
82 "ComputePress shutdown complete");
91 const std::vector<std::vector<DescriptorBindingInfo>>& descriptor_sets,
92 size_t push_constant_size)
97 "Invalid shader ID: {}", shader_id);
104 "Shader is not a compute shader (stage: {})",
static_cast<int>(stage));
119 for (
const auto& set_bindings : descriptor_sets) {
122 for (
const auto& binding : set_bindings) {
126 vk::ShaderStageFlagBits::eCompute,
134 pipeline_config.
shader = shader_module;
137 if (push_constant_size > 0) {
139 vk::ShaderStageFlagBits::eCompute,
140 static_cast<uint32_t
>(push_constant_size));
143 state.
pipeline = std::make_shared<Core::VKComputePipeline>();
144 if (!state.
pipeline->create(device, pipeline_config)) {
146 "Failed to create compute pipeline");
154 "Created compute pipeline (ID: {}, {} descriptor sets, {} bytes push constants)",
155 id, state.
layouts.size(), push_constant_size);
162 size_t push_constant_size)
166 std::map<uint32_t, std::vector<DescriptorBindingInfo>> bindings_by_set;
167 for (
const auto& binding : reflection.descriptor_bindings) {
169 config.
set = binding.set;
170 config.
binding = binding.binding;
171 config.
type = binding.type;
172 bindings_by_set[binding.set].push_back(config);
175 std::vector<std::vector<DescriptorBindingInfo>> descriptor_sets;
176 descriptor_sets.reserve(bindings_by_set.size());
177 for (
const auto& [set_index, bindings] : bindings_by_set) {
178 descriptor_sets.push_back(bindings);
181 size_t pc_size = push_constant_size;
182 if (pc_size == 0 && !reflection.push_constant_ranges.empty()) {
183 pc_size = reflection.push_constant_ranges[0].size;
187 "Auto-creating pipeline: {} descriptor sets, {} bindings total",
188 descriptor_sets.size(), reflection.descriptor_bindings.size());
202 if (it->second.pipeline) {
203 it->second.pipeline->cleanup(device);
206 if (it->second.layout) {
207 device.destroyPipelineLayout(it->second.layout);
213 "Destroyed compute pipeline (ID: {})", pipeline_id);
221 if (state.pipeline) {
222 state.pipeline->cleanup(device);
226 device.destroyPipelineLayout(state.layout);
231 "Cleaned up all compute pipelines");
243 "Invalid pipeline ID: {}", pipeline_id);
250 "Invalid command buffer ID: {}", cmd_id);
254 pipeline_it->second.pipeline->bind(cmd);
260 const std::vector<DescriptorSetID>& descriptor_set_ids)
265 "Invalid pipeline ID: {}", pipeline_id);
272 "Invalid command buffer ID: {}", cmd_id);
276 std::vector<vk::DescriptorSet> vk_sets;
277 for (
auto ds_id : descriptor_set_ids) {
281 pipeline_it->second.pipeline->bind_descriptor_sets(cmd, vk_sets);
293 "Invalid pipeline ID: {}", pipeline_id);
300 "Invalid command buffer ID: {}", cmd_id);
304 pipeline_it->second.pipeline->push_constants(
306 vk::ShaderStageFlagBits::eCompute,
308 static_cast<uint32_t
>(size),
321 "Invalid command buffer ID: {}", cmd_id);
325 cmd.dispatch(x, y, z);
328 "Dispatched compute: {}x{}x{} workgroups", x, y, z);
333 vk::Buffer indirect_buffer,
334 vk::DeviceSize offset)
339 "Invalid command buffer ID: {}", cmd_id);
343 cmd.dispatchIndirect(indirect_buffer, offset);
346 "Dispatched compute indirect from buffer");
358 "Invalid pipeline ID: {}", pipeline_id);
362 std::vector<DescriptorSetID> descriptor_set_ids;
363 for (
const auto& layout : pipeline_it->second.layouts) {
367 "Failed to allocate descriptor set for pipeline {}", pipeline_id);
370 descriptor_set_ids.push_back(ds_id);
374 "Allocated {} descriptor sets for pipeline {}",
375 descriptor_set_ids.size(), pipeline_id);
377 return descriptor_set_ids;
383 const std::vector<DescriptorSetID>& descriptor_set_ids,
384 const void* push_constants_data,
385 size_t push_constant_size)
390 if (push_constants_data && push_constant_size > 0) {
391 this->
push_constants(cmd_id, pipeline_id, push_constants_data, push_constant_size);
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
ShaderFoundry * m_shader_foundry
void destroy_pipeline(ComputePipelineID pipeline_id)
void push_constants(CommandBufferID cmd_id, ComputePipelineID pipeline_id, const void *data, size_t size)
Push constants to active command buffer.
void bind_pipeline(CommandBufferID cmd_id, ComputePipelineID pipeline_id)
Bind pipeline to active command buffer.
std::vector< DescriptorSetID > allocate_pipeline_descriptors(ComputePipelineID pipeline_id)
All-in-one: allocate descriptors for pipeline.
void bind_all(CommandBufferID cmd_id, ComputePipelineID pipeline_id, const std::vector< DescriptorSetID > &descriptor_set_ids, const void *push_constants_data=nullptr, size_t push_constant_size=0)
All-in-one: bind pipeline + descriptors + push constants.
void dispatch(CommandBufferID cmd_id, uint32_t x, uint32_t y, uint32_t z)
Dispatch compute workgroups.
std::atomic< uint64_t > m_next_pipeline_id
void bind_descriptor_sets(CommandBufferID cmd_id, ComputePipelineID pipeline_id, const std::vector< DescriptorSetID > &descriptor_set_ids)
Bind descriptor sets to active command buffer.
ComputePipelineID create_pipeline(ShaderID shader_id, const std::vector< std::vector< DescriptorBindingInfo > > &descriptor_sets={}, size_t push_constant_size=0)
Create compute pipeline.
std::unordered_map< ComputePipelineID, PipelineState > m_pipelines
void dispatch_indirect(CommandBufferID cmd_id, vk::Buffer indirect_buffer, vk::DeviceSize offset=0)
Dispatch compute workgroups indirectly.
static bool s_initialized
ComputePipelineID create_pipeline_auto(ShaderID shader_id, size_t push_constant_size=0)
Create pipeline with auto-reflection.
std::shared_ptr< Core::VKDescriptorManager > m_descriptor_manager
vk::DescriptorSet get_descriptor_set(DescriptorSetID descriptor_set_id)
Get Vulkan descriptor set handle from DescriptorSetID.
vk::Device get_device() const
std::shared_ptr< Core::VKShaderModule > get_vk_shader_module(ShaderID shader_id)
bool is_initialized() const
Check if compiler is initialized.
vk::CommandBuffer get_command_buffer(CommandBufferID cmd_id)
Get Vulkan command buffer handle from CommandBufferID.
ShaderReflectionInfo get_shader_reflection(ShaderID shader_id)
Get reflection info for compiled shader.
ShaderStage get_shader_stage(ShaderID shader_id)
Get shader stage for compiled shader.
DescriptorSetID allocate_descriptor_set(vk::DescriptorSetLayout layout)
Allocate descriptor set for a pipeline.
@ GPUCompute
GPU compute operations (shaders, GPGPU tasks)
@ Portal
High-level user-facing API layer.
uint64_t ComputePipelineID
MAYAFLUX_API ShaderFoundry & get_shader_foundry()
Get the global shader compiler instance.
constexpr ComputePipelineID INVALID_COMPUTE_PIPELINE
constexpr DescriptorSetID INVALID_DESCRIPTOR_SET
std::vector< vk::DescriptorSetLayout > set_layouts
Descriptor layouts.
std::shared_ptr< VKShaderModule > shader
Compute shader.
void add_push_constant(vk::ShaderStageFlags stages, uint32_t size, uint32_t offset=0)
Configuration for creating a compute pipeline.
void add_binding(uint32_t binding, vk::DescriptorType type, vk::ShaderStageFlags stages, uint32_t count=1)
Configuration for creating a descriptor set layout.
vk::PipelineLayout layout
std::vector< vk::DescriptorSetLayout > layouts
std::shared_ptr< Core::VKComputePipeline > pipeline