Repository navigation
Mod Compatibility Research
Startup Acceleration contains the October 15 source-backed roadmap: bounded parallel scanning, persistent artifact and shader caches, GPU texture/transfer feasibility, a concrete mipmap allocation/locality candidate and full-pack no-loss benchmark gates. Includes real reference-JAR metadata and an explicitly host-only averaging model. No launch-time or FPS gain has yet been measured for these proposals.
Snapshot: 2026-10-15. 28 official Modrinth artifacts from 23 projects downloaded and SHA-512 verified. Zero whole-mod/game/FPS qualifications performed by this cloud research. The 21 archives named by the older full-pack preflight and four additional library targets are accounted for below, but not all exact customized binaries are available. That older preflight is not the latest worker status.
| Target | Evidence and specific boundary | Next qualification |
|---|---|---|
| Blueprint 7.1.5 | JAR + source; animation/event/shader paths, no direct GL in initial scan | Separate CPU profile and original animation/render features |
| CorgiLib 4.0.3.6 | JAR + source; newer version removed old ImGui integration | Verify installed version, scheduled-tick behavior and dependents |
| Data Anchor 1.0.0.23 | Exact client mixin scans client chunk slots, tracked keys and block entities each client tick; no direct GL in initial scan | Lifecycle-indexed tick candidates, exactly-once callbacks and isolated CPU cost |
| FDLib 1.0.9 | JAR + source; post effects and two verified redundant audio-work patterns | Audio state/fade tests and effect reload/lifetime |
| Essential 1.5.0.1 | Nested payload; three existing caller pins match; extra screenshot backend inspected | Original UI/FBO features; native screenshot queue/context ownership |
| Xaero World Map 1.46.0 / 1.47.0 | Pinned helper matches; PBO paths and bounded calibration waits | Queued remap correctness and actual map update behavior |
| Xaero Minimap 26.5.0 / 26.6.0 | Pinned helper matches across versions | Original minimap render/PBO lifecycle |
| Physics 3.0.20 | Pristine JAR; transfer storage/defrag examined | Preserve custom ProviderDetection patch; safe copy batching |
| Botania 456 | Original stencil caller inspected | Progress pie pixels and state restoration |
| Malum 1.6.7 | Codex scissor caller inspected | Scaled UI clipping and subsequent draws |
| Lodestone 1.6.4.1 | Exact official hash disambiguates same-name releases; R32F samplerBuffer | Typed texel descriptors and actual consuming effect |
| Create Dragons Plus 1.11.9 | Ponder/offscreen framebuffer-state surfaces | Ponder rendering, nested viewport/state and resize |
| Create Big Cannons 5.11.4 | Blend-state query surface | Gas-mask overlay and original weapon effects |
| GuideME 20.1.15 | Selection logic-op and separate exporter query | Text selection plus export correctness |
| Moonlight 2.16.35 / 2.16.37 | Texture query/readback in inspected image-export routine | Accurate export; distinguish active rendering from tooling |
| NTGL 3.1.2 | Workbench/model scissor surfaces | Original workbench clipping and previews |
| Loot Beams | Only 1.2.2 JAR inspected; audit names 1.2.6 | Obtain exact 1.2.6 before transport qualification |
| TaCZ 1.1.8 hotfix / hotfix2 | Stencil paths; extra queries behind OptiFine branch | Actual scopes, hands, attachments and active branch |
| Supplementaries 3.1.43 / 3.1.44 | Exact older version obtained; optional ImmediatelyFast atlas mipmaps | Activation, upload ordering, colored/lighted maps |
| Sounds 2.2.1 | Config image texture filtering | Original config UI; don't blame audio loop |
| Scorched Guns 0.5.5 | Pristine scissor caller | Preserve installed DimThread interop patch; UI and gameplay |
| Sweet Calamity 1.0.1 | Texture dimensions and raw-coordinate cloud mesh invalidation | Exact geometry cache key and original cloud visuals |
| Crash Assistant 1.11.12 | Nested GPU diagnostic query guarded by GL context | Truthful Vulkan diagnostics without creating GL |
| Arcana | Public source only; version not matched to installed 1.1.4 | Extra world/scope passes, stencil/depth and official content parity |
| Macabre | Official release identified; download did not complete | Obtain exact custom Eye/UI/QoL replacement before analysis |
Additional renderer work: existing native Create/Flywheel CPU costs, post-effect ownership, PBO lifetime, shader compiler settings and pipeline-cache/variant allocation have separate reports. None warrants removing features or substituting a different renderer.
Priority: queued-PBO correctness, original-feature qualification, then measured CPU/lifetime improvements. The attachment also includes NEXT-CLOSEOUT-HANDOFF.md. The detailed findings below preserve provenance, uncertainty and acceptance criteria; no entry in this table means "fully compatible".
Research started 2026-10-15. Static inspection only; no game, downloaded mod, or third-party build script executed. No user-computer access or changes. No FPS gains claimed.
- Exact Essential callers recovered independently. The official Modrinth Forge 1.20.1 download Essential 1.5.0.1 contains a nested payload. Its UGpuDeviceImpl and color/depth write-framebuffer helper class SHA-256 hashes exactly match all three published Hari CALLER-PINS entries. This gives a concrete reproduction corpus, unlike inspecting an unrelated latest source version. The outer bootstrap JAR alone would misleadingly show zero direct GL references; the payload has 64 classes matching the initial GL/framebuffer surface scan. That count is a search result, not an exhaustive API inventory or compatibility result.
- Published Hari detach defect is observable. In the downloaded integration overlay GlFramebuffer, clearAttachment removes only attachment metadata; the cached color/depth/render-pass fields are not updated in that method. This matches the earlier worker diagnosis, so do not duplicate its unpublished local fix. Additional regression targets: deleting a currently bound framebuffer must restore the effective native target as well as Java IDs; attachment replacement while commands are in flight; distinct read/draw binding restoration; incomplete scratch targets must never accidentally clear the previous target. Audit cleanup/lifetime before declaring any further bug confirmed.
- Do not blame Blueprint's 725 FPS on an imagined direct OpenGL renderer. Downloaded Blueprint 7.1.5 exposes vanilla ShaderInstance registrations, render types, animation hooks and ordinary render-system use. Its SimpleEvent invoker is constructed at registration, not allocated anew on every animation tick. Its ClientLevel redirect preserves cancellation semantics; removing it would lose dependent mod behavior. Profile exact transformed methods and shader translation before changing code. Prior GPU background load makes the single reported FPS comparison inconclusive.
- CorgiLib version matters materially. The downloaded 4.0.3.6 changelog says ImGui was removed in 4.0.3.0. An older ImGui crash report is not evidence against this current artifact. 4.0.3.6 also claims a scheduled-tick memory-leak fix. Validate the installed version and dependents before proposing an update; no automatic pack changes made.
- FDLib has concrete postprocessing and per-render audio boundaries to test. Its GameRenderer mixin posts level/screen postshader events; effects are conditionally active. Window-sized PostChains are recreated on resource reload and resized on dimension changes. Its audio source cache checks OpenAL source state at render-end for each tracked source. At very high FPS, profile this independently from Vulkan command recording. Empty maps/effects are important controls. Do not remove audio synchronization or visual effects to improve the number.
- Data Anchor is not yet a graphics culprit. The downloaded JAR's initial constant-pool scan found no matching render/GL/event surfaces, unlike FDLib. This is negative evidence only, not proof of zero CPU cost or compatibility. Test separately, including attached data, network and save lifecycle.
Official Modrinth API responses and full version metadata are saved alongside the JARs. SHA-512 was checked against the API for each download. class-surface-report.json includes SHA-256. Downloaded releases may differ from the installed modpack; only the three Essential caller classes have an independently confirmed match so far.
- Blueprint 1.20.1-7.1.5
- CorgiLib Forge 1.20.1-4.0.3.6
- Data Anchor Forge 1.20.1-1.0.0.23
- FDLib 1.0.9-1.20.1
- Essential 1.5.0.1 Forge 1.20.1 (inspect nested payload)
Source snapshots have commit-pinned *-source-provenance.json records. They are inspection materials, not source redistribution deliverables. Essential source has restrictive terms; implement compatibility from behavior/API contracts rather than copying its implementation. The analysis scripts are original utilities.
- https://modrinth.com/mod/essential
- https://github.com/SparkUniverse/Essential-Mod
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/tree/migration/projectdump-20261004/integration/dimensions
- https://github.com/team-abnormals/blueprint/tree/1.20.x
- https://github.com/CorgiTaco/CorgiLib/tree/1.20.X
- https://github.com/CorgiTaco/Data-Anchor/tree/1.20.1
- https://github.com/FINDERFEED/FDLib/tree/1.20.1
- https://github.com/Engine-Room/Flywheel/tree/1.20.1/dev
User's interim target: full pack including Create at least 1000 FPS, then optimize upward. A single failed point with GPU load before launch does not identify a mod as causal. Repeat baseline/addition/baseline with fixed world, camera, window size, view distance, JVM, warm-up and background workload; preserve medians and p95/p99 frame times, CPU/GPU time and rendered correctness. Separate steady-state from compilation/reload/load spikes. Record inactive dependents as not tested rather than broken. No research here substitutes for these measurements.
Downloaded the older filenames from the published 327-mod audit as well as current releases: Xaero World Map 1.46.0/1.47.0, Xaero Minimap 26.5.0/26.6.0, Moonlight 2.16.35/2.16.37, and TaCZ 1.1.8-hotfix/hotfix2. The old audit is Hari54 evidence, not the latest local status. Physics Mod's pristine 3.0.20 download does not equal the pack's patched ProviderDetection-v1 artifact. No override of those local modifications is proposed.
CFR 0.152 from Maven Central (checksum checked) was run on selected class files as a static decompiler. No mod class was loaded as game code. Decompiled third-party bodies remain private analysis material and are not published in this report.
Static decompilation of 1.46.0 shows TextureUploader.uploadTextures uses glFinish when its per-upload-type benchmark is unfinished. TextureUploadBenchmark.post also waits before recording a sample, then marks a type finished after its configured sample count. Therefore this is a warm-up/calibration synchronization path, not evidence of an unconditional steady-state per-frame wait. Capture counters by upload type and benchmark-finished state before deciding it caused stutter. A Vulkan-native calibration adapter could use asynchronous timestamps/fences with conservative provisional budgets, but it must not silently turn glFinish into a no-op. Preserve PBO range ownership, map/unmap and same-frame readback correctness.
Static inspection of 1.1.8-hotfix RenderHelper places several raw attachment and texture-format queries behind its OptiFine-present branch. The ordinary branch requests the main target's stencil support, then enables stencil testing. Prioritize proof of correct native stencil behavior with the actual OptiFine presence result. Static references still matter for capability reporting, but do not infer that every listed query is executed in this pack. Test scopes, weapon attachments, first-person hands and transition back to world rendering. Never simply disable stencil to pass startup.
member_refs.py recursively reads JVM constant pools and nested JARs without executing target code. It records owner/name/descriptor references, not dynamic call frequency or reachability. Exclude bundled LWJGL implementation classes from mod-call totals. The scanner also exposes inherited owner aliases (for example a GL11 API referenced through GL30); adapters need exact JVM resolution rather than name-only regex replacement. Reflection, native code and generated calls require additional runtime observation.
Hari already has a native Flywheel backend and published bounded machinery tests. Do not replace that with an OpenGL fallback or a new blanket disable patch. A newly found public Vulkan-Create Compat patch targets Fabric 26.1.2, not this Forge 1.20.1 pack, and explicitly disables GPU instancing. It is a failure-mode reference, not a drop-in performance fix. Investigate existing Hari native backend gaps first.
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/tree/migration/projectdump-20261004/compat/native-flywheel-backend
- https://www.curseforge.com/minecraft/mc-mods/vulkan-create-compat
2026-10-15. Source-audited against the published integration overlay; not reproduced on a Vulkan device and not compared with unpublished local changes.
- Downloaded Xaero World Map 1.46.0 and Minimap 26.5.0
PixelBuffersclasses exactly match the raw SHA-256 values in Hari's published NativePixelBufferSmoke fixtures.xaero-caller-hash-match.jsonrecords this. -
XaeroPixelCallersdirects these pinned methods toNativePixelBufferApi, including both legacy map overloads. -
NativePixelBufferApi.Store.retainprotects allocations from destruction while recorded GPU readers remain. However,glMapBufferexposes that store's same host pointer without checking recorded readers, waiting for completion, or replacing storage for a writable map. - The neighboring
NativeBufferObjectApialready has a copy-on-writewritablehelper for host writes when recordedUses is nonzero. The pixel mapping path does not call it in the inspected snapshot. - The existing pixel smoke test performs synchronous readback before remapping/reusing the earlier upload buffer. That wait can hide a remap-before-consumption hazard.
A retained allocation can still be overwritten. Record an upload using red bytes; remap the same buffer writable before its recorded copy executes; write blue bytes; unmap and submit. Without copy-on-write or synchronization the earlier upload can see blue. Ordinary glMapBuffer promises completion of pending operations before returning its pointer. Deferring actual GPU consumption does not remove that contract.
Static evidence identifies an implementation gap to investigate; it does not prove the user's observed FPS regression or crash was caused by this path.
- Allocate one UNPACK PBO and two distinct destination textures A/B.
- Map/write red, unmap, record upload to A without readback, glFinish, mipmap submission, frame retirement or any implicit host wait.
- Map the same PBO WRITE_ONLY again; write blue, unmap, record upload to B.
- Submit once, then read back both images. Expect A red and B blue.
- Repeat with partial modifications, preserved prefix/suffix, old ByteBuffer reuse argument, both pinned original Xaero wrappers, two frames in flight, name deletion and numeric-ID reuse.
- Assert no premature frees; the old mapped view may legitimately be replaced when backing storage changes. Do not require Java object identity across a storage replacement.
The accompanying pbo_reference_model.py passes four host-only specification tests demonstrating the aliasing hazard and copy-on-write behavior. This is not a GPU test or a Hari build qualification.
Share the existing pending-reader-safe writable-storage policy across generic and pixel buffer facades, after validating target flags and preserving required VkBuffer usages. Preserve untouched bytes for legacy mapping; do not assume WRITE_ONLY means whole-buffer invalidation. Keep recorded commands on their old Store; publish the new Store for subsequent commands. Continue deferred destruction. Read-only maps must honor outstanding GPU writers. Any write invalidation, persistent mapping, unsynchronized flags or cross-thread access needs its own explicit contract.
Prefer scoped waiting only where a correct storage replacement cannot be established. Avoid inserting device-wide idle into every map. Measure allocation/copy counts and frame-time cost before selecting a pooled/versioned implementation.
The current published download path flushes recorded work, submits a copy, immediately waits for its fence and performs CPU swizzling. That is conservative and easy to verify, but it gives up PBO overlap even when the caller maps later.
A candidate improvement is per-Store pending completion plus deferred host visibility: queue the readback; retain image/buffer ownership; resolve only when mapping or another conflicting operation requires the data. Complete requested format conversion before host access, or use a proven GPU conversion path. Preserve command ordering when the same storage is rebound for a later GPU read. Support delete-before-completion, storage reallocation, device teardown and error recovery without dangling pointers. Ordinary client-memory readback remains synchronous.
Do this only after the remap correctness test passes. Measure total wait time, submission count, bytes copied, pending depth and end-to-end frame-time distributions; do not report a faster API return alone as a faster game.
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/NativePixelBufferApi.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/NativeBufferObjectApi.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/XaeroPixelCallers.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/tests/NativePixelBufferSmoke.java
- https://github.com/KhronosGroup/OpenGL-Refpages/blob/main/gl4/glMapBuffer.xml
Public source may lag the interrupted engineer's local work. Reconcile before changing code, and extend the existing smoke suite instead of creating a competing compatibility layer.
Static inspection, 2026-10-15. Pristine Physics Mod 3.0.20 is not the pack's patched ProviderDetection-v1 artifact; compare exact class hashes before assuming equivalence.
The inspected ArenaBuffer uploads through a staging buffer and calls glCopyBufferSubData; defragmentation can issue multiple copy operations for discontiguous ranges, then deletes the old buffer name. Hari's published NativeBufferObjectApi submits a Vulkan command and waits on its fence for each copy. If this exact path is hot in an active effect, many small transfers could serialize CPU/GPU work. The presence of these calls is not evidence of their runtime frequency.
Instrument transfer count, bytes, per-call fence wait and defragmentation bursts. Where profiling confirms material overhead, batch ordered copies in the current frame or an explicitly ordered transfer submission, using range-level pending-writer tracking. Retain source/destination Store generations until completion; deletion of the old name must not free pending reads. Preserve visibility to subsequent vertex/index/shader/host consumers.
Do not simply remove the wait: the present copy-on-write helper copies host pointers and assumes GPU writes are already complete. An asynchronous path requires either resolving pending GPU writes before host copies/maps or keeping preservation copies on the GPU with correct barriers. Track write-after-write and read-after-write dependencies. Respect same-buffer non-overlap rules and zero-byte operations. Keep immediate CPU-read semantics when the caller requests them.
- Small upload → same-frame draw → second upload → second draw: old and new consumers see their correct data.
- Multiple discontiguous defrag ranges preserve byte order and untouched spans.
- Delete source and destination names after recording; all pending work remains valid.
- Read-only and partial writable map after copy return correct values.
- ByteBuffer position/limit/remaining and typed element sizes are preserved; never use capacity as the universal transfer byte count.
- Buffer reallocation and binding to another target maintain identity/version semantics.
- Device teardown with queued work has zero leaks/use-after-free.
Profile before/after at equal active effects and rendered output. Compare p95/p99 frame time, CPU wait, GPU duration, bytes copied and peak retained storage. Do not use a higher FPS from skipped debris/water/cloth as acceptance.
Sources:
- Official binary metadata: https://modrinth.com/mod/physicsmod
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/NativeBufferObjectApi.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/NativePixelBufferApi.java
2026-10-15. Existing published NativeEngine/NativeWorldRenderer inspected; no local changes, runtime profile or gain claimed. Preserve the already working native backend and its light-cache gains. Previously rejected descriptor-batch13 work is not automatically reintroduced.
- Per-frame ordering and repeated sparse counts. NativeEngine.render allocates an entry list, sorts by bias, builds a second list, and calls count repeatedly. NativeWorldRenderer.prepare/render count again; each count walks the sparse handle array. A topology-revision-qualified stable order and one immutable active snapshot per render phase may avoid redundant scans and allocations. Preserve insertion order for equal bias. Invalidate on instancer creation, retirement, embedding teardown and reload.
- Unconditional instance serialization. packOriginalInstances calls the original writer for every live handle each preparation. Handle already has a generation counter, but the inspected packing code does not use it. Evaluate a CPU-side packed-byte cache keyed by owner, slot identity and generation; copy into frame-owned snapshots or update explicitly safe dirty ranges. A constantly changing contraption may not benefit; benchmark static and animated scenes separately.
- Sparse slot lifetime. Deleted slots are retained/reused via free indices. Never use only slot index as the cache identity; deletion/stealing/reuse must invalidate data. Never densify away original target indices unless all consumers are updated together.
- Global mutation monitor. The static MUTATIONS lock spans preparation and rendering. Measure contention across world/Ponder/embedded contexts before changing it. Handle visibility/deletion/generation setters are not all guarded by that monitor, so moving to cached counts or parallel recording without a verified publication boundary risks stale visibility and snapshot inconsistency.
- Capture CPU samples/allocation profile plus per-phase counters for sorting, count scans, packing, compute dispatch and draws at the same scene/workload.
- First experiment: reuse scratch lists and cache stable ordering only. Clear retained references on reload/deletion; no cross-frame GPU slice reuse.
- Second: derive counts and visibility from one phase-qualified snapshot after all required Flywheel plan work completes. Preserve selection/crumbling behavior and don't freeze animation for speed.
- Third: generation-based serialized-byte reuse only after exact InstanceHandle writer contract and generation publication are verified. Byte compare original and optimized packing on each fixture during qualification.
- Compare unchanged scene, rotating contraption, Ponder, moving embedding, sparse deletion/reuse, stolen handles, origin shift, resource reload, breaking overlays and dense machinery.
Same visible instance IDs, original packed bytes, lighting, animation phases, bounding behavior and material order. No leaked objects after reload. Equal-size workload; no culling/fidelity reduction. Show CPU and GPU timing separately, allocation counts, medians and p95/p99. Retain the prior implementation unless the matched improvement is real.
Sources:
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/compat/native-flywheel-backend/src/main/java/mvhflywheelbackend/NativeEngine.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/compat/native-flywheel-backend/src/main/java/mvhflywheelbackend/NativeWorldRenderer.java
- https://github.com/Engine-Room/Flywheel/tree/1.20.1/dev/common/src/api/java/dev/engine_room/flywheel/api/instance
These are improvements to investigate, not grounds to remove Create or replace it with non-instanced rendering.
2026-10-15. Supersedes the earlier upstream-only shaderc suggestions where they differ from Hari's published SPIRVUtils.
- Include callback payloads use owned allocations with an explicit release callback; the earlier upstream MemoryStack-lifetime lead does not describe this implementation.
- Compilation failures release the shaderc result through a finally block unless ownership was transferred.
- DEBUG is false and OPTIMIZATIONS is true. Do not suggest enabling performance optimization as if it were absent.
Do not spend the next engineering session repeating these completed changes. Nested include failure, resource reload and cancellation tests remain useful quality gates.
The inspected set_target_env call passes shaderc_env_version_vulkan_1_2 in the target-environment argument. The API defines shaderc_target_env_vulkan for that slot and the version constant separately. Correcting the enum is warranted for API clarity/portability, but is not a measured performance fix.
A real host-native shaderc probe compiled one minimal vertex shader with three settings. Default produced SPIR-V 1.0; the published argument pair and the corrected pair both succeeded and produced identical 752-byte SPIR-V 1.5 binaries in this installed library. The library hash and outputs are saved in shaderc-target-probe.json. This does not prove equivalence for all shaders or the Windows LWJGL-bundled shaderc version, but it rules out claiming that this call necessarily fails every compilation.
Measure duplicate source compilation and include expansion by resource-generation-qualified key before adding threads. A cache key must include final transformed source, include contents, stage/entrypoint, macros, target/options and compiler version. Preserve error identity and invalidate on reload. Coalesce identical in-flight jobs. Investigate actual compiler/options/include-state concurrency contracts before parallelizing shared static objects. Keep performance compilation off the latency-critical path only where the exact pipeline is ready before use; no missing draws or placeholder shader substitution.
Sources:
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java
- https://github.com/google/shaderc/blob/main/libshaderc/include/shaderc/env.h
- https://github.com/google/shaderc/blob/main/libshaderc/include/shaderc/shaderc.h
This probe is compiler-only. It is neither a game test nor GPU validation.
2026-10-15. Actual downloaded JARs inspected statically; live pack acceptance remains unverified. The older preflight is a prioritization source, not a current failure count.
ShaderDataBuffer allocates a GL_TEXTURE_BUFFER sized as float-count × 4 bytes, associates it with GL_R32F (0x822E), uploads a float array, and selects a texture unit for the shader uniform. Its packaged helper shader fetches individual scalar values from a samplerBuffer. This is R32F, not RGBA32F or a 2D sampled texture.
The inspected Hari function registry lists glTexBuffer as a no-op entry; the native preflight correctly does not treat that as a finished provider. Simply allowing the symbol would not implement the data path. A native Vulkan implementation should use a format-qualified buffer view and uniform-texel-buffer descriptor with the required buffer usage. Preserve the scalar indexing convention, allocated extent and resource-generation identity. Device format/texel-buffer limits must be checked explicitly.
A synthetic samplerBuffer fragment shader compiled successfully with the installed host shaderc library to 704-byte SPIR-V 1.5; its image type uses buffer dimension and sampled access. This proves compiler syntax support in that library only. It does not prove Hari's shader parser, descriptor reflection or actual GPU binding works.
- Pin the exact original ShaderDataBuffer class and packaged consumer shader before transformation.
- Implement buffer-name → storage-generation → VkBufferView identity and texture-unit association.
- Route the shader resource to a uniform texel buffer, not combined-image-sampler storage. Respect shader-stage usage and format support.
- Preserve view/descriptor lifetime when a buffer's storage is replaced; a view into the previous allocation cannot silently become the new allocation.
- Exercise upload → bind → texelFetch → reload → resized allocation → destroy, including two queued draws with distinct uploaded values.
- Validate float arrays with nonzero/negative/fractional values and non-power-of-two lengths; prove every fetched index and out-of-range policy follows the relevant GL contract.
- Restore prior active texture and other caller-visible state exactly as the actual caller expects. Keep safe failure for unsupported texture-buffer variants.
Native smoke fixture: values [0.25, -0.5, 0.75, 2.0], fetch index 2 to a float-capable reference output. Then change a different element and verify queued old reads and new reads independently. Do not clamp the storage itself to normalized color range.
| Artifact inspected | Observed caller purpose | Needed original-feature proof |
|---|---|---|
| Botania 456 | Progress pie uses stencil enable/disable around masked item drawing | Correct item-shaped progress mask, depth/color writes and restoration |
| Malum 1.6.7 | Codex content enables scissor, computes scaled screen rectangle, then disables it | Scroll/zoom/resize/GUI-scale clipping with correct coordinate origin |
| NTGL 3.1.2 | Workbench/model UI scissor-related entrypoints | Weapon model and UI clip boundaries, state restoration |
| Create Dragons Plus 1.11.9 | Ponder item texture captures framebuffer, viewport, blend/depth-write state before an offscreen render | Original Ponder preview at different GUI scales and correct return to main target |
| Create Big Cannons 5.11.4 | Gas-mask overlay queries prior blend state | Overlay visibility and alpha with/without other HUD layers |
| GuideME 20.1.15 | Document selection uses logic-op state; export has a separate texture-size query | Text selection/inversion plus export handled separately |
| Moonlight 2.16.35 | Direct texture readback queries inspected here are in saveTextureToFile | Accurate exported image; do not call this an unconditional per-frame stall |
| Loot Beams 1.2.2 | Particle setup redundantly enables blend alongside RenderSystem | Correct beam/particle color, alpha and depth; installed audit names 1.2.6, so this is a version-mismatched lead |
Small static call counts do not prove the whole mod is easy or safe. Reuse existing tested stencil/scissor/viewport/logic-op semantics, add exact original-caller transport, and test original UI/gameplay features. Avoid broad bytecode waivers or reporting synthetic primitives as whole-mod support.
- https://modrinth.com/mod/lodestonelib
- https://github.com/LodestarMC/Lodestone
- https://docs.vulkan.org/spec/latest/chapters/descriptorsets.html
- https://docs.vulkan.org/refpages/latest/refpages/source/VkBufferViewCreateInfo.html
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/compat/opengl/GlFunctionRegistry.java
- Official release metadata and hash-verified downloads are recorded in the research manifest; no third-party binary/source is redistributed with the handoff.
2026-10-15. Published commit 98a85a89cb792d1d335b095ed774cf71773126fc inspected. These are source-level findings to reconcile with local work; no resource-leak magnitude or GPU failure was measured.
EffectInstanceM creates a native GraphicsPipeline, but its intercepted close method closes uniforms only. In contrast, the inspected ShaderInstanceM has an idempotent close guard and explicitly cleans its pipeline. GraphicsPipeline registers itself in the global PIPELINES collection, and its cleanup destroys shader modules, descriptors, native pipelines/layouts and removes that registration. A separate global owner might affect lifetime, so validate the complete runtime before declaring a leak fixed.
EffectInstanceM.createShaders also opens vertex/fragment resources without a try-with-resources scope in the inspected method. Use deterministic stream closure, including error paths. Avoid relying on garbage collection to release resource-pack streams.
- Create and use a real FDLib/Lodestone-compatible post effect, close/reload it repeatedly, then let all frame fences retire.
- Count live effect objects, registered pipelines, shader modules, descriptor pools/layouts and resource streams. Counts must return to the retained baseline rather than grow each cycle.
- Inject compile failure between vertex and fragment creation, then recover with a valid effect.
- Close twice, resize, switch world, reload resources and exit while prior commands are pending.
- Use the existing frame-retirement mechanism for native resources still referenced by submitted work. Do not replace missing cleanup with immediate destruction that causes use-after-free.
- Clear stale lastPipeline identity when appropriate and make ownership explicit; shared pipelines need shared ownership, not unconditional double-free.
The inspected RenderStateSnapshot saves color/blend/depth/cull/topology-related state, but not viewport/scissor or stencil. PostPassM calls resetScissor in its final path; Renderer.resetScissor disables logical scissoring. This is not by itself proof of a vanilla-contract violation, because postprocessing may intentionally reset some state. It is a concrete integration-test boundary for nested mod UI/effects.
Seed non-default scissor/viewport/stencil plus separate read/draw targets; invoke the original post-effect sequence and compare its documented/caller-required exit state with an OpenGL reference. Include failure during apply/draw. Preserve intended vanilla side effects while preventing unrelated later draws from inheriting accidental state corruption.
An inject-and-cancel replacement can avoid another mod's injection-target crash while bypassing redirected/injected original-body behavior. Verify actual callbacks and original features after native postprocessing replacement; do not infer compatibility solely from a clean Mixin startup log. The downloaded Lodestone 1.6.4.1 does not itself expose a PostChain-named mixin in the inspected configuration, so an old source comment is not proof of that specific current interaction.
Sources:
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/source/forge/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/source/forge/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/source/forge/src/main/java/net/vulkanmod/compat/render/RenderStateSnapshot.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/source/forge/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java
2026-10-15. Public GitHub/Codeberg research; do not treat a project's README claims as verified compatibility.
Inspected source commit f03aefbd1baacaf9135620c2075591c233dabbeb. The project targets Fabric 1.21.1, not Hari's Forge 1.20.1 target. Its render manager attempts reflective calls against net.vulkanmod.render.VRenderSystem; Hari's inspected implementation uses a different package/API. Failed calls are swallowed into no-ops. Its depth-safe helper sets a boolean; that alone is not an image-layout transition. It also attempts periodic global cache invalidation every 20 ticks.
Conclusion: useful as a list of integration surfaces to test, not a ready Hari compatibility fix. Do not install it into the pack or copy its fallback policy. Verify actual native transitions, exception-safe nested scopes, resource ownership and API identities. Periodic global invalidation is especially unsuitable without a measured need and a resource-generation model.
Source: https://github.com/lozampy/Vulkan-map/tree/f03aefbd1baacaf9135620c2075591c233dabbeb
The author's page explicitly describes disabling Flywheel GPU instancing and skipping an OpenGL-specific reload operation for Fabric 26.1.2/Create Fly. It is a correctness workaround with a stated performance tradeoff. Hari already has a native Flywheel backend with published bounded feature tests, so replacing it with this workaround would discard relevant work and does not establish the user's no-loss performance goal.
Source: https://www.curseforge.com/minecraft/mc-mods/vulkan-create-compat
Prioritize concrete source, matching version/loader, tests of original features, typed resource lifetime and failure behavior. Reject silent no-op compatibility claims, blanket capability spoofing, dropping visual features, and timing claims made on a different scene/mod set. Reuse proven components where appropriate; do not spin up a parallel renderer merely because another repository exists.
Research search coverage is not exhaustive. Source access, version availability and licenses remain explicit per candidate.
2026-10-15. Research proposal only; no gate, game profile or shipped behavior changed.
Static references in the inspected pack span very different workloads: TaCZ's OptiFine-specific attachment queries, Moonlight's image-export routine, ordinary stencil/scissor UI calls, and Physics rendering/storage operations. FDLib even contains source-level readback code that is unreachable behind an immediate return and absent from its compiled GL references. A raw call count is useful inventory, but it is neither a runtime profile nor a proof that all references execute during startup.
- Discovered: artifact/hash and potential API surfaces recorded.
- Transport verified: exact original caller successfully transformed; its argument/return contract is preserved.
- Primitive verified: native pixels/data/lifetimes validated for the API sequence.
- Original feature verified: the actual mod feature works under native Vulkan, including reload/cleanup.
- Pack-qualified: the intended complete mod set and interactions pass gameplay/correctness and matched performance criteria.
Never collapse these into a single green compatible badge. An original shader/helper smoke test does not establish the whole Essential, Physics or Create feature set.
If the current engineer judges the transformation coverage sound, an isolated fail-closed discovery mode could replace every remaining supported-to-trap callsite in a hash-pinned module with a descriptive throwing stub. It must throw before entering any real OpenGL/JNI path. This would let a narrow original-feature test reveal the first actually reached missing API rather than silently skip calls or waive an entire archive.
This is not permission to bypass the native-required policy. Unaccounted reflection, method handles, dynamically loaded classes or function-pointer dispatch mean the module remains blocked. There must be no fallback OpenGL rendering, fake successful return value, missing draw, or accepted full-pack benchmark from an unqualified run. Use only disposable test profiles and a clearly labelled discovery build; production policy stays unchanged until reviewed and proven.
For each attempted original feature record artifact and class hashes, load context, caller method, exact owner/name/descriptor, arguments relevant to resource shape, frame/phase, chosen native transport, return/error state and cleanup outcome. Aggregate counts and timings off the render thread; avoid per-call stack traces/string formatting once a site is classified. Persist only useful bounded diagnostics, not a log line for every draw.
Pair this with the user's incremental pack method: dependencies first, measured baseline/addition/baseline, and explicit reason categories (load failure, native API trap, visible defect, performance regression, not yet exercised). Background GPU load and scene drift must remain attached to timing claims.
It directs effort toward real feature paths and exposes hidden late-loading APIs, while preserving a hard failure for genuinely untranslated behavior. It cannot prove arbitrary Java code unreachable, replace original-feature tests, or justify shipping unsupported pathways.
The published post-effect route uses EffectInstanceM → GlslConverter/UniformParser. UniformParser recognizes sampler-prefixed types, but constructs ImageDescriptor; ImageDescriptor selects combined-image-sampler for non-storage images and resolves a VulkanImage through VTextureSelector. A samplerBuffer cannot be made correct just by implementing the glTexBuffer call while leaving this descriptor model unchanged.
Separately, the custom NativeUiProgram frontend explicitly recognizes sampler2D and its UI render bridge constructs sampler2D image descriptors. Do not assume adding one token to that regex enables texel buffers. Identify which frontend the original Lodestone consumer actually reaches, then extend its resource reflection, descriptor construction, binding and lifetime together. Until supported, reject an unsupported resource kind explicitly instead of misdescribing it as a 2D image.
Code references:
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/source/forge/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/source/forge/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/source/forge/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/migration/projectdump-20261004/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/vulkan/shader/NativeUiProgram.java
Writable PBO remapping is tracked in issue 3. The research manifest now contains 24 official Modrinth artifacts with release-matching SHA-512 hashes. Exact original-caller matching has been verified for three Essential classes and both Xaero PixelBuffers helper classes. These are static transport provenance checks, not whole-mod or full-pack certification. Sounds 2.2.1 adds a config image widget filter-parameter callsite; it is not evidence of an audio-loop performance problem. Loot Beams 1.2.6 remains unverified: the inspected 1.2.2 is only a version-mismatched lead.
2026-10-15. Verified against source commit 76e5e3159c2857208732d4acad254a4f71d2eb2f and selected classes from official FDLib 1.0.9 Forge 1.20.1. Static decompilation only; the mod was not executed.
In FDMusicSystem.muteAllMusicBesidesFDMusic, the no-active-music branch sets musicWasPlaying=false when restoring ordinary music volume. The following volume-update block immediately sets it true again. After music has played once, subsequent unpaused client START ticks therefore keep entering the restoration block even with no active FD music. The method allocates its sound-instance list and traverses instanceToChannel; actual channel work depends on which music sources exist.
This is client-tick work, not a per-frame OpenGL issue. It cannot explain the earlier single FPS sample without profiling and the required music-playback history. On a fresh session that never plays FD music, the latch starts false and does not trigger this path.
A candidate minimal change is to avoid reasserting the flag in the generic volume-update block; preserve the active-music branch's true assignment and the one-time restoration branch. Verify sound-engine restart, world leave, volume changes, pause/resume, zero volume, overlapping music and new tracks. Don't replace this with deleting music synchronization.
An original host-only branch model passes four checks. One active tick followed by 200 inactive ticks produces 201 update-block entries with the inspected logic versus two in the candidate model. This is control-flow evidence, not measured saved CPU time or game FPS.
FDMusicPart.getSoundInstances returns old sound instances plus main when present. setAllSoundInstancesVolume iterates that result and queues a volume update for each present channel, then separately looks up main and queues the same volume update again. Thus an available main channel receives two identical submissions per method invocation in the inspected implementation.
Candidate: one pass over all intended instances, retaining fading old sounds and the main sound exactly once. Test concurrent channel retirement/replacement and fades; do not assume source IDs remain stable or remove required updates to overlapping old instances. Measure actual invocation counts and sound-executor queue depth before claiming performance impact.
FDMusicPart's render update schedules a ChannelHandle callback to query playback offset for each active part. FDLib's cleanup also checks cached OpenAL source state at render END. At very high FPS this is a separate CPU/audio-executor workload from Vulkan. Instrument active-part count, callback enqueue/completion count, queue latency and source-cache size. If repeated pending work is proven, explore generation-qualified coalescing while preserving loop boundaries and fade timing. Blindly reducing it to 20 Hz could introduce audible timing regressions and is not an accepted fix.
- FDMusicSystem.class SHA-256: 289b475505ae014d4a2d040942ec91556fd2f4708edc80f5b1ede74b47f1a8f3
- FDMusicPart.class SHA-256: 664fe86d058edc621e9aacb2019882dc521cbaad642c0ffc75523db2b4653d95
- https://github.com/FINDERFEED/FDLib/blob/76e5e3159c2857208732d4acad254a4f71d2eb2f/src/main/java/com/finderfeed/fdlib/systems/music/FDMusicSystem.java
- https://github.com/FINDERFEED/FDLib/blob/76e5e3159c2857208732d4acad254a4f71d2eb2f/src/main/java/com/finderfeed/fdlib/systems/music/FDMusicPart.java
No pack changes, upstream issue submissions, local worker interruption or performance claim. Reconcile local/version state first and contribute a minimal qualified fix upstream if authorized through that workflow.
2026-10-15. Inspected public source commit b2303e62a2f32030b1a604266e043d8b24e85b24. The installed audit names Arcana 1.1.4-loader-hybrid; this public snapshot's version.properties says VERSION_NAME=1.1 / VERSION_INCREMENT=7. Exact official installed-bytecode mapping is unresolved. No source build or mod execution occurred.
MixinGameRenderer injects before the normal GameRenderer.renderLevel call. When advanced rendering is active, its callback creates/resizes a stencil-enabled target, changes render-hand/light/outline-related state, invokes another renderLevel itself, copies output, and restores state before the original invocation proceeds. This means one displayed frame can contain multiple world-render phases.
Therefore Hari/Create's proposed CPU caches must not mean "one world snapshot per presented frame regardless of pass". Cache immutable topology separately, and qualify view-dependent culling, matrices, origin, target dimensions, lighting, material preparation and transient GPU resources by the actual view/pass. Reusing geometry bytes may be valid while reusing a view-dependent result is not. Test Create contraptions visible in the advanced scope as well as the main view.
The additional pass is intentional functionality, not automatically waste. Removing it to inflate FPS would violate feature parity. Investigate common immutable preparation and bounded dirty-data reuse while preserving genuinely distinct rendering.
- Scope rendering copies stencil from the main target, reads/restores viewport and depth/blend state, applies a custom shader, and restores its previous shader/projection state.
- RenderHelper.copyStencil preserves separate read and draw bindings and the stencil write mask. Exercise them with distinct initial targets.
- Flashlight rendering backs up/copies depth and fits stencil across its targets. Test combined depth/stencil ownership, resize and render-target retirement.
- Thermal and night-vision variants alter lighting plus shader uniforms. A colored fullscreen quad is insufficient proof of their original behavior.
- Exercise interrupted/error paths in the extra world pass. The inspected callback's state restoration is sequential rather than one enclosing finally; an exception can leave partially switched state. A compatible bridge must not swallow failures and continue into corrupted rendering.
The source contains legacy immediate-mode helper functions such as drawFullscreenQuad and an RGB/depth-stencil framebuffer factory. A source-wide call search found definitions but no direct Java/Kotlin call sites for drawFullscreenQuad, createFramebuffer or copyAndScaleFramebuffer in this snapshot. Reflection/generated/official protected components can change reachability. Do not treat these helpers as proven hot paths, or waive their bytecode APIs without exact installed-artifact analysis.
The author's public-source notice says source builds omit protected gunpack/skill-pack loading components. Do not replace the official pack artifact with a locally built "compatible" version that quietly loses this functionality. Work against supported public rendering contracts and preserve installed content support; no protection bypass is proposed.
- Advanced rendering off/on; normal scope, thermal, night vision, multiple ocular nodes.
- Create moving machinery in both main and scope views, plus translucent and outlined entities.
- Two distinct read/draw framebuffers before the helper; verify expected exit bindings.
- Resize/fullscreen, GUI scale, reload, world switch, shader compile failure and target reallocation.
- Flashlights and beam/weapon effects with depth/stencil occlusion.
- Known-good official gunpack with original feature parity; separately classify TaCZ-addon weapon-data conflicts rather than blaming Vulkan.
Sources:
- https://github.com/Hamster-Baron/TACZ-Arcana/tree/b2303e62a2f32030b1a604266e043d8b24e85b24
- https://github.com/Hamster-Baron/TACZ-Arcana/blob/b2303e62a2f32030b1a604266e043d8b24e85b24/client/src/main/java/group/taczexpands/client/mixin/MixinGameRenderer.java
- https://github.com/Hamster-Baron/TACZ-Arcana/blob/b2303e62a2f32030b1a604266e043d8b24e85b24/client/src/main/kotlin/group/taczexpands/client/util/RenderHelper.kt
- https://www.curseforge.com/minecraft/mc-mods/tacz-arcana-timeless-and-classics-guns/files/8215461
No runtime profile, original-feature pass or FPS improvement has been measured.
2026-10-15. Actual integration overlay at published commit 98a85a89cb792d1d335b095ed774cf71773126fc, rather than upstream-only source. No GPU measurements or production edits.
Pipeline already persists config/vulkanmod_pipeline_cache.bin and passes its data into vkCreatePipelineCache. GraphicsPipeline.getHandle uses a state-keyed map and creates missing variants synchronously. Therefore "add a pipeline cache" is not a new fix. Measure variant misses, creation duration and cache reuse; the useful work is safer persistence, better qualified keys and avoiding first-use compilation where possible.
The legacy vertex-format branch calls getBindingDescription, which allocates VkVertexInputBindingDescription.calloc(1) without a MemoryStack. The returned buffer is attached to the create-info and no explicit free is present in that path. LWJGL documents that this overload requires explicit freeing. The neighboring attribute descriptions are stack allocated.
Candidate minimal correction: allocate the binding description on the existing createGraphicsPipeline stack (pass that stack into the helper), whose lifetime covers vkCreateGraphicsPipelines. This also covers exceptional exits. The NativeVertexLayout branch is separate and must not be described as leaking through this helper. This is a small per-variant host allocation, not evidence of the user's disk-space problem or a measured large FPS loss. Verify the current local source before applying.
PipelineState equality/hash includes the Java RenderPass object's identity. Each GraphicsPipeline retains its variant map until cleanUp. New render-pass objects can therefore create distinct map keys even when their relevant pipeline compatibility properties are equivalent. Resize/offscreen target churn is a targeted test, not an established measured leak in the current runtime.
Candidate: an immutable, complete compatibility signature instead of a mutable framebuffer object identity, while keeping all existing raster/depth/stencil/blend/logic/color-mask state. For dynamic rendering, include color/depth/stencil formats, sample and view configuration, and all pipeline-affecting extension state actually used. For legacy render passes, apply Vulkan's full render-pass/subpass compatibility rules; matching only color format is insufficient. Dynamic viewport/scissor dimensions should not become artificial pipeline variants.
Do not confuse pipeline reuse with framebuffer, image, descriptor or view-dependent draw-data reuse. Those still need their own identity and lifetime. A key must not mutate after insertion. Destroy evicted native variants only after recorded work retires.
The inspected loader reads all bytes and passes any nonempty file as initial data. The writer writes directly to the final path. A truncated/partially written file should not be treated as valid driver cache data. Add bounded length, cache-header/device compatibility checks and application-owned integrity/version metadata; publish a completed temporary file atomically, preserving only the useful current cache rather than accumulating backups. An invalid disposable cache should be ignored before the Vulkan call and rebuilt. Genuine device/allocation errors must still be reported accurately.
A compatible but different-device cache is handled by Vulkan's compatibility rules; that is distinct from corrupt bytes which fail initial-data validity requirements. Avoid overclaiming that every mismatch crashes a driver. The existing code also narrows returned cache size to int; validate size before allocation/conversion and handle changed size/VK_INCOMPLETE correctly when introducing concurrent compilation. Free temporary native buffers in finally paths.
- Count pipeline variants by shader/state and render-pass compatibility signature across repeated same-format resizes, scope opens, map UI, post effects and reloads.
- Confirm distinct formats/sample configurations never alias. Exercise dynamic and legacy rendering separately.
- Track the legacy binding-description allocation count on successful and injected-failure pipeline creation.
- Cold/warm cache startup and first-use frame-time distributions; isolate shader compilation from steady-state draw time.
- Empty, truncated, oversized, old-device and concurrently published cache fixtures; cache rejection must not corrupt the pack or discard source assets.
- Keep required draws exact. Prewarming or asynchronous compilation must not silently skip the first draw; fallback policy remains correctness-preserving.
Sources:
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java
- https://javadoc.lwjgl.org/org/lwjgl/vulkan/VkVertexInputBindingDescription.html
- https://docs.vulkan.org/spec/latest/chapters/renderpass.html#renderpass-compatibility
- https://docs.vulkan.org/refpages/latest/refpages/source/VkPipelineCacheCreateInfo.html
2026-10-15. Three more official Forge 1.20.1 JARs downloaded and SHA-512 checked against Modrinth. Research manifest now has 27 artifacts. None was loaded as a mod. Selected classes were statically decompiled.
CandyCloudsProcedure's raw GL surface is texture-level width/height queries for GL_TEXTURE_2D level zero. Hari already exposes this through GlTexture.getTexLevelParameter using tracked native-image metadata. Exact caller transport should use that existing source of truth; there is no need for GPU readback, a dummy texture size, or disabling the clouds. Verify the selected shader texture really becomes the bound texture and resource-pack replacement updates dimensions.
The original cloud mesh cache compares raw double x/y/z against the previous call. The builder's geometry/UV computation instead uses floor(x), floor(z), and floor(y / cloudHeight), while the draw path separately applies fractional translation. Consequently continuous wind or camera movement can trigger a close/new STATIC VertexBuffer/upload even while those mesh-driving cell values are unchanged.
Candidate: key the mesh cache by the exact quantized inputs used to construct geometry, cloud mode, texture/resource generation and dimensions, plus any configurable width/height or other true builder dependency. Keep fractional motion in the existing transform. Do not simply round with integer casts: negative-coordinate floor behavior matters. Verify the entire generated vertex stream before adopting the key, including transitions above/below cloud layers. If multiple cloud layers/textures share the static buffer, identity must distinguish them rather than reuse the last layer blindly.
Acceptance: byte-identical mesh data for old/new logic within a cache cell; original visuals at cell crossings, negative coordinates, fast/fancy mode, cloud-off/on, teleport, camera altitude changes and resource reload. Count builds, uploads, transient buffer retirements and frame times. This is a concrete source-level CPU/upload candidate, not a measured speedup.
Class SHA-256: 428106beb8762de181088fd438816b6ff0a3b921d468debed8a4844823d58ef0.
The pristine official artifact's direct GL scan yields a scissor helper. It converts scaled GUI coordinates into bottom-left framebuffer coordinates and clamps nonnegative extents. Reuse Hari's tested scissor implementation with exact transformed signature and test clipping at multiple GUI scales/resize, nested panels and subsequent draw-state restoration.
The installed filename includes Noxviola-DimThread-Interop-v1. That custom artifact has not been obtained or hash-matched here. The pristine download is a reference, never an automatic replacement: preserve its existing interop fixes. A single direct GL method reference does not establish that all RenderSystem, buffers and original gameplay paths are qualified.
Pristine RenderUtil.class SHA-256: 029fae742a4730f49c2561535e62868e5e98fd3a481fb296b75faf58426c241f.
The relevant class is inside META-INF/jarjar/crash_assistant-forge.jar. CurrentGPUDetector first checks glfwGetCurrentContext and returns if it is zero, then calls glGetString(GL_RENDERER) and posts the renderer through its diagnostic signal channel. Under a genuinely Vulkan-only context, the early return can mean missing diagnostic identity even if a symbol adapter exists.
A native-aware diagnostic hook should supply the actual selected Vulkan device/backend information from the existing renderer, with the same bounded diagnostic purpose. Do not create an OpenGL context or invent an OpenGL driver string just to satisfy this detector. Missing GPU identity should be shown honestly, not misreported as a rendering incompatibility or silently blamed for FPS.
Nested class SHA-256: 7b83f95de7a5112c5fc58ce907927d3e53e096fe42e26bef8a6d3cac46a0fbb4.
Sources:
- https://modrinth.com/mod/sweet-calamity/version/xghWX7Hd
- https://modrinth.com/mod/scorched-guns-2/version/A57yER99
- https://modrinth.com/mod/crash-assistant/version/1UfKorj6
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/GlTexture.java
Counts are constant-pool references, not dynamic invocation counts. Downloaded payloads and decompiled implementation bodies remain private analysis materials.
2026-10-15. Downloaded exact official supplementaries-1.20-3.1.43-forge.jar from Modrinth release S0TIJ1hU and verified SHA-512. It matches the older audit's filename/version, not a complete current installed-file hash qualification. JAR SHA-256: 6132fc23a2fe1da0ca57439b35526ee9a1a8d898397ff8e61b2d08fb951cdf6a.
The audit's direct GL caller, CompatIFMapTextureMixin2, is annotated OptionalMixin for ImmediatelyFast's map-atlas-generation mixin and wraps its updateAtlasTexture handler. It processes colored/lighted map texture data, delegates the image upload, and conditionally generates mipmaps when autoClose is false and mipmap is true. This is not evidence that every ordinary Supplementaries frame calls raw GL or that the optional path is active in the user's native pack.
Class SHA-256: 45a0896513a881159108768c491cfa798e595f230f3a5947fd581ee44423bd53.
- Verify actual optional-mixin activation and transformed call coverage. Don't install an otherwise incompatible ImmediatelyFast build just to activate this fixture.
- Reuse Hari's native mipmap generation for the real bound texture and preserve upload-before-mipmap ordering. Do not waive the archive or turn mip generation into a no-op.
- Keep colored/lighted map processing and the delegated upload exactly once, including subregion offsets and lifetime/autoClose behavior.
- Test partial atlas updates, multiple maps, color/light changes, GUI/item-frame views, reload and texture retirement.
- The inspected helper toggles Moonlight's map-mipmap state before/after its work without an enclosing finally. Include upload/generation failure tests so a failed optional path cannot leave the flag enabled for later unrelated images.
Multiple tile uploads can potentially repeat full-atlas mip generation or stream flushing. Count by atlas identity/generation and first sampling point. Coalescing work is valid only when all relevant writes are complete before every dependent sample/readback; don't defer past an intervening draw, merge different textures, or skip required mip content. Prove identical mip levels and map appearance before claiming a saving.
This refines the earlier conservative raw-call inventory. Optional code is neither automatic incompatibility nor automatic safety; distinguish static discovery from original-feature execution.
Sources:
- https://modrinth.com/mod/supplementaries/version/S0TIJ1hU
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/GlTexture.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/gl/NativePixelBufferApi.java
2026-10-15. Static inspection of the hash-verified Essential1.5.0.1 Forge1.20.1 nested payload. No screenshot upload, network operation, mod execution or user-computer change.
MinecraftWindowedTextureProviderKt.makeUploadBackend reads the JVM property essential.async_texture_loading. It defaults true. False selects the existing NotAsyncUploadBackend before attempting shared-window/context setup. The normal async backend tries to create a hidden GLFW window and prepares an OpenGL context/capabilities on its worker. Its teardown destroys the auxiliary window via the Minecraft executor.
NotAsyncUploadBackend.submit invokes work inline; it does not itself guarantee which thread called it. AsyncTextureManager constructs a PixelBufferTexture, retains content, submits upload work, releases the content after upload, and publishes completion on the Minecraft executor. PixelBufferTexture performs real allocation/upload/filter operations and exposes its UGpuTexture.
In an isolated native test profile, selecting the existing non-async backend with -Dessential.async_texture_loading=false can avoid the auxiliary OpenGL-context branch. This is a test switch, not proof that Essential works: every reached texture call still needs correct native transport, and the calling thread must satisfy Hari's ownership rules. Do not claim a performance win merely because the context error disappears; inline large uploads can cause UI stalls.
Verify screenshot browsing, scrolling many previews, reopening, cancellation, reload and window shutdown. Count auxiliary GLFW windows/contexts and confirm none were created by this path. Test both old and newly decoded images, filtering, alpha/color layout and texture retirement. No change was made to the user's JVM properties.
Keep file reading/decoding/downsampling off-thread, but queue GPU operations through the existing renderer-owned submission path with bounded byte/work budgets. Retain or copy input pixels until the deferred upload has consumed them. The original caller releases its PixelBuffer after upload returns, so returning early without owning the bytes risks use-after-release. Publish a completed texture only when the native synchronization/lifetime contract makes it safe to sample.
Cancellation must release queued buffers and avoid publishing a texture into a closed/replaced gallery. Use request generations and the actual backend reference lifetime; don't globally drain/delete other consumers' textures. Queue limits should defer work and prioritize visible items, never silently drop images or reduce image quality.
This requires adapting backend lifecycle and completion semantics, not pretending GL.createCapabilities succeeded or removing render-thread assertions. The original three Essential UGpuDeviceImpl/helper pin matches do not cover this additional screenshot subsystem.
- AsyncUploadBackendImpl: a4ca7a0f59e35e38eaf2bf23c2b56f9934aa9b8f50c0e3741cc7eafb7493a24a
- PixelBufferTexture: 319ed2a420795fb501d0e0d30a3ea72308a9d399aabad4572856c330c74ad214
- MinecraftWindowedTextureProviderKt: fab6db2535848d6eec189cc77d8ba66465619e303fdf0dab2b86bd2560b01684
Release provenance: https://modrinth.com/mod/essential (exact version and download hash in DOWNLOAD-MANIFEST.json). Implementation bodies remain private analysis material; compatibility work should preserve original behavior without redistributing proprietary source.
Renderer.bindGraphicsPipeline already suppresses redundant vkCmdBindPipeline calls by comparing native handles. Do not propose that as a missing optimization. It still obtains PipelineState and calls GraphicsPipeline.getHandle before the comparison; getHandle performs a map lookup. PipelineState.hashCode uses Objects.hash over several boxed integer fields plus render-pass identity. Actual allocation/CPU cost depends on JIT optimization and must be profiled.
A small candidate is a per-GraphicsPipeline last-state/handle fast path or a precomputed non-allocating hash, but only after making the key genuinely immutable and confirming all writers. The inspected state integer fields are package-mutable, not final. The downloaded subset shows constructor writes, which is not proof that the full local tree has no other mutation. Clear cached handles on cleanup/rebuild and preserve all shader/layout/pass compatibility boundaries.
Crucially, do NOT early-return from the entire Renderer.bindGraphicsPipeline when the pipeline handle is unchanged. The remainder applies dynamic blend constants and stencil reference/masks, which can change independently of the pipeline key. Optimize the lookup only; keep required dynamic-state checks. Tests must change only blend constants or stencil masks while reusing the same native pipeline and verify the resulting pixels.
Measure getHandle/hash invocation counts, allocated bytes and CPU time at the real target scene before selecting the change. This is a CPU micro-cost candidate, not an established large FPS bottleneck.
A concrete, uncompiled draft for the existing GPU suite is available at Queued PBO Regression Draft. It has not passed a GPU test.
2026-10-15. Static review of active integration/dimensions/overlay at Hari commit 98a85a89cb792d1d335b095ed774cf71773126fc. No current pack profiling or GPU qualification. These are bounded optimization candidates, not proven FPS gains.
NativeVertexArrayApi.layout() constructs new attribute/binding lists and a TreeSet each call. NativeVertexLayout's immutable constructor copies lists and allocates validation sets. Both native arrays and indexed draws request this layout, build two TreeMaps for current storage/offsets, and derive attribute extent through streams per relevant binding. NativeUiRenderBridge then validates shader inputs with per-input searches, constructs a texture-unit list and a pipeline key, and binds vertex buffers one binding per Vulkan call.
The existing pipeline map already reuses compatible entries; this is not a proposal to add a second shader compiler or indiscriminate global pipeline cache. The question is whether repeat CPU allocations and validation are hot enough to matter.
Cache the immutable layout per owned VAO. Invalidate when enabled attributes, attribute-to-binding mapping, format/integer interpretation, relative attribute offset/width, binding stride or divisor changes. Preserve deterministic ordering. Precompute per-binding maximum attribute extent while rebuilding.
Buffer identities, data versions, byte offsets and storage replacements remain dynamic draw state. Changing these alone should not invalidate the structural layout, but MUST still resolve current storage, range validity and retirement on every draw. Zero-name binding resets stride in the inspected API, so handle that structural effect. Legacy pointer calls modify multiple structural fields and must participate in invalidation.
Cache shader-layout validation only by immutable layout identity plus the actual linked program generation. Relinking, program retirement, device reset and any changed validation contract must invalidate it. Never skip image/sampler readiness, dynamic uniforms, current rendering pass or ownership checks merely because the layout matches.
legacyPointer calls format() and then calls glVertexAttribFormat/IFormat, which calls format() again. Each successful format() queries vkGetPhysicalDeviceFormatProperties. A validated Format object can be passed to an internal setter once; preserve current argument validation and error behavior.
Consider a small format-feature cache tied to the physical device/device generation, populated from real driver queries. This is not a fabricated capability table and must not assume support merely from an enum. Handle failure results consistently and reset when the device changes. First measure call frequency: the source may run primarily during setup, so this may improve startup or resource churn more than steady-state FPS.
Bindings 0,1,3,6,7 can be issued as three runs [0,1], [3], [6,7]. Do not compact them into 0..4; binding numbers are part of the shader/pipeline contract. Preserve buffers and offsets in corresponding order. Do not invent buffers for gaps. Reuse bounded stack scratch storage for arrays, respecting the actual device limits.
Vulkan's vertex input guide separates binding descriptions from buffer binding, and vkCmdBindVertexBuffers updates a consecutive binding range. See Khronos vertex input guide and fixed-function vertex processing specification. Format capabilities must be queried against the real device; see Khronos formats guide.
probe_vertex_layout_cache.py uses 10,000 deterministic synthetic state transitions. All 1,075 draw-time comparisons matched freshly reconstructed structural layout; 177 draws reused an unchanged layout. Sparse run flattening preserved binding indices. This validates only the authored model, not Java mutation coverage, GPU output or performance. The synthetic update distribution is not representative of the user's pack.
- Trace every actual mutation path before adopting the cache, including legacy pointers, bulk bind, deletion/reset, disabled attributes, integer formats and non-unit divisors.
- Keep current buffer COW/retirement behavior. Cached native handles must not outlive their owning storage generation.
- Compare unchanged-VAO draws, per-draw offset changes, data replacement, sparse slots, relink, resize, multiple passes and malformed state.
- Count layout rebuilds, validation cache hits, allocation bytes and Vulkan binding calls in matched runs. Verify pixel equality and validation-layer cleanliness before benchmarking complete pack frame-time distributions.
- Do not conflate this generic native input path with all Create instancing paths; establish actual caller coverage first.
Source paths: NativeVertexArrayApi.java, NativeUiRenderBridge.java under the active overlay's net/vulkanmod/gl, and net/vulkanmod/vulkan/shader/NativeVertexLayout.java. No production source was changed.
2026-10-15. Hari overlay baseline 98a85a89cb792d1d335b095ed774cf71773126fc. Research only; no allocation policy changed, no device benchmark.
NativePixelBufferApi.Store requests HOST_VISIBLE and HOST_COHERENT, prefers HOST_CACHED, and keeps the allocation mapped. NativeBufferObjectApi also uses this Store for vertex/index/uniform/storage/transfer usage. Thus one allocation policy serves pixel readback, upload, generic mapped buffers and native draw buffers. The actual selected memory type and heap have not been measured; these flags alone do not prove system RAM or device-local placement on the user's hardware.
Its write path is not purely write-only: writable() copies old mapped bytes to a replacement whenever recorded readers exist. The generic API also supports read-only/read-write maps, and usage upgrading copies old storage. Therefore blindly selecting a write-combined allocation for every buffer may hurt these reads. Conversely, a repeatedly drawn static buffer may merit device-local storage, but the current direct-mapping API cannot simply return a device-only address.
VMA distinguishes sequential CPU uploads, random host access and GPU-preferred resources. Its automatic memory selection requires explicit host access flags when mapping; permitting a transfer fallback requires the application to implement staging when the allocation is not host-visible. Unified-memory and discrete devices can have different best paths. See VMA recommended usage patterns and memory type selection.
That guidance does not make a one-flag change safe here. Audit the bundled VMA/LWJGL version and all map/read/COW consumers first.
Instrument existing allocation decisions with resource role, size, selected memory type/property flags, heap, bytes written/read, COW replacement bytes, transfer count and time waiting for completion. Aggregate counters; avoid per-draw logging. Separate actual device timings from host allocation/marshalling time.
Then compare on a representative disposable renderer fixture:
- Existing coherent/cached policy as the compatibility baseline.
- Sequential upload allocations only for proven write-only staging roles, with no accidental read-modify-write access.
- Device-local mirrors for long-lived, repeatedly read draw data, using bounded staging and generation-qualified dirty ranges.
- Host-readable readback allocations kept separate from write-only upload roles.
Preserve explicit read-map synchronization, partial updates, COW snapshot semantics, pointer validity, coherent/noncoherent cache maintenance, deletion and device-loss cleanup. If the chosen memory is noncoherent, correct flush/invalidate and atom-aligned ranges are mandatory; do not drop the existing coherent requirement without implementing them.
Device-local mirrors introduce extra memory and transfer cost. Small frequently changed buffers may regress. A full-buffer COW copy can dominate a tiny partial write; any dirty-range optimization must preserve untouched bytes and every recorded reader. Pooling or ring allocation must remain bounded and retire by actual GPU completion, not frame-number guesses.
Keep original mod features, public API semantics and pixel output. Require controlled CPU/GPU timing and p95/p99 frame-time comparison, actual selected heaps and peak bytes. Reject policies that improve one synthetic transfer but regress Physics, Xaero uploads, Essential UI or long-session memory. No FPS improvement is established by this report.
2026-10-15. Active overlay at published commit 98a85a89cb792d1d335b095ed774cf71773126fc, on migration/projectdump-20261004. The repository default main branch remains an older initial commit; do not accidentally build or audit main as the current published renderer. The paused worker's unpublished local changes still require reconciliation.
NativeUiRenderBridge.Entry.update calls GlProgram.currentNativeUniforms on each native UI/input draw. That method requests a fresh allocation and serializes every stored active uniform. NativeUiProgram.allocateUniforms delegates to SpirvUniformBlock.allocate, which uses ByteBuffer.allocateDirect(bytes); the zero-uniform branch still allocates a zero-capacity direct buffer. Matrix-derived programs additionally allocate float[16] and Matrix4f objects for the model-view-projection value each update.
This is confirmed allocation behavior in the inspected source, not a measured pack bottleneck or proof of a memory leak. Superseded buffers become eligible for ordinary JVM reclamation. Direct-buffer churn may affect allocation costs and frame-time tails; determine actual invocation counts first.
Reuse a renderer-owned direct scratch buffer with exact ABI capacity and byte order. Reinitialize the required bytes and serialize the same values on each draw at first, preserving existing semantics before attempting dirty-only updates. Maintain a strong reference while ManualUBO stores its address. Avoid the zero-uniform allocation entirely only after verifying no consumer expects a source pointer when no UBO exists.
The active Pipeline.updateUniforms invokes ubo.update into the selected frame uniform buffer synchronously and advances its offset. ManualUBO.update performs a memory copy from the stored source address. This supports exploring scratch reuse after the synchronous copy, but it does NOT allow overwriting GPU-visible frame storage that an earlier draw still uses. Reentrant callbacks, alternate own-buffer paths, frame rollover and any future asynchronous upload path must be considered separately.
Use per-entry or otherwise explicitly owned scratch, not an unsynchronized global buffer. Free explicitly owned native allocations on the matching retirement path, or retain a bounded JVM-owned buffer; don't mix allocation/free conventions. Measure peak retained capacity if many program/layout/texture-unit entries exist.
The GlProgram getters return stored float/int arrays, so setter-only revisions may miss external array mutation. The MVP derives from RenderSystem matrices rather than only glUniform calls. Relinking changes ABI/default values, and a reused buffer can leak stale field or padding bytes if initialization differs from a fresh direct allocation.
Keep full repacking initially; add revisions only after tracing every mutation and matrix source. Precomputed uniform ordinals can remove repeated storageNames.indexOf lookups without changing values, but must be tied to the linked ABI. Never cache a render-pass-dependent value by program name alone.
Compiled the unmodified pinned pure-Java SpirvUniformBlock with the host Java 21 compiler module. Source SHA-256: 15ee308b2de7872f8bc083895deb16beac556a7aa89e9a37a720293f3f1f8975.
An original shaderc-generated SPIR-V fixture contains scalar, vec3, mat3, scalar-array and integer-vector fields. The actual reflection/writer produced five fields in a 144-byte block. An original harness compared fresh allocation versus cleared/reused allocation across 1,000 varied writes, including omitted-field/default cases. All bytes matched.
This executes the actual isolated writer, not GlProgram, Minecraft, LWJGL uploads or the GPU. It is a correctness fixture, not a speed benchmark. Host Java 21 differs from a Java 17 pack runtime, so it is not pack-runtime qualification.
Evidence: uniform-reuse-probe.json; original harness uniform-probe/UniformReuseProbe.java and fixture generator uniform-probe/make_fixture.py. The separately fetched project source and compiled class files are not included in the handoff bundle.
- Matched allocation profile identifies this path as material.
- Default values, partial arrays, integer bit patterns, matrix changes and relink remain byte-identical.
- Two draws with different uniforms in one command buffer retain distinct GPU-visible snapshots.
- Alternating programs, texture-unit variants, frame rollover, resize and retirement do not share stale pointers or values.
- Validation layers and original Essential/native UI visuals pass; compare CPU time, allocation bytes and frame-time tails with the full intended pack.
2026-10-15. The official CurseForge file page identifies 1.20.1-1.2.6 as file 5548970. A fresh cloud-browser download did not yield an artifact. Do not count it as downloaded or qualified. The existing 1.2.2 JAR remains the only downloaded pristine Loot Beams binary in this audit.
The author's public 1.20.1 branch was independently retrieved at commit 36f44644cf086de9da45c1cfa2bf86cbc4a67779. Its build.gradle declares 1.20.1-1.2.5, so this is a source lead, not a verified 1.2.6 implementation. Official source: https://github.com/shiroroku/LootBeams/tree/36f44644cf086de9da45c1cfa2bf86cbc4a67779 . Release: https://www.curseforge.com/minecraft/mc-mods/loot-beams/files/5548970 .
ClientSetup.onRenderNameplate collects delayed beam-render consumers. onLevelRender executes them at AFTER_PARTICLES using the event camera's transform, and clears the list at AFTER_WEATHER. LootBeamsParticleRenderType also uses a registered custom particle shader and Minecraft's buffered rendering in addition to its direct GL blend enable.
Consequently, replacing the direct blend call is not enough to establish compatibility. Hari must preserve the original nameplate/event path, stage ordering, custom shader, particles, textures, depth and transparency. A missing or reordered stage can lose or repeat beams without an unsupported GL call.
The delayed list is static and global in this inspected source. Nested scope/secondary world rendering is a targeted regression scenario: check whether a nested pass consumes or clears another pass's pending entries, and whether a captured buffer source belongs to the correct pass. This is a testable risk, not an observed current 1.2.6 or Hari failure.
If reproduced, scope pending work by actual view/render invocation with exception-safe cleanup. Preserve world-space interpolation and original transparency ordering. Do not suppress the extra view or discard beam effects to claim compatibility.
isItemInRegistryList builds a filtered stream result and parses resource identifiers on every call. Its callers include render eligibility, light override and sound filtering. Compile each configured list into namespace and exact-item match sets at the relevant configuration/registry generation, preserving empty entries, invalid-ID behavior and the existing match semantics. Reuse this classification across the same generation without caching mutable ItemStack-dependent rarity or NBT decisions as if they were item-type constants.
The source already has tooltip and light caches with entity-removal cleanup. Do not report it as having no cache or add a second unbounded entity cache. Evaluate invalidation on stack/NBT/name changes and world unload before broadening reuse.
- Ordinary beam, particles, resource-pack replacement, nametag and sound work independently.
- Main world plus nested scope/view, weather changes, item removal during the frame and interrupted rendering.
- Config changes take effect without restart or stale eligibility; unknown registry IDs keep established behavior.
- Apotheosis installed/uninstalled and item rarity changes; version 1.2.6 explicitly advertises an Apotheosis crash fix, so do not replace it with this older source build.
- Count pending consumers, render-stage invocations, eligibility evaluations and allocation bytes. No FPS benefit is measured here.
2026-10-15. Author-description review only; this patch's binary/source has not been inspected or executed.
Macabre Fixes and Optimizations Patch describes potential leads around repeated network synchronization, unnecessary boss sorting, duplicate delayed overlay work and null sound lookups. These deserve exact-version source and behavior review.
The same description also advertises fewer spawns/worldgen features, simplified plant models, AI/gravity changes for selected entities, muted whispers and a dimension-resource override. Those changes prevent recommending the whole patch as meeting the owner's unchanged-features/visuals requirement. Config toggles are advertised, but their coverage/defaults and interactions are unverified.
Do not install it over the custom Macabre artifact or stack competing patches blindly. Isolate semantics-preserving fixes, compare against the user's existing Eye/UI/QoL changes, and retain original models, sounds, encounter density and behavior. Any deliberate gameplay/visual option belongs in an explicit optional setting, not a hidden performance shortcut. This does not establish Vulkan compatibility or an FPS gain.
2026-10-15. Original Data_Anchor-forge-1.20.1-1.0.0.23.jar SHA-256: 9169d2387acc9cf00d6747fdf4b43111dde99ac5ca00f84de687d8d5502c23c7. The exact client LevelMixin.class SHA-256 is e1fabb38fbe0302d1cc79b26812da3730265717f8316ffc7c5e2b4453907163a. CFR static inspection confirms the traversal below; target classes were not executed.
Supporting author source at fdcc773df6b1cb4f55fdd6fc154ef12660ce36d8: https://github.com/CorgiTaco/Data-Anchor/tree/fdcc773df6b1cb4f55fdd6fc154ef12660ce36d8 . Adjacent lifecycle conclusions come from this source; only the named client mixin was independently checked against the release class in this step.
At Level.tickBlockEntities RETURN on the client, the mixin walks the entire ClientChunkCache AtomicReferenceArray. For every non-null chunk it enumerates tracked-data keys and invokes eligible TickableTrackedData. It also traverses every block entity in that chunk, enumerates its tracked-data keys and invokes eligible tickable data. Even chunks/block entities with no tickable attachments incur traversal/discovery work.
This is a client-tick path, not a render-frame loop. No timing or attribution to the earlier partial-pack FPS samples is established. The combined-library benchmark and unrelated background GPU activity cannot isolate this library's contribution.
Maintain an index of client-loaded chunks/block entities with actual TickableTrackedData, updated when containers are created/replaced and owners load/unload. Keep exactly the same tick phase, eligibility and call count. Empty registries or containers may permit a cheap fast path after their lifecycle contracts are established.
Do not build the index by dropping initialization or factory callbacks. In the supporting source, chunk containers are explicitly created during construction and block-entity containers on setLevel; the generic container also has an optional lazy mode. Preserve all those behaviors and verify exact installed classes before implementing hooks.
Keep TickableTrackedData.tick separate from PendingBlockEntityTick.blockEntityTick: the common mixin has a distinct callback around actual block-entity ticking. Coalescing these as if they were duplicates could change behavior.
- Chunk-cache slots can be reused after movement or view-distance changes. Bind index entries to the exact chunk instance and level generation, not coordinates alone.
- Remove/unregister before an old object can tick after unload; dimension switches must release all references.
- Preserve effective iteration ordering, especially if replacing per-chunk map traversal with a global insertion-ordered list. Rebuild discovery order on structural changes if needed.
- Handle attachment/container recreation and registrations at the actual supported lifecycle point. Don't cache a permanent empty result before registration is complete.
- Keep client/server ownership and the server tick path separate. Do not disable attachments merely because they are invisible to the renderer.
Add low-overhead aggregate counters for chunk slots visited, block entities visited, keys examined, absent lookups and actual tick callbacks. Measure time on the same scene with the same dependents, first with zero tickable data and then representative chunk/block-entity attachments. Trace exactly-once callback sequences through load, movement, view-distance changes, removal and dimension changes. Verify save/network behavior remains identical.
Only promote after matched frame-time distributions show a benefit with the full intended pack. This finding needs no Vulkan API workaround and does not justify removing Data Anchor or its dependent mods. No production code changed.
The original ShaderDataBuffer.upload caller uses glBufferSubData(int, long, float[]), JVM descriptor (IJ[F)V. The inspected NativeBufferObjectApi exposes ByteBuffer/FloatBuffer/IntBuffer/ShortBuffer overloads, not float[]. A direct owner-only rewrite needs a matching array adapter as well as typed texel descriptors. Preserve array extent, byte overflow/range checks, native float representation and existing COW/lifetime semantics; do not retain a Java array pointer beyond a synchronous copy. This is an additional ABI requirement, not a GPU result.
2026-10-15. Compiled and exercised the unmodified TextureUploadSpan.java from Hari commit 98a85a89cb792d1d335b095ed774cf71773126fc with an original Java 21 host harness. No game, renderer or Vulkan API executed.
100,000 deterministic randomized valid rectangle layouts matched independently calculated offsets/spans. Nine invalid/overflow cases were rejected. A padded-row fixture confirmed that final-row trailing padding is excluded: width 3, height 2, row length 8, four bytes per pixel consumes 44 bytes, not 64.
This is positive evidence for this small arithmetic helper, not a new bug or performance gain. Future upload adapters should reuse its checked arithmetic where applicable instead of replacing it with width × height × bytes-per-pixel for padded source data.
Its contract does not model every OpenGL pixel-store rule. Caller-side conversion/alignment, buffer position/remaining, packed formats, negative coordinates, actual image extent, row pitch and GPU synchronization remain separate obligations. The test does not validate those callers or whole-mod uploads. Host Java 21 is not the pack's Java 17 runtime qualification.
Original harness: span-probe/TextureSpanProbe.java. Result: texture-span-probe.json. Project source and compiled classes are excluded from the handoff archive.
Research addition, 2026-10-15. Source audit of published Hari commit 98a85a89cb792d1d335b095ed774cf71773126fc, active integration/dimensions/overlay/forge/.../shader/Pipeline.java. Reconcile with unpublished local fixes before implementation. No GPU test or FPS gain claimed.
DescriptorSets already uses dynamic uniform offsets, per-frame descriptor sets and a last-bound resource comparison. It does NOT allocate and update a descriptor set for every draw when resources remain unchanged. updateUniforms still snapshots per-draw data, while needsUpdate compares image-view/sampler and buffer handles.
The useful extra experiment is bounded reuse of previously seen resource tuples within a frame. A material sequence A/B/A/B currently advances to another set whenever the last resource tuple differs; identical consecutive A/A already avoids updates. Profile actual vkUpdateDescriptorSets counts, resource-tuple repetition, pool growth and CPU time first. A content-keyed cache should include layout identity/generation, descriptor type, image view, sampler when used, declared image layout, buffer identity/generation, offset/range, and pool epoch. Dynamic offsets remain per draw. Do not omit image transitions merely because a descriptor cache hits.
Frame-local reuse is a smaller first experiment than bindless or descriptor-buffer migration. Reuse must preserve descriptor/resource lifetime until GPU completion. Bound the cache and invalidate on pool replacement, frame recycling, resource reload and device recreation. Reused Vulkan numeric handles alone are not durable resource identities. Preserve transparent draw order; sorting all draws by material is not a free substitute.
Khronos discusses descriptor caching and larger shared buffers, but its sample's mobile performance numbers cannot predict this modpack's gains: https://docs.vulkan.org/samples/latest/samples/performance/descriptor_management/README.html
In the inspected Pipeline.DescriptorSets.createDescriptorSets, MemoryUtil.memAllocLong(poolSize) allocates the host array holding descriptor handles. On pool growth, this.sets is replaced without freeing that previous host allocation. cleanUp frees dynamicOffsets, but not sets. The Vulkan descriptor pool is separately queued for destruction, which does not release this LWJGL host allocation.
Candidate repair: explicit ownership for the host handle array, freeing the previous array only after no CPU path still reads it and freeing the final array at cleanup; failure paths must also release temporary host allocations. GPU lifetime of descriptor sets/pools remains a separate deferred-destruction obligation. Do not solve this by prematurely destroying in-flight pools. Validate repeated growth, reload/close, allocation failures and idempotence. This is a source-level leak finding, not measured process leakage or the cause of the user's disk-space problem.
updateUniforms loops over UBOs and calls ub.checkCapacity(alignedSize) separately for each. UniformBuffer.resizeBuffer queues the old allocation and creates a new allocation; the inspected allocation path does not copy the previously written bytes. updateDescriptorSet subsequently obtains the current buffer ID for every UBO using the shared buffer.
Therefore, if UBO A is written to the shared allocation, then UBO B triggers growth during the same draw, the descriptor writes can reference the new allocation for A even though A's bytes were written only to the old allocation. This requires multiple UBOs sharing the arena and a capacity boundary; it is not proof that the native UI's usual single-UBO path fails. Old already-recorded draws with old descriptor sets are a different lifetime case.
Preferred first repair to investigate: precompute checked aligned demand per actual backing arena for the entire draw, ensure capacity once before taking offsets or writing any of that arena's UBOs, then serialize and bind. Account separately for externally supplied/own uniform buffers, whose semantics differ. Alternatively preserve required contents during growth, but copying every prior draw's data can add avoidable work. Test exact-boundary, one-byte-over, multiple blocks, mixed own/global buffers, allocation failure and previous-frame/in-flight data. Validate image/data results with the real renderer before promotion.
The generic pool builder budgets every image descriptor as COMBINED_IMAGE_SAMPLER and every buffer descriptor as UNIFORM_BUFFER_DYNAMIC. ImageDescriptor can describe STORAGE_IMAGE. Layout construction also indexes its compact allocation with the declared binding number. Before expanding compatibility to storage images, texture buffers or sparse bindings, construct pool budgets from actual descriptor types and map entries separately from binding numbers. This is a requirement for those extended paths, not proof that current densely assigned sampled-image shaders fail.
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/integration/dimensions/overlay/forge/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/source/forge/src/main/java/net/vulkanmod/vulkan/memory/UniformBuffer.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/source/forge/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java
- https://github.com/Herbertofury/Minecraft-Vulkan-Hybrid/blob/98a85a89cb792d1d335b095ed774cf71773126fc/source/forge/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java