Files
chimera-gfx-Public/tools/validate_retroarch_phase10p.py
Chimera GFX release export a6037502d7
phase0-ci / build-and-audit (push) Successful in 2m14s
Publish Chimera GFX source
2026-09-03 03:27:14 +02:00

257 lines
11 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
"""Validate the offline Phase-1.0P VideoOut submit analysis."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
import subprocess
from typing import Any
PHASE = "PHASE_1_0P_VIDEOOUT_SUBMIT_OFFLINE_ANALYSIS"
STATUS = "VIDEOOUT_SUBMIT_FAILURE_SITE_PROVEN_ROOT_CAUSE_UNRESOLVED"
ARTIFACT_SHA256 = "c99a0856309a357ad2667d89b4924e4063ad214cae09c8a419457b0732f583cd"
TRACE_SHA256 = "3d0b8811ae11f5cac2c2d331e252e1789a10588cab0e6045828a6b6af0fe1eb6"
RA_SOURCE = "12cf1d783c41eb303987e49a5a920805a59ef7a4"
RA_RUNNER = "606909706f91d7213751c245081333f56c2cce89"
SDK_COMMIT = "d2e2e585740362976a39fdd5ccf390f199a7bc37"
SDL_COMMIT = "0baf4ac49382b537ba449901b5b6d0d189bb1fbb"
AUTHORIZATION_FIELDS = (
"ps5_connection_authorized", "device_transfer_authorized",
"device_execution_authorized", "result_receive_authorized",
"installation_authorized", "autoload_authorized",
"device_write_authorized", "automatic_retry",
)
def load_json(path: Path) -> dict[str, Any]:
value = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(value, dict):
raise ValueError("analysis manifest is not an object")
return value
def all_false(record: dict[str, Any], fields: tuple[str, ...]) -> bool:
return all(record.get(field) is False for field in fields)
def bound_inputs_are_exact(record: dict[str, Any]) -> bool:
return (
record.get("artifact_name") == "retroarch_ps5_write_diag.elf"
and record.get("artifact_size") == 1845208
and record.get("artifact_sha256") == ARTIFACT_SHA256
and record.get("trace_size") == 18031
and record.get("trace_sha256") == TRACE_SHA256
and record.get("linked_sdl_source_size") == 19642
and record.get("linked_sdl_source_sha256")
== "9949a280fed40241746788a8c001280455bc629e0566a88f82f16a8634d43025"
and record.get("linker_map_size") == 637728
and record.get("linker_map_sha256")
== "6768ffc7267b9b362c3b953571e5dfeed1e70004a3e19f41ef500c3f26272719"
)
def exact_call_is_bounded(record: dict[str, Any]) -> bool:
return (
record.get("symbol") == "sceVideoOutSubmitFlip"
and record.get("tuple") == "(handle,0,1,0)"
and record.get("function_address") == "0xfe560"
and record.get("call_address") == "0xfe7bc"
and record.get("got_address") == "0x1779b0"
and record.get("registers")
== {"edi": "handle", "esi": 0, "edx": 1, "ecx": 0}
and record.get("runtime_handle") == "0x4e100100"
and record.get("runtime_return") == -1
and record.get("saved_errno") == 0
and record.get("wait_called_after_failure") is False
)
def abi_claims_fail_closed(record: dict[str, Any]) -> bool:
required_unproven = (
"flip_mode_semantics", "frame_id_semantics", "buffer_zero_validity",
"buffer_attribute_semantics", "flip_master_or_active_app_requirement",
"return_code_semantics",
)
return (
record.get("sdk_exports_symbols_only") is True
and record.get("sdk_public_videoout_headers_present") is False
and record.get("sdl_fork_is_only_local_public_prototype_source") is True
and record.get("submit_signature_independently_corroborated") is False
and all(record.get(field) == "UNPROVEN" for field in required_unproven)
and record.get("errno_is_useful_for_observed_failure") is False
)
def terminal_order_is_not_promoted(record: dict[str, Any]) -> bool:
return (
record.get("observed") == ["D07", "D12", "D04"]
and record.get("source_deterministic") is True
and record.get("network_reordering_required") is False
and record.get("d12_meaning") == "FAILURE_SHUTDOWN_REQUEST"
and record.get("d12_proves_cleanup_complete") is False
and record.get("current_trace_valid_terminal_classification") is False
and record.get("host_parser_relaxation_allowed") is False
and record.get("future_protocol_requires_new_magic") is True
and record.get("future_terminal_after_d04_and_cleanup_evidence") is True
)
def decision_is_fail_closed(record: dict[str, Any]) -> bool:
return (
record.get("classification") == STATUS
and record.get("parameter_experiment_allowed") is False
and record.get("new_videoout_export_call_allowed") is False
and record.get("host_parser_promotion_allowed") is False
and record.get("phase10q_target_build_allowed") is False
and record.get("phase10q_device_action_allowed") is False
and record.get("required_next_evidence")
== "ACCEPTABLE_PUBLIC_VIDEOOUT_ABI_AND_RUNTIME_STATE_CONTRACT"
)
def git(root: Path, *args: str) -> str:
result = subprocess.run(
["git", *args], cwd=root, capture_output=True, text=True, check=False)
if result.returncode:
raise RuntimeError(result.stderr.strip() or "git failed")
return result.stdout
def validate_repository(root: Path, retroarch_root: Path, sdk_root: Path,
sdl_root: Path) -> list[str]:
errors: list[str] = []
record = load_json(
root / "manifests/retroarch/phase-1.0p-videoout-submit-analysis.json")
if record.get("phase") != PHASE or record.get("status") != STATUS:
errors.append("phase/status mismatch")
commits = record.get("source_commits", {})
expected = {
"chimera_gfx_phase10o": "af283ef93fae907e6c9c376df24d053ada3f7318",
"chimera_retroarch_artifact": RA_SOURCE,
"chimera_retroarch_runner": RA_RUNNER,
"ps5_payload_sdk_v0_41": SDK_COMMIT,
"public_ps5_sdl": SDL_COMMIT,
}
if commits != expected:
errors.append("source commit binding mismatch")
if not bound_inputs_are_exact(record.get("bound_inputs", {})):
errors.append("artifact, trace, source or map binding mismatch")
actions = record.get("offline_actions", {})
if not all(actions.get(field) is True for field in (
"source_inspected", "linker_map_inspected", "disassembly_inspected",
"dynamic_symbols_and_relocations_inspected",
)) or not all(actions.get(field) is False for field in (
"target_source_changed", "target_artifact_created", "ps5_connected",
"device_transfer_performed", "target_execution_performed",
"result_received_from_device",
)):
errors.append("offline-only action boundary mismatch")
if not all_false(record.get("current_authorizations", {}), AUTHORIZATION_FIELDS):
errors.append("authorization remains active")
if not exact_call_is_bounded(record.get("exact_call", {})):
errors.append("exact submit call is not bounded")
registration = record.get("registration", {})
if not (
registration.get("function_address") == "0xfdc20"
and registration.get("runtime_return") == 0
and registration.get("buffer_index_used") == 0
and registration.get("opaque_layout_semantics") == "UNPROVEN"
):
errors.append("registration evidence was broadened")
if not abi_claims_fail_closed(record.get("abi_evidence", {})):
errors.append("ABI uncertainty was promoted")
candidates = record.get("candidate_matrix", {})
if not (
candidates.get("diagnostic_normal_first_index_mismatch")
== "REJECTED_CURRENT_CAUSE"
and candidates.get("buffer_registration_failure")
== "REJECTED_BY_OBSERVED_RETURN_ZERO"
and candidates.get("errno_specific_failure_identity") == "ABSENT"
and all(candidates.get(field) == "UNPROVEN" for field in (
"wrong_submit_tuple", "wrong_opaque_buffer_contract",
"missing_flip_master_or_app_state", "visible_flip",
"complete_cleanup", "safe_exit",
))
):
errors.append("candidate matrix overclaims a root cause")
if not terminal_order_is_not_promoted(record.get("terminal_ordering", {})):
errors.append("terminal ordering is promoted or incomplete")
if not decision_is_fail_closed(record.get("decision", {})):
errors.append("decision is not fail-closed")
tests = record.get("tests", {})
if not (
tests.get("chimera_gfx_ctest") == "60_OF_60_PASS"
and tests.get("phase10p_guardrails") == 20
and tests.get("hardware_claim_from_host_test") is False
):
errors.append("test evidence mismatch")
tracked = git(root, "ls-files").splitlines()
if any(path.lower().endswith((".elf", ".self", ".sprx", ".pkg", ".map"))
for path in tracked):
errors.append("target artifact or linker map is tracked")
try:
if git(retroarch_root, "rev-parse", "HEAD").strip() != RA_RUNNER:
errors.append("RetroArch HEAD mismatch")
patch = git(retroarch_root, "show", f"{RA_SOURCE}:pkg/ps5/sdl2-ps5-early-diag.patch")
diag = git(retroarch_root, "show", f"{RA_SOURCE}:pkg/ps5/chimera_ps5_diag.c")
gfx = git(retroarch_root, "show", f"{RA_SOURCE}:gfx/drivers/sdl2_gfx.c")
for token in (
"CHIMERA_PS5_FIRST_FRAME_INDEX 0u",
"sceVideoOutSubmitFlip(",
"submit_errno = submit_result != 0 ? errno : 0",
"chimera_ps5_smoke_video_error(",
):
if token not in patch:
errors.append(f"artifact source token missing: {token}")
if "stage == CHIMERA_PS5_DIAG_D12" not in diag:
errors.append("D12 terminal source missing")
if "chimera_ps5_early_diag_sdl_result(sdl_init_result)" not in gfx:
errors.append("D04 caller source missing")
if git(sdk_root, "rev-parse", "HEAD").strip() != SDK_COMMIT:
errors.append("SDK commit mismatch")
if git(sdl_root, "rev-parse", "HEAD").strip() != SDL_COMMIT:
errors.append("SDL commit mismatch")
if git(sdk_root, "status", "--porcelain"):
errors.append("SDK tree is dirty")
if git(sdl_root, "status", "--porcelain"):
errors.append("SDL tree is dirty")
stubs = (sdk_root / "sce_stubs/libSceVideoOut.c").read_text(encoding="utf-8")
header = (sdl_root / "src/video/ps5/SDL_ps5video.h").read_text(encoding="utf-8")
source = (sdl_root / "src/video/ps5/SDL_ps5video.c").read_text(encoding="utf-8")
if "sceVideoOutSubmitFlip" not in stubs:
errors.append("SDK submit export missing")
if "int sceVideoOutSubmitFlip(int, int, uint32_t, int64_t);" not in header:
errors.append("SDL submit prototype missing")
if "static uint32_t frame_id = 0;" not in source or \
"sceVideoOutSubmitFlip(device_data->handle, idx, 1, frame_id)" not in source:
errors.append("public SDL first-frame source mismatch")
except (OSError, RuntimeError) as error:
errors.append(str(error))
return errors
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--root", type=Path, required=True)
parser.add_argument("--retroarch-root", type=Path, required=True)
parser.add_argument("--sdk-root", type=Path, required=True)
parser.add_argument("--sdl-root", type=Path, required=True)
args = parser.parse_args()
errors = validate_repository(
args.root.resolve(), args.retroarch_root.resolve(),
args.sdk_root.resolve(), args.sdl_root.resolve())
if errors:
for error in errors:
print(f"ERROR: {error}")
return 1
print("Phase-1.0P offline VideoOut analysis validation passed")
return 0
if __name__ == "__main__":
raise SystemExit(main())