MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
ShaderUtils.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "vulkan/vulkan.hpp"
4
5#include "GraphicsUtils.hpp"
6
8
9namespace MayaFlux::Core {
10struct VertexBinding;
11struct VertexAttribute;
12}
13
15
16/**
17 * @struct GpuBufferHandle
18 * @brief Non-owning view of a GPU storage buffer produced by a compute path.
19 *
20 * Names the buffer, its host mapping when the memory is host visible, and its
21 * size in bytes. The producer owns the memory: a handle stays valid until the
22 * producer says otherwise, and a null buffer means no data.
23 */
25 vk::Buffer buffer {};
26 void* mapped_ptr { nullptr };
27 size_t size_bytes { 0 };
28
29 [[nodiscard]] explicit operator bool() const noexcept { return static_cast<bool>(buffer); }
30};
31
32/**
33 * @brief Resolve the extra vk::BufferUsageFlags a BufferUsageHint requires,
34 * on top of whatever base usage the caller already applies.
35 */
36[[nodiscard]] inline vk::BufferUsageFlags to_buffer_usage_flags(BufferUsageHint hint)
37{
38 switch (hint) {
40 return vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eStorageBuffer;
42 return vk::BufferUsageFlagBits::eStorageBuffer;
43 default:
44 break;
45 }
46
47 vk::BufferUsageFlags flags = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst;
48
49 switch (hint) {
51 break;
54 flags |= vk::BufferUsageFlagBits::eStorageBuffer;
55 break;
57 flags |= vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eStorageBuffer;
58 break;
60 flags |= vk::BufferUsageFlagBits::eIndexBuffer;
61 break;
63 flags |= vk::BufferUsageFlagBits::eUniformBuffer;
64 break;
66 flags |= vk::BufferUsageFlagBits::eUniformBuffer
67 | vk::BufferUsageFlagBits::eShaderDeviceAddress;
68 break;
70 flags |= vk::BufferUsageFlagBits::eStorageBuffer
71 | vk::BufferUsageFlagBits::eShaderDeviceAddress;
72 break;
74 flags |= vk::BufferUsageFlagBits::eStorageBuffer;
75 break;
76 default:
77 break;
78 }
79
80 return flags;
81}
82
83using ShaderID = uint64_t;
84using DescriptorSetID = uint64_t;
85using CommandBufferID = uint64_t;
86using FenceID = uint64_t;
87using SemaphoreID = uint64_t;
88using RenderPipelineID = uint64_t;
89using FramebufferID = uint64_t;
90
94constexpr FenceID INVALID_FENCE = 0;
98
99/**
100 * @struct ShaderCompilerConfig
101 * @brief Configuration for shader compilation
102 */
105 bool enable_debug_info = false; ///< Include debug symbols (line numbers, variable names)
106 bool enable_reflection = true; ///< Extract descriptor bindings and metadata
107 bool enable_validation = true; ///< Validate SPIR-V after compilation
108 std::vector<std::string> include_directories; ///< Paths for #include resolution
109 std::unordered_map<std::string, std::string> defines; ///< Preprocessor macros
110
112};
113
114/**
115 * @struct GpuComputeConfig
116 * @brief Plain-data description of the compute shader to dispatch.
117 *
118 * Either shader_path or shader_id must be set. If shader_id is not
119 * INVALID_SHADER it takes precedence and shader_path is ignored,
120 * allowing callers who already hold a compiled ShaderID (e.g. from
121 * ShaderFoundry::load_shader(const ShaderSpec&)) to bypass file
122 * resolution entirely.
123 */
125 std::string shader_path;
126 std::array<uint32_t, 3> workgroup_size { 256, 1, 1 };
127 size_t push_constant_size { 0 };
129};
130
131/**
132 * @struct ShaderSource
133 * @brief Shader source descriptor for compilation
134 */
136 std::string content; ///< Shader source code, SPIR-V path, or SPIR-V assembly text
138 std::string entry_point = "main";
139
140 enum class SourceType : uint8_t {
141 GLSL_STRING, ///< In-memory GLSL source
142 GLSL_FILE, ///< Path to .comp/.vert/.frag/etc
143 SPIRV_FILE, ///< Path to .spv file
144 SPIRV_ASM, ///< In-memory SPIR-V assembly text (assembled via SPIRV-Tools, no shaderc)
146
147 ShaderSource() = default;
148 ShaderSource(std::string content_, ShaderStage stage_, SourceType type_)
149 : content(std::move(content_))
150 , stage(stage_)
151 , type(type_)
152 {
153 }
154};
155
156/**
157 * @struct PushConstantBindingInfo
158 * @brief Self-describing push constant fragment staged on a VKBuffer.
159 *
160 * The push constant analogue of DescriptorBindingInfo. Where a descriptor
161 * entry carries its own set and binding, a push constant entry carries its
162 * own byte offset, so a shared list on the buffer merges into any
163 * processor's own push constant block without a per-processor key.
164 */
166 uint32_t offset {};
167 std::vector<uint8_t> data;
168 std::string name;
169};
170
171/**
172 * @enum DescriptorRole
173 * @brief Semantic descriptor type — maps to Vulkan descriptor types internally.
174 *
175 * Users declare what role a binding plays rather than which Vulkan type to use.
176 * The mapping is:
177 * UNIFORM → vk::DescriptorType::eUniformBuffer (small, frequently updated values)
178 * STORAGE → vk::DescriptorType::eStorageBuffer (large or write-capable arrays)
179 * TEXTURE → vk::DescriptorType::eCombinedImageSampler (sampled image + sampler)
180 * STORAGE_IMAGE → vk::DescriptorType::eStorageImage (compute read/write image)
181 */
182enum class DescriptorRole : uint8_t {
183 UNIFORM, ///< Small, read-only, frequently updated (scalars, param structs)
184 STORAGE, ///< Large arrays or buffers the shader may write (SSBO)
185 TEXTURE, ///< Sampled image + sampler combined
186 STORAGE_IMAGE ///< Compute-writable image
187};
188
189/**
190 * @brief Convert DescriptorRole to the corresponding vk::DescriptorType.
191 */
192[[nodiscard]] inline vk::DescriptorType to_vk_descriptor_type(DescriptorRole role)
193{
194 switch (role) {
196 return vk::DescriptorType::eUniformBuffer;
198 return vk::DescriptorType::eStorageBuffer;
200 return vk::DescriptorType::eCombinedImageSampler;
202 return vk::DescriptorType::eStorageImage;
203 }
204 return vk::DescriptorType::eStorageBuffer;
205}
206
207/**
208 * @struct DescriptorBindingConfig
209 * @brief Portal-level descriptor binding configuration
210 */
212 uint32_t set { 1 };
213 uint32_t binding {};
214 vk::DescriptorType type = vk::DescriptorType::eStorageBuffer;
215 vk::DescriptorBufferInfo buffer_info;
216 std::string name;
217 uint32_t count { 1 };
218};
219
220/**
221 * @struct PushConstantRangeInfo
222 * @brief Extracted push constant range from shader reflection
223 */
225 uint32_t offset;
226 uint32_t size;
227};
228
229/**
230 * @struct ShaderReflectionInfo
231 * @brief Extracted reflection information from compiled shader
232 */
235 std::string entry_point;
236 std::optional<std::array<uint32_t, 3>> workgroup_size;
237 std::vector<DescriptorBindingInfo> descriptor_bindings;
238 std::vector<PushConstantRangeInfo> push_constant_ranges;
239};
240
241/**
242 * @struct RasterizationConfig
243 * @brief Rasterization state configuration
244 */
255
256/**
257 * @struct DepthStencilConfig
258 * @brief Depth and stencil test configuration
259 */
270
271/**
272 * @struct BlendAttachmentConfig
273 * @brief Per-attachment blend configuration
274 */
300
301/**
302 * @struct RenderPipelineConfig
303 * @brief Complete render pipeline configuration
304 */
306 // Shader stages
314
315 // Vertex input
316 std::vector<Core::VertexBinding> vertex_bindings;
317 std::vector<Core::VertexAttribute> vertex_attributes;
318
319 // Input assembly
321
322 // Optional semantic vertex layout
323 std::optional<Kakshya::VertexLayout> semantic_vertex_layout;
324
325 // Use reflection to auto-configure from vertex shader
327
328 // Rasterization
330
331 // Depth/stencil
333
334 // Blend
335 std::vector<BlendAttachmentConfig> blend_attachments;
336
337 // Descriptor sets (similar to compute)
338 std::vector<std::vector<DescriptorBindingInfo>> descriptor_sets;
339
340 // Push constants
342
344};
345
346} // namespace MayaFlux::Portal::Graphics
PolygonMode
Rasterization polygon mode.
constexpr RenderPipelineID INVALID_RENDER_PIPELINE
constexpr ShaderID INVALID_SHADER
ShaderStage
User-friendly shader stage enum.
constexpr FenceID INVALID_FENCE
DescriptorRole
Semantic descriptor type — maps to Vulkan descriptor types internally.
@ STORAGE_IMAGE
Compute-writable image.
@ TEXTURE
Sampled image + sampler combined.
@ STORAGE
Large arrays or buffers the shader may write (SSBO)
@ UNIFORM
Small, read-only, frequently updated (scalars, param structs)
constexpr FramebufferID INVALID_FRAMEBUFFER
BufferUsageHint
Semantic usage hint for buffer allocation and memory properties.
@ STORAGE_BDA
Storage buffer with device address query support.
@ HOST_STORAGE
Host-visible storage buffer (eStorageBuffer + eHostVisible|eHostCoherent)
@ INDIRECT
Indirect draw/dispatch buffer (device-local)
@ UNIFORM
Uniform buffer (host-visible)
@ COMPUTE
Storage buffer for compute shaders (device-local)
@ STAGING
Host-visible staging buffer (CPU-writable, eTransferSrc|Dst)
@ UNIFORM_BDA
Uniform buffer with device address query support.
@ COMPUTE_STORAGE
Bare eStorageBuffer, no transfer flags. GpuResourceManager's host-visible/host-coherent compute buffe...
@ DEVICE
Device-local GPU-only buffer.
PrimitiveTopology
Vertex assembly primitive topology.
vk::DescriptorType to_vk_descriptor_type(DescriptorRole role)
Convert DescriptorRole to the corresponding vk::DescriptorType.
CompareOp
Depth/stencil comparison operation.
vk::BufferUsageFlags to_buffer_usage_flags(BufferUsageHint hint)
Resolve the extra vk::BufferUsageFlags a BufferUsageHint requires, on top of whatever base usage the ...
constexpr DescriptorSetID INVALID_DESCRIPTOR_SET
constexpr SemaphoreID INVALID_SEMAPHORE
constexpr CommandBufferID INVALID_COMMAND_BUFFER
bool operator==(const BlendAttachmentConfig &) const =default
static BlendAttachmentConfig alpha_blend()
Create standard alpha blending configuration.
Per-attachment blend configuration.
bool operator==(const DepthStencilConfig &) const =default
Depth and stencil test configuration.
Non-owning view of a GPU storage buffer produced by a compute path.
Plain-data description of the compute shader to dispatch.
Self-describing push constant fragment staged on a VKBuffer.
Extracted push constant range from shader reflection.
Rasterization state configuration.
std::vector< std::vector< DescriptorBindingInfo > > descriptor_sets
std::vector< Core::VertexAttribute > vertex_attributes
std::vector< Core::VertexBinding > vertex_bindings
std::optional< Kakshya::VertexLayout > semantic_vertex_layout
std::vector< BlendAttachmentConfig > blend_attachments
Complete render pipeline configuration.
bool enable_reflection
Extract descriptor bindings and metadata.
std::vector< std::string > include_directories
Paths for #include resolution.
bool enable_debug_info
Include debug symbols (line numbers, variable names)
bool enable_validation
Validate SPIR-V after compilation.
std::unordered_map< std::string, std::string > defines
Preprocessor macros.
Configuration for shader compilation.
std::optional< std::array< uint32_t, 3 > > workgroup_size
std::vector< PushConstantRangeInfo > push_constant_ranges
std::vector< DescriptorBindingInfo > descriptor_bindings
Extracted reflection information from compiled shader.
std::string content
Shader source code, SPIR-V path, or SPIR-V assembly text.
enum MayaFlux::Portal::Graphics::ShaderSource::SourceType type
ShaderSource(std::string content_, ShaderStage stage_, SourceType type_)
@ SPIRV_ASM
In-memory SPIR-V assembly text (assembled via SPIRV-Tools, no shaderc)
Shader source descriptor for compilation.