MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VisionGpuDispatch.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
7namespace MayaFlux::Yantra {
8
9/**
10 * @file VisionGpuDispatch.hpp
11 * @brief GPU execution layer for Kinesis::Vision::VisionSequence.
12 *
13 * VisionGpuExecutor::run() mirrors VisionExecutor::run() in contract: same
14 * input types, same VisionResult output. Internally it drives a
15 * VisionGpuContexts through the sequence via swap_shader() + stage_image()
16 * + dispatch_core() per step, keeping the working image GPU-resident
17 * between steps via OutputMode::IMAGE.
18 *
19 * VisionGpuExecutor::config() is the inspectable shader config table. It
20 * returns the GpuComputeConfig for any given VisionOp. Ops that are
21 * expressible via ShaderSpec are assembled at call time (no .comp file);
22 * ops requiring neighbourhood access or structured output name a .comp
23 * file. Ops with no GPU implementation return a config with INVALID_SHADER.
24 *
25 * The caller is responsible for only passing sequences composed of ops
26 * whose config is valid. run() logs an error and returns a default
27 * VisionResult on encountering INVALID_SHADER mid-sequence.
28 */
29
30/**
31 * @brief Fixed set of TextureExecutionContexts covering every GPU-implemented
32 * VisionOp shape.
33 *
34 * Owned exclusively by VisionGpuExecutor, which lazily constructs and holds
35 * one instance per executor via m_contexts. Never rebuilt inside run() or
36 * per-step; the bindings each member declares are fixed at construction and
37 * dictated entirely by the shaders they drive, not by caller preference.
38 *
39 * There is exactly one correct binding layout per member, so this struct
40 * carries no configuration surface.
41 */
42struct MAYAFLUX_API VisionGpuContexts {
43 TextureExecutionContext pixel; ///< Image pipeline. IMAGE mode. Drives
44 ///< every op that reads/writes the
45 ///< working image (Threshold, Sobel,
46 ///< HarrisResponse, Downsample2x, etc).
47 TextureExecutionContext structured; ///< Buffer-only readback. SCALAR mode.
48 ///< Drives ops with no image output
49 ///< of their own (ExtractPeaks).
50 TextureExecutionContext labels; ///< Image + aux SSBO. IMAGE mode.
51 ///< Drives ops needing both a resident
52 ///< image output and structured aux
53 ///< data (ConnectedComponents,
54 ///< FindContours).
56
57 /**
58 * @brief Construct all three contexts in place with the one correct
59 * binding layout for every currently GPU-implemented VisionOp.
60 *
61 * TextureExecutionContext has no copy or move constructor (it owns GPU
62 * resource handles), so each member is built directly in this
63 * constructor's initializer list rather than assigned from a temporary.
64 * Constructed lazily by VisionGpuExecutor on first run(); never
65 * constructed directly by callers.
66 */
68};
69
70/**
71 * @class VisionGpuExecutor
72 * @brief Stateful GPU dispatch engine for VisionSequence execution.
73 *
74 * Owns a lazily-constructed VisionGpuContexts (m_contexts) plus any
75 * op-specific persistent GPU state that doesn't belong on a shared
76 * context (e.g. ConnectedComponents' ping-pong output image). Mirrors
77 * VisionExecutor's ownership model on the CPU side: construct one
78 * instance per independent pipeline, hold it, call run() every frame.
79 *
80 * Immovable: TextureExecutionContext owns GPU resource handles with no
81 * copy or move constructor, so VisionGpuContexts and therefore
82 * VisionGpuExecutor cannot be copied or moved either. Construct once,
83 * hold by reference, pointer, or shared_ptr, reuse indefinitely.
84 *
85 * Not safe to call run() concurrently from multiple threads on the same
86 * instance. Independent pipelines running concurrently should each own
87 * a separate VisionGpuExecutor instance.
88 */
89class MAYAFLUX_API VisionGpuExecutor {
90public:
91 /**
92 * @brief GpuComputeConfig for a given VisionOp and its parameters.
93 *
94 * Assembled ops (Threshold, NormalizeInplace, NormalizeRange, RgbaToGray,
95 * GrayToRgba) produce a config via ShaderSpec::Assemble + config_from_spec
96 * with no .comp file. All other implemented ops reference a .comp path
97 * under Portal/Shaders/Vision/. Unimplemented ops return a config with
98 * shader_id == INVALID_SHADER.
99 *
100 * Stateless; does not depend on or affect m_contexts.
101 *
102 * @param op VisionOp to look up.
103 * @param params Parameters for that op; used to derive push constant size
104 * for assembled ops.
105 */
106 [[nodiscard]] static GpuComputeConfig config(
108 const Kinesis::Vision::VisionParams& params);
109
110 /**
111 * @brief Execute a VisionSequence on the GPU through an explicit context set.
112 *
113 * contexts is caller-supplied rather than the instance's own lazily-built
114 * m_contexts. Reused across calls with no reset needed; construction is
115 * the caller's responsibility and never happens inside this function.
116 *
117 * @param contexts Long-lived context set. Never constructed internally.
118 * @param sequence Ordered steps to execute.
119 * @param image Input frame in eShaderReadOnlyOptimal layout.
120 * @param w Frame width in pixels.
121 * @param h Frame height in pixels.
122 * @return VisionResult matching the VisionExecutor::run() contract.
123 */
125 VisionGpuContexts& contexts,
126 const Kinesis::Vision::VisionSequence& sequence,
127 const std::shared_ptr<Core::VKImage>& image,
128 uint32_t w, uint32_t h);
129
130 /**
131 * @brief Execute a VisionSequence on the GPU using this instance's own
132 * lazily-constructed context set.
133 *
134 * m_contexts is built on first call and reused for every subsequent
135 * call to this overload on the same VisionGpuExecutor instance. The
136 * primary entry point; prefer this over the explicit-contexts overload
137 * unless a caller specifically needs to inspect or share a
138 * VisionGpuContexts across multiple calls outside this class.
139 *
140 * @param sequence Ordered steps to execute.
141 * @param image Input frame in eShaderReadOnlyOptimal layout.
142 * @param w Frame width in pixels.
143 * @param h Frame height in pixels.
144 * @return VisionResult matching the VisionExecutor::run() contract.
145 */
147 const Kinesis::Vision::VisionSequence& sequence,
148 const std::shared_ptr<Core::VKImage>& image,
149 uint32_t w, uint32_t h);
150
151 VisionGpuExecutor() = default;
157
158private:
159 std::unique_ptr<VisionGpuContexts> m_contexts;
160};
161
162} // namespace MayaFlux::Yantra
IO::ImageData image
Definition Decoder.cpp:64
uint32_t h
Definition InkPress.cpp:28
Dispatch engine for VisionSequence execution.
GpuExecutionContext specialisation for image compute shaders.
VisionGpuExecutor & operator=(const VisionGpuExecutor &)=delete
VisionGpuExecutor(const VisionGpuExecutor &)=delete
VisionGpuExecutor & operator=(VisionGpuExecutor &&)=delete
VisionGpuExecutor(VisionGpuExecutor &&)=delete
std::unique_ptr< VisionGpuContexts > m_contexts
Stateful GPU dispatch engine for VisionSequence execution.
void run()
Definition main.cpp:22
std::variant< std::monostate, ThresholdParams, ThresholdAdaptiveParams, NormalizeRangeParams, GaussianBlurParams, FilterSeparableParams, CannyParams, MorphParams, HarrisParams, ExtractPeaksParams, TrackKeypointsParams, ConnectedComponentsParams, FindContoursParams > VisionParams
Parameter variant covering all ops that carry parameters.
Definition VisionOp.hpp:148
VisionOp
Named operations available in a VisionSequence.
Definition VisionOp.hpp:29
Result of executing a VisionSequence on one frame.
Ordered sequence of VisionSteps describing a complete vision pipeline.
Definition VisionOp.hpp:163
Plain-data description of the compute shader to dispatch.
TextureExecutionContext labels
Image + aux SSBO.
TextureExecutionContext pixel
Image pipeline.
TextureExecutionContext structured
Buffer-only readback.
Fixed set of TextureExecutionContexts covering every GPU-implemented VisionOp shape.