mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 13:48:30 +09:00
[Test] (Pipe): pin the tracker's shutters and the CSO cache's content addressing, including the collision the memcmp exists to stop
- TrackerWalk drives the tracker and the cache DIRECTLY rather than through MGPipeValidateForVerb: the validate point reaches the library's one process-wide tracker, and a unit test that asserts on a shared singleton fails the moment ctest runs the suite in parallel. The three lines of emission logic it reproduces are the same three lines. - BlendToggleReusesTwoCsos is the Blaze3D shape the whole "push at validate, not in the setter" decision was made for: 32 enable/draw/disable/draw pairs mint exactly TWO CSOs, bind 64 times and hit 62. A per-setter design would show up here as 64 mints. - ViewportDoesNotMintACso is the regression RenderState.h records: 16 glViewports mint nothing, never move the pipeline version, and each sends exactly chunk D0 - not the other seven. - WrapAroundRePushesButNeverMisses drives m_version past 65535 and asserts every one of 70000 changes fired. The alternating value deliberately never touches the default: a setter that early-outs would otherwise make the first iteration a false miss and hide a real one. - AggregateGenerationCatchesABoundTextureMoving is the first test of the direction the P1 verify comparator cannot see - it compares object-class fields by identity only, so a bound texture whose content moved looks unchanged to it. The bit fires and then settles, so it is a shutter and not a stuck flag. - ANaNPatchLevelEqualsItselfAndDoesNotFireForever: a NaN outer level is a legal glPatchParameterfv value, float equality says it differs from itself and a byte compare says it does not. That is why the shutter is a memcmp. - ThePixelPackShutterIsAByteCompareOfThePackHalfOnly asserts an UNPACK write does not move the pack shutter, which is the half that deliberately has no carrier. - HashCollisionDoesNotAliasTwoStates needed a seam and got one: MGPipeCsoCache::s_hashForTest, null in every real build, one never-taken branch on a path that runs only when the pipeline version moved. Without it the memcmp confirm is unreachable code that nothing can prove is doing anything, and what it stops - two different render states on one CSO - is silent wrong pixels with no gate that can see it. - ContentAddressingOffMintsEveryTime pins that bit 63 really changes mint/reuse behaviour, so the negative control cannot rot into a dead switch. - The set-hash suppressor is exercised on all seven slots even though P2 wires one, including the reserved-zero contract: a computed hash of 0 is remapped to 1 so it is never confused with "never emitted".
This commit is contained in:
@@ -72,7 +72,8 @@ namespace MobileGL::MG_Pipe {
|
||||
const Bool contentAddressed =
|
||||
(MG_Config::Features.PipePush & kMGPipeBehaviourNoCsoContentAddressing) == 0;
|
||||
if (contentAddressed) {
|
||||
const Uint64 hash = MGPipeHashPipelineBytes(bytes.data());
|
||||
const Uint64 hash = s_hashForTest != nullptr ? s_hashForTest(bytes.data())
|
||||
: MGPipeHashPipelineBytes(bytes.data());
|
||||
for (SizeT i = 0; i < m_entries.size(); ++i) {
|
||||
if (m_entries[i].Hash != hash) continue;
|
||||
if (std::memcmp(m_entries[i].Bytes.data(), bytes.data(), bytes.size()) != 0) {
|
||||
@@ -110,6 +111,15 @@ namespace MobileGL::MG_Pipe {
|
||||
SizeT Size() const { return m_entries.size(); }
|
||||
const Counters& GetCounters() const { return m_counters; }
|
||||
|
||||
// TEST SEAM, and it is here because the thing it tests cannot be reached any other
|
||||
// way. A 64-bit collision between two DIFFERENT render states is silent wrong pixels
|
||||
// and it is exactly what the memcmp confirm above exists to stop, so
|
||||
// CsoCacheTest.HashCollisionDoesNotAliasTwoStates has to be able to make one happen.
|
||||
// Null in every real build - one never-taken, perfectly-predicted branch on a path
|
||||
// that runs only when the pipeline version moved, i.e. never in the steady state.
|
||||
using HashForTestFn = Uint64 (*)(const void* pipelineBytes);
|
||||
inline static HashForTestFn s_hashForTest = nullptr;
|
||||
|
||||
private:
|
||||
struct Entry {
|
||||
Uint64 Hash = 0;
|
||||
|
||||
Reference in New Issue
Block a user