mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 12:48:32 +09:00
[Test] (Pipe): reproduce the texture, framebuffer, renderbuffer, sampler, view and program handle ABA through public GL and prove the pre-rekey guards are what stops it
This commit is contained in:
@@ -194,10 +194,57 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
//
|
||||
// Off by default (Config.h), set only by the HandleRecycle AbaControl ctest lanes, and
|
||||
// #if MOBILEGL_PIPE_PUSH throughout, so no shipping pull build can even parse it.
|
||||
// P4a (BRIEF-P4A.md D-I2, G8): WHICH KINDS THIS ANSWER COVERS, and it is not "all of them".
|
||||
//
|
||||
// P4a mints six more client-side kinds - Texture, Renderbuffer, Framebuffer, SamplerCso,
|
||||
// SamplerViewCso and ShaderCso - and requires the ABA control to defeat "the identity half
|
||||
// of P4a's memo keys as well", because a control that only defeats the guards a phase
|
||||
// RETIRED says nothing about the key that phase SHIPS.
|
||||
//
|
||||
// On Magma there is no such key to defeat, and that is a fact about the roadmap rather than
|
||||
// an omission here. MagmaPipeIdentityTables below mints exactly TWO kinds,
|
||||
// VertexElementsCso and Buffer; a texture, a framebuffer, a sampler, a view and a program
|
||||
// are all still reached from their frontend objects on this backend, and moving them onto
|
||||
// handles is P7's work (ROADMAP.md:24 - "Magma anything"; P4a leaves MG_Backend/DirectVulkan
|
||||
// untouched apart from this file). So the honest statement is per KIND, and it is spelled as
|
||||
// code rather than as a comment so that a caller cannot read the blanket answer above and
|
||||
// conclude the knob covers its kind:
|
||||
//
|
||||
// * for the two kinds this backend really keys on {slot, gen}, the knob defeats the
|
||||
// identity exactly as it always has (MagmaPipeClaimSlotMemos);
|
||||
// * for P4a's six there is nothing here to defeat, so the answer is FALSE - and
|
||||
// MG_IntegrationTest's HandleRecycleScenario reads that through its own build probe and
|
||||
// makes those cases' AbaControl arm assert the CORRECT pixels while SAYING that it is
|
||||
// not controlling anything for that kind. It does not assert a corruption that no code
|
||||
// on this tree can produce, which would be a permanently red always-on lane.
|
||||
//
|
||||
// WHAT MAKES IT TRUE LATER, in one sentence, so the next reader does not have to derive it:
|
||||
// when a backend grows a Features.PipeHandleAbaControl consumer over its P4a object slot
|
||||
// tables - one `if` in GetOrCreate / FindByHandle, the shape MagmaPipeClaimSlotMemos already
|
||||
// has for vertex input - this function's per-kind answer becomes that consumer's, the
|
||||
// integration probe finds the consumer, and the six cases flip to expecting the corruption.
|
||||
inline Bool MagmaPipeAbaControlDefeatsIdentity() {
|
||||
return MG_Config::Features.PipeHandleAbaControl;
|
||||
}
|
||||
|
||||
// The per-kind form of the answer above. `kind` is MG_Pipe::MGPipeKind.
|
||||
//
|
||||
// Deliberately a SWITCH over the kinds this backend mints rather than a default of "true":
|
||||
// a kind added to MGPipeKind without a decision here lands in the `default` arm and is
|
||||
// reported as NOT covered, which is the safe direction - an uncovered kind whose control
|
||||
// asserts the correct pixels is a control that has not armed yet, while a covered-by-default
|
||||
// kind whose control asserts a corruption nobody can produce is a red lane.
|
||||
inline Bool MagmaPipeAbaControlCoversKind(MG_Pipe::MGPipeKind kind) {
|
||||
switch (kind) {
|
||||
case MG_Pipe::MGPipeKind::VertexElementsCso:
|
||||
case MG_Pipe::MGPipeKind::Buffer:
|
||||
return MagmaPipeAbaControlDefeatsIdentity();
|
||||
default:
|
||||
// P4a's six, and every other kind: not minted on this backend, so not defeatable.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The single consumer-table entry every VAO collapses onto while the control is on. Slot
|
||||
// 0 is a real, ordinary entry of both tables (MagmaPipeSlotIndex maps the first allocatable
|
||||
// handle onto it), so nothing about the tables changes shape for the control's sake.
|
||||
|
||||
@@ -405,6 +405,35 @@ function(mgl_itest_probe_for_symbol outVar directory symbolRegex)
|
||||
set(${outVar} "${mglItestProbeHit}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# The same probe, over a CONJUNCTION: the first source in the directory that names BOTH regexes.
|
||||
#
|
||||
# P4a needs it for exactly one question and the question cannot be asked any other way. "Does
|
||||
# MOBILEGL_PIPE_HANDLE_ABA_CONTROL defeat the identity of P4a's OBJECT kinds on this backend?" is
|
||||
# not answered by "some source reads Features.PipeHandleAbaControl" - MagmaPipeArms.h does, and its
|
||||
# consumers are Magma's VERTEX-INPUT keys, so a single-regex probe would arm the six P4a ABA
|
||||
# controls on a backend where the knob cannot reach a texture, a framebuffer, a sampler, a view or a
|
||||
# program, and every one of them would assert a corruption nothing on the tree can produce - a hard
|
||||
# red on an always-on integration-gpu lane. Nor is it answered by "some source names a P4a subsystem
|
||||
# bit", which will become true for a backend that honours the mask long before anyone wires the
|
||||
# knob. What the arm actually needs is ONE SOURCE THAT DOES BOTH, and that is what this asks.
|
||||
#
|
||||
# Same staleness guarantees as the single-regex probe: CONFIGURE_DEPENDS on the glob, and every file
|
||||
# it finds appended to CMAKE_CONFIGURE_DEPENDS.
|
||||
function(mgl_itest_probe_for_two_symbols outVar directory symbolRegexA symbolRegexB)
|
||||
file(GLOB_RECURSE mglItestProbeSources CONFIGURE_DEPENDS
|
||||
"${directory}/*.h" "${directory}/*.hpp" "${directory}/*.cpp" "${directory}/*.c")
|
||||
set(mglItestProbeHit "")
|
||||
foreach(mglItestProbeSource IN LISTS mglItestProbeSources)
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${mglItestProbeSource}")
|
||||
file(STRINGS "${mglItestProbeSource}" mglItestProbeLinesA REGEX "${symbolRegexA}")
|
||||
file(STRINGS "${mglItestProbeSource}" mglItestProbeLinesB REGEX "${symbolRegexB}")
|
||||
if (mglItestProbeLinesA AND mglItestProbeLinesB AND NOT mglItestProbeHit)
|
||||
set(mglItestProbeHit "${mglItestProbeSource}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${outVar} "${mglItestProbeHit}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if (MOBILEGL_PIPE_PUSH)
|
||||
# DirectGLES' Track H arm, probed by the subsystem bit it is gated on rather than by
|
||||
# SlotTables.h existing: the bit is declared in the contract (MG_Pipe/MGPipe.h:77) and the
|
||||
@@ -490,6 +519,50 @@ if (MOBILEGL_PIPE_PUSH)
|
||||
"mpr entries will SKIP")
|
||||
endif()
|
||||
|
||||
# P4a's THIRD re-key question, per backend, and it is not either of the two above. Bits 5/6
|
||||
# re-keyed each backend's VERTEX-INPUT memos and bit 7/8 the BUFFER's; P4a re-keys six OBJECT
|
||||
# classes - texture, renderbuffer, framebuffer, sampler CSO, sampler view, shader CSO - behind
|
||||
# four new subsystem bits, and a backend has to NAME one of those constants to honour
|
||||
# MOBILEGL_PIPE_PUSH's default mask. A P4a case that read either older marker would arm its
|
||||
# Handles arm on a tree where nothing about a texture is keyed on a handle: green for a re-key
|
||||
# that does not exist. Probed by the constants rather than by a file, for the reason the block
|
||||
# above gives - packages D and E choose their own file layout.
|
||||
foreach(mglItestObjectBackend DirectGLES DirectVulkan)
|
||||
mgl_itest_probe_for_symbol(MGL_ITEST_OBJECT_REKEY
|
||||
"${MGL_ITEST_ROOT}/MobileGL/MG_Backend/${mglItestObjectBackend}"
|
||||
"kMGPipeSubsystem(Framebuffer|TextureResources|Samplers|Programs)")
|
||||
if (MGL_ITEST_OBJECT_REKEY)
|
||||
message(STATUS "Integration tests: ${mglItestObjectBackend} is keyed on {slot, gen} for "
|
||||
"P4a's object families (${MGL_ITEST_OBJECT_REKEY})")
|
||||
list(APPEND MGL_ITEST_CAPABILITY_ENV
|
||||
"MGITEST_HANDLE_REKEY_OBJECTS_${mglItestObjectBackend}=1")
|
||||
else()
|
||||
message(STATUS "Integration tests: no ${mglItestObjectBackend} source names "
|
||||
"kMGPipeSubsystem{Framebuffer,TextureResources,Samplers,Programs} - "
|
||||
"HandleRecycle's six P4a cases will SKIP their Handles arm on it")
|
||||
endif()
|
||||
|
||||
# ...and whether the ABA knob reaches those kinds THERE. A conjunction, for the reason
|
||||
# mgl_itest_probe_for_two_symbols states: reading the knob is not the same as steering
|
||||
# P4a's keys with it, and arming this marker on the weaker evidence turns six always-on
|
||||
# entries into a permanent red.
|
||||
mgl_itest_probe_for_two_symbols(MGL_ITEST_OBJECT_ABA
|
||||
"${MGL_ITEST_ROOT}/MobileGL/MG_Backend/${mglItestObjectBackend}"
|
||||
"PipeHandleAbaControl"
|
||||
"kMGPipeSubsystem(Framebuffer|TextureResources|Samplers|Programs)")
|
||||
if (MGL_ITEST_OBJECT_ABA)
|
||||
message(STATUS "Integration tests: MOBILEGL_PIPE_HANDLE_ABA_CONTROL steers "
|
||||
"${mglItestObjectBackend}'s P4a object keys (${MGL_ITEST_OBJECT_ABA})")
|
||||
list(APPEND MGL_ITEST_CAPABILITY_ENV
|
||||
"MGITEST_HANDLE_ABA_OBJECTS_${mglItestObjectBackend}=1")
|
||||
else()
|
||||
message(STATUS "Integration tests: no ${mglItestObjectBackend} source both reads "
|
||||
"Features.PipeHandleAbaControl and names a P4a subsystem bit - "
|
||||
"HandleRecycle's six P4a cases will assert the CORRECT pixels on the "
|
||||
"AbaControl arm and say that it is not a control for them yet")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
mgl_itest_probe_for_symbol(MGL_ITEST_MAGMA_ABA
|
||||
"${MGL_ITEST_ROOT}/MobileGL/MG_Backend/DirectVulkan" "PipeHandleAbaControl")
|
||||
if (MGL_ITEST_MAGMA_ABA)
|
||||
@@ -939,14 +1012,15 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
# explicit bitmask below that leaked PUSH=0 turned this lane's LEGACY_MEMOS=0 into D14's armless
|
||||
# combination: the bring-up aborted, on purpose, and the lane went red for a reason that was never
|
||||
# about handles. The mask is the PHASE default, not a hand-picked bit, so the lane keeps measuring
|
||||
# the shape that ships: it was kMGPipeSubsystemsMigratedAtP2 (0x7f) and is now
|
||||
# kMGPipeSubsystemsMigratedAtP3a (0x1ff, MG_Pipe/MGPipe.h), which adds bit 7 (resources) and bit 8
|
||||
# (vertex input). Pinning it at 0x7f after P3a would leave the Handles arm asserting the P2 shape
|
||||
# while the buffer and vertex-input handles it is supposed to be about stayed switched off - a lane
|
||||
# that still passes and no longer measures the key that ships. Each phase's constant survives as the
|
||||
# NEXT phase's A/B control, which is what ResourceSubsystemControl's Off lane uses 0x7f for.
|
||||
# the shape that ships: it was kMGPipeSubsystemsMigratedAtP2 (0x7f), then
|
||||
# kMGPipeSubsystemsMigratedAtP3a (0x1ff), and is now kMGPipeSubsystemsMigratedAtP4a (0x1fff,
|
||||
# MG_Pipe/MGPipe.h), which adds bits 9-12 - framebuffer, texture resources, samplers and programs.
|
||||
# Pinning it at 0x1ff after P4a would leave the Handles arm asserting the P3a shape while the six
|
||||
# OBJECT handles it is now also about stayed switched off - a lane that still passes and no longer
|
||||
# measures the key that ships. Each phase's constant survives as the NEXT phase's A/B control, which
|
||||
# is what ResourceSubsystemControl's Off lane uses 0x7f for and ObjectSubsystemControl's uses 0x1ff.
|
||||
if (MOBILEGL_PIPE_PUSH)
|
||||
set(MGL_ITEST_HANDLES_ARM_KNOBS "MOBILEGL_PIPE_LEGACY_MEMOS=0" "MOBILEGL_PIPE_PUSH=0x1ff")
|
||||
set(MGL_ITEST_HANDLES_ARM_KNOBS "MOBILEGL_PIPE_LEGACY_MEMOS=0" "MOBILEGL_PIPE_PUSH=0x1fff")
|
||||
set(MGL_ITEST_ABA_ARM_KNOBS "MOBILEGL_PIPE_HANDLE_ABA_CONTROL=1")
|
||||
else()
|
||||
set(MGL_ITEST_HANDLES_ARM_KNOBS "")
|
||||
@@ -1051,33 +1125,36 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
# only thing these four lanes are an A/B about is `no CSO content addressing` (bit 63,
|
||||
# kMGPipeBehaviourNoCsoContentAddressing), which is what separates the On lane from the Off lane.
|
||||
# Every
|
||||
# other bit is the build's shipping mask, so it moves with the phase: it was 0x7f
|
||||
# (kMGPipeSubsystemsMigratedAtP2) and is now 0x1ff (kMGPipeSubsystemsMigratedAtP3a) for the same
|
||||
# reason MGL_ITEST_HANDLES_ARM_KNOBS above moved. Left pinned at 0x7f after P3a these lanes would
|
||||
# keep passing while running on a configuration nothing ships - bits 7 (resources) and 8 (vertex
|
||||
# input) cleared - which is the "still green, no longer measuring the shape that ships" failure
|
||||
# the Handles-arm comment above rejects. The counters they read (csom / csob) are render-state and
|
||||
# other bit is the build's shipping mask, so it moves with the phase: 0x7f
|
||||
# (kMGPipeSubsystemsMigratedAtP2), then 0x1ff (kMGPipeSubsystemsMigratedAtP3a), now 0x1fff
|
||||
# (kMGPipeSubsystemsMigratedAtP4a) for the same reason MGL_ITEST_HANDLES_ARM_KNOBS above moved. Left
|
||||
# pinned at 0x1ff after P4a these lanes would keep passing while running on a configuration nothing
|
||||
# ships - bits 9-12 (framebuffer, texture resources, samplers, programs) cleared - which is the
|
||||
# "still green, no longer measuring the shape that ships" failure the Handles-arm comment above
|
||||
# rejects. NOTE THAT THE OFF LANE'S MASK MOVED TOO, from 0x80000000000001ff to
|
||||
# 0x8000000000001fff: the mask moves with the phase, the control is bit 63, and the two must not be
|
||||
# confused. The counters they read (csom / csob) are render-state and
|
||||
# are steered by neither bit, so raising the mask is behaviour-preserving for what they assert;
|
||||
# what it buys is that a CSO regression that only shows up with the P3a subsystems on can reach
|
||||
# them. (contract-review-v1.md item 11, closed here for all three lane families.)
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_CSO_ON_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MGITEST_CSO_LANE=content-addressed"
|
||||
"MOBILEGL_PIPE_PUSH=0x1ff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_PIPE_PUSH=0x1fff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/cso-content-addressed-DirectGLES.log"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_CSO_OFF_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MGITEST_CSO_LANE=no-content-addressing"
|
||||
"MOBILEGL_PIPE_PUSH=0x80000000000001ff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_PIPE_PUSH=0x8000000000001fff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/cso-no-content-addressing-DirectGLES.log"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
mgl_itest_join_environment(MGL_ITEST_VULKAN_CSO_ON_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectVulkan" "MGITEST_CSO_LANE=content-addressed"
|
||||
"MOBILEGL_PIPE_PUSH=0x1ff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_PIPE_PUSH=0x1fff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/cso-content-addressed-DirectVulkan.log"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_VULKAN_ENV})
|
||||
mgl_itest_join_environment(MGL_ITEST_VULKAN_CSO_OFF_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectVulkan" "MGITEST_CSO_LANE=no-content-addressing"
|
||||
"MOBILEGL_PIPE_PUSH=0x80000000000001ff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_PIPE_PUSH=0x8000000000001fff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/cso-no-content-addressing-DirectVulkan.log"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_VULKAN_ENV})
|
||||
|
||||
@@ -1120,12 +1197,15 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
|
||||
# --- G12: the P3a subsystem A/B, and G10's map-persistent-roundtrips lanes ------------
|
||||
#
|
||||
# THE MASKS ARE THE TWO PHASE CONSTANTS, not hand-picked bits: 0x1ff is
|
||||
# kMGPipeSubsystemsMigratedAtP3a (the push build's default) and 0x7f is
|
||||
# kMGPipeSubsystemsMigratedAtP2, which is exactly that default with bits 7 (resources) and 8
|
||||
# (vertex input) cleared. MGPipe.h:79 keeps each phase's constant alive as the next phase's A/B
|
||||
# control for this reason, and a lane that spelled its own bit pattern would stop being the shape
|
||||
# that ships the first time the default moved.
|
||||
# THE MASKS ARE PHASE CONSTANTS, not hand-picked bits: 0x1fff is
|
||||
# kMGPipeSubsystemsMigratedAtP4a (the push build's default as of P4a) and 0x7f is
|
||||
# kMGPipeSubsystemsMigratedAtP2, which is that default with bits 7 (resources), 8 (vertex input)
|
||||
# and 9-12 (P4a's four object families) cleared. MGPipe.h keeps each phase's constant alive as the
|
||||
# next phase's A/B control for this reason, and a lane that spelled its own bit pattern would stop
|
||||
# being the shape that ships the first time the default moved. THE ON LANE MOVED TO 0x1fff WITH THE
|
||||
# PHASE and the OFF LANE'S 0x7f DID NOT: this A/B is about bit 7, and pinning its On arm at 0x1ff
|
||||
# after P4a would measure the resource emitter on a configuration nothing ships. P4a's own A/B -
|
||||
# 0x1fff against 0x1ff - is ObjectSubsystemControl's, further down.
|
||||
#
|
||||
# DirectGLES only. P3a migrates Espryt's buffer and VAO paths; Magma's buffer path is P7 and
|
||||
# registers no MGPipeResourceOps, so a DirectVulkan arm would be measuring the client emitter
|
||||
@@ -1146,7 +1226,7 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
# the field inside the push guard), exactly as the HandleRecycle Legacy lanes already rely on.
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_RESOURCE_SUBSYSTEM_ON_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MGITEST_RESOURCE_SUBSYSTEM_LANE=on"
|
||||
"MOBILEGL_PIPE_PUSH=0x1ff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_PIPE_PUSH=0x1fff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/resource-subsystem-on-DirectGLES.log"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_RESOURCE_SUBSYSTEM_OFF_ENVIRONMENT
|
||||
@@ -1180,12 +1260,12 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
# TEST_FILTER, for the private-log reason above.
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_MPR_REGROW_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MGITEST_MPR_LANE=storage-buffer-regrow"
|
||||
"MOBILEGL_PIPE_PUSH=0x1ff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_PIPE_PUSH=0x1fff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/mpr-storage-buffer-regrow-DirectGLES.log"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_MPR_ARENA_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MGITEST_MPR_LANE=large-arena-adoption"
|
||||
"MOBILEGL_PIPE_PUSH=0x1ff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_PIPE_PUSH=0x1fff" "MOBILEGL_PIPE_STATS=1" "MOBILEGL_PIPE_STATS_PERIOD=1"
|
||||
"MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/mpr-large-arena-adoption-DirectGLES.log"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
|
||||
@@ -1216,7 +1296,7 @@ gtest_discover_tests(MobileGLIntegrationTest
|
||||
# four processes to truncate. The fourth case skips in both lanes for exactly that reason, saying
|
||||
# so.
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_ARENA_SUBSYSTEM_ON_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MOBILEGL_PIPE_PUSH=0x1ff"
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MOBILEGL_PIPE_PUSH=0x1fff"
|
||||
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
|
||||
mgl_itest_join_environment(MGL_ITEST_GLES_ARENA_SUBSYSTEM_OFF_ENVIRONMENT
|
||||
"MOBILEGL_BACKEND_TYPE=DirectGLES" "MOBILEGL_PIPE_PUSH=0x7f"
|
||||
|
||||
@@ -20,11 +20,24 @@ namespace MGITest {
|
||||
|
||||
#if defined(MGITEST_PIPE_SLOT_PEEK_LIVE)
|
||||
namespace {
|
||||
// One arm per member, and NO `default:` on purpose: adding a PipeSlotKind without
|
||||
// deciding which MGPipeKind it names is a compiler warning here (-Wswitch) rather than
|
||||
// a row that silently counts VertexElementsCso and reports "did not leak" about a kind
|
||||
// it never looked at. The trailing return is the unreachable one the compiler needs.
|
||||
MobileGL::MG_Pipe::MGPipeKind Translate(PipeSlotKind kind) {
|
||||
switch (kind) {
|
||||
case PipeSlotKind::Buffer: return MobileGL::MG_Pipe::MGPipeKind::Buffer;
|
||||
default: return MobileGL::MG_Pipe::MGPipeKind::VertexElementsCso;
|
||||
case PipeSlotKind::VertexElementsCso:
|
||||
return MobileGL::MG_Pipe::MGPipeKind::VertexElementsCso;
|
||||
case PipeSlotKind::Texture: return MobileGL::MG_Pipe::MGPipeKind::Texture;
|
||||
case PipeSlotKind::Renderbuffer: return MobileGL::MG_Pipe::MGPipeKind::Renderbuffer;
|
||||
case PipeSlotKind::Framebuffer: return MobileGL::MG_Pipe::MGPipeKind::Framebuffer;
|
||||
case PipeSlotKind::SamplerCso: return MobileGL::MG_Pipe::MGPipeKind::SamplerCso;
|
||||
case PipeSlotKind::SamplerViewCso:
|
||||
return MobileGL::MG_Pipe::MGPipeKind::SamplerViewCso;
|
||||
case PipeSlotKind::ShaderCso: return MobileGL::MG_Pipe::MGPipeKind::ShaderCso;
|
||||
}
|
||||
return MobileGL::MG_Pipe::MGPipeKind::None;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -30,6 +30,29 @@ namespace MGITest {
|
||||
enum class PipeSlotKind {
|
||||
Buffer,
|
||||
VertexElementsCso,
|
||||
// P4a's six (G8b). Every one of them is a kind the CLIENT mints and the client alone
|
||||
// frees (BRIEF-P4A.md D-I1: one death helper per kind, called from the frontend
|
||||
// object's own destructor, whatever backend is running), so every one of them can leak
|
||||
// the P3a C-1 way - and the leak is invisible in pixels, in GL names and in
|
||||
// glGetError, exactly as the VertexElementsCso one was.
|
||||
Texture,
|
||||
Renderbuffer,
|
||||
// Framebuffer has a HANDLE but no wire lifetime (D-I2): no create_*, no destroy row in
|
||||
// the catalogue, and its death helper does the notice and the free and emits nothing.
|
||||
// That makes the allocator the ONLY observable of its lifetime, so this row matters
|
||||
// more here than the others rather than less.
|
||||
Framebuffer,
|
||||
SamplerCso,
|
||||
SamplerViewCso,
|
||||
// ShaderCso covers BOTH the ordinary program slots and the program-pipeline COMPOSITES
|
||||
// minted out of the reserved high band (MGPipeHandles.h:86-97, D-H7). One kind, because
|
||||
// that is what the allocator has: the band is a second dense table inside the same
|
||||
// kind, LiveCount counts both and HighWater is one past the highest slot handed out in
|
||||
// either. The composite's leak case is a separate CASE rather than a separate kind for
|
||||
// that reason - what makes it its own case is that a composite's slot has TWO
|
||||
// independent release paths (the pipeline cache's LRU eviction and the composite
|
||||
// ProgramObject's destructor), not that it is counted anywhere else.
|
||||
ShaderCso,
|
||||
};
|
||||
|
||||
// Live slots of this kind right now, and one past the highest slot ever handed out.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user