mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Test] (P11 A1/A2): LargeArenaAdoptionScenario asserts the tier its arena landed in and reads the tcp AdoptTier0 refusal; registered on Split/Spawn/Tcp for both backends (Espryt through the split-arms macro, Magma's Arena. block and Buffers lane), the monolith lanes declare adopted
This commit is contained in:
@@ -2042,6 +2042,13 @@ jobs:
|
||||
"PersistentCoherentMapScenario.TwoWritesThroughTheCoherentPointerEachReachTheirOwnDraw",
|
||||
"PersistentCoherentMapScenario.AWriteAfterAFrameBoundaryReachesTheNextFramesDraw",
|
||||
"StorageBufferRegrowScenario.AGrownStoreIsVisibleThroughItsExistingIndexedBinding",
|
||||
# P11 A2: the >= 16 MiB arena and its tier assertion (emulated).
|
||||
"LargeArenaAdoptionScenario.SubDataAfterAnInFlightDrawReachesTheNextDraw",
|
||||
"LargeArenaAdoptionScenario.RespecifiedVertexArenaKeepsVaoBindings",
|
||||
"LargeArenaAdoptionScenario.RespecifiedIndexArenaKeepsVaoBinding",
|
||||
"LargeArenaAdoptionScenario.ReadbackSeesTheLatestCpuWrite",
|
||||
"LargeArenaAdoptionScenario.GpuWriteIntoTheArenaIsReadBack",
|
||||
"LargeArenaAdoptionScenario.TheArenaLandsInTheTierItsLaneDeclares",
|
||||
]
|
||||
slp.require_green(json.load(open(sys.argv[2])), sys.argv[3],
|
||||
["DirectVulkan.Split.Buffers." + name for name in cases])
|
||||
@@ -2104,6 +2111,12 @@ jobs:
|
||||
"PersistentCoherentMapScenario.TwoWritesThroughTheCoherentPointerEachReachTheirOwnDraw",
|
||||
"PersistentCoherentMapScenario.AWriteAfterAFrameBoundaryReachesTheNextFramesDraw",
|
||||
"StorageBufferRegrowScenario.AGrownStoreIsVisibleThroughItsExistingIndexedBinding",
|
||||
"LargeArenaAdoptionScenario.SubDataAfterAnInFlightDrawReachesTheNextDraw",
|
||||
"LargeArenaAdoptionScenario.RespecifiedVertexArenaKeepsVaoBindings",
|
||||
"LargeArenaAdoptionScenario.RespecifiedIndexArenaKeepsVaoBinding",
|
||||
"LargeArenaAdoptionScenario.ReadbackSeesTheLatestCpuWrite",
|
||||
"LargeArenaAdoptionScenario.GpuWriteIntoTheArenaIsReadBack",
|
||||
"LargeArenaAdoptionScenario.TheArenaLandsInTheTierItsLaneDeclares",
|
||||
]
|
||||
required = [sys.argv[4] + name for name in cases]
|
||||
if sys.argv[5] == "tcp":
|
||||
|
||||
@@ -1495,14 +1495,25 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
# No log path: none of these three cases reads one, and giving them one would only add a file for
|
||||
# four processes to truncate. The fourth case skips in both lanes for exactly that reason, saying
|
||||
# so.
|
||||
#
|
||||
# P11 A2: both lanes pin monolith, so both DECLARE the adopted arm (MGITEST_PERSISTENT_MAP_ARM) and
|
||||
# LargeArenaAdoptionScenario.TheArenaLandsInTheTierItsLaneDeclares asserts the 24 MiB arena really
|
||||
# adopted on the handle arm (Ops_H_MapPersistentTracked) and on the legacy one. Red once with
|
||||
# MOBILEGL_DISABLE_LARGE_BUFFER_ADOPTION=1 in the job environment (CONTRACT-P11 §2).
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_ARENA_SUBSYSTEM_ON_ENVIRONMENT
|
||||
"MOBILEGL_TRANSPORT=monolith"
|
||||
"MOBILEGL_TRANSPORT=monolith" "MGITEST_PERSISTENT_MAP_ARM=adopted"
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MOBILEGL_PIPE_PUSH=0x1fff"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_ARENA_SUBSYSTEM_OFF_ENVIRONMENT
|
||||
"MOBILEGL_TRANSPORT=monolith"
|
||||
"MOBILEGL_TRANSPORT=monolith" "MGITEST_PERSISTENT_MAP_ARM=adopted"
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MOBILEGL_PIPE_PUSH=0x7f"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
# ... and Magma's monolith half: the legacy AcquirePersistentMap (the wire resource table is
|
||||
# registered only off monolith, VkBufferManager.cpp RegisterWireResourceOps).
|
||||
mgl_itest_join_environment(MGL_ITEST_VULKAN_ARENA_ARM_ENVIRONMENT
|
||||
"MOBILEGL_TRANSPORT=monolith" "MGITEST_PERSISTENT_MAP_ARM=adopted"
|
||||
"MOBILEGL_BACKEND_TYPE=DirectVulkan" "MOBILEGL_ITEST_REQUIRE_GPU=1"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_VULKAN_ENV})
|
||||
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectGLES.ResourceSubsystemOn."
|
||||
@@ -1522,6 +1533,15 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
ENVIRONMENT "${MGL_ITEST_GLES_ARENA_SUBSYSTEM_OFF_ENVIRONMENT}"
|
||||
)
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.ArenaArm."
|
||||
TEST_FILTER "LargeArenaAdoptionScenario.TheArenaLandsInTheTierItsLaneDeclares"
|
||||
DISCOVERY_TIMEOUT 30
|
||||
PROPERTIES
|
||||
LABELS "integration-gpu\;integration-monolith-control"
|
||||
TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
ENVIRONMENT "${MGL_ITEST_VULKAN_ARENA_ARM_ENVIRONMENT}"
|
||||
)
|
||||
|
||||
# --- G12: the P4a subsystem A/B, and its dependency refusal ---------------------------
|
||||
#
|
||||
@@ -2407,6 +2427,30 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
mgl_itest_register_split_arms("ClearThenReadPixelsScenario.*" "")
|
||||
mgl_itest_register_split_arms("TriangleScenario.*" "")
|
||||
mgl_itest_register_split_arms("PersistentCoherentMapScenario.*" "")
|
||||
# P11 A2 (MG_Remote/CONTRACT-P11.md §2): the >= 16 MiB arena on all three arms. Its tier case
|
||||
# is declared emulated per entry by SplitLogPaths (T2: every acquisition declines); the mpr and
|
||||
# adopt-tier-refusal cases skip here for want of their lane markers. The Magma arms are the
|
||||
# gated `Arena.` block beside `Pbo.` / `Fence.` below, plus the Buffers lane.
|
||||
mgl_itest_register_split_arms("LargeArenaAdoptionScenario.*" "")
|
||||
# P11 A1 (CONTRACT-P11 §1): the tcp arm with MOBILEGL_IPC_ADOPT_TIER=0. A stream refuses the
|
||||
# tier by name at the client's handshake and runs T2, so the whole scenario is green here and
|
||||
# AStreamSessionRefusesTheAdoptTierOnceByName reads exactly one refusal line. TCP ONLY by
|
||||
# construction: over shared segments (split, spawn) the same knob dies at the handshake, which
|
||||
# is the unit gate RemoteClientControls.AdoptTier*OverSharedSegments*. The `.AdoptTier0.` tail is
|
||||
# what keeps these names out of spawn_lane_parity.py's case set (see MAGMA_TCP_ONLY there).
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectGLES.Tcp.AdoptTier0."
|
||||
TEST_LIST "MGL_SPLIT_ARM_TESTS_${MGL_SPLIT_ARM_INDEX}"
|
||||
TEST_FILTER "LargeArenaAdoptionScenario.*"
|
||||
DISCOVERY_TIMEOUT 30
|
||||
PROPERTIES
|
||||
LABELS "integration-gpu\;integration-tcp"
|
||||
TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
ENVIRONMENT "${MGL_ITEST_GLES_TCP_ENVIRONMENT}\;MOBILEGL_IPC_ADOPT_TIER=0\;MGITEST_ADOPT_TIER_REFUSAL=T0"
|
||||
FIXTURES_REQUIRED mobilegl-tcp RESOURCE_LOCK mobilegl-tcp
|
||||
)
|
||||
list(APPEND MGL_SPLIT_ARM_TEST_LISTS "MGL_SPLIT_ARM_TESTS_${MGL_SPLIT_ARM_INDEX}")
|
||||
math(EXPR MGL_SPLIT_ARM_INDEX "${MGL_SPLIT_ARM_INDEX} + 1")
|
||||
|
||||
# ---- P3b/P4b espryt D1 slice 1: THE ORPHANED XFB CAPTURE TARGET -------------------------
|
||||
#
|
||||
@@ -3697,6 +3741,16 @@ endif()
|
||||
# Fatal{ReplyTooLarge, "ReadPixels 256x512 0x1908/0x1406 2097152 > 2097136"}. One entry per case
|
||||
# for a private log each - two processes append to it on the spawn arm.
|
||||
if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
# P11: LargeArenaAdoptionScenario's cases that run on every Magma arm - the five behavioural
|
||||
# cases and the tier assertion (the mpr and adopt-tier-refusal cases need lane markers of their
|
||||
# own). The `Arena.` block below and the Buffers lane both walk it.
|
||||
set(MGL_ITEST_ARENA_CASES
|
||||
SubDataAfterAnInFlightDrawReachesTheNextDraw
|
||||
RespecifiedVertexArenaKeepsVaoBindings
|
||||
RespecifiedIndexArenaKeepsVaoBinding
|
||||
ReadbackSeesTheLatestCpuWrite
|
||||
GpuWriteIntoTheArenaIsReadBack
|
||||
TheArenaLandsInTheTierItsLaneDeclares)
|
||||
set(MGL_ITEST_MAGMA_BAND_FLAVOUR_ENV
|
||||
"MOBILEGL_BACKEND_TYPE=DirectVulkan"
|
||||
"MOBILEGL_IPC_ROLE_SPLIT_STATE=1" "MOBILEGL_IPC_STRICT_ERRORS=1" "MOBILEGL_IPC_RUN_AHEAD=1"
|
||||
@@ -3753,6 +3807,34 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
${mglItestArmProperties}
|
||||
ENVIRONMENT "${mglItestMagmaBandEnvironment}\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/p10-fence${mglItestArmLogTag}-${fenceCase}.log")
|
||||
endforeach()
|
||||
# P11 A2 (MG_Remote/CONTRACT-P11.md §2): the >= 16 MiB arena on Magma's three arms, in the
|
||||
# same flavour. Declared emulated: every split acquisition declines (the wire resource
|
||||
# table's MapPersistent returns null, VkBufferManager.cpp), so the tier case asserts T2
|
||||
# on every arm; DirectVulkan.ArenaArm. is its monolith (adopted) half.
|
||||
foreach(arenaCase IN LISTS MGL_ITEST_ARENA_CASES)
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.${mglItestArm}.Arena."
|
||||
TEST_FILTER "LargeArenaAdoptionScenario.${arenaCase}"
|
||||
DISCOVERY_TIMEOUT 30
|
||||
PROPERTIES LABELS "${mglItestMagmaLabels}" TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
${mglItestArmProperties}
|
||||
ENVIRONMENT "${mglItestMagmaBandEnvironment}\;MGITEST_PERSISTENT_MAP_ARM=emulated\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/p11-arena${mglItestArmLogTag}-${arenaCase}.log")
|
||||
endforeach()
|
||||
# P11 A1 (CONTRACT-P11 §1): the tcp arm with MOBILEGL_IPC_ADOPT_TIER=0 - refused by name at
|
||||
# the client's handshake, T2, the scenario green. TCP ONLY by construction (over shared
|
||||
# segments the knob dies at the handshake); spawn_lane_parity.py names the tail in
|
||||
# MAGMA_TCP_ONLY.
|
||||
if(mglItestArm STREQUAL "Tcp")
|
||||
foreach(arenaCase IN LISTS MGL_ITEST_ARENA_CASES ITEMS AStreamSessionRefusesTheAdoptTierOnceByName)
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.Tcp.AdoptTier0."
|
||||
TEST_FILTER "LargeArenaAdoptionScenario.${arenaCase}"
|
||||
DISCOVERY_TIMEOUT 30
|
||||
PROPERTIES LABELS "${mglItestMagmaLabels}" TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
${mglItestArmProperties}
|
||||
ENVIRONMENT "${mglItestMagmaBandEnvironment}\;MOBILEGL_IPC_ADOPT_TIER=0\;MGITEST_ADOPT_TIER_REFUSAL=T0\;MGITEST_PERSISTENT_MAP_ARM=emulated\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/p11-adopt-tier0-tcp-${arenaCase}.log")
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -3915,7 +3997,15 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
CrossFrameBufferScenario.IndexOrphanAndReupload
|
||||
PersistentCoherentMapScenario.TwoWritesThroughTheCoherentPointerEachReachTheirOwnDraw
|
||||
PersistentCoherentMapScenario.AWriteAfterAFrameBoundaryReachesTheNextFramesDraw
|
||||
StorageBufferRegrowScenario.AGrownStoreIsVisibleThroughItsExistingIndexedBinding)
|
||||
StorageBufferRegrowScenario.AGrownStoreIsVisibleThroughItsExistingIndexedBinding
|
||||
# P11 A2: the >= 16 MiB arena, the flavour's MGITEST_PERSISTENT_MAP_ARM=emulated
|
||||
# asserted by its tier case (MG_Remote/CONTRACT-P11.md §2).
|
||||
LargeArenaAdoptionScenario.SubDataAfterAnInFlightDrawReachesTheNextDraw
|
||||
LargeArenaAdoptionScenario.RespecifiedVertexArenaKeepsVaoBindings
|
||||
LargeArenaAdoptionScenario.RespecifiedIndexArenaKeepsVaoBinding
|
||||
LargeArenaAdoptionScenario.ReadbackSeesTheLatestCpuWrite
|
||||
LargeArenaAdoptionScenario.GpuWriteIntoTheArenaIsReadBack
|
||||
LargeArenaAdoptionScenario.TheArenaLandsInTheTierItsLaneDeclares)
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.${mglItestArm}.Buffers."
|
||||
TEST_FILTER "${bufferCase}"
|
||||
|
||||
@@ -25,6 +25,9 @@ foreach(listName IN ITEMS @MGL_SPLIT_ARM_TEST_LISTS@)
|
||||
elseif(entry MATCHES "PersistentCoherentMapScenario.TheMapLandsInTheArmItsLaneDeclares$")
|
||||
set_tests_properties("${entry}" PROPERTIES ENVIRONMENT
|
||||
"MGITEST_PMAP_LANE=1;MGITEST_PERSISTENT_MAP_ARM=emulated;MOBILEGL_PIPE_STATS=1;MOBILEGL_PIPE_STATS_PERIOD=1")
|
||||
elseif(entry MATCHES "LargeArenaAdoptionScenario.TheArenaLandsInTheTierItsLaneDeclares$")
|
||||
# P11 A2: every split arm runs T2, so the arena is declared emulated.
|
||||
set_tests_properties("${entry}" PROPERTIES ENVIRONMENT "MGITEST_PERSISTENT_MAP_ARM=emulated")
|
||||
elseif(entry MATCHES "CtWireScenario\\.")
|
||||
set_tests_properties("${entry}" PROPERTIES ENVIRONMENT "MOBILEGL_TEST_SERVER_COUNTERS=1")
|
||||
endif()
|
||||
|
||||
@@ -49,8 +49,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../Harness/HeadlessGL.h"
|
||||
#include "../Harness/PersistentMapPeek.h"
|
||||
#include "../Harness/PipeStatsWindow.h"
|
||||
#include "../Harness/ScenarioFixture.h"
|
||||
#include "../Harness/SplitLane.h"
|
||||
|
||||
#ifdef GLAPI
|
||||
#undef GLAPI
|
||||
@@ -94,6 +96,9 @@ void main() { word = 0xC0FFEEu; }
|
||||
// Set by the MapPersistentRoundtrips. ctest entry and by nothing else; a harness marker,
|
||||
// never read by the library.
|
||||
constexpr const char* kLaneMarker = "MGITEST_MPR_LANE";
|
||||
// P11 A1: set (to the tier the lane names, "T0") only by the `.AdoptTier0.` tcp entries,
|
||||
// which also set MOBILEGL_IPC_ADOPT_TIER=0; a harness marker, never read by the library.
|
||||
constexpr const char* kAdoptTierRefusalMarker = "MGITEST_ADOPT_TIER_REFUSAL";
|
||||
// Draws issued against the arena inside the counted window. One definition, many draws:
|
||||
// "one per definition" (1) and "one per draw" (kDrawsInTheWindow) have to be different
|
||||
// numbers or the assertion cannot tell them apart.
|
||||
@@ -260,6 +265,27 @@ void main() { word = 0xC0FFEEu; }
|
||||
return px;
|
||||
}
|
||||
|
||||
// P11 A2: the arena's tier as the frontend object records it, against the lane's
|
||||
// declaration. Adopted = the resource owner minted a persistent coherent mapping and
|
||||
// the CPU shadow was released; emulated = the owner declined (T2) and the shadow is
|
||||
// the truth. Pixels cannot tell them apart - every case above is green on both.
|
||||
void ExpectDeclaredArm(const std::string& declared, const char* when) {
|
||||
bool adopted = false;
|
||||
ASSERT_TRUE(PeekBufferIsAdoptedPersistentMap(m_arena, &adopted))
|
||||
<< "no frontend BufferObject behind the arena " << when;
|
||||
const std::string landed = adopted ? "adopted" : "emulated";
|
||||
RecordProperty(std::string("arena_arm_") + (m_armPeeks++ == 0 ? "defined" : "used"),
|
||||
landed.c_str());
|
||||
EXPECT_EQ(declared, landed)
|
||||
<< "the lane declared the " << declared << " arm and the " << (kArenaBytes >> 20)
|
||||
<< " MiB arena is " << landed << " " << when
|
||||
<< ". Monolith lanes adopt on both backends (Espryt's handle arm mints through "
|
||||
"Ops_H_MapPersistentTracked, Magma's legacy AcquirePersistentMap); split lanes "
|
||||
"run T2, where every acquisition declines.";
|
||||
}
|
||||
|
||||
int m_armPeeks = 0;
|
||||
|
||||
unsigned int m_program = 0;
|
||||
unsigned int m_compute = 0;
|
||||
unsigned int m_vao = 0;
|
||||
@@ -505,4 +531,92 @@ void main() { word = 0xC0FFEEu; }
|
||||
<< window.line;
|
||||
}
|
||||
|
||||
// P11 A2 (MG_Remote/CONTRACT-P11.md §2): WHICH TIER THE ARENA REALLY LANDED IN. The cases above
|
||||
// are green whether the arena adopted or stayed emulated, so the lane declares the arm
|
||||
// (MGITEST_PERSISTENT_MAP_ARM) and this case asserts it, the way
|
||||
// PersistentCoherentMapScenario.TheMapLandsInTheArmItsLaneDeclares does for a sub-16-MiB map.
|
||||
// Asked twice: after the NULL-data definition (TryAdoptLargeStorage's door) and after a frame
|
||||
// of use that ends in an SSBO binding and a dispatch (the storage-binding door,
|
||||
// EnsureGpuResidentStorage, which Magma's server walk opens). Lanes that declare nothing - the
|
||||
// ambient entries, which run under whatever transport the job exports - skip.
|
||||
TEST_F(LargeArenaAdoptionScenario, TheArenaLandsInTheTierItsLaneDeclares) {
|
||||
if (!Ready() || IsSkipped()) return;
|
||||
const std::string declared = SplitLane::DeclaredPersistentMapArm();
|
||||
if (declared.empty()) {
|
||||
GTEST_SKIP() << "this lane declares no arm: MGITEST_PERSISTENT_MAP_ARM is set only by the "
|
||||
"lanes that pin their transport (monolith: adopted; the split arms: "
|
||||
"emulated)";
|
||||
}
|
||||
if (!PersistentMapPeekAvailable()) {
|
||||
GTEST_SKIP() << "this lane declares the " << declared << " arm but Harness/PersistentMapPeek "
|
||||
"cannot look in this build (on Android this module links the shipping "
|
||||
"library, built -fvisibility=hidden). 'Could not look' is not 'it was "
|
||||
<< declared << "'.";
|
||||
}
|
||||
ExpectDeclaredArm(declared, "right after its NULL-data definition");
|
||||
if (HasFatalFailure()) return;
|
||||
|
||||
UploadQuad(1.f, 0.f, 0.f);
|
||||
DrawQuad();
|
||||
EXPECT_GT(CenterPixel()[0], 200) << "the draw from the arena never landed";
|
||||
Gl().EndFrame();
|
||||
|
||||
GLint maxComputeStorageBlocks = 0;
|
||||
glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &maxComputeStorageBlocks);
|
||||
if (maxComputeStorageBlocks >= 1) {
|
||||
const GLuint compute = CompileStage(GL_COMPUTE_SHADER, kMarkerComputeSource);
|
||||
ASSERT_NE(compute, 0u) << m_buildLog;
|
||||
m_compute = glCreateProgram();
|
||||
glAttachShader(m_compute, compute);
|
||||
glLinkProgram(m_compute);
|
||||
glDeleteShader(compute);
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_arena, 0, sizeof(unsigned int));
|
||||
glUseProgram(m_compute);
|
||||
glDispatchCompute(1, 1, 1);
|
||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT);
|
||||
unsigned int marker = 0;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_arena);
|
||||
glGetBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(marker), &marker);
|
||||
EXPECT_EQ(marker, 0xC0FFEEu) << "the dispatch through the arena's SSBO binding never landed";
|
||||
} else {
|
||||
RecordProperty("arena_arm_used", "not asked: no compute shader storage blocks");
|
||||
}
|
||||
EXPECT_EQ(FirstGLError(), 0u);
|
||||
ExpectDeclaredArm(declared, "after a frame of draws, an SSBO binding and a dispatch");
|
||||
}
|
||||
|
||||
// P11 A1 (MG_Remote/CONTRACT-P11.md §1): THE TCP LANE WITH MOBILEGL_IPC_ADOPT_TIER=0. A stream
|
||||
// data plane has no memory the two sides share, so the client refuses the knob by name at its
|
||||
// handshake - exactly one `Refuse{AdoptTierOnStream, "T0"}` line in its log - and the session
|
||||
// runs T2: the other cases in the same `.AdoptTier0.` lane are green and the arena is emulated.
|
||||
// Before A1 this lane ran T2 silently. Everywhere else it skips.
|
||||
TEST_F(LargeArenaAdoptionScenario, AStreamSessionRefusesTheAdoptTierOnceByName) {
|
||||
if (!Ready() || IsSkipped()) return;
|
||||
const char* tier = std::getenv(kAdoptTierRefusalMarker);
|
||||
if (tier == nullptr || tier[0] == '\0') {
|
||||
GTEST_SKIP() << "runs only in the `.AdoptTier0.` tcp entries, which set "
|
||||
"MOBILEGL_IPC_ADOPT_TIER=0 and " << kAdoptTierRefusalMarker << "=T0";
|
||||
}
|
||||
if (PipeStatsWindow::LibraryLogPath().empty()) {
|
||||
GTEST_SKIP() << "the lane configured no MOBILEGL_LOG_FILE_PATH, and the client's log is "
|
||||
"where the refusal is written";
|
||||
}
|
||||
// A frame of the arena's work first: a refusal is only worth reading from a session that
|
||||
// then ran - and an armed split lane requires the case to move the record ordinal anyway.
|
||||
UploadQuad(0.f, 1.f, 0.f);
|
||||
DrawQuad();
|
||||
EXPECT_GT(CenterPixel()[1], 200) << "the session that refused the tier did not render";
|
||||
EXPECT_EQ(FirstGLError(), 0u);
|
||||
Gl().EndFrame();
|
||||
|
||||
const std::string log = PipeStatsWindow::ReadWholeFile(PipeStatsWindow::LibraryLogPath());
|
||||
const std::string line = std::string("Refuse{AdoptTierOnStream, \"") + tier + "\"}";
|
||||
std::size_t count = 0;
|
||||
for (auto at = log.find(line); at != std::string::npos; at = log.find(line, at + 1)) ++count;
|
||||
RecordProperty("adopt_tier_refusals", static_cast<int>(count));
|
||||
EXPECT_EQ(count, 1u) << "the client names MOBILEGL_IPC_ADOPT_TIER on a stream exactly once, at "
|
||||
"its handshake (" << line << "), in " << PipeStatsWindow::LibraryLogPath();
|
||||
EXPECT_EQ(log.find("Fatal{UnimplementedAdoptTier"), std::string::npos) << log;
|
||||
}
|
||||
|
||||
} // namespace MGITest
|
||||
|
||||
@@ -122,6 +122,16 @@ MAGMA_SERVER_ENV_KNOB_NO_TCP = (".ShaderMip1.", ".ShaderMip2.", ".DepthMip.",
|
||||
f".PrimGenReroute.PrimitivesGeneratedNoXfbScenario.{case}" for case in PRIMGEN_REROUTE_CASES)
|
||||
|
||||
|
||||
# P11 A1: THE MIRROR SHAPE - entries that exist on tcp ALONE, by construction. `.AdoptTier0.` runs
|
||||
# LargeArenaAdoptionScenario with MOBILEGL_IPC_ADOPT_TIER=0 on the CLIENT: a stream data plane
|
||||
# refuses that tier by name and runs T2 (the scenario is green there), while over shared segments -
|
||||
# the split and spawn arms - the same knob dies at the handshake by design (CONTRACT-P11 §1), so a
|
||||
# split or spawn copy could only ever be a death. Each tail must match at least one tcp entry, or
|
||||
# the exception names nothing. (The DirectGLES `.AdoptTier0.` twins need no entry: the Espryt
|
||||
# CASE pattern does not parse a middle segment, so they never enter that comparison.)
|
||||
MAGMA_TCP_ONLY = (".AdoptTier0.",)
|
||||
|
||||
|
||||
def lane_names(build_dir, label):
|
||||
"""Every ctest entry name under an ANCHORED label (`ctest -L` is a regex, not a name)."""
|
||||
out = subprocess.run(["ctest", "-N", "-L", "^" + label + "$"], cwd=build_dir,
|
||||
@@ -169,7 +179,7 @@ def tcp_lock_check(build_dir):
|
||||
return False
|
||||
|
||||
|
||||
def compare_arms(build_dir, tier, labels, inproc_only=(), no_tcp=()):
|
||||
def compare_arms(build_dir, tier, labels, inproc_only=(), no_tcp=(), tcp_only=()):
|
||||
"""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
|
||||
@@ -195,6 +205,20 @@ def compare_arms(build_dir, tier, labels, inproc_only=(), no_tcp=()):
|
||||
return False
|
||||
failed = False
|
||||
reference = "split"
|
||||
if tcp_only and "tcp" in sets:
|
||||
for tail in tcp_only:
|
||||
hits = sorted(k for k in sets["tcp"] if tail in k)
|
||||
if not hits:
|
||||
print(f"::error::{tier}: the tcp-only tail {tail!r} matches no tcp entry - an exception "
|
||||
f"about nothing.", file=sys.stderr)
|
||||
return True
|
||||
elsewhere = sorted(k for arm, keys in sets.items() if arm != "tcp" for k in keys if tail in k)
|
||||
if elsewhere:
|
||||
print(f"::error::{tier}: the tcp-only tail {tail!r} also names non-tcp entries "
|
||||
f"{elsewhere}.", file=sys.stderr)
|
||||
return True
|
||||
print(f"{tier}: {len(hits)} tcp-only entrie(s) excluded from the comparison ({tail})")
|
||||
sets["tcp"] = {k for k in sets["tcp"] if not any(only in k for only in tcp_only)}
|
||||
comparable = {k for k in sets[reference]
|
||||
if not any(only in k for only in inproc_only)}
|
||||
if len(comparable) != len(sets[reference]):
|
||||
@@ -294,7 +318,8 @@ def main():
|
||||
"spawn": "integration-magma-spawn",
|
||||
"tcp": "integration-magma-tcp"},
|
||||
inproc_only=MAGMA_INPROC_ONLY,
|
||||
no_tcp=MAGMA_SERVER_ENV_KNOB_NO_TCP)
|
||||
no_tcp=MAGMA_SERVER_ENV_KNOB_NO_TCP,
|
||||
tcp_only=MAGMA_TCP_ONLY)
|
||||
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