From d846ff811e28331981c8f28939a3b1c696175d0d Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 28 Oct 2024 14:09:53 -0700 Subject: [PATCH 1/2] The great debug groups --- .../java/net/irisshaders/iris/gl/GLDebug.java | 25 ++++++--- .../iris/mixin/MixinRenderTarget.java | 13 +++++ .../irisshaders/iris/mixin/gui/MixinGui.java | 15 ++++-- .../iris/pipeline/CompositePass.java | 8 +++ .../iris/pipeline/CompositeRenderer.java | 43 +++++++++++++-- .../iris/pipeline/FinalPassRenderer.java | 3 ++ .../iris/pipeline/IrisRenderingPipeline.java | 53 ++++++++++++++++--- .../iris/shaderpack/programs/ProgramSet.java | 13 ++++- .../iris/shadows/ShadowCompositeRenderer.java | 8 ++- .../iris/shadows/ShadowRenderer.java | 10 +++- .../iris/targets/RenderTarget.java | 25 ++++----- .../sodium/terrain/FormatAnalyzer.java | 3 -- 12 files changed, 178 insertions(+), 41 deletions(-) create mode 100644 common/src/main/java/net/irisshaders/iris/pipeline/CompositePass.java diff --git a/common/src/main/java/net/irisshaders/iris/gl/GLDebug.java b/common/src/main/java/net/irisshaders/iris/gl/GLDebug.java index 5a97eaceb5..b48ca10a51 100644 --- a/common/src/main/java/net/irisshaders/iris/gl/GLDebug.java +++ b/common/src/main/java/net/irisshaders/iris/gl/GLDebug.java @@ -6,6 +6,7 @@ package net.irisshaders.iris.gl; import net.irisshaders.iris.Iris; +import net.irisshaders.iris.platform.IrisPlatformHelpers; import org.lwjgl.opengl.AMDDebugOutput; import org.lwjgl.opengl.ARBDebugOutput; import org.lwjgl.opengl.GL; @@ -19,6 +20,7 @@ import org.lwjgl.system.APIUtil; import java.io.PrintStream; +import java.util.Stack; import java.util.function.Consumer; public final class GLDebug { @@ -313,11 +315,11 @@ public static void nameObject(int id, int object, String name) { } public static void pushGroup(int id, String name) { - //debugState.pushGroup(id, name); + debugState.pushGroup(id, name); } public static void popGroup() { - //debugState.popGroup(); + debugState.popGroup(); } private interface DebugState { @@ -329,7 +331,10 @@ private interface DebugState { } private static class KHRDebugState implements DebugState { + // Let's see how bad this goes + private static final boolean ENABLE_DEBUG_GROUPS = true; private int stackSize; + private final Stack stack = new Stack<>(); @Override public void nameObject(int id, int object, String name) { @@ -338,15 +343,21 @@ public void nameObject(int id, int object, String name) { @Override public void pushGroup(int id, String name) { - KHRDebug.glPushDebugGroup(KHRDebug.GL_DEBUG_SOURCE_APPLICATION, id, name); - stackSize += 1; + if (ENABLE_DEBUG_GROUPS) { + KHRDebug.glPushDebugGroup(KHRDebug.GL_DEBUG_SOURCE_APPLICATION, id, name); + stack.push(name); + stackSize += 1; + } } @Override public void popGroup() { - if (stackSize != 0) { - KHRDebug.glPopDebugGroup(); - stackSize -= 1; + if (ENABLE_DEBUG_GROUPS) { + if (stackSize != 0) { + KHRDebug.glPopDebugGroup(); + stack.pop(); + stackSize -= 1; + } } } } diff --git a/common/src/main/java/net/irisshaders/iris/mixin/MixinRenderTarget.java b/common/src/main/java/net/irisshaders/iris/mixin/MixinRenderTarget.java index 209f767a6d..516d3955bf 100644 --- a/common/src/main/java/net/irisshaders/iris/mixin/MixinRenderTarget.java +++ b/common/src/main/java/net/irisshaders/iris/mixin/MixinRenderTarget.java @@ -1,7 +1,9 @@ package net.irisshaders.iris.mixin; import com.mojang.blaze3d.pipeline.RenderTarget; +import net.irisshaders.iris.gl.GLDebug; import net.irisshaders.iris.targets.Blaze3dRenderTargetExt; +import org.lwjgl.opengl.GL43C; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -18,6 +20,10 @@ public class MixinRenderTarget implements Blaze3dRenderTargetExt { @Shadow protected int depthBufferId; + @Shadow + protected int colorTextureId; + @Shadow + public int frameBufferId; @Unique private int iris$depthBufferVersion; @Unique @@ -29,6 +35,13 @@ public class MixinRenderTarget implements Blaze3dRenderTargetExt { iris$colorBufferVersion++; } + @Inject(method = "createBuffers", at = @At(value = "RETURN")) + private void nameDepthBuffer(int i, int j, boolean bl, CallbackInfo ci) { + GLDebug.nameObject(GL43C.GL_TEXTURE, this.depthBufferId, "Main depth texture"); + GLDebug.nameObject(GL43C.GL_TEXTURE, this.colorTextureId, "Main color texture"); + GLDebug.nameObject(GL43C.GL_FRAMEBUFFER, this.frameBufferId, "Main framebuffer"); + } + @Override public int iris$getDepthBufferVersion() { return iris$depthBufferVersion; diff --git a/common/src/main/java/net/irisshaders/iris/mixin/gui/MixinGui.java b/common/src/main/java/net/irisshaders/iris/mixin/gui/MixinGui.java index f6b0373af8..49ae780e33 100644 --- a/common/src/main/java/net/irisshaders/iris/mixin/gui/MixinGui.java +++ b/common/src/main/java/net/irisshaders/iris/mixin/gui/MixinGui.java @@ -1,7 +1,10 @@ package net.irisshaders.iris.mixin.gui; +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.mojang.blaze3d.systems.RenderSystem; import net.irisshaders.iris.Iris; +import net.irisshaders.iris.gl.GLDebug; import net.irisshaders.iris.gui.screen.HudHideable; import net.irisshaders.iris.pipeline.WorldRenderingPipeline; import net.minecraft.client.DeltaTracker; @@ -28,13 +31,19 @@ public class MixinGui { @Final private DebugScreenOverlay debugOverlay; - @Inject(method = "render", at = @At("HEAD"), cancellable = true) - public void iris$handleHudHidingScreens(GuiGraphics guiGraphics, DeltaTracker deltaTracker, CallbackInfo ci) { + @WrapMethod(method = "render") + public void iris$handleHudHidingScreens(GuiGraphics guiGraphics, DeltaTracker deltaTracker, Operation original) { Screen screen = this.minecraft.screen; if (screen instanceof HudHideable) { - ci.cancel(); + return; } + + GLDebug.pushGroup(1000, "GUI"); + + original.call(guiGraphics, deltaTracker); + + GLDebug.popGroup(); } @Inject(method = "renderVignette", at = @At("HEAD"), cancellable = true) diff --git a/common/src/main/java/net/irisshaders/iris/pipeline/CompositePass.java b/common/src/main/java/net/irisshaders/iris/pipeline/CompositePass.java new file mode 100644 index 0000000000..ca8db12590 --- /dev/null +++ b/common/src/main/java/net/irisshaders/iris/pipeline/CompositePass.java @@ -0,0 +1,8 @@ +package net.irisshaders.iris.pipeline; + +public enum CompositePass { + BEGIN, + PREPARE, + DEFERRED, + COMPOSITE +} diff --git a/common/src/main/java/net/irisshaders/iris/pipeline/CompositeRenderer.java b/common/src/main/java/net/irisshaders/iris/pipeline/CompositeRenderer.java index 671c64d317..0dc82f9d1f 100644 --- a/common/src/main/java/net/irisshaders/iris/pipeline/CompositeRenderer.java +++ b/common/src/main/java/net/irisshaders/iris/pipeline/CompositeRenderer.java @@ -7,6 +7,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import net.irisshaders.iris.features.FeatureFlags; +import net.irisshaders.iris.gl.GLDebug; import net.irisshaders.iris.gl.IrisRenderSystem; import net.irisshaders.iris.gl.blending.BlendModeOverride; import net.irisshaders.iris.gl.buffer.ShaderStorageBufferHolder; @@ -51,6 +52,7 @@ import org.lwjgl.opengl.GL43C; import java.util.Arrays; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -69,14 +71,16 @@ public class CompositeRenderer { private final Set customImages; private final TextureStage textureStage; private final WorldRenderingPipeline pipeline; + private final CompositePass compositePass; - public CompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives packDirectives, ProgramSource[] sources, ComputeSource[][] computes, RenderTargets renderTargets, ShaderStorageBufferHolder holder, + public CompositeRenderer(WorldRenderingPipeline pipeline, CompositePass compositePass, PackDirectives packDirectives, ProgramSource[] sources, ComputeSource[][] computes, RenderTargets renderTargets, ShaderStorageBufferHolder holder, TextureAccess noiseTexture, FrameUpdateNotifier updateNotifier, CenterDepthSampler centerDepthSampler, BufferFlipper bufferFlipper, Supplier shadowTargetsSupplier, TextureStage textureStage, Object2ObjectMap customTextureIds, Object2ObjectMap irisCustomTextures, Set customImages, ImmutableMap explicitPreFlips, CustomUniforms customUniforms) { this.pipeline = pipeline; + this.compositePass = compositePass; this.noiseTexture = noiseTexture; this.centerDepthSampler = centerDepthSampler; this.renderTargets = renderTargets; @@ -107,8 +111,9 @@ public CompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives packDir ImmutableSet flippedAtLeastOnceSnapshot = flippedAtLeastOnce.build(); if (source == null || !source.isValid()) { - if (computes[i] != null) { + if (computes.length != 0 && computes[i] != null && computes[i].length > 0) { ComputeOnlyPass pass = new ComputeOnlyPass(); + pass.name = computes[i].length > 0 ? computes[i][0].getName() : "unknown"; pass.computes = createComputes(computes[i], flipped, flippedAtLeastOnceSnapshot, shadowTargetsSupplier, holder); passes.add(pass); } @@ -118,9 +123,14 @@ public CompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives packDir Pass pass = new Pass(); ProgramDirectives directives = source.getDirectives(); + pass.name = source.getName(); pass.program = createProgram(source, flipped, flippedAtLeastOnceSnapshot, shadowTargetsSupplier); pass.blendModeOverride = source.getDirectives().getBlendModeOverride().orElse(null); - pass.computes = createComputes(computes[i], flipped, flippedAtLeastOnceSnapshot, shadowTargetsSupplier, holder); + if (computes.length != 0) { + pass.computes = createComputes(computes[i], flipped, flippedAtLeastOnceSnapshot, shadowTargetsSupplier, holder); + } else { + pass.computes = new ComputeProgram[0]; + } int[] drawBuffers = directives.getDrawBuffers(); @@ -172,6 +182,23 @@ public CompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives packDir GlStateManager._glBindFramebuffer(GL30C.GL_READ_FRAMEBUFFER, 0); } + private boolean hasComputes(ComputeSource[][] computes) { + boolean hasCompute = false; + + for (int i = 0; i < computes.length; i++) { + if (computes[i].length > 0) { + for (int j = 0; j < computes[i].length; j++) { + if (computes[i][j] != null) { + hasCompute = true; + break; + } + } + } + } + + return hasCompute; + } + private static void setupMipmapping(net.irisshaders.iris.targets.RenderTarget target, boolean readFromAlt) { if (target == null) return; @@ -224,12 +251,15 @@ public void recalculateSizes() { } public void renderAll() { + GLDebug.pushGroup(20 + compositePass.ordinal(), compositePass.name().toLowerCase(Locale.ROOT)); RenderSystem.disableBlend(); FullScreenQuadRenderer.INSTANCE.begin(); com.mojang.blaze3d.pipeline.RenderTarget main = Minecraft.getInstance().getMainRenderTarget(); - for (Pass renderPass : passes) { + for (int i = 0, passesSize = passes.size(); i < passesSize; i++) { + Pass renderPass = passes.get(i); + GLDebug.pushGroup(20 * compositePass.ordinal() + i, renderPass.name); boolean ranCompute = false; for (ComputeProgram computeProgram : renderPass.computes) { if (computeProgram != null) { @@ -247,6 +277,7 @@ public void renderAll() { Program.unbind(); if (renderPass instanceof ComputeOnlyPass) { + GLDebug.popGroup(); continue; } @@ -278,6 +309,7 @@ public void renderAll() { FullScreenQuadRenderer.INSTANCE.renderQuad(); BlendModeOverride.restore(); + GLDebug.popGroup(); } FullScreenQuadRenderer.INSTANCE.end(); @@ -300,6 +332,8 @@ public void renderAll() { } RenderSystem.activeTexture(GL15C.GL_TEXTURE0); + + GLDebug.popGroup(); } // TODO: Don't just copy this from DeferredWorldRenderingPipeline @@ -432,6 +466,7 @@ private static class Pass { int[] drawBuffers; int viewWidth; int viewHeight; + String name; Program program; BlendModeOverride blendModeOverride; ComputeProgram[] computes; diff --git a/common/src/main/java/net/irisshaders/iris/pipeline/FinalPassRenderer.java b/common/src/main/java/net/irisshaders/iris/pipeline/FinalPassRenderer.java index 6ffa39d9bb..26aefe2d4d 100644 --- a/common/src/main/java/net/irisshaders/iris/pipeline/FinalPassRenderer.java +++ b/common/src/main/java/net/irisshaders/iris/pipeline/FinalPassRenderer.java @@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import net.irisshaders.iris.features.FeatureFlags; +import net.irisshaders.iris.gl.GLDebug; import net.irisshaders.iris.gl.IrisRenderSystem; import net.irisshaders.iris.gl.buffer.ShaderStorageBufferHolder; import net.irisshaders.iris.gl.framebuffer.GlFramebuffer; @@ -218,6 +219,7 @@ public void renderFinalPass() { } if (this.finalPass != null) { + GLDebug.pushGroup(990, "final"); // If there is a final pass, we use the shader-based full screen quad rendering pathway instead // of just copying the color buffer. @@ -251,6 +253,7 @@ public void renderFinalPass() { FullScreenQuadRenderer.INSTANCE.renderQuad(); FullScreenQuadRenderer.INSTANCE.end(); + GLDebug.popGroup(); } else { // If there are no passes, we somehow need to transfer the content of the Iris color render targets into // the main Minecraft framebuffer. diff --git a/common/src/main/java/net/irisshaders/iris/pipeline/IrisRenderingPipeline.java b/common/src/main/java/net/irisshaders/iris/pipeline/IrisRenderingPipeline.java index b86468e042..e44b206e29 100644 --- a/common/src/main/java/net/irisshaders/iris/pipeline/IrisRenderingPipeline.java +++ b/common/src/main/java/net/irisshaders/iris/pipeline/IrisRenderingPipeline.java @@ -76,6 +76,7 @@ import net.irisshaders.iris.shadows.ShadowCompositeRenderer; import net.irisshaders.iris.shadows.ShadowRenderTargets; import net.irisshaders.iris.shadows.ShadowRenderer; +import net.irisshaders.iris.shadows.ShadowRenderingState; import net.irisshaders.iris.targets.Blaze3dRenderTargetExt; import net.irisshaders.iris.targets.BufferFlipper; import net.irisshaders.iris.targets.ClearPass; @@ -302,28 +303,28 @@ public IrisRenderingPipeline(ProgramSet programSet) { this.shadowComputes = createShadowComputes(programSet.getShadowCompute(), programSet); - this.beginRenderer = new CompositeRenderer(this, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Begin), programSet.getCompute(ProgramArrayId.Begin), renderTargets, shaderStorageBufferHolder, + this.beginRenderer = new CompositeRenderer(this, CompositePass.BEGIN, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Begin), programSet.getCompute(ProgramArrayId.Begin), renderTargets, shaderStorageBufferHolder, customTextureManager.getNoiseTexture(), updateNotifier, centerDepthSampler, flipper, shadowTargetsSupplier, TextureStage.BEGIN, customTextureManager.getCustomTextureIdMap().getOrDefault(TextureStage.BEGIN, Object2ObjectMaps.emptyMap()), customTextureManager.getIrisCustomTextures(), customImages, programSet.getPackDirectives().getExplicitFlips("begin_pre"), customUniforms); flippedBeforeShadow = flipper.snapshot(); - this.prepareRenderer = new CompositeRenderer(this, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Prepare), programSet.getCompute(ProgramArrayId.Prepare), renderTargets, shaderStorageBufferHolder, + this.prepareRenderer = new CompositeRenderer(this, CompositePass.PREPARE, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Prepare), programSet.getCompute(ProgramArrayId.Prepare), renderTargets, shaderStorageBufferHolder, customTextureManager.getNoiseTexture(), updateNotifier, centerDepthSampler, flipper, shadowTargetsSupplier, TextureStage.PREPARE, customTextureManager.getCustomTextureIdMap().getOrDefault(TextureStage.PREPARE, Object2ObjectMaps.emptyMap()), customTextureManager.getIrisCustomTextures(), customImages, programSet.getPackDirectives().getExplicitFlips("prepare_pre"), customUniforms); flippedAfterPrepare = flipper.snapshot(); - this.deferredRenderer = new CompositeRenderer(this, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Deferred), programSet.getCompute(ProgramArrayId.Deferred), renderTargets, shaderStorageBufferHolder, + this.deferredRenderer = new CompositeRenderer(this, CompositePass.DEFERRED, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Deferred), programSet.getCompute(ProgramArrayId.Deferred), renderTargets, shaderStorageBufferHolder, customTextureManager.getNoiseTexture(), updateNotifier, centerDepthSampler, flipper, shadowTargetsSupplier, TextureStage.DEFERRED, customTextureManager.getCustomTextureIdMap().getOrDefault(TextureStage.DEFERRED, Object2ObjectMaps.emptyMap()), customTextureManager.getIrisCustomTextures(), customImages, programSet.getPackDirectives().getExplicitFlips("deferred_pre"), customUniforms); flippedAfterTranslucent = flipper.snapshot(); - this.compositeRenderer = new CompositeRenderer(this, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Composite), programSet.getCompute(ProgramArrayId.Composite), renderTargets, shaderStorageBufferHolder, + this.compositeRenderer = new CompositeRenderer(this, CompositePass.COMPOSITE, programSet.getPackDirectives(), programSet.getComposite(ProgramArrayId.Composite), programSet.getCompute(ProgramArrayId.Composite), renderTargets, shaderStorageBufferHolder, customTextureManager.getNoiseTexture(), updateNotifier, centerDepthSampler, flipper, shadowTargetsSupplier, TextureStage.COMPOSITE_AND_FINAL, customTextureManager.getCustomTextureIdMap().getOrDefault(TextureStage.COMPOSITE_AND_FINAL, Object2ObjectMaps.emptyMap()), customTextureManager.getIrisCustomTextures(), customImages, programSet.getPackDirectives().getExplicitFlips("composite_pre"), customUniforms); @@ -428,7 +429,7 @@ public IrisRenderingPipeline(ProgramSet programSet) { customTextureManager.getCustomTextureIdMap(TextureStage.SHADOWCOMP), customImages, programSet.getPackDirectives().getExplicitFlips("shadowcomp_pre"), customTextureManager.getIrisCustomTextures(), customUniforms); if (programSet.getPackDirectives().getShadowDirectives().isShadowEnabled().orElse(true)) { - this.shadowRenderer = new ShadowRenderer(resolver.resolveNullable(ProgramId.ShadowSolid), + this.shadowRenderer = new ShadowRenderer(this, resolver.resolveNullable(ProgramId.ShadowSolid), programSet.getPackDirectives(), shadowRenderTargets, shadowCompositeRenderer, customUniforms, programSet.getPack().hasFeature(FeatureFlags.SEPARATE_HARDWARE_SAMPLERS)); } else { shadowRenderer = null; @@ -745,8 +746,16 @@ public void addGbufferOrShadowSamplers(SamplerHolder samplers, ImageHolder image } } + private boolean shouldRemovePhase = false; + @Override public WorldRenderingPhase getPhase() { + if (shouldRemovePhase) { + phase = WorldRenderingPhase.NONE; + shouldRemovePhase = false; + GLDebug.popGroup(); + } + if (overridePhase != null) { return overridePhase; } @@ -754,11 +763,35 @@ public WorldRenderingPhase getPhase() { return phase; } + public void removePhaseIfNeeded() { + if (shouldRemovePhase) { + phase = WorldRenderingPhase.NONE; + shouldRemovePhase = false; + GLDebug.popGroup(); + } + } + @Override public void setPhase(WorldRenderingPhase phase) { + if (phase == WorldRenderingPhase.NONE) { + if (shouldRemovePhase) GLDebug.popGroup(); + shouldRemovePhase = true; + return; + } else { + shouldRemovePhase = false; + if (phase == this.phase) { + return; + } + } + GLDebug.popGroup(); - if (phase != WorldRenderingPhase.NONE) - GLDebug.pushGroup(phase.ordinal(), StringUtils.capitalize(phase.name().toLowerCase(Locale.ROOT).replace("_", " "))); + if (phase != WorldRenderingPhase.NONE && phase != WorldRenderingPhase.TERRAIN_CUTOUT && phase != WorldRenderingPhase.TERRAIN_CUTOUT_MIPPED && phase != WorldRenderingPhase.TRIPWIRE) { + if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { + GLDebug.pushGroup(phase.ordinal(), "Shadow " + StringUtils.capitalize(phase.name().toLowerCase(Locale.ROOT).replace("_", " "))); + } else { + GLDebug.pushGroup(phase.ordinal(), StringUtils.capitalize(phase.name().toLowerCase(Locale.ROOT).replace("_", " "))); + } + } this.phase = phase; } @@ -812,6 +845,7 @@ public void beginLevelRendering() { RenderSystem.activeTexture(GL15C.GL_TEXTURE0); Vector4f emptyClearColor = new Vector4f(1.0F); + GLDebug.pushGroup(100, "Clear textures"); for (GlImage image : clearImages) { ARBClearTexture.glClearTexImage(image.getId(), 0, image.getFormat().getGlFormat(), image.getPixelType().getGlFormat(), (int[]) null); @@ -917,6 +951,8 @@ public void beginLevelRendering() { clearPass.execute(fogColor); } + GLDebug.popGroup(); + // Make sure to switch back to the main framebuffer. If we forget to do this then our alt buffers might be // cleared to the fog color, which absolutely is not what we want! // @@ -1006,6 +1042,8 @@ public void beginTranslucents() { throw new IllegalStateException("Tried to use a destroyed world rendering pipeline"); } + removePhaseIfNeeded(); + isBeforeTranslucent = false; // We need to copy the current depth texture so that depthtex1 can contain the depth values for @@ -1032,6 +1070,7 @@ public void beginTranslucents() { @Override public void finalizeLevelRendering() { isRenderingWorld = false; + removePhaseIfNeeded(); compositeRenderer.renderAll(); finalPassRenderer.renderFinalPass(); } diff --git a/common/src/main/java/net/irisshaders/iris/shaderpack/programs/ProgramSet.java b/common/src/main/java/net/irisshaders/iris/shaderpack/programs/ProgramSet.java index c0a7cecefc..bed5ddcbaf 100644 --- a/common/src/main/java/net/irisshaders/iris/shaderpack/programs/ProgramSet.java +++ b/common/src/main/java/net/irisshaders/iris/shaderpack/programs/ProgramSet.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.EnumMap; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -65,10 +66,14 @@ public ProgramSet(AbsolutePackPath directory, Function ProgramSource[] sources = readProgramArray(directory, sourceProvider, id.getSourcePrefix(), shaderProperties, readTesselation); compositePrograms.put(id, sources); ComputeSource[][] computes = new ComputeSource[id.getNumPrograms()][]; + boolean hasNoComputes = true; for (int i = 0; i < id.getNumPrograms(); i++) { computes[i] = readComputeArray(directory, sourceProvider, id.getSourcePrefix() + (i == 0 ? "" : i), shaderProperties); + if (computes[i].length > 0) { + hasNoComputes = false; + } } - computePrograms.put(id, computes); + computePrograms.put(id, hasNoComputes ? new ComputeSource[0][] : computes); } Future[] sources = new Future[ProgramId.values().length]; @@ -198,6 +203,10 @@ private ComputeSource[] readComputeArray(AbsolutePackPath directory, } } + if (Arrays.stream(programs).allMatch(Objects::isNull)) { + return new ComputeSource[0]; + } + return programs; } @@ -297,6 +306,6 @@ public ProgramSource[] getComposite(ProgramArrayId programArrayId) { } public ComputeSource[][] getCompute(ProgramArrayId programArrayId) { - return computePrograms.getOrDefault(programArrayId, new ComputeSource[programArrayId.getNumPrograms()][27]); + return computePrograms.getOrDefault(programArrayId, new ComputeSource[0][0]); } } diff --git a/common/src/main/java/net/irisshaders/iris/shadows/ShadowCompositeRenderer.java b/common/src/main/java/net/irisshaders/iris/shadows/ShadowCompositeRenderer.java index 2a79e67945..b81d4feef0 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/ShadowCompositeRenderer.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/ShadowCompositeRenderer.java @@ -91,7 +91,7 @@ public ShadowCompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives p ImmutableSet flippedAtLeastOnceSnapshot = flippedAtLeastOnce.build(); if (source == null || !source.isValid()) { - if (computes[i] != null) { + if (computes.length > 0 && computes[i] != null) { ComputeOnlyPass pass = new ComputeOnlyPass(); pass.computes = createComputes(computes[i], flipped, flippedAtLeastOnceSnapshot, renderTargets, holder); passes.add(pass); @@ -103,7 +103,11 @@ public ShadowCompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives p ProgramDirectives directives = source.getDirectives(); pass.program = createProgram(source, flipped, flippedAtLeastOnceSnapshot, renderTargets); - pass.computes = createComputes(computes[i], flipped, flippedAtLeastOnceSnapshot, renderTargets, holder); + if (computes.length > 0) { + pass.computes = createComputes(computes[i], flipped, flippedAtLeastOnceSnapshot, renderTargets, holder); + } else { + pass.computes = new ComputeProgram[0]; + } int[] drawBuffers = source.getDirectives().hasUnknownDrawBuffers() ? new int[]{0, 1} : source.getDirectives().getDrawBuffers(); GlFramebuffer framebuffer = renderTargets.createColorFramebuffer(flipped, drawBuffers); diff --git a/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java b/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java index 8e7cbfdb09..f8233e6d6f 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java @@ -11,9 +11,11 @@ import net.irisshaders.batchedentityrendering.impl.RenderBuffersExt; import net.irisshaders.iris.Iris; import net.irisshaders.iris.compat.dh.DHCompat; +import net.irisshaders.iris.gl.GLDebug; import net.irisshaders.iris.gl.IrisRenderSystem; import net.irisshaders.iris.gui.option.IrisVideoSettings; import net.irisshaders.iris.mixin.LevelRendererAccessor; +import net.irisshaders.iris.pipeline.IrisRenderingPipeline; import net.irisshaders.iris.shaderpack.programs.ProgramSource; import net.irisshaders.iris.shaderpack.properties.PackDirectives; import net.irisshaders.iris.shaderpack.properties.PackShadowDirectives; @@ -85,6 +87,7 @@ public class ShadowRenderer { private final String debugStringOverall; private final boolean separateHardwareSamplers; private final boolean shouldRenderLightBlockEntities; + private final IrisRenderingPipeline pipeline; private boolean packHasVoxelization; private FrustumHolder terrainFrustumHolder; private FrustumHolder entityFrustumHolder; @@ -92,9 +95,10 @@ public class ShadowRenderer { private int renderedShadowEntities = 0; private int renderedShadowBlockEntities = 0; - public ShadowRenderer(ProgramSource shadow, PackDirectives directives, + public ShadowRenderer(IrisRenderingPipeline pipeline, ProgramSource shadow, PackDirectives directives, ShadowRenderTargets shadowRenderTargets, ShadowCompositeRenderer compositeRenderer, CustomUniforms customUniforms, boolean separateHardwareSamplers) { + this.pipeline = pipeline; this.separateHardwareSamplers = separateHardwareSamplers; final PackShadowDirectives shadowDirectives = directives.getShadowDirectives(); @@ -565,7 +569,11 @@ public void renderShadows(LevelRendererAccessor levelRenderer, Camera playerCame ((CullingDataCache) levelRenderer).restoreState(); } + pipeline.removePhaseIfNeeded(); + + GLDebug.pushGroup(901, "shadowcomp"); compositeRenderer.renderAll(); + GLDebug.popGroup(); levelRenderer.setRenderBuffers(playerBuffers); diff --git a/common/src/main/java/net/irisshaders/iris/targets/RenderTarget.java b/common/src/main/java/net/irisshaders/iris/targets/RenderTarget.java index 7e480c6907..b9be97c75f 100644 --- a/common/src/main/java/net/irisshaders/iris/targets/RenderTarget.java +++ b/common/src/main/java/net/irisshaders/iris/targets/RenderTarget.java @@ -23,10 +23,12 @@ public class RenderTarget { private int width; private int height; private boolean isValid; + private String name; public RenderTarget(Builder builder) { this.isValid = true; + this.name = builder.name; this.internalFormat = builder.internalFormat; this.format = builder.format; this.type = builder.type; @@ -41,13 +43,8 @@ public RenderTarget(Builder builder) { this.altTexture = textures[1]; boolean isPixelFormatInteger = builder.internalFormat.getPixelFormat().isInteger(); - setupTexture(mainTexture, builder.width, builder.height, !isPixelFormatInteger); - setupTexture(altTexture, builder.width, builder.height, !isPixelFormatInteger); - - if (builder.name != null) { - GLDebug.nameObject(GL43C.GL_TEXTURE, mainTexture, builder.name + " main"); - GLDebug.nameObject(GL43C.GL_TEXTURE, mainTexture, builder.name + " alt"); - } + setupTexture(mainTexture, builder.width, builder.height, !isPixelFormatInteger, false); + setupTexture(altTexture, builder.width, builder.height, !isPixelFormatInteger, true); // Clean up after ourselves // This is strictly defensive to ensure that other buggy code doesn't tamper with our textures @@ -58,8 +55,8 @@ public static Builder builder() { return new Builder(); } - private void setupTexture(int texture, int width, int height, boolean allowsLinear) { - resizeTexture(texture, width, height); + private void setupTexture(int texture, int width, int height, boolean allowsLinear, boolean alt) { + resizeTexture(texture, width, height, alt); IrisRenderSystem.texParameteri(texture, GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_MIN_FILTER, allowsLinear ? GL11C.GL_LINEAR : GL11C.GL_NEAREST); IrisRenderSystem.texParameteri(texture, GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_MAG_FILTER, allowsLinear ? GL11C.GL_LINEAR : GL11C.GL_NEAREST); @@ -67,8 +64,12 @@ private void setupTexture(int texture, int width, int height, boolean allowsLine IrisRenderSystem.texParameteri(texture, GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_WRAP_T, GL13C.GL_CLAMP_TO_EDGE); } - private void resizeTexture(int texture, int width, int height) { + private void resizeTexture(int texture, int width, int height, boolean alt) { IrisRenderSystem.texImage2D(texture, GL11C.GL_TEXTURE_2D, 0, internalFormat.getGlFormat(), width, height, 0, format.getGlFormat(), type.getGlFormat(), NULL_BUFFER); + + if (name != null) { + GLDebug.nameObject(GL43C.GL_TEXTURE, texture, name + " " + (alt ? "alt" : "main")); + } } void resize(Vector2i textureScaleOverride) { @@ -82,9 +83,9 @@ void resize(int width, int height) { this.width = width; this.height = height; - resizeTexture(mainTexture, width, height); + resizeTexture(mainTexture, width, height, false); - resizeTexture(altTexture, width, height); + resizeTexture(altTexture, width, height, true); } public InternalTextureFormat getInternalFormat() { diff --git a/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/FormatAnalyzer.java b/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/FormatAnalyzer.java index fb182cc3c8..cdbcfe6ab0 100644 --- a/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/FormatAnalyzer.java +++ b/common/src/main/java/net/irisshaders/iris/vertices/sodium/terrain/FormatAnalyzer.java @@ -89,9 +89,6 @@ public static ChunkVertexType createFormat(boolean blockId, boolean normal, bool VERTEX_FORMAT.addElement(IrisChunkMeshAttributes.MID_BLOCK, 14, midBlockOffset); } - System.out.println("Created a new format with " + offset + " stride: " + Integer.toBinaryString(key)); - - return classMap.computeIfAbsent(key, k -> new XHFPModelVertexType(VERTEX_FORMAT.build(), blockIdOffset, normalOffset, midUvOffset, midBlockOffset)); } } From f9c974b90da9cf824249cbc62f4495d197720a29 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Tue, 29 Oct 2024 09:04:30 -0700 Subject: [PATCH 2/2] Improve shadow projection code --- .../irisshaders/iris/compat/dh/DHCompat.java | 4 +-- .../properties/PackShadowDirectives.java | 5 ++-- .../iris/shadows/ShadowMatrices.java | 27 ++++++------------- .../iris/shadows/ShadowRenderer.java | 13 ++++++--- .../iris/uniforms/MatrixUniforms.java | 6 ++--- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/net/irisshaders/iris/compat/dh/DHCompat.java b/common/src/main/java/net/irisshaders/iris/compat/dh/DHCompat.java index c980c8f4c8..090ecd7b80 100644 --- a/common/src/main/java/net/irisshaders/iris/compat/dh/DHCompat.java +++ b/common/src/main/java/net/irisshaders/iris/compat/dh/DHCompat.java @@ -151,7 +151,7 @@ public void clearPipeline() { } public int getDepthTex() { - if (compatInternalInstance == null) return -1; + if (compatInternalInstance == null) return 0; try { return (int) getDepthTex.invoke(compatInternalInstance); @@ -161,7 +161,7 @@ public int getDepthTex() { } public int getDepthTexNoTranslucent() { - if (compatInternalInstance == null) return -1; + if (compatInternalInstance == null) return 0; try { return (int) getDepthTexNoTranslucent.invoke(compatInternalInstance); diff --git a/common/src/main/java/net/irisshaders/iris/shaderpack/properties/PackShadowDirectives.java b/common/src/main/java/net/irisshaders/iris/shaderpack/properties/PackShadowDirectives.java index ea7fff28cd..41705db998 100644 --- a/common/src/main/java/net/irisshaders/iris/shaderpack/properties/PackShadowDirectives.java +++ b/common/src/main/java/net/irisshaders/iris/shaderpack/properties/PackShadowDirectives.java @@ -7,6 +7,7 @@ import net.irisshaders.iris.gl.texture.InternalTextureFormat; import net.irisshaders.iris.helpers.OptionalBoolean; import net.irisshaders.iris.shaderpack.parsing.DirectiveHolder; +import net.irisshaders.iris.shadows.ShadowMatrices; import org.joml.Vector4f; import java.util.Optional; @@ -60,8 +61,8 @@ public PackShadowDirectives(ShaderProperties properties) { // shadowRenderDistanceMul to a nonzero value, since having a high shadow render distance will impact // performance quite heavily on most systems. this.distance = 160.0f; - this.nearPlane = 0.05f; - this.farPlane = 256.0f; + this.nearPlane = ShadowMatrices.NEAR; + this.farPlane = ShadowMatrices.FAR; this.voxelDistance = 0.0f; // By default, shadows are not culled based on distance from the player. However, pack authors may diff --git a/common/src/main/java/net/irisshaders/iris/shadows/ShadowMatrices.java b/common/src/main/java/net/irisshaders/iris/shadows/ShadowMatrices.java index 3b317576aa..b51a075fe4 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/ShadowMatrices.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/ShadowMatrices.java @@ -5,22 +5,12 @@ import org.joml.Matrix4f; public class ShadowMatrices { - private static final float NEAR = 0.05f; - private static final float FAR = 256.0f; - - // NB: These matrices are in column-major order, not row-major order like what you'd expect! + public static final float NEAR = -100.05f; + public static final float FAR = 156.0f; public static Matrix4f createOrthoMatrix(float halfPlaneLength, float nearPlane, float farPlane) { - return new Matrix4f( - // column 1 - 1.0f / halfPlaneLength, 0f, 0f, 0f, - // column 2 - 0f, 1.0f / halfPlaneLength, 0f, 0f, - // column 3 - 0f, 0f, 2.0f / (nearPlane - farPlane), 0f, - // column 4 - 0f, 0f, -(farPlane + nearPlane) / (farPlane - nearPlane), 1f - ); + //System.out.println("making a matrix with " + nearPlane + " / " + farPlane + " * " + halfPlaneLength); + return new Matrix4f().setOrthoSymmetric(halfPlaneLength, halfPlaneLength, nearPlane, farPlane); } public static Matrix4f createPerspectiveMatrix(float fov) { @@ -38,7 +28,7 @@ public static Matrix4f createPerspectiveMatrix(float fov) { ); } - public static void createBaselineModelViewMatrix(PoseStack target, float shadowAngle, float sunPathRotation) { + public static void createBaselineModelViewMatrix(PoseStack target, float shadowAngle, float sunPathRotation, float nearPlane, float farPlane) { float skyAngle; if (shadowAngle < 0.25f) { @@ -50,7 +40,6 @@ public static void createBaselineModelViewMatrix(PoseStack target, float shadowA target.last().normal().identity(); target.last().pose().identity(); - target.last().pose().translate(0.0f, 0.0f, -100.0f); target.mulPose(Axis.XP.rotationDegrees(90.0F)); target.mulPose(Axis.ZP.rotationDegrees(skyAngle * -360.0f)); target.mulPose(Axis.XP.rotationDegrees(sunPathRotation)); @@ -88,8 +77,8 @@ public static void snapModelViewToGrid(PoseStack target, float shadowIntervalSiz } public static void createModelViewMatrix(PoseStack target, float shadowAngle, float shadowIntervalSize, - float sunPathRotation, double cameraX, double cameraY, double cameraZ) { - createBaselineModelViewMatrix(target, shadowAngle, sunPathRotation); + float sunPathRotation, double cameraX, double cameraY, double cameraZ, float nearPlane, float farPlane) { + createBaselineModelViewMatrix(target, shadowAngle, sunPathRotation, nearPlane, farPlane); snapModelViewToGrid(target, shadowIntervalSize, cameraX, cameraY, cameraZ); } @@ -155,7 +144,7 @@ public static void main(String[] args) { // When DayTime=0, skyAngle = 282 degrees. // Thus, sunAngle = shadowAngle = 0.03451777f createModelViewMatrix(modelView, 0.03451777f, 2.0f, - 0.0f, 0.646045982837677f, 82.53274536132812f, -514.0264282226562f); + 0.0f, 0.646045982837677f, 82.53274536132812f, -514.0264282226562f, NEAR, FAR); test("model view at dawn", expectedModelViewAtDawn, modelView.last().pose()); } diff --git a/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java b/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java index f8233e6d6f..c496386ab0 100644 --- a/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java +++ b/common/src/main/java/net/irisshaders/iris/shadows/ShadowRenderer.java @@ -154,7 +154,7 @@ public ShadowRenderer(IrisRenderingPipeline pipeline, ProgramSource shadow, Pack configureSamplingSettings(shadowDirectives); } - public static PoseStack createShadowModelView(float sunPathRotation, float intervalSize) { + public static PoseStack createShadowModelView(float sunPathRotation, float intervalSize, float nearPlane, float farPlane) { // Determine the camera position Vector3d cameraPos = CameraUniforms.getUnshiftedCameraPosition(); @@ -164,7 +164,7 @@ public static PoseStack createShadowModelView(float sunPathRotation, float inter // Set up our modelview matrix stack PoseStack modelView = new PoseStack(); - ShadowMatrices.createModelViewMatrix(modelView, getShadowAngle(), intervalSize, sunPathRotation, cameraX, cameraY, cameraZ); + ShadowMatrices.createModelViewMatrix(modelView, getShadowAngle(), intervalSize, sunPathRotation, cameraX, cameraY, cameraZ, nearPlane, farPlane); return modelView; } @@ -384,7 +384,7 @@ public void renderShadows(LevelRendererAccessor levelRenderer, Camera playerCame setupShadowViewport(); // Create our camera - PoseStack modelView = createShadowModelView(this.sunPathRotation, this.intervalSize); + PoseStack modelView = createShadowModelView(this.sunPathRotation, this.intervalSize, nearPlane, farPlane); MODELVIEW = new Matrix4f(modelView.last().pose()); // Set up our orthographic projection matrix and load it into RenderSystem @@ -393,7 +393,7 @@ public void renderShadows(LevelRendererAccessor levelRenderer, Camera playerCame // If FOV is not null, the pack wants a perspective based projection matrix. (This is to support legacy packs) shadowProjection = ShadowMatrices.createPerspectiveMatrix(this.fov); } else { - shadowProjection = ShadowMatrices.createOrthoMatrix(halfPlaneLength, nearPlane < 0 ? -DHCompat.getRenderDistance() : nearPlane, farPlane < 0 ? DHCompat.getRenderDistance() : farPlane); + shadowProjection = ShadowMatrices.createOrthoMatrix(halfPlaneLength, nearPlane < 0 ? -DHCompat.getRenderDistance() * 16 : nearPlane, farPlane < 0 ? DHCompat.getRenderDistance() * 16 : farPlane); } IrisRenderSystem.setShadowProjection(shadowProjection); @@ -703,6 +703,7 @@ public void addDebugText(List messages) { messages.add("[" + Iris.MODNAME + "] Shadow Maps: " + debugStringOverall); messages.add("[" + Iris.MODNAME + "] Shadow Distance Terrain: " + terrainFrustumHolder.getDistanceInfo() + " Entity: " + entityFrustumHolder.getDistanceInfo()); messages.add("[" + Iris.MODNAME + "] Shadow Culling Terrain: " + terrainFrustumHolder.getCullingInfo() + " Entity: " + entityFrustumHolder.getCullingInfo()); + messages.add("[" + Iris.MODNAME + "] Shadow Projection: " + getProjectionInfo()); messages.add("[" + Iris.MODNAME + "] Shadow Terrain: " + debugStringTerrain + (shouldRenderTerrain ? "" : " (no terrain) ") + (shouldRenderTranslucent ? "" : "(no translucent)")); messages.add("[" + Iris.MODNAME + "] Shadow Entities: " + getEntitiesDebugString()); @@ -718,6 +719,10 @@ public void addDebugText(List messages) { } } + private String getProjectionInfo() { + return "Near: " + nearPlane + " Far: " + farPlane + " distance " + halfPlaneLength; + } + private String getEntitiesDebugString() { return (shouldRenderEntities || shouldRenderPlayer) ? (renderedShadowEntities + "/" + Minecraft.getInstance().level.getEntityCount()) : "disabled by pack"; } diff --git a/common/src/main/java/net/irisshaders/iris/uniforms/MatrixUniforms.java b/common/src/main/java/net/irisshaders/iris/uniforms/MatrixUniforms.java index 1b7cea1f8b..8f33aae815 100644 --- a/common/src/main/java/net/irisshaders/iris/uniforms/MatrixUniforms.java +++ b/common/src/main/java/net/irisshaders/iris/uniforms/MatrixUniforms.java @@ -21,10 +21,10 @@ public static void addMatrixUniforms(UniformHolder uniforms, PackDirectives dire addMatrix(uniforms, "Projection", CapturedRenderingState.INSTANCE::getGbufferProjection); addDHMatrix(uniforms, "Projection", DHCompat::getProjection); addShadowMatrix(uniforms, "ModelView", () -> - new Matrix4f(ShadowRenderer.createShadowModelView(directives.getSunPathRotation(), directives.getShadowDirectives().getIntervalSize()).last().pose())); + new Matrix4f(ShadowRenderer.createShadowModelView(directives.getSunPathRotation(), directives.getShadowDirectives().getIntervalSize(), directives.getShadowDirectives().getNearPlane(), directives.getShadowDirectives().getFarPlane()).last().pose())); addShadowMatrix(uniforms, "Projection", () -> ShadowMatrices.createOrthoMatrix(directives.getShadowDirectives().getDistance(), - directives.getShadowDirectives().getNearPlane() < 0 ? -DHCompat.getRenderDistance() : directives.getShadowDirectives().getNearPlane(), - directives.getShadowDirectives().getFarPlane() < 0 ? DHCompat.getRenderDistance() : directives.getShadowDirectives().getFarPlane())); + directives.getShadowDirectives().getNearPlane() < 0 ? -DHCompat.getRenderDistance() * 16 : directives.getShadowDirectives().getNearPlane(), + directives.getShadowDirectives().getFarPlane() < 0 ? DHCompat.getRenderDistance() * 16 : directives.getShadowDirectives().getFarPlane())); } private static void addMatrix(UniformHolder uniforms, String name, Supplier supplier) {