MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
RenderProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
5#include "ShaderProcessor.hpp"
6
7namespace MayaFlux::Core {
8class VKImage;
9}
10
11namespace MayaFlux::Buffers {
12
13/**
14 * @class RenderShaderProcessor
15 * @brief Graphics rendering processor - inherits from ShaderProcessor
16 *
17 * Overrides pipeline creation to use RenderFlow instead of ComputePress.
18 * Records draw commands but does NOT submit/present.
19 */
20class MAYAFLUX_API RenderProcessor : public ShaderProcessor {
21public:
22 RenderProcessor(const ShaderConfig& config);
23
25 {
26 cleanup();
27 }
28
29 void set_geometry_shader(const std::string& geometry_path);
30 void set_tess_control_shader(const std::string& tess_control_path);
31 void set_tess_eval_shader(const std::string& tess_eval_path);
32 void set_fragment_shader(const std::string& fragment_path);
33 void set_target_window(const std::shared_ptr<Core::Window>& window, const std::shared_ptr<VKBuffer>& buffer);
34
36
37 void on_attach(const std::shared_ptr<Buffer>& buffer) override;
38
39 /// Set primitive topology (e.g., triangle list, line list, point list)
41 {
42 m_primitive_topology = topology;
43 m_needs_pipeline_rebuild = true;
44 }
45
46 /// Set polygon mode (e.g., fill, line, point)
48 {
49 m_polygon_mode = mode;
50 m_needs_pipeline_rebuild = true;
51 }
52
53 /// Set cull mode (e.g., none, front, back)
55 {
56 m_cull_mode = mode;
57 m_needs_pipeline_rebuild = true;
58 }
59
60 /**
61 * @brief Bind a texture to a descriptor binding point
62 * @param binding Binding index (matches shader layout(binding = N))
63 * @param texture VKImage texture to bind
64 * @param sampler Optional sampler (uses default linear if null)
65 */
66 void bind_texture(
67 uint32_t binding,
68 const std::shared_ptr<Core::VKImage>& texture,
69 vk::Sampler sampler = nullptr);
70
71 /**
72 * @brief Bind a texture to a named descriptor
73 * @param descriptor_name Logical name (must be in config.bindings)
74 * @param texture VKImage texture to bind
75 * @param sampler Optional sampler (uses default linear if null)
76 */
77 void bind_texture(
78 const std::string& descriptor_name,
79 const std::shared_ptr<Core::VKImage>& texture,
80 vk::Sampler sampler = nullptr);
81
82 /**
83 * @brief Check if pipeline is created
84 */
85 bool is_pipeline_ready() const { return m_pipeline_id != Portal::Graphics::INVALID_RENDER_PIPELINE; }
86
87 /**
88 * @brief Set vertex range for drawing subset of buffer
89 * @param first_vertex Starting vertex index in buffer
90 * @param vertex_count Number of vertices to draw
91 *
92 * Enables drawing a specific range of vertices from the bound buffer.
93 * Used for composite geometry where multiple collections are aggregated
94 * into a single buffer but rendered with different topologies.
95 *
96 * Default: draws all vertices (first_vertex=0, vertex_count=0 means "use layout count")
97 */
98 void set_vertex_range(uint32_t first_vertex, uint32_t vertex_count);
99
100 /**
101 * @brief Override the vertex layout used when building the pipeline for buffer
102 * @param buffer Target buffer (key into m_buffer_info)
103 * @param layout Layout specific to this processor's topology
104 *
105 * Called by CompositeGeometryBuffer to give each RenderProcessor its own
106 * topology-specific layout rather than the shared aggregate on the VKBuffer.
107 * Triggers a pipeline rebuild on the next execute_shader() call.
108 */
109 void set_buffer_vertex_layout(
110 const std::shared_ptr<VKBuffer>& buffer,
111 const Kakshya::VertexLayout& layout);
112
113 /**
114 * @brief Set blend mode for color attachment
115 * @param config Blend attachment configuration
116 */
118 {
119 m_blend_attachment = config;
120 m_needs_pipeline_rebuild = true;
121 }
122
123 /** @brief Enable standard alpha blending (src_alpha, one_minus_src_alpha). Does not touch depth state. */
124 void enable_alpha_blending();
125
126 /** @brief Disable blending on the color attachment, restoring opaque writes. Does not touch depth state. */
127 void disable_alpha_blending();
128
129 /**
130 * @brief Toggle standard alpha blending.
131 * @param enabled true enables src_alpha/one_minus_src_alpha blending, false restores opaque.
132 *
133 * Blending and depth are independent. Toggling blend never changes depth
134 * test or depth write; use enable_depth_test / disable_depth_test for that.
135 */
136 void set_alpha_blending(bool enabled);
137
138 /** @brief Query whether the color attachment currently has blending enabled. */
139 [[nodiscard]] bool is_alpha_blending_enabled() const
140 {
141 return m_blend_attachment.has_value() && m_blend_attachment->blend_enable;
142 }
143
144 /**
145 * @brief Enable depth testing for this processor's pipeline
146 * @param compare_op Depth comparison operation (default: LESS)
147 *
148 * Marks the owning buffer as requiring a depth attachment.
149 * Pipeline will be created with D32_SFLOAT depth format.
150 */
151 void enable_depth_test(Portal::Graphics::CompareOp compare_op = Portal::Graphics::CompareOp::LESS);
152
153 /**
154 * @brief Disable depth testing and depth writes for this processor's pipeline.
155 *
156 * Leaves the buffer's depth attachment requirement intact so the pass still
157 * has a depth buffer available; only the per-pipeline test and write are off.
158 */
159 void disable_depth_test();
160
161 /**
162 * @brief Set static view transform (evaluated once)
163 * @param vt View and projection matrices
164 *
165 * Automatically enables depth testing and configures push
166 * constant size for the 128-byte ViewTransform block.
167 */
168 void set_view_transform(const Kinesis::ViewTransform& vt);
169
170 /**
171 * @brief Set dynamic view transform source (evaluated every frame)
172 * @param fn Callable returning ViewTransform, invoked each execute_shader
173 *
174 * Automatically enables depth testing and configures push
175 * constant size for the 128-byte ViewTransform block.
176 */
177 void set_view_transform_source(std::function<Kinesis::ViewTransform()> fn);
178
179 /** @brief Get current static view transform, if set */
180 const std::optional<Kinesis::ViewTransform>& get_view_transform() const { return m_view_transform; }
181
182 /** @brief Get current dynamic view transform source, if set */
183 const std::function<Kinesis::ViewTransform()>& get_view_transform_source() const { return m_view_transform_source; }
184
185 /**
186 * @brief Set number of instances for the next draw call.
187 * @param count Instance count. 1 is the default (non-instanced draw).
188 */
189 void set_instance_count(uint32_t count) { m_instance_count = count; }
190 [[nodiscard]] uint32_t get_instance_count() const { return m_instance_count; }
191
192protected:
193 void initialize_pipeline(const std::shared_ptr<VKBuffer>& buffer) override;
194 void execute_shader(const std::shared_ptr<VKBuffer>& buffer) override;
195 void initialize_descriptors(const std::shared_ptr<VKBuffer>& buffer) override;
196
197 bool on_before_execute(Portal::Graphics::CommandBufferID cmd_id, const std::shared_ptr<VKBuffer>& buffer) override;
198
199 void cleanup() override;
200
201private:
202 struct VertexInfo {
204 bool use_reflection {};
205 };
206
207 Portal::Graphics::RenderPipelineID m_pipeline_id = Portal::Graphics::INVALID_RENDER_PIPELINE;
208 Portal::Graphics::ShaderID m_geometry_shader_id = Portal::Graphics::INVALID_SHADER;
209 Portal::Graphics::ShaderID m_tess_control_shader_id = Portal::Graphics::INVALID_SHADER;
210 Portal::Graphics::ShaderID m_tess_eval_shader_id = Portal::Graphics::INVALID_SHADER;
211 Portal::Graphics::ShaderID m_fragment_shader_id = Portal::Graphics::INVALID_SHADER;
212 Portal::Graphics::DescriptorSetID m_view_transform_descriptor_set_id {
213 Portal::Graphics::INVALID_DESCRIPTOR_SET
214 };
215 std::shared_ptr<Core::Window> m_target_window;
216
217 std::unordered_map<std::shared_ptr<VKBuffer>, VertexInfo> m_buffer_info;
218 Registry::Service::DisplayService* m_display_service = nullptr;
219
220 Portal::Graphics::PrimitiveTopology m_primitive_topology { Portal::Graphics::PrimitiveTopology::TRIANGLE_LIST };
221 Portal::Graphics::PolygonMode m_polygon_mode { Portal::Graphics::PolygonMode::FILL };
222 Portal::Graphics::CullMode m_cull_mode { Portal::Graphics::CullMode::NONE };
223
225 std::shared_ptr<Core::VKImage> texture;
226 vk::Sampler sampler;
227 };
228 std::unordered_map<uint32_t, TextureBinding> m_texture_bindings;
229
230 std::optional<Portal::Graphics::BlendAttachmentConfig> m_blend_attachment;
231
233
234 bool m_depth_enabled {};
235 std::shared_ptr<VKBuffer> m_view_transform_ubo;
236 bool m_view_transform_active {};
237 uint32_t m_first_vertex { 0 };
238 uint32_t m_vertex_count { 0 };
239 uint32_t m_instance_count { 1 };
240
241 std::optional<Kinesis::ViewTransform> m_view_transform;
243
244 const Kakshya::VertexLayout* get_or_cache_vertex_layout(
245 std::unordered_map<std::shared_ptr<VKBuffer>, VertexInfo>& buffer_info,
246 const std::shared_ptr<VKBuffer>& buffer);
247};
248
249} // namespace MayaFlux::Buffers
size_t count
void set_cull_mode(Portal::Graphics::CullMode mode)
Set cull mode (e.g., none, front, back)
void set_primitive_topology(Portal::Graphics::PrimitiveTopology topology)
Set primitive topology (e.g., triangle list, line list, point list)
void set_blend_attachment(const Portal::Graphics::BlendAttachmentConfig &config)
Set blend mode for color attachment.
std::unordered_map< std::shared_ptr< VKBuffer >, VertexInfo > m_buffer_info
std::optional< Portal::Graphics::BlendAttachmentConfig > m_blend_attachment
const std::optional< Kinesis::ViewTransform > & get_view_transform() const
Get current static view transform, if set.
void set_instance_count(uint32_t count)
Set number of instances for the next draw call.
std::function< Kinesis::ViewTransform()> m_view_transform_source
bool is_pipeline_ready() const
Check if pipeline is created.
std::optional< Kinesis::ViewTransform > m_view_transform
Portal::Graphics::DepthStencilConfig m_depth_stencil
std::unordered_map< uint32_t, TextureBinding > m_texture_bindings
Portal::Graphics::RenderPipelineID get_render_pipeline_id() const
void set_polygon_mode(Portal::Graphics::PolygonMode mode)
Set polygon mode (e.g., fill, line, point)
bool is_alpha_blending_enabled() const
Query whether the color attachment currently has blending enabled.
const std::function< Kinesis::ViewTransform()> & get_view_transform_source() const
Get current dynamic view transform source, if set.
std::shared_ptr< Core::Window > m_target_window
std::shared_ptr< VKBuffer > m_view_transform_ubo
Abstract base class for shader-based buffer processing.
PolygonMode
Rasterization polygon mode.
PrimitiveTopology
Vertex assembly primitive topology.
CompareOp
Depth/stencil comparison operation.
Complete description of vertex data layout in a buffer.
View and projection matrices as a named push constant slot.
Per-attachment blend configuration.
Depth and stencil test configuration.
Backend display and presentation service interface.