47 void updateInputTexture(
const Port& input, QRhiTexture* tex, QRhiTexture* depthTex =
nullptr)
override;
49 QRhiTexture* textureForOutput(
const Port& output)
override;
51 void init(
RenderList& renderer, QRhiResourceUpdateBatch& res)
override;
52 void update(
RenderList& renderer, QRhiResourceUpdateBatch& res,
Edge* edge)
override;
55 void initState(
RenderList& renderer, QRhiResourceUpdateBatch& res)
override;
56 void releaseState(
RenderList& renderer)
override;
58 RenderList& renderer,
Edge& edge, QRhiResourceUpdateBatch& res)
override;
60 bool hasOutputPassForEdge(
Edge& edge)
const override;
62 addInputEdge(
RenderList& renderer,
Edge& edge, QRhiResourceUpdateBatch& res)
override;
64 bool followsRenderSize()
const noexcept override;
66 void runInitialPasses(
67 RenderList&, QRhiCommandBuffer& commands, QRhiResourceUpdateBatch*& res,
70 void runRenderPass(
RenderList&, QRhiCommandBuffer& commands,
Edge& edge)
override;
72 std::vector<Sampler> allSamplers()
const noexcept;
75 void initComputeSRBAndPasses(
RenderList& renderer, QRhiResourceUpdateBatch& res);
76 void createComputePipeline(
RenderList& renderer);
79 struct CompiledComputePipelines
81 std::vector<std::unique_ptr<QRhiComputePipeline>> owned;
82 std::vector<QRhiComputePipeline*> perPass;
84 std::vector<std::vector<uint32_t>> spec;
88 bool compileComputePipelines(
RenderList& renderer, CompiledComputePipelines& out);
90 void commitComputePipelines(CompiledComputePipelines& c);
93 void bindInputSampler(std::size_t samplerIndex, QRhiTexture* tex);
94 void prepareSelfFeedbackInputs(
RenderList& renderer, QRhiResourceUpdateBatch& res);
97 void registerCommonExpressionVariables(
98 ossia::math_expression& e, ossia::small_pod_vector<double, 16>& data)
const;
105 std::size_t expressionSymbolReserveCount()
const noexcept;
110 QSize getImageSize(
const isf::csf_image_input&, QSize fallback)
const noexcept;
111 QSize computeTextureSize(
const isf::csf_image_input& img)
const noexcept;
114 int calculateStorageBufferSize(std::span<const isf::storage_input::layout_field> layout,
int arrayCount)
const;
116 RenderList& renderer,
const QString& name,
const QString& access, int64_t size);
117 void updateStorageBuffers(
RenderList& renderer, QRhiResourceUpdateBatch& res);
118 void recreateShaderResourceBindings(
RenderList& renderer, QRhiResourceUpdateBatch& res);
121 std::vector<QRhiBuffer*> m_srbAdoptedBuffers;
123 std::vector<QRhiBuffer*> m_srbPreviousAdoptions;
128 void adoptForSrb(QRhiBuffer* buf);
138 void buildComputeSrbBindings(
139 RenderList& renderer, QRhiResourceUpdateBatch& res,
140 QList<QRhiShaderResourceBinding>& bindings);
141 int getArraySizeFromUI(
const QString& bufferName)
const;
142 QString updateShaderWithImageFormats(QString current);
145 void updateGeometryBindings(
RenderList& renderer, QRhiResourceUpdateBatch& res);
147 void pushOutputGeometry(
RenderList& renderer, QRhiResourceUpdateBatch& res,
Edge& edge);
148 int resolveCountExpression(
149 const std::string& expr,
const isf::geometry_input& geo,
150 const std::string& fieldName)
const;
151 int resolveDispatchExpression(
const std::string& expr)
const;
157 QRhiComputePipeline* pipeline{};
158 QRhiShaderResourceBindings* srb{};
159 QRhiBuffer* processUBO{};
165 size_t srbBindingsHash{0};
171 QRhiSampler* outputSampler{};
175 ossia::small_vector<std::pair<Edge*, ComputePass>, 2> m_computePasses;
176 ossia::small_vector<std::pair<Edge*, GraphicsPass>, 2> m_graphicsPasses;
180 std::vector<Sampler> m_inputSamplers;
181 std::vector<Sampler> m_audioSamplers;
183 struct SelfFeedbackInput
185 std::size_t sampler{};
186 std::size_t storage{};
187 QRhiTexture* snapshot{};
190 std::vector<SelfFeedbackInput> m_selfFeedbackInputs;
196 QRhiBuffer* buffer{};
199 int64_t lastKnownSize{};
202 std::vector<isf::storage_input::layout_field> layout;
204 std::string buffer_usage;
207 bool persistent{
false};
212 bool m_auxSizeUnresolved{
false};
213 std::vector<StorageBuffer> m_storageBuffers;
216 ossia::hash_map<std::string, QRhiBuffer*> m_uniformPlaceholders;
219 ossia::hash_map<std::string, QString> m_uniformRefusals;
220 bool m_warnedIndirectArgs{
false};
221 bool m_warnedIndirectNumWorkGroups{
false};
225 bool m_numWorkGroupsUniform{
false};
226 bool m_warnedDispatchTooLarge{
false};
229 bool m_storageUnallocated{
false};
230 bool m_warnedStorageUnallocated{
false};
234 std::vector<std::pair<const score::gfx::Port*, int>> m_outStorageBuffers;
239 QRhiTexture* texture{};
240 QRhiTexture* read_texture{};
243 QRhiTexture::Format format{QRhiTexture::RGBA8};
246 bool persistent{
false};
247 bool pending_initial_copy{
false};
248 bool generate_mips{
false};
254 int prev_binding{-1};
256 std::vector<StorageImage> m_storageImages;
259 std::vector<std::pair<const score::gfx::Port*, int>> m_outStorageImages;
262 struct GeometryBinding
267 QRhiBuffer* buffer{};
268 QRhiBuffer* read_buffer{};
271 bool read_buffer_is_snapshot{
false};
272 bool warned_size_mismatch{
false};
273 bool warned_borrowed_pair{
false};
280 QRhiBuffer* restore_source{};
281 int64_t restore_offset{};
282 int64_t restore_size{};
283 bool restore_seen{
false};
286 bool per_instance{
false};
287 const void* lastUploadSrc{};
290 QRhiBuffer* scatterStaging{};
292 QRhiBuffer* scatter_source{};
293 bool scatter_seen{
false};
294 int64_t scatterStagingSize{};
297 bool scatterPending{
false};
310 QRhiBuffer* buffer{};
316 QRhiBuffer* restore_source{};
317 int64_t restore_offset{};
318 int64_t restore_size{};
319 bool restore_seen{
false};
320 bool is_uniform{
false};
323 std::vector<isf::storage_input::layout_field> layout;
324 std::string size_expr;
331 QRhiBuffer* column_table_buffer{};
342 uint32_t byte_offset{};
347 std::vector<ColumnAttribute> column_attributes;
348 std::vector<int64_t> column_layout;
349 std::vector<std::pair<const void*, int64_t>> column_buffers;
351 bool column_from_mesh{};
352 QRhiBuffer* column_bound{};
361 QRhiSampler* sampler{};
362 QRhiTexture* texture{};
363 bool mips_follow_texture{
false};
364 QRhiTexture* placeholder{};
367 bool is_storage{
false};
382 std::vector<AttributeSSBO> attribute_ssbos;
383 std::vector<AuxiliarySSBO> auxiliary_ssbos;
384 std::vector<AuxiliaryTexture> auxiliary_textures;
385 std::string input_name;
387 int instance_count{1};
388 int input_port_index{-1};
389 int outlet_index{-1};
392 bool closesCycle{
false};
393 uint64_t closesCycleGeneration{~uint64_t{0}};
394 bool has_output{
false};
395 bool has_vertex_count_spec{
false};
396 bool warned_multiple_cables{
false};
397 bool has_instance_count_spec{
false};
398 bool is_feedback_receiver{
false};
399 bool pending_initial_copy{
false};
403 std::vector<QRhiBuffer*> copyFromBuffers;
407 ossia::geometry_spec outputGeometry;
408 int prev_vertex_count{-1};
409 int prev_instance_count{-1};
410 int prev_attribute_count{-1};
411 int prev_upstream_attr_count{-1};
412 int prev_upstream_aux_count{-1};
413 int prev_mesh_count{-1};
416 std::vector<std::pair<const ossia::mesh_list*, int64_t>> mesh_seen;
420 std::vector<int> declared;
421 std::vector<std::pair<int, int>> forwarded;
422 std::vector<int> auxiliary;
423 std::vector<int> storage;
424 int forwarded_aux_begin{0};
425 int forwarded_aux_end{0};
428 QRhiBuffer* indirectBuffer{};
429 int64_t indirectBufferSize{};
430 int indirectCountResult{0};
431 std::string indirectCountExpr;
432 bool uses_indirect_draw{
false};
436 QRhiBuffer* indirectCountBuffer{};
437 bool uses_indirect_count{
false};
439 std::vector<GeometryBinding> m_geometryBindings;
444 std::vector<std::vector<uint32_t>> columnSpecialization()
const;
447 QString specializeColumns(
448 QString src,
const std::vector<std::vector<uint32_t>>& spec)
const;
450 void rebuildComputePipelines(RenderList& renderer);
451 std::vector<std::vector<uint32_t>> m_columnSpec;
454 uint64_t m_columnTablesGeneration{1};
456 std::vector<uint32_t> m_columnTableScratch;
457 uint64_t m_columnSpecGeneration{0};
458 bool m_hasColumns{
false};
460 bool m_specializeColumns{
true};
464 RenderList& renderer, QRhiResourceUpdateBatch& res, GeometryBinding& binding,
465 const isf::geometry_input& geo,
const ossia::geometry* mesh);
472 std::vector<GeometryBinding> bindings;
473 std::vector<ComputePass> passes;
475 bool auxSizeUnresolved{
false};
477 bool passthrough{
false};
479 std::vector<MeshLayer> m_meshLayers;
483 struct MeshLayerScope
485 RenderedCSFNode& self;
487 MeshLayerScope(RenderedCSFNode& s, MeshLayer& l)
noexcept;
490 void swapMeshLayer(MeshLayer& layer)
noexcept;
491 int processedMeshCount()
const;
492 void updateMeshLayers(RenderList& renderer, QRhiResourceUpdateBatch& res);
493 void releaseMeshLayer(RenderList& renderer, MeshLayer& layer);
494 const ossia::geometry* upstreamMesh(
int port)
const noexcept;
495 void runGeometryPasses(
496 RenderList& renderer, QRhiCommandBuffer& commands, QRhiResourceUpdateBatch*& res,
497 Edge& edge,
bool firstMesh);
501 bool m_loggedIndirectDispatch{
false};
503 QByteArray m_liveCheckLabel;
505 QRhiBuffer* m_materialUBO{};
506 int m_materialSize{};
510 std::size_t m_srbRangeHash{};
513 QRhiTexture* m_outputTexture{};
514 QRhiTexture::Format m_outputFormat{QRhiTexture::RGBA8};
517 QRhiComputePipeline* m_computePipeline{};
518 QShader m_computeShader;
519 QString m_computeShaderSource;
520 std::vector<QRhiComputePipeline*> m_perPassPipelines;
521 std::vector<QRhiComputePipeline*> m_ownedPipelines;
522 bool m_pipelinesDirty{
true};
525 GPUBufferScatter m_gpuScatter;
526 bool m_gpuScatterAvailable{
false};
533 bool m_inputsHaveBeenWritten{
false};
543 int64_t m_lastRunFrame{-1};
545 int64_t m_frameIndexFrame{-1};