mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[MG_IntegrationTest, scripts] (P7): a server-side magma test knob is registered on split and spawn only, and the parity gate names the five entries tcp cannot carry
ID-P7-31 review, should-fix 1. Every MGITEST_MAGMA_FORCE_* knob is read BY THE SERVER (the getenv readers in WireFramebuffer.inc run on the apply thread), and a ctest ENVIRONMENT property only reaches the process ctest starts - the client. Inproc runs the server in that process and ServerSpawn.cpp copies ::environ into the spawned child, so both arms see the knob; the tcp arm's server is the lane-wide TcpServer.Start fixture, started once from scripts/ci/tcp_server_fixture.py's own os.environ, and nothing a per-case property says reaches it. The tcp copy of each knob=1 entry ran the DEFAULT arm under a name claiming otherwise. Measured, not deduced: a temporary fatal in each of the three readers killed all five knob=1 entries on split and on spawn and left all five green on tcp. So ShaderMip1, ShaderMip2, DepthMip, DefaultBlitShape1 and MsResolve1 are registered on split+spawn only (the first four are package B's pre-existing vacuity of the same shape). The knob=0 twins DefaultBlitShape0 / MsResolve0 keep their tcp entries: zero is the default and means the same thing on every arm. spawn_lane_parity.py names the exception, following ID-P7-14's MAGMA_INPROC_ONLY: MAGMA_SERVER_ENV_KNOB_NO_TCP, applied through a new compare_arms(no_tcp=) that drops the keys from the tcp comparison ONLY - folding them into inproc_only would stop requiring them on spawn, which is where they do most of their work.
This commit is contained in:
@@ -3005,7 +3005,43 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
# the shared Fm environment would silently retarget GenerateMipmapPixels,
|
||||
# GenerateMipmapPackedFloatPixels, GenerateMipmapDepthPixels and the two base/view cases
|
||||
# as well - four green entries that would stop measuring the arm they were written for.
|
||||
# ---- P7 wave 2-B2: A SERVER-SIDE KNOB HAS NO TCP ARM, AND THAT IS STRUCTURAL ---------
|
||||
#
|
||||
# Every MGITEST_MAGMA_FORCE_* knob in this block is read BY THE SERVER
|
||||
# (WireFramebuffer.inc's three `std::getenv` readers run on the apply thread). A ctest
|
||||
# ENVIRONMENT property reaches the process ctest starts - the CLIENT - and the two arms
|
||||
# differ in where the server comes from:
|
||||
# inproc the server is a thread of that same process, so it sees the knob;
|
||||
# spawn ServerSpawn.cpp copies ::environ into the child, so it sees the knob;
|
||||
# tcp the server is the LANE-WIDE TcpServer.Start fixture, started once from the
|
||||
# fixture's own os.environ (scripts/ci/tcp_server_fixture.py) long before any
|
||||
# case runs, and it forks a session child per Hello. Nothing a per-test
|
||||
# ENVIRONMENT says can reach it.
|
||||
#
|
||||
# So a tcp copy of a knob entry does not exercise the arm it names - it runs the
|
||||
# DEFAULT arm under a name that claims otherwise, which for ShaderMip is precisely what
|
||||
# that case's own skip message says must not happen ("this case would assert the native
|
||||
# blit twice over"). MEASURED, not deduced: a temporary fatal in each of the three
|
||||
# readers killed all five knob=1 entries on split and on spawn and left ALL FIVE GREEN
|
||||
# on tcp.
|
||||
#
|
||||
# Registering them on split+spawn only is therefore a coverage statement, not a gap, and
|
||||
# it is NAMED in scripts/ci/spawn_lane_parity.py (MAGMA_SERVER_ENV_KNOB_NO_TCP) the way
|
||||
# MAGMA_INPROC_ONLY and MONOLITH_ONLY are, so the parity gate keeps its teeth for
|
||||
# everything else. The knob=0 twins (DefaultBlitShape0, MsResolve0) DO stay on tcp: zero
|
||||
# is the default, so those entries mean the same thing on all three arms.
|
||||
#
|
||||
# Making the tcp lane able to carry these would need the fixture to take a per-case
|
||||
# server environment - a supervisor control, not a ctest property - and that is a debt,
|
||||
# recorded in notes/p7/magma-b2.md §6.
|
||||
set(mglItestServerEnvKnobArm TRUE)
|
||||
if(mglItestArm STREQUAL "Tcp")
|
||||
set(mglItestServerEnvKnobArm FALSE)
|
||||
endif()
|
||||
foreach(shaderMipTier 1 2)
|
||||
if(NOT mglItestServerEnvKnobArm)
|
||||
continue()
|
||||
endif()
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.${mglItestArm}.ShaderMip${shaderMipTier}."
|
||||
TEST_FILTER "F1WireScenario.GenerateMipmapWithoutNativeBlitPixels"
|
||||
@@ -3017,7 +3053,9 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
# The DEPTH half of the same knob (CONTRACT-P7 §5.1 (A)). ONE TIER, not two: the depth
|
||||
# pass renders into a depth ATTACHMENT view of the destination level, which a depth
|
||||
# image always has usage for - there is no "cannot be attached" shape to force, so
|
||||
# tier 2 would register a second copy of tier 1's run.
|
||||
# tier 2 would register a second copy of tier 1's run. Split+spawn only, for the
|
||||
# server-side-knob reason above.
|
||||
if(mglItestServerEnvKnobArm)
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.${mglItestArm}.DepthMip."
|
||||
TEST_FILTER "F1WireScenario.GenerateMipmapDepthWithoutNativeBlitPixels"
|
||||
@@ -3025,6 +3063,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
PROPERTIES LABELS "${mglItestMagmaLabels}" TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
${mglItestArmProperties}
|
||||
ENVIRONMENT "${mglItestMagmaWireEnvironment}\;MGITEST_MAGMA_FORCE_SHADER_MIPMAP=1\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/p7-depthmip${mglItestArmLogTag}.log")
|
||||
endif()
|
||||
# NO KNOB on the decline: it is decided on the aspect before the blit-support question
|
||||
# is asked, so the plain Fm environment reaches it on every driver.
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
@@ -3098,7 +3137,12 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
# VK_SURFACE_TRANSFORM_IDENTITY, so the scratch path that exists FOR rotation would
|
||||
# never run. Forced onto an identity surface it must produce the SAME pixels as the
|
||||
# fall-through, which is what the shared assertions check.
|
||||
# The knob=1 copy is split+spawn only (the server-side-knob note above); knob=0 is the
|
||||
# default and means the same thing on all three arms, so it keeps its tcp entry.
|
||||
foreach(defaultBlitScratch 0 1)
|
||||
if(defaultBlitScratch AND NOT mglItestServerEnvKnobArm)
|
||||
continue()
|
||||
endif()
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.${mglItestArm}.DefaultBlitShape${defaultBlitScratch}."
|
||||
TEST_FILTER "F1WireScenario.ColorBlitToDefaultFromANonSampleableSourceDegrades"
|
||||
@@ -3149,6 +3193,11 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
# ITS OWN ENTRIES RATHER THAN A LANE-WIDE FLIP, the shader-mip block's reason: the knob
|
||||
# changes how EVERY depth/stencil resolve in the process is performed.
|
||||
foreach(shaderDepthResolve 0 1)
|
||||
# Same split+spawn restriction, same reason, same parity exception: the knob is read
|
||||
# on the server and the tcp server is the lane fixture. MsResolve0 stays everywhere.
|
||||
if(shaderDepthResolve AND NOT mglItestServerEnvKnobArm)
|
||||
continue()
|
||||
endif()
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.${mglItestArm}.MsResolve${shaderDepthResolve}."
|
||||
TEST_FILTER "DepthStencilReadbackMatrixScenario.AResolvedMultisampleDepthReadsBackFromTheDestination"
|
||||
|
||||
@@ -57,6 +57,24 @@ FIXTURE_ENTRIES = {"TcpServer.Start", "TcpServer.Stop"}
|
||||
# until they do, naming the two scenarios here keeps the tolerance from widening for anything else.
|
||||
MAGMA_INPROC_ONLY = ("MagmaRunAheadScenario.", "MagmaWireCacheScenario.")
|
||||
|
||||
# P7 wave 2-B2: THE SANCTIONED ASYMMETRY THAT IS NOT INPROC-ONLY - these exist on split AND
|
||||
# spawn and cannot exist on tcp. Every MGITEST_MAGMA_FORCE_* knob is read BY THE SERVER
|
||||
# (WireFramebuffer.inc's getenv readers run on the apply thread), and a ctest ENVIRONMENT
|
||||
# property only reaches the process ctest starts, the CLIENT. Under inproc the server is a
|
||||
# thread of that process and under spawn ServerSpawn.cpp copies ::environ into the child, so
|
||||
# both see it; under tcp the server is the LANE-WIDE TcpServer.Start fixture, started once from
|
||||
# the fixture's own os.environ before any case runs, so nothing a per-test property says can
|
||||
# reach it. A tcp copy would run the DEFAULT arm under a name claiming otherwise.
|
||||
#
|
||||
# MEASURED (a temporary fatal in each of the three readers): all five knob=1 entries died on
|
||||
# split and on spawn and ALL FIVE PASSED on tcp.
|
||||
#
|
||||
# These are TAILS, not scenarios - the normaliser above keeps the sub-lane tail for the Magma
|
||||
# tier on purpose, so `.MsResolve1.` names the knob entry and `.MsResolve0.` (the default, which
|
||||
# does keep its tcp entry) is untouched.
|
||||
MAGMA_SERVER_ENV_KNOB_NO_TCP = (".ShaderMip1.", ".ShaderMip2.", ".DepthMip.",
|
||||
".DefaultBlitShape1.", ".MsResolve1.")
|
||||
|
||||
|
||||
def lane_names(build_dir, label):
|
||||
"""Every ctest entry name under an ANCHORED label (`ctest -L` is a regex, not a name)."""
|
||||
@@ -75,9 +93,15 @@ def lane_cases(build_dir, label):
|
||||
return {m.group(1) for m in CASE.finditer(out)}
|
||||
|
||||
|
||||
def compare_arms(build_dir, tier, labels, inproc_only=()):
|
||||
def compare_arms(build_dir, tier, labels, inproc_only=(), no_tcp=()):
|
||||
"""The three arms of one tier must name the same set after the arm segment comes off.
|
||||
|
||||
`inproc_only` drops a key from the comparison for EVERY non-split arm; `no_tcp` drops it for
|
||||
the tcp arm alone, which is a different shape and needs to be: a server-side test knob does
|
||||
reach a spawned server and does not reach the tcp lane's shared fixture, so the entry is
|
||||
required on spawn and forbidden on tcp. Folding it into `inproc_only` would stop requiring
|
||||
it on spawn, which is where it does most of its work.
|
||||
|
||||
Returns True on failure, the way main() below counts them."""
|
||||
sets = {}
|
||||
for arm, label in labels.items():
|
||||
@@ -100,10 +124,19 @@ def compare_arms(build_dir, tier, labels, inproc_only=()):
|
||||
if len(comparable) != len(sets[reference]):
|
||||
print(f"{tier}: {len(sets[reference]) - len(comparable)} inproc-only entrie(s) excluded "
|
||||
f"from the comparison by name ({', '.join(inproc_only)})")
|
||||
if no_tcp:
|
||||
dropped = {k for k in comparable if any(only in k for only in no_tcp)}
|
||||
if dropped:
|
||||
print(f"{tier}: {len(dropped)} server-env-knob entrie(s) excluded from the TCP "
|
||||
f"comparison only ({', '.join(no_tcp)}) - the knob is read on the server and "
|
||||
f"the tcp server is the lane fixture, not a per-case process")
|
||||
for arm, keys in sets.items():
|
||||
if arm == reference:
|
||||
continue
|
||||
missing, extra = sorted(comparable - keys), sorted(keys - comparable)
|
||||
expected = comparable
|
||||
if arm == "tcp" and no_tcp:
|
||||
expected = {k for k in comparable if not any(only in k for only in no_tcp)}
|
||||
missing, extra = sorted(expected - keys), sorted(keys - expected)
|
||||
if missing or extra:
|
||||
print(f"::error::{tier}: the {arm} arm does not match the {reference} arm: "
|
||||
f"missing={missing}, extra={extra}. Every arm of a tier is emitted from one "
|
||||
@@ -163,11 +196,15 @@ def main():
|
||||
# every arm - it is a whole-binary filter, and there they simply SKIP for want of their
|
||||
# lane marker - so excluding them there would turn a present-on-all-arms case into a
|
||||
# spurious "extra".
|
||||
# The server-env knob entries are gated-tier only for the same per-tier reason: the
|
||||
# full-suite census is a whole-binary filter with no knob in its environment at all, so
|
||||
# there is nothing there to exclude.
|
||||
failed |= compare_arms(args.build_dir, "magma gated tier",
|
||||
{"split": "integration-magma-split",
|
||||
"spawn": "integration-magma-spawn",
|
||||
"tcp": "integration-magma-tcp"},
|
||||
inproc_only=MAGMA_INPROC_ONLY)
|
||||
inproc_only=MAGMA_INPROC_ONLY,
|
||||
no_tcp=MAGMA_SERVER_ENV_KNOB_NO_TCP)
|
||||
failed |= compare_arms(args.build_dir, "magma informational tier",
|
||||
{"split": "integration-magma-all-split",
|
||||
"spawn": "integration-magma-all-spawn",
|
||||
|
||||
Reference in New Issue
Block a user