#323
preserve: true on an MSAA offscreen target loads a discarded attachment (undefined contents, no error)
Summary
preserve: true on a pass over an MSAA offscreen target loads an attachment whose previous storeOp was "discard" — the loaded contents are undefined. No error, no warning: silent corruption of the "preserved" contents.
Found during the #320 vNext design review (lifecycle adjudication, finding V9), verified against release/v0.3.0 at packages/vgpu-api/src/target-utils.ts:69-72.
Repro sketch
const t = target(gpu, { size: [512, 512], msaa: true });
frameLoop(gpu, (f) => {
f.pass({ target: t, preserve: true }, (p) => { /* draws */ });
});
// preserve: true requests loadOp "load" — keep previous contents.
// But the internal multisample attachment was stored with storeOp "discard"
// on the previous frame (target-utils.ts:69-72), so the "preserved" contents
// are undefined. Platform-dependent garbage, typically silently wrong.Notes
- The existing
VGPU-PASS-PRESERVE-MSAAguard does not cover this path (that is what makes the bug latent). Whether the fix is extending that validation to this case, or changing the internal storeOp when a target is preserve-eligible, is an implementation decision — either way the current silent behavior is wrong. - Independent of #320: this is 0.3.0 behavior today. The vNext design prevents the class going forward (its transient/discard predicate structurally excludes preservable attachments), but the current behavior needs a fix regardless.
- Full analysis with verification details: lifecycle adjudication (sandbox:
~/.agents/2359bf9d-143e-4ce6-9c7f-1257165c7187/adj-lifecycle.md, finding V9 + verification table).
Activity
0No activity yet.