Commit Graph
1886 Commits
Author SHA1 Message Date
swung0x48andClaude Fable 5 bd208783d7 [Perf] (MG_Backend/DirectVulkan, MG_State): stop re-deriving per-draw state
- Memoize the program content hash on ProgramObject (keyed by the backend
  state version + compile flags; relinking and binding changes invalidate
  it) and the vertex-input hash on VertexArrayObject (keyed by a new
  aggregate config version bumped by every attribute mutation). Full-SPIRV
  XXH64 hashing fell from 13.7% to 1.4% of the render thread.
- ProgramObject also gains a link version and a global-UBO content version
  (bumped by uniform writes and on relink, wrap-safe around the backends'
  "never uploaded" sentinel) for backends to gate uploads and link caches.
- Reuse member scratch vectors in SetupDraw, UploadAndBindVertexBuffers,
  GetOrCreatePipeline and BindProgramUniformBuffers instead of allocating
  per draw (~12% of render-thread time was in the allocator).
- Replace hot-path dynamic_cast with AsMipmapTexture (storage-type tag +
  static_cast); TextureObjectMipmap is the only Mipmap-tagged branch.
- Register/prune texture aliases only when a new (texture, lifetimeId)
  identity appears instead of scanning the entire alive map on every
  sampled-texture sync.
- Make the fallback VkPresentModeKHR log strings report the actual mode.

Vanilla render-thread share of libMobileGL dropped from 48% to 35% on
DirectVulkan (simpleperf, Adreno 830).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 12:12:50 +00:00
swung0x48andClaude Fable 5 08e808ef20 [Perf] (MG_State/FastSTL): make object deletion cheap again
- GLContext::MarkBufferObjectForDeletion now detaches the deleted buffer
  only from the currently bound VAO (GL 4.6 5.1.2 semantics; other VAOs
  keep their shared_ptr attachments alive). The old every-VAO scan was
  O(VAOs) per delete - with one VAO per chunk section, vanilla chunk
  churn made it dominate the render thread and FPS decay over minutes.
- Bump FastSTL: erase(key) destroys in place instead of building the
  discarded successor iterator (a linear bucket-array scan), and switch
  the buffer/framebuffer/renderbuffer deletion paths to the key overload.

Together these removed the 34% render-thread deletion overhead measured
in aged vanilla sessions (simpleperf, Adreno 830 / DirectVulkan).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 12:12:50 +00:00
swung0x48andClaude Fable 5 bb3a18c627 [Fix] (MG_Backend/DirectGLES): rebind image uniforms to frontend image units
139de763 started preserving layout(binding) on SSBO/image declarations in
transpiled ESSL (ES cannot rebind either through the API). That is correct
for SSBOs and for images whose GL source carries an explicit binding
(Flywheel), but wrong for image uniforms without one: glslang auto-assigns
a binding during transpile, while the app addresses the unit through
desktop-GL semantics - the link-time default (0) or glUniform1i, which ES
forbids on image uniforms. Iris/Photon picks image units with glUniform1i,
so its compute passes (auto exposure / colored light) read and wrote the
transpiler-invented units instead: the photon-v1.3b retrace came out dark
and orange-tinted (ssim 0.65 vs golden).

Rewrite every image uniform declaration's binding qualifier to the
frontend-tracked unit (layout binding reflected at link, overridden by any
later glUniform1i) when transpiling for the backend. Flywheel's explicit
bindings rewrite to the same value; Iris packs get the unit the app
actually bound with glBindImageTexture.

Verified on llvmpipe DirectGLES: photon-v1.3b retrace 0.652 -> 0.9988,
photon-v1.1 control stays at 0.9991, all 147 unit tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:06:01 +00:00
swung0x48andClaude Fable 5 74ae1e4a29 [Fix] (MG_Test): expect resolved effective offset in DSA VAO test
Since the ARB_vertex_attrib_binding state model (9fbb708e), the flat
VertexAttribute view backends consume holds the resolved effective
offset (binding offset + relative offset), so
glVertexArrayVertexBuffer(offset=16) + glVertexArrayAttribFormat(
relativeoffset=12) yields Offset == 28. The old expectation of 12
encoded the pre-refactor bug where the binding offset was clobbered
by the last call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 07:41:32 +00:00
swung0x48andClaude Fable 5 139de76347 [Fix] (MG_State/MG_Impl/MG_Backend): render Flywheel instanced+indirect on both backends
Create 6 / Flywheel 1.0.6 now renders correctly with both flywheel:instancing
and flywheel:indirect on DirectGLES and DirectVulkan (verified in-game on
Adreno 830: waterwheels and cogwheels solid, animated, correct pairing, no
crashes across all four combinations).

