[Docs] (.github/workflows, MG_Backend/DirectGLES, MG_Backend/DirectVulkan, MG_Benchmark/Driver, MG_Impl/EGLImpl, MG_Impl/Pipe, MG_IntegrationTest, MG_IntegrationTest/Harness, MG_IntegrationTest/Scenarios, MG_Pipe, MG_State/GLState, MG_Test, MG_Test/Pipe, MG_Test/Program, MG_Test/SelfTest, MG_Test/ShaderTranspiler, MG_Test/Swapchain, MG_Test/Wire, MG_Util/Async, MG_Util/BackendLoaders, MG_Util/SelfTest, MG_Util/ShaderTranspiler, MobileGL, scripts/ci, tools/spikes, tools/trace_replay): name drivers and techniques instead of external projects

This commit is contained in:
2026-10-15 10:15:37 -04:00
parent 506ab1541d
commit 5370d917d0
66 changed files with 92 additions and 92 deletions
+1 -1
View File
@@ -452,7 +452,7 @@ jobs:
# Second, filtered pass: with the range-invalidating map flush disabled,
# the buffer scenarios run on the upload ring's staged-copy tier - which
# the default pass never reaches (the map tier absorbs every flush on
# Mesa), so without this the Mali fallback tier would have zero CI
# the CI drivers), so without this the Mali fallback tier would have zero CI
# coverage. The flag is NOT baked into the ctest ENVIRONMENT properties,
# so an inline env reaches the test processes (unlike the ICD pin above).
if [ "${{ secrets.ACTIONS_STEP_DEBUG }}" = "true" ]; then
+2 -2
View File
@@ -283,7 +283,7 @@ namespace MobileGL::MG_Config {
Bool DisableLargeBufferAdoption = false;
// MOBILEGL_ESPRYT_FORCE_DS_READBACK_EMULATION: make DirectGLES skip the native ES
// depth/stencil reads and always go through the shader-sampling emulation. Core GL
// ES has no depth or stencil readback, but some drivers accept it anyway (Mesa does,
// ES has no depth or stencil readback, but some drivers accept it anyway (llvmpipe does,
// Adreno does not), which means the emulation is dead code on exactly the stack the
// headless suite runs on. This forces it live so the scenarios and the CTS can
// exercise the path, and gives the device an A/B lever over the same choice.
@@ -378,7 +378,7 @@ namespace MobileGL::MG_Config {
// MOBILEGL_MAGMA_PRIMGEN_QUERY_REROUTE: DirectVulkan's GL_PRIMITIVES_GENERATED
// reroute for draws made while transform feedback is INACTIVE. The stream query
// (VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT primitivesNeeded) is defined to count
// them, but a Mali driver - and Mesa lavapipe - answers 0 unless a capture span is
// them, but a Mali driver - and lavapipe - answers 0 unless a capture span is
// open, which is exactly the shape the CTS uses to measure the tessellator, so ~29
// tessellation tests per tree size a capture buffer from the 0 and die on the
// zero-length map. Auto defers to a device probe at renderer bring-up
@@ -10153,7 +10153,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// was never anything but the frontend's way of naming the texture, and the record
// names it now.
backendTexture->Bind(backendTarget, TextureImpl::TempTextureUnit);
// ANGLE/Mesa may validate the currently bound FBO while generating mipmaps, so the
// ANGLE and some other drivers may validate the currently bound FBO while generating mipmaps, so the
// source texture is detached from every framebuffer that attaches it - by handle,
// over the applier's own framebuffer records.
ScopedDetachedTextureFramebufferAttachments detachedAttachments(mipRes);
@@ -10726,7 +10726,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// all. GL_DEPTH_COMPONENT, GL_STENCIL_INDEX and GL_DEPTH_STENCIL are simply not
// accepted formats there, and the optional extensions that add them (GL_NV_read_depth,
// GL_NV_read_stencil, GL_NV_read_depth_stencil) are absent on both the Adreno device
// and Mesa's ES. Every native attempt therefore failed with a GL error and wrote
// and llvmpipe's ES. Every native attempt therefore failed with a GL error and wrote
// NOTHING, so the caller kept whatever its buffer already held - which is how the CTS
// reports "expected DEPTH[0.25] but got DEPTH[0.2]": 0.2 is the poison value the test
// itself put there.
+7 -7
View File
@@ -837,7 +837,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// case). Written only under the mutex; read lock-free.
std::atomic<Bool> g_hasDeferredBufferReleases{false};
// --- Buffer-storage pool (Mesa-style BO recycle) -------------------------
// --- Buffer-storage pool (buffer-object recycling) -----------------------
// Recycle idle GL buffer ids of an EXACT byte size instead of glDeleteBuffers
// (which triggers the kgsl_sharedmem_free -> mmu_unmap -> smmu/power/bandwidth
// cascade that dominated per-frame driver cost). An id retired during frame N
@@ -11962,7 +11962,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
//
// A driver that HAS GL_NV_image_formats still needs part of this. SPIRV-Cross throws
// for its is_desktop_only_format set when it targets ESSL rather than printing a
// token, and the throw loses the stage however willing the driver was - Mesa
// token, and the throw loses the stage however willing the driver was - llvmpipe
// advertises the extension and `layout(r8ui) uimage2D` lost its whole program there
// until the widening ran for it too. So the driver bit decides HOW MUCH is widened,
// never WHETHER.
@@ -11996,7 +11996,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// reaches SPIRV-Cross intact and comes out as ESSL a strict driver rejects
// outright ("array indexes for fragment outputs must be constant integral
// expressions"), linking no program and silently no-oping every draw that
// uses it. Mesa accepts it, ANGLE does not - which is the whole of the
// uses it. llvmpipe accepts it, ANGLE does not - which is the whole of the
// improved-transparency-minecraft-26.3 failure. Fold or lower the index here,
// on the ESSL path only: the same module is legal for DirectVulkan.
Vector<unsigned int> outputIndexSpirv;
@@ -12012,7 +12012,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// dynamically-uniform expression, GLSL ES keeps the ES 3.1
// constant-expression rule for both, and the drivers enforce it - Qualcomm
// ("indexing into an SSBO array using a non-constant expression is not
// permitted"), Mesa ("image arrays indexed with non-constant expressions are
// permitted"), llvmpipe ("image arrays indexed with non-constant expressions are
// forbidden in GLSL ES") - losing the stage, the program, and every draw or
// dispatch that used it, while the frontend keeps reporting the link glslang
// performed. Fold or lower the index here, on the ESSL path only: the same
@@ -12158,7 +12158,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// `readonly writeonly` together says the buffer variable can only be asked its
// .length(), which the frontend has already enforced - so the pair is inert, and
// printing it is not. Mesa's ES compiler refuses a block spelled that way and the
// printing it is not. llvmpipe's ES compiler refuses a block spelled that way and the
// stage never reaches the program.
spvcSession.RelaxReadWriteExclusiveStorageBuffers();
@@ -13327,8 +13327,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
// installs the new executable - but only "for all shader stages where the program
// is active", and a stage the previous link did not produce is not active for
// anything. So a relink that ADDS a stage is precisely the case the promise does
// not cover. Verified with no MobileGL in the process (bare EGL + GLES 3.2, Mesa
// 26.1.4 llvmpipe): vertex+fragment linked, used and drawn renders; a geometry
// not cover. Verified with no MobileGL in the process (bare EGL + GLES 3.2,
// llvmpipe 26.1.4): vertex+fragment linked, used and drawn renders; a geometry
// shader attached and relinked reports LINK_STATUS true with an empty info log,
// and the next draw renders NOTHING and raises no error - while the same draw
// after a fresh glUseProgram of the same name renders again.
+1 -1
View File
@@ -3273,7 +3273,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// P4a (D-F2/D-F3): the SIXTH Espryt twin table, and the only one of the six whose kind
// has no frontend object at all. MobileGL has no sampler-view class: GL binds a texture
// to a unit and the sampler uniform's type, the mipmap-completeness predicates and
// IsUndefinedDefaultTexture decide what the shader sees. Gallium's one-view-per-slot IS
// IsUndefinedDefaultTexture decide what the shader sees. Binding one sampler view per slot IS
// that resolved form, the resolution moves to the CLIENT (ARCHITECTURE.md §5.5), and
// create_sampler_view carries the restrictions the resolution had to read.
//
+1 -1
View File
@@ -390,7 +390,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl {
// driver entries it saves. mc_sodium_multidraw (132 batches x 32 sub-draws),
// ns/op, median of three:
//
// NVIDIA ES 3.2 Mesa llvmpipe ES 3.2
// NVIDIA ES 3.2 llvmpipe ES 3.2
// ext n/a 19300
// basevertex 2500 25200
// multiindirect 5700 27600
+3 -3
View File
@@ -191,7 +191,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// behind the native probe), so a driver that does render to a three-channel image keeps
// allocating it byte for byte.
//
// Do NOT read that as "nothing changes off-device". Measured on Mesa 26.1.6 llvmpipe
// Do NOT read that as "nothing changes off-device". Measured on llvmpipe 26.1.6
// (the headless CI driver), an ES 3.2 GL_TEXTURE_2D colour attachment is COMPLETE for
// GL_RGB8 and GL_RGB16F but INCOMPLETE_ATTACHMENT for GL_RGB8_SNORM, GL_SRGB8 and every
// RGB integer format, and UNSUPPORTED for GL_RGB32F. Those eight formats therefore DO
@@ -328,7 +328,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// A driver WITH GL_NV_image_formats can spell the narrow format - but only for the
// formats SPIRV-Cross will actually print. It throws for its is_desktop_only_format
// set instead of emitting a token, and the throw loses the stage whatever the driver
// would have accepted: on Mesa, which advertises the extension, `layout(r8ui)
// would have accepted: on llvmpipe, which advertises the extension, `layout(r8ui)
// uimage2D` still lost its whole program until the widening ran for it too.
if (g_GLESCapabilities.SupportsExtendedImageFormats &&
MG_Util::ShaderTranspiler::ShaderCompiler::SpirvCrossCanPrintEsslImageFormat(requested)) {
@@ -1787,7 +1787,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// KHR-GL43.shading_language_420pack.binding_images_texture_type_* went from 6
// image uniforms to 30 and the link failed outright with "Error: Image Image
// location or component exceeds max allowed." on an Adreno 830, where Mali and
// Mesa both accept the same text.
// llvmpipe both accept the same text.
//
// Nothing downstream reads these names: the two passes that key on the GL uniform
// name (RebindImageUniformsToFrontendUnits, BakeImageFormatQualifiers) both run
+2 -2
View File
@@ -352,7 +352,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// That rewrite needs every k in the emitted text to be a LITERAL, and it is:
// LegalizeResourceArrayIndexingForEssl has already folded or lowered every dynamic
// image-array subscript in the module, because ESSL forbids one outright ("image arrays
// indexed with non-constant expressions are forbidden in GLSL ES", Mesa 26.1.4 at
// indexed with non-constant expressions are forbidden in GLSL ES", llvmpipe 26.1.4 at
// ES 3.2, on a raw GLES probe with no MobileGL in the loop). The earlier shape here -
// widening the array to cover the whole span of units and routing each subscript through
// a `const highp int` offset table - was written before that pass covered images, and
@@ -510,7 +510,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// linker answered "Error: Image Image location or component exceeds max allowed. Error:
// Linking failed." - which, the frontend having already published LINK_STATUS = TRUE from
// glslang's link, surfaced only as every draw silently doing nothing and the images
// reading back zero. Mali and Mesa link the same text, so nothing but a device gate
// reading back zero. Mali and a desktop GLES driver link the same text, so nothing but a device gate
// catches this.
//
// A declaration SPIRV-Cross already tagged `readonly` or `writeonly` needs no qualifier
@@ -1531,7 +1531,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
case 0x1010u: // Imagination
m_dynamicParameters.GpuVendor = GpuVendorKind::ImgTec;
break;
case 0x10005u: // Mesa software (lavapipe)
case 0x10005u: // software (lavapipe)
case 0x1AE0u: // Google (SwiftShader)
m_dynamicParameters.GpuVendor = GpuVendorKind::Software;
break;
@@ -1350,7 +1350,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Uint32 m_xfbQueryOpenSlot = 0;
// GL_PRIMITIVES_GENERATED reroute for draws made while transform feedback is
// INACTIVE. The stream pool's primitivesNeeded is defined to count those draws
// too, but a Mali driver (and Mesa lavapipe) answers 0 unless a capture span
// too, but a Mali driver (and lavapipe) answers 0 unless a capture span
// is open (the CTS's tessellator-measuring shape). Where the bring-up probe
// finds that defect with a working control - or
// MOBILEGL_MAGMA_PRIMGEN_QUERY_REROUTE forces it - such draws accumulate the
@@ -1047,7 +1047,7 @@
// otherwise - so `glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, COLOR|DEPTH)` out of a
// multisample framebuffer blitted its COLOUR correctly (the colour arm has handled a
// flip since P5f and now handles a scale too) and then died on its DEPTH. GL 4.6 core
// 18.3.1 asks for identical DIMENSIONS, not identical corners - Mesa compares absolute
// 18.3.1 asks for identical DIMENSIONS, not identical corners - a conforming check compares absolute
// spans - so a flip is a legal blit that has to produce a mirrored picture.
//
// Spans are therefore signed and everything downstream works off the min corner.
+1 -1
View File
@@ -336,7 +336,7 @@ static int boot_egl(void) {
/* The default display first: it is the one a windowed app would get, and
* on a desktop it is the one that reaches the real GPU - which is the
* driver this bench exists to measure. It does need a window system,
* though; Mesa's default platform is X11, so with no $DISPLAY (CI, a
* though; desktop EGL usually defaults to the X11 platform, so with no $DISPLAY (CI, a
* build server, ssh without forwarding) eglInitialize fails. Fall back to
* EGL_MESA_platform_surfaceless rather than give up: every case draws into
* the FBO built by build_resources(), so no window is needed for any of
@@ -10,7 +10,7 @@
#
# Pin the vendor libraries explicitly. A bare libEGL.so.1 on a glvnd system
# picks whatever vendor eglGetDisplay(EGL_DEFAULT_DISPLAY) resolves first,
# which is Mesa/llvmpipe here - a software rasteriser silently replacing the
# which is llvmpipe here - a software rasteriser silently replacing the
# GPU under a benchmark. Override MGL_EGL_VENDOR / MGL_VK_ICD to test another
# driver.
set -eu
+1 -1
View File
@@ -50,7 +50,7 @@ namespace MobileGL::MG_Impl::EGLImpl::Wayland {
inline constexpr EGLenum kPlatformWayland = 0x31D8;
// Whether a display is a Wayland one: asked for as EGL_PLATFORM_WAYLAND, or (eglGetDisplay with
// no platform) a native display that is a wl_display - recognised the way Mesa does, by its
// no platform) a native display that is a wl_display - recognised the way EGL loaders usually do, by its
// first word being libwayland-client's wl_display_interface (or, for an application with its
// own copy of libwayland, an interface named "wl_display").
Bool IsWaylandDisplay(Uint64 nativeDisplay, EGLenum platform);
+2 -2
View File
@@ -20,8 +20,8 @@
// before reusing the handle. ARCHITECTURE.md 4.1 says content addressing on an
// xxHash; a bare 64-bit equality would let a collision alias two different render
// states onto one CSO, which is silent wrong pixels with no gate that can see it.
// Mesa's cso_cache memcmps for the same reason. The memcmp only ever runs on a
// pipeline-version change, i.e. never in the steady state.
// Hashed constant-state caches confirm a hit with a full-key memcmp for the same reason.
// The memcmp only ever runs on a pipeline-version change, i.e. never in the steady state.
// 3. miss -> mint a slot, emit create_render_state with every pipeline chunk, then bind.
//
// CAPACITY 64 (ROADMAP.md P2). 64 x (8 + 8 + 396 + 8) = about 26 KB per context. ROADMAP.md
+1 -1
View File
@@ -617,7 +617,7 @@ namespace MobileGL::MG_Pipe {
// ---------------------------------------------------------------------------------
//
// GL binds one texture per unit PER TARGET; which one the shader actually samples depends
// on the sampler uniform's TYPE. Gallium's one-view-per-slot is the resolved form, so the
// on the sampler uniform's TYPE. One sampler view per slot is the resolved form, so the
// resolution moves to the client and the record carries the answer rather than the inputs.
//
// This is DirectGLES' SamplerUniformTextureTarget, moved to the side of the boundary that
+4 -4
View File
@@ -241,7 +241,7 @@ endif()
# --- ctest wiring --------------------------------------------------------
# A bare libEGL on a glvnd box resolves to whatever vendor comes first, which is
# usually Mesa/llvmpipe - a software rasteriser silently replacing the GPU under
# usually llvmpipe - a software rasteriser silently replacing the GPU under
# a GPU test. Pin the vendor/ICD json the same way MG_Benchmark's
# run_driver_bench.sh does.
#
@@ -316,7 +316,7 @@ else()
message(WARNING
"Integration tests: no EGL vendor json found or configured (MOBILEGL_ITEST_EGL_VENDOR is empty). "
"An unpinned libEGL on a glvnd system resolves to whichever vendor comes first, which is usually "
"Mesa/llvmpipe - the scenarios would then go green against a software rasteriser instead of the GPU. "
"llvmpipe - the scenarios would then go green against a software rasteriser instead of the GPU. "
"Set -DMOBILEGL_ITEST_EGL_VENDOR=/usr/share/glvnd/egl_vendor.d/<vendor>.json.")
endif()
if (MOBILEGL_ITEST_VK_ICD)
@@ -905,7 +905,7 @@ gtest_discover_tests(MobileGLIntegrationTest
# A fourth registration, of the depth/stencil readback scenarios, with the ES
# shader-sampling emulation forced on. Not paranoia - without it these scenarios are
# UNFALSIFIABLE on the machines this suite runs on: OpenGL ES has no depth or stencil
# readback in core, but Mesa accepts the reads anyway, so on llvmpipe every one of them
# readback in core, but llvmpipe accepts the reads anyway, so every one of them
# goes green through a native path that the Adreno device does not have. Deleting the
# entire emulation left all of them passing. With the flag the native spellings are off
# the table and only the path the device actually takes remains. DirectGLES only - the
@@ -2680,7 +2680,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
#
# Without it this scenario is UNFALSIFIABLE on the machines this suite runs on, and the
# ambient DirectGLES.ForcedDepthStencilEmulation. lane says why: OpenGL ES has no depth or
# stencil readback in core, but Mesa accepts the reads anyway, so on llvmpipe every case goes
# stencil readback in core, but llvmpipe accepts the reads anyway, so every case goes
# green through a native path the Adreno device does not have - deleting the whole emulation
# left all of them passing. A split arm that inherited the ambient default would be measuring
# the same non-path three more times. So the pin is MIRRORED here, which is what the plan's
@@ -167,10 +167,10 @@ namespace MGITest {
// not a CI accommodation - it is what keeps a developer's run and a CI run
// the same run. The lane was wired up green on a workstation and immediately
// died on the runner precisely because the workstation had a DISPLAY (WSLg)
// and took Mesa's x11 platform, while the runner has none; that divergence
// and took the x11 EGL platform, while the runner has none; that divergence
// is the bug, and pinning the platform here is the fix for it.
//
// Mesa selects its EGL platform from EGL_PLATFORM at loader time, so this
// The desktop EGL library selects its platform from EGL_PLATFORM at loader time, so this
// has to run before the first EGL call in the process (see EnsureHeadless
// callers). surfaceless is the platform with no window-system dependency at
// all; the surface this file then creates is still a pbuffer, which every
@@ -180,7 +180,7 @@ void main() { fragColor = vec4(0.0, 1.0, 0.0, 1.0); }
// forwarded at all.
// - Vulkan has no such state: every clip distance a shader declares is active,
// always. DirectVulkan therefore clips by a disabled distance.
// - Mesa's llvmpipe ES driver behaves like Vulkan here.
// - llvmpipe's ES driver behaves like Vulkan here.
//
// Emulating GL's semantics on those two would mean forcing the disabled slots to a
// non-negative value inside the shader, which makes the enable mask part of the
@@ -24,7 +24,7 @@
//
// On DirectGLES none of this exists natively - ES has no depth or stencil readback in
// core - so every assertion here is really an assertion about the shader-sampling
// emulation. The catch is that some ES drivers accept the reads anyway (Mesa does,
// emulation. The catch is that some ES drivers accept the reads anyway (llvmpipe does,
// Adreno does not), which would make the emulation dead code on the very stack the
// headless suite runs on. That is what the second ctest registration is for: the same
// scenarios run again with MOBILEGL_ESPRYT_FORCE_DS_READBACK_EMULATION=1, which takes the
@@ -516,7 +516,7 @@ namespace MGITest {
// P7 wave 2-B2 (review round): A MULTISAMPLE DEPTH RESOLVE THAT FLIPS, AND ONE THAT SCALES.
//
// GL 4.6 core 18.3.1 asks a multisample blit for identical rectangle DIMENSIONS, not for
// identical corners - Mesa compares absolute spans - so `glBlitFramebuffer(0, h, w, 0, ...)`
// identical corners - a conforming check compares absolute spans - so `glBlitFramebuffer(0, h, w, 0, ...)`
// out of a multisample framebuffer is legal and owes a mirrored picture, while a blit whose
// sizes differ is INVALID_OPERATION and owes nothing. The wire arm used to end the SESSION
// on both: `Magma:multisample-depth-resolve-region` covered the reversed rectangle and the
@@ -60,7 +60,7 @@ namespace MGITest {
protected:
// Both backends now answer these reads. DirectGLES has no native ES path for
// either aspect (GL_NV_read_depth / GL_NV_read_stencil are optional and absent on
// both the Adreno device and Mesa's ES), so it stages the attachment into a
// both the Adreno device and llvmpipe's ES), so it stages the attachment into a
// scratch depth texture and samples it into a colour target; the assertions below
// are the same either way, which is the point.
bool BackendReadsDepthStencil() const { return true; }
@@ -26,7 +26,7 @@
// capability absent - src0, written straight through
//
// What each CI lane actually reaches: lavapipe has dualSrcBlend, so the DirectVulkan lane runs the
// whole sequence and measures the blend. Mesa's GLES front end on llvmpipe has no
// whole sequence and measures the blend. The GLES front end on llvmpipe has no
// GL_EXT_blend_func_extended, so the ESSL stage carrying `layout(index = 1)` never compiles and the
// program renders nothing - the DirectGLES lane therefore SKIPS on the capability probe in SetUp
// rather than measuring a picture the driver never produced. The DECLINE arm itself - the path this
@@ -26,7 +26,7 @@
// KHR-GL43.stencil_texturing.functional is where it surfaced: its compute half writes through a
// format-less `uimage2D` bound to an R8UI texture, and returned zeros for every texel.
//
// DISCRIMINATING ONLY WHERE THE DRIVER ADVERTISES GL_NV_image_formats - Mesa does, which is what
// DISCRIMINATING ONLY WHERE THE DRIVER ADVERTISES GL_NV_image_formats - llvmpipe does, which is what
// the software lanes run and where this was found. On Adreno 830 and both Malis the extension is
// absent, the old code already armed the widening, and these cases pass before and after; they
// are kept running there as a guard against the opposite mistake.
@@ -21,7 +21,7 @@
// ProgramUtilTest, LoopDerivedFragmentOutputIndexFoldsToConstantIndices and its
// genuinely-dynamic sibling) prove the SPIR-V comes out with constant indices, validates, and
// decompiles to ESSL with only literal indices. What they cannot prove is that a real driver
// then ACCEPTS and RUNS it - and acceptance is the whole failure mode, because Mesa accepts the
// then ACCEPTS and RUNS it - and acceptance is the whole failure mode, because the desktop CI drivers accept the
// illegal form too. Only a live glCompileShader/glLinkProgram followed by a draw can tell the two
// apart, and only reading the pixels back can tell "linked" from "wrote the right attachment".
//
@@ -211,7 +211,7 @@ void main()
// r32ui program for the rgba32ui texture, and the second half would come back seeded.
//
// What the SOFTWARE lanes cannot falsify: with the key disabled this case still passes on
// Mesa, because the reused r32ui declaration writes the red channel of an RGBA32UI image
// llvmpipe, because the reused r32ui declaration writes the red channel of an RGBA32UI image
// anyway - a format-class mismatch GL leaves undefined and that driver happens to absorb.
// FirstBindAfterLinkRebuilds below is the case that fails there, because the reused
// program was built with no format at all and never compiled. Both are kept: this one is
@@ -34,7 +34,7 @@
// EVERY CASE HERE IS PHRASED IN THOSE GL RULES AND NOTHING ELSE, which is what makes it a
// falsifiable net rather than a restatement of the implementation. Magma needs none of the
// machinery (Vulkan takes the declared format natively), a driver that DOES advertise
// GL_NV_image_formats - Mesa's, which is what the software lanes run - keeps the narrow format and
// GL_NV_image_formats - llvmpipe, which is what the software lanes run - keeps the narrow format and
// widens nothing, and all of them must produce the same numbers. A widening that forgot to mask a
// store, or masked it with the wrong constants, or widened the storage without widening the bind,
// fails these on the device while the software lanes stay green.
@@ -1003,7 +1003,7 @@ void main()
// 3 were written past the end of the application's buffer.
//
// This runs on every backend, and on a driver that CAN spell rg32f for an imageBuffer
// (Mesa's, which the software lanes use) nothing is split at all - which is the other half
// (llvmpipe, which the software lanes use) nothing is split at all - which is the other half
// of the claim: the arming has to agree with the shader, so a split that fired where the
// driver needed none would double every subscript and fail here just as loudly.
TEST_F(NonCoreImageFormatScenario, BufferImageAddressesTheApplicationsOwnTexels) {
@@ -19,7 +19,7 @@
//
// Every case uploads a level, lets the GPU clear it, writes one 2x2 box, and reads the level back:
// the clear outside the box, the write inside. The formats are picked by what they cost the ES
// upload, which is per driver - on Mesa llvmpipe GL_SRGB8, GL_RGB8_SNORM and GL_RGB8UI are stored
// upload, which is per driver - on llvmpipe GL_SRGB8, GL_RGB8_SNORM and GL_RGB8UI are stored
// four-channel (see ThreeChannelAttachmentScenario) while GL_RGB16F is native; ES has no renderable
// three-channel format at all, so on a phone all four are converted. GL_RGBA8 is the control that
// never converts. A format a backend cannot attach is skipped, not failed.
@@ -18,7 +18,7 @@
//
// DirectVulkan serves the query from the transform-feedback stream query's
// primitivesNeeded, which VK_EXT_transform_feedback defines to count whether or
// not a capture span is open. Both the Mali-G1-Ultra driver AND Mesa lavapipe
// not a capture span is open. Both the Mali-G1-Ultra driver AND lavapipe
// disagree with that definition: with no vkCmdBeginTransformFeedbackEXT recorded,
// the pair reads back 0. Where the bring-up probe measures that defect with a
// working control - or MOBILEGL_MAGMA_PRIMGEN_QUERY_REROUTE=1 pins it on - the
@@ -17,7 +17,7 @@
// until the program stops being current, so GL_CURRENT_PROGRAM still names it. GuiBatchScenario
// then replays AcceleratedRendering's save / switch / restore: it reads GL_CURRENT_PROGRAM, makes
// its compute program current - which is what finally deletes the old one - and restores the
// saved name, which no longer exists. GL_INVALID_VALUE, from MobileGL and from native Mesa alike:
// saved name, which no longer exists. GL_INVALID_VALUE, from MobileGL and from a native driver alike:
// the implementation is right and the fixture's "clean slate" was not.
//
// The two cases below run in declaration order in ONE process (the
@@ -24,7 +24,7 @@
// worse outcome, so the round trip below is pinned tightly enough to fail on a half-float substitute
// (tolerance two SNORM steps, half-float error six).
//
// WHAT THIS GATE CAN AND CANNOT SEE. Both CI drivers (Mesa llvmpipe) and Adreno expose
// WHAT THIS GATE CAN AND CANNOT SEE. Both CI drivers (llvmpipe) and Adreno expose
// GL_EXT_render_snorm, so they take the NATIVE path here and the substitution stays dead. That is
// precisely why the assertions are written as invariants of the format rather than of the fallback:
// "a signed-normalized colour attachment is complete and round-trips its channel values" has to
@@ -69,7 +69,7 @@ void main() {
// GL 4.6 core 4.10 lets a buffer variable be declared readonly AND writeonly at once:
// it can then be neither read nor written, and `.length()` is the only thing left that
// may be asked of it. The pair is inert - and printing it into ESSL is not, because
// SPIRV-Cross hoists the qualifiers every member shares onto the BLOCK and Mesa's ES
// SPIRV-Cross hoists the qualifiers every member shares onto the BLOCK and llvmpipe's ES
// compiler refuses that spelling ("Interface block sets both readonly and writeonly").
// Lifted from KHR-GL43.shader_storage_buffer_object.basic-readonly-writeonly.
constexpr const char* kReadonlyWriteonlyComputeSource = R"(#version 430 core
@@ -23,7 +23,7 @@
// actually PRODUCES that caveat. Only a live glCheckFramebufferStatus can, and the answer is
// per-driver, not per-platform:
//
// Mesa llvmpipe (the headless CI driver), ES 3.2, GL_TEXTURE_2D colour attachment:
// llvmpipe (the headless CI driver), ES 3.2, GL_TEXTURE_2D colour attachment:
// COMPLETE GL_RGB8, GL_RGB16F, GL_R11F_G11F_B10F, every RGBA*
// INCOMPLETE_ATTACHMENT GL_RGB8_SNORM, GL_SRGB8, every RGB integer format
// UNSUPPORTED GL_RGB32F
@@ -9,7 +9,7 @@
#
# Pin the vendor libraries explicitly, for the same reason
# MG_Benchmark/Driver/run_driver_bench.sh does: a bare libEGL on a glvnd system
# resolves to whatever vendor comes first, which is usually Mesa/llvmpipe - a
# resolves to whatever vendor comes first, which is usually llvmpipe - a
# software rasteriser silently replacing the GPU under a GPU test. Override
# MGL_EGL_VENDOR / MGL_VK_ICD to test another driver.
#
+1 -1
View File
@@ -17,7 +17,7 @@
// The MGPipe boundary (plan B section 4).
//
// The two interface tables are FUNCTION-POINTER STRUCTS, not virtual bases. Three reasons
// out of this repository rather than out of gallium: the boundary already is a
// out of this repository rather than out of other driver interfaces: the boundary already is a
// function-pointer struct sitting on one hook point in MG_Backend/Init.cpp; a nullptr entry
// already means "not implemented, frontend falls back", which is exactly what a
// not-yet-migrated subsystem needs to say while it keeps pulling; and MG_Test already
+2 -2
View File
@@ -15,8 +15,8 @@
// The backend -> frontend reverse channel, named (plan B section 7.1).
//
// Today this traffic is 95 call sites across 17 methods poked directly into frontend
// objects. gallium has no vocabulary for shadow writeback, GPU-write notification or
// default-framebuffer geometry, because in Mesa the state tracker and the driver share an
// objects. An in-process driver interface has no vocabulary for shadow writeback, GPU-write notification or
// default-framebuffer geometry, because in such a design the state tracker and the driver share an
// address space. Naming them as callbacks is the deliberate deviation (D8).
//
// SEVEN, NOT THE TEN PLAN B WROTE. Three went, each because nothing produces it.
+1 -1
View File
@@ -13,7 +13,7 @@
//
// A handle is a {slot, gen} pair minted by the CLIENT and never by the server: no create_*
// call in the catalogue returns a server-cast handle, which is the deliberate deviation
// from gallium (D1) that lets the whole catalogue be remoted with ZERO creation round
// from driver-minted handles (D1) that lets the whole catalogue be remoted with ZERO creation round
// trips.
//
// Slots are dense and allocated PER KIND, so the server's object table is an array rather
@@ -100,7 +100,7 @@ namespace MobileGL::MG_State::GLState {
virtual ~BackendBufferResource() = default;
};
// Mesa pipe_resource analogue for a GL buffer's storage. It owns the buffer's
// The storage resource behind a GL buffer object. It owns the buffer's
// bytes and its backend GPU resource, and abstracts WHERE the authoritative
// bytes live so no caller has to branch on the mode:
//
+1 -1
View File
@@ -954,7 +954,7 @@ namespace {
// ARCHITECTURE's third merge rule: the client emits the PROGRAM-RESOLVED set. A unit the
// shader does not sample carries no view, whatever is bound to it - which is exactly the
// gallium one-view-per-slot resolved form, and exactly what DirectGLES arrives at by
// one-view-per-slot resolved form, and exactly what DirectGLES arrives at by
// asking the program which of a unit's aliased bindings is the sampled one.
TEST(SamplerEmit, OnlyTheProgramResolvedUnitsAreEmitted) {
EmitterScope scope;
+1 -1
View File
@@ -3010,7 +3010,7 @@ void main() {
// (GLSL ES 3.00 4.3.6). SPIRV-Cross carries the dynamic index straight into the ESSL, a strict
// driver rejects the shader, the program links nothing, and every draw using it silently draws
// nothing - which is what empties the translucent layer of improved-transparency-minecraft-26.3
// on the Android DirectGLES (ANGLE) lane while Mesa, being lenient, renders it correctly.
// on the Android DirectGLES (ANGLE) lane while llvmpipe, being lenient, renders it correctly.
namespace {
Vector<Uint32> CompileFragmentToRawSpirv(const String& source) {
using namespace MG_Util::ShaderTranspiler;
+1 -1
View File
@@ -4051,7 +4051,7 @@ TEST(DirectGLESSlotTable, EverySwitchedOverKindResolvesItsTwinThroughTheHandleAr
// P4a: the EIGHTH table and the SIXTH kind - the sampler view, which is the only kind in
// the phase with no frontend object at all. MobileGL has no sampler-view class: GL binds a
// texture to a unit and the sampler uniform's type plus the two completeness predicates
// decide what the shader sees, gallium's one-view-per-slot IS that resolved form, and the
// decide what the shader sees, a one-view-per-slot model IS that resolved form, and the
// resolution moves to the CLIENT (D-F3). So this table is handle-keyed only, like the
// buffer resource table above, and its twin owns no driver id whatsoever - what it holds is
// the server's memo of one resolved view plus the raw-depth-fetch substitution decision,
@@ -971,7 +971,7 @@ TEST(DriverBugProbes, ImageCoherencyResidualIsDetectedAndQuantified) {
ExpectProbeReleasedEverything();
}
// The reason the subject is the STRONGEST shape and not the one MobileGL emits. Mesa llvmpipe
// The reason the subject is the STRONGEST shape and not the one MobileGL emits. llvmpipe
// misses every texel with `coherent` + memoryBarrierImage() and none once the pair is also
// `volatile` - a defect MobileGL could fix by emitting a different shape, which is not what
// UNFIXABLE means and does not belong in this section.
@@ -14,7 +14,7 @@
// characterised is written down here as a fake measurement so the mapping cannot
// drift without a red:
// - a conforming driver (stream counts everywhere),
// - Mesa lavapipe as measured 2026-08: stream silent everywhere, the dedicated
// - lavapipe as measured 2026-08: stream silent everywhere, the dedicated
// VK_EXT_primitives_generated_query exact everywhere (discard included), and
// the statistics control exact on the plain shape but dead under rasterizer
// discard (llvmpipe's discard short-circuit),
@@ -113,7 +113,7 @@ TEST(PrimitivesGeneratedNoXfbVerdictTest, HealthNeedsNeitherTessellationNorACont
PrimitivesGeneratedNoXfbVerdict::StreamCounts);
}
// Mesa lavapipe as measured (2026-08): stream silent for every capture-less
// lavapipe as measured (2026-08): stream silent for every capture-less
// draw, the dedicated primitives-generated query exact on every shape (discard
// included), the statistics control dead under discard. The dedicated query must
// win - it is the only substitute that covers the CTS shape there.
@@ -273,7 +273,7 @@ void main() {
// The IMAGE half, and the case that has always been broken independently of any per-element
// unit remapping: a plain CONSECUTIVE image array subscripted by a loop variable. This is
// KHR-GL42.shader_image_load_store.advanced-sso-simple's own fragment shader shape, and a raw
// GLES probe on Mesa 26.1.4 at ES 3.2 refuses the ESSL it produces with "image arrays indexed
// GLES probe on llvmpipe 26.1.4 at ES 3.2 refuses the ESSL it produces with "image arrays indexed
// with non-constant expressions are forbidden in GLSL ES". Foldable: after unrolling every
// subscript is a literal.
constexpr const char* kLoopIndexedImageArray = R"(#version 450 core
@@ -847,7 +847,7 @@ TEST(WidenImageFormats, WidenedModulesEmitEsslNamingTheCoreCarrier) {
}
}
// The narrow mode, for a driver that HAS GL_NV_image_formats - Mesa, which every software lane
// The narrow mode, for a driver that HAS GL_NV_image_formats - llvmpipe, which every software lane
// runs on. There the driver can spell rg32f, so widening it would spend two to four times the
// texture memory to change nothing; but SPIRV-Cross STILL throws for r8ui rather than printing it,
// and the throw loses the stage whatever the driver would have accepted. So the extension narrows
@@ -15,7 +15,7 @@ using MobileGL::MG_Backend::DirectVulkan::SwapchainObject;
namespace {
// What each surface reports. Android's loader exposes MAILBOX and FIFO (plus the shared
// modes with VK_KHR_shared_presentable_image) but never IMMEDIATE; Mesa's X11 WSI has
// modes with VK_KHR_shared_presentable_image) but never IMMEDIATE; a desktop X11 WSI has
// all four classic modes.
const Vector<VkPresentModeKHR> kAndroidModes{
VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR,
@@ -173,7 +173,7 @@ namespace {
// THE HARNESS'S HEADLESS PIN (HeadlessGL.cpp, EnsureHeadlessPlatform), for the servers this test
// starts itself: both the `--serve` supervisor (SupervisorEnvironment copies this process's
// environment) and the LaunchServer child inherit it, and each peer brings a pbuffer context up
// on that server. Without it Mesa takes its build-time x11 platform: on a WSLg workstation that
// on that server. Without it the host EGL takes its build-time x11 platform: on a WSLg workstation that
// binds the window system and goes green, on a runner with no DISPLAY InitPbufferSurface fails
// and every case reds before the ring ever fills. An operator's explicit EGL_PLATFORM still
// wins, as in the harness and in tcp_server_fixture.py.
+1 -1
View File
@@ -1589,7 +1589,7 @@ namespace {
// Welcome, the applied record and the clean reap of the next session - has been evaluated
// by now, and a GTEST_SKIP after a failed EXPECT still reports the case FAILED; so on such a
// host "Skipped" means "latched and served, render half not run". The CI unit job
// (.github/workflows/test.yml `test`) installs libegl1, whose Recommends brings the Mesa
// (.github/workflows/test.yml `test`) installs libegl1, whose Recommends brings the distribution's EGL
// vendor library on an Ubuntu runner; a runner without it shows these rows as Skipped and
// PresentFrameSerialZero (which needs a context to reach its site) as skipped outright.
if (b.egl == 0) {
+4 -4
View File
@@ -1541,7 +1541,7 @@ TEST(ServerLoopTest, TheSevenFormatCapabilityReadsAnswerFromTheServersBackendNot
}
// =====================================================================================
// The EGL fixture: the SERVER's real DirectGLES backend, a real headless context (mesa
// The EGL fixture: the SERVER's real DirectGLES backend, a real headless context (EGL
// surfaceless, llvmpipe) on the apply thread, driven only through v1's twelve forwarders
// =====================================================================================
//
@@ -1563,7 +1563,7 @@ TEST(ServerLoopTest, TheSevenFormatCapabilityReadsAnswerFromTheServersBackendNot
// counting 1, review v2 item 10).
//
// NO USABLE EGL IS A SKIP, UNLESS MOBILEGL_ITEST_REQUIRE_GPU SAYS OTHERWISE - the integration
// harness's own rule (ScenarioFixture.h): a developer box without mesa should not fail a run it could
// harness's own rule (ScenarioFixture.h): a developer box without headless EGL should not fail a run it could
// not perform, but a lane that relies on these cases sets the variable, and then an unusable EGL is
// a FAILURE naming the step, never a green that ran nothing (review v2 N-1's lesson).
#if !defined(_WIN32)
@@ -1588,7 +1588,7 @@ namespace {
}
// The integration harness's headless pin (HeadlessGL.cpp, EnsureHeadlessPlatform), for the same
// reason: mesa's surfaceless platform needs no display, and glvnd has to be told which vendor to
// reason: the EGL surfaceless platform needs no display, and glvnd has to be told which vendor to
// load. The vendor json is the one MG_IntegrationTest/CMakeLists.txt pins by default; an operator
// who set __EGL_VENDOR_LIBRARY_FILENAMES keeps theirs.
void PinHeadlessEglEnvironment() {
@@ -1654,7 +1654,7 @@ namespace {
// THE SURFACE'S OWN CREATION is what binds natively (InitPbufferSurface -> MakeCurrent).
if (!Server::ServerCreateEGLPbufferSurface(Surf(), 64, 64)) {
return "ServerCreateEGLPbufferSurface - no usable headless EGL (EGL_PLATFORM=surfaceless, "
"__EGL_VENDOR_LIBRARY_FILENAMES -> mesa/llvmpipe) on this box";
"__EGL_VENDOR_LIBRARY_FILENAMES -> llvmpipe) on this box";
}
return {};
}
+1 -1
View File
@@ -322,7 +322,7 @@ namespace {
EXPECT_EQ(r.glxLoaded, 1);
EXPECT_EQ(r.clientQueries, 1);
// Mesa's software-renderer selection must not disable MobileGL's EGL/GLX entry points.
// Selecting the software renderer (LIBGL_ALWAYS_SOFTWARE) must not disable MobileGL's EGL/GLX entry points.
const EntryReport software = RunEntryPoints(server.endpoint, logBase, true);
EXPECT_EQ(software.vendorDisplay, 1);
EXPECT_EQ(software.getDisplay, 1);
+1 -1
View File
@@ -18,7 +18,7 @@
// time. Do not add one here.
namespace MobileGL::MG_Util::Async {
// Stage 7: on by default. The gate behind the flip (2026-08-09, headless Mesa, both
// Stage 7: on by default. The gate behind the flip (2026-08-09, headless llvmpipe and lavapipe, both
// backends): GL30-40 mustpass + KHR-GL46.parallel_shader_compile at async=1 with the
// extension advertised - 58,344 case-runs, 8 failures, and every one of the 8 also
// fails standalone at async=0 and under the pre-P1 library, i.e. zero async-attributable
@@ -714,7 +714,7 @@ namespace MobileGL::MG_Util::BackendLoader {
eglLib = OpenLib({"libtinygl4angle.dylib"});
#else
// Versioned SONAME first. The unversioned "libEGL.so" is a development
// symlink: it ships in libegl-dev/mesa-libEGL-devel, NOT in the runtime
// symlink: it ships in the EGL development package (libegl-dev), NOT in the runtime
// package, so a machine that can run GL perfectly well may not have it -
// every stock Ubuntu/Debian runtime image, the GitHub Actions runners
// included. Asking only for the unversioned name there makes dlopen fail,
@@ -40,7 +40,7 @@ namespace MobileGL::MG_Util::SelfTest {
"void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }\n";
// No gl_PointSize anywhere: writing it from a geometry shader needs
// EXT/OES_geometry_point_size, which not every ES 3.2 driver exposes (Mesa's does not),
// EXT/OES_geometry_point_size, which not every ES 3.2 driver exposes (some desktop drivers do not),
// and a probe that fails to COMPILE reaches no verdict at all.
const char* const kProbeGeometrySource =
"#version 320 es\n"
+1 -1
View File
@@ -309,7 +309,7 @@ namespace MobileGL::MG_Util::SelfTest {
// "unfixable". Probing only the shape MobileGL emits today (`coherent` plus
// memoryBarrierImage()) reports a bug on drivers where simply adding `volatile` makes the
// read correct, which is a defect MobileGL could fix rather than one it cannot: measured on
// Mesa llvmpipe, the emitted shape misses every texel while the `volatile` shape misses
// llvmpipe, the emitted shape misses every texel while the `volatile` shape misses
// none. Only a driver that fails even the strongest shape has no in-shader substitute left.
//
// The control is the same dependency split across TWO draws with a glMemoryBarrier and a
+1 -1
View File
@@ -1986,7 +1986,7 @@ namespace MobileGL::MG_Util::SelfTest {
constexpr const char* RowName = "Subgroup first-reduction witness";
// FailOptional, not Fail. The witness reports whether the NATIVE subgroup
// first-reduction works; when it does not, the renderer takes its non-subgroup
// iteration path and draws the same image. Both an Adreno 830 and Mesa lavapipe
// iteration path and draws the same image. Both an Adreno 830 and lavapipe
// fail this row's topology check today while running the DirectVulkan backend
// perfectly well, so a fatal verdict here would have the screen announce that a
// backend the user is looking at through that very backend cannot run.
@@ -66,7 +66,7 @@ namespace MobileGL::MG_Util::SelfTest {
//
// THE CONTROL DISCIPLINE (DriverBugProbes.h): the substitute slots are the
// probe's controls, and the DISCARD dimension is measured separately because
// it is a real fault line, not paranoia: Mesa llvmpipe short-circuits its
// it is a real fault line, not paranoia: llvmpipe short-circuits its
// clipping statistics under rasterizer discard (reading 0 there while counting
// the identical undiscarded draw exactly) while its dedicated
// primitives-generated query counts both - measured 2026-08, and the reason
@@ -213,7 +213,7 @@ namespace MobileGL {
// constant-expression rule for both and the drivers refuse the whole stage
// ("indexing into an SSBO array using a non-constant expression is not
// permitted" on Qualcomm, "image arrays indexed with non-constant expressions
// are forbidden in GLSL ES" on Mesa), which loses the program while the
// are forbidden in GLSL ES" on llvmpipe), which loses the program while the
// frontend still reports GL_LINK_STATUS = TRUE. Same two halves as the
// fragment-output legalization: fold the loop-derived indices, then lower
// whatever is genuinely dynamic to a switch over the array's range. SAMPLER
@@ -24,7 +24,7 @@ namespace MobileGL {
// '[' : array indexes for fragment outputs must be constant integral expressions
//
// The program then links nothing and every draw that uses it is a silent no-op.
// Mesa accepts the same source, which is why this only ever showed on the ANGLE
// llvmpipe accepts the same source, which is why this only ever showed on the ANGLE
// lane (see tools/trace_replay/README.md, improved-transparency-minecraft-26.3:
// the whole translucent layer disappears because the OIT coefficient shader is
// exactly this shape).
@@ -24,7 +24,7 @@ namespace MobileGL {
// Qualcomm, storage blocks:
// '[' : indexing into an SSBO array using a non-constant expression is not
// permitted
// Mesa, images:
// llvmpipe, images:
// image arrays indexed with non-constant expressions are forbidden in GLSL ES
//
// glslang keeps the whole array as ONE SPIR-V variable, so SPIRV-Cross prints
@@ -38,7 +38,7 @@ namespace MobileGL {
// Verified on the device for the storage-block half: an Adreno 830 ES probe with no
// MobileGL in the loop rejects the non-constant subscript with AND without
// GL_EXT_gpu_shader5 (which the driver does advertise), and accepts a constant one.
// Verified again for the image half on llvmpipe / Mesa 26.1.4 at ES 3.2, on a raw
// Verified again for the image half on llvmpipe 26.1.4 at ES 3.2, on a raw
// GLES probe: a scalar image and an array with literal subscripts both write the
// units they name, and both a loop-variable subscript and a `const int[]` table
// lookup are refused with the message above. So the ES 3.2 "dynamically uniform"
@@ -22,7 +22,7 @@ namespace MobileGL {
// (Flywheel's glMultiDrawElementsIndirect, glDrawElementsInstancedBaseInstance)
// therefore feeds shaders an InstanceID offset by baseInstance. This pass rebases
// every load of the InstanceIndex builtin to (InstanceIndex - BaseInstance), the
// same lowering Zink/DXVK use, so the value seen by the shader matches GL's
// same lowering other API-on-Vulkan translation layers use, so the value seen by the shader matches GL's
// zero-based gl_InstanceID. Vulkan backend only - the DirectGLES transpile path
// already receives a zero-based gl_InstanceID from SPIRV-Cross.
class RebaseInstanceIndexPass : public spvtools::opt::Pass {
@@ -1060,7 +1060,7 @@ namespace MobileGL {
// The raw texel through an OpCopyObject before anything reads it, which costs
// nothing in SPIR-V and is load-bearing in the ESSL: SPIRV-Cross emits a copy
// of a non-opaque value as a real `uvec4 _n = imageLoad(...);` statement,
// where the read's own result is FORWARDED into whatever consumes it. Mesa's
// where the read's own result is FORWARDED into whatever consumes it. The
// llvmpipe compiler miscompiles the forwarded form - `vec4(imageLoad(img, c))`
// written straight into an expression comes back as zeroes, and 0xFFFF comes
// back as a NaN, while the identical arithmetic on a named uvec4 is correct.
@@ -95,7 +95,7 @@ namespace MobileGL {
// no ESSL route even on a driver that DOES advertise GL_NV_image_formats.
// SPIRV-Cross's is_desktop_only_format set - r8ui, rg16f, r16i and fifteen others -
// makes it THROW for an ESSL target rather than print a token, and the throw takes
// the stage with it whatever the driver could have accepted. Mesa is exactly that
// the stage with it whatever the driver could have accepted. llvmpipe is exactly that
// case: it advertises the extension, so nothing else needs widening there, and
// `layout(r8ui) uimage2D` still lost its whole program until this ran for it.
//
@@ -143,7 +143,7 @@ namespace MobileGL {
// harmless: GLSL ES has no `index` layout qualifier in core, so the driver
// answers "index layout qualifier requires EXT_blend_func_extended" and refuses
// the stage. The program then links nothing and every draw with it renders
// NOTHING - verified on Mesa 26.1.4 llvmpipe with no MobileGL in the process,
// NOTHING - verified on llvmpipe 26.1.4 with no MobileGL in the process,
// and it is why KHR-GL43.shader_atomic_counters.basic-program-query read back a
// black render target.
//
@@ -163,9 +163,9 @@ namespace MobileGL {
// dropping it cannot change what the shader does.
//
// Emitting it does change whether the shader EXISTS. SPIRV-Cross hoists the
// qualifiers every member shares onto the block, and Mesa's ES compiler rejects
// qualifiers every member shares onto the block, and llvmpipe's ES compiler rejects
// that spelling outright ("Interface block sets both readonly and writeonly",
// verified on Mesa 26.1.4 llvmpipe with no MobileGL in the process, against the
// verified on llvmpipe 26.1.4 with no MobileGL in the process, against the
// exact source this transpiler emitted). The stage then never compiles, the
// program links without it, and every dispatch or draw is a silent no-op -
// which is how KHR-GL43.shader_storage_buffer_object.basic-readonly-writeonly
+1 -1
View File
@@ -347,7 +347,7 @@ class Supervisor(unittest.TestCase):
Under inproc and spawn the server inherits the CLIENT's environment after
HeadlessGL.cpp's EnsureHeadlessPlatform pinned EGL_PLATFORM=surfaceless and cleared
DISPLAY/WAYLAND_DISPLAY. This supervisor is started by ctest from the job environment
instead, so on a WSLg workstation it bound Mesa's build-time default x11 platform and went
instead, so on a WSLg workstation it bound the host EGL's build-time default x11 platform and went
green, and on a runner with no window system eglInitialize failed with "xcb_connect
failed" for every session."""
seen = self.started_server_environment(DISPLAY=':0', WAYLAND_DISPLAY='wayland-0', EGL_PLATFORM=None)
+1 -1
View File
@@ -75,7 +75,7 @@ def start(args):
env.pop(key, None)
# The harness's headless pin (HeadlessGL.cpp, EnsureHeadlessPlatform), for the one server it
# does not start. Under inproc and spawn the server inherits the client's environment AFTER the
# pin; this supervisor inherits ctest's. Without it Mesa takes its build-time x11 platform: on a
# pin; this supervisor inherits ctest's. Without it the host EGL takes its build-time x11 platform: on a
# WSLg workstation that binds the window system and goes green, on a runner with no DISPLAY
# eglInitialize fails ("xcb_connect failed") and every Tcp. case reds with "remote TCP bring-up
# failed". An operator's explicit EGL_PLATFORM still wins, as it does in the harness.
+1 -1
View File
@@ -1256,7 +1256,7 @@ static void glImportFdBuffer(GlCtx& g, int fd, uint64_t allocationSize, uint64_t
if (eImport != GL_NO_ERROR) {
// Deliberately NOT closed: EXT_memory_object_fd transfers ownership of
// the fd to the implementation and does not say whether that still
// happens when the import fails, and Mesa closes it either way. A
// happens when the import fails, and llvmpipe closes it either way. A
// double close would land on whatever fd the allocator handed out
// next -- the socket, in this program. At most a handful of rungs
// run, so leaking the dup is the cheap, safe side of that trade.
+1 -1
View File
@@ -5,7 +5,7 @@ if(NOT UNIX)
return()
endif()
option(MOBILEGL_TRACE_SOFTWARE_RENDERING "Force Mesa software rendering for trace tests" ON)
option(MOBILEGL_TRACE_SOFTWARE_RENDERING "Force host software rendering (llvmpipe) for trace tests" ON)
set(MOBILEGL_TRACE_ROOT "${CMAKE_CURRENT_LIST_DIR}")
set(MOBILEGL_TRACE_SHARED_CPP_DIR "${CMAKE_SOURCE_DIR}/android-plugin/app/src/trace/cpp")