RenderedISFNode.hpp
1 #pragma once
2 #include <Gfx/Graph/ISFNode.hpp>
3 #include <Gfx/Graph/NodeRenderer.hpp>
4 
5 #include <ossia/audio/fft.hpp>
6 #include <ossia/detail/small_flat_map.hpp>
7 #include <ossia/detail/variant.hpp>
8 #include <ossia/math/math_expression.hpp>
9 
10 namespace score::gfx
11 {
12 struct Pass
13 {
14  TextureRenderTarget renderTarget;
15  Pipeline p;
16  QRhiBuffer* processUBO{};
17 };
18 
20 {
21  QRhiSampler* sampler{};
22  QRhiTexture* textures[2]{nullptr, nullptr};
23 };
24 using PassOutput = ossia::variant<PersistSampler, TextureRenderTarget>;
25 
27 {
28  explicit AudioTextureUpload();
29 
30  void
31  process(AudioTexture& audio, QRhiResourceUpdateBatch& res, QRhiTexture* rhiTexture);
32 
33  void processTemporal(
34  AudioTexture& audio, QRhiResourceUpdateBatch& res, QRhiTexture* rhiTexture);
35 
36  void processSpectral(
37  AudioTexture& audio, QRhiResourceUpdateBatch& res, QRhiTexture* rhiTexture);
38 
39  [[nodiscard]] std::optional<Sampler> updateAudioTexture(
40  AudioTexture& audio, RenderList& renderer, char* materialData,
41  QRhiResourceUpdateBatch& res);
42 
43 private:
44  std::vector<float> m_scratchpad;
45  ossia::fft m_fft;
46 };
47 
49 {
50  RenderedISFNode(const ISFNode& node) noexcept;
51 
52  virtual ~RenderedISFNode();
53 
54  TextureRenderTarget renderTargetForInput(const Port& p) override;
55 
56  void init(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
57  void update(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
58  void release(RenderList& r) override;
59 
60  void runInitialPasses(
61  RenderList&, QRhiCommandBuffer& commands, QRhiResourceUpdateBatch*& res,
62  Edge& edge) override;
63 
64  void runRenderPass(RenderList&, QRhiCommandBuffer& commands, Edge& edge) override;
65 
66 private:
67  ossia::small_flat_map<const Port*, TextureRenderTarget, 2> m_rts;
68 
69  std::pair<Pass, Pass> createPass(
70  RenderList& renderer, ossia::small_vector<PassOutput, 1>& m_passSamplers,
71  PassOutput target, bool previousPassIsPersistent);
72 
73  std::pair<Pass, Pass> createFinalPass(
74  RenderList& renderer, ossia::small_vector<PassOutput, 1>& m_passSamplers,
75  const TextureRenderTarget& target);
76  void initPasses(
77  const TextureRenderTarget& rt, RenderList& renderer, Edge& edge, int& cur_pos,
78  QSize mainTexSize, QRhiResourceUpdateBatch& res);
79 
80  PassOutput initPassSampler(
81  ISFNode& n, const isf::pass& pass, RenderList& renderer, int& cur_pos,
82  QSize mainTexSize, QRhiResourceUpdateBatch& res);
83 
84  struct Passes
85  {
86  ossia::small_vector<Pass, 1> passes;
87  ossia::small_vector<Pass, 1> altPasses;
88  ossia::small_vector<PassOutput, 1> samplers;
89  };
90 
91  std::vector<Sampler>
92  allSamplers(ossia::small_vector<PassOutput, 1>&, int mainOrAltPass) const noexcept;
93 
94  ossia::small_vector<std::pair<Edge*, Passes>, 2> m_passes;
95 
96  ISFNode& n;
97 
98  std::vector<Sampler> m_inputSamplers;
99  std::vector<Sampler> m_audioSamplers;
100 
101  std::vector<TextureRenderTarget> m_innerPassTargets;
102 
103  const Mesh* m_mesh{};
104  QRhiBuffer* m_meshBuffer{};
105  QRhiBuffer* m_idxBuffer{};
106 
107  QRhiBuffer* m_materialUBO{};
108  int m_materialSize{};
109  int64_t materialChangedIndex{-1};
110 
111  AudioTextureUpload m_audioTex;
112 };
113 
114 // Used for the simple case of a single, non-persistent pass (the most common case)
115 
117 {
118  SimpleRenderedISFNode(const ISFNode& node) noexcept;
119 
120  virtual ~SimpleRenderedISFNode();
121 
122  TextureRenderTarget renderTargetForInput(const Port& p) override;
123 
124  void init(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
125  void update(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
126  void release(RenderList& r) override;
127 
128  void runInitialPasses(
129  RenderList&, QRhiCommandBuffer& commands, QRhiResourceUpdateBatch*& res,
130  Edge& edge) override;
131 
132  void runRenderPass(RenderList&, QRhiCommandBuffer& commands, Edge& edge) override;
133 
134 private:
135  ossia::small_flat_map<const Port*, TextureRenderTarget, 2> m_rts;
136 
137  void initPass(const TextureRenderTarget& rt, RenderList& renderer, Edge& edge);
138 
139  std::vector<Sampler> allSamplers() const noexcept;
140 
141  ossia::small_vector<std::pair<Edge*, Pass>, 2> m_passes;
142 
143  ISFNode& n;
144 
145  std::vector<Sampler> m_inputSamplers;
146  std::vector<Sampler> m_audioSamplers;
147 
148  const Mesh* m_mesh{};
149  QRhiBuffer* m_meshBuffer{};
150  QRhiBuffer* m_idxBuffer{};
151 
152  QRhiBuffer* m_materialUBO{};
153  int m_materialSize{};
154  int64_t materialChangedIndex{-1};
155 
156  std::optional<AudioTextureUpload> m_audioTex;
157 };
158 }
Data model for Interactive Shader Format filters.
Definition: ISFNode.hpp:20
Renderer for a given node.
Definition: NodeRenderer.hpp:11
List of nodes to be rendered to an output.
Definition: RenderList.hpp:19
Graphics rendering pipeline for ossia score.
Definition: Filter/PreviewWidget.hpp:12
Data model for audio data being sent to the GPU.
Definition: score-plugin-gfx/Gfx/Graph/Utils.hpp:34
Definition: RenderedISFNode.hpp:27
Connection between two score::gfx::Port.
Definition: score-plugin-gfx/Gfx/Graph/Utils.hpp:66
Data model for meshes.
Definition: Mesh.hpp:23
Definition: RenderedISFNode.hpp:13
Definition: RenderedISFNode.hpp:20
Useful abstraction for storing a graphics pipeline and associated resource bindings.
Definition: score-plugin-gfx/Gfx/Graph/Utils.hpp:93
Port of a score::gfx::Node.
Definition: score-plugin-gfx/Gfx/Graph/Utils.hpp:48
Definition: RenderedISFNode.hpp:49
Definition: RenderedISFNode.hpp:117
Useful abstraction for storing all the data related to a render target.
Definition: score-plugin-gfx/Gfx/Graph/Utils.hpp:111