4 #include <Process/ExecutionContext.hpp>
6 #include <Crousti/MessageBus.hpp>
7 #include <Gfx/GfxExecNode.hpp>
8 #include <Gfx/Graph/Node.hpp>
9 #include <Gfx/Graph/OutputNode.hpp>
10 #include <Gfx/Graph/RenderState.hpp>
14 #include <avnd/binding/ossia/port_run_postprocess.hpp>
15 #include <avnd/binding/ossia/port_run_preprocess.hpp>
16 #include <avnd/concepts/parameter.hpp>
17 #include <fmt/format.h>
18 #include <gpp/layout.hpp>
20 #include <score_plugin_avnd_export.h>
25 requires requires { F::format(); }
26 constexpr QRhiTexture::Format textureFormat()
28 constexpr std::string_view fmt = F::format();
30 if(fmt ==
"rgba" || fmt ==
"rgba8")
31 return QRhiTexture::RGBA8;
32 else if(fmt ==
"bgra" || fmt ==
"bgra8")
33 return QRhiTexture::BGRA8;
35 return QRhiTexture::R8;
36 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
38 return QRhiTexture::RG8;
41 return QRhiTexture::R16;
42 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
43 else if(fmt ==
"rg16")
44 return QRhiTexture::RG16;
46 else if(fmt ==
"red_or_alpha8")
47 return QRhiTexture::RED_OR_ALPHA8;
48 else if(fmt ==
"rgba16f")
49 return QRhiTexture::RGBA16F;
50 else if(fmt ==
"rgba32f")
51 return QRhiTexture::RGBA32F;
52 else if(fmt ==
"r16f")
53 return QRhiTexture::R16F;
55 return QRhiTexture::R32F;
56 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
57 else if(fmt ==
"rgb10a2")
58 return QRhiTexture::RGB10A2;
62 return QRhiTexture::D16;
64 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
66 return QRhiTexture::D24;
67 else if(fmt ==
"d24s8")
68 return QRhiTexture::D24S8;
70 else if(fmt ==
"d32f")
71 return QRhiTexture::D32F;
74 return QRhiTexture::BC1;
76 return QRhiTexture::BC2;
78 return QRhiTexture::BC3;
80 return QRhiTexture::BC4;
82 return QRhiTexture::BC5;
83 else if(fmt ==
"bc6h")
84 return QRhiTexture::BC6H;
86 return QRhiTexture::BC7;
87 else if(fmt ==
"etc2_rgb8")
88 return QRhiTexture::ETC2_RGB8;
89 else if(fmt ==
"etc2_rgb8a1")
90 return QRhiTexture::ETC2_RGB8A1;
91 else if(fmt ==
"etc2_rgb8a8")
92 return QRhiTexture::ETC2_RGBA8;
93 else if(fmt ==
"astc_4x4")
94 return QRhiTexture::ASTC_4x4;
95 else if(fmt ==
"astc_5x4")
96 return QRhiTexture::ASTC_5x4;
97 else if(fmt ==
"astc_5x5")
98 return QRhiTexture::ASTC_5x5;
99 else if(fmt ==
"astc_6x5")
100 return QRhiTexture::ASTC_6x5;
101 else if(fmt ==
"astc_6x6")
102 return QRhiTexture::ASTC_6x6;
103 else if(fmt ==
"astc_8x5")
104 return QRhiTexture::ASTC_8x5;
105 else if(fmt ==
"astc_8x6")
106 return QRhiTexture::ASTC_8x6;
107 else if(fmt ==
"astc_8x8")
108 return QRhiTexture::ASTC_8x8;
109 else if(fmt ==
"astc_10x5")
110 return QRhiTexture::ASTC_10x5;
111 else if(fmt ==
"astc_10x6")
112 return QRhiTexture::ASTC_10x6;
113 else if(fmt ==
"astc_10x8")
114 return QRhiTexture::ASTC_10x8;
115 else if(fmt ==
"astc_10x10")
116 return QRhiTexture::ASTC_10x10;
117 else if(fmt ==
"astc_12x10")
118 return QRhiTexture::ASTC_12x10;
119 else if(fmt ==
"astc_12x12")
120 return QRhiTexture::ASTC_12x12;
122 return QRhiTexture::RGBA8;
125 template <
typename F>
126 requires std::is_enum_v<typename F::format>
127 constexpr QRhiTexture::Format textureFormat()
130 requires { F::RGBA; } || requires { F::RGBA8; })
131 return QRhiTexture::RGBA8;
133 requires { F::BGRA; } || requires { F::BGRA8; })
134 return QRhiTexture::BGRA8;
136 requires { F::R8; } || requires { F::GRAYSCALE; })
137 return QRhiTexture::R8;
138 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
139 else if constexpr(requires { F::RG8; })
140 return QRhiTexture::RG8;
142 else if constexpr(requires { F::R16; })
143 return QRhiTexture::R16;
144 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
145 else if constexpr(requires { F::RG16; })
146 return QRhiTexture::RG16;
148 else if constexpr(requires { F::RED_OR_ALPHA8; })
149 return QRhiTexture::RED_OR_ALPHA8;
150 else if constexpr(requires { F::RGBA16F; })
151 return QRhiTexture::RGBA16F;
152 else if constexpr(requires { F::RGBA32F; })
153 return QRhiTexture::RGBA32F;
154 else if constexpr(requires { F::R16F; })
155 return QRhiTexture::R16F;
156 else if constexpr(requires { F::R32F; })
157 return QRhiTexture::R32F;
158 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
159 else if constexpr(requires { F::RGB10A2; })
160 return QRhiTexture::RGB10A2;
162 else if constexpr(requires { F::D16; })
163 return QRhiTexture::D16;
165 #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
166 else if constexpr(requires { F::D24; })
167 return QRhiTexture::D24;
168 else if constexpr(requires { F::D24S8; })
169 return QRhiTexture::D24S8;
171 else if constexpr(requires { F::D32F; })
172 return QRhiTexture::D32F;
174 else if constexpr(requires { F::BC1; })
175 return QRhiTexture::BC1;
176 else if constexpr(requires { F::BC2; })
177 return QRhiTexture::BC2;
178 else if constexpr(requires { F::BC3; })
179 return QRhiTexture::BC3;
180 else if constexpr(requires { F::BC4; })
181 return QRhiTexture::BC4;
182 else if constexpr(requires { F::BC5; })
183 return QRhiTexture::BC5;
184 else if constexpr(requires { F::BC6H; })
185 return QRhiTexture::BC6H;
186 else if constexpr(requires { F::BC7; })
187 return QRhiTexture::BC7;
188 else if(requires { F::ETC2_RGB8; })
189 return QRhiTexture::ETC2_RGB8;
190 else if(requires { F::ETC2_RGB8A1; })
191 return QRhiTexture::ETC2_RGB8A1;
192 else if(requires { F::ETC2_RGB8A8; })
193 return QRhiTexture::ETC2_RGBA8;
194 else if(requires { F::ASTC_4X4; })
195 return QRhiTexture::ASTC_4x4;
196 else if(requires { F::ASTC_5X4; })
197 return QRhiTexture::ASTC_5x4;
198 else if(requires { F::ASTC_5X5; })
199 return QRhiTexture::ASTC_5x5;
200 else if(requires { F::ASTC_6X5; })
201 return QRhiTexture::ASTC_6x5;
202 else if(requires { F::ASTC_6X6; })
203 return QRhiTexture::ASTC_6x6;
204 else if(requires { F::ASTC_8X5; })
205 return QRhiTexture::ASTC_8x5;
206 else if(requires { F::ASTC_8X6; })
207 return QRhiTexture::ASTC_8x6;
208 else if(requires { F::ASTC_8X8; })
209 return QRhiTexture::ASTC_8x8;
210 else if(requires { F::ASTC_10X5; })
211 return QRhiTexture::ASTC_10x5;
212 else if(requires { F::ASTC_10X6; })
213 return QRhiTexture::ASTC_10x6;
214 else if(requires { F::ASTC_10X8; })
215 return QRhiTexture::ASTC_10x8;
216 else if(requires { F::ASTC_10X10; })
217 return QRhiTexture::ASTC_10x10;
218 else if(requires { F::ASTC_12X10; })
219 return QRhiTexture::ASTC_12x10;
220 else if(requires { F::ASTC_12X12; })
221 return QRhiTexture::ASTC_12x12;
223 return QRhiTexture::RGBA8;
226 struct DefaultPipeline
238 static constexpr
auto name() {
return "position"; }
239 static constexpr
int location() {
return 0; }
246 struct fragment_input
254 static QString vertex()
256 return R
"_(#version 450
257 layout(location = 0) in vec2 position;
258 out gl_PerVertex { vec4 gl_Position; };
260 gl_Position = vec4( position, 0.0, 1.0 );
266 template <
typename C>
267 constexpr
auto usage()
269 if constexpr(requires { C::vertex; })
270 return QRhiBuffer::VertexBuffer;
271 else if constexpr(requires { C::index; })
272 return QRhiBuffer::IndexBuffer;
273 else if constexpr(requires { C::ubo; })
274 return QRhiBuffer::UniformBuffer;
275 else if constexpr(requires { C::storage; })
276 return QRhiBuffer::StorageBuffer;
279 static_assert(C::unhandled);
284 template <
typename C>
285 constexpr
auto buffer_type()
287 if constexpr(requires { C::immutable; })
288 return QRhiBuffer::Immutable;
289 else if constexpr(requires { C::static_; })
290 return QRhiBuffer::Static;
291 else if constexpr(requires { C::dynamic; })
292 return QRhiBuffer::Dynamic;
295 static_assert(C::unhandled);
300 template <
typename C>
303 if constexpr(requires { C::samples; })
309 struct handle_release
312 template <
typename C>
313 void operator()(C command)
315 if constexpr(requires { C::deallocation; })
318 requires { C::vertex; } || requires { C::index; } || requires { C::ubo; })
320 auto buf =
reinterpret_cast<QRhiBuffer*
>(command.handle);
323 else if constexpr(requires { C::sampler; })
325 auto buf =
reinterpret_cast<QRhiSampler*
>(command.handle);
328 else if constexpr(requires { C::texture; })
330 auto buf =
reinterpret_cast<QRhiTexture*
>(command.handle);
335 static_assert(C::unhandled);
340 static_assert(C::unhandled);
345 template <
typename Self,
typename Res>
346 struct handle_dispatch
350 QRhiCommandBuffer& cb;
351 QRhiResourceUpdateBatch*& res;
352 QRhiComputePipeline& pip;
353 template <
typename C>
354 Res operator()(C command)
356 if constexpr(requires { C::compute; })
358 if constexpr(requires { C::dispatch; })
360 cb.dispatch(command.x, command.y, command.z);
363 else if constexpr(requires { C::begin; })
365 cb.beginComputePass(res);
367 cb.setComputePipeline(&pip);
368 cb.setShaderResources(pip.shaderResourceBindings());
372 else if constexpr(requires { C::end; })
374 cb.endComputePass(res);
381 static_assert(C::unhandled);
385 else if constexpr(requires { C::readback; })
388 if constexpr(requires { C::request; })
390 if constexpr(requires { C::buffer; })
392 using ret =
typename C::return_type;
394 #if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
395 auto readback =
new QRhiBufferReadbackResult;
397 auto readback =
new QRhiReadbackResult;
399 self.addReadback(readback);
402 ret user_rb{.handle =
reinterpret_cast<decltype(ret::handle)
>(readback)};
413 auto next = rhi.nextResourceUpdateBatch();
414 auto buf =
reinterpret_cast<QRhiBuffer*
>(command.handle);
416 next->readBackBuffer(buf, command.offset, command.size, readback);
421 else if constexpr(requires { C::texture; })
423 using ret =
typename C::return_type;
424 QRhiReadbackResult readback;
429 static_assert(C::unhandled);
433 else if constexpr(requires { C::await; })
435 if constexpr(requires { C::buffer; })
437 using ret =
typename C::return_type;
439 #if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
440 auto readback =
reinterpret_cast<QRhiBufferReadbackResult*
>(command.handle);
442 auto readback =
reinterpret_cast<QRhiReadbackResult*
>(command.handle);
446 .data = readback->data.data(), .size = (std::size_t)readback->data.size()};
448 else if constexpr(requires { C::texture; })
450 using ret =
typename C::return_type;
452 auto readback =
reinterpret_cast<QRhiReadbackResult*
>(command.handle);
455 .data = readback->data.data(), .size = (std::size_t)readback->data.size()};
461 static_assert(C::unhandled);
469 template <
typename Self,
typename Ret>
474 QRhiResourceUpdateBatch& res;
475 std::vector<QRhiShaderResourceBinding>& srb;
478 template <
typename C>
479 Ret operator()(C command)
481 if constexpr(requires { C::allocation; })
484 requires { C::vertex; } || requires { C::index; })
486 auto buf = rhi.newBuffer(buffer_type<C>(), usage<C>(), command.size);
488 return reinterpret_cast<typename C::return_type
>(buf);
490 else if constexpr(requires { C::sampler; })
492 auto buf = rhi.newSampler({}, {}, {}, {}, {});
494 return reinterpret_cast<typename C::return_type
>(buf);
497 requires { C::ubo; } || requires { C::storage; })
499 auto buf = rhi.newBuffer(buffer_type<C>(), usage<C>(), command.size);
503 score::gfx::replaceBuffer(srb, command.binding, buf);
505 return reinterpret_cast<typename C::return_type
>(buf);
507 else if constexpr(requires { C::texture; })
509 auto tex = rhi.newTexture(
510 QRhiTexture::RGBA8, QSize{command.width, command.height}, samples(command));
513 score::gfx::replaceTexture(srb, command.binding, tex);
515 return reinterpret_cast<typename C::return_type
>(tex);
519 static_assert(C::unhandled);
523 else if constexpr(requires { C::upload; })
525 if constexpr(requires { C::texture; })
527 QRhiTextureSubresourceUploadDescription sub(command.data, command.size);
529 reinterpret_cast<QRhiTexture*
>(command.handle),
530 QRhiTextureUploadDescription{{0, 0, sub}});
534 auto buf =
reinterpret_cast<QRhiBuffer*
>(command.handle);
535 if constexpr(requires { C::dynamic; })
536 res.updateDynamicBuffer(buf, command.offset, command.size, command.data);
538 requires { C::static_; } || requires { C::immutable; })
539 res.uploadStaticBuffer(buf, command.offset, command.size, command.data);
542 static_assert(C::unhandled);
547 else if constexpr(requires { C::getter; })
549 if constexpr(requires { C::ubo; })
551 auto buf =
self.createdUbos.at(command.binding);
552 return reinterpret_cast<typename C::return_type
>(buf);
556 static_assert(C::unhandled);
562 handle_release{rhi}(command);
569 struct generate_shaders
571 template <
typename T,
int N>
574 static constexpr std::string_view field_type(
float) {
return "float"; }
575 static constexpr std::string_view field_type(
const float (&)[2]) {
return "vec2"; }
576 static constexpr std::string_view field_type(
const float (&)[3]) {
return "vec3"; }
577 static constexpr std::string_view field_type(
const float (&)[4]) {
return "vec4"; }
579 static constexpr std::string_view field_type(
float*) {
return "float"; }
580 static constexpr std::string_view field_type(vec<float, 2>*) {
return "vec2"; }
581 static constexpr std::string_view field_type(vec<float, 3>*) {
return "vec3"; }
582 static constexpr std::string_view field_type(vec<float, 4>*) {
return "vec4"; }
584 static constexpr std::string_view field_type(
int) {
return "int"; }
585 static constexpr std::string_view field_type(
const int (&)[2]) {
return "ivec2"; }
586 static constexpr std::string_view field_type(
const int (&)[3]) {
return "ivec3"; }
587 static constexpr std::string_view field_type(
const int (&)[4]) {
return "ivec4"; }
589 static constexpr std::string_view field_type(
int*) {
return "int"; }
590 static constexpr std::string_view field_type(vec<int, 2>*) {
return "ivec2"; }
591 static constexpr std::string_view field_type(vec<int, 3>*) {
return "ivec3"; }
592 static constexpr std::string_view field_type(vec<int, 4>*) {
return "ivec4"; }
594 static constexpr std::string_view field_type(uint32_t) {
return "uint"; }
595 static constexpr std::string_view field_type(
const uint32_t (&)[2]) {
return "uvec2"; }
596 static constexpr std::string_view field_type(
const uint32_t (&)[3]) {
return "uvec3"; }
597 static constexpr std::string_view field_type(
const uint32_t (&)[4]) {
return "uvec4"; }
599 static constexpr std::string_view field_type(uint32_t*) {
return "uint"; }
600 static constexpr std::string_view field_type(vec<uint32_t, 2>*) {
return "uvec2"; }
601 static constexpr std::string_view field_type(vec<uint32_t, 3>*) {
return "uvec3"; }
602 static constexpr std::string_view field_type(vec<uint32_t, 4>*) {
return "uvec4"; }
604 static constexpr std::string_view field_type(avnd::xy_value
auto) {
return "vec2"; }
606 static constexpr
bool field_array(
float) {
return false; }
607 static constexpr
bool field_array(
const float (&)[2]) {
return false; }
608 static constexpr
bool field_array(
const float (&)[3]) {
return false; }
609 static constexpr
bool field_array(
const float (&)[4]) {
return false; }
611 static constexpr
bool field_array(
float*) {
return true; }
612 static constexpr
bool field_array(vec<float, 2>*) {
return true; }
613 static constexpr
bool field_array(vec<float, 3>*) {
return true; }
614 static constexpr
bool field_array(vec<float, 4>*) {
return true; }
616 static constexpr
bool field_array(
int) {
return false; }
617 static constexpr
bool field_array(
const int (&)[2]) {
return false; }
618 static constexpr
bool field_array(
const int (&)[3]) {
return false; }
619 static constexpr
bool field_array(
const int (&)[4]) {
return false; }
621 static constexpr
bool field_array(
int*) {
return true; }
622 static constexpr
bool field_array(vec<int, 2>*) {
return true; }
623 static constexpr
bool field_array(vec<int, 3>*) {
return true; }
624 static constexpr
bool field_array(vec<int, 4>*) {
return true; }
626 static constexpr
bool field_array(uint32_t) {
return false; }
627 static constexpr
bool field_array(
const uint32_t (&)[2]) {
return false; }
628 static constexpr
bool field_array(
const uint32_t (&)[3]) {
return false; }
629 static constexpr
bool field_array(
const uint32_t (&)[4]) {
return false; }
631 static constexpr
bool field_array(uint32_t*) {
return true; }
632 static constexpr
bool field_array(vec<uint32_t, 2>*) {
return true; }
633 static constexpr
bool field_array(vec<uint32_t, 3>*) {
return true; }
634 static constexpr
bool field_array(vec<uint32_t, 4>*) {
return true; }
636 static constexpr
bool field_array(avnd::xy_value
auto) {
return false; }
638 template <
typename T>
639 static constexpr std::string_view image_qualifier()
641 if constexpr(requires { T::readonly; })
643 else if constexpr(requires { T::writeonly; })
646 static_assert(T::readonly || T::writeonly);
653 template <
typename T>
654 void operator()(
const T& field)
656 shader += fmt::format(
657 "layout(location = {}) in {} {};\n", T::location(), field_type(field.data),
666 template <
typename T>
667 void operator()(
const T& field)
669 if constexpr(requires { field.location(); })
671 shader += fmt::format(
672 "layout(location = {}) out {} {};\n", T::location(), field_type(field.data),
682 template <
typename T>
683 void operator()(
const T& field)
685 shader += fmt::format(
686 " {} {}{};\n", field_type(field.value), T::name(),
687 field_array(field.value) ?
"[]" :
"");
691 struct write_bindings
695 template <
typename C>
696 void operator()(
const C& field)
698 if constexpr(requires { C::sampler2D; })
700 shader += fmt::format(
701 "layout(binding = {}) uniform sampler2D {};\n\n", C::binding(), C::name());
703 else if constexpr(requires { C::image2D; })
705 shader += fmt::format(
706 "layout(binding = {}, {}) {} uniform image2D {};\n\n", C::binding(),
707 C::format(), image_qualifier<C>(), C::name());
709 else if constexpr(requires { C::ubo; })
711 shader += fmt::format(
712 "layout({}, binding = {}) uniform {}\n{{\n",
715 C::binding(), C::name());
717 boost::pfr::for_each_field(field, write_binding{shader});
719 shader += fmt::format(
"}};\n\n");
721 else if constexpr(requires { C::buffer; })
723 shader += fmt::format(
724 "layout({}, binding = {}) buffer {}\n{{\n",
727 C::binding(), C::name());
729 boost::pfr::for_each_field(field, write_binding{shader});
731 shader += fmt::format(
"}};\n\n");
736 template <
typename T>
737 std::string vertex_shader(
const T& lay)
739 using namespace gpp::qrhi;
740 std::string shader =
"#version 450\n\n";
742 if constexpr(requires { lay.vertex_input; })
743 boost::pfr::for_each_field(lay.vertex_input, write_input{shader});
744 else if constexpr(requires {
typename T::vertex_input; })
745 boost::pfr::for_each_field(
typename T::vertex_input{}, write_input{shader});
747 boost::pfr::for_each_field(
748 DefaultPipeline::layout::vertex_input{}, write_input{shader});
750 if constexpr(requires { lay.vertex_output; })
751 boost::pfr::for_each_field(lay.vertex_output, write_output{shader});
752 else if constexpr(requires {
typename T::vertex_output; })
753 boost::pfr::for_each_field(
typename T::vertex_output{}, write_output{shader});
757 if constexpr(requires { lay.bindings; })
758 boost::pfr::for_each_field(lay.bindings, write_bindings{shader});
759 else if constexpr(requires {
typename T::bindings; })
760 boost::pfr::for_each_field(
typename T::bindings{}, write_bindings{shader});
765 template <
typename T>
766 std::string fragment_shader(
const T& lay)
768 std::string shader =
"#version 450\n\n";
770 if constexpr(requires { lay.fragment_input; })
771 boost::pfr::for_each_field(lay.fragment_input, write_input{shader});
772 else if constexpr(requires {
typename T::fragment_input; })
773 boost::pfr::for_each_field(
typename T::fragment_input{}, write_input{shader});
775 if constexpr(requires { lay.fragment_output; })
776 boost::pfr::for_each_field(lay.fragment_output, write_output{shader});
777 else if constexpr(requires {
typename T::fragment_output; })
778 boost::pfr::for_each_field(
typename T::fragment_output{}, write_output{shader});
782 if constexpr(requires { lay.bindings; })
783 boost::pfr::for_each_field(lay.bindings, write_bindings{shader});
784 else if constexpr(requires {
typename T::bindings; })
785 boost::pfr::for_each_field(
typename T::bindings{}, write_bindings{shader});
790 template <
typename T>
791 std::string compute_shader(
const T& lay)
793 std::string fstr =
"#version 450\n\n";
796 if constexpr(requires { T::local_size_x(); })
798 fstr += fmt::format(
"local_size_x = {}, ", T::local_size_x());
800 if constexpr(requires { T::local_size_y(); })
802 fstr += fmt::format(
"local_size_y = {}, ", T::local_size_y());
804 if constexpr(requires { T::local_size_z(); })
806 fstr += fmt::format(
"local_size_z = {}, ", T::local_size_z());
810 fstr.resize(fstr.size() - 2);
813 boost::pfr::for_each_field(lay.bindings, write_bindings{fstr});
824 template <
typename Node>
825 static void initWorker(Node& state) noexcept
827 if constexpr(avnd::has_worker<Node>)
829 using worker_type = decltype(state.worker);
831 state.worker.request = [&state]<
typename... Args>(Args&&... f) {
832 using type_of_result = decltype(worker_type::work(std::forward<Args>(f)...));
833 if constexpr(std::is_void_v<type_of_result>)
835 worker_type::work(std::forward<Args>(f)...);
841 auto res = worker_type::work(std::forward<Args>(f)...);
852 template <
typename Node_T>
856 avnd::parameter_input_introspection<Node_T>::for_all_n2(
857 avnd::get_inputs<Node_T>(state),
858 [&](avnd::parameter
auto& t,
auto pred_index,
auto field_index) {
859 if(mess.input.size() > field_index)
861 if(auto val = ossia::get_if<ossia::value>(&mess.input[field_index]))
863 oscr::from_ossia_value(t, *val, t.value);
864 if_possible(t.update(state));
871 struct GpuControlOuts
873 std::weak_ptr<Execution::ExecutionCommandQueue> queue;
874 Gfx::exec_controls control_outs;
878 template <
typename Node_T>
879 void processControlOut(Node_T& state)
const noexcept
881 if(!this->control_outs.empty())
883 auto q = this->queue.lock();
888 avnd::parameter_output_introspection<Node_T>::for_all(
889 avnd::get_outputs(state), [&]<avnd::parameter T>(
const T& t) {
890 qq.enqueue([v = oscr::to_ossia_value(t, t.value),
891 port = control_outs[parm_k]]()
mutable {
892 std::swap(port->value, v);
893 port->changed = true;
904 virtual ~CustomGfxNodeBase();
911 virtual ~CustomGfxOutputNodeBase();
916 struct CustomGpuNodeBase
923 std::weak_ptr<Execution::ExecutionCommandQueue>&& q, Gfx::exec_controls&& ctls)
924 : GpuControlOuts{std::move(q), std::move(ctls)}
928 virtual ~CustomGpuNodeBase() =
default;
930 QString vertex, fragment, compute;
935 struct SCORE_PLUGIN_AVND_EXPORT CustomGpuOutputNodeBase
941 CustomGpuOutputNodeBase(
942 std::weak_ptr<Execution::ExecutionCommandQueue> q, Gfx::exec_controls&& ctls);
943 virtual ~CustomGpuOutputNodeBase();
945 std::weak_ptr<score::gfx::RenderList> m_renderer{};
946 std::shared_ptr<score::gfx::RenderState> m_renderState{};
947 std::function<void()> m_update;
949 QString vertex, fragment, compute;
953 void setRenderer(std::shared_ptr<score::gfx::RenderList>)
override;
956 void startRendering()
override;
957 void render()
override;
958 void stopRendering()
override;
959 bool canRender()
const override;
960 void onRendererChange()
override;
964 std::function<
void()> onUpdate, std::function<
void()> onResize)
override;
966 void destroyOutput()
override;
967 std::shared_ptr<score::gfx::RenderState> renderState()
const override;
969 Configuration configuration() const noexcept override;
972 template <typename Node_T, typename Node>
973 void prepareNewState(Node_T& eff, const Node& parent)
975 if constexpr(avnd::has_worker<Node_T>)
977 parent.initWorker(eff);
979 if constexpr(avnd::has_processor_to_gui_bus<Node_T>)
981 auto& process = parent.processModel;
982 eff.send_message = [&
process](
auto&& b)
mutable {
987 MessageBusSender{process.to_ui}(std::move(b));
994 avnd::init_controls(eff);
996 if constexpr(avnd::can_prepare<Node_T>)
998 using prepare_type = avnd::first_argument<&Node_T::prepare>;
1000 if_possible(t.instance = parent.instance);
Root data model for visual nodes.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:60
virtual void process(Message &&msg)
Process a message from the execution engine.
Definition: Node.cpp:24
Common base class for most single-pass, simple nodes.
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:180
Base class for sink nodes (QWindow, spout, syphon, NDI output, ...)
Definition: OutputNode.hpp:23
void process(Message &&msg) override
Process a message from the execution engine.
Definition: Node.cpp:337
List of nodes to be rendered to an output.
Definition: RenderList.hpp:19
GraphicsApi
Available graphics APIs to use.
Definition: RenderState.hpp:17
Definition: score-plugin-gfx/Gfx/Graph/Node.hpp:51