diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fab1844d..748eb39d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2007,6 +2007,8 @@ jobs: "F1WireScenario.EnabledVertexBufferDrawKeepsNamedP7Fatal", "F1WireScenario.UniformBufferRangeAndRebindPixels", "F1WireScenario.ShortUniformBufferRangePadsMissingBytes", + "F1WireScenario.SubWordUniformBufferRangePadsMissingBytes", + "F1WireScenario.UnalignedAtomicCounterRangeDeclinesAndTheSessionLives", "F1WireScenario.ComputeWrittenVertexAndIndexBuffersDrawAndReadBack", "F1WireScenario.ColorBlitToDefaultIgnoresViewportAndPreservesOrientation", "F1WireScenario.ColorBlitToDefaultHonorsScissorAndReversedRect", @@ -2028,10 +2030,11 @@ jobs: ["DirectVulkan.Split.Buffers." + name for name in cases]) PY - # P7 package L: THE SAME NINETEEN, BY NAME, IN TWO PROCESSES. + # P7 package L: THE SAME TWENTY-ONE, BY NAME, IN TWO PROCESSES (nineteen at package L; the + # sub-word uniform range and the unaligned atomic-counter decline joined later). # # `--no-tests=error` in the lane step above answers "did something run and pass"; it does - # not answer "did these nineteen run". require_green does, and it is the check that would + # not answer "did these twenty-one run". require_green does, and it is the check that would # catch the failure mode this package could plausibly introduce - an arm that registers # SOME of the lane and goes green on a smaller set. The label spelling is what keeps the # three arms apart under `ctest -L`'s regex: the inproc arm keeps the historical @@ -2041,7 +2044,7 @@ jobs: # TcpServer.Start / TcpServer.Stop ARE IN THE tcp ARM'S REQUIRED LIST ON PURPOSE. Every # tcp entry declares FIXTURES_REQUIRED mobilegl-tcp, so ctest lists the supervisor's two # fixture entries under the label as well - and they must be green too: a lane whose - # supervisor failed to start has nothing to say about the nineteen. + # supervisor failed to start has nothing to say about the twenty-one. - name: Magma application-buffer wire cases must all execute on the spawn and tcp arms working-directory: build-split env: @@ -2066,6 +2069,8 @@ jobs: "F1WireScenario.EnabledVertexBufferDrawKeepsNamedP7Fatal", "F1WireScenario.UniformBufferRangeAndRebindPixels", "F1WireScenario.ShortUniformBufferRangePadsMissingBytes", + "F1WireScenario.SubWordUniformBufferRangePadsMissingBytes", + "F1WireScenario.UnalignedAtomicCounterRangeDeclinesAndTheSessionLives", "F1WireScenario.ComputeWrittenVertexAndIndexBuffersDrawAndReadBack", "F1WireScenario.ColorBlitToDefaultIgnoresViewportAndPreservesOrientation", "F1WireScenario.ColorBlitToDefaultHonorsScissorAndReversedRect", diff --git a/MobileGL/MG_IntegrationTest/CMakeLists.txt b/MobileGL/MG_IntegrationTest/CMakeLists.txt index 445a9421..541ccc50 100644 --- a/MobileGL/MG_IntegrationTest/CMakeLists.txt +++ b/MobileGL/MG_IntegrationTest/CMakeLists.txt @@ -2198,7 +2198,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED) # historical name (`integration-magma-buffers`); on the others the ARM comes first # (`integration-magma-spawn-buffers`). `ctest -L` is a regex, so the obvious # `integration-magma-buffers-spawn` would be SELECTED by the CI step that runs - # `-L integration-magma-buffers` and require_greens its nineteen inproc entries by name - + # `-L integration-magma-buffers` and require_greens its twenty-one inproc entries by name - # the lane would red on "required green entries differ" the day this package landed. macro(mgl_itest_magma_arm_shape mglItestArm) string(TOLOWER "${mglItestArm}" mglItestArmLower) diff --git a/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py b/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py index 2fb17fe4..628f4032 100644 --- a/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py +++ b/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py @@ -153,7 +153,7 @@ def print_marker_table(title, table): print(f" {len(table[pair]):4d} {pair}") -# These six skips predate P5f closure. Match both the exact entry and its reason; +# The first six skips predate P5f closure. Match both the exact entry and its reason; # losing a GPU/preflight, a required lane marker, or either RSP probe is never allowed. DUALBLOCK_ALLOWED_SKIPS = { "DirectGLES.Split.TriangleScenario.TheServerStampedAVerbBoundaryOnThisDrawingFrame": "not the strict-arming lane:", @@ -162,6 +162,22 @@ DUALBLOCK_ALLOWED_SKIPS = { "DirectGLES.Split.SmallRing.PersistentCoherentMapScenario.TheMapLandsInTheArmItsLaneDeclares": "not the counting lane: MGITEST_PMAP_LANE", "DirectVulkan.Split.Fm.ClipDistanceScenario.ADisabledClipDistanceRemovesNothing": "clips by a DISABLED gl_ClipDistance", "DirectVulkan.Split.Fm.ClipDistanceScenario.TheEnablesAreIndependentPerDistance": "clips by every declared gl_ClipDistance regardless of the enables", + # P7 D1/B2 and the twelve-scenario census put these on the split arms; each skips by its own + # named reason (the spawn and tcp arms skip the same set). Backend-structural on DirectGLES: + "DirectGLES.Split.Xfb.XfbRepeatedCaptureScenario.AVertexOnlyAdjacencyCaptureRecords": + "DirectGLES cannot forward a geometry-shader-less adjacency draw", + "DirectGLES.Split.ForcedDs.DepthStencilReadbackMatrixScenario.AFlippedMultisampleResolveMirrorsTheBandsAndAScaleDeclines": + "does not produce this picture yet: a flipped multisample depth resolve writes nothing", + "DirectGLES.Split.Glsl420DeclarationScenario.AnArrayOfSamplerArraysIsHonouredOrDeclinedCleanly": + "the frontend's binding-qualifier seeding does not walk an array of arrays", + # ...and driver capabilities llvmpipe does not have (the runner and the host both skip them). + "DirectGLES.Split.ForcedDs.DepthStencilReadbackMatrixScenario.SeparateDepthAndStencilAttachmentsAreBothReadable": + "this driver cannot host separate DEPTH_COMPONENT24 and STENCIL_INDEX8 attachments", + "DirectGLES.Split.ImageTargetKindScenario.LoadsTexture2DMultisample": "GL_MAX_IMAGE_SAMPLES is 0", + "DirectGLES.Split.ImageTargetKindScenario.LoadsTexture2DMultisampleArray": "GL_MAX_IMAGE_SAMPLES is 0", + "DirectGLES.Split.ImageTargetKindScenario.StoresTexture2DMultisample": "GL_MAX_IMAGE_SAMPLES is 0", + "DirectGLES.Split.ImageTargetKindScenario.StoresTexture2DMultisampleArray": "GL_MAX_IMAGE_SAMPLES is 0", + "DirectGLES.Split.ImageTargetKindScenario.IgnoresLayerForTexture2DMultisample": "GL_MAX_IMAGE_SAMPLES is 0", } diff --git a/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py b/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py index 80e7a092..50737372 100644 --- a/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py +++ b/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py @@ -87,15 +87,41 @@ class ResultAccountingTest(unittest.TestCase): self.census() def test_known_skip_requires_its_exact_reason(self): - name, reason = next(iter(helper.DUALBLOCK_ALLOWED_SKIPS.items())) - self.document = self.discovery([name]) - self.results([(name, "notrun", "skipped")]) - with self.assertRaisesRegex(ValueError, "unexpected skip"): - self.census() - tree = ET.parse(self.xml) - ET.SubElement(tree.getroot().find("testcase"), "system-out").text = reason - tree.write(self.xml) - self.census() + for name, reason in helper.DUALBLOCK_ALLOWED_SKIPS.items(): + with self.subTest(name=name): + self.assertTrue(reason.strip(), "an allowed skip needs a non-empty reason") + self.document = self.discovery([name]) + self.results([(name, "notrun", "skipped")]) + with self.assertRaisesRegex(ValueError, "unexpected skip"): + self.census() + tree = ET.parse(self.xml) + ET.SubElement(tree.getroot().find("testcase"), "system-out").text = reason + tree.write(self.xml) + self.census() + + def test_an_allowed_entry_skipping_for_another_reason_is_refused(self): + # The Glsl420 row names the DECLINE; a program that stopped building skips too, with a + # different sentence, and must not ride the same row. The accepted half is asserted + # FIRST: without it this case would pass on a helper that does not list the entry at all + # (CI's dual-block census went red on exactly that, run 35785685692 onward). + name = "DirectGLES.Split.Glsl420DeclarationScenario.AnArrayOfSamplerArraysIsHonouredOrDeclinedCleanly" + self.assertIn(name, helper.DUALBLOCK_ALLOWED_SKIPS) + for reason, accepted in [ + ("the frontend's binding-qualifier seeding does not walk an array of arrays, so " + "DirectGLES samples unit 0 for every element; the locations asserted above are " + "the half of this case it can answer", True), + ("the frontend does not build an array of sampler arrays: link error", False)]: + with self.subTest(accepted=accepted): + self.document = self.discovery([name]) + self.results([(name, "notrun", "skipped")]) + tree = ET.parse(self.xml) + ET.SubElement(tree.getroot().find("testcase"), "system-out").text = "Skipped\n" + reason + tree.write(self.xml) + if accepted: + self.census() + else: + with self.assertRaisesRegex(ValueError, "unexpected skip"): + self.census() def test_admitted_or_fatal_on_passed_case_is_not_hidden(self): for marker in ['Admitted{UnmigratedPipeInput, "GetProgramObject@Clear"}',