From cdf49a4624cfb9f3561cdf71281a1109c7646cb2 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 23 Sep 2026 11:13:01 -0400 Subject: [PATCH] [CI, tools] (P7): every retrace-split step gets the Magma repair knobs, and a verify retrace reads the pull library's mobilegl.log --- .github/workflows/test.yml | 65 ++++++++++++++----------- tools/trace_replay/run_trace_case.cmake | 38 ++++++++++++--- 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 748eb39d..f87a6e64 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3081,6 +3081,43 @@ jobs: chmod +x build-linux/libMobileGLServer.so echo "server image: $(readlink -f build-linux/libMobileGLServer.so)" + # THE MAGMA KNOBS GO TO $GITHUB_ENV, NOT TO ONE STEP'S SHELL: the replay below AND both + # negative controls after it must run the same repair set. Exported inside "Retrace and + # validate" only, they never reached the pull-library control, which replayed + # iterationrp x DirectVulkan unrepaired (ssim 0.028 < 0.98), reddened at + # run_trace_case.cmake:173 before the transport assertion, and failed as "the failure never + # says the library did not resolve the transport" - a red that is not the control's own. + - name: Magma repair knobs for this case (every later step) + run: | + # P7 package L: THE SAME MAGMA KNOBS THE MONOLITH RETRACE JOB EXPORTS, ALL OF THEM. + # This job exported none at all, so every DirectVulkan row of the split matrix was + # compared against a monolith row running a different repair set - and a split retrace + # whose control is not comparable cannot say whether a divergence is a transport fact. + # R11F_G11F_B10F fallback is whole-backend; the blended depth-write quirk auto-enables + # only on Qualcomm, which no runner has, so the OIT case forces it exactly as the + # monolith job does (ForceOn bypasses only the vendor gate). + if [ '${{ matrix.backend }}' = 'DirectVulkan' ]; then + echo "MOBILEGL_MAGMA_R11G11B10F_FALLBACK=1" >> "${GITHUB_ENV}" + fi + if [ '${{ matrix.backend }}' = 'DirectVulkan' ] \ + && [ '${{ matrix.case }}' = 'improved-transparency-minecraft-26.3' ]; then + echo "MOBILEGL_MAGMA_DISABLE_BLENDED_DEPTH_WRITE=1" >> "${GITHUB_ENV}" + fi + # THE THREE ITERATIONRP KNOBS, FOR THE ONE CASE THE MONOLITH JOB NAMES. + # The iterationRP repairs are tri-state quirks that default to device auto-detection and + # lavapipe is on no auto list, so without them Program 203 runs unrepaired and misses its + # golden output. The monolith job has exported them since they landed; this job never + # did, so `iterationrp x DirectVulkan` was the one cell of the split matrix whose red + # could not be read as a transport fact - the monolith control it is compared against was + # running a different repair set. Exit gate 1 asks for the two halves to be COMPARABLE, + # and two runs that differ in a quirk knob are not. + if [ '${{ matrix.backend }}' = 'DirectVulkan' ] \ + && [ '${{ matrix.case }}' = 'minecraft-1.21.4-fabric-iris-iterationrp-in-world' ]; then + echo "MOBILEGL_MAGMA_FIX_ITERATIONRP_SUBGROUP_SCRATCH=1" >> "${GITHUB_ENV}" + echo "MOBILEGL_MAGMA_DERIVE_NUM_SUBGROUPS=1" >> "${GITHUB_ENV}" + echo "MOBILEGL_MAGMA_ITERATIONRP_FIX_BARRIER=1" >> "${GITHUB_ENV}" + fi + - name: Retrace and validate under MOBILEGL_TRANSPORT=${{ matrix.transport }} working-directory: build-retrace/tools/trace_replay # run_trace_case.cmake turns MOBILEGL_TRANSPORT into assertions of its own - the library @@ -3096,34 +3133,6 @@ jobs: # resolves the image relative to nothing. Harmless on the inproc arm, which reads it # only to decide it does not need it. export MOBILEGL_IPC_SERVER_PATH="${GITHUB_WORKSPACE}/build-linux/libMobileGLServer.so" - # P7 package L: THE SAME MAGMA KNOBS THE MONOLITH RETRACE JOB EXPORTS, ALL OF THEM. - # This job exported none at all, so every DirectVulkan row of the split matrix was - # compared against a monolith row running a different repair set - and a split retrace - # whose control is not comparable cannot say whether a divergence is a transport fact. - # R11F_G11F_B10F fallback is whole-backend; the blended depth-write quirk auto-enables - # only on Qualcomm, which no runner has, so the OIT case forces it exactly as the - # monolith job does (ForceOn bypasses only the vendor gate). - if [ '${{ matrix.backend }}' = 'DirectVulkan' ]; then - export MOBILEGL_MAGMA_R11G11B10F_FALLBACK=1 - fi - if [ '${{ matrix.backend }}' = 'DirectVulkan' ] \ - && [ '${{ matrix.case }}' = 'improved-transparency-minecraft-26.3' ]; then - export MOBILEGL_MAGMA_DISABLE_BLENDED_DEPTH_WRITE=1 - fi - # THE THREE ITERATIONRP KNOBS, FOR THE ONE CASE THE MONOLITH JOB NAMES. - # The iterationRP repairs are tri-state quirks that default to device auto-detection and - # lavapipe is on no auto list, so without them Program 203 runs unrepaired and misses its - # golden output. The monolith job has exported them since they landed; this job never - # did, so `iterationrp x DirectVulkan` was the one cell of the split matrix whose red - # could not be read as a transport fact - the monolith control it is compared against was - # running a different repair set. Exit gate 1 asks for the two halves to be COMPARABLE, - # and two runs that differ in a quirk knob are not. - if [ '${{ matrix.backend }}' = 'DirectVulkan' ] \ - && [ '${{ matrix.case }}' = 'minecraft-1.21.4-fabric-iris-iterationrp-in-world' ]; then - export MOBILEGL_MAGMA_FIX_ITERATIONRP_SUBGROUP_SCRATCH=1 - export MOBILEGL_MAGMA_DERIVE_NUM_SUBGROUPS=1 - export MOBILEGL_MAGMA_ITERATIONRP_FIX_BARRIER=1 - fi ctest -V --no-tests=error --timeout 10800 \ -R '^MobileGLTraceReplay\.${{ matrix.case }}\.${{ matrix.backend }}$' diff --git a/tools/trace_replay/run_trace_case.cmake b/tools/trace_replay/run_trace_case.cmake index d5936128..2a442dc0 100644 --- a/tools/trace_replay/run_trace_case.cmake +++ b/tools/trace_replay/run_trace_case.cmake @@ -119,6 +119,11 @@ set(mobilegl_log "${TRACE_OUTPUT_DIR}/output/mobilegl.client.log") # The client file keeps the unsuffixed name, so every other reader here - the transport markers, # the pipe-verify block, the artifact copy - is unchanged. set(mobilegl_server_log "${TRACE_OUTPUT_DIR}/output/mobilegl.server.log") +# A PULL library (no MOBILEGL_BUILD_DISAGGREGATED: CI's build-linux and build-linux-verify) has +# one log role and writes MOBILEGL_LOG_FILE_PATH unchanged (Log.h's pull RoleLogPath). It is kept +# and dumped beside the two role logs, and the verify block below reads it when there is no client +# log; the MOBILEGL_TRANSPORT block never does, because it must refuse a run with no client log. +set(mobilegl_pull_log "${TRACE_OUTPUT_DIR}/output/mobilegl.log") if(EXISTS "${retrace_log}") file(STRINGS "${retrace_log}" gl_identity_lines REGEX "MOBILEGL_TRACE_GL_") foreach(line IN LISTS gl_identity_lines) @@ -152,6 +157,9 @@ if(DEFINED TRACE_ARTIFACT_DIR AND NOT "${TRACE_ARTIFACT_DIR}" STREQUAL "") if(EXISTS "${mobilegl_log}") file(COPY_FILE "${mobilegl_log}" "${TRACE_ARTIFACT_DIR}/${TRACE_CASE_NAME}-${TRACE_BACKEND}-mobilegl.client.log") endif() + if(EXISTS "${mobilegl_pull_log}") + file(COPY_FILE "${mobilegl_pull_log}" "${TRACE_ARTIFACT_DIR}/${TRACE_CASE_NAME}-${TRACE_BACKEND}-mobilegl.log") + endif() endif() if(EXISTS "${result_json}") @@ -162,10 +170,15 @@ else() file(READ "${retrace_log}" retrace_log_contents) message(STATUS "${retrace_log_contents}") endif() - if(EXISTS "${mobilegl_log}") - file(READ "${mobilegl_log}" mobilegl_log_contents) - message(STATUS "${mobilegl_log_contents}") - endif() + # Every log the library could have written: under a pull library the only one is + # mobilegl.log, and that is where a verify negative control's Fatal{PipeVerifyDiffer} is - + # without it the transcript of a replay that aborted before result.json says nothing about why. + foreach(role_log IN ITEMS "${mobilegl_log}" "${mobilegl_pull_log}") + if(EXISTS "${role_log}") + file(READ "${role_log}" role_log_contents) + message(STATUS "--- ${role_log}\n${role_log_contents}") + endif() + endforeach() message(FATAL_ERROR "trace replay did not write ${result_json}") endif() @@ -197,15 +210,24 @@ endif() # aborted, so the run would otherwise finish 0 with its own report in the log. if(DEFINED ENV{MOBILEGL_PIPE_VERIFY} AND NOT "$ENV{MOBILEGL_PIPE_VERIFY}" STREQUAL "") set(pipe_verify_case "${TRACE_CASE_NAME} ${TRACE_BACKEND}") + # THE VERIFY LIBRARY IS A PULL BUILD in CI (test.yml build-linux-verify configures no + # MOBILEGL_BUILD_DISAGGREGATED), and a pull build has one log role and writes + # MOBILEGL_LOG_FILE_PATH unchanged (Log.h's pull RoleLogPath): output/mobilegl.log. A split + # verify build writes mobilegl.client.log. Read whichever this library wrote - this block only; + # the MOBILEGL_TRANSPORT block below must keep refusing a run with no client log. + set(pipe_verify_log_path "${mobilegl_log}") + if(NOT EXISTS "${pipe_verify_log_path}" AND EXISTS "${mobilegl_pull_log}") + set(pipe_verify_log_path "${mobilegl_pull_log}") + endif() if("$ENV{MOBILEGL_PIPE_VERIFY}" STREQUAL "0" OR "$ENV{MOBILEGL_PIPE_VERIFY}" STREQUAL "false") message(STATUS "MGPipe verify: MOBILEGL_PIPE_VERIFY=$ENV{MOBILEGL_PIPE_VERIFY}, no verify assertions for ${pipe_verify_case}") - elseif(NOT EXISTS "${mobilegl_log}") + elseif(NOT EXISTS "${pipe_verify_log_path}") message(FATAL_ERROR - "MOBILEGL_PIPE_VERIFY is set for ${pipe_verify_case} but the run wrote no ${mobilegl_log}, " + "MOBILEGL_PIPE_VERIFY is set for ${pipe_verify_case} but the run wrote no ${pipe_verify_log_path}, " "so there is no evidence the comparator ever armed. A verify retrace with no library log " "cannot be counted as a verify retrace.") else() - file(READ "${mobilegl_log}" pipe_verify_log) + file(READ "${pipe_verify_log_path}" pipe_verify_log) string(FIND "${pipe_verify_log}" "MGPipe: verify armed" pipe_verify_armed_at) if(pipe_verify_armed_at EQUAL -1) message(FATAL_ERROR @@ -215,7 +237,7 @@ if(DEFINED ENV{MOBILEGL_PIPE_VERIFY} AND NOT "$ENV{MOBILEGL_PIPE_VERIFY}" STREQU "nothing - or the runtime knob never reached the process. Check that the VERIFY " "runtime artifact is the one unpacked at ${MOBILEGL_LIBRARY}.") endif() - file(STRINGS "${mobilegl_log}" pipe_verify_fatals + file(STRINGS "${pipe_verify_log_path}" pipe_verify_fatals REGEX "Fatal\\{(PipeVerifyDiffer|UnmigratedPipeInput|PipeVerifyBadKnob)") if(pipe_verify_fatals) foreach(line IN LISTS pipe_verify_fatals)