mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MGPipe, Metrics, Config, CI): exchange the per-frame stats instead of racing a store, carry the three uncarried table entries, drop the inline host span from a buffer range, spell the buffer subdata range, and close the small gate holes
- S-1 PipeStats::OnPresent read each frame accumulator and then store(0)'d it; a Bump from a staging thread landing in between was lost from the Tracy plot and from every frame. Each accumulator is now exchange(0, relaxed) and the exchanged value is what is plotted, so every add lands in exactly one frame. - T-3 FdPassing without MSG_CMSG_CLOEXEC (macOS, BSD) handed back descriptors that survived exec; every received fd now gets FD_CLOEXEC by hand under !MSG_CMSG_CLOEXEC. MSG_NOSIGNAL is defined to 0 where the platform lacks it (FdPassing.cpp, Doorbell.cpp) and SO_NOSIGPIPE is set on the socketpair and on a SocketDoorbell's descriptor where it exists, so a write to a hung-up peer is EPIPE rather than a fatal signal. - T-4 the missing-flatbuffers fallback wrote OFF into the cache with FORCE, so a plain re-configure after `git submodule update` stayed OFF silently. It is a normal-variable set now, shadowing the cache for that configure only; verified by hiding flatbuffers.h, configuring with ON (warning, transport off, cache still ON) and re-configuring plainly with the header back (transport ON). - P-2 three LIVE GLFunctionsTable entries had no carrier: GetGpuTimestampNs (glGetInteger64v(GL_TIMESTAMP), a synchronous server answer), QueryCounterTimestamp (glQueryCounter, a one-shot stamp, not a begin/end pair) and WaitSync (the GPU-side wait FenceWait's client wait does not express). QueryTimestamp (MGPTimestampRequest, kCtxQuery, kReplySlot), QueryCounter (MGPQueryDesc with Kind = GL_TIMESTAMP, kCtxQuery) and FenceWaitServer (MGPFenceWait, kScreen) are APPENDED at the end of PipeCalls.def because the opcode is the position: SetSwapInterval stays 68, the three take 69-71, and PipeCatalogue.LateArrivalsAreAppendedWithoutRenumbering pins that. Header counts 71 (screen 11, query 8); the seven generators regenerated. - P-3 MGPBufferRange inlined a 32-byte MGHostSpan into every range of every class - dead space on every SSBO, atomic-counter and XFB range, and D-B8 says not to freeze the named-UBO payload before the stage-ubo-named numbers exist. The range is 24 bytes now; the host spans are an optional second var-tail behind the ranges, announced by MGPShaderBuffers::HostSpanCount (0 or Count), with set_shader_buffers keeping its kVarTail|kHostSpan flags. PipeCatalogue.BufferRangeCarriesNoInlineHostSpan pins the sizes, the flags and the comparator's view of the count. - P-4 QueryEnvUint64 parsed with base 0 (a leading zero meant octal: MOBILEGL_PIPE_PUSH=010 read as 8) and accepted -1 as every bit set; it is decimal or explicit 0x now and a '-' anywhere is refused with the warning (smoke through the integration binary: -1 and 12abc warn, 010 and 0x10 parse). The CI stdio gate's alternation now also catches fprintf(stdout, puts( and std::cout/cerr; it is green over MG_Backend and MG_State. MGPSubData states how the buffer half expresses [offset, size): UnionBox.X / UnionBox.W with Target == Buffer, Y = Z = 0, H = D = 1, one record bounded at a 2^31-1 offset and 2^32-1 size beyond which the emitter splits (the same rule the ring's half-capacity bound already imposes); MGPipeSetSubDataBufferRange / MGPipeSubDataBufferOffset / Size are the only spelling and PipeCatalogue.SubDataBufferRangeRidesInTheUnionBox pins the encoding and its bounds. gen_pipe.py now refuses, in both modes, a call payload named in PipeCalls.def with no field list in PipeFields.def (the four memcmp-fallback member types are the documented exception); shown by dropping P(MGPSwapInterval), which exits 1 naming the payload. - The MGPPixelPackState size assertion compared sizeof against itself; it asserts the literal 28 PixelStoreParameters measures. - Verified: ctest -L unit green in both the default and the split configuration, gen_pipe.py --check clean with the generated files committed, nm --defined-only of the default libMobileGL.so has no MG_Remote symbol, and the full integration-gpu suite passes (the *IsActuallyArmedWhenTheEnvironmentPinsItOn family trips under -j 8 as documented and passes serially).
This commit is contained in:
@@ -24,6 +24,9 @@ from the catalogue (they all consume the same .def).
|
||||
|
||||
python3 scripts/gen_pipe.py # write the generated files, print the summary
|
||||
python3 scripts/gen_pipe.py --check # fail if regenerating would change anything
|
||||
|
||||
Both modes refuse a catalogue whose call payload has no field list in PipeFields.def: a
|
||||
payload the G4 comparator cannot see is a payload MOBILEGL_PIPE_VERIFY is blind to.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -157,6 +160,17 @@ def parse_calls():
|
||||
return calls
|
||||
|
||||
|
||||
# The member types the G4 comparator falls back to memcmp for (see gen_verify): the
|
||||
# MG_State / MG_Backend value structs and MGHostSpan. They are not call payloads and get
|
||||
# field lists of their own in P0.5. Nothing else may be missing from PipeFields.def.
|
||||
MEMCMP_FALLBACK_TYPES = {
|
||||
"RenderStateParameters",
|
||||
"PixelStoreParameters",
|
||||
"DynamicBackendParameters",
|
||||
"MGHostSpan",
|
||||
}
|
||||
|
||||
|
||||
def parse_verify_payloads():
|
||||
text = read(os.path.join(PIPE_DIR, "PipeFields.def"))
|
||||
match = re.search(r"#define MGP_VERIFY_PAYLOAD_LIST\(P\)(.*?)\n\n", text, re.S)
|
||||
@@ -169,6 +183,17 @@ def parse_verify_payloads():
|
||||
return payloads
|
||||
|
||||
|
||||
def check_call_payloads_have_field_lists(calls, payloads):
|
||||
"""Every payload PipeCalls.def names must have a G4 field list, or the verify comparator
|
||||
is silently blind to that call. Runs in both modes, --check included."""
|
||||
known = set(payloads)
|
||||
missing = sorted({c.Payload for c in calls
|
||||
if c.Payload not in known and c.Payload not in MEMCMP_FALLBACK_TYPES})
|
||||
if missing:
|
||||
sys.exit("PipeFields.def: call payload(s) with no field list, so MOBILEGL_PIPE_VERIFY "
|
||||
"would be blind to them: %s" % ", ".join(missing))
|
||||
|
||||
|
||||
def parse_coverage():
|
||||
text = read(os.path.join(PIPE_DIR, "Coverage.def"))
|
||||
accessors = []
|
||||
@@ -608,6 +633,7 @@ def main():
|
||||
|
||||
calls = parse_calls()
|
||||
payloads = parse_verify_payloads()
|
||||
check_call_payloads_have_field_lists(calls, payloads)
|
||||
accessors, deltas = parse_coverage()
|
||||
rows = parse_inventory()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user