15 "ComputePress already initialized (static flag)");
22 "Cannot initialize ComputePress: ShaderFoundry not initialized");
32 "ComputePress initialized");
44 "Cannot shutdown ComputePress: ShaderFoundry not initialized");
52 "Cannot shutdown ComputePress: Vulkan device is null");
58 state.pipeline->cleanup(device);
61 if (state.layout && device) {
62 device.destroyPipelineLayout(state.layout);
76 "ComputePress shutdown complete");
85 const std::vector<std::vector<DescriptorBindingConfig>>& descriptor_sets,
86 size_t push_constant_size)
91 "Invalid shader ID: {}", shader_id);
98 "Shader is not a compute shader (stage: {})",
static_cast<int>(stage));
113 for (
const auto& set_bindings : descriptor_sets) {
116 for (
const auto& binding : set_bindings) {
120 vk::ShaderStageFlagBits::eCompute,
128 pipeline_config.
shader = shader_module;
131 if (push_constant_size > 0) {
133 vk::ShaderStageFlagBits::eCompute,
134 static_cast<uint32_t
>(push_constant_size));
137 state.
pipeline = std::make_shared<Core::VKComputePipeline>();
138 if (!state.
pipeline->create(device, pipeline_config)) {
140 "Failed to create compute pipeline");
148 "Created compute pipeline (ID: {}, {} descriptor sets, {} bytes push constants)",
149 id, state.
layouts.size(), push_constant_size);
156 size_t push_constant_size)
160 std::map<uint32_t, std::vector<DescriptorBindingConfig>> bindings_by_set;
161 for (
const auto& binding : reflection.descriptor_bindings) {
163 config.
set = binding.set;
164 config.
binding = binding.binding;
165 config.
type = binding.type;
166 bindings_by_set[binding.set].push_back(config);
169 std::vector<std::vector<DescriptorBindingConfig>> descriptor_sets;
170 descriptor_sets.reserve(bindings_by_set.size());
171 for (
const auto& [set_index, bindings] : bindings_by_set) {
172 descriptor_sets.push_back(bindings);
175 size_t pc_size = push_constant_size;
176 if (pc_size == 0 && !reflection.push_constant_ranges.empty()) {
177 pc_size = reflection.push_constant_ranges[0].size;
181 "Auto-creating pipeline: {} descriptor sets, {} bindings total",
182 descriptor_sets.size(), reflection.descriptor_bindings.size());
196 if (it->second.pipeline) {
197 it->second.pipeline->cleanup(device);
200 if (it->second.layout) {
201 device.destroyPipelineLayout(it->second.layout);
207 "Destroyed compute pipeline (ID: {})", pipeline_id);
219 "Invalid pipeline ID: {}", pipeline_id);
226 "Invalid command buffer ID: {}", cmd_id);
230 pipeline_it->second.pipeline->bind(cmd);
236 const std::vector<DescriptorSetID>& descriptor_set_ids)
241 "Invalid pipeline ID: {}", pipeline_id);
248 "Invalid command buffer ID: {}", cmd_id);
252 std::vector<vk::DescriptorSet> vk_sets;
253 for (
auto ds_id : descriptor_set_ids) {
257 pipeline_it->second.pipeline->bind_descriptor_sets(cmd, vk_sets);
269 "Invalid pipeline ID: {}", pipeline_id);
276 "Invalid command buffer ID: {}", cmd_id);
280 pipeline_it->second.pipeline->push_constants(
282 vk::ShaderStageFlagBits::eCompute,
284 static_cast<uint32_t
>(size),
297 "Invalid command buffer ID: {}", cmd_id);
301 cmd.dispatch(x, y, z);
304 "Dispatched compute: {}x{}x{} workgroups", x, y, z);
309 vk::Buffer indirect_buffer,
310 vk::DeviceSize offset)
315 "Invalid command buffer ID: {}", cmd_id);
319 cmd.dispatchIndirect(indirect_buffer, offset);
322 "Dispatched compute indirect from buffer");
334 "Invalid pipeline ID: {}", pipeline_id);
338 std::vector<DescriptorSetID> descriptor_set_ids;
339 for (
const auto& layout : pipeline_it->second.layouts) {
343 "Failed to allocate descriptor set for pipeline {}", pipeline_id);
346 descriptor_set_ids.push_back(ds_id);
350 "Allocated {} descriptor sets for pipeline {}",
351 descriptor_set_ids.size(), pipeline_id);
353 return descriptor_set_ids;
359 const std::vector<DescriptorSetID>& descriptor_set_ids,
360 const void* push_constants_data,
361 size_t push_constant_size)
366 if (push_constants_data && push_constant_size > 0) {
367 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.
std::unordered_map< ComputePipelineID, PipelineState > m_pipelines
ComputePipelineID create_pipeline(ShaderID shader_id, const std::vector< std::vector< DescriptorBindingConfig > > &descriptor_sets={}, size_t push_constant_size=0)
Create compute pipeline.
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
Portal-level descriptor binding configuration.