From ffc4fb7d779ce7e557c99c798fcc2136343ee2a3 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 22 Sep 2026 22:06:35 -0400 Subject: [PATCH] [MG_Impl, MG_IntegrationTest, ci] (P7): the first perturbation block's falsifier is the DirectVulkan entry - measured with one block removed at a time: without the re-applied block both server halves drop to 1 (DirectGLES 1 / DirectVulkan 1, both entries red); without the first block DirectVulkan drops to 1 (red) while DirectGLES stays at 2 (green), because the GLES backend reads the pack field twice after the neutral pack is installed (3 = the saved-pack read + 2 post-install) and DirectVulkan once (2 = 1 + 1) - so the >= 2 requirement falsifies the re-applied block on both backends and the first block on DirectVulkan; the CI step runs both backends and needs both, which it already does - the scenario, hook and CI comments now say exactly that, instead of "removing either block drops it to 1" --- .github/workflows/test.yml | 7 +++++-- MobileGL/MG_Impl/Pipe/PipeFill.cpp | 7 +++++-- .../Scenarios/PipeVerifyArmingScenario.cpp | 6 +++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5d38f32e..fab1844d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1099,8 +1099,11 @@ jobs: # installs the neutral one, the backend's ReadPixels reads it after - and the hook perturbs # its oracle once per read, because the ID-49 overwrite inside the window wipes the first # perturbation before the second read's compare. A step satisfied by ONE line was satisfied - # by either perturbation alone and falsified neither; two is one per read, each falsified on - # its own. Measured at landing: 3 (DirectGLES) / 2 (DirectVulkan). + # by either perturbation alone and falsified neither. Measured at landing: 3 (DirectGLES, + # whose backend reads the field twice after the install) / 2 (DirectVulkan); without the + # re-applied perturbation both drop to 1, without the first one DirectVulkan drops to 1 + # while DirectGLES stays at 2 - so BOTH backends are required, and the first perturbation's + # falsifier is the DirectVulkan entry. # # THE GREEN HALF is the lane run above: the same hook, the same window, with no corruption # armed, across 1070 entries at zero divergences. diff --git a/MobileGL/MG_Impl/Pipe/PipeFill.cpp b/MobileGL/MG_Impl/Pipe/PipeFill.cpp index 6a588fca..5c5d0db3 100644 --- a/MobileGL/MG_Impl/Pipe/PipeFill.cpp +++ b/MobileGL/MG_Impl/Pipe/PipeFill.cpp @@ -779,8 +779,11 @@ namespace MobileGL::MG_Pipe { // GetPixelStoreParameters cannot turn red - and a control that accepted ONE report // would never notice, because the saved-pack read still reports through the block // above. The VerifySplitReadCorrupted. entries and the CI step therefore require at - // least TWO `where=read` reports in the server half: one per block, each falsified - // alone (V1 fix round 2). + // least TWO `where=read` reports in the server half (V1 fix round 2). Measured: 3 on + // DirectGLES (its backend reads the field twice after the install) / 2 on + // DirectVulkan; without this block both drop to 1, without the block above + // DirectVulkan drops to 1 while DirectGLES's two post-install reports keep it at 2 - + // so this block is falsified on both backends and the one above on DirectVulkan. if (g_verify.Corrupt && *g_verify.Corrupt == field) { MGPipeApplyVerifyCorruption(g_readScratch, field); } diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp index 95b8c0e0..b9b89b9a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp @@ -380,7 +380,11 @@ void main() { o_color = vec4(0.25, 0.5, 0.75, 1.0); } // after the window's overwrite can turn the post-install read red, because there the // stored value IS the neutral pack. A control satisfied by ONE line is satisfied by // either block alone and so falsified neither. Measured at landing the server half - // carries 3 (DirectGLES) / 2 (DirectVulkan); removing either block drops it to 1. + // carries 3 (DirectGLES: the saved-pack read and TWO post-install reads) / 2 + // (DirectVulkan: one of each). Removing the re-applied block drops both backends to + // 1; removing the first block drops DirectVulkan to 1 and leaves DirectGLES at 2, so + // the first block's falsifier is the DirectVulkan entry - which is why the CI step + // runs both backends and needs both. const std::size_t reads = CountReadReports(server, expected); EXPECT_GE(reads, std::size_t{2}) << "the server half carries " << reads << " `where=read` report(s) for " << expected