feat(gfx): colored-draw ops store packed ARGB; alpha blend deferred + guarded
0x202/0x203 pack (alpha,color) via GfxState.PackColor onto the object; the actual alpha/additive blend is deferred and surfaced once through the trace sink (observe- only, parity held). Full suite 37 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -52,4 +52,21 @@ public class GfxCommandBufferTests
|
||||
Assert.NotEqual(0, vm.Globals[10]); // not collapsed to slot 0
|
||||
Assert.NotEqual(vm.Globals[10], vm.Globals[11]); // distinct slots => no collapse
|
||||
}
|
||||
|
||||
private static (int, Operand[]) BlitColor(int h, int x, int y, int alpha, int color)
|
||||
=> (0x202, new[] { G(h), G(x), G(y), G(alpha), G(color) });
|
||||
|
||||
[Fact]
|
||||
public void BlitColorStoresPackedArgbOnTheObject()
|
||||
{
|
||||
var t = T();
|
||||
var scene = ScriptAssembler.Assemble(t, "GFX", new List<(int, Operand[])>
|
||||
{
|
||||
MovGI(1, 0x1000), MovGI(2, 0), MovGI(3, 0), MovGI(4, 0x80), MovGI(5, 0x112233),
|
||||
BlitColor(1, 2, 3, 4, 5), Exit(),
|
||||
}, System.Array.Empty<string>());
|
||||
var vm = new VirtualMachine(scene, t, new RecordingHost());
|
||||
vm.Run();
|
||||
Assert.Equal(0x80_112233L, vm.Gfx.TryGet(0x1000)!.Color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,10 +258,26 @@ public sealed class VirtualMachine
|
||||
Gfx.GetOrCreate(Read(a[0])); return pc + 1;
|
||||
case "gfx-elem-release": // 0x1fa (handle)
|
||||
Gfx.Release(Read(a[0])); return pc + 1;
|
||||
case "gfx-blit-color": // 0x202 (handle)(x)(y)(alpha)(color) — blend deferred
|
||||
Gfx.GetOrCreate(Read(a[0])).Color = GfxState.PackColor(Read(a[3]), Read(a[4]));
|
||||
WarnAlphaDeferredOnce(); return pc + 1;
|
||||
case "gfx-draw-color": // 0x203 (handle)(v)(alpha)(color) — blend deferred
|
||||
Gfx.GetOrCreate(Read(a[0])).Color = GfxState.PackColor(Read(a[2]), Read(a[3]));
|
||||
WarnAlphaDeferredOnce(); return pc + 1;
|
||||
default:
|
||||
// Stub is per-instruction frequency (the VM handles ~30 ops; the rest hit here, e.g.
|
||||
// 0x258/0x259 stmt markers appear en masse), so gate it with Step — else --trace floods.
|
||||
if (_sink.TracingSteps) _sink.Emit(TraceEvent.Stub(op, pc)); return pc + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Colored-draw ops (0x202/0x203) store the packed color on the object now; the actual alpha/additive
|
||||
// blend in the compositor is deferred. Surface it once (not silently) via the trace sink — observe-only,
|
||||
// so parity holds. See docs/superpowers/specs/2026-07-07-gfx-command-buffer-design.md (Deferrals).
|
||||
private bool _warnedAlpha;
|
||||
private void WarnAlphaDeferredOnce()
|
||||
{
|
||||
if (_warnedAlpha) return; _warnedAlpha = true;
|
||||
_sink.Emit(TraceEvent.Stub(0x202, -1));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user