Loading...
Searching...
No Matches
RenderList.hpp
1#pragma once
2#include <Gfx/Graph/CommonUBOs.hpp>
3#include <Gfx/Graph/GpuTiming.hpp>
4#include <Gfx/Graph/Node.hpp>
5
6#include <ossia/detail/hash_map.hpp>
7
8#include <memory>
9
10namespace Gfx
11{
12class AssetTable;
13}
14namespace score::gfx
15{
16
17class GpuResourceRegistry;
18class OutputNode;
19class VertexFallbackPool;
29class SCORE_PLUGIN_GFX_EXPORT RenderList
30{
31 friend struct Graph;
32private:
33 QRhiCommandBuffer* m_currentCommands{};
34 std::shared_ptr<RenderState> m_state;
35
36public:
37 explicit RenderList(OutputNode& output, const std::shared_ptr<RenderState>& state);
39
43 void init();
44
50 [[nodiscard]] QRhiResourceUpdateBatch* initialBatch() const noexcept;
51
58 void setInitialBatch(QRhiResourceUpdateBatch* batch) noexcept { m_initialBatch = batch; }
59
69 void flushInitialBatch();
70
77 MeshBuffers initMeshBuffer(const Mesh& mesh, QRhiResourceUpdateBatch& res);
78
82 void update(QRhiResourceUpdateBatch& res);
83
87 void render(QRhiCommandBuffer& commands, bool force = false);
88
92 QRhiCommandBuffer* currentCommandBuffer() const noexcept
93 {
94 return m_currentCommands;
95 }
96
100 void release();
101
102 void releaseBuffer(QRhiBuffer* buf);
103
107 bool maybeRebuild(bool force = false);
108
134 bool resizeSwapchainSizedTargets(QSize newOutputSize, QSize newRenderSize);
135
141 TextureRenderTarget renderTargetForOutput(const Edge& edge) const noexcept;
142
149 TextureRenderTarget renderTargetForInputPort(const Port& p) const noexcept;
150
151 BufferView bufferForInput(const Edge& edge) const noexcept;
152 BufferView bufferForOutput(const Edge& edge) const noexcept;
153
159 QImage adaptImage(const QImage& in);
160
165
170
171 using Buffers = std::pair<const Mesh* const, MeshBuffers>;
172 Buffers acquireMesh(
173 const ossia::geometry_spec&, QRhiResourceUpdateBatch& res, const Mesh* current,
174 MeshBuffers currentbufs) noexcept;
175
179 std::vector<score::gfx::Node*> nodes;
180
184 std::vector<score::gfx::NodeRenderer*> renderers;
185
187 void clearRenderers();
188
192 QRhiTexture& emptyTexture() const noexcept { return *m_emptyTexture; }
193
197 QRhiTexture& emptyTexture3D() const noexcept { return *m_emptyTexture3D; }
198
202 QRhiTexture& emptyTextureCube() const noexcept { return *m_emptyTextureCube; }
203
207 QRhiTexture& emptyTextureArray() const noexcept { return *m_emptyTextureArray; }
208
215 QRhiBuffer& outputUBO() const noexcept { return *m_outputUBO; }
216
235 GpuResourceRegistry& registry() noexcept { return *m_registry; }
236 const GpuResourceRegistry& registry() const noexcept { return *m_registry; }
237
245 VertexFallbackPool& vertexFallbackPool() noexcept { return *m_vertexFallbackPool; }
246
254 GpuTimings& gpuTimings() noexcept { return m_gpuTimings; }
255 const GpuTimings& gpuTimings() const noexcept { return m_gpuTimings; }
256
264 Gfx::AssetTable* assetTable() const noexcept { return m_assetTable; }
265 void setAssetTable(Gfx::AssetTable* t) noexcept { m_assetTable = t; }
266
270 const score::gfx::Mesh& defaultQuad() const noexcept;
271
275 const score::gfx::Mesh& defaultTriangle() const noexcept;
276
282 bool requiresDepth(const score::gfx::Port& p) const noexcept;
283 bool anyNodeRequiresDepth() const noexcept { return m_requiresDepth; }
284
285 int samples() const noexcept { return m_samples; }
286
287 bool canRender() const noexcept { return m_ready; }
288
289 QSize renderSize(const Edge* e) const noexcept;
290
291 int64_t frame = 0;
292 float currentDate[4]{};
293
294 void createAllInputRenderTargets();
295
303 void markBuilt() noexcept { m_built = true; m_lastSize = state.renderSize; }
304
315 [[nodiscard]] bool isBuilt() const noexcept { return m_built; }
316
321 void markRequiresDepth(bool value) noexcept { m_requiresDepth = value; }
322
330 void
331 onEdgeRemoved(Edge& edge, const ossia::hash_set<const Port*>* preserveSinks = nullptr);
332
334 void removeInputRenderTarget(const Port* port);
335
343 QSize resolveDownstreamSize(
344 const Node* node,
345 const ossia::small_flat_map<const Port*, RenderTargetSpecs, 16>& resolvedSpecs)
346 const noexcept;
347
348private:
349 OutputUBO m_outputUBOData;
350
351
352 QRhiResourceUpdateBatch* m_initialBatch{};
353
354 // Scene-graph arena store (camera / light / material / per_draw buffers).
355 // Persist-across-rebuild contract: ownership is on the OutputNode
356 // (OutputNode::m_registry), so the registry — and all its arena
357 // buffers, mesh slabs, texture-array channels, ScenePreprocessor
358 // material/env slots — survives `Graph::recreateOutputRenderList`
359 // (viewport resize / fallback rebuild). RenderList::init() either
360 // calls GpuResourceRegistry::init() once (first RL on this output)
361 // or adopts the populated state as-is (every subsequent rebuild).
362 // RenderList::release() does NOT destroy it. OutputNode::releaseRegistry()
363 // tears it down via destroyOwned() when its QRhi goes away.
364 GpuResourceRegistry* m_registry{};
365
366 // Pool of tiny shared vertex buffers used to satisfy "REQUIRED: false"
367 // VERTEX_INPUTS whose upstream geometry is missing an attribute.
368 // Same lifetime as m_registry.
369 std::unique_ptr<VertexFallbackPool> m_vertexFallbackPool;
370
371 // GPU-timing collector. Lives as long as the RenderList — outlives
372 // individual renderers so per-pass measurements survive node churn.
373 GpuTimings m_gpuTimings;
374
375 // Session-wide asset decode cache. Non-owning; GfxContext is the
376 // owner. May be null.
377 Gfx::AssetTable* m_assetTable{};
378
379 // Material
380 QRhiBuffer* m_outputUBO{};
381 QRhiTexture* m_emptyTexture{};
382 QRhiTexture* m_emptyTexture3D{};
383 QRhiTexture* m_emptyTextureCube{};
384 QRhiTexture* m_emptyTextureArray{};
385
389 ossia::flat_map<Mesh*, MeshBuffers> m_vertexBuffers;
390
391 ossia::flat_map<ossia::geometry_spec, Mesh*> m_customMeshCache;
392
399 ossia::small_flat_map<const Port*, TextureRenderTarget, 8> m_inputRenderTargets;
400
404 QSize m_lastSize{};
405
406 int m_minTexSize{};
407 int m_maxTexSize{};
408 int m_samples{1};
409
410 bool m_requiresDepth{};
411 bool m_ready{};
412 bool m_built{};
413};
414
422SCORE_PLUGIN_GFX_EXPORT
423QRhiTexture::Format imageTextureFormat(const QRhi& rhi) noexcept;
424
431SCORE_PLUGIN_GFX_EXPORT
432QImage adaptImageFormat(QImage img, QRhiTexture::Format fmt);
433}
Cross-RenderList content-hash dedup for decoded asset bytes.
Definition AssetTable.hpp:71
Per-RenderList arena store for GPU-resident scene data.
Definition GpuResourceRegistry.hpp:44
Named-bucket GPU timing collector.
Definition GpuTiming.hpp:38
Root data model for visual nodes.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:74
Base class for sink nodes (QWindow, spout, syphon, NDI output, ...)
Definition OutputNode.hpp:54
List of nodes to be rendered to an output.
Definition RenderList.hpp:30
GpuResourceRegistry & registry() noexcept
Per-output GPU arena store for scene-graph source nodes.
Definition RenderList.hpp:235
void markBuilt() noexcept
Mark this render list as fully built.
Definition RenderList.hpp:303
VertexFallbackPool & vertexFallbackPool() noexcept
Per-RenderList pool of neutral fallback vertex buffers for "REQUIRED: false" VERTEX_INPUTS whose upst...
Definition RenderList.hpp:245
void setInitialBatch(QRhiResourceUpdateBatch *batch) noexcept
Store a resource update batch to be submitted on the next render frame.
Definition RenderList.hpp:58
bool isBuilt() const noexcept
Is this render list currently coherent with its output's GPU objects?
Definition RenderList.hpp:315
QRhiBuffer & outputUBO() const noexcept
UBO corresponding to the output parameters:
Definition RenderList.hpp:215
void markRequiresDepth(bool value) noexcept
Definition RenderList.hpp:321
QRhiTexture & emptyTexture3D() const noexcept
Texture to use when a 3D (sampler3D) texture is missing.
Definition RenderList.hpp:197
QRhiTexture & emptyTextureCube() const noexcept
Texture to use when a cubemap (samplerCube) is missing.
Definition RenderList.hpp:202
std::vector< score::gfx::NodeRenderer * > renderers
Renderers - one per node.
Definition RenderList.hpp:184
QRhiTexture & emptyTextureArray() const noexcept
Texture to use when a 2D array (sampler2DArray) is missing.
Definition RenderList.hpp:207
Gfx::AssetTable * assetTable() const noexcept
Session-wide asset decode cache.
Definition RenderList.hpp:264
QRhiCommandBuffer * currentCommandBuffer() const noexcept
Definition RenderList.hpp:92
std::vector< score::gfx::Node * > nodes
Nodes present in this RenderList, in order.
Definition RenderList.hpp:179
RenderState & state
RenderState corresponding to this RenderList.
Definition RenderList.hpp:169
QRhiTexture & emptyTexture() const noexcept
Texture to use when a texture is missing (2D)
Definition RenderList.hpp:192
OutputNode & output
Output node to which this RenderList is rendering to.
Definition RenderList.hpp:164
GpuTimings & gpuTimings() noexcept
Per-RenderList GPU-timing collector.
Definition RenderList.hpp:254
Definition VertexFallbackPool.hpp:43
Binds the rendering pipeline to ossia processes.
Definition AssetTable.cpp:7
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
QRhiTexture::Format imageTextureFormat(const QRhi &rhi) noexcept
Texture format to use for images uploaded from the CPU.
Definition RenderList.cpp:671
QImage adaptImageFormat(QImage img, QRhiTexture::Format fmt)
Put an image in the byte order imageTextureFormat() asks for.
Definition RenderList.cpp:677
Base toolkit upon which the software is built.
Definition Application.cpp:116
Definition Mesh.hpp:18
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:103
Represents a graph of renderers.
Definition score-plugin-gfx/Gfx/Graph/Graph.hpp:22
Definition Mesh.hpp:94
Data model for meshes.
Definition Mesh.hpp:179
UBO shared across all entities shown on the same output.
Definition CommonUBOs.hpp:82
Port of a score::gfx::Node.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:82
Global state associated to a rendering context.
Definition RenderState.hpp:37
Useful abstraction for storing all the data related to a render target.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:152