#323

preserve: true on an MSAA offscreen target loads a discarded attachment (undefined contents, no error)

Openmatiasngfopened 3mo ago

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-MSAA guard 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

0

No activity yet.