[MG_Backend] (P7): a transient ring past 4 GiB declines its uniform binding instead of killing the session

`uniform-buffer-dynamic-offset@P7` becomes a decline (rule I (a)). A Vulkan
dynamic offset is a uint32_t, so a transient uniform ring that grew past 4 GiB
inside one frame has nowhere to put the padded block - which is our ring's
problem, not a protocol fault, and nothing the peer could have sent differently.
Killing the session for it was the wrong shape twice over.

The monolith arm has the same ceiling and truncates silently on the way out
(ResolveDynamicUboDescriptor's static_cast<Uint32>), i.e. it binds a WRONG window
rather than none. Declining is the strictly better observable of the two: one
binding is skipped, the draw is lost, the session keeps running, and the next
frame's rewound ring resolves it.

red-once (R-16). The site is not reachable from a test - a 4 GiB transient arena
inside one frame is not something an integration case can build - so the red is
the same case with the ceiling condition forced true, both shapes built and run
back to back on the Split and Spawn arms:

  before (fb25ed6b + forced condition)
    DirectVulkan.Split.Buffers.F1WireScenario.ShortUniformBufferRangePadsMissingBytes
    DirectVulkan.Spawn.Buffers.F1WireScenario.ShortUniformBufferRangePadsMissingBytes
        Subprocess aborted - MGPipe: Fatal{UnmigratedVerb, "Magma:uniform-buffer-dynamic-offset@P7"}

  after (this commit + forced condition)
    both ***Failed on the pixel, NO Fatal and NO abort, and the role log carries
    ResolveWireUniformBufferPayload: the transient uniform ring reached offset 0,
    past the 4 GiB a Vulkan dynamic offset can name; uniform binding point 3 is
    declined for this draw

  restored (this commit as committed): both green, no force markers left.

Lanes: integration-magma-split 74/74, -spawn 53/53, integration-magma-buffers
20/20. -tcp not read this round: port 40613 is held by a concurrently running
lane in another worktree, which is a fixture collision and not a result.
This commit is contained in:
2026-09-22 16:22:40 -04:00
parent 450d30759e
commit 362b27df8c
@@ -2415,8 +2415,21 @@ namespace MobileGL::MG_Backend::DirectVulkan {
m_wireFrameIndex, padded, 0)))
return false;
}
if (padded.offset > std::numeric_limits<Uint32>::max())
WireDescriptorFatal("uniform-buffer-dynamic-offset@P7");
if (padded.offset > std::numeric_limits<Uint32>::max()) {
// P7 A.2, a decline (rule I (a)), not a session death. A Vulkan dynamic offset is a
// uint32_t, so a transient uniform ring that grew past 4 GiB inside one frame has
// nowhere to put this block - which is our ring's problem, not a protocol fault, and
// nothing the peer could have sent differently. One binding is skipped and the draw
// is lost; the session keeps running and the next frame's rewound ring resolves it.
// The monolith arm has the same ceiling and truncates silently on the way out
// (ResolveDynamicUboDescriptor's static_cast<Uint32>), i.e. it binds a WRONG window
// rather than none, so declining is the strictly better observable of the two.
MGLOG_E_ONCE("ResolveWireUniformBufferPayload: the transient uniform ring reached offset "
"%llu, past the 4 GiB a Vulkan dynamic offset can name; uniform binding "
"point %u is declined for this draw",
static_cast<unsigned long long>(padded.offset), bindingPoint);
return false;
}
out.directBindable = true;
out.buffer = padded.buffer;
out.range = blockSize;