mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
235 lines
17 KiB
Modula-2
235 lines
17 KiB
Modula-2
// MobileGL - MobileGL/MG_Pipe/Coverage.def
|
|
// Copyright (c) 2025-2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
// The hand-maintained half of G6 (plan B section 4.7, gate 10.3-5): which MGPipe call
|
|
// answers each backend read point in scripts/data/backend_read_inventory.md (477 rows, 57
|
|
// files, generated from the backends by MobileGL-CS's extract_backend_read_inventory.py).
|
|
//
|
|
// gen_pipe.py joins the inventory's `member` column against MGP_COVERAGE_ACCESSOR_LIST and
|
|
// its `delta` column against MGP_COVERAGE_DELTA_LIST, then writes generated/PipeCoverage.inc
|
|
// with the per-accessor table and prints the coverage summary. Rows matching neither are
|
|
// UNMAPPED: allowed in P0 and merely counted, ZERO from P5 onward, when the gate becomes
|
|
// "regenerate and git diff --exit-code with 0 UNMAPPED".
|
|
//
|
|
// Three pseudo-calls stand for read points that do NOT become a forward call:
|
|
// kClientResolved - the frontend answers it itself; the server is never asked
|
|
// (section 4.4.6: "the server answers nothing the client can answer").
|
|
// kReverseChannel - it becomes one of the ten MGPipeCallbacks (section 7.1).
|
|
// kStructuralHandle - the row is a SIGNATURE carrying SharedPtr<MG_State...>, which
|
|
// becomes an MGPipeHandle parameter; there is no single call to name.
|
|
//
|
|
// clang-format off
|
|
|
|
// X(Accessor, PipeCall)
|
|
#define MGP_COVERAGE_ACCESSOR_LIST(X) \
|
|
X(GetActiveTextureUnit, SetSamplerViews) \
|
|
X(GetBlendColor, SetDynamicState) \
|
|
X(GetBlendEquationIndexed, CreateRenderState) \
|
|
X(GetBlendFuncIndexed, CreateRenderState) \
|
|
/* dead: no backend reads it since D21; kept for inventory row 594 */ \
|
|
X(GetBoundTransformFeedbackName, SetStreamOutputTargets) \
|
|
X(GetBoundVertexArray, BindVertexElements) \
|
|
/* Polymorphic over BufferTarget, and P3a SPLITS it - not by re-vendoring the */ \
|
|
/* inventory (the extractor lives in MobileGL-CS and still does not carry the */ \
|
|
/* target argument), but by supplying the target from the EMISSION SITE, which */ \
|
|
/* knows it exactly. The split, target by target, in BufferTarget's OWN */ \
|
|
/* spelling (BufferObject.h:15-33) so the list cross-checks mechanically: */ \
|
|
/* Vertex, and the per-attribute buffer of a VAO -> set_vertex_buffers */ \
|
|
/* Index -> set_index_buffer */ \
|
|
/* DrawIndirect, Parameter -> set_indirect_buffers */ \
|
|
/* Uniform, ShaderStorage, AtomicCounter, */ \
|
|
/* TransformFeedback -> set_shader_buffers */ \
|
|
/* CopyRead, CopyWrite, PixelPack, PixelUnpack, */ \
|
|
/* Texture -> still pulled: the */ \
|
|
/* transfer and pixel-store targets have no call of their own yet; */ \
|
|
/* DispatchIndirect -> still pulled, and */ \
|
|
/* it is the one a reader most plausibly assumes set_indirect_buffers */ \
|
|
/* covers: BOTH backends read it (SyncBoundBuffer at every */ \
|
|
/* glDispatchComputeIndirect) and NO call carries it - MGPIndirectBuffers */ \
|
|
/* is the DrawIndirect + Parameter pair only - so the field stays the */ \
|
|
/* fill loop's for this target; */ \
|
|
/* Query -> still pulled: no */ \
|
|
/* backend reads it at all and no call names it. */ \
|
|
/* That is 15 of 15; a target missing from this list is a target a later */ \
|
|
/* phase would retire the pull for on the strength of a split that never */ \
|
|
/* covered it. */ \
|
|
/* THE ROW STAYS ONE ROW, and that is structural rather than a shortcut: this */ \
|
|
/* list IS the MGPipeInputField enum and the PipeInputs field set, and the */ \
|
|
/* field is ONE array (m_bufferBindingSlot[kBufferTargetCount]) that a second */ \
|
|
/* row of the same name could only duplicate. So the split lives here and in */ \
|
|
/* the emitters, and the row keeps naming set_indirect_buffers for the plan's */ \
|
|
/* explicit replacement of the DrawIndirect/Parameter pair. It is deliberately */ \
|
|
/* NOT in the EMITTED list below: seven targets above are still pulled, and a */ \
|
|
/* row there says "the whole field is supplied", which for this field would be */ \
|
|
/* the same half-truth GetPixelStoreParameters is kept out for. */ \
|
|
X(GetBufferBindingSlot, SetIndirectBuffers) \
|
|
X(GetBufferBindingPoint, SetShaderBuffers) \
|
|
X(GetBufferBindingPointCount, SetShaderBuffers) \
|
|
X(GetTouchedBufferBindingPointCount, SetShaderBuffers) \
|
|
X(GetClampReadColor, SetDynamicState) \
|
|
X(GetClearColor, SetDynamicState) \
|
|
X(GetClearDepth, SetDynamicState) \
|
|
X(GetClearStencil, SetDynamicState) \
|
|
X(GetColorMaskIndexed, CreateRenderState) \
|
|
X(GetCullFaceMode, CreateRenderState) \
|
|
X(GetCurrentVertexAttribute, SetVertexAttribDefaults) \
|
|
X(GetDepthFunc, CreateRenderState) \
|
|
X(GetDepthMask, CreateRenderState) \
|
|
X(GetDepthRangeIndexed, SetDynamicState) \
|
|
X(GetFramebufferBindingSlot, SetFramebufferState) \
|
|
X(GetImageTextureBinding, SetShaderImages) \
|
|
X(GetLineWidth, SetDynamicState) \
|
|
X(GetLogicOp, CreateRenderState) \
|
|
X(GetMaxTouchedTextureUnit, SetSamplerViews) \
|
|
X(GetMinSampleShadingValue, CreateRenderState) \
|
|
X(GetPatchDefaultInnerLevel, SetPatchState) \
|
|
X(GetPatchDefaultOuterLevel, SetPatchState) \
|
|
X(GetPatchVertices, SetPatchState) \
|
|
X(GetPipelineStateVersion, BindRenderState) \
|
|
X(GetPixelStoreParameters, SetPixelPackState) \
|
|
X(GetPolygonModeFront, CreateRenderState) \
|
|
X(GetPolygonOffsetFactor, SetDynamicState) \
|
|
X(GetPolygonOffsetUnits, SetDynamicState) \
|
|
X(GetPrimitiveRestartIndex, DrawVbo) \
|
|
X(GetProgramForDispatch, SetDispatchProgram) \
|
|
X(GetProgramForDraw, SetDrawProgram) \
|
|
X(GetProgramObject, CreateShaderState) \
|
|
/* ANSWERED by P2: it is in the pipeline half. SetProvokingVertexMode calls */ \
|
|
/* BumpVersions(), and the chunk table's rule is exactly that, so it rides */ \
|
|
/* pipeline chunk P4 - a strict superset of what ComputePipelineStateHash used */ \
|
|
/* to hash (MGPipeRenderStateSpans.cpp records the provenance). */ \
|
|
X(GetProvokingVertexMode, CreateRenderState) \
|
|
X(GetRenderStateParameters, CreateRenderState) \
|
|
X(GetRenderStateParametersVersion, BindRenderState) \
|
|
X(GetSamplingResolutionGeneration, SetSamplerViews) \
|
|
X(GetScissorBox, SetDynamicState) \
|
|
X(GetStencilState, CreateRenderState) \
|
|
X(GetTextureBindGeneration, SetSamplerViews) \
|
|
X(GetTextureContextId, SetSamplerViews) \
|
|
X(GetTextureObject, SetSamplerViews) \
|
|
X(GetTextureUnitObject, SetSamplerViews) \
|
|
X(GetTransformFeedbackCapturedVertices, DrawVbo) \
|
|
X(GetTransformFeedbackGeneration, SetStreamOutputTargets) \
|
|
X(GetTransformFeedbackPausedPrimitiveCounter, EndStreamOutput) \
|
|
X(GetTransformFeedbackProgram, SetStreamOutputTargets) \
|
|
X(GetViewport, SetDynamicState) \
|
|
X(GetViewportIndexed, SetDynamicState) \
|
|
X(IsCapabilityEnabled, CreateRenderState) \
|
|
X(IsCapabilityEnabledIndexed, CreateRenderState) \
|
|
X(IsTransformFeedbackActive, BeginStreamOutput) \
|
|
X(IsTransformFeedbackPaused, PauseStreamOutput) \
|
|
X(InvalidateCompileEnv, kClientResolved) \
|
|
X(ValidateProgramName, kClientResolved) \
|
|
X(RecordError, kReverseChannel) \
|
|
/* The D21 XFB counter-slot rekey's reads (VulkanRenderer.cpp); the calls they */ \
|
|
/* map to are GetTransformFeedbackGeneration's. */ \
|
|
X(GetBoundTransformFeedbackLifetimeId, SetStreamOutputTargets) \
|
|
X(HasOpenTransformFeedbackSpan, SetStreamOutputTargets)
|
|
|
|
// X(Accessor, Reason) - the STICKY fields (P1 brief D6): the only PipeInputs fields whose
|
|
// value is valid across verbs, so the poison's per-verb generation does not apply to them.
|
|
// Exactly the seven F-class (forwarded) accessors, and the argument for each is the same:
|
|
// it takes an argument that is not verb state - a GL name, a lifetime id, a target - i.e.
|
|
// it is a lookup or a reverse-channel write, not a state read; there is no value the
|
|
// filler could copy and no verb whose fill could make it stale; phase C replaces them
|
|
// with handle tables and callbacks. None of the version/generation accessors is sticky:
|
|
// those change under verbs and are precisely what the poison must protect. The verify
|
|
// lane's Fatal{UnmigratedPipeInput} is fixed by a FillPoints.def row, never by a row here.
|
|
// gen_pipe.py refuses a name that is not an accessor above.
|
|
#define MGP_COVERAGE_STICKY_LIST(X) \
|
|
X(GetBufferBindingPointCount, "keyed by target: a constexpr capacity table, not verb state") \
|
|
X(GetProgramObject, "keyed by GL name: an object lookup, not verb state") \
|
|
X(GetTextureObject, "keyed by GL name: an object lookup, not verb state") \
|
|
X(HasOpenTransformFeedbackSpan, "keyed by lifetime id: an object lookup, not verb state") \
|
|
X(ValidateProgramName, "keyed by GL name: a name-table lookup, not verb state") \
|
|
X(InvalidateCompileEnv, "reverse channel: a write into the frontend, not a state read") \
|
|
X(RecordError, "reverse channel: a write into the frontend, not a state read")
|
|
|
|
// X(DeltaKind, PipeCall) - for inventory rows with no accessor in the member column.
|
|
// Read by gen_pipe.py ONLY, never by the C++ preprocessor: the delta kinds are the
|
|
// inventory's own free-text labels, not C tokens.
|
|
#define MGP_COVERAGE_DELTA_LIST(X) \
|
|
X(handle-ify (wire handle), kStructuralHandle) \
|
|
X(Buffer ops delta, ResourceRespecify)
|
|
|
|
// X(Accessor, PipeCall) - the EMITTED list (P2 brief D5): which P2 call now SUPPLIES this
|
|
// PipeInputs field, so the per-verb residual fill loop no longer has to pull it out of
|
|
// GLContext. gen_pipe.py turns it into kMGPipeFieldEmittedBy[] (generated/PipeFilled.inc);
|
|
// a field with no row here keeps going through the fill loop, which is what makes the
|
|
// MOBILEGL_PIPE_PUSH bitmask a true per-subsystem A/B rather than an all-or-nothing switch.
|
|
//
|
|
// Every name must be an accessor in MGP_COVERAGE_ACCESSOR_LIST and every call must be a
|
|
// real call in PipeCalls.def; gen_pipe.py refuses anything else.
|
|
//
|
|
// The one row whose call differs from the accessor list's is GetPrimitiveRestartIndex:
|
|
// coverage maps it onto draw_vbo because that is where a backend reads it, but the VALUE
|
|
// travels in dynamic chunk D6, so set_dynamic_state is what supplies it.
|
|
//
|
|
// GetPixelStoreParameters is DELIBERATELY ABSENT, and the reason is the shape of the field
|
|
// rather than of the call. The field is PipeInputs::m_pixelStore[2] - pack AND unpack - and
|
|
// set_pixel_pack_state carries the PACK half only, deliberately and permanently (D10,
|
|
// ARCHITECTURE.md 4.6 D5: nothing on the far side of the boundary reads unpack state). A row
|
|
// here says "this field is supplied, the fill loop may skip it", which would be a half-truth:
|
|
// the moment the render-state bitmask has its bit set, the unpack half would be written by
|
|
// nothing while its poison stamp said it was published, so neither the poison nor the verify
|
|
// comparator could see it. Until the field is split, the whole of it keeps going through the
|
|
// fill loop and the pack half is simply written twice.
|
|
//
|
|
// P3a ADDS ONE ROW, GetBoundVertexArray -> BindVertexElements, and it is the vertex-input
|
|
// family's only candidate: GetBufferBindingSlot is polymorphic over a target set P3a covers
|
|
// only part of (see its comment above) and GetCurrentVertexAttribute has been here since P2.
|
|
// The row is INERT until the vertex-input subsystem is wired - MG_Impl/Pipe/PipeFill.cpp's
|
|
// kMGPipeWiredSubsystems does not carry that bit at the contract commit, because the emitters
|
|
// beside it are still stubs - which is exactly the guard that lets a row land before the call
|
|
// that carries it exists.
|
|
//
|
|
// A NOTE FOR THE COMMIT THAT WIRES IT, because it is not visible from this file: the field is
|
|
// a shared pointer to the frontend VAO, and the vertex-input calls supply the CONFIGURATION
|
|
// (the applier's MGPipeVertexElementsRecord), not the object. So the row is shape-only in the
|
|
// same sense GetCurrentVertexAttribute's is, and it stays so until the backend's twin
|
|
// resolution reads the applier's BoundVertexElements instead of the object - at which point
|
|
// PipeFill.cpp's EmittedCallSuppliesTheWholeField arm is where that is decided, deliberately
|
|
// rather than silently by this row's presence.
|
|
#define MGP_COVERAGE_EMITTED_LIST(X) \
|
|
X(GetBlendColor, SetDynamicState) \
|
|
X(GetBlendEquationIndexed, CreateRenderState) \
|
|
X(GetBlendFuncIndexed, CreateRenderState) \
|
|
X(GetBoundVertexArray, BindVertexElements) \
|
|
X(GetClampReadColor, SetDynamicState) \
|
|
X(GetClearColor, SetDynamicState) \
|
|
X(GetClearDepth, SetDynamicState) \
|
|
X(GetClearStencil, SetDynamicState) \
|
|
X(GetColorMaskIndexed, CreateRenderState) \
|
|
X(GetCullFaceMode, CreateRenderState) \
|
|
X(GetCurrentVertexAttribute, SetVertexAttribDefaults) \
|
|
X(GetDepthFunc, CreateRenderState) \
|
|
X(GetDepthMask, CreateRenderState) \
|
|
X(GetDepthRangeIndexed, SetDynamicState) \
|
|
X(GetLineWidth, SetDynamicState) \
|
|
X(GetLogicOp, CreateRenderState) \
|
|
X(GetMinSampleShadingValue, CreateRenderState) \
|
|
X(GetPatchDefaultInnerLevel, SetPatchState) \
|
|
X(GetPatchDefaultOuterLevel, SetPatchState) \
|
|
X(GetPatchVertices, SetPatchState) \
|
|
X(GetPipelineStateVersion, BindRenderState) \
|
|
X(GetPolygonModeFront, CreateRenderState) \
|
|
X(GetPolygonOffsetFactor, SetDynamicState) \
|
|
X(GetPolygonOffsetUnits, SetDynamicState) \
|
|
X(GetPrimitiveRestartIndex, SetDynamicState) \
|
|
X(GetProvokingVertexMode, CreateRenderState) \
|
|
X(GetRenderStateParameters, CreateRenderState) \
|
|
X(GetRenderStateParametersVersion, BindRenderState) \
|
|
X(GetScissorBox, SetDynamicState) \
|
|
X(GetStencilState, CreateRenderState) \
|
|
X(GetViewport, SetDynamicState) \
|
|
X(GetViewportIndexed, SetDynamicState) \
|
|
X(IsCapabilityEnabled, CreateRenderState) \
|
|
X(IsCapabilityEnabledIndexed, CreateRenderState)
|
|
|
|
// clang-format on
|