Add custom uniform block (ChunkFix) passthrough API (#2974) - #3203
Draft
Wiz1991 wants to merge 1 commit into
Draft
Add custom uniform block (ChunkFix) passthrough API (#2974)#3203Wiz1991 wants to merge 1 commit into
Wiz1991 wants to merge 1 commit into
Conversation
When a shader pack is active, Iris substitutes its own program for a mod's assigned terrain pipeline and declares only its own uniform blocks, so a mod's custom UBO (bound to the render pass via RenderPass.setUniform) is silently dropped. This is the ChunkFix case reported in IrisShaders#2974 for MaLiLib/Litematica. Add IrisApi.registerCustomUniformBlock(pipeline, blockName, glslDeclaration) (API minor revision -> 4). Iris injects the given std140 block declaration into the substituted program's source and, at draw time, binds the mod-provided buffer to it -- but only for draws that actually supply the block on their pass, so other draws that share the substituted program (e.g. vanilla terrain) are unaffected. - IrisApi / IrisApiV0Impl: new method, minor API revision -> 4 - IrisPipelines: registry of custom blocks keyed by resolved ShaderKey - ShaderCreator: inject block declaration after #version into program source - ExtendedShader / IrisProgram / MixinGlCommandEncoder: optional per-draw bind of the pass-provided buffer (GlBuffer.handle() + glBindBufferRange) - IrisRenderSystem: bindBufferRange helper - accesswidener: widen GlRenderPass.uniforms (mirrors existing .samplers) Untested in-game; opening as a draft for review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzV8TMASPtN4nZY9dUeiBP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the custom-UBO (
ChunkFix) passthrough requested in #2974, so a mod can have its ownstd140uniform block forwarded to the program Iris substitutes for its terrain pipeline when a shader pack is active.Status: draft — compiles cleanly (
:fabric:build) but is not yet verified in-game. Opening for design review and to give the assignee something concrete to build on. Details and open questions below.The problem (per #2974)
When a shader pack is active and a mod assigns a terrain pipeline via
IrisApi.assignPipeline(...), Iris substitutes its ownExtendedShaderfor that pipeline. That substituted program declares only Iris's own uniform blocks (ExtendedShaderbind-group layouts), so a custom block the mod bound to the render pass viaRenderPass.setUniform("ChunkFix", buffer)is silently discarded — nothing in Iris reads unknown UBO names off the pass. This is what breaks MaLiLib/Litematica'sChunkFix(texture-atlas size) block under shaders.Approach
New API (minor revision bumped
3 → 4):The mod passes the block name and its exact
std140GLSL declaration (Iris can't derive the layout, and the mod can't edit Iris's generated program, so both pieces cross the API). Then:IrisPipelines) — resolves the pipeline to itsShaderKeyat registration and stores the block(s) under that key.ShaderCreator) — injects the block's GLSL after the#versionline of the substituted program's source, so the block exists in the linked program.ExtendedShader+MixinGlCommandEncoder) — after Iris sets up the substituted program, for each registered block present on this draw's pass, binds the mod'sGpuBufferSlice(GlBuffer.handle()+glBindBufferRange) to a binding point clear of Iris's own blocks.Why this is safe for shared programs
A mod's terrain pipeline resolves to the same
ShaderKey(e.g.TERRAIN_SOLID) that vanilla chunk terrain uses, so the substituted program is shared. The bind is therefore made optional: it only fires for draws whoseGlRenderPass.uniformsactually contains the block. Vanilla terrain draws neversetUniform("ChunkFix", …), so they are provably untouched — the block is declared-but-unbound-and-unused for them.Files
api/v0/IrisApi+apiimpl/IrisApiV0Impl— new method, revision → 4pipeline/IrisPipelines— registry keyed by resolvedShaderKeypipeline/programs/ShaderCreator— inject declaration after#versionpipeline/programs/ExtendedShader+pipeline/programs/IrisProgram+mixin/MixinGlCommandEncoder— optional per-draw bindgl/IrisRenderSystem—bindBufferRangehelperiris.accesswidener— widenGlRenderPass.uniforms(mirrors existing.samplers)Open questions for review
12) beyond Iris's own blocks rather than dynamically queried — is there a canonical free range to use?#version; a transformer-level injection may be preferable. An unused injected block could in principle be optimized out (then the bind is a safe no-op).sampleNearest(TextureSize)— so this is the plumbing half; the visual result still depends on the mod side. Paired with a MaLiLib change that registers the block; happy to iterate.Refs #2974.
🤖 Generated with Claude Code