Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
f7e4031
isf: TEX_DIMENSIONS_3D / IMG_SIZE_3D aliases for 3D samplers
jcelerier May 4, 2026
1a0ffc4
isf: point3d_input AS_COLOR flag for color-swatch display
jcelerier May 4, 2026
9d3d325
isf: parse-time warning on unknown csf_image_input FORMAT
jcelerier May 4, 2026
e8d272a
isf: parser rework — top-level descriptors, uniform inputs, geometry …
jcelerier May 4, 2026
41443fc
3rdparty: add OffsetAllocator submodule
jcelerier May 4, 2026
1944985
gfx: add AssetTable + TextureLoader for shared decoded-asset cache
jcelerier May 4, 2026
98bf94f
gfx: add GpuResourceRegistry — slab-allocated GPU arenas backed by Of…
jcelerier May 4, 2026
23d4276
gfx: add CameraMath / GpuTiming / VertexFallback helpers
jcelerier May 4, 2026
bd93207
gfx: add IsfBindingsBuilder + PipelineStateHelpers
jcelerier May 4, 2026
813dae8
gfx: add SceneGPUState — FlatScene + scene packer
jcelerier May 4, 2026
4745b5f
gfx: add OffscreenDevice + RhiPreviewWidget + Metal buffer-copy backend
jcelerier May 4, 2026
2ab12d5
gfx: extend ISF / SimpleRenderedISF nodes for new ISF features
jcelerier May 4, 2026
4920035
csf: rework for scene-aware compute pipeline
jcelerier May 4, 2026
ea8a9b6
gfx: rework raw raster pipeline (MRT, AUXILIARY, EXECUTION_MODEL) and…
jcelerier May 4, 2026
582a6c7
gfx: refresh shared graph plumbing for incremental scene pipeline
jcelerier May 4, 2026
7664b48
gfx: add ScenePreprocessorNode — scene_spec to flat draws + arena upl…
jcelerier May 4, 2026
30ce172
gfx: add SceneFilterNode + FlattenedSceneFilterNode + MergeGeometries…
jcelerier May 4, 2026
c4e2653
avnd: split CpuFilter / CpuAnalysis lifecycle into init / initState /…
jcelerier May 4, 2026
d703e1d
avnd: add scene_port concept
jcelerier May 4, 2026
5948674
avnd: split GpuNode lifecycle and add scene_port storage helpers
jcelerier May 4, 2026
15577f1
gfx: extend ShaderProgram for new ISF features
jcelerier May 4, 2026
2068312
gfx: refresh Filter / GeometryFilter / TexturePort for new pipeline
jcelerier May 4, 2026
52aa6e6
gfx: refresh WindowDevice / Spout / Syphon / WindowCapture
jcelerier May 4, 2026
ec41476
gfx: refresh GfxContext + window / screen / multiwindow nodes for inc…
jcelerier May 4, 2026
eb50d55
js: gpu node lifecycle rework with deterministic teardown
jcelerier May 4, 2026
6704d8a
wip: many bugfixes across the board
jcelerier May 14, 2026
fa22767
build: more build fixes
jcelerier May 14, 2026
9cd51e6
ci: fixes for older qt versions
jcelerier May 15, 2026
14b20a0
rhi: populate caps
jcelerier May 15, 2026
46d86b4
ci: try windows fixes
jcelerier May 16, 2026
31f1dfb
gfx: restore PhongNode, still used by score-vfx-template
claude Jun 11, 2026
01865a9
gfx: keep TextureRenderTarget compatible with addons' aggregate init
claude Jun 11, 2026
465b9ad
gfx: do not include mmsystem.h in CommonUBOs.hpp
claude Jun 11, 2026
376e12c
gfx: fix build with Qt < 6.9
claude Jun 11, 2026
a5c08b7
gfx: fix designator order after TextureRenderTarget reorder
claude Jun 11, 2026
0425c18
gfx: fix build with Qt 6.4
claude Jun 11, 2026
c0fc579
gfx: more Qt 6.4 compatibility guards
claude Jun 11, 2026
cf7bc19
gfx: QRhi render-graph core fixes (PR #2050 review)
jcelerier Jun 16, 2026
903695d
gfx: ISF/CSF shader port-routing + codegen coherence (PR #2050)
jcelerier Jun 16, 2026
2b47961
gfx: harden GfxContext incremental edge updates (PR #2050)
jcelerier Jun 16, 2026
9e9e003
gfx: scene-preprocessor / SceneGPUState correctness (PR #2050)
jcelerier Jun 16, 2026
487b4fb
gfx: shader preview manager UAF + port drift (PR #2050)
jcelerier Jun 16, 2026
2447c67
gfx: video output device fixes - GStreamer/Spout/Syphon (PR #2050)
jcelerier Jun 16, 2026
c39a015
avnd: Crousti GPU-node lifecycle, leaks and build fixes (PR #2050)
jcelerier Jun 16, 2026
d4b62fd
js: GPU node engine-keying, asserts and leaks (PR #2050)
jcelerier Jun 16, 2026
1e22f4c
threedim: adapt ModelDisplay to Pass::p.pipeline engine API
jcelerier Jun 17, 2026
81958a9
gfx: fix non-unity macOS + Windows/MSVC builds (PR #2077 CI)
jcelerier Jun 19, 2026
56461aa
ci: minor build fixes with Qt 6.12
jcelerier Jun 26, 2026
b940d06
avnd: remove duplicate include
jcelerier Jul 7, 2026
dbf0053
gfx: fix ambiguous QFlags cast for indirect buffer usage flags
jcelerier Jul 7, 2026
02ee1d0
gfx: keep Pass constructible from a bare Pipeline for addon compat
jcelerier Jul 7, 2026
980fc95
gfx: fix crash-grade issues from renderer review
jcelerier Jul 7, 2026
19e99fb
gfx: functional fixes from renderer review (P1 batch)
jcelerier Jul 7, 2026
a624c6c
gfx: shadow-cascade split contract + multi-layout sub-mesh guard
jcelerier Jul 7, 2026
0f82b3a
gfx: corrections from adversarial fix-verification round
jcelerier Jul 9, 2026
41f8d37
gfx: VSA cull-mode ordering + initPass leak fixes
jcelerier Jul 10, 2026
5b302f3
gfx: CSF once-per-frame guard, port/outlet drift, expr reserve, codeg…
jcelerier Jul 10, 2026
743708d
gfx: RawRaster per-invocation SRB staleness, depth-only render area, …
jcelerier Jul 10, 2026
aef5459
gfx/media: video frame-queue TOCTOU, HW-transfer format-change leak, …
jcelerier Jul 10, 2026
b828d90
gfx: bind fragment storage buffers in the MRT ISF pipeline SRB
jcelerier Jul 10, 2026
bd6d34c
gfx: render the color output of a multipass ISF that has a storage bu…
jcelerier Jul 10, 2026
8a2398c
gfx: map MRT color outputs past interleaved non-image output ports
jcelerier Jul 10, 2026
142be66
gfx: draw VSA triangles with CullMode::None on every backend
jcelerier Jul 10, 2026
54a5bd1
gfx: fix stale VkRenderPass use-after-free on offscreen-sink resize
jcelerier Jul 10, 2026
305d1b8
gfx: fix all-black 3D storage-image compute output on OpenGL
jcelerier Jul 10, 2026
8ab01f3
gfx: fix three ISF graphics-storage binding bugs
jcelerier Jul 10, 2026
de81090
gfx: clear stale dynamic texture slots to prevent UAF in SRB binding
jcelerier Jul 10, 2026
3155a7f
gfx: rebuild an intermediate node's own output passes on rt_changed
jcelerier Jul 10, 2026
87ce959
gfx: don't permanently drop incremental edges to a not-yet-added node
jcelerier Jul 10, 2026
48a9a1a
gfx: release transitively-unreachable renderers on node removal
jcelerier Jul 10, 2026
824a08d
gfx: extend GL layered-storage-image compute workaround to cube/array
jcelerier Jul 10, 2026
0efeab4
gfx: clamp GPU buffer scatter dispatch to backend max workgroups
jcelerier Jul 10, 2026
c2c4242
gfx: fix use-after-free on HWTransferDecoder mid-stream sw-format change
jcelerier Jul 10, 2026
2570359
gfx: don't let a GStreamer bus WARNING truncate the recording
jcelerier Jul 10, 2026
a7464ff
gfx: make staged-but-never-acquired AssetTable entries evictable
jcelerier Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,6 @@
[submodule "3rdparty/opengametools"]
path = 3rdparty/opengametools
url = https://github.com/jpaver/opengametools
[submodule "3rdparty/OffsetAllocator"]
path = 3rdparty/OffsetAllocator
url = https://github.com/sebbbi/OffsetAllocator
1 change: 1 addition & 0 deletions 3rdparty/OffsetAllocator
Submodule OffsetAllocator added at 3610a7
21 changes: 18 additions & 3 deletions src/plugins/score-lib-process/Process/Drop/ProcessDropHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <ossia/detail/algorithms.hpp>

#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QSet>
Expand All @@ -19,8 +20,22 @@ void ProcessDropHandler::getCustomDrops(
std::vector<ProcessDropHandler::ProcessDrop>& drops, const QMimeData& mime,
const score::DocumentContext& ctx) const noexcept
{
// Check for special mime handling code
return dropCustom(drops, mime, ctx);
// dropCustom is no longer noexcept (some overrides invoke parsers that
// can throw on malformed input — see ProcessDropHandler.hpp). Catch
// here so a throwing handler never escapes through the noexcept
// public API and tears down the editor.
try
{
dropCustom(drops, mime, ctx);
}
catch(const std::exception& e)
{
qWarning() << "ProcessDropHandler::dropCustom threw:" << e.what();
}
catch(...)
{
qWarning() << "ProcessDropHandler::dropCustom threw an unknown exception";
}
}

void ProcessDropHandler::getMimeDrops(
Expand Down Expand Up @@ -61,7 +76,7 @@ QSet<QString> ProcessDropHandler::fileExtensions() const noexcept

void ProcessDropHandler::dropCustom(
std::vector<ProcessDropHandler::ProcessDrop>&, const QMimeData& data,
const score::DocumentContext& ctx) const noexcept
const score::DocumentContext& ctx) const
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class SCORE_LIB_PROCESS_EXPORT ProcessDropHandler : public score::InterfaceBase
protected:
virtual void dropCustom(
std::vector<ProcessDrop>& drops, const QMimeData& mime,
const score::DocumentContext& ctx) const noexcept;
const score::DocumentContext& ctx) const;

virtual void dropPath(
std::vector<ProcessDrop>& drops, const score::FilePath& path,
Expand Down
30 changes: 29 additions & 1 deletion src/plugins/score-plugin-avnd/Crousti/Concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,35 @@ make_control_in(avnd::field_index<N>, Id<Process::Port>&& id, QObject* parent)
auto [Mx, My, Mz] = c.max;
auto [ix, iy, iz] = c.init;
return new Process::XYZSpinboxes{{mx, my, mz}, {Mx, My, Mz}, {ix, iy, iz},
qname, id, parent};
false, qname, id, parent};
}
}
else if constexpr(widg.widget == avnd::widget_type::xyzw_spinbox)
{
static constexpr auto c = avnd::get_range<T>();
if constexpr(requires {
c.min == 0.f;
c.max == 0.f;
c.init == 0.f;
})
{
return new Process::XYZSpinboxes{
{c.min, c.min, c.min},
{c.max, c.max, c.max},
{c.init, c.init, c.init},
false,
qname,
id,
parent};
}
else
{
auto [mx, my, mz, mw] = c.min;
auto [Mx, My, Mz, Mw] = c.max;
auto [ix, iy, iz, iw] = c.init;
// FIXME we don't have a good 4-way widget
return new Process::XYZSpinboxes{{mx, my, mz}, {Mx, My, Mz}, {ix, iy, iz},
false, qname, id, parent};
}
}
else if constexpr(widg.widget == avnd::widget_type::color)
Expand Down
83 changes: 73 additions & 10 deletions src/plugins/score-plugin-avnd/Crousti/CpuAnalysisNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

namespace oscr
{

template <typename Node_T>
requires(
(avnd::texture_output_introspection<Node_T>::size + avnd::buffer_output_introspection<Node_T>::size + avnd::geometry_output_introspection<Node_T>::size) == 0
(avnd::texture_output_introspection<Node_T>::size + avnd::buffer_output_introspection<Node_T>::size + avnd::geometry_output_introspection<Node_T>::size + scene_output_introspection<Node_T>::size) == 0
&& (avnd::gpu_render_target_output_port_output_introspection<Node_T>::size == 0)
)
struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
{
Expand All @@ -19,6 +19,7 @@ struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
AVND_NO_UNIQUE_ADDRESS texture_inputs_storage<Node_T> texture_ins;
AVND_NO_UNIQUE_ADDRESS buffer_inputs_storage<Node_T> buffer_ins;
AVND_NO_UNIQUE_ADDRESS geometry_inputs_storage<Node_T> geometry_ins;
AVND_NO_UNIQUE_ADDRESS scene_inputs_storage<Node_T> scene_ins;

const GfxNode<Node_T>& node() const noexcept
{
Expand All @@ -44,9 +45,19 @@ struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
return {};
}

void init(score::gfx::RenderList& renderer, QRhiResourceUpdateBatch& res) override
// See CpuFilterNode.hpp for the reasoning: init must live in initState
// so the incremental edge-rewire path also runs it.
void initState(score::gfx::RenderList& renderer, QRhiResourceUpdateBatch& res) override
{
auto& parent = node();
if(m_initialized)
return;

// See CpuFilterNode for the reasoning: optional renderlist
// backchannel populated via SFINAE so nodes can reach the
// RenderList's GpuResourceRegistry / AssetTable without plumbing.
if constexpr(requires { state->renderlist = &renderer; })
state->renderlist = &renderer;

if constexpr(requires { state->prepare(); })
{
this->node().processControlIn(
Expand All @@ -59,6 +70,13 @@ struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
texture_ins.init(*this, renderer);

if_possible(state->init(renderer, res));

m_initialized = true;
}

void init(score::gfx::RenderList& renderer, QRhiResourceUpdateBatch& res) override
{
initState(renderer, res);
}

void update(
Expand All @@ -82,32 +100,69 @@ struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
}
}

void release(score::gfx::RenderList& r) override
void releaseState(score::gfx::RenderList& r) override
{
if(!m_initialized)
return;

if constexpr(avnd::texture_input_introspection<Node_T>::size > 0)
texture_ins.release();

if constexpr(avnd::geometry_input_introspection<Node_T>::size > 0)
geometry_ins.release(r);

if constexpr(scene_input_introspection<Node_T>::size > 0)
scene_ins.release(r);

if constexpr(
avnd::texture_input_introspection<Node_T>::size > 0
|| avnd::texture_output_introspection<Node_T>::size > 0)
{
// FIXME this->defaultRelease(r);
// No call-through to GenericNodeRenderer::defaultRelease here:
// CpuAnalysisNode's GfxRenderer derives from OutputNodeRenderer,
// not GenericNodeRenderer, and OutputNodeRenderer has no
// defaultRelease equivalent (it owns no pipeline / passes — it
// is a sink, not a node renderer with m_p / m_pipelineCache).
// CpuFilterNode's mirror at line ~357 IS valid because that
// GfxRenderer derives from GenericNodeRenderer.
//
// If a future CpuAnalysisNode uses textures via OutputNodeRenderer
// surfaces, they'll need their own per-storage release path
// (texture_ins.release above already handles texture INPUTS).
}

if_possible(state->release(r));

// Clear the optional renderlist backchannel. Paired with initState;
// same SFINAE guard.
if constexpr(requires { state->renderlist = nullptr; })
state->renderlist = nullptr;

m_initialized = false;
}

void release(score::gfx::RenderList& r) override
{
releaseState(r);
}

void inputAboutToFinish(
score::gfx::RenderList& renderer, const score::gfx::Port& p,
QRhiResourceUpdateBatch*& res) override
{
// Outer guard includes scene_input_introspection so a node with ONLY
// scene inputs (no texture / buffer / geometry) still allocates `res`
// — necessary if scene_inputs_storage ever grows an inputAboutToFinish
// method (today it's read-only via readInputScenes, but the storage's
// lifecycle is part of the new scene_port concept and may evolve).
// Without the include, a scene-only sink would silently skip the
// res allocation and any future scene-side write would have nowhere
// to land.
if constexpr(
avnd::texture_input_introspection<Node_T>::size > 0
|| avnd::buffer_input_introspection<Node_T>::size > 0
|| avnd::geometry_input_introspection<Node_T>::size > 0)
|| avnd::geometry_input_introspection<Node_T>::size > 0
|| scene_input_introspection<Node_T>::size > 0)
{
res = renderer.state.rhi->nextResourceUpdateBatch();

Expand All @@ -118,6 +173,8 @@ struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
if constexpr(avnd::geometry_input_introspection<Node_T>::size > 0)
geometry_ins.inputAboutToFinish(
renderer, res, this->geometry, *state, this->node());
// No scene_ins.inputAboutToFinish today — the guard is forward-
// looking; add the call here when scene_inputs_storage grows one.
}

if_possible(state->inputAboutToFinish(renderer, p, res));
Expand All @@ -144,6 +201,8 @@ struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
buffer_ins.readInputBuffers(renderer, parent, *state);
if constexpr(avnd::geometry_input_introspection<Node_T>::size > 0)
geometry_ins.readInputGeometries(renderer, this->geometry, parent, *state);
if constexpr(scene_input_introspection<Node_T>::size > 0)
scene_ins.readInputScenes(this->scene, *state);

parent.processControlIn(
*this, *state, m_last_message, parent.last_message, parent.m_ctx);
Expand All @@ -158,9 +217,13 @@ struct GfxRenderer<Node_T> final : score::gfx::OutputNodeRenderer
};

template <typename Node_T>
requires(
(avnd::texture_output_introspection<Node_T>::size + avnd::buffer_output_introspection<Node_T>::size + avnd::geometry_output_introspection<Node_T>::size) == 0
)
requires((avnd::texture_output_introspection<Node_T>::size
+ avnd::buffer_output_introspection<Node_T>::size
+ avnd::geometry_output_introspection<Node_T>::size
+ scene_output_introspection<Node_T>::size)
== 0
&& (avnd::gpu_render_target_output_port_output_introspection<Node_T>::size
== 0))
struct GfxNode<Node_T> final
: CustomGpuOutputNodeBase
, GpuNodeElements<Node_T>
Expand Down
Loading
Loading