mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Docs] (MG_Backend/DirectGLES, MG_Backend/DirectVulkan, MG_Backend/Record, MG_Impl/Pipe, MG_IntegrationTest/Scenarios, MG_Pipe, MG_Remote/Client, MG_Remote/Server, MG_State/GLState, MG_Test, MG_Test/Backend, MG_Test/Buffer, MG_Test/Pipe, MG_Test/Wire, scripts, scripts/ci): cite symbols, not lines, in the split backend files
This commit is contained in:
@@ -903,8 +903,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
m_valid = false;
|
||||
return;
|
||||
}
|
||||
// The M-3 rule for a whole-store reader (Managers.cpp:3238): for a store whose
|
||||
// content the application SUPPLIED a coverage gap is a missing record and is
|
||||
// The M-3 rule for a whole-store reader (ResourceContentIsDeclared in ManagersBuffers.cpp): for a store
|
||||
// whose content the application SUPPLIED a coverage gap is a missing record and is
|
||||
// Fatal by name; for one it ORPHANED the gap is its own undefined content and
|
||||
// reading the shadow's zero-fill is exactly what the monolith arm's
|
||||
// MappedData() answers.
|
||||
|
||||
@@ -1021,10 +1021,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// Managers.cpp RequireImageBindableStorage - re-dirties every defined level so the
|
||||
// widened image carrier is replayed rather than allocated empty (LIVE,
|
||||
// and it is this helper's only caller);
|
||||
// DirectGLES.cpp:7406 GenerateThreeChannelFloatMipmapOnCpu - same shape, milder
|
||||
// GenerateThreeChannelFloatMipmapOnCpu, since removed - same shape, milder
|
||||
// outcome (package E's file; E's verification round calls this helper
|
||||
// there, or states why not);
|
||||
// DirectGLES.cpp:6735 the CLEAR half (MarkStorageDirty(..., false)) after a
|
||||
// the CLEAR half (MarkStorageDirty(..., false), since removed) after a
|
||||
// glGetTexImage shadow refresh - it clears rather than dirties, so
|
||||
// nothing is owed and there is nothing to re-arm.
|
||||
//
|
||||
|
||||
@@ -945,7 +945,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
//
|
||||
// `GL_MAP_INVALIDATE_RANGE_BIT` is not a hint, it is an ASSERTION THAT THE OLD BYTES
|
||||
// ARE DEAD - and it is only true of the bytes this call is about to rewrite from the
|
||||
// authoritative shadow. Managers.cpp:1125-1128 records what happens when it is not:
|
||||
// authoritative shadow. ManagersBuffers.cpp's FlushPendingRangesFrom records what happens when it is not:
|
||||
// widening the map to page bounds "looked free and was not - the widened bytes
|
||||
// clobbered GPU-written data (an SSBO counter beside the app's SubData) with the stale
|
||||
// shadow". It fails SILENTLY, unlike tier 3, which only stalls.
|
||||
@@ -2436,7 +2436,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// makes forgetting impossible, and that call is written below.
|
||||
//
|
||||
// IT IS GATED, AND HERE IS THE HANDSHAKE, because the definition is `static` in E's file
|
||||
// on the tree this package was built against (esprytdraw v2, DirectGLES.cpp:2789) and an
|
||||
// on the tree this package was built against (esprytdraw v2; now in DirectGLESInternal.h) and an
|
||||
// internal-linkage function cannot be called from Managers.cpp. E's verification round
|
||||
// drops that one keyword; D's verification round flips this constant to 1, in this file,
|
||||
// one line. Neither side can do it silently: the flip has no other reader and the
|
||||
@@ -3193,7 +3193,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// bind_sampler_states; the caller that knows the unit passes it here.
|
||||
//
|
||||
// Defaulted so a caller that has no unit - the backend's OWN raw-depth-fetch
|
||||
// sampler (DirectGLES.cpp:217), a SamplerObject the client has never seen and for
|
||||
// sampler (GetRawDepthFetchSampler no longer calls this), a SamplerObject the client has never seen and for
|
||||
// which no record can exist - keeps working: that arm reads the object, which is
|
||||
// the authority for server-owned state. An APPLICATION sampler reaching here
|
||||
// without a handle is the E-side call-site gap and says so once.
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
namespace {
|
||||
// P7 wave 2 package C, CONTRACT-P7 §5.5: MAGMA'S MIRROR OF g_glesStateObjectDeathOps
|
||||
// (DirectGLES/Managers.cpp:335), and the one arm of that table Magma has any work in.
|
||||
// (in DirectGLES/Managers.cpp), and the one arm of that table Magma has any work in.
|
||||
//
|
||||
// WHAT THE NOTICE IS FOR HERE, and it is not what it is for on Espryt. Espryt's arm
|
||||
// destroys a BACKEND TWIN keyed by lifetime id; Magma keeps no such twin - its two
|
||||
|
||||
@@ -877,8 +877,8 @@ namespace MobileGL::MG_Record {
|
||||
// THE BITS GO OVER VERBATIM AND ARE LOWERED HERE BY NOBODY. Espryt's atomic-counter
|
||||
// lowering - the counter bit implying the storage bit, because glslang lowers every
|
||||
// atomic_uint onto a storage block - lives inside its own MemoryBarrier
|
||||
// (DirectGLES.cpp:8837) and is a statement about the DRIVER. Repeating it on this side
|
||||
// would make the split arm and the monolith arm two different calls.
|
||||
// (LowerAtomicCounterBarrierBits, DirectGLESCopy.cpp) and is a statement about the driver.
|
||||
// Repeating it on this side would make the split arm and the monolith arm two different calls.
|
||||
if (barrier.ByRegion != 0) {
|
||||
if (gl.MemoryBarrierByRegion == nullptr) return false;
|
||||
gl.MemoryBarrierByRegion(static_cast<GLbitfield>(barrier.Bits));
|
||||
@@ -903,7 +903,7 @@ namespace MobileGL::MG_Record {
|
||||
if (copy.DstTarget == GL_RENDERBUFFER) dst.RenderbufferHandle = copy.Dst;
|
||||
else dst.TextureHandle = copy.Dst;
|
||||
if (MG_Pipe::MGPipeHandleIsNull(copy.Src) || MG_Pipe::MGPipeHandleIsNull(copy.Dst)) {
|
||||
// The monolith's own answer to this, in its own words (DirectGLES.cpp:9067
|
||||
// The monolith's own answer to this, in its own words (DirectGLESCopy.cpp's CopyImageSubData,
|
||||
// "source or destination image failed to sync; declining the copy"): the frontend
|
||||
// validator is what keeps it unreachable and what reports the INVALID_VALUE the
|
||||
// application is owed. A decline here is a real answer, not a silent success.
|
||||
@@ -933,8 +933,8 @@ namespace MobileGL::MG_Record {
|
||||
if (table->GL.BindImageTexture == nullptr) return false;
|
||||
// THE SAME CALL IS RIGHT FOR BOTH BACKENDS, which is why the record carries the whole
|
||||
// argument list although neither reads all of it today: Espryt ignores everything but
|
||||
// Unit and syncs that unit from the barrier-pulled GetImageTextureBinding
|
||||
// (DirectGLES.cpp:9154, :2471), and Magma's slot is a no-op (DirectVulkan.cpp:665). The
|
||||
// Unit and whether a texture is named (BindImageTexture in DirectGLESCopy.cpp), leaving the bind
|
||||
// to the next SyncImageTextureBindings sweep, and Magma's slot is a no-op (DirectVulkan.cpp:665). The
|
||||
// arguments travel because rule D says a verb crosses as the CALL, and because P7 is
|
||||
// what makes the backend read them instead of pulling.
|
||||
table->GL.BindImageTexture(static_cast<GLuint>(bind.Unit), static_cast<GLuint>(bind.GlName),
|
||||
@@ -996,10 +996,10 @@ namespace MobileGL::MG_Record {
|
||||
const MG_Backend::GlobalBackendFunctionsTable* table = Table("begin_stream_output");
|
||||
if (table == nullptr) return false;
|
||||
if (table->GL.BeginTransformFeedback == nullptr) return false;
|
||||
// Espryt's Begin only ARMS the span (DirectGLES.cpp:1212-1220: primitiveMode, pending,
|
||||
// Espryt's Begin only arms the span (XfbImpl::BeginTransformFeedback: primitiveMode, pending,
|
||||
// targets cleared); the driver glBeginTransformFeedback happens in the tail of the next
|
||||
// PrepareForDraw (StartPendingTransformFeedback, :1224), where the capture program and
|
||||
// the buffer bindings are read through the pulls. So this record's effect is not
|
||||
// PrepareForDraw (XfbImpl::StartPendingTransformFeedback), where the capture program and
|
||||
// the buffer bindings are read from the span this record stored. So this record's effect is not
|
||||
// visible until a DRAW crosses - which is why an XFB scenario whose draw is still class
|
||||
// C moves its first blocker to that draw rather than rendering.
|
||||
table->GL.BeginTransformFeedback(static_cast<GLenum>(begin.PrimitiveMode));
|
||||
@@ -1055,9 +1055,9 @@ namespace MobileGL::MG_Record {
|
||||
const MG_Backend::GlobalBackendFunctionsTable* table = Table("bind_stream_output");
|
||||
if (table == nullptr) return false;
|
||||
// THE GL NAME IS THE ARGUMENT, NOT THE LifetimeId BESIDE IT. Espryt keys its driver
|
||||
// objects by the GL name (XfbImpl::g_xfbObjects[name], DirectGLES.cpp:1401) and creates
|
||||
// the ES object on first bind; passing the lifetime id would index a map that has never
|
||||
// heard of it and silently create a second driver object per bind. The lifetime id
|
||||
// objects by the applier's BoundStreamOutputLifetimeId, which is set just below, and not by
|
||||
// the GL name: XfbImpl::BindTransformFeedback (DirectGLESBuffers.cpp) ignores its argument
|
||||
// and creates the ES object on first bind. The lifetime id
|
||||
// identifies the P5f capture snapshot on this side. Keeping it separate preserves
|
||||
// the backend GL-name argument while Begin/End find the right server-owned span.
|
||||
MG_Pipe::MGPipeApplier().BoundStreamOutputLifetimeId = bind.LifetimeId;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// THE SNAPSHOT EXTENT IS EXACTLY WHAT THE RECORD DECLARED, NEVER WIDENED (the integrator's
|
||||
// ruling on b1's open M-6 half). Widening looked free once before and was not: a page-aligned
|
||||
// INVALIDATE_RANGE clobbered GPU-written data - an SSBO counter beside the app's SubData - with
|
||||
// stale shadow bytes (Managers.cpp:1126-1129). Tier 1's INVALIDATE_RANGE is an ASSERTION that
|
||||
// stale shadow bytes (FlushPendingRangesFrom, ManagersBuffers.cpp). Tier 1's INVALIDATE_RANGE is an ASSERTION that
|
||||
// the old bytes are dead, so declaring bytes covered that nothing staged is not a missing
|
||||
// optimisation, it is a silent data loss. The coverage set below is therefore exact, and a
|
||||
// drain that reaches outside it is Fatal rather than a re-read of whatever happens to be there.
|
||||
@@ -172,16 +172,17 @@ namespace MobileGL::MG_Record {
|
||||
if (it == m_shadows.end() || it->second.Bytes.data() != hostBase) return;
|
||||
if (CoverageHas(it->second.Covered, start, end)) return;
|
||||
// Verbatim what the MGLOG_F said, through the funnel that publishes it (P7 wave 0).
|
||||
MG_Pipe::MGPipeRecordFail(MG_Pipe::MGFatalFamily::StageSnapshotTooNarrow,
|
||||
"MGPipe: Fatal{StageSnapshotTooNarrow, \"%s\"} - the server's ladder wants "
|
||||
"[%zu, %zu) of a buffer whose staged coverage does not include it. Under "
|
||||
"split the authoritative shadow is SERVER-OWNED (rule C) and "
|
||||
"resource_subdata is the only way bytes reach it, so bytes outside a staged "
|
||||
"range have never existed on this side. Re-reading them would move zeroes "
|
||||
"into the store, and an INVALIDATE_RANGE over them would declare live "
|
||||
"GPU-written bytes dead (Managers.cpp:1126-1129). This is a missing record, "
|
||||
"not a missing widening",
|
||||
site, start, end);
|
||||
MG_Pipe::MGPipeRecordFail(
|
||||
MG_Pipe::MGFatalFamily::StageSnapshotTooNarrow,
|
||||
"MGPipe: Fatal{StageSnapshotTooNarrow, \"%s\"} - the server's ladder wants "
|
||||
"[%zu, %zu) of a buffer whose staged coverage does not include it. Under "
|
||||
"split the authoritative shadow is SERVER-OWNED (rule C) and "
|
||||
"resource_subdata is the only way bytes reach it, so bytes outside a staged "
|
||||
"range have never existed on this side. Re-reading them would move zeroes "
|
||||
"into the store, and an INVALIDATE_RANGE over them would declare live "
|
||||
"GPU-written bytes dead (FlushPendingRangesFrom, ManagersBuffers.cpp). This is a missing record, "
|
||||
"not a missing widening",
|
||||
site, start, end);
|
||||
}
|
||||
|
||||
// Diagnostics the unit cases read, so that a check can assert WHAT HAPPENED rather than
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// THE DEFECT THIS ENDS (T1/T5). resource_subdata's texture half stages the level bytes into
|
||||
// SEG_STAGE and ApplyTextureUpload (PipeApply.cpp) drops the pointer after the gate,
|
||||
// the accumulation and the serial. Espryt then re-reads the client's MipmapStorage at sync
|
||||
// time (Managers.cpp:6940, :7129, :7198, :7315), reads per-level shape off the client object
|
||||
// (:6928, :6936, :7314, :7332, DirectGLES.cpp:8502-8507, :8528-8529), and Magma WRITES the
|
||||
// time (ManagersTextureSync.cpp's SyncMipmapsToBackend), reads per-level shape off the client object
|
||||
// (the same function, and the depth and color Texture2D mipmap chains in DirectGLESCopy.cpp), and Magma writes the
|
||||
// client's level storage outright (VulkanRenderer's AllocateStorage +
|
||||
// MarkStorageDirty). In monolith every one of those is correct - the bytes belong to a
|
||||
// frontend object that outlives the call. Under split the pointer names SEG_STAGE, valid
|
||||
@@ -25,8 +25,8 @@
|
||||
// WHAT A KEY IS, AND WHY IT IS NOT THE TWIN ADDRESS THE CONTRACT'S FIRST DRAFT SAID.
|
||||
// CONTRACT-P5C §2.1 rules "keyed by the texture resource twin's address". The buffer half
|
||||
// keys by twin address because the twin is minted at sub-data time under split
|
||||
// (Managers.cpp:2139-2142) and GLESBufferResource's constructor is GL-free. The texture
|
||||
// twin's constructor is NOT: BackendTextureObject() calls glGenTextures (Managers.cpp:5496),
|
||||
// (Ops_H_SubData in ManagersBuffers.cpp) and GLESBufferResource's constructor is GL-free. The texture
|
||||
// twin's constructor is not: BackendTextureObject() in ManagersTextures.cpp calls glGenTextures,
|
||||
// so minting it at sub-data time would allocate a driver name for every texture that is
|
||||
// written and never drawn, and would put a GL call into a unit test that has no context
|
||||
// (R-16's unit case, StagedTextureStoreTest, exercises the REAL ops table headless). The
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace MobileGL::MG_Record {
|
||||
void MarkShaderStorageBindings(MG_State::GLState::GLContext* context) {
|
||||
if (!context) return;
|
||||
// The TOUCHED count, exactly as the backend twin uses it
|
||||
// (DirectGLES.cpp:559-560): the binding-point array is 84 entries wide and
|
||||
// (SyncBufferBindingPointsByRecord, DirectGLESBuffers.cpp): the binding-point array is 84 entries wide and
|
||||
// walking all of them on every draw is what the high-water mark exists to avoid.
|
||||
const SizeT points = context->GetTouchedBufferBindingPointCount(BufferTarget::ShaderStorage);
|
||||
for (SizeT i = 0; i < points; ++i) {
|
||||
@@ -63,7 +63,7 @@ namespace MobileGL::MG_Record {
|
||||
void MarkAtomicCounterBindings(MG_State::GLState::GLContext* context) {
|
||||
if (!context) return;
|
||||
// WIDER THAN ITS BACKEND TWIN, ON PURPOSE AND IN THE SAFE DIRECTION.
|
||||
// SyncAtomicCounterBuffers (DirectGLES.cpp:578-583) walks the GL bindings the
|
||||
// SyncAtomicCounterBuffers (DirectGLESBuffers.cpp) walks the GL bindings the
|
||||
// TRANSPILED program declared, which is a subset of what is bound; the client has
|
||||
// the bindings but not that per-program list at this point, so it marks every
|
||||
// touched atomic-counter point. Over-approximating costs a readback the narrowing
|
||||
@@ -102,7 +102,7 @@ namespace MobileGL::MG_Record {
|
||||
}
|
||||
|
||||
Bool ImageUnitIsAWritableBufferTexture(const ImageTextureBinding& binding) {
|
||||
// Verbatim from IsWritableImageBufferTexture (DirectGLES.cpp:2354-2357). All three
|
||||
// Verbatim from the backend's former IsWritableImageBufferTexture. All three
|
||||
// terms are client state; none of them is a driver question.
|
||||
return binding.Texture != nullptr && binding.Access != GL_READ_ONLY &&
|
||||
binding.Texture->GetStorageType() == TextureStorageType::Buffer;
|
||||
|
||||
@@ -86,10 +86,10 @@ namespace MobileGL::MG_Record {
|
||||
|
||||
// ---- the row predicates, exposed so a unit case can drive one row at a time -------
|
||||
|
||||
// Row 2's discriminator, verbatim from DirectGLES.cpp:2354-2357. It is a function rather
|
||||
// than three inline conditions at the call site because it is the one row whose backend
|
||||
// twin is narrow on purpose, and a client that re-derived it slightly wider would mark
|
||||
// read-only image bindings with nothing able to see that it had.
|
||||
// Row 2's discriminator, verbatim from the backend's former IsWritableImageBufferTexture (now
|
||||
// IsWritableImageBufferView, DirectGLESTextures.cpp). A function rather than three inline conditions, because
|
||||
// it is the one row whose backend twin is narrow on purpose, and a client that re-derived it slightly wider
|
||||
// would mark read-only image bindings with nothing able to see that it had.
|
||||
Bool ImageUnitIsAWritableBufferTexture(const MG_State::GLState::ImageTextureBinding& binding);
|
||||
|
||||
// The one place a row actually marks. Null and duplicate marks are absorbed here so the
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace MobileGL::MG_Record {
|
||||
const PixelStoreParameters& pack) {
|
||||
// SKIP_IMAGES (and IMAGE_HEIGHT) are NOT consulted: glReadPixels is a 2-D read and GL
|
||||
// ignores the image-level pack parameters for it, exactly as the monolith conversion
|
||||
// path does at DirectGLES.cpp:10905 (honorPackImageParams=false). A non-zero
|
||||
// path does in ReadPixels (DirectGLESReadback.cpp, honorPackImageParams=false). A non-zero
|
||||
// SkipImages therefore does not make the layout non-tight (codex 6).
|
||||
if (pack.SkipRows != 0 || pack.SkipPixels != 0) return false;
|
||||
if (pack.RowLength != 0 && pack.RowLength != width) return false;
|
||||
@@ -1344,7 +1344,7 @@ namespace MobileGL::MG_Record {
|
||||
// already validated them and already folds glTextureBarrier onto the same field
|
||||
// (GL_Drawing.cpp:920-937), and Espryt's atomic-counter lowering - the counter bit
|
||||
// implying the storage bit - stays inside the backend where the reason for it lives
|
||||
// (DirectGLES.cpp:8837). A client that pre-lowered would be answering a driver question
|
||||
// (LowerAtomicCounterBarrierBits). A client that pre-lowered would be answering a driver question
|
||||
// from the wrong side and the two arms would stop being byte-identical.
|
||||
//
|
||||
// No pre-verb hook: a barrier orders memory the GPU already holds. It starts no shader
|
||||
@@ -1417,8 +1417,8 @@ namespace MobileGL::MG_Record {
|
||||
void EmitShaderStorageBlockBinding(GLuint program, const GLchar* storageBlockName,
|
||||
GLuint storageBlockBinding) {
|
||||
VerbChannel session = ChannelFor("ShaderStorageBlockBinding");
|
||||
// The backend slot's own first line (DirectGLES.cpp:9201), kept here so a null name
|
||||
// never becomes a zero-size blob - which rule A forbids spelling at all.
|
||||
// The backend slot's own first line (ShaderStorageBlockBinding, DirectGLESCopy.cpp), kept
|
||||
// here so a null name never becomes a zero-size blob - which rule A forbids spelling at all.
|
||||
if (storageBlockName == nullptr) return;
|
||||
BeforeReadOnlyVerb();
|
||||
|
||||
@@ -1537,7 +1537,7 @@ namespace MobileGL::MG_Record {
|
||||
MG_Pipe::MGPStreamOutputBind record{};
|
||||
// THE GL NAME IS NOT AN IDENTITY (ARCHITECTURE 4.2.1) and is carried anyway, because
|
||||
// it is the key the backend has always used: Espryt indexes its driver objects by it
|
||||
// (XfbImpl::g_xfbObjects[name], DirectGLES.cpp:1401) and generates the ES object on
|
||||
// (XfbImpl::g_xfbObjects, DirectGLESBuffers.cpp) and generates the ES object on
|
||||
// first bind. Name 0 is the default object, which is why the field is not a handle.
|
||||
record.GlName = static_cast<Uint32>(name);
|
||||
// Beside it, the identity that WILL dispatch: the frontend's per-object lifetime id,
|
||||
@@ -1563,7 +1563,7 @@ namespace MobileGL::MG_Record {
|
||||
record.Value = static_cast<Int32>(value);
|
||||
// set_patch_state (43) STILL TRAVELS, at the next validate, and that is not a
|
||||
// duplicate: it is the applier's working-block copy, this is the driver push Espryt
|
||||
// does AT THE CALL (DirectGLES.cpp:8760), and both pushes happen today on the
|
||||
// does AT THE CALL (PatchParameteri, DirectGLESCopy.cpp), and both pushes happen today on the
|
||||
// monolith path too (CONTRACT-P5B.md §2 t2).
|
||||
session.EmitAndWait(MG_Pipe::MGPWireOp::PatchParameter, &record, sizeof(record),
|
||||
nullptr, 0, nullptr, 0, nullptr);
|
||||
@@ -1805,7 +1805,7 @@ namespace MobileGL::MG_Record {
|
||||
const Uint64 writtenPerRow = where.Columns * bytesPerPixel;
|
||||
// SKIP_IMAGES and IMAGE_HEIGHT ARE IGNORED (codex 6). glReadPixels is a 2-D read; GL
|
||||
// does not apply the image-level pack parameters to it, and the monolith conversion path
|
||||
// says so explicitly with honorPackImageParams=false (DirectGLES.cpp:10905). Applying
|
||||
// says so explicitly with honorPackImageParams=false (ReadPixels, DirectGLESReadback.cpp). Applying
|
||||
// SKIP_IMAGES here shifted a read with SKIP_IMAGES=1 by a whole image and overran an
|
||||
// application buffer sized for exactly `height` rows. Only SKIP_ROWS and SKIP_PIXELS -
|
||||
// the 2-D skips - offset the first written byte; the band's own row and column then
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
// has no store route to exercise.
|
||||
//
|
||||
// THE KNOB. MGITEST_ESPRYT_REFUSE_TEXTURE_READBACK_EXTENT=<w>x<h> is read BY THE ESPRYT SERVER
|
||||
// (WireTextureReadback.inc, ReadTextureImageWire): a colour level of exactly that extent is
|
||||
// (DirectGLESReadback.cpp, ReadTextureImageWire): a colour level of exactly that extent is
|
||||
// treated as a level the driver refused to attach - what a driver without EXT_texture_norm16 /
|
||||
// EXT_render_snorm does for these formats (an Adreno 750, which has both, reads them all back
|
||||
// through the GPU; measured in P13), and what llvmpipe can be made to do no other way. The
|
||||
|
||||
@@ -1848,8 +1848,8 @@ void main() { oColor = texture(uTex, vec2(4.0, 4.0)); }
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// 7. The program (ShaderCso). Espryt reaches a program's backend twin through
|
||||
// g_programTwinLookupMemo (DirectGLES.cpp:134-135), which is keyed on the frontend
|
||||
// 7. The program (ShaderCso). Espryt used to reach a program's backend twin through
|
||||
// g_programTwinLookupMemo (since removed), which was keyed on the frontend
|
||||
// ProgramObject; P4a re-keys it on the shader CSO's {slot, gen} and gives the program a
|
||||
// create_shader_state / delete_shader_state lifetime of its own.
|
||||
//
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
// Texture handle and only bit 10 populates the texture slot table, so a sampler subsystem
|
||||
// without it would miss every lookup and walk on without unbinding. The bring-up logs ONE
|
||||
// error naming BOTH bits, refuses bit 11 and runs the legacy sampler arm - modelled on the
|
||||
// bit-8-requires-bit-7 refusal that already ships (Managers.cpp:2393-2410). The assertion is
|
||||
// bit-8-requires-bit-7 refusal of ResolveVertexInputSubsystemArm (since removed). The assertion is
|
||||
// that the refusal is NAMED and that the run then produces the same pixels as any other
|
||||
// lane: a refusal that half-ran, or that aborted, would both be failures here.
|
||||
//
|
||||
@@ -617,8 +617,8 @@ void main() { oColor = texture(uTex, vUv); }
|
||||
"Samplers, Programs}, so this backend does not honour P4a's mask "
|
||||
"and cannot refuse a dependency inside it. D-K2's refusal lives "
|
||||
"in ResolveSamplersSubsystemArm() beside the bit-8-requires-bit-7 "
|
||||
"one that already ships (Managers.cpp:2393-2410), which is P4a "
|
||||
"package D's file; this control arms itself when that lands. The "
|
||||
"one ResolveVertexInputSubsystemArm made (since removed), in "
|
||||
"Managers.cpp; this control arms itself when that lands. The "
|
||||
"lane itself is not wasted: the library came up under 0x9ff, "
|
||||
"which on a tree with no P4a arm is P3a's mask plus one inert "
|
||||
"bit, and a mask that aborted a bring-up would have failed this "
|
||||
|
||||
+11
-11
@@ -33,7 +33,7 @@
|
||||
// A texture parameter's only public-GL observable is a SAMPLE - nothing about an attachment, an
|
||||
// image binding or a copy endpoint reads a swizzle or an aspect mode - and a sample puts the
|
||||
// texture on SyncNeccessaryTextures' UNIT list. That walk calls SyncTextureParamsToBackend for
|
||||
// every entry whose IsDrawSyncClean is false (DirectGLES.cpp:1896-1898), and IsDrawSyncClean is
|
||||
// every entry whose IsDrawSyncClean is false (DirectGLESTextures.cpp), and IsDrawSyncClean is
|
||||
// false whenever the frontend's parameter version has moved since the last sync
|
||||
// (Managers.h:1399-1416, `m_syncedTextureParamsVersion != paramsVersion`). So the very act of
|
||||
// observing the parameter repairs the state the observation was meant to catch: the gap between
|
||||
@@ -96,7 +96,7 @@
|
||||
// attachment of the DRAW framebuffer SyncNeccessaryTextures' FBO list -> synced
|
||||
// attachment of the READ framebuffer ONLY SyncCurrentFBO -> SyncToBackend ->
|
||||
// SyncAttachmentObject, which calls
|
||||
// SyncMipmapsToBackend at Managers.cpp:7161
|
||||
// SyncMipmapsToBackend (ManagersTextureSync.cpp)
|
||||
// and NOTHING ELSE -> NOT synced
|
||||
// bound to an image unit SyncImageTextureBinding ->
|
||||
// SyncTextureObjectToBackend, and
|
||||
@@ -105,8 +105,8 @@
|
||||
// a glCopyImageSubData endpoint MakeGLESCopyImageEndpoint ->
|
||||
// SyncTextureObjectToBackend -> synced
|
||||
//
|
||||
// SyncNeccessaryTextures' attachment list reads GetFramebufferBindingSlotChecked(Draw) only
|
||||
// (DirectGLES.cpp:1944), so a texture that is exclusively a READ attachment gets its STORAGE synced
|
||||
// SyncNeccessaryTextures' attachment list reads GetFramebufferBindingSlotChecked(Draw) only,
|
||||
// so a texture that is exclusively a READ attachment gets its STORAGE synced
|
||||
// and its PARAMETERS never. P4a closes that gap deliberately (D-E3): the record is addressed by
|
||||
// resource, and Espryt's SyncAttachmentObject applies parameters for ANY attachment, draw or read.
|
||||
// It is a behaviour change and it is the deliverable, not a drive-by dev fix (guide/discipline.md).
|
||||
@@ -197,8 +197,8 @@ void main() {
|
||||
if (Gl().BackendName() != "DirectGLES") {
|
||||
GTEST_SKIP() << "DirectGLES only: this scenario is about Espryt's own reachability "
|
||||
"table - SyncNeccessaryTextures' attachment list walks the DRAW "
|
||||
"slot only (DirectGLES.cpp:1944) and SyncAttachmentObject syncs "
|
||||
"storage and not parameters (Managers.cpp:7161). "
|
||||
"slot only and SyncAttachmentObject syncs "
|
||||
"storage (SyncMipmapsToBackend) and not parameters. "
|
||||
<< Gl().BackendName()
|
||||
<< " answers the same GL question through a different path, so a "
|
||||
"verdict here would be evidence about that backend rather than "
|
||||
@@ -532,7 +532,7 @@ void main() {
|
||||
// where the application asked for stencil, and the value that comes back is not the
|
||||
// stencil that was written. RecreateBackendTexture's own comment says exactly this -
|
||||
// "the mode makes it visible because falling back to the default silently samples the
|
||||
// wrong aspect rather than merely mis-filtering" (Managers.cpp:4826-4833).
|
||||
// wrong aspect rather than merely mis-filtering" (ManagersTextures.cpp).
|
||||
//
|
||||
// The framebuffer is bound to GL_READ_FRAMEBUFFER and the DRAW target is left on the
|
||||
// default framebuffer for the whole window, which is the ONE thing that separates this
|
||||
@@ -666,7 +666,7 @@ void main() {
|
||||
// 3. IMAGE UNIT ONLY, across a storage RE-MINT. Green today and green after, and the
|
||||
// reason it is green is the thing P4a must not lose: glBindImageTexture drives
|
||||
// RequireImageBindableStorage, which re-mints the storage in a possibly WIDENED carrier
|
||||
// and sets m_forceTextureParamsResync (Managers.cpp:4787) precisely because the
|
||||
// and sets m_forceTextureParamsResync (in RequireImageBindableStorageByHandle) precisely because the
|
||||
// frontend's parameter version does not move across that transition. A parameter sync
|
||||
// gated only on the frontend version would leave the driver at its defaults and sample
|
||||
// the carrier's surplus channels raw.
|
||||
@@ -713,7 +713,7 @@ void main() {
|
||||
"after its swizzle moved and its storage was re-minted"))
|
||||
<< "the swizzle did not survive the RequireImageBindableStorage re-mint. The re-mint "
|
||||
"creates a new driver texture at the ES defaults without moving the frontend's "
|
||||
"parameter version, so the forced resync (Managers.cpp:4787) is the only thing "
|
||||
"parameter version, so the forced resync (m_forceTextureParamsResync) is the only thing "
|
||||
"that puts the application's parameters back.";
|
||||
|
||||
GLuint cleanup = texture;
|
||||
@@ -721,8 +721,8 @@ void main() {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// 4. glCopyImageSubData ENDPOINT ONLY. Green today (MakeGLESCopyImageEndpoint calls
|
||||
// SyncTextureObjectToBackend, DirectGLES.cpp:7588) and green after. The endpoint is the
|
||||
// 4. glCopyImageSubData ENDPOINT ONLY. Green today (MakeGLESCopyImageEndpoint in DirectGLESCopy.cpp
|
||||
// calls SyncTextureObjectToBackend) and green after. The endpoint is the
|
||||
// DESTINATION, so the case also proves the copy itself still lands: a swizzled read of
|
||||
// the copied texel is only meaningful if the texel arrived.
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
// pin a shape for exactly the input the P3b/P4b work changed and say nothing about the input
|
||||
// it changed it for.
|
||||
//
|
||||
// DIRECTGLES ONLY. The server-side counters are Espryt's (Managers.cpp:6360-6395); Magma's upload
|
||||
// DIRECTGLES ONLY. The server-side counters are Espryt's (BackendTextureObject::SyncMipmapsToBackend); Magma's upload
|
||||
// path is P7 and contributes nothing to them, so a DirectVulkan lane would record a bracket of
|
||||
// zeroes and call it a shape.
|
||||
//
|
||||
@@ -118,7 +118,7 @@ namespace MGITest {
|
||||
// The original stride was x = ((i*7) % (kAtlasSize/kRectSize)) * kRectSize and the same
|
||||
// with 5 for y. Both are surjective onto 0..31 over 40 iterations (rect 9 lands at x=62,
|
||||
// rect 19 at y=62), so the rects' UNION BOX is the whole 64x64 level - and the server's
|
||||
// subRectEligible (Managers.cpp:8486-8491) requires !dirtyRegion.CoversWholeLevel, a
|
||||
// subRectEligible (ManagersTextureSync.cpp's SyncMipmapsToBackend) requires !dirtyRegion.CoversWholeLevel, a
|
||||
// BOUNDING-BOX test (MipmapStorage.h:30-33). Both scatter textures were therefore
|
||||
// rect-INELIGIBLE on every arm, before any policy about rect lists was consulted: the
|
||||
// box-versus-rect decision this scenario exists to pin was never reached, and the only
|
||||
@@ -161,7 +161,7 @@ namespace MGITest {
|
||||
// texels) is far under 3/4 of the union box - so neither the 2..maxRects test nor the
|
||||
// summedArea*4 >= unionArea*3 fallback takes the box arm. The record carries all thirty.
|
||||
//
|
||||
// THE SERVER DECIDES, and it decides BOX, at Managers.cpp:8649:
|
||||
// THE SERVER DECIDES, and it decides BOX, in ManagersTextureSync.cpp's SyncMipmapsToBackend:
|
||||
//
|
||||
// if (BufferImpl::UnpackRingAvailable()) dirtyRectCount = 0;
|
||||
//
|
||||
@@ -174,7 +174,7 @@ namespace MGITest {
|
||||
//
|
||||
// WHAT THE FIRST VERSION GOT WRONG, because the trap is easy to fall into twice: the
|
||||
// original scatter stride reached x=62 and y=62 in a 64-px atlas, so the union box
|
||||
// covered the whole level - and the server's subRectEligible (Managers.cpp:8486-8491)
|
||||
// covered the whole level - and the server's subRectEligible (ManagersTextureSync.cpp's SyncMipmapsToBackend)
|
||||
// requires !dirtyRegion.CoversWholeLevel, a BOUNDING-BOX test (MipmapStorage.h:30-33).
|
||||
// Both scatter textures were rect-INELIGIBLE before the ring policy was ever consulted,
|
||||
// so the gold looked identical while measuring something else entirely, and the only
|
||||
@@ -271,7 +271,8 @@ void main() { oColor = texture(uTex, vUv); }
|
||||
}
|
||||
if (Gl().BackendName() != "DirectGLES") {
|
||||
GTEST_SKIP() << "DirectGLES only: the upload-shape counters are Espryt's "
|
||||
"(Managers.cpp:6360-6395) and " << Gl().BackendName()
|
||||
"(SyncMipmapsToBackend in ManagersTextureSync.cpp) and "
|
||||
<< Gl().BackendName()
|
||||
<< " contributes nothing to them, so this lane would record a "
|
||||
"bracket of zeroes and call it a shape.";
|
||||
return;
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
/* It takes a content pointer today, but under split it CARRIES NO BYTES AT ALL: it is */ \
|
||||
/* a {range, AccessFlags} control record, and the bytes of [Offset, Offset+Size) arrive */ \
|
||||
/* AHEAD of it as resource_subdata records covering exactly that range. The ladder this */ \
|
||||
/* drives rewrites its range "from the authoritative shadow" (Managers.cpp:1047-1076), */ \
|
||||
/* drives rewrites its range "from the authoritative shadow" (FlushPendingRangesFrom), */ \
|
||||
/* and under split the authoritative shadow is server-owned (R-11), so subdata is the */ \
|
||||
/* only way bytes reach it - a blobref here would be a SECOND way to say the same thing. */ \
|
||||
X(ResourceFlushRange, MGPFlushRange, kCtxObject, kNone, kWaitNone) \
|
||||
|
||||
@@ -487,7 +487,7 @@ namespace MobileGL::MG_Remote::Client {
|
||||
// DeleteTransformFeedback is the one that stays: it has NO ROW in P5b, by ruling and
|
||||
// not by omission (unmeasured; the driver object leaks on the server until P9's XFB
|
||||
// namespace work, and a bind of name 0 is what the backend does on delete of the bound
|
||||
// one, DirectGLES.cpp:1422). It therefore still aborts by its own name.
|
||||
// one, XfbImpl::DeleteTransformFeedback in DirectGLESBuffers.cpp). It therefore still aborts by its own name.
|
||||
#define MGR_UNMIGRATED_T2_SLOTS(X)
|
||||
|
||||
#define MGR_UNMIGRATED_F1_SLOTS(X)
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace MobileGL::MG_Remote::Server {
|
||||
const MG_Backend::GlobalBackendFunctionsTable* table = Table("present");
|
||||
if (table == nullptr) return false;
|
||||
if (table->Present == nullptr) return false;
|
||||
// Present is the ONLY frame-boundary drain the backend has (DirectGLES.cpp:12424-12470:
|
||||
// Present is the ONLY frame-boundary drain the backend has (in DirectGLESSync.cpp it runs
|
||||
// the fence poll, the four ring OnPresent hooks, TrimBufferPool, PipeStats::OnPresent),
|
||||
// which is why ARCHITECTURE.md §14 wants present <-> eglSwapBuffers to stay 1:1.
|
||||
//
|
||||
|
||||
@@ -477,10 +477,10 @@ namespace MobileGL::MG_State::GLState {
|
||||
// mapped streaming arena behind a static VAO, there IS no next content record. The
|
||||
// only one is the block push, the push for a vertex/uniform/SSBO map runs inside
|
||||
// EnsureBufferResourceForHandle, and a draw-clean answer SKIPS that ensure
|
||||
// (DirectGLES.cpp:691) and then LATCHES it (:697, vboCleanEpoch - and a coherent
|
||||
// (SyncVaoAttributeBuffersByRecord in DirectGLESBind.cpp) and then LATCHES it (vboCleanEpoch - and a coherent
|
||||
// persistent map bumps no mutation epoch, which is its whole point). So: draw 1
|
||||
// pushes, draw 2 probes clean, draw 3 onward never probes again, and the frame draws
|
||||
// frame 1's bytes for ever with no diagnostic. That is Managers.cpp:2650-2655's
|
||||
// frame 1's bytes for ever with no diagnostic. That is IsBufferDrawCleanByHandle's
|
||||
// regression one layer down, and the rising-edge record is what breaks the cycle: the
|
||||
// server learns a host writer is live BEFORE the first probe, answers dirty while the
|
||||
// map lives, and the ensure - and with it the push - runs every draw.
|
||||
|
||||
@@ -91,8 +91,8 @@ TEST(ContextEpochTest, UnpackDefaultIsRepublishedForANewNativeContextOrRole) {
|
||||
}
|
||||
|
||||
// THE TRANSPORT-NATIVE ARM, which is the one a served context takes. DriverScope pins
|
||||
// TransportMode::InProcess, so GetRawDepthFetchSampler() returns early at DirectGLES.cpp:343 and
|
||||
// never reaches the monolith pair below it.
|
||||
// TransportMode::InProcess, and GetRawDepthFetchSampler() (DirectGLES.cpp) now has only this
|
||||
// native arm; the monolith pair that used to follow its early return is gone.
|
||||
TEST(ContextEpochTest, RawDepthSamplerOwnsANativeIdForEachContextGeneration) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
DriverScope scope;
|
||||
|
||||
@@ -164,7 +164,7 @@ TEST_F(SplitBufferSet, Row1EveryBoundAtomicCounterIsMarkedByADraw) {
|
||||
EXPECT_EQ(MG_Record::ProducerMarkCount(GpuWriteProducer::AtomicCounterBinding), 1u);
|
||||
}
|
||||
|
||||
// Row 2's DISCRIMINATOR - DirectGLES.cpp:2354-2357. This is the one row whose backend twin is
|
||||
// Row 2's DISCRIMINATOR - IsWritableImageBufferView (DirectGLESTextures.cpp). This is the one row whose backend twin is
|
||||
// narrow on purpose, so the narrowness is what the case is about: a GL_READ_ONLY image binding
|
||||
// must NOT be marked, or the next map waits on and re-reads a dispatch that cannot have changed
|
||||
// a byte of it.
|
||||
@@ -901,7 +901,7 @@ TEST(EsprytFlushLadder, ASmallPartialRangeFallsThroughToTheStagingRing) {
|
||||
"substituting pages, which is the whole reason tier 2 exists";
|
||||
}
|
||||
|
||||
// THE EDGE THAT HAS ALREADY DRAWN BLOOD (Managers.cpp:1125-1128): widening the map past the
|
||||
// THE EDGE THAT HAS ALREADY DRAWN BLOOD (FlushPendingRangesFrom, ManagersBuffers.cpp): widening the map past the
|
||||
// queued range clobbered GPU-written data - an SSBO counter beside the app's SubData - with
|
||||
// the stale shadow, SILENTLY. Under split the same shape arrives with a different cause: the
|
||||
// server may hold no pointer into the client's shadow (R-11), so `hostBase` becomes a
|
||||
|
||||
@@ -1039,9 +1039,9 @@ TEST_F(FieldOwnershipTest, TheUnpackHalfOfThePixelStoreAbortsWhileThePackHalfDoe
|
||||
EXPECT_EQ(ok.Log.find("Fatal{"), std::string::npos) << ok.Log;
|
||||
}
|
||||
|
||||
// One function edit, five call sites (Managers.cpp:5334, DirectGLES.cpp:8051, :8702, :8997,
|
||||
// :10623). The arm is the TRANSPORT, not the build: build-split's own lanes run monolith and
|
||||
// several of the five are on ordinary monolith paths they exercise.
|
||||
// One function edit, five call sites when this test was written ("texture-remint-pull", "generate-mipmap-storage",
|
||||
// "generate-mipmap-cpu-fallback", "copy-image-shadow-mirror", "get-tex-image-shadow"), all since removed. The arm
|
||||
// is the transport, not the build: build-split's own lanes run monolith and exercised several of the five.
|
||||
TEST_F(FieldOwnershipTest, AnUnmigratedEmulationIsFatalUnderARealTransportAndInertUnderMonolith) {
|
||||
const ChildResult monolith = RunInChild([] {
|
||||
MG_Config::Transport = MG_Config::TransportMode::Monolith;
|
||||
|
||||
@@ -1335,7 +1335,7 @@ TEST(TextureEmit, EveryDKTwoDependencyRowGatesItsOwnFamilyAndTheMirrorPairsStayL
|
||||
EXPECT_TRUE(emits(kMGPipeSubsystemPrograms));
|
||||
|
||||
// ---- THE MIRROR PAIRS, said out loud: an unreachable branch that says something different
|
||||
// is how the reachable one drifts (Managers.cpp:2377-2381's own words) ----
|
||||
// is how the reachable one drifts (words Managers.cpp's arm resolvers once used) ----
|
||||
// bits 10 + 11 without bit 9: FINE, and it is the 0xdff arm.
|
||||
MG_Config::Features.PipePush = kAll & ~kMGPipeSubsystemFramebuffer;
|
||||
EXPECT_TRUE(emits(kMGPipeSubsystemTextureResources));
|
||||
|
||||
@@ -4427,7 +4427,7 @@ TEST(DirectGLESBufferDrawProbe, UnderSplitTheRecordAloneAnswersTheLiveHostMapQue
|
||||
|
||||
EXPECT_TRUE(record.HasLiveHostWrites)
|
||||
<< "the map published nothing the server can see. Without it the probe below answers "
|
||||
"CLEAN, the ensure path is skipped and then latched (DirectGLES.cpp:691/:697), "
|
||||
"CLEAN, the ensure path is skipped and then latched (SyncVaoAttributeBuffersByRecord's vboCleanEpoch), "
|
||||
"SyncPersistentMappedRange is never reached again, and the frame draws the last "
|
||||
"uploaded bytes for ever with no diagnostic";
|
||||
|
||||
|
||||
@@ -1522,7 +1522,7 @@ TEST_F(PipeWireCodecTest, EndStreamOutputCarriesAllThreeAccountingFieldsAndNotJu
|
||||
TEST_F(PipeWireCodecTest, BindStreamOutputOfNameZeroIsTheDefaultObjectAndNotAnAbsentOne) {
|
||||
// THE ONE NAME t2 CANNOT TREAT AS "NOTHING". CONTRACT-P5B.md gives DeleteTransformFeedback
|
||||
// no row, and the backend's answer to deleting the bound object is a bind of NAME 0
|
||||
// (DirectGLES.cpp:1422) - so a row that folded 0 into kMGPipeNullHandle, or a sink that read
|
||||
// (XfbImpl::DeleteTransformFeedback) - so a row that folded 0 into kMGPipeNullHandle, or a sink that read
|
||||
// 0 as "no object", would silently stop rebinding the default object and leave the driver
|
||||
// bound to a deleted one. The lifetime id beside it is 0 too here, which is the frontend's
|
||||
// seed value for the default object, so this case also pins that a wholly-zero record is
|
||||
|
||||
@@ -1231,7 +1231,7 @@ TEST(RemoteReadback, TheTightRowsAreScatteredWhereThePackStateSaysAndTheGapsAreL
|
||||
TEST(RemoteReadback, PackSkipImagesIsIgnoredForATwoDimensionalRead) {
|
||||
// codex 6: SKIP_IMAGES (and IMAGE_HEIGHT) are image-level pack parameters and GL ignores
|
||||
// them for glReadPixels, a 2-D read - the monolith conversion path says so with
|
||||
// honorPackImageParams=false (DirectGLES.cpp:10905). The first cut applied SKIP_IMAGES as a
|
||||
// honorPackImageParams=false (ReadPixels, DirectGLESReadback.cpp). The first cut applied SKIP_IMAGES as a
|
||||
// whole-image offset: a 4x3 RGBA8 read with SKIP_IMAGES=1 wrote bytes 48..95 of a 96-byte
|
||||
// destination sized for one image, overrunning it. With the fix the reply lands at bytes
|
||||
// 0..47 and the second image's worth of bytes keeps its sentinel.
|
||||
|
||||
@@ -1103,7 +1103,7 @@ TEST(StagedShadowTest, ADrainOutsideTheStagedCoverageIsFatalByName) {
|
||||
|
||||
// M-1 / codex 8: the R-11 gate that drives the PRODUCTION path - the real resource op table
|
||||
// installed by RegisterBufferBackendOps, dispatched through MGPipeGetResourceOps()->SubData, i.e.
|
||||
// the exact Managers.cpp:2118 call site R-11 changed - and NOT StagedShadowStore in isolation.
|
||||
// the exact MGL_SERVER_STAGED_ADOPT call site in Ops_H_SubData - and not StagedShadowStore in isolation.
|
||||
// StagedShadowTest stays as the container test; this is the gate that goes red under the two
|
||||
// perturbations the reviewer used (restore `hostBytes = raw - offset`, neuter the coverage clamp).
|
||||
#if !defined(_WIN32)
|
||||
|
||||
@@ -32,7 +32,7 @@ import sys
|
||||
|
||||
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# `Managers.cpp:4340-4390`, `MobileGL/MG_State/.../RenderState.h:263`, `:12-13` is NOT
|
||||
# `File.cpp:123-456`, `MobileGL/MG_State/.../RenderState.h:263`, `:12-13` is NOT
|
||||
# matched on purpose: a citation with no file name cannot be checked, only guessed.
|
||||
CITATION_RE = re.compile(
|
||||
r"(?<![\w/.-])((?:[\w.-]+/)*[\w.-]+\.(?:h|hpp|cpp|cc|c|py|def|inc|md|json|yml|yaml|txt|fbs))"
|
||||
|
||||
@@ -58,7 +58,7 @@ prose is why that map reads the way it does.
|
||||
They carry their family word today, which is the point of widening the perimeter: the
|
||||
census can SEE them now, and the ratchet makes retiring one visible.
|
||||
(iii) NAMED, BUT NOT SESSION-SCOPED - Init.cpp's ConsumerMaskLie pair, MagmaPipeArms.h's and
|
||||
Managers.cpp's PipeLegacyMemosDisabled, DirectGLES.cpp:227's UnnamedIdentity,
|
||||
Managers.cpp's PipeLegacyMemosDisabled, DirectGLES.cpp's former UnnamedIdentity,
|
||||
PipeFill.cpp's PipeVerify knob parser. Startup and role self-checks that predate the
|
||||
split: they die BEFORE a session exists, so routing them through SessionFail would
|
||||
publish a SessionFault to a peer that has not connected. They are named, which is what
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#
|
||||
# 1. MGPSurface::Layered stops being copied in MG_Impl/Pipe/FramebufferEmit.h. A layered
|
||||
# attachment travels as a non-layered one, which is the shape that turns a whole-array render
|
||||
# target into slice 0 - and SupportsLayeredImageBinding's rule (DirectGLES.cpp:1992-2013,
|
||||
# target into slice 0 - and SupportsLayeredImageBinding's rule (DirectGLESTextures.cpp,
|
||||
# D-O) forces `layer` to 0 for a non-layerable target, so the wrong answer is silently
|
||||
# plausible rather than an error. It is also the field with the least other coverage: the
|
||||
# surface's Res, Level and Layer are all still right, so nothing about the ATTACHMENT changes
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
# UnpackRingAllocate Managers.cpp: on the hot upload route
|
||||
# RecomputeBackendColorSlots Managers.cpp: the attachment permutation - three passes plus the
|
||||
# forced ~0 version memo on every moved attachment; removing the
|
||||
# empty-point detach breaks the invariant (Managers.cpp:7651-7658)
|
||||
# empty-point detach breaks the invariant (SyncToBackendByHandle)
|
||||
# DepthStencilSamplingReadImpl DirectGLES.cpp: the D24S8 sampling-emulation core (memory
|
||||
# better-clouds-fullmode), entered from :8617 and :8721
|
||||
# better-clouds-fullmode), entered from its two Read*Native callers
|
||||
# ShouldUseCaveatTextureFormat Utils.cpp: the format handler P4a's InternalFormat descriptors
|
||||
# feed; a change here silently changes what every texture is
|
||||
# allocated as
|
||||
@@ -60,7 +60,7 @@
|
||||
# 1. A PER-REGION SOURCE PATH. The parent's SOURCE_PATH is a single file (:85); the seventeen live
|
||||
# in three. Each row below carries its own path and the extractor reads each file once.
|
||||
# 2. A REGION KIND. [declared deviation, see DEVIATIONS below] Sixteen of the seventeen are
|
||||
# FUNCTIONS. `DepthStencilSamplingReadImpl` is a NAMESPACE (DirectGLES.cpp:8117-8578) - the
|
||||
# FUNCTIONS. `DepthStencilSamplingReadImpl` is a NAMESPACE (in DirectGLESReadback.cpp) - the
|
||||
# brief's D-N table names it as though it were a function, and the parent's extractor, which
|
||||
# finds a definition as the one `<name> (` whose closing paren is followed by `{`, finds ZERO
|
||||
# definitions of it and exits 2 forever. Hashing the whole namespace block is also the
|
||||
@@ -330,7 +330,7 @@ def find_function(text, masked, name):
|
||||
def find_namespace(text, masked, name):
|
||||
"""Every (begin, end) at which `name` is DEFINED as a namespace.
|
||||
|
||||
P4a's DepthStencilSamplingReadImpl is a namespace, not a function (DirectGLES.cpp:8117-8578):
|
||||
P4a's DepthStencilSamplingReadImpl is a namespace, not a function (in DirectGLESReadback.cpp):
|
||||
the D24S8 sampling-emulation CORE is the whole block, and a function-shaped search finds no
|
||||
definition of it at all. The closing `} // namespace <name>` comment is masked away by the
|
||||
time this runs, so the extent is decided by brace matching exactly as a function's is - and a
|
||||
|
||||
Reference in New Issue
Block a user