MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
GraphicsUtils.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Core {
7class Window;
8class VKImage;
9}
10
12
13//============================================================================
14// Primitive Topology
15//============================================================================
16
17/**
18 * @enum PrimitiveTopology
19 * @brief Vertex assembly primitive topology
20 *
21 * Used to configure how vertices are assembled into primitives
22 * before rasterization.
23 */
32
33/**
34 * @brief Whether two adjacent spans of this topology can be concatenated
35 * without altering the primitives they assemble.
36 *
37 * List topologies assemble each primitive from its own fixed-size group of
38 * consecutive vertices, so appending one span to another adds primitives and
39 * leaves existing ones untouched. Strip and fan topologies assemble each
40 * primitive from vertices shared with its predecessor, so concatenation
41 * fabricates an extra primitive spanning the join.
42 */
49
50//============================================================================
51// Rasterization
52//============================================================================
53
54/**
55 * @enum PolygonMode
56 * @brief Rasterization polygon mode
57 */
58enum class PolygonMode : uint8_t {
59 FILL,
60 LINE,
61 POINT
62};
63
64/**
65 * @enum CullMode
66 * @brief Face culling mode
67 */
68enum class CullMode : uint8_t {
69 NONE,
70 FRONT,
71 BACK,
73};
74
75//============================================================================
76// Depth/Stencil
77//============================================================================
78
79/**
80 * @enum CompareOp
81 * @brief Depth/stencil comparison operation
82 */
83enum class CompareOp : uint8_t {
84 NEVER,
85 LESS,
86 EQUAL,
88 GREATER,
91 ALWAYS
92};
93
94//============================================================================
95// Blending
96//============================================================================
97
98/**
99 * @enum BlendFactor
100 * @brief Blending factor
101 */
114
115/**
116 * @enum BlendOp
117 * @brief Blending operation
118 */
119enum class BlendOp : uint8_t {
120 ADD,
121 SUBTRACT,
123 MIN,
124 MAX
125};
126
127//============================================================================
128// GPU Buffer Bindings
129//============================================================================
130
131/**
132 * @enum BufferUsageHint
133 * @brief Semantic usage hint for buffer allocation and memory properties
134 *
135 * This enum describes the intended usage pattern of a buffer, which informs
136 * the graphics backend how to allocate memory and set Vulkan usage flags.
137 * It is not a direct mapping to Vulkan flags, but rather a higher-level
138 * abstraction for common use cases.
139 */
140enum class BufferUsageHint : uint8_t {
141 STAGING, ///< Host-visible staging buffer (CPU-writable, eTransferSrc|Dst)
142 DEVICE, ///< Device-local GPU-only buffer
143 COMPUTE, ///< Storage buffer for compute shaders (device-local)
144 VERTEX, ///< Vertex buffer
145 INDEX, ///< Index buffer
146 UNIFORM, ///< Uniform buffer (host-visible)
147 UNIFORM_BDA, ///< Uniform buffer with device address query support
148 STORAGE_BDA, ///< Storage buffer with device address query support
149 INDIRECT, ///< Indirect draw/dispatch buffer (device-local)
150 HOST_STORAGE, ///< Host-visible storage buffer (eStorageBuffer + eHostVisible|eHostCoherent)
151 COMPUTE_STORAGE, ///< Bare eStorageBuffer, no transfer flags. GpuResourceManager's host-visible/host-coherent compute buffers.
152};
153
154/**
155 * @struct GpuBufferBinding
156 * @brief Declares a single storage buffer or image binding a compute shader expects.
157 *
158 * Vulkan-agnostic description consumed by ComputePress/ShaderFoundry to
159 * derive descriptor types, barrier targets, and staging behavior. Carries
160 * no vk:: types itself; translation to vk::DescriptorType happens at the
161 * point of use.
162 */
164 uint32_t set { 0 }; ///< Descriptor set index.
165 uint32_t binding { 0 }; ///< Binding index within the set.
166 bool skip_auto_readback { false }; ///< Skip automatic CPU readback after dispatch for this binding.
167
168 /**
169 * @enum Direction
170 * @brief Data flow direction for this binding.
171 *
172 * INPUT_OUTPUT bindings receive a cross-pass memory barrier when used
173 * across multiple recorded dispatches in one command buffer (see
174 * ComputePress::record_sequence), since the same resource is both
175 * read and written by consecutive stages.
176 */
177 enum class Direction : uint8_t {
178 INPUT,
179 OUTPUT,
181 } direction { Direction::INPUT };
182
183 /**
184 * @enum ElementType
185 * @brief Element type the shader expects in this binding.
186 *
187 * FLOAT32 — cast double channels to float (default).
188 * UINT32 — reinterpret variant bytes as uint32_t.
189 * INT32 — reinterpret variant bytes as int32_t.
190 * PASSTHROUGH — upload raw variant bytes with no cast; caller
191 * must pre-stage for INPUT / INPUT_OUTPUT bindings.
192 * IMAGE_STORAGE — writeonly/readonly image2D, storage image descriptor.
193 * IMAGE_SAMPLED — sampler2D, combined image sampler descriptor.
194 */
195 enum class ElementType : uint8_t {
196 FLOAT32,
197 UINT32,
198 INT32,
202 } element_type { ElementType::FLOAT32 };
203
204 BufferUsageHint usage_hint { BufferUsageHint::COMPUTE_STORAGE }; ///< Hint for buffer allocation and memory properties.
205};
206
207/**
208 * @brief Byte width of one GpuBufferBinding::ElementType element.
209 *
210 * Bridges to Kakshya::gpu_data_format_bytes for FLOAT32/UINT32/INT32,
211 * the single authoritative sizing source. Returns 0 for PASSTHROUGH,
212 * IMAGE_STORAGE, and IMAGE_SAMPLED, which carry no fixed element width.
213 *
214 * @param et ElementType to size.
215 * @return Byte width, or 0 if unsized.
216 */
217[[nodiscard]] MAYAFLUX_API size_t element_type_bytes(GpuBufferBinding::ElementType et) noexcept;
218
219//============================================================================
220// Shader Types
221//============================================================================
222
223/**
224 * @enum ShaderStage
225 * @brief User-friendly shader stage enum
226 *
227 * Abstracts vk::ShaderStageFlagBits for Portal API convenience.
228 * Maps directly to Vulkan stages internally.
229 */
230enum class ShaderStage : uint8_t {
231 COMPUTE,
232 VERTEX,
233 FRAGMENT,
234 GEOMETRY,
237 MESH,
238 TASK
239};
240
241//============================================================================
242// Image Helpers
243//============================================================================
244
245/**
246 * @brief Portal name for Kakshya::ImageFormat, which maps to vk::Format in TextureLoom.
247 */
249
250/**
251 * @enum FilterMode
252 * @brief Texture filtering mode
253 */
254enum class FilterMode : uint8_t {
255 NEAREST, ///< Nearest neighbor (pixelated)
256 LINEAR, ///< Bilinear filtering (smooth)
257 CUBIC ///< Bicubic filtering (high quality, slower)
258};
259
260/**
261 * @enum AddressMode
262 * @brief Texture addressing mode (wrapping)
263 */
264enum class AddressMode : uint8_t {
265 REPEAT, ///< Repeat texture
266 MIRRORED_REPEAT, ///< Mirror and repeat
267 CLAMP_TO_EDGE, ///< Clamp to edge color
268 CLAMP_TO_BORDER ///< Clamp to border color
269};
270
271/**
272 * @enum BorderColor
273 * @brief Color read outside the texture when an address mode is CLAMP_TO_BORDER
274 */
275enum class BorderColor : uint8_t {
276 DEFAULT, ///< The sampler's historical border, opaque black
277 TRANSPARENT_BLACK, ///< Zero in every channel
278 OPAQUE_BLACK, ///< Black with full alpha
279 OPAQUE_WHITE ///< White with full alpha
280};
281
282/**
283 * @struct SamplerConfig
284 * @brief Sampler configuration
285 */
296
297/**
298 * @enum FitMode
299 * @brief How a source extent is mapped onto a destination extent
300 */
301enum class FitMode : uint8_t {
302 STRETCH, ///< Whole source onto whole destination, aspect ignored
303 CONTAIN, ///< Whole source, aspect kept, centered, the rest left uncovered
304 COVER, ///< Aspect kept, destination filled, source cropped
305 CENTER, ///< No scaling, centered, clipped to the destination
306 TILE, ///< Source repeated at its own size
307 TILE_MIRRORED ///< Source repeated, every other tile mirrored
308};
309
310
311/**
312 * @struct RenderConfig
313 * @brief Unified rendering configuration for graphics buffers
314 *
315 * This is the persistent state that processors query and react to.
316 * All rendering parameters in one place, independent of buffer type.
317 * Child buffer classes populate it with context-specific defaults
318 * during construction, then expose it to their processors.
319 *
320 * Design:
321 * - Owned by VKBuffer as persistent state
322 * - Processors query and react to changes
323 * - Child classes have their own convenience RenderConfig with defaults
324 * that bridge to this Portal-level config
325 */
327 std::shared_ptr<Core::Window> target_window;
328 std::string vertex_shader;
329 std::string fragment_shader;
330 std::string geometry_shader;
335
336 /**
337 * @brief Reduce supplied spans to triangles before drawing them.
338 *
339 * @c topology describes span ordering, not the pipeline: it is always
340 * built TRIANGLE_LIST, no geometry stage on any platform, and each span
341 * is milled into quads/ribbons before one draw. Applies to any span
342 * shape on any platform; macOS additionally forces it on for
343 * LINE_LIST/LINE_STRIP since line.geom (NDC expansion) isn't available
344 * there.
345 *
346 * A custom vertex_shader is unchanged: same attributes, same transform
347 * to clip space. A custom fragment_shader needs one new thing: every
348 * span shares one fragment shader, so @c \#include "include/mill_shape.glsl"
349 * and check @c mill_is_point(in_uv) to tell a point quad from a
350 * ribbon/passthrough-triangle fragment. milled_shape.frag/_textured/_multi
351 * are reference implementations (the multi variant's array index shares
352 * MillSpec's per-vertex size slot -- set use_vertex_extent = false to
353 * decouple them).
354 *
355 * Resolved at configuration time, not inferred from spans arriving,
356 * since shader/topology/geometry-stage selection happen here while
357 * spans arrive per frame.
358 */
359 bool triangulate { false };
360
361 std::vector<std::pair<std::string, std::shared_ptr<Core::VKImage>>> additional_textures;
362
363 /**
364 * @brief Clip this buffer's draws to an NDC region.
365 *
366 * Unset means the full framebuffer, matching the behavior before this
367 * field existed. Set via Kinesis::Scissor::from(bounds), from(anchor)
368 * for anything exposing bounds(), or from(aabb3d, view_transform) to
369 * project a world-space box.
370 */
371 std::optional<Kinesis::Scissor> scissor;
372
373 ///< For child-specific fields
374 std::unordered_map<std::string, std::string> extra_string_params;
375
376 /// @brief Draw-order priority. Higher sorts later (drawn on top). Default 0.
377 int64_t draw_priority {};
378
379 bool operator==(const RenderConfig& other) const = default;
380};
381
382/**
383 * @struct DrawRun
384 * @brief One contiguous span of vertices sharing a primitive topology.
385 *
386 * The topology declares how this span's vertices are ordered, not which
387 * pipeline draws it. A consumer configured to triangulate reduces every span to
388 * triangles and draws them all with one call, turning points into quads and
389 * line segments into ribbons, so a set of spans of differing topology still
390 * resolves to a single draw.
391 *
392 * Carries no knowledge of what produced it: an operator's collections, an
393 * arena's per-element sub-ranges, or anything else. Producers build these; the
394 * consumer shapes and draws them.
395 */
396struct DrawRun {
398 uint32_t vertex_offset {};
399 uint32_t vertex_count {};
400};
401
402/**
403 * @brief Vertices a span of @p n at @p topology yields once reduced to a
404 * TRIANGLE_LIST, with points becoming quads and line segments ribbons.
405 *
406 * Closed form, so a caller can size a destination or budget a dispatch without
407 * inspecting vertex data. Spans too short to assemble a primitive yield zero
408 * rather than underflowing, and list topologies floor to whole primitives, so
409 * an odd LINE_LIST count drops its dangling vertex instead of reading past the
410 * span.
411 */
412[[nodiscard]] constexpr uint32_t triangle_vertex_count(
414 uint32_t n) noexcept
415{
416 switch (topology) {
418 return 6U * n;
420 return 6U * (n / 2U);
422 return n < 2U ? 0U : 6U * (n - 1U);
424 return 3U * (n / 3U);
427 return n < 3U ? 0U : 3U * (n - 2U);
428 }
429 return 0U;
430}
431
432}
PrimitiveTopology topology
ImageFormat
User-friendly image format enum.
Definition ImageData.hpp:12
PolygonMode
Rasterization polygon mode.
AddressMode
Texture addressing mode (wrapping)
@ CLAMP_TO_BORDER
Clamp to border color.
constexpr bool is_concatenable_topology(PrimitiveTopology topology) noexcept
Whether two adjacent spans of this topology can be concatenated without altering the primitives they ...
ShaderStage
User-friendly shader stage enum.
FilterMode
Texture filtering mode.
@ LINEAR
Bilinear filtering (smooth)
@ NEAREST
Nearest neighbor (pixelated)
@ CUBIC
Bicubic filtering (high quality, slower)
BorderColor
Color read outside the texture when an address mode is CLAMP_TO_BORDER.
@ TRANSPARENT_BLACK
Zero in every channel.
@ DEFAULT
The sampler's historical border, opaque black.
@ OPAQUE_BLACK
Black with full alpha.
@ OPAQUE_WHITE
White with full alpha.
constexpr uint32_t triangle_vertex_count(PrimitiveTopology topology, uint32_t n) noexcept
Vertices a span of n at topology yields once reduced to a TRIANGLE_LIST, with points becoming quads a...
size_t element_type_bytes(GpuBufferBinding::ElementType et) noexcept
Byte width of one GpuBufferBinding::ElementType element.
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.
CompareOp
Depth/stencil comparison operation.
FitMode
How a source extent is mapped onto a destination extent.
@ TILE_MIRRORED
Source repeated, every other tile mirrored.
@ STRETCH
Whole source onto whole destination, aspect ignored.
@ CONTAIN
Whole source, aspect kept, centered, the rest left uncovered.
@ COVER
Aspect kept, destination filled, source cropped.
@ CENTER
No scaling, centered, clipped to the destination.
@ TILE
Source repeated at its own size.
One contiguous span of vertices sharing a primitive topology.
ElementType
Element type the shader expects in this binding.
Direction
Data flow direction for this binding.
BufferUsageHint usage_hint
Hint for buffer allocation and memory properties.
enum MayaFlux::Portal::Graphics::GpuBufferBinding::Direction INPUT
bool skip_auto_readback
Skip automatic CPU readback after dispatch for this binding.
uint32_t binding
Binding index within the set.
enum MayaFlux::Portal::Graphics::GpuBufferBinding::ElementType FLOAT32
Declares a single storage buffer or image binding a compute shader expects.
std::shared_ptr< Core::Window > target_window
std::unordered_map< std::string, std::string > extra_string_params
std::optional< Kinesis::Scissor > scissor
Clip this buffer's draws to an NDC region.
int64_t draw_priority
Draw-order priority. Higher sorts later (drawn on top). Default 0.
std::vector< std::pair< std::string, std::shared_ptr< Core::VKImage > > > additional_textures
bool triangulate
Reduce supplied spans to triangles before drawing them.
bool operator==(const RenderConfig &other) const =default
Unified rendering configuration for graphics buffers.