mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Test] (P13 W3b): a GL-level successor for the borrowed-slot unit-memo probe
This commit is contained in:
@@ -172,6 +172,8 @@ add_executable(MobileGLIntegrationTest
|
||||
Scenarios/CsoContentAddressingScenario.cpp
|
||||
Scenarios/ResourceSubsystemControlScenario.cpp
|
||||
Scenarios/TextureParamsWithoutASamplerViewScenario.cpp
|
||||
# P13 W3b: the GL-level successor of the borrowed-slot unit-memo probe.
|
||||
Scenarios/DsaUpdateKeepsTheBoundUnitScenario.cpp
|
||||
Scenarios/TextureUploadShapeScenario.cpp
|
||||
Scenarios/ObjectSubsystemControlScenario.cpp
|
||||
Scenarios/P4aSeamAuditScenario.cpp
|
||||
@@ -1461,7 +1463,7 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
ENVIRONMENT "${MGL_ITEST_GLES_RESOURCE_SUBSYSTEM_ON_ENVIRONMENT}"
|
||||
)
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.ResourceSubsystemControl.Off.RefusedAtStartup" "0x7f" "ResourceSubsystemControlScenario.*"
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.SubsystemMaskRefusal.ResourceSubsystemControlOff" "0x7f" "ResourceSubsystemControlScenario.*"
|
||||
"${MGL_ITEST_GLES_RESOURCE_SUBSYSTEM_OFF_ENVIRONMENT}")
|
||||
|
||||
# G10's two counting entries, one per scenario that has a claim about the counter:
|
||||
@@ -1536,7 +1538,7 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
ENVIRONMENT "${MGL_ITEST_GLES_ARENA_SUBSYSTEM_ON_ENVIRONMENT}"
|
||||
)
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.ResourceSubsystemOff.RefusedAtStartup" "0x7f" "LargeArenaAdoptionScenario.*"
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.SubsystemMaskRefusal.ResourceSubsystemOff" "0x7f" "LargeArenaAdoptionScenario.*"
|
||||
"${MGL_ITEST_GLES_ARENA_SUBSYSTEM_OFF_ENVIRONMENT}")
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectVulkan.ArenaArm."
|
||||
@@ -1646,11 +1648,11 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
TIMEOUT ${MGL_ITEST_TIMEOUT}
|
||||
ENVIRONMENT "${MGL_ITEST_GLES_OBJECT_SUBSYSTEM_ON_ENVIRONMENT}"
|
||||
)
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.ObjectSubsystemControl.Off.RefusedAtStartup" "0x1ff" "ObjectSubsystemControlScenario.ClearingTheP4aBitsStopsTheEmissionsAndNotThePixels"
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.SubsystemMaskRefusal.ObjectSubsystemControlOff" "0x1ff" "ObjectSubsystemControlScenario.ClearingTheP4aBitsStopsTheEmissionsAndNotThePixels"
|
||||
"${MGL_ITEST_GLES_OBJECT_SUBSYSTEM_OFF_ENVIRONMENT}")
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.ObjectSubsystemControl.Refused.RefusedAtStartup" "0x9ff" "ObjectSubsystemControlScenario.ASamplerBitWithoutTheTextureBitIsRefusedAndNamed"
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.SubsystemMaskRefusal.ObjectSubsystemControlRefused" "0x9ff" "ObjectSubsystemControlScenario.ASamplerBitWithoutTheTextureBitIsRefusedAndNamed"
|
||||
"${MGL_ITEST_GLES_OBJECT_SUBSYSTEM_REFUSED_ENVIRONMENT}")
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.ObjectSubsystemControl.RefusedTexture.RefusedAtStartup" "0x5ff" "ObjectSubsystemControlScenario.ATextureBitWithoutTheSamplerBitIsRefusedAndNamed"
|
||||
mgl_itest_add_refused_mask_control("DirectGLES.SubsystemMaskRefusal.ObjectSubsystemControlRefusedTexture" "0x5ff" "ObjectSubsystemControlScenario.ATextureBitWithoutTheSamplerBitIsRefusedAndNamed"
|
||||
"${MGL_ITEST_GLES_OBJECT_SUBSYSTEM_REFUSED_TEXTURE_ENVIRONMENT}")
|
||||
gtest_discover_tests(MobileGLIntegrationTest
|
||||
TEST_PREFIX "DirectGLES.ObjectSubsystemControl.Consumer."
|
||||
|
||||
@@ -42,6 +42,7 @@ set(MGL_P8A_AMBIENT_CASES
|
||||
DepthStencilReadbackAttachmentShapeScenario.PackedArrayLayerAttachmentReadsBackBothAspects
|
||||
DepthStencilReadbackScenario.*
|
||||
DoublePrecisionScenario.*
|
||||
DsaUpdateKeepsTheBoundUnitScenario.*
|
||||
DualSourceBlendScenario.*
|
||||
EmptyScissorScenario.*
|
||||
F1WireScenario.ColorBlitToDefaultFromANonSampleableSourceDegrades
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
// MobileGL - MobileGL/MG_IntegrationTest/Scenarios/DsaUpdateKeepsTheBoundUnitScenario.cpp
|
||||
// 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
|
||||
//
|
||||
// Scenario - A BY-NAME (DSA) UPDATE OF TEXTURE B DOES NOT RETARGET THE UNIT THAT HOLDS TEXTURE A.
|
||||
//
|
||||
// GL 4.6 core 8.1/8.5: glTextureSubImage2D / glTextureStorage2D name their texture directly and
|
||||
// change no binding. So with A bound to unit 0, a by-name update of B must leave every later draw
|
||||
// that samples unit 0 sampling A - A's texels and A's shape.
|
||||
//
|
||||
// The regression this guards (P13 W3b; it used to be the white-box SanityTest probe
|
||||
// DirectGLESTextureSync.UnitMemoRefusesToDriveATwinFromAnotherTexture): Espryt's per-unit texture
|
||||
// sync list on the monolith arm BORROWS a pointer into the frontend binding slot and replays it on
|
||||
// the next draw. A by-name emulation that swapped the slot behind the binding accounting left the
|
||||
// replay driving A's backend twin from B's frontend object, so A's storage was respecified with
|
||||
// B's shape and its GPU-only contents were lost (Iris/BSL: the 16x16 lightmap blanked when a
|
||||
// 2048x2048 shadow map was uploaded by name, and the HUD text discarded itself). The probe ran only
|
||||
// at the P2 subsystem mask, whose legacy unit arm is gone; this asserts the same thing through
|
||||
// public GL, on every lane and on both backends, at the shipping mask.
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../Harness/HeadlessGL.h"
|
||||
#include "../Harness/ScenarioFixture.h"
|
||||
|
||||
#ifdef GLAPI
|
||||
#undef GLAPI
|
||||
#endif
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glcorearb.h>
|
||||
#undef GL_GLEXT_PROTOTYPES
|
||||
|
||||
namespace MGITest {
|
||||
namespace {
|
||||
|
||||
constexpr int kInset = 2;
|
||||
constexpr int kSmall = 4; // A: the lightmap
|
||||
constexpr int kLarge = 32; // B: the shadow map
|
||||
|
||||
constexpr const char* kQuadVS = R"(#version 330 core
|
||||
in vec2 aPos;
|
||||
out vec2 vUv;
|
||||
void main() {
|
||||
vUv = aPos * 0.5 + 0.5;
|
||||
gl_Position = vec4(aPos, 0.0, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
// texelFetch at the texture's own last texel: a texture whose shape moved to B's would
|
||||
// fetch a different texel, and one whose contents moved would fetch B's colour.
|
||||
constexpr const char* kFetchFS = R"(#version 330 core
|
||||
uniform sampler2D uTex;
|
||||
out vec4 oColor;
|
||||
void main() {
|
||||
ivec2 size = textureSize(uTex, 0);
|
||||
oColor = (size == ivec2(4, 4)) ? texelFetch(uTex, size - ivec2(1, 1), 0) : vec4(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
struct Vertex {
|
||||
float x, y;
|
||||
};
|
||||
|
||||
std::vector<std::uint8_t> Solid(int size, std::uint8_t r, std::uint8_t g, std::uint8_t b) {
|
||||
std::vector<std::uint8_t> texels(static_cast<std::size_t>(size) * size * 4);
|
||||
for (std::size_t i = 0; i < texels.size(); i += 4) {
|
||||
texels[i] = r;
|
||||
texels[i + 1] = g;
|
||||
texels[i + 2] = b;
|
||||
texels[i + 3] = 255;
|
||||
}
|
||||
return texels;
|
||||
}
|
||||
|
||||
class DsaUpdateKeepsTheBoundUnitScenario : public ScenarioTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ScenarioTest::SetUp();
|
||||
if (!Ready()) return;
|
||||
std::string error;
|
||||
m_program = CompileProgram(kQuadVS, kFetchFS, &error);
|
||||
ASSERT_NE(m_program, 0u) << error;
|
||||
static const Vertex quad[6] = {{-1.0f, -1.0f}, {1.0f, -1.0f}, {1.0f, 1.0f},
|
||||
{-1.0f, -1.0f}, {1.0f, 1.0f}, {-1.0f, 1.0f}};
|
||||
glGenBuffers(1, &m_quad);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_quad);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
|
||||
glBindVertexArray(0);
|
||||
ASSERT_EQ(FirstGLError(), GLenum(GL_NO_ERROR)) << "the scene setup left a GL error behind";
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
if (!Ready() || IsSkipped()) return;
|
||||
glUseProgram(0);
|
||||
glBindVertexArray(0);
|
||||
if (m_vao != 0) glDeleteVertexArrays(1, &m_vao);
|
||||
if (m_quad != 0) glDeleteBuffers(1, &m_quad);
|
||||
if (m_program != 0) glDeleteProgram(m_program);
|
||||
}
|
||||
|
||||
// The classic path for A, on purpose: it is BOUND to unit 0 and sampled through the
|
||||
// binding, which is what puts it on the per-unit list the hazard lived in.
|
||||
GLuint MakeBoundTexture(int size, std::uint8_t r, std::uint8_t g, std::uint8_t b) {
|
||||
const auto texels = Solid(size, r, g, b);
|
||||
GLuint texture = 0;
|
||||
glGenTextures(1, &texture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, texels.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Samples whatever unit 0 holds now - no bind here, the unit is the subject.
|
||||
Image DrawSamplingUnitZero() {
|
||||
BindDefaultFramebuffer();
|
||||
glViewport(0, 0, Gl().Width(), Gl().Height());
|
||||
ClearTo(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glUseProgram(m_program);
|
||||
glUniform1i(glGetUniformLocation(m_program, "uTex"), 0);
|
||||
glBindVertexArray(m_vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
const Image image = ReadPixels(Gl().Width(), Gl().Height());
|
||||
Gl().EndFrame();
|
||||
return image;
|
||||
}
|
||||
|
||||
::testing::AssertionResult WholeViewportIs(const Image& image, const char* expected,
|
||||
const std::string& when) {
|
||||
return RegionIsMostly(image, kInset, image.Width() - kInset, kInset,
|
||||
image.Height() - kInset, expected, 0.0, when);
|
||||
}
|
||||
|
||||
GLuint m_program = 0;
|
||||
GLuint m_quad = 0;
|
||||
GLuint m_vao = 0;
|
||||
};
|
||||
|
||||
TEST_F(DsaUpdateKeepsTheBoundUnitScenario, AByNameUploadToAnotherTextureLeavesTheUnitsTextureIntact) {
|
||||
if (!Ready()) return;
|
||||
GLuint probe = 0;
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &probe);
|
||||
if (FirstGLError() != GLenum(GL_NO_ERROR) || probe == 0) {
|
||||
GTEST_SKIP() << "glCreateTextures is not usable here; the case needs a by-name update";
|
||||
}
|
||||
glDeleteTextures(1, &probe);
|
||||
|
||||
// B first, then unbound: it exists but holds no unit.
|
||||
const GLuint b = MakeBoundTexture(kSmall, 0, 0, 255);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// A on unit 0, sampled once so the unit's sync list is built and memoised.
|
||||
const GLuint a = MakeBoundTexture(kSmall, 255, 0, 0);
|
||||
EXPECT_TRUE(WholeViewportIs(DrawSamplingUnitZero(), "red", "A sampled through unit 0"));
|
||||
|
||||
// THE HAZARD: B respecified to a different shape and filled BY NAME while A stays bound.
|
||||
const auto large = Solid(kLarge, 0, 255, 0);
|
||||
// (glTextureStorage2D on a mutable texture is legal and makes it immutable at the new shape.)
|
||||
glTextureStorage2D(b, 1, GL_RGBA8, kLarge, kLarge);
|
||||
glTextureSubImage2D(b, 0, 0, 0, kLarge, kLarge, GL_RGBA, GL_UNSIGNED_BYTE, large.data());
|
||||
EXPECT_EQ(FirstGLError(), GLenum(GL_NO_ERROR));
|
||||
|
||||
EXPECT_TRUE(WholeViewportIs(DrawSamplingUnitZero(), "red",
|
||||
"unit 0 after a by-name update of ANOTHER texture: it must still sample A "
|
||||
"(magenta = A took B's shape, green = A took B's texels)"));
|
||||
|
||||
// And the update itself landed where it was addressed.
|
||||
GLint bound = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound);
|
||||
EXPECT_EQ(static_cast<GLuint>(bound), a) << "a by-name update moved the unit's binding";
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTextures(1, &a);
|
||||
glDeleteTextures(1, &b);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace MGITest
|
||||
@@ -14,9 +14,10 @@ them wrong.
|
||||
| 2026-10-06 | `build explicit pull runtime control` (the pull `libMobileGL.so`, `-DMOBILEGL_PIPE_PUSH=OFF`) | Test / `build-linux-monolith-control` | P13 W2 retires the pull build: CMake defaults to push and nothing ships pull (ID-P13-1) | the same job builds the push monolith without MG_Remote (the FCL shape); its `runtime_mode_proof --mode monolith` is the zero-MG_Remote-symbol check |
|
||||
| 2026-10-06 | `Negative control (pull library)` | Test / `retrace-split` (every leg) | its library was the pull build above | `Negative control (library without a transport)`: same script (renamed `retrace_transport_control.sh`) and evidence sentence, with the push library without MG_Remote; W1 ran both side by side on every leg |
|
||||
| 2026-10-06 | `DirectGLES.HandleRecycle.Legacy.*`, `DirectVulkan.HandleRecycle.Legacy.*`, `DirectVulkan.HandleRecycle.AbaControl.*` | Test / integration-gpu (`integration-monolith-control`) | they ran `MOBILEGL_PIPE_PUSH=0`, the pre-handle arm, which P13 W3b removed with `MOBILEGL_PIPE_LEGACY_MEMOS` (ID-P13-3) | `HandleRecycle.Handles.*` and `DirectVulkan.HandleRecycle.AbaControlHandles.*` (the ABA control against the handle arm that ships) stay |
|
||||
| 2026-10-06 | `DirectGLES.ResourceSubsystemControl.Off.*`, `DirectGLES.ResourceSubsystemOff.*`, `DirectGLES.ObjectSubsystemControl.{Off,Refused,RefusedTexture}.*` | Test / integration-gpu | they cleared subsystem bits (masks 0x7f / 0x1ff / 0x9ff / 0x5ff) to run legacy arms; since W3b bits 0-13 are fixed on (ID-P13-3) | one named-refusal control per lane, `<lane>.RefusedAtStartup`: the same scenario and mask must go red with `Fatal{PipeSubsystemsFixedOn}` naming that mask (`Harness/RefusedMaskControl.cmake`); the `On` lanes now run 0x3fff |
|
||||
| 2026-10-06 | `SanityTest`: `DirectGLESSlotTable.{AnArmlessKnobCombinationStopsInsteadOfSkippingTheLane, TheArmlessCasesLeaveTheLogPathAndTheConfigAsTheyFoundThem, EglBringUpUnderTheArmlessKnobPairReturnsInsteadOfStopping}` | Test / unit | they pinned the `MOBILEGL_PIPE_LEGACY_MEMOS=0` + cleared-bit knob pair; the knob is gone and the mask is refused at startup | the RefusedAtStartup controls above |
|
||||
| 2026-10-06 | `SanityTest`: `DirectGLESTextureSync.{UnitMemoRefusesToDriveATwinFromAnotherTexture, AnAttachmentOnlyTexturesParametersReachTheDriverWithNoSamplerView}` | Test / unit | white-box probes that only ever ran at the P2 mask (0x7f): the borrowed-slot unit memo and the pre-handle texture-parameter push; both arms are gone with the legacy memos, and at the shipping mask the fixture cannot produce the applier records the handle arm reads | `DirectGLESTextureSync`'s handle-arm ABA sibling (P5e tx2) and `TextureParamsWithoutASamplerViewScenario` (G9, every lane) |
|
||||
| 2026-10-06 | `DirectGLES.ResourceSubsystemControl.Off.*`, `DirectGLES.ResourceSubsystemOff.*`, `DirectGLES.ObjectSubsystemControl.{Off,Refused,RefusedTexture}.*` | Test / integration-gpu | they cleared subsystem bits (masks 0x7f / 0x1ff / 0x9ff / 0x5ff) to run legacy arms; since W3b bits 0-13 are fixed on (ID-P13-3) | one named-refusal control per lane, `DirectGLES.SubsystemMaskRefusal.<Lane>`: the same scenario and mask must go red with `Fatal{PipeSubsystemsFixedOn}` naming that mask (`Harness/RefusedMaskControl.cmake`); the `On` lanes now run 0x3fff |
|
||||
| 2026-10-06 | `SanityTest`: `DirectGLESSlotTable.{AnArmlessKnobCombinationStopsInsteadOfSkippingTheLane, TheArmlessCasesLeaveTheLogPathAndTheConfigAsTheyFoundThem, EglBringUpUnderTheArmlessKnobPairReturnsInsteadOfStopping}` | Test / unit | they pinned the `MOBILEGL_PIPE_LEGACY_MEMOS=0` + cleared-bit knob pair; the knob is gone and the mask is refused at startup | the SubsystemMaskRefusal controls above |
|
||||
| 2026-10-06 | `SanityTest`: `DirectGLESTextureSync.UnitMemoRefusesToDriveATwinFromAnotherTexture` | Test / unit | **not a behaviour gap; the probe cannot run at the shipping mask in the unit lane.** The code it pins - the monolith arm's borrowed-slot unit list and its pairing check - is still live (`UnitTexturesByHandle()` is false on monolith), but at 0x3fff the twin sync below it reads applier records, and `MGPipeApplyResourceCreate` declines in every unit-lane process (`NoP4aConsumer`), so the probe observed nothing (red before W3b at 0x3fff too, green only at P2). | **replaced**, not just removed: `DsaUpdateKeepsTheBoundUnitScenario` asserts the same hazard through public GL at the shipping mask, every lane, both backends (A bound to unit 0, B respecified and filled by name, unit 0 must still sample A's texels and shape). The handle arm's ABA sibling (P5e tx2) stays in SanityTest. Goes away with the borrowed-slot list itself in W4c |
|
||||
| 2026-10-06 | `SanityTest`: `DirectGLESTextureSync.AnAttachmentOnlyTexturesParametersReachTheDriverWithNoSamplerView` | Test / unit | **not a behaviour gap.** At 0x3fff the parameter push is record-addressed (`SyncTextureParamsToBackend` reads the texture's applier record; nothing in it consults a sampler view), but the unit lane cannot create that record (`NoP4aConsumer`, as above), so the probe's handle half never had a record to read; its legacy half pinned the pre-handle push that W3b removed | `TextureParamsWithoutASamplerViewScenario` (G9): its four cases take a WHITE-BOX reading of the driver-side parameters before any sample (`TakeTheWhiteBoxReadingBeforeAnySample`, ID-19), at the shipping mask on every lane - the same property, observed where records exist |
|
||||
| 2026-10-06 | unit `RenderStateSpans.{ResidualTripWireIsSilentUntilTheApplierOwnsTheBytes, ResidualTripWireHoldsAcrossAVerbClassThatDoesNotPublishTheBlock, ResidualTripWireFiresNamingTheCapability}` and PeerLatchTest's `SetResidualValueStateBlobSize` row | Test / unit | P13 W3c deleted ResidualValueBlock and its applier trip wire (op 46 is a retired, declined row) | integration-verify's new `Negative control A2 (corrupted capability)`: the verify comparator must go red on a corrupted `IsCapabilityEnabled`; `PipeWireCodecTest.ResidualValueBlockCrossesAsItsOwnBlob` now pins that op 46 is declined; `TrackerTest...AClipDistanceEnableReArmsTheResidualBlock` now asserts the capability reaches the applier's block |
|
||||
|
||||
## Kept after investigation
|
||||
|
||||
@@ -21,6 +21,7 @@ HandleRecycleScenario.* mechanism pointer-key ABA / slot recycling inside one pr
|
||||
CsoContentAddressingScenario.* mechanism toggles the process-local CSO content-addressing switch
|
||||
ResourceSubsystemControlScenario.* mechanism toggles the process-local P3a push mask
|
||||
ObjectSubsystemControlScenario.* mechanism toggles the process-local P4a push mask
|
||||
DirectGLES:SubsystemMaskRefusal.* mechanism P13 W3b named-refusal controls: a startup refusal of a cleared subsystem bit (ConfigLoader), pinned to the monolith lane environment
|
||||
PipeVerifyArmingScenario.* mechanism same-address-space verify comparator; its split arm is build-verify's integration-verify-split
|
||||
PoisonOmissionScenario.* mechanism withheld-stamp oracle; its split arm is build-verify's VerifySplitPoisonOmitted entries
|
||||
StorageBufferRegrowScenario.NStorageDefinitionsCostNMapPersistentRoundtripsNotOnePerDraw mechanism counts synchronous stats-slot roundtrips of direct persistent adoption
|
||||
|
||||
Reference in New Issue
Block a user