Loading...
Searching...
No Matches
isf.hpp
1#pragma once
2#include <ossia/detail/variant.hpp>
3
4#include <score_plugin_gfx_export.h>
5
6#include <array>
7#include <optional>
8#include <stdexcept>
9#include <string>
10#include <vector>
11
12namespace isf
13{
14class invalid_file : public std::runtime_error
15{
16public:
17 using std::runtime_error::runtime_error;
18};
19
20struct event_input
21{
22};
23
24struct bool_input
25{
26 using value_type = bool;
27 using has_default = std::true_type;
28 bool def{};
29};
30
31struct long_input
32{
33 using value_type = int64_t;
34 using has_minmax = std::true_type;
35 std::vector<ossia::variant<int64_t, double, std::string>> values;
36 std::vector<std::string> labels;
37 std::size_t def{}; // index of default value (enum mode) or default value (numeric mode)
38
39 // Numeric mode: when values/labels are empty and min/max are set,
40 // create an IntSpinBox instead of a ComboBox.
41 std::optional<int64_t> min;
42 std::optional<int64_t> max;
43};
44struct float_input
45{
46 using value_type = double;
47 using has_minmax = std::true_type;
48 double min{0.};
49 double max{0.};
50 double def{0.};
51};
52
53struct point2d_input
54{
55 using value_type = std::array<double, 2>;
56 using has_minmax = std::true_type;
57 std::optional<value_type> def{};
58 std::optional<value_type> min{};
59 std::optional<value_type> max{};
60};
61
62struct point3d_input
63{
64 using value_type = std::array<double, 3>;
65 using has_minmax = std::true_type;
66 std::optional<value_type> def{};
67 std::optional<value_type> min{};
68 std::optional<value_type> max{};
69};
70
71struct color_input
72{
73 using value_type = std::array<double, 4>;
74 using has_minmax = std::true_type;
75 std::optional<value_type> def{};
76 std::optional<value_type> min{};
77 std::optional<value_type> max{};
78};
79
80struct image_input
81{
82 int dimensions{2}; // 2 or 3
83 bool depth{false}; // true = shader wants sampleable depth on this input
84};
85
86struct cubemap_input
87{
88};
89
90struct audio_input
91{
92 int max{};
93};
94
95struct audioFFT_input
96{
97 int max{};
98};
99
100struct audioHist_input
101{
102 int max{};
103};
104
105// CSF-specific input types
106struct storage_input
107{
108 std::string access; // "read_only", "write_only", "read_write"
109
110 struct layout_field
111 {
112 std::string name;
113 std::string type;
114 };
115
116 std::vector<layout_field> layout;
117
118 std::string buffer_usage; // "", "indirect_draw", "indirect_draw_indexed"
119};
120
121struct texture_input
122{
123 int dimensions{2}; // 2 or 3
124};
125
126struct csf_image_input
127{
128 std::string access; // "read_only", "write_only", "read_write"
129 std::string format; // "RGBA8", "R32F", etc.
130
131 std::string width_expression;
132 std::string height_expression;
133 std::string depth_expression; // non-empty means 3D texture
134
135 int dimensions{2}; // 2 or 3 (alternative to depth_expression for declaring 3D)
136
137 bool is3D() const noexcept { return dimensions == 3 || !depth_expression.empty(); }
138};
139
140// CSF geometry port input: SoA layout, one SSBO per attribute.
141// Declares which geometry attributes the compute shader wants to access.
142struct geometry_input
143{
144 // Explicit cross-geometry forwarding directive.
145 // Used when an output geometry needs data from a different input geometry.
146 struct copy_from
147 {
148 std::string geometry; // Source geometry resource name (e.g. "geoIn")
149 std::string attribute; // Source attribute name (for attribute forwarding)
150 std::string auxiliary; // Source auxiliary name (for auxiliary forwarding; defaults to this name)
151 };
152
153 struct attribute_request
154 {
155 std::string name; // Attribute name used in GLSL (e.g. "position", "velocity")
156 std::string semantic; // Maps to ossia::attribute_semantic name (e.g. "position", "custom")
157 std::string type; // GLSL type (e.g. "vec3", "vec4", "float")
158 std::string access; // "read_only", "write_only", "read_write"
159 std::string rate; // "vertex" (default) or "instance"
160 bool required{true}; // false = optional, zero fallback if missing
161
162 // If set, this attribute is forwarded from another geometry's buffer
163 // rather than being allocated/computed by this shader.
164 std::optional<copy_from> forward;
165 };
166
167 // Structured SSBOs that travel with the geometry (matched by name
168 // against ossia::geometry::auxiliary_buffer entries).
169 struct auxiliary_request
170 {
171 std::string name;
172 std::string access; // "read_only", "write_only", "read_write"
173 std::vector<storage_input::layout_field> layout;
174 std::string size; // expression for flexible array count, may contain $USER
175
176 // If set, this auxiliary is forwarded from another geometry's upstream.
177 std::optional<copy_from> forward;
178 };
179
180 std::vector<attribute_request> attributes;
181 std::vector<auxiliary_request> auxiliary;
182
183 std::string vertex_count; // expression string, may contain $USER
184 std::string instance_count; // expression string, may contain $USER
185
186 bool indirect_draw{false}; // compute shader writes draw args to an indirect buffer
187 std::string indirect_draw_type; // "draw" (default) or "draw_indexed"
188};
189
190struct input
191{
192 using input_impl = ossia::variant<
193 float_input, long_input, event_input, bool_input, color_input, point2d_input,
194 point3d_input, image_input, cubemap_input, audio_input, audioFFT_input,
195 audioHist_input, storage_input, texture_input, csf_image_input,
196 geometry_input>;
197
198 std::string name;
199 std::string label;
200
201 input_impl data;
202};
203
204// Matches QShaderDescription::VariableType
205enum class attribute_type
206{
207 Unknown = 0,
208
209 Float,
210 Vec2,
211 Vec3,
212 Vec4,
213 Mat2,
214 Mat2x3,
215 Mat2x4,
216 Mat3,
217 Mat3x2,
218 Mat3x4,
219 Mat4,
220 Mat4x2,
221 Mat4x3,
222
223 Int,
224 Int2,
225 Int3,
226 Int4,
227
228 Uint,
229 Uint2,
230 Uint3,
231 Uint4,
232
233 Bool,
234 Bool2,
235 Bool3,
236 Bool4,
237
238 Double,
239 Double2,
240 Double3,
241 Double4,
242 DMat2,
243 DMat2x3,
244 DMat2x4,
245 DMat3,
246 DMat3x2,
247 DMat3x4,
248 DMat4,
249 DMat4x2,
250 DMat4x3,
251
252 Sampler1D,
253 Sampler2D,
254 Sampler2DMS,
255 Sampler3D,
256 SamplerCube,
257 Sampler1DArray,
258 Sampler2DArray,
259 Sampler2DMSArray,
260 Sampler3DArray,
261 SamplerCubeArray,
262 SamplerRect,
263 SamplerBuffer,
264 SamplerExternalOES,
265 Sampler,
266
267 Image1D,
268 Image2D,
269 Image2DMS,
270 Image3D,
271 ImageCube,
272 Image1DArray,
273 Image2DArray,
274 Image2DMSArray,
275 Image3DArray,
276 ImageCubeArray,
277 ImageRect,
278 ImageBuffer,
279
280 Struct,
281
282 Half,
283 Half2,
284 Half3,
285 Half4
286};
287
288struct vertex_attribute
289{
290 int location{};
291 attribute_type type{};
292 std::string name;
293};
294
295struct vertex_input : vertex_attribute
296{
297};
298struct vertex_output : vertex_attribute
299{
300};
301struct fragment_input : vertex_attribute
302{
303};
304struct fragment_output : vertex_attribute
305{
306};
307
308struct pass
309{
310 std::string target;
311 bool persistent{};
312 bool float_storage{};
313 bool nearest_filter{};
314 std::string width_expression{};
315 std::string height_expression{};
316};
317
318struct output_declaration
319{
320 std::string name; // User-chosen name (e.g. "color", "sceneDepth")
321 std::string type; // "color" (default) or "depth"
322};
323
324struct descriptor
325{
326 enum Mode
327 {
328 ISF,
329 VSA,
330 CSF,
331 RawRaster
332 } mode{ISF};
333 std::string description;
334 std::string credits;
335 std::vector<std::string> categories;
336 std::vector<input> inputs;
337 std::vector<output_declaration> outputs; // Parsed from OUTPUTS array; empty = single color output
338 std::vector<pass> passes;
339 std::vector<std::string> pass_targets;
340 bool default_vertex_shader{};
341
342 // For VSA
343 int point_count{};
344 std::string primitive_mode;
345 std::string line_size;
346 std::array<double, 4> background_color;
347
348 // For CSF
349 struct type_definition
350 {
351 std::string name;
352 std::vector<storage_input::layout_field> layout;
353 };
354 std::vector<type_definition> types;
355
356 struct dispatch_info
357 {
358 std::array<int, 3> local_size{16, 16, 1};
359 std::string execution_type{"2D_IMAGE"}; // "2D_IMAGE", "1D_BUFFER", "PER_VERTEX", "PER_INSTANCE", "MANUAL", "USER"
360 std::string target_resource;
361 std::array<int, 3> workgroups{1, 1, 1}; // For MANUAL mode
362 std::array<std::string, 3> stride{"1", "1", "1"}; // Per-axis stride (supports formulas)
363 std::array<int, 3> user_dispatch_ports{-1, -1, -1}; // Port indices for USER mode (X, Y, Z)
364 };
365 std::vector<dispatch_info> csf_passes;
366
367 // For raw shaders
368
369 std::vector<vertex_input> vertex_inputs;
370 std::vector<vertex_output> vertex_outputs;
371 std::vector<fragment_input> fragment_inputs;
372 std::vector<fragment_output> fragment_outputs;
373
374 // Auxiliary SSBOs expected from upstream geometry (matched by name).
375 // Populated from top-level AUXILIARY key in RAW_RASTER_PIPELINE mode.
376 std::vector<geometry_input::auxiliary_request> auxiliary;
377};
378
379class SCORE_PLUGIN_GFX_EXPORT parser
380{
381 std::string m_sourceVertex;
382 std::string m_sourceFragment;
383 std::string m_source_geometry_filter;
384 int m_version{450};
385
386 std::string m_vertex;
387 std::string m_fragment;
388 std::string m_geometry_filter;
389
390 descriptor m_desc;
391
392public:
393 enum class ShaderType
394 {
395 Autodetect,
396 ISF,
397 ShaderToy,
398 GLSLSandBox,
399 GeometryFilter,
400 VertexShaderArt,
401 CSF,
402 RawRasterPipeline,
403 RawRaytracePipeline,
404 RawMeshPipeline
405 };
406 parser(std::string vert, std::string frag, int glslVersion, ShaderType);
407 explicit parser(std::string isf_geom_filter, ShaderType t);
408
409 descriptor data() const;
410 descriptor::Mode mode() const;
411 std::string vertex() const;
412 std::string fragment() const;
413 std::string geometry_filter() const;
414 std::string compute_shader() const;
415 static std::pair<int, descriptor> parse_isf_header(std::string_view source);
416 void parse_shadertoy_json(const std::string& json);
417
418 std::string write_isf() const;
419
420private:
421 void parse_isf();
422 void parse_raw_raster_pipeline();
423 void parse_shadertoy();
424 void parse_glsl_sandbox();
425 void parse_geometry_filter();
426 void parse_vsa();
427 void parse_csf();
428};
429}