You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixed
- DispatchUserD3D11Compute early-returned when isCompiled() was false,
but for D3D11 compute the bytecode is only populated inside that
function. Chicken-and-egg meant Channel / Luminance / Chromaticity
Statistics never compiled or dispatched. Removed the early-out.
- D3D11ComputeRunner::CompileShader threw away the bytecode blob after
creating the shader object; now caches it and exposes it via
GetCompiledBytecode() so the host can persist it on the def for
cbuffer reflection.
- cbuffer pack code wrote raw float bit patterns into uint/int/bool
slots. Now reflects each variable's D3D_SHADER_VARIABLE_TYPE and
converts before memcpy, so if (Units == 1) works as written.
- Analysis-only compute nodes froze their output fields after frame 1
because their own properties never change. Added topological dirty
propagation pre-pass in both Evaluate and RenderFrame so video-frame
updates flow through analysis nodes the same frame they're decoded.
- Effect Designer LoadDefinition didn't restore the Output Type
selector or the typed analysis-field rows. Refactored the field-row
builder into a reusable helper and taught LoadDefinition to use it.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,15 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
5
5
6
6
## [Unreleased]
7
7
8
+
## [1.3.9] - 2026-05-05
9
+
10
+
### Fixed
11
+
-**D3D11 compute effects (Channel / Luminance / Chromaticity Statistics) never compiled or dispatched.**`DispatchUserD3D11Compute` started with `if (!node.customEffect->isCompiled()) return;` — but `isCompiled()` checks `compiledBytecode.empty()`, and for D3D11 compute the bytecode is only ever populated *inside* this function via the lazy `runner->CompileShader` path. Chicken-and-egg: every call early-returned, no bytecode was ever stored, the shader never ran, and analysis-output fields stayed empty forever. Removed the early-out for that case so the runner can compile on first dispatch and persist the bytecode back to `def.compiledBytecode` for the cbuffer reflection pass.
12
+
-**`D3D11ComputeRunner::CompileShader` discarded the compiled bytecode blob** after creating the `ID3D11ComputeShader` object, leaving `def.compiledBytecode` empty for D3D11 compute effects forever. Cached the blob in `m_bytecode` and exposed it via `GetCompiledBytecode()`; `DispatchUserD3D11Compute` now copies it onto `node.customEffect->compiledBytecode` after a successful compile so the cbuffer-reflection pass that packs user properties has something to reflect against.
13
+
-**D3D11 compute cbuffers received raw float bit patterns where shaders declared `uint`/`int`/`bool`.** The Properties panel stores enum-style fields (e.g. `Units`, `ClipSource`) as `float`, but the HLSL declares `cbuffer { uint Units; ... }`. Doing `memcpy(dest, &floatVal, 4)` writes `0x3F800000` (1,065,353,216) into the uint slot, so `if (Units == 1)` was never true and conditional code paths were dead. The pack code now reflects each variable's `D3D_SHADER_VARIABLE_TYPE` and converts via `static_cast<uint32_t>` / `static_cast<int32_t>` based on the declared HLSL type before writing.
14
+
-**Analysis-only compute nodes froze their output fields after the first frame.**`needsCompute` was only true on `node->dirty || fields.empty()`, and a Statistics node's own properties don't change frame-to-frame even as the upstream video does. Added a topological dirty-propagation pre-pass at the start of `Evaluate`: any node that's dirty marks all its direct downstream consumers dirty before the eval loop runs. Same pass is also done in `RenderFrame` after `TickAndUploadVideos`, so video-frame updates correctly flow through pixel-shader chains *and* analysis-only compute nodes in the same frame they're decoded. Both passes are idempotent — no-op when nothing is dirty.
15
+
-**Effect Designer "Output type" + analysis fields were blank when opening a built-in ShaderLab effect** (or any saved custom effect with typed analysis output). `LoadDefinition` populated inputs / parameters / thread-groups but never restored the `OutputTypeSelector` selection or the analysis-field rows, so opening *Channel Statistics* showed no record of its declared `Min` / `Max` / `Mean` / etc. Refactored the per-row construction in the Add-Field click handler into a reusable `AppendAnalysisFieldRow()` method, then taught `LoadDefinition` to map `def.analysisOutputType` → selector index and rebuild one row per `def.analysisFields` entry with name / type / array length restored.
0 commit comments