[MG_IntegrationTest] (Disaggregated): P5f close - pin zero residual reads on each backend frame

This commit is contained in:
2026-09-19 23:49:06 -04:00
parent 377aede6ef
commit 52bee2fa1b
3 changed files with 84 additions and 6 deletions
@@ -2576,3 +2576,28 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
ENVIRONMENT "${MGL_ITEST_GLES_DUALBLOCK_ENVIRONMENT}\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/split-logs/DirectGLES.Split.DualBlock.TheTwoRolesHaveDistinctBlocks.log"
)
endif()
# P5f exit: observe every one of three real drawing frames on both backend roles.
if (MOBILEGL_BUILD_DISAGGREGATED)
foreach(backend DirectGLES DirectVulkan)
if (backend STREQUAL "DirectGLES")
set(p5f_rsp_label "integration-split")
else()
set(p5f_rsp_label "integration-magma-split")
endif()
mgl_itest_join_environment(p5f_rsp_environment
"MOBILEGL_BACKEND_TYPE=${backend}" "MOBILEGL_TRANSPORT=inproc"
"MOBILEGL_IPC_SERVER_PATH=${MGL_ITEST_SPLIT_SERVER_PATH}" "MGITEST_SPLIT_LANE=1"
"MGITEST_P5F_RSP_LANE=1" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/p5f-rsp-${backend}.log"
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "${backend}.Split.P5fRsp."
TEST_FILTER "F1WireScenario.EachWireFrameHasZeroResidualPulls"
DISCOVERY_TIMEOUT 30
PROPERTIES LABELS "${p5f_rsp_label}\;integration-p5f-rsp"
TIMEOUT ${MGL_ITEST_TIMEOUT}
RESOURCE_LOCK "p5f-rsp-${backend}.log"
ENVIRONMENT "${p5f_rsp_environment}")
endforeach()
endif()
@@ -1,6 +1,8 @@
// f1 split-only pixel controls: every result depends on the migrated verb.
#include "../Harness/ScenarioFixture.h"
#include "../Harness/SplitRuntimePeek.h"
#include "../Harness/PipeStatsWindow.h"
#include "../Harness/SplitLane.h"
#include <array>
#include <cstdio>
#include <cstdlib>
@@ -93,6 +95,61 @@ protected:
};
}
// P5f exit: each published frame must have a real draw and server stamp, and
// zero residual reads. Missing instrumentation is a failure rather than a false zero.
TEST_F(F1WireScenario, EachWireFrameHasZeroResidualPulls) {
if (!Ready()) return;
if (!SplitLane::MarkerIsOne("MGITEST_P5F_RSP_LANE"))
GTEST_SKIP() << "requires the dedicated per-frame stats lane";
ASSERT_FALSE(PipeStatsWindow::LibraryLogPath().empty());
Attach(GL_RGBA8);
const char* fragment = R"(#version 430 core
uniform float value;
layout(location=0) out vec4 color;
void main() { color = vec4(value, 0.25, 0.75, 1.0); }
)";
const GLuint program = BuildWireProgram({{GL_VERTEX_SHADER, kWireVertexIdTriangle},
{GL_FRAGMENT_SHADER, fragment}});
ASSERT_NE(program, 0u);
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glUseProgram(program);
const GLint location = glGetUniformLocation(program, "value");
ASSERT_GE(location, 0);
glViewport(0, 0, 8, 8);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_RASTERIZER_DISCARD);
Gl().EndFrame(); // close setup's counter window
for (int frame = 0; frame < 3; ++frame) {
const float value = float(frame + 1) / 4.0f;
glUniform1f(location, value);
glDrawArrays(GL_TRIANGLES, 0, 3);
std::array<GLubyte, 4> pixel{};
glReadPixels(3, 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel.data());
ASSERT_EQ(FirstGLError(), GLenum(GL_NO_ERROR));
EXPECT_NEAR(pixel[0], value * 255.0f, 1) << "frame " << frame;
EXPECT_NEAR(pixel[1], 64, 1);
EXPECT_NEAR(pixel[2], 191, 1);
EXPECT_EQ(pixel[3], 255);
Gl().EndFrame();
const auto window = PipeStatsWindow::LastFromLaneLog();
ASSERT_TRUE(window.found) << "P5f rsp window missing on frame " << frame;
EXPECT_GT(PipeStatsWindow::CounterOrAbsent(window, "draws"), 0) << window.line;
EXPECT_GT(PipeStatsWindow::CounterOrAbsent(window, "vbs"), 0) << window.line;
EXPECT_EQ(PipeStatsWindow::CounterOrAbsent(window, "rsp"), 0)
<< "P5f residual pull on frame " << frame << ": " << window.line;
RecordProperty("p5f_frame_" + std::to_string(frame), window.line);
}
glUseProgram(0);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
glDeleteProgram(program);
}
TEST_F(F1WireScenario, ClearBufferfvPixels) {
// Red once (executed, reverted): zero the clear record values; F1.ClearBufferfv.pixels fails.
if (!Ready()) return;
@@ -381,12 +381,8 @@ void main() { oColor = vec4(vColor, 1.0); }
"a green strict lane containing only entries like this one would mean the knob "
"was never armed rather than that the debt was paid (ID-115): "
<< window.line;
EXPECT_TRUE(residual == 0 || residual >= draws)
<< "rsp neither scales with draws nor is zero (" << residual << " vs " << draws
<< "). ID-119: while this phase's draw-path debt is unretired every draw pulls at "
"least one BARRIER-PULLED row, and the retirement is visible as rsp ceasing to "
"scale with draws - a value strictly between is neither state: "
<< window.line;
EXPECT_EQ(residual, 0)
<< "P5f exit: a drawing frame still reads client residual state: " << window.line;
}
} // namespace MGITest