- MG_State/MG_Impl: sync explicitly-ranged SSBO bindings of FLUSH_EXPLICIT
  persistent maps to the backend before compute dispatches. Flywheel writes
  its scatter-copy descriptors into the staging ring's persistent map and
  never flushes that span (UB per spec, works on drivers whose maps alias
  GPU-visible memory); our maps alias the CPU shadow, so the descriptors
  never reached the GPU: the scatter compute copied nothing (GLES: empty
  draw commands) or stale garbage (Vulkan: wild indirect commands ending in
  VK_ERROR_DEVICE_LOST).
- MG_Impl/MG_Backend: real glFenceSync objects backed by backend fences
  (GLES: native ES syncs guarded by context generation and owner thread;
  Vulkan: buffer-manager frame serials), replacing always-signaled stubs
  that let Flywheel reclaim staging memory the GPU still reads.
- MG_Backend/DirectGLES: compute dispatches now run the same per-program
  resource sync as draws (uniform-block bindings and sampler units must be
  re-established through the API because layout(binding) is stripped from
  transpiled ESSL) and rebind texture units afterwards; the cull shader
  used to read a stale _FlwFrameUniforms binding and the depth-pyramid
  downsample sampled a stale unit-0 texture, zeroing the Hi-Z pyramid and
  occlusion-culling all Flywheel geometry. Image uniforms are excluded from
  glUniform1i (ES bakes their unit via layout(binding)); image-unit sync is
  clamped to the device limit; eliminated/SSBO-classified uniform blocks
  are skipped.
- MG_Backend/DirectGLES: gl_BaseInstance in native indirect draws reads the
  GPU-written command buffer through an injected mg_IndirectParams SSBO
  view addressed per draw instead of the zero CPU shadow; layout(binding)
  is preserved for SSBO/image declarations (ES has no API rebinding for
  them); the ES context ownership claim moved to a global atomic owner
  thread with an EGL ground-truth check, and deferred buffer op state is
  mutex-guarded, so ops cannot silently no-op after context migration.
- MG_Backend/DirectVulkan: new RebaseInstanceIndexPass rewrites vertex
  InstanceIndex loads to (InstanceIndex - BaseInstance). glslang's relaxed
  Vulkan mode aliases gl_InstanceID to InstanceIndex, which includes
  firstInstance, but GL's gl_InstanceID is zero-based - draws with nonzero
  baseInstance paired meshes with wrong instance data (cogwheel drawn as a
  waterwheel, another wheel collapsed invisible). Gated on the
  shaderDrawParameters device feature. Sampled-read barriers additionally
  cover the compute stage (the Hi-Z downsample samples the depth
  attachment from compute), and short uniform-buffer ranges keep the
  existing zero-padding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 06:30:10 +00:00
swung0x48andClaude Fable 5 2395a6ded2 [Fix] (MG_Backend/DirectGLES): always use native indirect draws with a bound buffer
Adreno (830) exposes no GL_EXT_base_instance, and gating the native path
on it sent Flywheel's whole MDI call to the CPU loop, which reads the
stale shadow instanceCount (0) and draws nothing. A non-zero reserved
word is benign on mobile drivers, instanced arrays were never
baseInstance-offset in the emulation anyway, and the CPU loop can never
see GPU-written commands - native is strictly better.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 13:47:45 +00:00
swung0x48andClaude Fable 5 41b15955b0 [Fix] (MG_Impl): export real glNamedFramebufferTextureLayer
The GLImpl implementation existed but the exported symbol was still a
stub; Flywheel's indirect OIT framebuffer attaches array-texture layers
through it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 13:35:34 +00:00
swung0x48andClaude Fable 5 07055bb531 [Fix] (MG_Backend/DirectGLES): bind GL_DRAW_INDIRECT_BUFFER for native indirect draws
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 13:34:31 +00:00
swung0x48andClaude Fable 5 638999213e [Feat] (MG_Backend/DirectVulkan): native GPU indirect draws + draw parameters
- Enable multiDrawIndirect and shaderDrawParameters device features when
  supported (the latter via VkPhysicalDeviceShaderDrawParametersFeatures on
  Vulkan 1.1+), so DrawIndex/BaseInstance SPIR-V builtins are valid and
  vkCmdDrawIndexedIndirect(Count) may draw more than one command.
- Plain glMultiDrawElementsIndirect no longer requires a GL_PARAMETER_BUFFER
  (it previously drew nothing for the standard Flywheel call); it now issues
  a native vkCmdDrawIndexedIndirect, with a per-command loop fallback when
  the multiDrawIndirect feature is unavailable.
- glDrawElementsIndirect / glDrawArraysIndirect / glMultiDrawArraysIndirect
  read the live GPU buffer via native indirect draws instead of the CPU
  shadow (which cannot see compute-written commands); the CPU path remains
  only for client-memory commands.
- Advertise the same five extensions as DirectGLES for Flywheel's
  capability probe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 13:33:05 +00:00
