diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/util/RenderTargetTracker.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/util/RenderTargetTracker.java new file mode 100644 index 0000000000..e521212e9a --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/util/RenderTargetTracker.java @@ -0,0 +1,35 @@ +package net.caffeinemc.mods.sodium.client.render.util; + +import com.mojang.blaze3d.pipeline.RenderTarget; +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import it.unimi.dsi.fastutil.objects.ReferenceSet; + +public class RenderTargetTracker { + private static final ReferenceSet DIRTY_FRAMEBUFFERS = new ReferenceOpenHashSet<>(); + + private static RenderTarget ACTIVE_WRITE_TARGET; + + public static void setActiveWriteTarget(RenderTarget rt) { + ACTIVE_WRITE_TARGET = rt; + } + + public static void notifyActiveWriteTargetModified() { + RenderTarget rt = ACTIVE_WRITE_TARGET; + + if (rt != null) { + markDirty(rt); + } + } + + public static void markDirty(RenderTarget rt) { + DIRTY_FRAMEBUFFERS.add(rt); + } + + public static boolean isDirty(RenderTarget rt) { + return DIRTY_FRAMEBUFFERS.contains(rt); + } + + public static void markClean(RenderTarget rt) { + DIRTY_FRAMEBUFFERS.remove(rt); + } +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/LevelRendererMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/LevelRendererMixin.java new file mode 100644 index 0000000000..2988e9c62a --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/LevelRendererMixin.java @@ -0,0 +1,30 @@ +package net.caffeinemc.mods.sodium.mixin.features.render.compositing; + +import com.mojang.blaze3d.pipeline.RenderTarget; +import net.caffeinemc.mods.sodium.client.render.util.RenderTargetTracker; +import net.minecraft.client.renderer.LevelRenderer; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LevelRenderer.class) +public class LevelRendererMixin { + @Shadow + @Nullable + private RenderTarget entityTarget; + + @Inject(method = "doEntityOutline", at = @At("HEAD"), cancellable = true) + private void preEntityOutlineComposite(CallbackInfo ci) { + RenderTarget entityTarget = this.entityTarget; + + // If the entity render target hasn't been modified, don't try to composite it into the final image + if (entityTarget != null && !RenderTargetTracker.isDirty(entityTarget)) { + ci.cancel(); + } + + RenderTargetTracker.markClean(entityTarget); + } +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/RenderTargetMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/RenderTargetMixin.java index c63e4a0c87..dd90a0b237 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/RenderTargetMixin.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/RenderTargetMixin.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.pipeline.RenderTarget; +import net.caffeinemc.mods.sodium.client.render.util.RenderTargetTracker; import org.lwjgl.opengl.GL32C; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -20,6 +21,11 @@ public class RenderTargetMixin { @Shadow public int height; + @Inject(method = "bindWrite", at = @At("HEAD")) + public void onBindWrite(boolean setViewport, CallbackInfo ci) { + RenderTargetTracker.setActiveWriteTarget((RenderTarget) (Object) this); + } + /** * @author JellySquid * @reason Use fixed function hardware for framebuffer blits diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/VertexBufferMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/VertexBufferMixin.java new file mode 100644 index 0000000000..81b2ad91b4 --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/compositing/VertexBufferMixin.java @@ -0,0 +1,17 @@ +package net.caffeinemc.mods.sodium.mixin.features.render.compositing; + +import com.mojang.blaze3d.vertex.VertexBuffer; +import net.caffeinemc.mods.sodium.client.render.util.RenderTargetTracker; +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; + +@Mixin(VertexBuffer.class) +public class VertexBufferMixin { + @Inject(method = "draw", at = @At("RETURN")) + private void postDraw(CallbackInfo ci) { + // When any geometry is drawn, mark the framebuffer that it was rasterized to + RenderTargetTracker.notifyActiveWriteTargetModified(); + } +} diff --git a/common/src/main/resources/sodium.mixins.json b/common/src/main/resources/sodium.mixins.json index e110e980ee..38183853e3 100644 --- a/common/src/main/resources/sodium.mixins.json +++ b/common/src/main/resources/sodium.mixins.json @@ -41,7 +41,9 @@ "features.options.render_layers.LeavesBlockMixin", "features.options.render_layers.ItemBlockRenderTypesMixin", "features.options.weather.LevelRendererMixin", + "features.render.compositing.LevelRendererMixin", "features.render.compositing.RenderTargetMixin", + "features.render.compositing.VertexBufferMixin", "features.render.entity.CubeMixin", "features.render.entity.ModelPartMixin", "features.render.entity.cull.EntityRendererMixin",