diff --git a/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSourceChild.java b/src/main/java/net/coderbot/iris/mixin/MixinBufferSource_WrapperChecking.java similarity index 96% rename from src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSourceChild.java rename to src/main/java/net/coderbot/iris/mixin/MixinBufferSource_WrapperChecking.java index 42f46e2808..c4a0130d31 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSourceChild.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinBufferSource_WrapperChecking.java @@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(MultiBufferSource.BufferSource.class) -public class MixinMultiBufferSourceChild { +public class MixinBufferSource_WrapperChecking { @Unique private final Set unwrapped = new ObjectOpenHashSet<>(); diff --git a/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSource.java b/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSource.java deleted file mode 100644 index 52ec0d34a9..0000000000 --- a/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSource.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.coderbot.iris.mixin; - -import java.util.Set; -import java.util.function.Function; - -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import net.coderbot.iris.Iris; -import net.coderbot.iris.fantastic.WrappingMultiBufferSource; -import net.coderbot.iris.layer.InnerWrappedRenderType; -import net.coderbot.iris.layer.IrisRenderTypeWrapper; -import net.coderbot.iris.mixin.rendertype.RenderStateShardAccessor; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(MultiBufferSource.BufferSource.class) -public class MixinMultiBufferSource implements WrappingMultiBufferSource { - @Unique - private final Set unwrapped = new ObjectOpenHashSet<>(); - - @Inject(method = "endBatch(Lnet/minecraft/client/renderer/RenderType;)V", at = @At("HEAD")) - private void iris$beginDraw(RenderType type, CallbackInfo callback) { - if (!(type instanceof IrisRenderTypeWrapper) && !(type instanceof InnerWrappedRenderType)) { - String name = ((RenderStateShardAccessor) type).getName(); - - if (unwrapped.contains(name)) { - return; - } - - unwrapped.add(name); - - Iris.logger.warn("Iris has detected a non-wrapped render type, it will not be rendered with the correct shader program: " + name); - } - } - - @Unique - private Function wrappingFunction; - - @ModifyVariable(method = "getBuffer", - at = @At("HEAD"), ordinal = 0) - private RenderType iris$applyWrappingFunction(RenderType type) { - if (wrappingFunction == null) { - return type; - } - - return wrappingFunction.apply(type); - } - - @Override - public void pushWrappingFunction(Function wrappingFunction) { - this.wrappingFunction = wrappingFunction; - } - - @Override - public void popWrappingFunction() { - this.wrappingFunction = null; - } - - @Override - public void assertWrapStackEmpty() { - - } -} diff --git a/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSource_WrapperManager.java b/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSource_WrapperManager.java deleted file mode 100644 index 2f4e85bdf9..0000000000 --- a/src/main/java/net/coderbot/iris/mixin/MixinMultiBufferSource_WrapperManager.java +++ /dev/null @@ -1,157 +0,0 @@ -package net.coderbot.iris.mixin; - -import net.coderbot.iris.layer.*; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.VertexConsumer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * Vanilla depends on being able to write to some buffers at the same time as other ones. - * This includes enchantment glints. - * - * We need to make sure that wrapped variants of buffered render layers are buffered too, - * or else we'll get crashes with this approach. - * - * This mixin dynamically creates buffers for the wrapped variants of buffered layers. - * This strategy is needed for mods that dynamically add buffered layers, like Charm - * which adds colored enchantment glints. - */ -@Mixin(MultiBufferSource.BufferSource.class) -public class MixinMultiBufferSource_WrapperManager { - @Shadow - @Final - protected Map fixedBuffers; - - @Shadow - public void endBatch(RenderType type) { - throw new AssertionError(); - } - - // A set of wrapped layers - layers that have corresponding wrappers - @Unique - private final Set wrapped = new HashSet<>(); - - // A set of wrapper layers - layers that wrap an existing layer to provide additional information - @Unique - private final Set wrappers = new HashSet<>(); - - // Maps a wrapped layer to its list of wrapper layers - @Unique - private final Map> wrappedToWrapper = new HashMap<>(); - - @Inject(method = "getBuffer", - at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;fixedBuffers:Ljava/util/Map;")) - private void iris$fillInWrappers(RenderType type, CallbackInfoReturnable cir) { - ensureBuffersPresent(type); - } - - @Inject(method = "getBuilderRaw", at = @At("HEAD")) - private void iris$onGetBuffer(RenderType type, CallbackInfoReturnable cir) { - ensureBuffersPresent(type); - } - - // Ensure that when Minecraft explicitly flushes a buffer, its corresponding wrapped buffers are flushed too. - // This might avoid rendering issues. - @Inject(method = "endBatch(Lnet/minecraft/client/renderer/RenderType;)V", at = @At("RETURN")) - private void iris$onExplicitDraw(RenderType type, CallbackInfo callback) { - ensureBuffersPresent(type); - - List correspondingWrappers = wrappedToWrapper.get(type); - - if (correspondingWrappers == null) { - return; - } - - for (RenderType wrapper : correspondingWrappers) { - endBatch(Objects.requireNonNull(wrapper)); - } - } - - @Inject(method = "endBatch()V", at = @At(value = "FIELD", - target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;fixedBuffers:Ljava/util/Map;")) - private void iris$onFullFlush(CallbackInfo callback) { - // Ensure that all corresponding buffers are filled in now. - // This avoids us mutating layerBuffers while iterating through it. - Set bufferedTypes = new HashSet<>(fixedBuffers.keySet()); - - for (RenderType buffered : bufferedTypes) { - ensureBuffersPresent(buffered); - } - } - - @Unique - private void ensureBuffersPresent(RenderType type) { - if (fixedBuffers.containsKey(type) && !wrappers.contains(type)) { - // If this is a buffered type that isn't a wrapper itself, add the corresponding wrapped buffers. - ensureWrapped(type); - } else if (type instanceof WrappableRenderType) { - // If this is a wrapper, try to unwrap it to find the base type. - RenderType unwrapped = ((WrappableRenderType) type).unwrap(); - - if (unwrapped != type && unwrapped != null) { - ensureBuffersPresent(unwrapped); - } - } - } - - @Unique - private void ensureWrapped(RenderType base) { - // add() returns true if wrapped didn't contain the layer already - // If this layer is already wrapped, we don't try to add wrapped buffer variants for it. - if (!wrapped.add(base)) { - return; - } - - Objects.requireNonNull(base); - - iris$addWrappedBuffer(base, iris$wrapWithIsEntity(base)); - iris$addWrappedBuffer(base, iris$wrapWithIsBlockEntity(base)); - iris$addWrappedBuffer(base, iris$wrapWithEntityColor(base, true, false)); - iris$addWrappedBuffer(base, iris$wrapWithEntityColor(base, false, true)); - iris$addWrappedBuffer(base, iris$wrapWithIsEntity(iris$wrapWithEntityColor(base, true, false))); - iris$addWrappedBuffer(base, iris$wrapWithIsEntity(iris$wrapWithEntityColor(base, false, true))); - } - - @Unique - private void iris$addWrappedBuffer(RenderType base, RenderType wrapper) { - Objects.requireNonNull(wrapper); - - // add() returns true if wrappers didn't contain the layer already - if (wrappers.add(wrapper)) { - fixedBuffers.put(wrapper, new BufferBuilder(wrapper.bufferSize())); - wrappedToWrapper.computeIfAbsent(base, layer -> new ArrayList<>()).add(wrapper); - } - } - - @Unique - private RenderType iris$wrapWithEntityColor(RenderType base, boolean hurt, boolean whiteFlash) { - EntityColorRenderStateShard phase = new EntityColorRenderStateShard(hurt, whiteFlash ? 1.0F : 0.0F); - return new InnerWrappedRenderType("iris_entity_color", base, phase); - } - - @Unique - private RenderType iris$wrapWithIsEntity(RenderType base) { - return new OuterWrappedRenderType("iris:is_entity", base, IsEntityRenderStateShard.INSTANCE); - } - - @Unique - private RenderType iris$wrapWithIsBlockEntity(RenderType base) { - return new OuterWrappedRenderType("iris:is_block_entity", base, IsBlockEntityRenderStateShard.INSTANCE); - } -} diff --git a/src/main/resources/mixins.iris.json b/src/main/resources/mixins.iris.json index eb57d97f43..fe36b17d12 100644 --- a/src/main/resources/mixins.iris.json +++ b/src/main/resources/mixins.iris.json @@ -17,7 +17,7 @@ "MixinLevelRenderer", "MixinLivingEntityRenderer", "MixinModelViewBobbing", - "MixinMultiBufferSourceChild", + "MixinBufferSource_WrapperChecking", "MixinParticleEngine", "MixinTextureAtlas", "MixinTheEndPortalRenderer",