MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
ComputePress.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "ShaderFoundry.hpp"
4
6
7using ComputePipelineID = uint64_t;
8
10
11//==========================================================================
12// Multi-Pipeline Sequencing
13//==========================================================================
14
15/**
16 * @struct HazardResource
17 * @brief One resource this stage's dispatch reads/writes that a later
18 * stage in the sequence depends on, paired with its binding
19 * metadata for barrier construction.
20 *
21 * ComputePress owns no resource registry (that lives in callers like
22 * Yantra::GpuResourceManager), so the raw handle must travel with the
23 * binding description rather than being looked up by index.
24 */
26 GpuBufferBinding binding; ///< Direction/element_type describing this resource.
27 vk::Image image; ///< Valid when binding.element_type is IMAGE_STORAGE/IMAGE_SAMPLED.
28 vk::Buffer buffer; ///< Valid when binding.element_type is anything else.
29};
30
31/**
32 * @struct ComputeStage
33 * @brief One pipeline dispatch within a ComputePress::record_sequence call.
34 *
35 * Bundles everything needed to bind a pipeline, push constants, dispatch,
36 * and determine the barrier owed to the next stage in the sequence.
37 * Pipeline and descriptor sets must already exist (created via
38 * create_pipeline / allocate_pipeline_descriptors) — this struct only
39 * describes how to use them within a recorded sequence, it does not
40 * own their lifetime.
41 */
43 ComputePipelineID pipeline_id; ///< Pipeline to bind for this stage.
44 std::vector<DescriptorSetID> descriptor_set_ids; ///< Descriptor sets to bind.
45 std::array<uint32_t, 3> groups; ///< Workgroup dispatch counts {x, y, z}.
46 std::vector<uint8_t> push_constant_data; ///< Raw push constant bytes for this stage.
47
48 /**
49 * @brief Resources this stage reads or writes that a subsequent
50 * stage in the same sequence depends on.
51 *
52 * Drives the compute-to-compute barrier inserted immediately after
53 * this stage's dispatch, before the next stage binds its pipeline.
54 * Only entries whose binding.direction is INPUT_OUTPUT trigger a
55 * barrier; include a resource here if a later stage must observe
56 * this stage's writes to it. Leave empty if nothing downstream
57 * depends on this stage's output within the sequence.
58 */
59 std::vector<HazardResource> hazard_resources;
60};
61
62/**
63 * @class ComputePress
64 * @brief Compute-specific pipeline and dispatch orchestration
65 *
66 * Responsibilities:
67 * - Create compute pipelines
68 * - Bind compute pipelines
69 * - Dispatch compute workgroups (direct + indirect)
70 * - Compute-specific optimizations
71 *
72 * Uses ShaderFoundry for:
73 * - Shaders, descriptors, commands, sync, barriers
74 */
75class MAYAFLUX_API ComputePress {
76public:
78 {
79 static ComputePress press;
80 return press;
81 }
82
83 ComputePress(const ComputePress&) = delete;
85 ComputePress(ComputePress&&) noexcept = delete;
86 ComputePress& operator=(ComputePress&&) noexcept = delete;
87
88 bool initialize();
89 void stop();
90 void shutdown();
91
92 //==========================================================================
93 // Pipeline Creation (COMPUTE-SPECIFIC)
94 //==========================================================================
95
96 /**
97 * @brief Create compute pipeline
98 */
99 ComputePipelineID create_pipeline(
100 ShaderID shader_id,
101 const std::vector<std::vector<DescriptorBindingInfo>>& descriptor_sets = {},
102 size_t push_constant_size = 0);
103
104 /**
105 * @brief Create pipeline with auto-reflection
106 */
107 ComputePipelineID create_pipeline_auto(
108 ShaderID shader_id,
109 size_t push_constant_size = 0);
110
111 void destroy_pipeline(ComputePipelineID pipeline_id);
112
113 //==========================================================================
114 // Pipeline Binding (COMPUTE-SPECIFIC)
115 //==========================================================================
116
117 /**
118 * @brief Bind pipeline to active command buffer
119 */
120 void bind_pipeline(CommandBufferID cmd_id, ComputePipelineID pipeline_id);
121
122 /**
123 * @brief Bind descriptor sets to active command buffer
124 */
125 void bind_descriptor_sets(
126 CommandBufferID cmd_id,
127 ComputePipelineID pipeline_id,
128 const std::vector<DescriptorSetID>& descriptor_set_ids);
129
130 /**
131 * @brief Push constants to active command buffer
132 */
133 void push_constants(
134 CommandBufferID cmd_id,
135 ComputePipelineID pipeline_id,
136 const void* data,
137 size_t size);
138
139 //==========================================================================
140 // Dispatch (COMPUTE-SPECIFIC)
141 //==========================================================================
142
143 /**
144 * @brief Dispatch compute workgroups
145 */
146 void dispatch(CommandBufferID cmd_id, uint32_t x, uint32_t y, uint32_t z);
147
148 /**
149 * @brief Dispatch compute workgroups indirectly
150 */
151 void dispatch_indirect(
152 CommandBufferID cmd_id,
153 vk::Buffer indirect_buffer,
154 vk::DeviceSize offset = 0);
155
156 //==========================================================================
157 // Convenience Wrappers
158 //==========================================================================
159
160 /**
161 * @brief All-in-one: allocate descriptors for pipeline
162 */
163 std::vector<DescriptorSetID> allocate_pipeline_descriptors(ComputePipelineID pipeline_id);
164
165 /**
166 * @brief All-in-one: bind pipeline + descriptors + push constants
167 */
168 void bind_all(
169 CommandBufferID cmd_id,
170 ComputePipelineID pipeline_id,
171 const std::vector<DescriptorSetID>& descriptor_set_ids,
172 const void* push_constants_data = nullptr,
173 size_t push_constant_size = 0);
174
175 /**
176 * @brief Record multiple pipeline dispatches into one already-open
177 * command buffer, inserting a barrier between each consecutive
178 * stage for that stage's hazard_bindings.
179 *
180 * Vulkan permits binding different pipelines sequentially within a
181 * single command buffer recording — this is not a render-pass-style
182 * batching mechanism, only direct multi-pipeline recording plus the
183 * hazard barriers each transition needs. Does not submit; caller owns
184 * the command buffer's lifetime via ShaderFoundry (begin_commands /
185 * submit_and_wait or submit_async), the same as any other recorded
186 * sequence of commands.
187 *
188 * Image bindings receive an eGeneral -> eGeneral shader write/read
189 * hazard barrier via ShaderFoundry::image_barrier. Non-image bindings
190 * receive a buffer_barrier with the same access/stage masks. Both use
191 * compute-to-compute pipeline stages throughout, since this method is
192 * for chaining compute stages only.
193 *
194 * @param cmd_id Command buffer to record into. Must already be active
195 * (begun via ShaderFoundry::begin_commands).
196 * @param stages Ordered list of pipeline dispatches to record.
197 */
198 void record_sequence(CommandBufferID cmd_id, const std::vector<ComputeStage>& stages);
199
200private:
201 ComputePress() = default;
202 ~ComputePress() { shutdown(); }
203 void cleanup_pipelines();
204
207 std::shared_ptr<Core::VKComputePipeline> pipeline;
208 std::vector<vk::DescriptorSetLayout> layouts;
209 vk::PipelineLayout layout;
210 };
211
212 std::shared_ptr<Core::VKDescriptorManager> m_descriptor_manager;
213 std::unordered_map<ComputePipelineID, PipelineState> m_pipelines;
214 std::atomic<uint64_t> m_next_pipeline_id { 1 };
215 ShaderFoundry* m_shader_foundry = nullptr;
216
217 static bool s_initialized;
218};
219
220inline MAYAFLUX_API ComputePress& get_compute_press()
221{
222 return ComputePress::instance();
223}
224
225} // namespace MayaFlux::Portal::Graphics
float offset
ComputePress & operator=(const ComputePress &)=delete
ComputePress(ComputePress &&) noexcept=delete
std::unordered_map< ComputePipelineID, PipelineState > m_pipelines
ComputePress(const ComputePress &)=delete
std::shared_ptr< Core::VKDescriptorManager > m_descriptor_manager
Compute-specific pipeline and dispatch orchestration.
Portal-level shader compilation and caching.
void initialize()
Definition main.cpp:11
constexpr ComputePipelineID INVALID_COMPUTE_PIPELINE
MAYAFLUX_API ComputePress & get_compute_press()
std::vector< vk::DescriptorSetLayout > layouts
std::shared_ptr< Core::VKComputePipeline > pipeline
ComputePipelineID pipeline_id
Pipeline to bind for this stage.
std::vector< uint8_t > push_constant_data
Raw push constant bytes for this stage.
std::array< uint32_t, 3 > groups
Workgroup dispatch counts {x, y, z}.
std::vector< DescriptorSetID > descriptor_set_ids
Descriptor sets to bind.
std::vector< HazardResource > hazard_resources
Resources this stage reads or writes that a subsequent stage in the same sequence depends on.
One pipeline dispatch within a ComputePress::record_sequence call.
Declares a single storage buffer or image binding a compute shader expects.
vk::Buffer buffer
Valid when binding.element_type is anything else.
vk::Image image
Valid when binding.element_type is IMAGE_STORAGE/IMAGE_SAMPLED.
GpuBufferBinding binding
Direction/element_type describing this resource.
One resource this stage's dispatch reads/writes that a later stage in the sequence depends on,...