diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRendererMixin.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRendererMixin.java index 8ec2ec6..274910e 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRendererMixin.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRendererMixin.java @@ -2,20 +2,27 @@ package io.github.slimeistdev.crystalline_sky.mixin.client; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.pipeline.TextureTarget; +import com.mojang.blaze3d.vertex.PoseStack; +import io.github.slimeistdev.crystalline_sky.compat.Mods; +import io.github.slimeistdev.crystalline_sky.mixin.client.compat.iris.IrisRenderingPipelineAccessor; +import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.IrisRenderingPipeline_Duck; import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.LevelRenderer_Duck; import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderTarget_Duck; import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes; -import net.minecraft.client.Minecraft; -import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.pipeline.TextureTarget; -import net.minecraft.client.CloudStatus; +import io.github.slimeistdev.crystalline_sky.util.SharedRenderVariables; +import net.irisshaders.iris.Iris; +import net.irisshaders.iris.pipeline.IrisRenderingPipeline; +import net.irisshaders.iris.targets.RenderTargets; import net.minecraft.client.Camera; +import net.minecraft.client.CloudStatus; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.renderer.LevelRenderer; -import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; @@ -101,7 +108,23 @@ public abstract class LevelRendererMixin implements LevelRenderer_Duck { Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci) { var skyBuffer = crystalline_sky$getSkyFramebuffer(); skyBuffer.clear(Minecraft.ON_OSX); - ((RenderTarget_Duck) skyBuffer).crystalline_sky$copyColorFrom(minecraft.getMainRenderTarget()); + var copiedFromIris = Mods.IRIS.runIfInstalled(() -> () -> { + var pipeline = Iris.getPipelineManager().getPipelineNullable(); + if (!(pipeline instanceof IrisRenderingPipeline irisPipeline)) return false; + + IrisRenderingPipelineAccessor pipelineAccessor = ((IrisRenderingPipelineAccessor) irisPipeline); + RenderTargets targets = pipelineAccessor.crystalline_sky$getRenderTargets(); + var defaultTarget = targets.get(pipelineAccessor.crystalline_sky$getPackDirectives().getFallbackTex()); + ((RenderTarget_Duck) skyBuffer).crystalline_sky$copyColorFrom( + ((IrisRenderingPipeline_Duck) irisPipeline)::crystalline_sky$bindDefaultForRead, + irisPipeline::bindDefault, + defaultTarget.getWidth(), defaultTarget.getHeight() + ); + + return true; + }); + if (!copiedFromIris.orElse(false)) + ((RenderTarget_Duck) skyBuffer).crystalline_sky$copyColorFrom(minecraft.getMainRenderTarget()); // render clouds CloudStatus cloudRenderMode = this.minecraft.options.getCloudsType(); @@ -115,7 +138,9 @@ public abstract class LevelRendererMixin implements LevelRenderer_Duck { var cloudsFramebuffer0 = this.cloudsTarget; this.cloudsTarget = skyBuffer; cloudsTarget.bindWrite(false); + SharedRenderVariables.pushBlockIrisShaderFramebufferBind(); this.renderClouds(new PoseStack(), matrix4f, matrix4f2, f, cx, cy, cz); + SharedRenderVariables.popBlockIrisShaderFramebufferBind(); minecraft.getMainRenderTarget().bindWrite(false); this.cloudsTarget = cloudsFramebuffer0; } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/RenderTargetMixin.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/RenderTargetMixin.java index 70d93b1..72a46bd 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/RenderTargetMixin.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/RenderTargetMixin.java @@ -30,14 +30,28 @@ public class RenderTargetMixin implements RenderTarget_Duck { } else if (framebuffer.getColorTextureId() == -1) { throw new IllegalStateException("Trying to copy color texture from a RenderTarget without a color texture"); } else { - GlStateManager._glBindFramebuffer(GlConst.GL_READ_FRAMEBUFFER, framebuffer.frameBufferId); + crystalline_sky$copyColorFrom( + () -> GlStateManager._glBindFramebuffer(GlConst.GL_READ_FRAMEBUFFER, framebuffer.frameBufferId), + () -> GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, framebuffer.frameBufferId), + framebuffer.width, framebuffer.height + ); + } + } + + @Override + public void crystalline_sky$copyColorFrom(Runnable bindRead, Runnable bind, int width, int height) { + RenderSystem.assertOnRenderThreadOrInit(); + if (this.colorTextureId == -1) { + throw new IllegalStateException("Trying to copy color texture to a RenderTarget without a color texture"); + } else { + bindRead.run(); GlStateManager._glBindFramebuffer(GlConst.GL_DRAW_FRAMEBUFFER, this.frameBufferId); GlStateManager._glBlitFrameBuffer( - 0, 0, framebuffer.width, framebuffer.height, + 0, 0, width, height, 0, 0, this.width, this.height, GlConst.GL_COLOR_BUFFER_BIT, GlConst.GL_NEAREST ); - GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, framebuffer.frameBufferId); + bind.run(); } } } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/ExtendedShaderMixin.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/ExtendedShaderMixin.java new file mode 100644 index 0000000..0d69c57 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/ExtendedShaderMixin.java @@ -0,0 +1,20 @@ +package io.github.slimeistdev.crystalline_sky.mixin.client.compat.iris; + +import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin; +import io.github.slimeistdev.crystalline_sky.compat.Mods; +import io.github.slimeistdev.crystalline_sky.util.SharedRenderVariables; +import net.irisshaders.iris.pipeline.programs.ExtendedShader; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@ConditionalMixin(mods = Mods.IRIS) +@Mixin(ExtendedShader.class) +public class ExtendedShaderMixin { + @Inject(method = "bindFramebuffer", at = @At("HEAD"), cancellable = true) + private void skipBind(CallbackInfo ci) { + if (SharedRenderVariables.shouldBlockIrisShaderFramebufferBind()) + ci.cancel(); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/IrisRenderingPipelineAccessor.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/IrisRenderingPipelineAccessor.java new file mode 100644 index 0000000..2c6fb1b --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/IrisRenderingPipelineAccessor.java @@ -0,0 +1,19 @@ +package io.github.slimeistdev.crystalline_sky.mixin.client.compat.iris; + +import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin; +import io.github.slimeistdev.crystalline_sky.compat.Mods; +import net.irisshaders.iris.pipeline.IrisRenderingPipeline; +import net.irisshaders.iris.shaderpack.properties.PackDirectives; +import net.irisshaders.iris.targets.RenderTargets; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@ConditionalMixin(mods = Mods.IRIS) +@Mixin(IrisRenderingPipeline.class) +public interface IrisRenderingPipelineAccessor { + @Accessor("packDirectives") + PackDirectives crystalline_sky$getPackDirectives(); + + @Accessor("renderTargets") + RenderTargets crystalline_sky$getRenderTargets(); +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/IrisRenderingPipelineMixin.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/IrisRenderingPipelineMixin.java new file mode 100644 index 0000000..383ae02 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/IrisRenderingPipelineMixin.java @@ -0,0 +1,31 @@ +package io.github.slimeistdev.crystalline_sky.mixin.client.compat.iris; + +import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin; +import io.github.slimeistdev.crystalline_sky.compat.Mods; +import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.IrisRenderingPipeline_Duck; +import net.irisshaders.iris.gl.framebuffer.GlFramebuffer; +import net.irisshaders.iris.pipeline.IrisRenderingPipeline; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@ConditionalMixin(mods = Mods.IRIS) +@Mixin(IrisRenderingPipeline.class) +public class IrisRenderingPipelineMixin implements IrisRenderingPipeline_Duck { + @Shadow + public boolean isBeforeTranslucent; + + @Shadow + private GlFramebuffer defaultFB; + + @Shadow + private GlFramebuffer defaultFBAlt; + + @Override + public void crystalline_sky$bindDefaultForRead() { + if (this.isBeforeTranslucent) { + this.defaultFB.bindAsReadBuffer(); + } else { + this.defaultFBAlt.bindAsReadBuffer(); + } + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/XHFPTerrainVertexMixin.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/XHFPTerrainVertexMixin.java new file mode 100644 index 0000000..23f6810 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/iris/XHFPTerrainVertexMixin.java @@ -0,0 +1,23 @@ +package io.github.slimeistdev.crystalline_sky.mixin.client.compat.iris; + +import com.llamalad7.mixinextras.expression.Definition; +import com.llamalad7.mixinextras.expression.Expression; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin; +import io.github.slimeistdev.crystalline_sky.compat.Mods; +import net.irisshaders.iris.vertices.sodium.terrain.XHFPTerrainVertex; +import net.minecraft.util.Mth; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@ConditionalMixin(mods = Mods.IRIS) +@Mixin(XHFPTerrainVertex.class) +public class XHFPTerrainVertexMixin { + @Definition(id = "quantized", local = @Local(type = int.class, name = "quantized")) + @Expression("quantized = @(?)") + @ModifyExpressionValue(method = "encodeTexture", at = @At("MIXINEXTRAS:EXPRESSION")) + private static int clamp(int original) { + return Mth.clamp(original, 0, 32767); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin_ducks/client/IrisRenderingPipeline_Duck.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin_ducks/client/IrisRenderingPipeline_Duck.java new file mode 100644 index 0000000..ec22652 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin_ducks/client/IrisRenderingPipeline_Duck.java @@ -0,0 +1,5 @@ +package io.github.slimeistdev.crystalline_sky.mixin_ducks.client; + +public interface IrisRenderingPipeline_Duck { + void crystalline_sky$bindDefaultForRead(); +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin_ducks/client/RenderTarget_Duck.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin_ducks/client/RenderTarget_Duck.java index 63d6ca6..175b68d 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin_ducks/client/RenderTarget_Duck.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin_ducks/client/RenderTarget_Duck.java @@ -4,4 +4,5 @@ import com.mojang.blaze3d.pipeline.RenderTarget; public interface RenderTarget_Duck { void crystalline_sky$copyColorFrom(RenderTarget framebuffer); + void crystalline_sky$copyColorFrom(Runnable bindRead, Runnable bind, int width, int height); } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/util/SharedRenderVariables.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/util/SharedRenderVariables.java index 853198d..995eb3b 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/util/SharedRenderVariables.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/util/SharedRenderVariables.java @@ -7,6 +7,7 @@ public class SharedRenderVariables { public static final Matrix4f invSkyboxMat = new Matrix4f(); // because chunk meshing is multithreaded :( public static final ThreadLocal shadeFullBright = ThreadLocal.withInitial(() -> new MutableInt(0)); + private static int blockIrisShaderFramebufferBind = 0; public static boolean shouldShadeFullBright() { return shadeFullBright.get().intValue() > 0; @@ -19,4 +20,16 @@ public class SharedRenderVariables { public static void popShadeFullBright() { shadeFullBright.get().decrement(); } + + public static boolean shouldBlockIrisShaderFramebufferBind() { + return blockIrisShaderFramebufferBind > 0; + } + + public static void pushBlockIrisShaderFramebufferBind() { + blockIrisShaderFramebufferBind++; + } + + public static void popBlockIrisShaderFramebufferBind() { + blockIrisShaderFramebufferBind--; + } } diff --git a/common/src/main/resources/crystalline_sky-common.mixins.json b/common/src/main/resources/crystalline_sky-common.mixins.json index 9c04a2d..d2bdd40 100644 --- a/common/src/main/resources/crystalline_sky-common.mixins.json +++ b/common/src/main/resources/crystalline_sky-common.mixins.json @@ -26,8 +26,12 @@ "client.ModelBlockRendererMixin", "client.RenderTargetMixin", "client.SimpleBakedModelMixin", + "client.compat.iris.ExtendedShaderMixin", + "client.compat.iris.IrisRenderingPipelineAccessor", + "client.compat.iris.IrisRenderingPipelineMixin", "client.compat.iris.SodiumProgramsMixin", "client.compat.iris.WorldRenderingPhaseMixin", + "client.compat.iris.XHFPTerrainVertexMixin", "client.compat.sodium.CompactChunkVertexMixin", "client.compat.sodium.DefaultMaterialsMixin", "client.compat.sodium.DefaultTerrainRenderPassesMixin",