swung0x48andClaude Fable 5 5ea49f3c50 [Feat] (MG_Backend/DirectGLES): support Flywheel indirect rendering
- Advertise ARB_gpu_shader5 / ARB_multi_bind / ARB_shading_language_420pack /
  ARB_vertex_attrib_binding / ARB_shader_image_size so LWJGL reports
  SUPPORTS_INDIRECT.
- New LowerDrawParametersPass demotes DrawIndex/BaseInstance/BaseVertex
  builtins to Private globals (mg_DrawID/mg_BaseInstance/mg_BaseVertex) for
  the ESSL transpile; SPIRV-Cross otherwise throws for ES profiles. The
  program manager promotes the emitted globals to uniforms and feeds them
  per (sub-)draw.
- Indirect draws now execute natively on the GPU (glDrawElementsIndirect /
  glDrawArraysIndirect per command) when an indirect buffer is bound, so
  compute-written command fields (Flywheel culling updates instanceCount)
  are honored; detects GL_EXT_base_instance and falls back to the CPU loop
  when the command's baseInstance cannot be consumed natively.
- Sync SSBO binding points for graphics draws, not just compute (Flywheel
  vertex shaders read instance data from SSBOs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 13:33:05 +00:00
swung0x48andClaude Fable 5 9fbb708e64 [Feat] (MG_State/MG_Impl): ARB_vertex_attrib_binding + ARB_multi_bind state model
Add a separate binding-point model to VertexArrayObject with eager
resolution into the flat per-attribute view backends already consume.
Implements glBindVertexBuffer(s), glVertexAttrib(I)Format,
glVertexAttribBinding, glVertexBindingDivisor and the DSA variants
(glVertexArrayAttribBinding, glVertexArrayBindingDivisor,
glVertexArrayVertexBuffers), fixing glVertexArrayVertexBuffer which
previously conflated binding index with attribute index. Multi-bind
(glBindBuffersBase/Range) loops over the single-bind entry points.

Needed by Flywheel's indirect backend (GlVertexArrayDSA setup path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 13:32:40 +00:00
swung0x48andClaude Fable 5 f355080b6f [Fix] (MG_Backend/DirectGLES): survive ES context recreation in buffer ops
Track context generation + synced change serial per resource; re-register
ops on MakeCurrent. Fixes frozen buffer contents after the trace replayer's
probe context teardown.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 15:02:38 +08:00
swung0x48andClaude Fable 5 b8ffd25148 [WIP] Mesa-style buffer overhaul: resource abstraction + immediate transfer ops
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 14:47:51 +08:00
swung0x48 2ed96e9678 [Fix] (MG_Backend/DirectVulkan): pad short uniform buffer ranges 2026-07-08 10:50:14 +08:00
swung0x48 fbbf3c4beb [Chore] (trace-replay): document bliss ANGLE workaround 2026-07-08 07:14:45 +08:00
swung0x48 b88066b73b [Fix] (trace-replay): accept Android SDK licenses explicitly 2026-07-08 01:56:45 +08:00
swung0x48 83d475eb02 [Fix] (trace-replay): stabilize ANGLE retrace cases 2026-07-08 01:07:20 +08:00
swung0x48 292576d2a1 [Fix] (MG_Backend/DirectGLES): avoid ANGLE llvmpipe mipmap hangs 2026-07-07 21:19:50 +08:00
swung0x48 0c8af978db [Chore] (MG_Backend): lower format capability logs 2026-07-07 09:58:30 +08:00
swung0x48 23671f1a99 [Chore] (trace-replay): cache Android retrace AVD 2026-07-07 06:30:15 +08:00
swung0x48 94e882762e [Chore] (trace-replay): reduce retrace CI swap 2026-07-07 06:28:15 +08:00
swung0x48 672538f4f1 [Chore] (trace-replay): add swap to retrace CI 2026-07-07 05:21:50 +08:00
swung0x48 a9763639ed [Chore] (trace-replay): add Derivative Android ANGLE golden 2026-07-06 21:12:41 +08:00
swung0x48 616e694bdd [Fix] (MG_Backend/DirectGLES): flush ANGLE memory barriers 2026-07-06 12:39:51 +08:00
swung0x48 0bee379b61 [Fix] (MG_Util/ShaderTranspiler): keep decomposed workgroup types before globals 2026-07-06 03:58:26 +08:00
swung0x48 d35e452368 [Fix] (MG_Util/ShaderTranspiler): rewrite workgroup vec3 composite loads 2026-07-06 01:25:44 +08:00
swung0x48 86f322e252 [Fix] (MG_Util/ShaderTranspiler): keep workgroup vec3 pass no-op clean 2026-07-06 00:25:49 +08:00
swung0x48 b40def47eb [Refactor] (MG_Util/ShaderTranspiler): replace Photon shared vec3 regex hack with SPIR-V pass
Replace the application-specific PackPhotonSharedVec3Memory GLSL regex
patch with a general DecomposeWorkgroupVec3Pass SPIR-V optimization pass.

The new pass decomposes vec3/ivec3/uvec3/bvec3 Workgroup (shared) memory
variables into scalar arrays (e.g. shared vec3 arr[N][M] -> shared float
arr[N][M][3]), rewriting whole-vector loads/stores into per-component
scalar loads/stores. Component-level accesses (e.g. arr[i].x) are
unchanged since a trailing component index into a float[3] yields the
same scalar pointer as it did for a vec3.

Unlike the regex hack, the pass is application-agnostic: it does not
match on variable names, array dimensions, or shader pack identity, and
runs at the SPIR-V level before SPIRV-Cross decompilation.

Registered in SanitizeAndOptimizeBinary after AggressiveDCE so dead
workgroup accesses are already eliminated. Asserts on unsupported
OpAtomic*/OpCopyMemory targeting vec3 workgroup pointers.

Adds ProgramUtilTest.DecomposeWorkgroupVec3InSpirvPass covering array
declaration, +=, whole load/store, component access, and row-copy loop.
2026-07-05 23:48:27 +08:00
swung0x48 93cf3559e1 [Fix] (MG_Backend/DirectGLES): fix Photon image replay 2026-07-05 18:41:32 +08:00
swung0x48 8f947253ad [Chore] (trace-replay): add Minecraft 1.17 menu fixture 2026-07-05 15:18:54 +08:00
swung0x48 8cce59302b [Fix] (MG_Util/ShaderTranspiler): keep GL shaders off Vulkan macro path 2026-07-05 09:15:47 +08:00
swung0x48 74ad6d76eb [Feat] (trace-replay): add macOS window retrace harness 2026-07-04 23:35:27 +08:00
swung0x48 95f2f5bab9 [Fix] (MG_Impl/Getter): don't ask system GL for context flags 2026-07-04 21:14:04 +08:00
swung0x48 e5ef9b2ace [Fix] (trace-replay): avoid Android startup race 2026-07-04 08:55:43 +08:00
swung0x48 0a138276f8 [Fix] (trace-replay): align Android retrace harness 2026-07-04 08:21:46 +08:00
swung0x48 1549598e52 [Fix] (trace-replay): request compatibility EGL profile 2026-07-04 08:20:39 +08:00
swung0x48 1902518cd6 [Fix] (trace-replay): enable Vulkan fallback in APK CI 2026-07-04 07:51:49 +08:00
swung0x48 bcb8a9b57b [Chore] (trace-replay): skip 26.2 cases in CI 2026-07-03 20:42:46 +08:00
swung0x48 bdb276cd68 Revert "[Fix] (MG_Backend/DirectVulkan): separate EGL surface lifecycle"
This reverts commit 45f1a13cc3.
2026-07-03 15:16:46 +08:00
swung0x48 79aa381722 [Fix] (MG_Backend/DirectVulkan, trace-replay): gate R11G11B10F fallback 2026-07-03 13:00:01 +08:00
swung0x48 45f1a13cc3 [Fix] (MG_Backend/DirectVulkan): separate EGL surface lifecycle 2026-07-03 12:20:40 +08:00
swung0x48 afdbf0a194 [Fix] (MG_Backend/DirectVulkan): support layered texture framebuffers 2026-07-03 12:05:20 +08:00
swung0x48 940ab5fd8e [Fix] (MG_State/GLState, MG_Backend): track layered framebuffer textures 2026-07-03 10:38:51 +08:00
swung0x48 6418561d3c [Fix] (MG_State/EGLState, MG_Backend): defer current EGL surface destruction 2026-07-03 10:14:26 +08:00
swung0x48 ce2b5a793f [Fix] (MG_Backend): support GLES depth-stencil readback 2026-07-03 10:02:49 +08:00
swung0x48 6ecefaec75 [Fix] (MG_Backend): track EGL backend surfaces 2026-07-03 09:15:26 +08:00
swung0x48 bdf29fc4d5 [Fix] (MG_Impl/GLImpl): validate DSA texture parameters 2026-07-03 09:05:52 +08:00
swung0x48 51d9fa91ed [Fix] (MG_Impl/GLImpl, MG_Backend): fix piglit texture and buffer cases 2026-07-03 08:51:22 +08:00
swung0x48 5cdc6c902e [Fix] (MG_Impl/EGLImpl, MG_Backend): track EGL surface lifecycle 2026-07-03 07:45:40 +08:00
swung0x48 03696f8a1a [Fix] (MG_Impl/GLImpl, MG_State, MG_Backend): validate image uniform state 2026-07-03 02:03:23 +08:00