swung0x48
981f10e4da
[Fix] (MG_Impl/GLImpl): unblock the non-texture sections of GL CTS per-case state reset - clamp advertised GL_MAX_UNIFORM_BUFFER_BINDINGS to the state layer indexed-binding capacity (glBindBufferBase rejected indices past it), let glBindRenderbuffer(0) unbind without recording INVALID_OPERATION (name 0 must never reach the name-table lookup), and allow writes to generic vertex attribute 0 current value (core GL has no attribute-0 restriction; gluStateReset writes vertexAttrib4f(0,...) after every case) - with these plus the default-texture work, multi-case glcts batches complete in one process instead of aborting after the first case
2026-07-16 23:36:58 -04:00
swung0x48
076cd0d19d
[Feat] (MG_State, MG_Impl/GLImpl): per-target default texture objects (name 0) - binding 0 binds a real per-context default object (the initial binding of every unit/target slot, rebound on delete of a bound texture), so glTexImage*/glTexParameter*/glGetTex* on it work like any texture while glIsTexture(0)/Gen/Delete keep excluding it and TexStorage* rejects it per spec; backends skip image-less defaults as cheaply as the old null slots (DirectGLES per-draw sync/bind loops, DirectVulkan sampler-fallback resolve); also accept the full advertised GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS range in glActiveTexture, allow zero-layer TexImage3DMultisample, and let glTexBuffer(buffer=0) detach - the texture section of GL CTS per-case state reset (gluStateReset) now runs clean
2026-07-16 23:36:43 -04:00
swung0x48
efd7b47388
[Chore] (MG_Test): assert exact GL error counts - name-lifecycle regression tests per object family, plus fixtures that drain on setup and fail the test that leaks an unconsumed error
2026-07-16 22:12:12 -04:00
swung0x48
a08669df72
[Fix] (MG_Impl/GLImpl): stop recording GL errors on the delete/query paths of every object family - glDeleteBuffers/VertexArrays/Renderbuffers/Framebuffers must silently ignore unknown names and glIsTexture must never raise, while glBindSampler now reports INVALID_OPERATION like the other bind entry points
2026-07-16 22:11:43 -04:00
swung0x48
b8db509581
[Fix] (MG_Util/ShaderTranspiler): normalize legacy desktop shaders to GLSL 330
2026-07-16 21:39:39 -04:00
swung0x48
5d6b544021
[Fix] (MG_Impl/Texture): support anisotropic sampler parameters
2026-07-16 21:39:38 -04:00
swung0x48
346cd417ca
[Fix] (MG_Backend/DirectVulkan): fix ERROR-level vertex stream build
2026-07-16 21:36:22 -04:00
swung0x48
f61675e9ce
[Fix] (MG_Impl/Texture): validate the bound texture before dereferencing it in TexSubImage2D, and stop recording an error when glDeleteTextures is handed unknown names
2026-07-16 21:34:40 -04:00
swung0x48
8026838563
[Fix] (MG_Backend/DirectVulkan): honor scissor in glClearBuffer*/glClearNamedFramebuffer* and clamp their depth clear values to [0,1]
2026-07-16 21:18:01 -04:00
swung0x48
5bd8fa8c4e
[Perf] (MG_Backend/DirectVulkan): route full-coverage scissored glClear back to the deferred loadOp path, skip render-pass churn for no-op clears, and drop the per-clear heap Vector (extracted PrepareScissoredClear)
2026-07-16 21:18:00 -04:00
swung0x48
37ef2cb600
[Fix] (MG_Backend/DirectVulkan): materialize mid-pass pending color clears at the subpass color slot index, not the compacted description index
2026-07-16 21:18:00 -04:00
swung0x48
5184901a5b
[Fix] (MG_Backend/DirectVulkan): clear every layer of layered framebuffers in vkCmdClearAttachments paths (rename the never-read RenderPassEntry::subpass to layers)
2026-07-16 21:17:59 -04:00
swung0x48
4172959e49
[Fix] (MG_Backend/DirectVulkan): honor the front stencil write mask in scissored glClear and drop a redundant compatibility re-check
2026-07-16 21:17:58 -04:00
swung0x48
eb5b4bca3e
[Fix] (MG_Backend/DirectVulkan): ignore glClear/glClearBuffer* while GL_RASTERIZER_DISCARD is enabled, and early-out on an empty clear mask
2026-07-16 21:17:58 -04:00
swung0x48
56db115a1a
[Fix] (MG_Impl/GLImpl): clamp glClearDepth to [0,1] per GL 3.3 (Vulkan clear values require it)
2026-07-16 21:17:57 -04:00
swung0x48
b14edd515a
Merge branch 'worktree-agent-a1381c9e6b342e8d4' into dev
2026-07-16 19:47:52 -04:00
swung0x48
57030b5fb9
[Chore] (MG_Test/Texture): regression tests for 2D-array unpack subcuboid selection and TexStorage3D layer-count semantics, DirectGLES 2D-array target support, packed-format canonical transfer types, and the GL_RGB565 enum round-trip
2026-07-16 19:44:37 -04:00
swung0x48
72532de780
[Fix] (MG_Util/Texture, MG_Util/Converters): canonical packed transfer types for RGBA4/RGB565/RGB10_A2UI - NormalizePixelFormat's default handed backends GL_UNSIGNED_BYTE (and a non-integer GL_RGB transfer format for RGB10_A2UI), so uploads read 4 bytes per texel from 2-byte packed shadow rows (rgba4 layers shifted by 2x slice stride) or were rejected outright; also map GL_RGB565 <-> TextureInternalFormat::RGB5 (the enum had no GL_RGB565 mapping at all, glTexImage* with it failed as unknown)
2026-07-16 19:44:36 -04:00
swung0x48
25323bfb8e
[Fix] (MG_Backend/DirectGLES, MG_Impl/GLImpl): sync GL_TEXTURE_2D_ARRAY textures to the ES backend - the target was skipped as unsupported so array textures never uploaded or bound (every KHR-GL33.pixelstoragemodes.teximage3d case failed); also keep array layer counts constant across mip levels in TexStorage3D and generated-mip storage allocation (only true 3D textures halve depth)
2026-07-16 19:44:20 -04:00
swung0x48
9ed5dbf483
[Perf] (MG_Backend/DirectVulkan): return VkBufferResource by raw pointer from GetOrCreateResource to drop per-draw SharedPtr refcounting
2026-07-16 18:34:55 -04:00
swung0x48
075471cdbd
Merge branch 'worktree-agent-a7bc533bede191e68' into dev
2026-07-16 16:37:58 -04:00
swung0x48
8bf8f6f906
[Fix] (MG_Backend/DirectGLES, MG_Util/ShaderTranspiler): make the uniform-block cross-stage precision fix surgical - revert the global SPVC ES highp-default options (they changed emission for EVERY fragment shader: sampling code that used to inherit the effective highp default was suddenly printed as explicit mediump, regressing KHR-GL3x.texture_repeat_mode NPOT mip cases on device) and instead strip RelaxedPrecision member decorations from uniform-block-reachable structs in a DirectGLES-only SPIR-V pass, so matched blocks declare identical (highp) member precision in both stages and every other shader keeps its previous emission byte-for-byte
2026-07-16 16:36:28 -04:00
swung0x48
6a843b3088
[Fix] (MG_Backend/DirectVulkan): honor scissor in glClear
2026-07-16 12:39:55 -04:00
swung0x48
c59c15f66a
Merge branch 'worktree-agent-a7bc533bede191e68' into dev
2026-07-16 12:12:47 -04:00
swung0x48
254cf1dc21
[Fix] (MG_Util/ShaderTranspiler, MG_State, MG_Impl/GLImpl, MG_Backend/DirectGLES): GL CTS uniform_block - coerce packed/shared block layouts to std140 at source preprocess (glslang rejects them when targeting SPIR-V; std140 is the only UBO layout the pipeline emits), GL-style block reflection (array "[0]" names, per-element struct-array expansion, unused members and declared-but-unread blocks stay active), vec4-padded GL_UNIFORM_BLOCK_DATA_SIZE, std140 array strides for struct-nested arrays (glslang reflects tight strides there), arrayed-block instances share the first instance member set, glDeleteShader-flagged names stay usable while attached, and backend ESSL emits against highp default precision so relaxed block members match across stages (KHR-GL33.shaders.uniform_block on llvmpipe: 659 Fail -> 828/828 Pass)
2026-07-16 12:09:11 -04:00
swung0x48
df0e9fca71
Merge branch 'worktree-agent-af155789372f0003b' into dev
2026-07-16 11:30:03 -04:00
swung0x48
0005a50517
[Feat] (MG_Backend/DirectGLES): packed-type readback encoding - repack wide RGBA reads into all GL 3.3 packed pixel types (3_3_2/2_3_3_REV, 5_6_5(_REV), 4_4_4_4(_REV), 5_5_5_1/1_5_5_5_REV, 8_8_8_8(_REV), 10_10_10_2/2_10_10_10_REV, packed-float 10F_11F_11F_REV and shared-exponent 5_9_9_9_REV) for ReadPixels/GetTexImage; conversion helpers extracted to context-free ReadbackImpl (Utils.cpp) with unit tests asserting exact packed words against the GL CTS pack_* oracle layouts
2026-07-16 11:08:02 -04:00
swung0x48
f896c7396f
[Fix] (MG_Impl/GLImpl): TexImage3D - apply ConvertInternalFormatToSized like 2D/1D so unsized-internal 3D uploads get channel/type conversion, skip proxy shadow allocation, auto-generate mipmaps; TexSubImage3D - bound level and region against the target mip
2026-07-16 10:54:48 -04:00
swung0x48
1cefb9780b
[Feat] (MG_State, MG_Util, MG_Impl/GLImpl, MG_Backend/DirectGLES): desktop-GL single-channel client formats GL_GREEN/GL_BLUE/GL_ALPHA and _INTEGER variants - validate and readback via wide-RGBA channel extraction (GL CTS packed_pixels rgba8_format_green/blue read with them), unpack GREEN/BLUE(_INTEGER) TexImage uploads into the named channel with 0/1 defaults per table 3.3; GL_ALPHA keeps the legacy Red upload mapping (R8 storage + 000R swizzle), its readback corrected at the backend to source channel 3
2026-07-16 06:47:33 -04:00
swung0x48
bae222227a
[Fix] (MG_Backend/DirectGLES, MG_Impl/GLImpl): ReadPixels - fall back to wide-format conversion when the ES driver rejects a legacy native read combo (Adreno errors on e.g. GL_RED/GL_UNSIGNED_INT and leaves the buffer untouched), and enforce packed-type/format pairing at the state layer via shared ValidateClientFormatTypePairing (GL_RED + GL_UNSIGNED_SHORT_5_6_5 now raises GL_INVALID_OPERATION)
2026-07-16 06:11:53 -04:00
swung0x48
12a67f596c
[Fix] (MG_Backend/DirectGLES): upload shadow mips with UNPACK_ALIGNMENT=1 - shadow rows are tightly packed but uploads ran with alignment 4, shifting every row of non-multiple-of-4-width textures by one pixel (R8 7-wide CTS gradients read back diagonally)
2026-07-16 05:52:01 -04:00
swung0x48
274c234aff
[Fix] (MG_State/ErrorState): GL error flags are sticky per error code, not an unbounded queue - repeated same-code errors accumulated and leaked into later unrelated glGetError checks (GL CTS "Texture state reset failed" deinit noise and false "Error during glGetTexImage" failures)
2026-07-16 05:29:46 -04:00
swung0x48
20e1b417cc
[Fix] (MG_Util/Texture): expand channels and convert component types on texture unpack to the internal shadow layout
2026-07-16 04:39:57 -04:00
swung0x48
4dbdbd3bcd
Merge branch 'worktree-agent-acd555500daee6840' into dev
2026-07-16 04:13:25 -04:00
swung0x48
5eeba29579
[Fix] (CI): resume interrupted fixture downloads
2026-07-16 04:11:48 -04:00
swung0x48
dae8a40af1
Merge branch 'worktree-agent-a08726da20d78531a' into dev
...
# Conflicts:
2026-07-16 03:57:12 -04:00
swung0x48
8b78379f6f
[Feat] (MG_Backend/DirectVulkan): implement combined depth-stencil texture upload via per-aspect de-interleaved staging copies
2026-07-16 03:54:33 -04:00
swung0x48
535e9f8b15
[Fix] (MG_Util/Metrics): correct Depth32FStencil8 shadow texel size (16->8) and FLOAT_32_UNSIGNED_INT_24_8_REV type size (4->8) to the GL client transfer layout
2026-07-16 03:54:33 -04:00
swung0x48
b9844ed7c1
[Fix] (MG_Util/Texture): infer RGBA8 for packed RGBA uploads
...
(cherry picked from commit 1146188ed4 )
2026-07-16 03:41:29 -04:00
swung0x48
f0ed5c1b8e
[Fix] (MG_Backend/DirectGLES): convert narrow client formats (RED/RG/RGB/BGR/BGRA + integer variants, byte/short/half/8888 types) in GetTexImage/ReadPixels via wide RGBA readback
2026-07-16 03:40:54 -04:00
swung0x48
b604188849
Merge branch 'worktree-agent-aae96e27d8b07e982' into dev
2026-07-16 03:32:39 -04:00
swung0x48
cf8f928db8
[Fix] (MG_Impl/GLImpl, MG_State): fallback UBO backing for optimizer-eliminated uniforms (null-MapUBO SIGSEGV in KHR-GL33 do_while loops) + per-element locations/offsets for array uniforms incl. nested struct arrays (size assert in KHR-GL33 struct.uniform); demote uniform write assert to log-and-clamp
2026-07-16 03:31:32 -04:00
swung0x48
176d130f09
[Fix] (MG_Backend): GetTexImage level-range check was off-by-one (max level is inclusive; single-level textures asserted on level 0), demoted to logged skip; advertise GL_ARB_texture_storage_multisample (entry points already implemented - unadvertised extension left null glw pointers and CTS framebuffer_blit jumped to address 0)
2026-07-16 03:06:03 -04:00
swung0x48
0b94e02de5
[Fix] (MG_Backend/DirectVulkan): skip combined depth-stencil texture data uploads instead of recording invalid single-copy with multi-bit aspect mask (VK_INCOMPLETE at vkEndCommandBuffer killed the process); proper per-aspect de-interleave tracked separately
2026-07-16 02:36:07 -04:00
swung0x48
fe7a5ee1b2
[Fix] (MG_Impl/GLImpl, MG_State, MG_Backend/DirectGLES): eliminate packed_pixels SIGTRAPs - complete TexImage format/type/internalformat validation matrix (depth-stencil family, integer-ness, packed-type pairing, 3D depth rejection), fix inverted UpdateSubData assert with clamped copy, demote unimplemented readback asserts to logged no-ops
2026-07-16 02:23:18 -04:00
swung0x48
5331150cb9
[Fix] (MG_Util/ShaderTranspiler): stop stripping precision qualifiers - the strip corrupted "precision highp float;" into invalid syntax; glslang accepts and ignores them natively in 460 core (unblocks ~2000 GL CTS cases per backend)
2026-07-16 01:50:33 -04:00
swung0x48
dc2f3a477b
[Chore] (MG_Backend/DirectGLES): demote UBO ring creation log to debug level
2026-07-16 00:10:14 -04:00
swung0x48
21753b0e4c
[Fix] (MG_Backend/DirectGLES): UBO ring - preserve generation across ES context recreation, retire frame marks at Present to bound growth
2026-07-16 00:10:14 -04:00
swung0x48
f509b19b1d
[Fix] (MG_Backend/DirectGLES): UBO ring review fixes - invalidate array-buffer bind cache on failed ring creation, bump generation on emergency drain, division-based alignment rounding
2026-07-16 00:10:13 -04:00
swung0x48
c7ac5de28e
[Chore] (MG_Backend/DirectGLES): log global-UBO ring creation
2026-07-16 00:10:13 -04:00
swung0x48
2e7073a890
[Perf] (MG_Backend/DirectGLES): replace per-draw global-UBO glBufferSubData with a persistent-mapped ring allocator (fence-watermark reclaimed, MOBILEGL_DISABLE_UBO_RING opt-out); scrub stale indexed-binding shadow on glDeleteBuffers
2026-07-16 00:10:12 -04:00
swung0x48
305701326c
[Fix] (MG_Util/SelfTest): preserve POST checks before format probing
2026-07-16 00:10:12 -04:00
swung0x48
8c89b1618a
[Feat] (MG_Backend, android-plugin): show format capability tables in POST
2026-07-16 00:10:11 -04:00
swung0x48
3e4ce5caa7
[Refactor] (MG_Impl/GLImpl): replace Flywheel dispatch sync hack with MOBILEGL_COHERENT_AS_FLUSH
2026-07-15 21:51:20 -04:00
swung0x48
f80f6f4a62
[Fix] (CI): retain fixtures for failed retraces
2026-07-15 04:36:15 -04:00
swung0x48
66caf907fd
[Fix] (CI): remove intermediate trace artifacts
2026-07-15 02:52:03 -04:00
swung0x48
d3150399c7
[Fix] (CI): download direct trace APK artifact
2026-07-15 02:01:53 -04:00
swung0x48
f1c6a12c06
[Fix] (CI): use full commit SHAs
2026-07-15 01:33:56 -04:00
swung0x48
947442ec78
[Fix] (CI): resolve trace APK by SHA
2026-07-15 01:27:09 -04:00
swung0x48
165dd003d7
[Chore] (CI): clean intermediate artifacts
2026-07-15 00:53:50 -04:00
swung0x48
b852ced3c1
[Chore] (CI): upgrade GitHub Actions runtimes
2026-07-15 00:36:08 -04:00
swung0x48
4a03d62b91
[Fix] (CI): publish APK artifacts directly
2026-07-15 00:34:52 -04:00
swung0x48
056574eebe
[Fix] (CI): name APK artifacts by commit
2026-07-15 00:22:12 -04:00
swung0x48
e61685547a
[Fix] (CI): locate unified trace APK
2026-07-15 00:17:08 -04:00
swung0x48
7ebaf43282
[Refactor] (Android plugin): unify renderer APK with Plugin V2 DSL
2026-07-14 23:37:21 -04:00
swung0x48
15580ff6a6
[Fix] (Retrace): preserve bundled ANGLE binaries
2026-07-15 08:46:28 +08:00
swung0x48
fd6f5bca83
[Fix] (Retrace): rely on APK signing for bundled ANGLE
2026-07-15 07:50:40 +08:00
swung0x48
b6d311f20b
[Fix] (Retrace): bundle and select signed ANGLE variants
2026-07-15 06:48:10 +08:00
swung0x48
9c0d5517bd
[Refactor] (MG_Backend/DirectVulkan): replace null-renderer guards with MOBILEGL_ASSERT
...
Drops the if (!pVulkanRenderer) { return; } / !MG_State::pGLContext early-return guards across DirectVulkan.cpp in favor of MOBILEGL_ASSERT, matching the pattern already used by the rest of the backend. Legitimate runtime conditions (index bounds, sync/query handle nullness, renderer-generation mismatch, timer-query support) are kept as real checks; only the null-pointer defenses are converted.
2026-07-14 03:55:41 -04:00
swung0x48
3445ab9304
[Refactor] (MG_Backend/DirectVulkan, trace-replay): extract dump-image capture out of MobileGL backend
...
Moves snapshot capture entirely into the apitrace retrace layer (glReadPixels + PNG encode). Drops the MOBILEGL_PRESENT_DUMP_PATH / MOBILEGL_PRESENT_STATS / MOBILEGL_PRESENT_DUMP_CALL / MOBILEGL_PRESENT_CURRENT_CALL / MOBILEGL_TRACE_CURRENT_CALL_OVERRIDE plumbing from Config, ConfigLoader, VulkanRenderer (GetPresentedDumpPixel/WritePresentedDumpPpm + present-stats readback), the EGL/GLX/Android ws shims, and the Android trace_replay_core PPM reader.
DirectVulkan ReadPixels on the default framebuffer now remaps raw swapchain pixels (top-left origin, preTransform-rotated) to GL orientation (bottom-left origin) so the retrace snapshot matches the golden; SwapchainObject also resizes the default-FBO stencil attachment to the swapchain extent to fix GL_INVALID_FRAMEBUFFER_OPERATION under the glReadPixels completeness check.
2026-07-14 02:40:20 -04:00
swung0x48
533219ede7
[Fix] (Retrace): load ANGLE through LD_LIBRARY_PATH
2026-07-13 21:20:02 -04:00
swung0x48
b1f55026af
[Chore] (MobileGL/ConfigLoader): rename/clean up more env var clutter
2026-07-13 20:45:40 -04:00
swung0x48
a26e9aaf25
[Refactor] (MG_Config, MG_Backend, trace-replay): remove unused stats instrumentation
2026-07-13 20:33:31 -04:00
swung0x48
a55a0645e2
[Refactor] (MG_Config, MG_Backend/DirectVulkan, trace-replay): centralize Magma env parsing and rename R11G11B10F fallback
2026-07-13 19:58:06 -04:00
swung0x48
e529e12d27
[Perf] (MG_Backend/DirectVulkan): bind GetBoundObject/GetSamplerObject const-ref returns by reference in BindProgramUniformBuffers resolve paths (UBO/SSBO/texel/sampler override) instead of copying the SharedPtr; ResolveUniformBufferPayload 2.2%->1.6%
2026-07-13 08:27:12 -04:00
swung0x48
e78eee972e
[Perf] (MG_Backend/DirectVulkan): store the resolved TextureResource pointer in the per-draw sync memo so repeat SyncTextureAndGetDescriptor calls skip the resource-map lookup
2026-07-13 06:53:37 -04:00
swung0x48
37cd5b42de
[Perf] (MG_Backend/DirectVulkan): drop redundant per-draw work in UploadAndBindVertexBuffers - pass programObj from SetupDraw, use the VAO attribute's buffer SharedPtr directly instead of re-resolving by external index; 8.5%->6.2%
2026-07-13 05:21:57 -04:00
swung0x48
7fe5247626
[Fix] (MG_Backend/DirectVulkan): key the sampled-set walk-skip on a program lifetime id, not the recyclable GL name, so a deleted+recreated program can't false-hit the cache
2026-07-13 04:58:05 -04:00
swung0x48
f098983c9f
[Perf] (MG_Backend/DirectVulkan): skip the per-draw sampled-texture walk when the bound set is unchanged (texture-bind generation + program state version); CollectSampledTextures 5.0%->0.2%, fps 228->249
2026-07-13 04:41:14 -04:00
swung0x48
516d2a659e
[Perf] (MG_Backend/DirectVulkan): cache resolved VkSampler per binding to skip the per-draw sampler key hash, keyed on a new sampler lifetime id
2026-07-13 02:04:57 -04:00
swung0x48
808c5dcc46
[Perf] (MG_Backend/DirectVulkan): re-land content-version texture early-out; bump content version on glGenerateMipmap so cached sampled views re-sync (fixes Iris shader retrace)
2026-07-13 00:50:09 -04:00
swung0x48
ecea8054a6
Revert content-version texture early-out ( e8e1521): the SyncTexture cross-draw skip breaks Iris shader retrace validation (correctness regression)
2026-07-12 23:27:54 -04:00
swung0x48
b0076af9bd
[Perf] (MG_Backend/DirectVulkan): raw-ptr in ResolveSamplerDescriptor drops the per-draw SharedPtr refcount on the sampler descriptor path
2026-07-12 22:48:05 -04:00
swung0x48
24cf1e3a7f
[Perf] (MG_Backend/DirectVulkan): frames-in-flight from MOBILEGL_MAGMA_FRAMESINFLIGHT env (fallback 3), clamped to surface maxImageCount at init
2026-07-12 20:35:05 -04:00
swung0x48
e5ee4cde4f
[Perf] (MG_Backend/DirectVulkan): deepen frame pipeline 2->3 to hide GPU-completion latency; cross-frame glClientWaitSync fence stalls -28%
2026-07-12 19:42:35 -04:00
swung0x48
e8e1521972
[Perf] (MG_Backend/DirectVulkan): skip cross-draw re-sync of unchanged textures via a content-version early-out; SyncTextureAndGetDescriptor 8.9%->2.4%
2026-07-12 18:40:48 -04:00
swung0x48
6f53b9a6bb
[Perf] (MG_Backend/DirectVulkan): raw-ptr sampled-texture walk skips SharedPtr refcount churn per draw
2026-07-12 10:51:15 -04:00
swung0x48
acaa9f6dc7
[Perf] (MG_Backend/DirectVulkan): zero-copy UBO bind - point descriptor at the app's persistent VkBuffer instead of a per-draw transient copy; fps 127->166
2026-07-12 10:11:49 -04:00
swung0x48
375f2df694
[Perf] (MG_Backend/DirectVulkan): skip per-draw pipeline resolution when pipeline state unchanged; SetupDraw 54%->51%, fps 109->127
2026-07-12 09:28:30 -04:00
swung0x48
542e50be33
[Perf] (MG_Backend/DirectVulkan): skip per-draw render-pass hash when framebuffer state unchanged; SetupDraw 60%->54%, fps 96->109
2026-07-12 08:18:37 -04:00
swung0x48
ad9ee99521
[Perf] (MG_Backend/DirectGLES): dedup per-draw indexed UBO/SSBO binds with a shadow cache; BindCurrentProgramWithResources 5.1% -> 3.1%
2026-07-12 06:32:18 -04:00
swung0x48
25395a9f9a
[Docs] (MG_Backend/DirectGLES): TODO for buffer-pool Phase 2 orphan-on-respecify
2026-07-12 05:37:03 -04:00
swung0x48
d7029952bb
[Perf] (MG_Backend/DirectGLES): recycle idle GL buffers via a fence-gated size pool instead of glDeleteBuffers; pinned fps 184->220
2026-07-12 05:28:34 -04:00
swung0x48
340449b77e
[Perf] (MG_State, MG_Backend/DirectGLES): skip never-touched buffer bind points via high-water mark; SyncNeccessaryBuffers 15.7% -> 4.2%
2026-07-12 04:31:34 -04:00
swung0x48
527e229ac8
[Perf] (MG_Backend/DirectGLES): drop redundant per-draw UBO binding-point sync; BindCurrentProgramWithResources already rebinds them
2026-07-12 04:11:23 -04:00
swung0x48
d5bc753764
[Perf] (MG_Backend/DirectGLES): skip scratch bind + upload for fully-synced mipmap textures
2026-07-12 04:11:22 -04:00
swung0x48
436f7f7e86
[Perf] (DirectGLES): shadow-track unpack state instead of glGetIntegerv
...
ScopedDefaultUnpackState saved the backend GL unpack state with 6 glGetIntegerv
calls on every construction. glGetIntegerv forces a driver pipeline sync, and
because it ran per dirty texture per frame in the texture upload path, it
dominated the DirectGLES draw path - and stalling the pipeline serialized CPU-GPU
work far beyond its raw CPU cost.
The backend unpack state is set only by MobileGL's own save/restore helpers
(ScopedDefaultUnpackState, TempPixelStoreParameterSync, the R32F copy path), all
of which restore to the resting GL default, so it can be shadow-tracked: read the
previous state from a static shadow (no query), pin the backend to the known
default once up front, and set state with compare-and-set so the paired
glPixelStorei calls also usually no-op.
Device-verified on Adreno 830 (MC 26.3-snapshot3, Espryt, CPU pinned to 1.56/1.96
GHz for a thermally-comparable measurement): rendering correct; fps 105 -> 147
(+40%); render-thread profile: glGetIntegerv ~9% -> below noise, SyncNeccessary-
Textures 25% -> 12%, SyncMipmapsToBackend 23% -> 9%.
2026-07-12 03:11:28 -04:00
swung0x48
009e37ec6f
[Perf] (DirectVulkan): reuse descriptor set across draws with identical bindings
...
BindProgramUniformBuffers rebuilt a fresh descriptor set and called
vkUpdateDescriptorSets on every draw, even when consecutive draws bound the exact
same textures/samplers/buffers (common in MC: many draws share a program + atlas).
Now, after resolving the bindings (still needed for the UBO dynamic offset),
compute a cheap word-wise signature of the resolved descriptor content + layout;
when it matches the previous draw, reuse that descriptor set and skip
AcquireDescriptorSet + vkUpdateDescriptorSets - only the bind-time dynamic offsets
differ.
Correct by construction: bindings are re-resolved every draw so the signature
always reflects current state and reuse only happens on an exact match; the reused
set is never re-acquired within a frame (the acquire cursor only advances); the
descriptor set layout is in the signature so reuse never crosses programs; the
cache resets each frame in BeginFrame when the frame's sets are recycled; sampler
overrides (blits) bypass and invalidate it. The signature hashes 64-bit words (the
Vk*Info payloads are 8-byte-multiple sized and value-initialized) so its own
per-draw cost stays small.
Device-verified on Adreno 830 (MC 26.3-snapshot3, optimized -O2 Magma): rendering
correct, no validation errors. Render-thread wall-clock profile:
BindProgramUniformBuffers 22.85% -> 19.82% (vkUpdateDescriptorSets ~5% dropped below
noise; word-wise signature adds ~0.6% self), SetupDraw 62% -> 60%.
2026-07-12 01:55:31 -04:00
swung0x48 and Claude Opus 4.8
b253df881d
[Perf] (DirectVulkan): memoize per-draw texture sync in SetupDraw
...
Each sampled texture was resolved ~3x per draw: SetupDraw's layout-probe
loop, its post-transition loop, and again inside ResolveSamplerDescriptor.
No GL texture mutation happens mid-SetupDraw, and layout is tracked on the
TextureResource independently of SyncTexture, so the repeat SyncTexture work
(mip-completeness / resource+view resync / dirty scan) is pure redundancy.
Add a per-draw memo in VkTextureManager (BeginDrawSyncScope/EndDrawSyncScope
+ RAII DrawSyncScope guard around SetupDraw): after the first successful sync
of a texture in a draw, repeat SyncTextureAndGetDescriptor calls short-circuit
to the already-synced resource.
Device-verified on Adreno 830 (MC 26.3-snapshot3, Magma): rendering correct,
no validation errors; wall-clock profile of the render thread shows
SyncTextureAndGetDescriptor dropping from 15.2% to ~5% and SetupDraw from
43.7% to 28.9%.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-11 22:06:28 -04:00
swung0x48
c1743aa42d
[Refactor] (MG_State, MG_Backend): PipeResource storage layer + zero-copy coherent persistent maps
...
Introduce a Mesa pipe_resource-style PipeResource that owns a GL buffer's bytes
and its backend GPU resource, abstracting WHERE the authoritative bytes live:
- Shadow mode (non-persistent buffers): a CPU Vector; the backend keeps its own
GPU copy in sync via BufferBackendOps, exactly as before.
- Persistent mode (coherent GL_MAP_PERSISTENT maps): the backend's host-visible,
COHERENT, persistently-mapped GPU memory is the single source of truth. The app
writes into it directly, every reader resolves against it, and NO per-write
backend transfer happens. The CPU shadow is released.
BufferObject no longer owns a raw shadow Vector; it holds a PipeResource and
exposes one accessor, MappedData(), that all readers go through. Every buffer-data
consumer (UBO payload, PBO texture upload, indirect draws, resident/streamed
uploads, both backends) was migrated from GetDataReadOnly()->data() to
MappedData(), so a persistent buffer's readers see GPU memory - not a stale
shadow. That stale-shadow inconsistency is what corrupted rendering (wrong UBOs ->
misplaced/"lost" vertices) in the first zero-copy attempt (625c8a6, reverted in
896cafc); routing every consumer through one accessor makes it structurally
impossible.
Backends provide the map via BufferBackendOps::AcquirePersistentMap:
- DirectVulkan: a HOST_VISIBLE|HOST_COHERENT (required, not just requested),
persistently mapped resident VkBuffer carrying every usage, seeded from the
shadow, never recreated; AcquireResidentSlice binds it directly.
- DirectGLES: EXT_buffer_storage immutable persistent+coherent glMapBufferRange,
falling back to the shadow when the extension is absent.
Fixes the ~7GB GpuMemory OOM + 100%-CPU/ANR running modern Blaze3D Minecraft on
both Magma and Espryt (per-draw whole-buffer re-upload of the coherent persistent
ring buffer), without the coherency/stale-read hazards of the reverted attempt.
BufferTest: zero-copy stress guard (15,360 draws -> 0 per-draw transfers, and every
reader resolves to GPU memory) + a shadow-fallback test. Host suite: 203/203 pass.
Device verification pending.
2026-07-11 20:18:38 -04:00