From 27d46449f960701fd6ce9a2c03b730ea40008b4c Mon Sep 17 00:00:00 2001 From: IMS212 Date: Tue, 12 Dec 2023 16:38:15 -0800 Subject: [PATCH 01/17] The final boss: Tessellation Shaders --- .../coderbot/iris/gl/shader/ShaderType.java | 4 +- .../iris/mixin/MixinGameRenderer.java | 2 + ...ixinGlStateManager_DepthColorOverride.java | 17 +++++ .../iris/mixin/MixinProgramManager.java | 6 ++ .../coderbot/iris/mixin/MixinProgramType.java | 9 ++- .../iris/mixin/MixinShaderInstance.java | 11 +-- .../DeferredWorldRenderingPipeline.java | 14 +--- .../iris/pipeline/SodiumTerrainPipeline.java | 66 +++++++++++++++++ .../pipeline/newshader/ExtendedShader.java | 47 +++++++++++- .../pipeline/newshader/IrisProgramTypes.java | 2 + .../pipeline/newshader/NewShaderTests.java | 26 ++++++- .../newshader/ShaderInstanceInterface.java | 2 +- .../pipeline/transform/PatchShaderType.java | 6 ++ .../pipeline/transform/TransformPatcher.java | 46 +++++++----- .../coderbot/iris/shaderpack/ProgramSet.java | 8 +- .../iris/shaderpack/ProgramSource.java | 20 ++++- .../include/ShaderPackSourceNames.java | 2 + .../iris/vertices/ImmediateState.java | 3 +- .../IrisChunkProgramOverrides.java | 74 ++++++++++++++++++- .../IrisChunkShaderInterface.java | 9 ++- .../shader_overrides/IrisShaderTypes.java | 2 + .../shader_overrides/MixinChunkProgram.java | 0 .../MixinChunkRenderShaderBackend.java | 0 .../shader_overrides/MixinGlRenderDevice.java | 18 +++++ .../shader_overrides/MixinShaderType.java | 7 +- .../resources/mixins.iris.compat.sodium.json | 1 + 26 files changed, 345 insertions(+), 57 deletions(-) delete mode 100644 src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkProgram.java delete mode 100644 src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkRenderShaderBackend.java create mode 100644 src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlRenderDevice.java diff --git a/src/main/java/net/coderbot/iris/gl/shader/ShaderType.java b/src/main/java/net/coderbot/iris/gl/shader/ShaderType.java index 8368c41b22..0bcc1c52f7 100644 --- a/src/main/java/net/coderbot/iris/gl/shader/ShaderType.java +++ b/src/main/java/net/coderbot/iris/gl/shader/ShaderType.java @@ -13,7 +13,9 @@ public enum ShaderType { VERTEX(GL20.GL_VERTEX_SHADER), GEOMETRY(GL32C.GL_GEOMETRY_SHADER), FRAGMENT(GL20.GL_FRAGMENT_SHADER), - COMPUTE(GL43C.GL_COMPUTE_SHADER); + COMPUTE(GL43C.GL_COMPUTE_SHADER), + TESSELATION_CONTROL(GL43C.GL_TESS_CONTROL_SHADER), + TESSELATION_EVAL(GL43C.GL_TESS_EVALUATION_SHADER); public final int id; diff --git a/src/main/java/net/coderbot/iris/mixin/MixinGameRenderer.java b/src/main/java/net/coderbot/iris/mixin/MixinGameRenderer.java index cea7e40e54..511b4ed747 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinGameRenderer.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinGameRenderer.java @@ -66,6 +66,8 @@ public class MixinGameRenderer { private ArrayList iris$reloadGeometryShaders() { ArrayList programs = Lists.newArrayList(); programs.addAll(IrisProgramTypes.GEOMETRY.getPrograms().values()); + programs.addAll(IrisProgramTypes.TESS_CONTROL.getPrograms().values()); + programs.addAll(IrisProgramTypes.TESS_EVAL.getPrograms().values()); return programs; } diff --git a/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java b/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java index 1581e44318..6834b94547 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java @@ -2,9 +2,12 @@ import com.mojang.blaze3d.platform.GlStateManager; import net.coderbot.iris.gl.blending.DepthColorStorage; +import net.coderbot.iris.vertices.ImmediateState; +import org.lwjgl.opengl.GL43C; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(GlStateManager.class) @@ -24,4 +27,18 @@ public class MixinGlStateManager_DepthColorOverride { ci.cancel(); } } + + @Redirect(method = "_drawElements", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glDrawElements(IIIJ)V")) + private static void iris$modify(int mode, int count, int type, long indices) { + if (mode == GL43C.GL_TRIANGLES && ImmediateState.usingTessellation) { + mode = GL43C.GL_PATCHES; + } + + GL43C.glDrawElements(mode, count, type, indices); + } + + @Inject(method = "_glUseProgram", at = @At("TAIL")) + private static void iris$resetTessellation(int pInt0, CallbackInfo ci) { + ImmediateState.usingTessellation = false; + } } diff --git a/src/main/java/net/coderbot/iris/mixin/MixinProgramManager.java b/src/main/java/net/coderbot/iris/mixin/MixinProgramManager.java index 6768728d96..a41ba8d0a9 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinProgramManager.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinProgramManager.java @@ -15,5 +15,11 @@ public class MixinProgramManager { if (shader instanceof ExtendedShader && ((ExtendedShader) shader).getGeometry() != null) { ((ExtendedShader) shader).getGeometry().close(); } + if (shader instanceof ExtendedShader && ((ExtendedShader) shader).getTessControl() != null) { + ((ExtendedShader) shader).getTessControl().close(); + } + if (shader instanceof ExtendedShader && ((ExtendedShader) shader).getTessEval() != null) { + ((ExtendedShader) shader).getTessEval().close(); + } } } diff --git a/src/main/java/net/coderbot/iris/mixin/MixinProgramType.java b/src/main/java/net/coderbot/iris/mixin/MixinProgramType.java index 5e0bdc5744..44316a1ff2 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinProgramType.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinProgramType.java @@ -4,6 +4,7 @@ import net.coderbot.iris.pipeline.newshader.IrisProgramTypes; import org.apache.commons.lang3.ArrayUtils; import org.lwjgl.opengl.GL32C; +import org.lwjgl.opengl.GL42C; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -23,6 +24,12 @@ public class MixinProgramType { IrisProgramTypes.GEOMETRY = ProgramTypeAccessor.createProgramType("GEOMETRY", baseOrdinal, "geometry", ".gsh", GL32C.GL_GEOMETRY_SHADER); - $VALUES = ArrayUtils.addAll($VALUES, IrisProgramTypes.GEOMETRY); + IrisProgramTypes.TESS_CONTROL + = ProgramTypeAccessor.createProgramType("TESS_CONTROL", baseOrdinal + 1, "tess_control", ".tcs", GL42C.GL_TESS_CONTROL_SHADER); + + IrisProgramTypes.TESS_EVAL + = ProgramTypeAccessor.createProgramType("TESS_EVAL", baseOrdinal + 2, "tess_eval", ".tes", GL42C.GL_TESS_EVALUATION_SHADER); + + $VALUES = ArrayUtils.addAll($VALUES, IrisProgramTypes.GEOMETRY, IrisProgramTypes.TESS_CONTROL, IrisProgramTypes.TESS_EVAL); } } diff --git a/src/main/java/net/coderbot/iris/mixin/MixinShaderInstance.java b/src/main/java/net/coderbot/iris/mixin/MixinShaderInstance.java index 37d0b46f6c..3baa14ba62 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinShaderInstance.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinShaderInstance.java @@ -4,7 +4,6 @@ import com.mojang.blaze3d.shaders.Uniform; import com.mojang.blaze3d.vertex.VertexFormat; import net.coderbot.iris.Iris; -import net.coderbot.iris.gl.IrisRenderSystem; import net.coderbot.iris.gl.blending.DepthColorStorage; import net.coderbot.iris.pipeline.WorldRenderingPipeline; import net.coderbot.iris.pipeline.newshader.CoreWorldRenderingPipeline; @@ -13,9 +12,6 @@ import net.coderbot.iris.pipeline.newshader.fallback.FallbackShader; import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.server.packs.resources.ResourceProvider; -import org.lwjgl.opengl.ARBTextureSwizzle; -import org.lwjgl.opengl.GL20C; -import org.lwjgl.opengl.GL30C; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -24,9 +20,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.Objects; @Mixin(ShaderInstance.class) public abstract class MixinShaderInstance implements ShaderInstanceInterface { @@ -85,11 +78,11 @@ private static boolean shouldOverrideShaders() { @Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/GsonHelper;parse(Ljava/io/Reader;)Lcom/google/gson/JsonObject;")) public void iris$setupGeometryShader(ResourceProvider resourceProvider, String string, VertexFormat vertexFormat, CallbackInfo ci) { - this.iris$createGeometryShader(resourceProvider, string); + this.iris$createExtraShaders(resourceProvider, string); } @Override - public void iris$createGeometryShader(ResourceProvider provider, String name) { + public void iris$createExtraShaders(ResourceProvider provider, String name) { //no-op, used for ExtendedShader to call before the super constructor } } diff --git a/src/main/java/net/coderbot/iris/pipeline/DeferredWorldRenderingPipeline.java b/src/main/java/net/coderbot/iris/pipeline/DeferredWorldRenderingPipeline.java index 858528c985..580f6b5e34 100644 --- a/src/main/java/net/coderbot/iris/pipeline/DeferredWorldRenderingPipeline.java +++ b/src/main/java/net/coderbot/iris/pipeline/DeferredWorldRenderingPipeline.java @@ -684,21 +684,9 @@ private Pass createDefaultPass() { private Pass createPass(ProgramSource source, InputAvailability availability, boolean shadow, ProgramId id) { // TODO: Properly handle empty shaders? - Map transformed = TransformPatcher.patchAttributes( - source.getVertexSource().orElseThrow(NullPointerException::new), - source.getGeometrySource().orElse(null), - source.getFragmentSource().orElseThrow(NullPointerException::new), - availability, customTextureMap); - String vertex = transformed.get(PatchShaderType.VERTEX); - String geometry = transformed.get(PatchShaderType.GEOMETRY); - String fragment = transformed.get(PatchShaderType.FRAGMENT); - ShaderPrinter.printProgram(source.getName()).addSources(transformed).print(); - ProgramBuilder builder = ProgramBuilder.begin(source.getName(), vertex, geometry, fragment, - IrisSamplers.WORLD_RESERVED_TEXTURE_UNITS); - - return createPassInner(builder, source.getParent().getPack().getIdMap(), source.getDirectives(), source.getParent().getPackDirectives(), availability, shadow, id); + return createPassInner(null, source.getParent().getPack().getIdMap(), source.getDirectives(), source.getParent().getPackDirectives(), availability, shadow, id); } private Pass createPassInner(ProgramBuilder builder, IdMap map, ProgramDirectives programDirectives, diff --git a/src/main/java/net/coderbot/iris/pipeline/SodiumTerrainPipeline.java b/src/main/java/net/coderbot/iris/pipeline/SodiumTerrainPipeline.java index 8370e0b8c0..1b014fc10e 100644 --- a/src/main/java/net/coderbot/iris/pipeline/SodiumTerrainPipeline.java +++ b/src/main/java/net/coderbot/iris/pipeline/SodiumTerrainPipeline.java @@ -39,6 +39,8 @@ public class SodiumTerrainPipeline { Optional terrainSolidVertex; Optional terrainSolidGeometry; + Optional terrainSolidTessControl; + Optional terrainSolidTessEval; Optional terrainSolidFragment; GlFramebuffer terrainSolidFramebuffer; BlendModeOverride terrainSolidBlendOverride; @@ -46,6 +48,8 @@ public class SodiumTerrainPipeline { Optional terrainCutoutVertex; Optional terrainCutoutGeometry; + Optional terrainCutoutTessControl; + Optional terrainCutoutTessEval; Optional terrainCutoutFragment; GlFramebuffer terrainCutoutFramebuffer; BlendModeOverride terrainCutoutBlendOverride; @@ -54,6 +58,8 @@ public class SodiumTerrainPipeline { Optional translucentVertex; Optional translucentGeometry; + Optional translucentTessControl; + Optional translucentTessEval; Optional translucentFragment; GlFramebuffer translucentFramebuffer; BlendModeOverride translucentBlendOverride; @@ -62,6 +68,8 @@ public class SodiumTerrainPipeline { Optional shadowVertex; Optional shadowGeometry; + Optional shadowTessControl; + Optional shadowTessEval; Optional shadowFragment; Optional shadowCutoutFragment; GlFramebuffer shadowFramebuffer; @@ -147,11 +155,15 @@ public void patchShaders(ChunkVertexType vertexType) { Map transformed = TransformPatcher.patchSodium( sources.getVertexSource().orElse(null), sources.getGeometrySource().orElse(null), + sources.getTessControlSource().orElse(null), + sources.getTessEvalSource().orElse(null), sources.getFragmentSource().orElse(null), AlphaTest.ALWAYS, inputs, vertexType.getPositionScale(), vertexType.getPositionOffset(), vertexType.getTextureScale(), parent.getTextureMap()); terrainSolidVertex = Optional.ofNullable(transformed.get(PatchShaderType.VERTEX)); terrainSolidGeometry = Optional.ofNullable(transformed.get(PatchShaderType.GEOMETRY)); + terrainSolidTessControl = Optional.ofNullable(transformed.get(PatchShaderType.TESS_CONTROL)); + terrainSolidTessEval = Optional.ofNullable(transformed.get(PatchShaderType.TESS_EVAL)); terrainSolidFragment = Optional.ofNullable(transformed.get(PatchShaderType.FRAGMENT)); ShaderPrinter.printProgram(sources.getName() + "_sodium_solid").addSources(transformed).print(); @@ -160,6 +172,8 @@ public void patchShaders(ChunkVertexType vertexType) { terrainSolidBufferOverrides = Collections.emptyList(); terrainSolidVertex = Optional.empty(); terrainSolidGeometry = Optional.empty(); + terrainSolidTessControl = Optional.empty(); + terrainSolidTessEval = Optional.empty(); terrainSolidFragment = Optional.empty(); }); @@ -177,11 +191,15 @@ public void patchShaders(ChunkVertexType vertexType) { Map transformed = TransformPatcher.patchSodium( sources.getVertexSource().orElse(null), sources.getGeometrySource().orElse(null), + sources.getTessControlSource().orElse(null), + sources.getTessEvalSource().orElse(null), sources.getFragmentSource().orElse(null), terrainCutoutAlpha.orElse(AlphaTests.ONE_TENTH_ALPHA), inputs, vertexType.getPositionScale(), vertexType.getPositionOffset(), vertexType.getTextureScale(), parent.getTextureMap()); terrainCutoutVertex = Optional.ofNullable(transformed.get(PatchShaderType.VERTEX)); terrainCutoutGeometry = Optional.ofNullable(transformed.get(PatchShaderType.GEOMETRY)); + terrainCutoutTessControl = Optional.ofNullable(transformed.get(PatchShaderType.TESS_CONTROL)); + terrainCutoutTessEval = Optional.ofNullable(transformed.get(PatchShaderType.TESS_EVAL)); terrainCutoutFragment = Optional.ofNullable(transformed.get(PatchShaderType.FRAGMENT)); ShaderPrinter.printProgram(sources.getName() + "_sodium_cutout").addSources(transformed).print(); @@ -191,6 +209,8 @@ public void patchShaders(ChunkVertexType vertexType) { terrainCutoutAlpha = terrainCutoutDefault.get(); terrainCutoutVertex = Optional.empty(); terrainCutoutGeometry = Optional.empty(); + terrainCutoutTessControl = Optional.empty(); + terrainCutoutTessEval = Optional.empty(); terrainCutoutFragment = Optional.empty(); }); @@ -209,11 +229,15 @@ public void patchShaders(ChunkVertexType vertexType) { Map transformed = TransformPatcher.patchSodium( sources.getVertexSource().orElse(null), sources.getGeometrySource().orElse(null), + sources.getTessControlSource().orElse(null), + sources.getTessEvalSource().orElse(null), sources.getFragmentSource().orElse(null), translucentAlpha.orElse(AlphaTest.ALWAYS), inputs, vertexType.getPositionScale(), vertexType.getPositionOffset(), vertexType.getTextureScale(), parent.getTextureMap()); translucentVertex = Optional.ofNullable(transformed.get(PatchShaderType.VERTEX)); translucentGeometry = Optional.ofNullable(transformed.get(PatchShaderType.GEOMETRY)); + translucentTessControl = Optional.ofNullable(transformed.get(PatchShaderType.TESS_CONTROL)); + translucentTessEval = Optional.ofNullable(transformed.get(PatchShaderType.TESS_EVAL)); translucentFragment = Optional.ofNullable(transformed.get(PatchShaderType.FRAGMENT)); ShaderPrinter.printProgram(sources.getName() + "_sodium").addSources(transformed).print(); @@ -223,6 +247,8 @@ public void patchShaders(ChunkVertexType vertexType) { translucentAlpha = translucentDefault.get(); translucentVertex = Optional.empty(); translucentGeometry = Optional.empty(); + translucentTessControl = Optional.empty(); + translucentTessEval = Optional.empty(); translucentFragment = Optional.empty(); }); @@ -240,17 +266,23 @@ public void patchShaders(ChunkVertexType vertexType) { Map transformed = TransformPatcher.patchSodium( sources.getVertexSource().orElse(null), sources.getGeometrySource().orElse(null), + sources.getTessControlSource().orElse(null), + sources.getTessEvalSource().orElse(null), sources.getFragmentSource().orElse(null), AlphaTest.ALWAYS, inputs, vertexType.getPositionScale(), vertexType.getPositionOffset(), vertexType.getTextureScale(), parent.getTextureMap()); Map transformedCutout = TransformPatcher.patchSodium( sources.getVertexSource().orElse(null), sources.getGeometrySource().orElse(null), + sources.getTessControlSource().orElse(null), + sources.getTessEvalSource().orElse(null), sources.getFragmentSource().orElse(null), shadowAlpha.get(), inputs, vertexType.getPositionScale(), vertexType.getPositionOffset(), vertexType.getTextureScale(), parent.getTextureMap()); shadowVertex = Optional.ofNullable(transformed.get(PatchShaderType.VERTEX)); shadowGeometry = Optional.ofNullable(transformed.get(PatchShaderType.GEOMETRY)); + shadowTessControl = Optional.ofNullable(transformed.get(PatchShaderType.TESS_CONTROL)); + shadowTessEval = Optional.ofNullable(transformed.get(PatchShaderType.TESS_EVAL)); shadowCutoutFragment = Optional.ofNullable(transformedCutout.get(PatchShaderType.FRAGMENT)); shadowFragment = Optional.ofNullable(transformed.get(PatchShaderType.FRAGMENT)); @@ -265,6 +297,8 @@ public void patchShaders(ChunkVertexType vertexType) { shadowAlpha = shadowDefault.get(); shadowVertex = Optional.empty(); shadowGeometry = Optional.empty(); + shadowTessControl = Optional.empty(); + shadowTessEval = Optional.empty(); shadowCutoutFragment = Optional.empty(); shadowFragment = Optional.empty(); }); @@ -278,6 +312,14 @@ public Optional getTerrainSolidGeometryShaderSource() { return terrainSolidGeometry; } + public Optional getTerrainSolidTessControlShaderSource() { + return terrainSolidTessControl; + } + + public Optional getTerrainSolidTessEvalShaderSource() { + return terrainSolidTessEval; + } + public Optional getTerrainSolidFragmentShaderSource() { return terrainSolidFragment; } @@ -290,6 +332,14 @@ public Optional getTerrainCutoutGeometryShaderSource() { return terrainCutoutGeometry; } + public Optional getTerrainCutoutTessControlShaderSource() { + return terrainCutoutTessControl; + } + + public Optional getTerrainCutoutTessEvalShaderSource() { + return terrainCutoutTessEval; + } + public Optional getTerrainCutoutFragmentShaderSource() { return terrainCutoutFragment; } @@ -329,6 +379,14 @@ public Optional getTranslucentGeometryShaderSource() { return translucentGeometry; } + public Optional getTranslucentTessControlShaderSource() { + return translucentTessControl; + } + + public Optional getTranslucentTessEvalShaderSource() { + return translucentTessEval; + } + public Optional getTranslucentFragmentShaderSource() { return translucentFragment; } @@ -357,6 +415,14 @@ public Optional getShadowGeometryShaderSource() { return shadowGeometry; } + public Optional getShadowTessControlShaderSource() { + return shadowTessControl; + } + + public Optional getShadowTessEvalShaderSource() { + return shadowTessEval; + } + public Optional getShadowFragmentShaderSource() { return shadowFragment; } diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java b/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java index b60755acec..c6cb9df05b 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java @@ -31,6 +31,7 @@ import net.coderbot.iris.uniforms.custom.CustomUniforms; import net.coderbot.iris.vendored.joml.FrustumRayBuilder; import net.coderbot.iris.vendored.joml.Vector3f; +import net.coderbot.iris.vertices.ImmediateState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.resources.ResourceLocation; @@ -71,13 +72,14 @@ public class ExtendedShader extends ShaderInstance implements ShaderInstanceInte GlFramebuffer baseline; BlendModeOverride blendModeOverride; float alphaTest; - private Program geometry; + boolean usesTessellation; + private Program geometry, tessControl, tessEval; private final ShaderAttributeInputs inputs; private static ExtendedShader lastApplied; private final Vector3f chunkOffset = new Vector3f(); - public ExtendedShader(ResourceProvider resourceFactory, String string, VertexFormat vertexFormat, + public ExtendedShader(ResourceProvider resourceFactory, String string, VertexFormat vertexFormat, boolean usesTessellation, GlFramebuffer writingToBeforeTranslucent, GlFramebuffer writingToAfterTranslucent, GlFramebuffer baseline, BlendModeOverride blendModeOverride, AlphaTest alphaTest, Consumer uniformCreator, BiConsumer samplerCreator, boolean isIntensity, @@ -92,6 +94,7 @@ public ExtendedShader(ResourceProvider resourceFactory, String string, VertexFor ProgramImages.Builder builder = ProgramImages.builder(programId); samplerCreator.accept(samplerBuilder, builder); customUniforms.mapholderToPass(uniformBuilder, this); + this.usesTessellation = usesTessellation; uniforms = uniformBuilder.buildUniforms(); this.customUniforms = customUniforms; @@ -161,6 +164,8 @@ public void apply() { IrisRenderSystem.bindTextureToUnit(TextureType.TEXTURE_2D.getGlType(), IrisSamplers.OVERLAY_TEXTURE_UNIT, RenderSystem.getShaderTexture(1)); IrisRenderSystem.bindTextureToUnit(TextureType.TEXTURE_2D.getGlType(), IrisSamplers.LIGHTMAP_TEXTURE_UNIT, RenderSystem.getShaderTexture(2)); + ImmediateState.usingTessellation = usesTessellation; + if (PROJECTION_MATRIX != null) { if (projectionInverse != null) { projectionInverse.set(tempMatrix4f.set(PROJECTION_MATRIX.getFloatBuffer()).invert().get(tempFloats)); @@ -245,10 +250,16 @@ public void attachToProgram() { if (this.geometry != null) { this.geometry.attachToShader(this); } + if (this.tessControl != null) { + this.tessControl.attachToShader(this); + } + if (this.tessEval != null) { + this.tessEval.attachToShader(this); + } } @Override - public void iris$createGeometryShader(ResourceProvider factory, String name) throws IOException { + public void iris$createExtraShaders(ResourceProvider factory, String name) throws IOException { Resource geometry = factory.getResource(new ResourceLocation("minecraft", name + "_geometry.gsh")); if (geometry != null) { this.geometry = Program.compileShader(IrisProgramTypes.GEOMETRY, name, geometry.getInputStream(), geometry.getSourceName(), new GlslPreprocessor() { @@ -259,12 +270,42 @@ public String applyImport(boolean bl, String string) { } }); } + + Resource tessControl = factory.getResource(new ResourceLocation("minecraft", name + "_tessControl.tcs")); + if (tessControl != null) { + this.tessControl = Program.compileShader(IrisProgramTypes.TESS_CONTROL, name, tessControl.getInputStream(), tessControl.getSourceName(), new GlslPreprocessor() { + @Nullable + @Override + public String applyImport(boolean bl, String string) { + return null; + } + }); + } + + Resource tessEval = factory.getResource(new ResourceLocation("minecraft", name + "_tessEval.tes")); + if (tessEval != null) { + this.tessEval = Program.compileShader(IrisProgramTypes.TESS_EVAL, name, tessEval.getInputStream(), tessEval.getSourceName(), new GlslPreprocessor() { + @Nullable + @Override + public String applyImport(boolean bl, String string) { + return null; + } + }); + } } public Program getGeometry() { return this.geometry; } + public Program getTessControl() { + return this.tessControl; + } + + public Program getTessEval() { + return this.tessEval; + } + public boolean hasActiveImages() { return images.getActiveImages() > 0; } diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/IrisProgramTypes.java b/src/main/java/net/coderbot/iris/pipeline/newshader/IrisProgramTypes.java index 43ddb734dd..2ab068c930 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/IrisProgramTypes.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/IrisProgramTypes.java @@ -4,4 +4,6 @@ public class IrisProgramTypes { public static Program.Type GEOMETRY; + public static Program.Type TESS_CONTROL; + public static Program.Type TESS_EVAL; } diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java b/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java index 6c7d761bb8..30251f8b8d 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java @@ -49,10 +49,14 @@ public static ExtendedShader create(WorldRenderingPipeline pipeline, String name Map transformed = TransformPatcher.patchVanilla( source.getVertexSource().orElseThrow(RuntimeException::new), source.getGeometrySource().orElse(null), + source.getTessControlSource().orElse(null), + source.getTessEvalSource().orElse(null), source.getFragmentSource().orElseThrow(RuntimeException::new), alpha, isLines, true, inputs, pipeline.getTextureMap()); String vertex = transformed.get(PatchShaderType.VERTEX); String geometry = transformed.get(PatchShaderType.GEOMETRY); + String tessControl = transformed.get(PatchShaderType.TESS_CONTROL); + String tessEval = transformed.get(PatchShaderType.TESS_EVAL); String fragment = transformed.get(PatchShaderType.FRAGMENT); StringBuilder shaderJson = new StringBuilder("{\n" + @@ -90,7 +94,7 @@ public static ExtendedShader create(WorldRenderingPipeline pipeline, String name ShaderPrinter.printProgram(name).addSources(transformed).addJson(shaderJsonString).print(); - ResourceProvider shaderResourceFactory = new IrisProgramResourceFactory(shaderJsonString, vertex, geometry, fragment); + ResourceProvider shaderResourceFactory = new IrisProgramResourceFactory(shaderJsonString, vertex, geometry, tessControl, tessEval, fragment); List overrides = new ArrayList<>(); source.getDirectives().getBufferBlendOverrides().forEach(information -> { @@ -100,7 +104,7 @@ public static ExtendedShader create(WorldRenderingPipeline pipeline, String name } }); - return new ExtendedShader(shaderResourceFactory, name, vertexFormat, writingToBeforeTranslucent, writingToAfterTranslucent, baseline, blendModeOverride, alpha, uniforms -> { + return new ExtendedShader(shaderResourceFactory, name, vertexFormat, tessControl != null || tessEval != null, writingToBeforeTranslucent, writingToAfterTranslucent, baseline, blendModeOverride, alpha, uniforms -> { CommonUniforms.addDynamicUniforms(uniforms, FogMode.PER_VERTEX); customUniforms.assignTo(uniforms); //SamplerUniforms.addWorldSamplerUniforms(uniforms); @@ -166,7 +170,7 @@ public static FallbackShader createFallback(String name, GlFramebuffer writingTo .addJson(shaderJsonString) .print(); - ResourceProvider shaderResourceFactory = new IrisProgramResourceFactory(shaderJsonString, vertex, null, fragment); + ResourceProvider shaderResourceFactory = new IrisProgramResourceFactory(shaderJsonString, vertex, null, null, null, fragment); return new FallbackShader(shaderResourceFactory, name, vertexFormat, writingToBeforeTranslucent, writingToAfterTranslucent, blendModeOverride, alpha.getReference(), parent); @@ -176,12 +180,16 @@ private static class IrisProgramResourceFactory implements ResourceProvider { private final String json; private final String vertex; private final String geometry; + private final String tessControl; + private final String tessEval; private final String fragment; - public IrisProgramResourceFactory(String json, String vertex, String geometry, String fragment) { + public IrisProgramResourceFactory(String json, String vertex, String geometry, String tessControl, String tessEval, String fragment) { this.json = json; this.vertex = vertex; this.geometry = geometry; + this.tessControl = tessControl; + this.tessEval = tessEval; this.fragment = fragment; } @@ -198,6 +206,16 @@ public Resource getResource(ResourceLocation id) throws IOException { return null; } return new StringResource(id, geometry); + } else if (path.endsWith("tcs")) { + if (tessControl == null) { + return null; + } + return new StringResource(id, tessControl); + } else if (path.endsWith("tes")) { + if (tessEval == null) { + return null; + } + return new StringResource(id, tessEval); } else if (path.endsWith("fsh")) { return new StringResource(id, fragment); } diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/ShaderInstanceInterface.java b/src/main/java/net/coderbot/iris/pipeline/newshader/ShaderInstanceInterface.java index eda7a42905..a06505c06d 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/ShaderInstanceInterface.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/ShaderInstanceInterface.java @@ -5,5 +5,5 @@ import java.io.IOException; public interface ShaderInstanceInterface { - void iris$createGeometryShader(ResourceProvider factory, String name) throws IOException; + void iris$createExtraShaders(ResourceProvider factory, String name) throws IOException; } diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/PatchShaderType.java b/src/main/java/net/coderbot/iris/pipeline/transform/PatchShaderType.java index 7bfb08fd26..a3c8474b69 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/PatchShaderType.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/PatchShaderType.java @@ -5,6 +5,8 @@ public enum PatchShaderType { VERTEX(ShaderType.VERTEX, ".vsh"), GEOMETRY(ShaderType.GEOMETRY, ".gsh"), + TESS_CONTROL(ShaderType.TESSELATION_CONTROL, ".tcs"), + TESS_EVAL(ShaderType.TESSELATION_EVAL, ".tes"), FRAGMENT(ShaderType.FRAGMENT, ".fsh"), COMPUTE(ShaderType.COMPUTE, ".csh"); @@ -22,6 +24,10 @@ public static PatchShaderType[] fromGlShaderType(ShaderType glShaderType) { return new PatchShaderType[] { VERTEX }; case GEOMETRY: return new PatchShaderType[] { GEOMETRY }; + case TESSELATION_CONTROL: + return new PatchShaderType[] { TESS_CONTROL }; + case TESSELATION_EVAL: + return new PatchShaderType[] { TESS_EVAL }; case COMPUTE: return new PatchShaderType[] { COMPUTE }; case FRAGMENT: diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java b/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java index 7e11c69722..abe112019f 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java @@ -77,13 +77,17 @@ private static class CacheKey { final Parameters parameters; final String vertex; final String geometry; + final String tessControl; + final String tessEval; final String fragment; final String compute; - public CacheKey(Parameters parameters, String vertex, String geometry, String fragment) { + public CacheKey(Parameters parameters, String vertex, String geometry, String tessControl, String tessEval, String fragment) { this.parameters = parameters; this.vertex = vertex; this.geometry = geometry; + this.tessControl = tessControl; + this.tessEval = tessEval; this.fragment = fragment; this.compute = null; } @@ -92,6 +96,8 @@ public CacheKey(Parameters parameters, String compute) { this.parameters = parameters; this.vertex = null; this.geometry = null; + this.tessControl = null; + this.tessEval = null; this.fragment = null; this.compute = compute; } @@ -103,6 +109,8 @@ public int hashCode() { result = prime * result + ((parameters == null) ? 0 : parameters.hashCode()); result = prime * result + ((vertex == null) ? 0 : vertex.hashCode()); result = prime * result + ((geometry == null) ? 0 : geometry.hashCode()); + result = prime * result + ((tessControl == null) ? 0 : tessControl.hashCode()); + result = prime * result + ((tessEval == null) ? 0 : tessEval.hashCode()); result = prime * result + ((fragment == null) ? 0 : fragment.hashCode()); result = prime * result + ((compute == null) ? 0 : compute.hashCode()); return result; @@ -132,6 +140,16 @@ public boolean equals(Object obj) { return false; } else if (!geometry.equals(other.geometry)) return false; + if (tessControl == null) { + if (other.tessControl != null) + return false; + } else if (!tessControl.equals(other.tessControl)) + return false; + if (tessEval == null) { + if (other.tessEval != null) + return false; + } else if (!tessEval.equals(other.tessEval)) + return false; if (fragment == null) { if (other.fragment != null) return false; @@ -300,10 +318,10 @@ private static Map transformInternal( } } - private static Map transform(String vertex, String geometry, String fragment, + private static Map transform(String vertex, String geometry, String tessControl, String tessEval, String fragment, Parameters parameters) { // stop if all are null - if (vertex == null && geometry == null && fragment == null) { + if (vertex == null && geometry == null && tessControl == null && tessEval == null && fragment == null) { return null; } @@ -311,7 +329,7 @@ private static Map transform(String vertex, String geom CacheKey key; Map result = null; if (useCache) { - key = new CacheKey(parameters, vertex, geometry, fragment); + key = new CacheKey(parameters, vertex, geometry, tessControl, tessEval, fragment); if (cache.containsKey(key)) { result = cache.get(key); } @@ -323,6 +341,8 @@ private static Map transform(String vertex, String geom EnumMap inputs = new EnumMap<>(PatchShaderType.class); inputs.put(PatchShaderType.VERTEX, vertex); inputs.put(PatchShaderType.GEOMETRY, geometry); + inputs.put(PatchShaderType.TESS_CONTROL, tessControl); + inputs.put(PatchShaderType.TESS_EVAL, tessEval); inputs.put(PatchShaderType.FRAGMENT, fragment); result = transformInternal(inputs, parameters); @@ -363,29 +383,21 @@ private static Map transformCompute(String compute, Par return result; } - public static Map patchAttributes( - String vertex, String geometry, String fragment, - InputAvailability inputs, - Object2ObjectMap, String> textureMap) { - return transform(vertex, geometry, fragment, - new AttributeParameters(Patch.ATTRIBUTES, textureMap, geometry != null, inputs)); - } - public static Map patchVanilla( - String vertex, String geometry, String fragment, + String vertex, String geometry, String tessControl, String tessEval, String fragment, AlphaTest alpha, boolean isLines, boolean hasChunkOffset, ShaderAttributeInputs inputs, Object2ObjectMap, String> textureMap) { - return transform(vertex, geometry, fragment, + return transform(vertex, geometry, tessControl, tessEval, fragment, new VanillaParameters(Patch.VANILLA, textureMap, alpha, isLines, hasChunkOffset, inputs, geometry != null)); } - public static Map patchSodium(String vertex, String geometry, String fragment, + public static Map patchSodium(String vertex, String geometry, String tessControl, String tessEval, String fragment, AlphaTest alpha, ShaderAttributeInputs inputs, float positionScale, float positionOffset, float textureScale, Object2ObjectMap, String> textureMap) { - return transform(vertex, geometry, fragment, + return transform(vertex, geometry, tessControl, tessEval, fragment, new SodiumParameters(Patch.SODIUM, textureMap, alpha, inputs, positionScale, positionOffset, textureScale)); } @@ -394,7 +406,7 @@ public static Map patchComposite( String vertex, String geometry, String fragment, TextureStage stage, Object2ObjectMap, String> textureMap) { - return transform(vertex, geometry, fragment, new TextureStageParameters(Patch.COMPOSITE, stage, textureMap)); + return transform(vertex, geometry, null, null, fragment, new TextureStageParameters(Patch.COMPOSITE, stage, textureMap)); } public static String patchCompute( diff --git a/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java b/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java index 00c54305c1..e7794cfd3d 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java +++ b/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java @@ -516,6 +516,12 @@ private static ProgramSource readProgramSource(AbsolutePackPath directory, AbsolutePackPath geometryPath = directory.resolve(program + ".gsh"); String geometrySource = sourceProvider.apply(geometryPath); + AbsolutePackPath tessControlPath = directory.resolve(program + ".tcs"); + String tessControlSource = sourceProvider.apply(tessControlPath); + + AbsolutePackPath tessEvalPath = directory.resolve(program + ".tes"); + String tessEvalSource = sourceProvider.apply(tessEvalPath); + AbsolutePackPath fragmentPath = directory.resolve(program + ".fsh"); String fragmentSource = sourceProvider.apply(fragmentPath); @@ -538,7 +544,7 @@ void main() { """; } - return new ProgramSource(program, vertexSource, geometrySource, fragmentSource, programSet, properties, + return new ProgramSource(program, vertexSource, geometrySource, tessControlSource, tessEvalSource, fragmentSource, programSet, properties, defaultBlendModeOverride); } diff --git a/src/main/java/net/coderbot/iris/shaderpack/ProgramSource.java b/src/main/java/net/coderbot/iris/shaderpack/ProgramSource.java index 9ef8500a73..c519567dc8 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/ProgramSource.java +++ b/src/main/java/net/coderbot/iris/shaderpack/ProgramSource.java @@ -8,25 +8,31 @@ public class ProgramSource { private final String name; private final String vertexSource; private final String geometrySource; + private final String tessControlSource; + private final String tessEvalSource; private final String fragmentSource; private final ProgramDirectives directives; private final ProgramSet parent; - private ProgramSource(String name, String vertexSource, String geometrySource, String fragmentSource, + private ProgramSource(String name, String vertexSource, String geometrySource, String tessControlSource, String tessEvalSource, String fragmentSource, ProgramDirectives directives, ProgramSet parent) { this.name = name; this.vertexSource = vertexSource; this.geometrySource = geometrySource; + this.tessControlSource = tessControlSource; + this.tessEvalSource = tessEvalSource; this.fragmentSource = fragmentSource; this.directives = directives; this.parent = parent; } - public ProgramSource(String name, String vertexSource, String geometrySource, String fragmentSource, + public ProgramSource(String name, String vertexSource, String geometrySource, String tessControlSource, String tessEvalSource, String fragmentSource, ProgramSet parent, ShaderProperties properties, BlendModeOverride defaultBlendModeOverride) { this.name = name; this.vertexSource = vertexSource; this.geometrySource = geometrySource; + this.tessControlSource = tessControlSource; + this.tessEvalSource = tessEvalSource; this.fragmentSource = fragmentSource; this.parent = parent; this.directives = new ProgramDirectives(this, properties, @@ -34,7 +40,7 @@ public ProgramSource(String name, String vertexSource, String geometrySource, St } public ProgramSource withDirectiveOverride(ProgramDirectives overrideDirectives) { - return new ProgramSource(name, vertexSource, geometrySource, fragmentSource, overrideDirectives, parent); + return new ProgramSource(name, vertexSource, geometrySource, tessControlSource, tessEvalSource, fragmentSource, overrideDirectives, parent); } public String getName() { @@ -49,6 +55,14 @@ public Optional getGeometrySource() { return Optional.ofNullable(geometrySource); } + public Optional getTessControlSource() { + return Optional.ofNullable(tessControlSource); + } + + public Optional getTessEvalSource() { + return Optional.ofNullable(tessEvalSource); + } + public Optional getFragmentSource() { return Optional.ofNullable(fragmentSource); } diff --git a/src/main/java/net/coderbot/iris/shaderpack/include/ShaderPackSourceNames.java b/src/main/java/net/coderbot/iris/shaderpack/include/ShaderPackSourceNames.java index 7709618e0e..31556ab7c9 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/include/ShaderPackSourceNames.java +++ b/src/main/java/net/coderbot/iris/shaderpack/include/ShaderPackSourceNames.java @@ -74,6 +74,8 @@ private static ImmutableList findPotentialStarts() { private static void addStarts(ImmutableList.Builder potentialFileNames, String baseName) { potentialFileNames.add(baseName + ".vsh"); + potentialFileNames.add(baseName + ".tcs"); + potentialFileNames.add(baseName + ".tes"); potentialFileNames.add(baseName + ".gsh"); potentialFileNames.add(baseName + ".fsh"); } diff --git a/src/main/java/net/coderbot/iris/vertices/ImmediateState.java b/src/main/java/net/coderbot/iris/vertices/ImmediateState.java index 2762c6bda0..7e13ce2970 100644 --- a/src/main/java/net/coderbot/iris/vertices/ImmediateState.java +++ b/src/main/java/net/coderbot/iris/vertices/ImmediateState.java @@ -1,9 +1,10 @@ package net.coderbot.iris.vertices; /** - * Some annoying global state needed for the extended vertex format disabling optimization. + * Some annoying global state needed for rendering. */ public class ImmediateState { public static boolean isRenderingLevel = false; + public static boolean usingTessellation = false; public static boolean renderWithExtendedVertexFormat = true; } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkProgramOverrides.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkProgramOverrides.java index 7c5542480b..154b8895c6 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkProgramOverrides.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkProgramOverrides.java @@ -80,6 +80,56 @@ private GlShader createGeometryShader(IrisTerrainPass pass, SodiumTerrainPipelin "sodium-terrain-" + pass.toString().toLowerCase(Locale.ROOT) + ".gsh"), source); } + private GlShader createTessControlShader(IrisTerrainPass pass, SodiumTerrainPipeline pipeline) { + Optional irisTessControlShader; + + if (pass == IrisTerrainPass.SHADOW || pass == IrisTerrainPass.SHADOW_CUTOUT) { + irisTessControlShader = pipeline.getShadowTessControlShaderSource(); + } else if (pass == IrisTerrainPass.GBUFFER_SOLID) { + irisTessControlShader = pipeline.getTerrainSolidTessControlShaderSource(); + } else if (pass == IrisTerrainPass.GBUFFER_CUTOUT) { + irisTessControlShader = pipeline.getTerrainCutoutTessControlShaderSource(); + } else if (pass == IrisTerrainPass.GBUFFER_TRANSLUCENT) { + irisTessControlShader = pipeline.getTranslucentTessControlShaderSource(); + } else { + throw new IllegalArgumentException("Unknown pass type " + pass); + } + + String source = irisTessControlShader.orElse(null); + + if (source == null) { + return null; + } + + return new GlShader(IrisShaderTypes.TESS_CONTROL, new ResourceLocation("iris", + "sodium-terrain-" + pass.toString().toLowerCase(Locale.ROOT) + ".tcs"), source); + } + + private GlShader createTessEvalShader(IrisTerrainPass pass, SodiumTerrainPipeline pipeline) { + Optional irisTessEvalShader; + + if (pass == IrisTerrainPass.SHADOW || pass == IrisTerrainPass.SHADOW_CUTOUT) { + irisTessEvalShader = pipeline.getShadowTessEvalShaderSource(); + } else if (pass == IrisTerrainPass.GBUFFER_SOLID) { + irisTessEvalShader = pipeline.getTerrainSolidTessEvalShaderSource(); + } else if (pass == IrisTerrainPass.GBUFFER_CUTOUT) { + irisTessEvalShader = pipeline.getTerrainCutoutTessEvalShaderSource(); + } else if (pass == IrisTerrainPass.GBUFFER_TRANSLUCENT) { + irisTessEvalShader = pipeline.getTranslucentTessEvalShaderSource(); + } else { + throw new IllegalArgumentException("Unknown pass type " + pass); + } + + String source = irisTessEvalShader.orElse(null); + + if (source == null) { + return null; + } + + return new GlShader(IrisShaderTypes.TESS_EVAL, new ResourceLocation("iris", + "sodium-terrain-" + pass.toString().toLowerCase(Locale.ROOT) + ".tes"), source); + } + private GlShader createFragmentShader(IrisTerrainPass pass, SodiumTerrainPipeline pipeline) { Optional irisFragmentShader; @@ -139,6 +189,8 @@ private List getBufferBlendOverride(IrisTerrainPass pass, S private GlProgram createShader(IrisTerrainPass pass, SodiumTerrainPipeline pipeline) { GlShader vertShader = createVertexShader(pass, pipeline); GlShader geomShader = createGeometryShader(pass, pipeline); + GlShader tessCShader = createTessControlShader(pass, pipeline); + GlShader tessEShader = createTessEvalShader(pass, pipeline); GlShader fragShader = createFragmentShader(pass, pipeline); BlendModeOverride blendOverride = getBlendOverride(pass, pipeline); List bufferOverrides = getBufferBlendOverride(pass, pipeline); @@ -153,6 +205,14 @@ private GlProgram createShader(IrisTerrainPass pass, S geomShader.delete(); } + if (tessCShader != null) { + tessCShader.delete(); + } + + if (tessEShader != null) { + tessEShader.delete(); + } + if (fragShader != null) { fragShader.delete(); } @@ -168,6 +228,12 @@ private GlProgram createShader(IrisTerrainPass pass, S if (geomShader != null) { builder.attachShader(geomShader); } + if (tessCShader != null) { + builder.attachShader(tessCShader); + } + if (tessEShader != null) { + builder.attachShader(tessEShader); + } return builder.attachShader(vertShader) .attachShader(fragShader) @@ -187,13 +253,19 @@ private GlProgram createShader(IrisTerrainPass pass, S ShaderBindingContextExt contextExt = (ShaderBindingContextExt) shader; return new IrisChunkShaderInterface(handle, contextExt, pipeline, - pass == IrisTerrainPass.SHADOW || pass == IrisTerrainPass.SHADOW_CUTOUT, blendOverride, bufferOverrides, alpha, pipeline.getCustomUniforms()); + tessCShader != null || tessEShader != null, pass == IrisTerrainPass.SHADOW || pass == IrisTerrainPass.SHADOW_CUTOUT, blendOverride, bufferOverrides, alpha, pipeline.getCustomUniforms()); }); } finally { vertShader.delete(); if (geomShader != null) { geomShader.delete(); } + if (tessCShader != null) { + tessCShader.delete(); + } + if (tessEShader != null) { + tessEShader.delete(); + } fragShader.delete(); } } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkShaderInterface.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkShaderInterface.java index 8dd1600d6b..2651f017ed 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkShaderInterface.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisChunkShaderInterface.java @@ -17,6 +17,7 @@ import net.coderbot.iris.samplers.IrisSamplers; import net.coderbot.iris.uniforms.CapturedRenderingState; import net.coderbot.iris.uniforms.custom.CustomUniforms; +import net.coderbot.iris.vertices.ImmediateState; import org.jetbrains.annotations.Nullable; import org.joml.Matrix3f; import org.joml.Matrix4f; @@ -48,10 +49,11 @@ public class IrisChunkShaderInterface { private final ProgramImages irisProgramImages; private final List bufferBlendOverrides; private final boolean hasOverrides; + private final boolean isTess; private CustomUniforms customUniforms; public IrisChunkShaderInterface(int handle, ShaderBindingContextExt contextExt, SodiumTerrainPipeline pipeline, - boolean isShadowPass, BlendModeOverride blendModeOverride, List bufferOverrides, float alpha, CustomUniforms customUniforms) { + boolean isTess, boolean isShadowPass, BlendModeOverride blendModeOverride, List bufferOverrides, float alpha, CustomUniforms customUniforms) { this.uniformModelViewMatrix = contextExt.bindUniformIfPresent("iris_ModelViewMatrix", GlUniformMatrix4f::new); this.uniformModelViewMatrixInverse = contextExt.bindUniformIfPresent("iris_ModelViewMatrixInverse", GlUniformMatrix4f::new); this.uniformProjectionMatrix = contextExt.bindUniformIfPresent("iris_ProjectionMatrix", GlUniformMatrix4f::new); @@ -60,6 +62,7 @@ public IrisChunkShaderInterface(int handle, ShaderBindingContextExt contextExt, this.uniformNormalMatrix = contextExt.bindUniformIfPresent("iris_NormalMatrix", GlUniformMatrix3f::new); this.uniformBlockDrawParameters = contextExt.bindUniformBlockIfPresent("ubo_DrawParameters", 0); this.customUniforms = customUniforms; + this.isTess = isTess; this.alpha = alpha; @@ -87,6 +90,8 @@ public void setup() { blendModeOverride.apply(); } + ImmediateState.usingTessellation = isTess; + if (hasOverrides) { bufferBlendOverrides.forEach(BufferBlendOverride::apply); } @@ -102,6 +107,8 @@ public void setup() { } public void restore() { + ImmediateState.usingTessellation = false; + if (blendModeOverride != null || hasOverrides) { BlendModeOverride.restore(); } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisShaderTypes.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisShaderTypes.java index ef30b90648..18c8980d2c 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisShaderTypes.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/shader_overrides/IrisShaderTypes.java @@ -7,4 +7,6 @@ */ public class IrisShaderTypes { public static ShaderType GEOMETRY; + public static ShaderType TESS_CONTROL; + public static ShaderType TESS_EVAL; } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkProgram.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkProgram.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkRenderShaderBackend.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinChunkRenderShaderBackend.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlRenderDevice.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlRenderDevice.java new file mode 100644 index 0000000000..ca9dd80f2b --- /dev/null +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlRenderDevice.java @@ -0,0 +1,18 @@ +package net.coderbot.iris.compat.sodium.mixin.shader_overrides; + +import me.jellysquid.mods.sodium.client.gl.tessellation.GlPrimitiveType; +import net.coderbot.iris.vertices.ImmediateState; +import org.lwjgl.opengl.GL43C; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(targets = "me.jellysquid.mods.sodium.client.gl.device.GLRenderDevice$ImmediateDrawCommandList", remap = false) +public class MixinGlRenderDevice { + @Redirect(method = "multiDrawElementsBaseVertex", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/gl/tessellation/GlPrimitiveType;getId()I")) + private int replaceId(GlPrimitiveType instance) { + if (ImmediateState.usingTessellation) return GL43C.GL_PATCHES; + + return instance.getId(); + } +} diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinShaderType.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinShaderType.java index 56af4d60d0..0b42012993 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinShaderType.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinShaderType.java @@ -4,6 +4,7 @@ import net.coderbot.iris.compat.sodium.impl.shader_overrides.IrisShaderTypes; import org.apache.commons.lang3.ArrayUtils; import org.lwjgl.opengl.GL32C; +import org.lwjgl.opengl.GL42C; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -22,7 +23,11 @@ public class MixinShaderType { IrisShaderTypes.GEOMETRY = ShaderTypeAccessor.createShaderType("GEOMETRY", baseOrdinal, GL32C.GL_GEOMETRY_SHADER); + IrisShaderTypes.TESS_CONTROL + = ShaderTypeAccessor.createShaderType("TESS_CONTROL", baseOrdinal + 1, GL42C.GL_TESS_CONTROL_SHADER); + IrisShaderTypes.TESS_EVAL + = ShaderTypeAccessor.createShaderType("TESS_EVAL", baseOrdinal + 2, GL42C.GL_TESS_EVALUATION_SHADER); - $VALUES = ArrayUtils.addAll($VALUES, IrisShaderTypes.GEOMETRY); + $VALUES = ArrayUtils.addAll($VALUES, IrisShaderTypes.GEOMETRY, IrisShaderTypes.TESS_CONTROL, IrisShaderTypes.TESS_EVAL); } } diff --git a/src/sodiumCompatibility/resources/mixins.iris.compat.sodium.json b/src/sodiumCompatibility/resources/mixins.iris.compat.sodium.json index e5b7faa62d..8751ae30fb 100644 --- a/src/sodiumCompatibility/resources/mixins.iris.compat.sodium.json +++ b/src/sodiumCompatibility/resources/mixins.iris.compat.sodium.json @@ -25,6 +25,7 @@ "separate_ao.MixinFluidRenderer", "shader_overrides.MixinBlockRenderPass", "shader_overrides.MixinGlProgram", + "shader_overrides.MixinGlRenderDevice", "shader_overrides.MixinRegionChunkRenderer", "shader_overrides.MixinShaderChunkRenderer", "shader_overrides.MixinShaderType", From 3d69f1beb7be7b18cb695b4016a42c550cf67f90 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Wed, 13 Dec 2023 16:30:25 -0800 Subject: [PATCH 02/17] Wireflamin --- src/main/java/net/coderbot/iris/Iris.java | 6 ++++++ .../coderbot/iris/mixin/MixinLevelRenderer.java | 14 ++++++++++++++ src/main/resources/assets/iris/lang/en_us.json | 1 + 3 files changed, 21 insertions(+) diff --git a/src/main/java/net/coderbot/iris/Iris.java b/src/main/java/net/coderbot/iris/Iris.java index c543735a80..5ee77b93bc 100644 --- a/src/main/java/net/coderbot/iris/Iris.java +++ b/src/main/java/net/coderbot/iris/Iris.java @@ -79,6 +79,7 @@ public class Iris { private static KeyMapping reloadKeybind; private static KeyMapping toggleShadersKeybind; private static KeyMapping shaderpackScreenKeybind; + private static KeyMapping wireframeKeybind; private static final Map shaderPackOptionQueue = new HashMap<>(); // Flag variable used when reloading @@ -130,6 +131,7 @@ public void onEarlyInitialize() { reloadKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping("iris.keybind.reload", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_R, "iris.keybinds")); toggleShadersKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping("iris.keybind.toggleShaders", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_K, "iris.keybinds")); shaderpackScreenKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping("iris.keybind.shaderPackSelection", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_O, "iris.keybinds")); + wireframeKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping("iris.keybind.wireframe", InputConstants.Type.KEYSYM, InputConstants.UNKNOWN.getValue(), "iris.keybinds")); setupCommands(Minecraft.getInstance()); @@ -240,6 +242,10 @@ public static void handleKeybinds(Minecraft minecraft) { } } + public static boolean shouldActivateWireframe() { + return wireframeKeybind.isDown(); + } + public static void toggleShaders(Minecraft minecraft, boolean enabled) throws IOException { irisConfig.setShadersEnabled(enabled); irisConfig.save(); diff --git a/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java b/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java index 5355426038..eaba334871 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java @@ -21,6 +21,7 @@ import net.fabricmc.api.Environment; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LightTexture; @@ -30,6 +31,8 @@ import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL43C; import org.spongepowered.asm.mixin.Final; import net.minecraft.client.Options; @@ -65,6 +68,9 @@ public class MixinLevelRenderer { @Shadow private Frustum cullingFrustum; + @Shadow + private @Nullable ClientLevel level; + @Inject(method = "renderLevel", at = @At("HEAD")) private void iris$setupPipeline(PoseStack poseStack, float tickDelta, long startTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, @@ -81,6 +87,10 @@ public class MixinLevelRenderer { if (pipeline.shouldDisableFrustumCulling()) { this.cullingFrustum = new NonCullingFrustum(); } + + if (Iris.shouldActivateWireframe() && this.minecraft.isLocalServer()) { + GL43C.glPolygonMode(GL43C.GL_FRONT_AND_BACK, GL43C.GL_LINE); + } } // Begin shader rendering after buffers have been cleared. @@ -104,6 +114,10 @@ public class MixinLevelRenderer { Minecraft.getInstance().getProfiler().popPush("iris_final"); pipeline.finalizeLevelRendering(); pipeline = null; + + if (Iris.shouldActivateWireframe() && this.minecraft.isLocalServer()) { + GL43C.glPolygonMode(GL43C.GL_FRONT_AND_BACK, GL43C.GL_FILL); + } } // Setup shadow terrain & render shadows before the main terrain setup. We need to do things in this order to diff --git a/src/main/resources/assets/iris/lang/en_us.json b/src/main/resources/assets/iris/lang/en_us.json index 510ac759ec..0f14f7f7db 100644 --- a/src/main/resources/assets/iris/lang/en_us.json +++ b/src/main/resources/assets/iris/lang/en_us.json @@ -9,6 +9,7 @@ "iris.shaders.ssbofailure": "The shader requested a specific feature (SSBO) that is not supported by your GPU, it may not work correctly.", "iris.keybind.reload": "Reload Shaders", "iris.keybind.shaderPackSelection": "Shaderpack Selection Screen", + "iris.keybind.wireframe": "Wireframe (SP only)", "iris.keybind.toggleShaders": "Toggle Shaders", "iris.keybinds": "Iris", "iris.shaders.reloaded.failure": "Failed to reload shaders! Reason: %s", From 540a45f22546407965b2047b50a1242db29bedbc Mon Sep 17 00:00:00 2001 From: IMS212 Date: Wed, 13 Dec 2023 10:25:31 -0800 Subject: [PATCH 03/17] Fix patching --- .../pipeline/transform/TransformPatcher.java | 2 +- .../parameter/AttributeParameters.java | 2 +- .../parameter/GeometryInfoParameters.java | 4 +- .../parameter/VanillaParameters.java | 4 +- .../transformer/AttributeTransformer.java | 59 ++++++++++++++++++- 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java b/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java index abe112019f..ebfcec90d1 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java @@ -390,7 +390,7 @@ public static Map patchVanilla( ShaderAttributeInputs inputs, Object2ObjectMap, String> textureMap) { return transform(vertex, geometry, tessControl, tessEval, fragment, - new VanillaParameters(Patch.VANILLA, textureMap, alpha, isLines, hasChunkOffset, inputs, geometry != null)); + new VanillaParameters(Patch.VANILLA, textureMap, alpha, isLines, hasChunkOffset, inputs, geometry != null, tessControl != null || tessEval != null)); } public static Map patchSodium(String vertex, String geometry, String tessControl, String tessEval, String fragment, diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/parameter/AttributeParameters.java b/src/main/java/net/coderbot/iris/pipeline/transform/parameter/AttributeParameters.java index 83b6659530..fd9a81ecfe 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/parameter/AttributeParameters.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/parameter/AttributeParameters.java @@ -15,7 +15,7 @@ public AttributeParameters(Patch patch, Object2ObjectMap, String> textureMap, boolean hasGeometry, InputAvailability inputs) { - super(patch, textureMap, hasGeometry); + super(patch, textureMap, hasGeometry, false); this.inputs = inputs; } diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/parameter/GeometryInfoParameters.java b/src/main/java/net/coderbot/iris/pipeline/transform/parameter/GeometryInfoParameters.java index ad57e6add9..dcfec4f283 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/parameter/GeometryInfoParameters.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/parameter/GeometryInfoParameters.java @@ -8,12 +8,14 @@ public abstract class GeometryInfoParameters extends Parameters { public final boolean hasGeometry; + public final boolean hasTesselation; // WARNING: adding new fields requires updating hashCode and equals methods! public GeometryInfoParameters(Patch patch, - Object2ObjectMap, String> textureMap, boolean hasGeometry) { + Object2ObjectMap, String> textureMap, boolean hasGeometry, boolean hasTesselation) { super(patch, textureMap); this.hasGeometry = hasGeometry; + this.hasTesselation = hasTesselation; } @Override diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/parameter/VanillaParameters.java b/src/main/java/net/coderbot/iris/pipeline/transform/parameter/VanillaParameters.java index 86f027b4a9..08f6309aad 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/parameter/VanillaParameters.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/parameter/VanillaParameters.java @@ -19,8 +19,8 @@ public VanillaParameters( Patch patch, Object2ObjectMap, String> textureMap, AlphaTest alpha, boolean isLines, boolean hasChunkOffset, - ShaderAttributeInputs inputs, boolean hasGeometry) { - super(patch, textureMap, hasGeometry); + ShaderAttributeInputs inputs, boolean hasGeometry, boolean hasTesselation) { + super(patch, textureMap, hasGeometry, hasTesselation); this.alpha = alpha; this.isLines = isLines; this.hasChunkOffset = hasChunkOffset; diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java index e140e1bcd5..2057fb79e3 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java @@ -167,6 +167,32 @@ public static void patchOverlayColor( // Some shader packs incorrectly ignore the alpha value, and assume that rgb // will be zero if there is no hit flash, we try to emulate that here "entityColor.rgb *= float(entityColor.a != 0.0);"); + } else if (parameters.type.glShaderType == ShaderType.TESSELATION_CONTROL) { + // replace read references to grab the color from the first vertex. + root.replaceReferenceExpressions(t, "entityColor", "entityColor[gl_InvocationID]"); + + // TODO: this is passthrough behavior + tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, + "out vec4 entityColorTCS[];", + "in vec4 entityColor[];", + "out vec4 iris_vertexColorTCS[];", + "in vec4 iris_vertexColor[];"); + tree.prependMainFunctionBody(t, + "entityColorTCS[gl_InvocationID] = entityColor[gl_InvocationID];", + "iris_vertexColorTCS[gl_InvocationID] = iris_vertexColor[gl_InvocationID];"); + } else if (parameters.type.glShaderType == ShaderType.TESSELATION_EVAL) { + // replace read references to grab the color from the first vertex. + root.replaceReferenceExpressions(t, "entityColor", "entityColorTCS[0]"); + + // TODO: this is passthrough behavior + tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, + "out vec4 entityColorTES;", + "in vec4 entityColorTCS[];", + "out vec4 iris_vertexColorTES;", + "in vec4 iris_vertexColorTCS[];"); + tree.prependMainFunctionBody(t, + "entityColorTES = entityColorTCS[0];", + "iris_vertexColorTES = iris_vertexColorTCS[0];"); } else if (parameters.type.glShaderType == ShaderType.GEOMETRY) { // replace read references to grab the color from the first vertex. root.replaceReferenceExpressions(t, "entityColor", "entityColor[0]"); @@ -180,6 +206,11 @@ public static void patchOverlayColor( tree.prependMainFunctionBody(t, "entityColorGS = entityColor[0];", "iris_vertexColorGS = iris_vertexColor[0];"); + + if (parameters.hasTesselation) { + root.rename("iris_vertexColor", "iris_vertexColorTES"); + root.rename("entityColor", "entityColorTES"); + } } else if (parameters.type.glShaderType == ShaderType.FRAGMENT) { tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, "in vec4 entityColor;", "in vec4 iris_vertexColor;"); @@ -190,6 +221,9 @@ public static void patchOverlayColor( if (parameters.hasGeometry) { root.rename("entityColor", "entityColorGS"); root.rename("iris_vertexColor", "iris_vertexColorGS"); + } else if (parameters.hasTesselation) { + root.rename("entityColor", "entityColorTES"); + root.rename("iris_vertexColor", "iris_vertexColorTES"); } } } @@ -238,13 +272,32 @@ public static void patchEntityId( // stage. tree.prependMainFunctionBody(t, "iris_entityInfo = iris_Entity;"); + } else if (parameters.type.glShaderType == ShaderType.TESSELATION_CONTROL) { + // TODO: this is passthrough behavior + tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, + "flat out ivec3 iris_entityInfoTCS[];", + "flat in ivec3 iris_entityInfo[];"); + root.replaceReferenceExpressions(t, "iris_entityInfo", "iris_EntityInfo[gl_InvocationID]"); + + tree.prependMainFunctionBody(t, + "iris_entityInfoTCS[gl_InvocationID] = iris_entityInfo[gl_InvocationID];"); + } else if (parameters.type.glShaderType == ShaderType.TESSELATION_EVAL) { + // TODO: this is passthrough behavior + tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, + "flat out ivec3 iris_entityInfoTES;", + "flat in ivec3 iris_entityInfoTCS[];"); + tree.prependMainFunctionBody(t, + "iris_entityInfoTES = iris_entityInfoTCS[0];"); + + root.replaceReferenceExpressions(t, "iris_entityInfo", "iris_EntityInfoTCS[0]"); + } else if (parameters.type.glShaderType == ShaderType.GEOMETRY) { // TODO: this is passthrough behavior tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, "flat out ivec3 iris_entityInfoGS;", - "flat in ivec3 iris_entityInfo[];"); + "flat in ivec3 iris_entityInfo" + (parameters.hasTesselation ? "TES" : "") + "[];"); tree.prependMainFunctionBody(t, - "iris_entityInfoGS = iris_entityInfo[0];"); + "iris_entityInfoGS = iris_entityInfo" + (parameters.hasTesselation ? "TES" : "") + "[0];"); } else if (parameters.type.glShaderType == ShaderType.FRAGMENT) { tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, "flat in ivec3 iris_entityInfo;"); @@ -252,6 +305,8 @@ public static void patchEntityId( // Different output name to avoid a name collision in the geometry shader. if (parameters.hasGeometry) { root.rename("iris_entityInfo", "iris_EntityInfoGS"); + } else if (parameters.hasTesselation) { + root.rename("iris_entityInfo", "iris_entityInfoTES"); } } } From d01aa71bdc81492fcaf8addf81d84e5bf6898915 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Wed, 13 Dec 2023 16:33:55 -0800 Subject: [PATCH 04/17] douira's turn --- .../transform/transformer/AttributeTransformer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java index 2057fb79e3..c99c490ff2 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java @@ -173,7 +173,7 @@ public static void patchOverlayColor( // TODO: this is passthrough behavior tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, - "out vec4 entityColorTCS[];", + "patch out vec4 entityColorTCS[];", "in vec4 entityColor[];", "out vec4 iris_vertexColorTCS[];", "in vec4 iris_vertexColor[];"); @@ -182,16 +182,16 @@ public static void patchOverlayColor( "iris_vertexColorTCS[gl_InvocationID] = iris_vertexColor[gl_InvocationID];"); } else if (parameters.type.glShaderType == ShaderType.TESSELATION_EVAL) { // replace read references to grab the color from the first vertex. - root.replaceReferenceExpressions(t, "entityColor", "entityColorTCS[0]"); + root.replaceReferenceExpressions(t, "entityColor", "entityColorTCS"); // TODO: this is passthrough behavior tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, "out vec4 entityColorTES;", - "in vec4 entityColorTCS[];", + "patch in vec4 entityColorTCS;", "out vec4 iris_vertexColorTES;", "in vec4 iris_vertexColorTCS[];"); tree.prependMainFunctionBody(t, - "entityColorTES = entityColorTCS[0];", + "entityColorTES = entityColorTCS;", "iris_vertexColorTES = iris_vertexColorTCS[0];"); } else if (parameters.type.glShaderType == ShaderType.GEOMETRY) { // replace read references to grab the color from the first vertex. From 5eb3d9afd5580d1522e979cb5e1a6b903f55331a Mon Sep 17 00:00:00 2001 From: IMS212 Date: Wed, 13 Dec 2023 16:35:02 -0800 Subject: [PATCH 05/17] fix --- .../pipeline/transform/transformer/AttributeTransformer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java index c99c490ff2..baa53ad1d8 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/AttributeTransformer.java @@ -173,12 +173,12 @@ public static void patchOverlayColor( // TODO: this is passthrough behavior tree.parseAndInjectNodes(t, ASTInjectionPoint.BEFORE_DECLARATIONS, - "patch out vec4 entityColorTCS[];", + "patch out vec4 entityColorTCS;", "in vec4 entityColor[];", "out vec4 iris_vertexColorTCS[];", "in vec4 iris_vertexColor[];"); tree.prependMainFunctionBody(t, - "entityColorTCS[gl_InvocationID] = entityColor[gl_InvocationID];", + "entityColorTCS = entityColor[gl_InvocationID];", "iris_vertexColorTCS[gl_InvocationID] = iris_vertexColor[gl_InvocationID];"); } else if (parameters.type.glShaderType == ShaderType.TESSELATION_EVAL) { // replace read references to grab the color from the first vertex. From 8bc3a7ef7da23d082592f2c356a5ae313d4f4ccd Mon Sep 17 00:00:00 2001 From: IMS212 Date: Wed, 13 Dec 2023 21:22:30 -0800 Subject: [PATCH 06/17] Fix wireframe and patch stuff --- .../coderbot/iris/gl/IrisRenderSystem.java | 19 +++++++++++++++++++ .../iris/mixin/MixinLevelRenderer.java | 5 +++-- .../pipeline/transform/TransformPatcher.java | 6 +----- .../postprocess/FullScreenQuadRenderer.java | 3 +++ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java b/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java index 6d54d86f4d..971fd3a48d 100644 --- a/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java +++ b/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java @@ -41,6 +41,8 @@ public class IrisRenderSystem { private static DSAAccess dsaState; private static boolean hasMultibind; private static boolean supportsCompute; + private static int polygonMode = GL43C.GL_FILL; + private static int backupPolygonMode = GL43C.GL_FILL; private static int[] samplers; public static void initRenderer() { @@ -424,6 +426,23 @@ public static void deleteBuffers(int glId) { GL43C.glDeleteBuffers(glId); } + public static void setPolygonMode(int mode) { + if (mode != polygonMode) { + polygonMode = mode; + GL43C.glPolygonMode(GL43C.GL_FRONT_AND_BACK, mode); + } + } + + public static void overridePolygonMode() { + backupPolygonMode = polygonMode; + setPolygonMode(GL43C.GL_FILL); + } + + public static void restorePolygonMode() { + setPolygonMode(backupPolygonMode); + backupPolygonMode = GL43C.GL_FILL; + } + public interface DSAAccess { void generateMipmaps(int texture, int target); diff --git a/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java b/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java index eaba334871..1b564909ce 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java @@ -6,6 +6,7 @@ import com.mojang.math.Vector3f; import net.coderbot.iris.Iris; import net.coderbot.iris.fantastic.WrappingMultiBufferSource; +import net.coderbot.iris.gl.IrisRenderSystem; import net.coderbot.iris.gl.program.Program; import net.coderbot.iris.layer.IsOutlineRenderStateShard; import net.coderbot.iris.layer.OuterWrappedRenderType; @@ -89,7 +90,7 @@ public class MixinLevelRenderer { } if (Iris.shouldActivateWireframe() && this.minecraft.isLocalServer()) { - GL43C.glPolygonMode(GL43C.GL_FRONT_AND_BACK, GL43C.GL_LINE); + IrisRenderSystem.setPolygonMode(GL43C.GL_LINE); } } @@ -116,7 +117,7 @@ public class MixinLevelRenderer { pipeline = null; if (Iris.shouldActivateWireframe() && this.minecraft.isLocalServer()) { - GL43C.glPolygonMode(GL43C.GL_FRONT_AND_BACK, GL43C.GL_FILL); + IrisRenderSystem.setPolygonMode(GL43C.GL_FILL); } } diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java b/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java index ebfcec90d1..a3c62b0a2c 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/TransformPatcher.java @@ -194,11 +194,7 @@ public TranslationUnit parseTranslationUnit(Root rootInstance, String input) { throw new IllegalArgumentException( "No #version directive found in source code! See debugging.md for more information."); } - Version version = Version.fromNumber(Integer.parseInt(matcher.group(1))); - if (version.number >= 200) { - version = Version.GLSL33; - } - transformer.getLexer().version = version; + transformer.getLexer().version = Version.fromNumber(Integer.parseInt(matcher.group(1))); return super.parseTranslationUnit(rootInstance, input); } diff --git a/src/main/java/net/coderbot/iris/postprocess/FullScreenQuadRenderer.java b/src/main/java/net/coderbot/iris/postprocess/FullScreenQuadRenderer.java index 3d3554ea81..6af4f42051 100644 --- a/src/main/java/net/coderbot/iris/postprocess/FullScreenQuadRenderer.java +++ b/src/main/java/net/coderbot/iris/postprocess/FullScreenQuadRenderer.java @@ -7,6 +7,7 @@ import com.mojang.blaze3d.vertex.VertexBuffer; import com.mojang.blaze3d.vertex.VertexFormat; import net.coderbot.iris.fantastic.VertexBufferHelper; +import net.coderbot.iris.gl.IrisRenderSystem; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL20C; @@ -51,7 +52,9 @@ public void begin() { } public void renderQuad() { + IrisRenderSystem.overridePolygonMode(); quad.drawChunkLayer(); + IrisRenderSystem.restorePolygonMode(); } public void end() { From de9d9699ba241c6ae90d233e56387856b74bf0e9 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sat, 16 Dec 2023 08:43:39 -0800 Subject: [PATCH 07/17] fix --- .../iris/pipeline/newshader/FakeChainedJsonException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/FakeChainedJsonException.java b/src/main/java/net/coderbot/iris/pipeline/newshader/FakeChainedJsonException.java index ebf79e12a2..5d387a45b9 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/FakeChainedJsonException.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/FakeChainedJsonException.java @@ -7,7 +7,7 @@ public class FakeChainedJsonException extends ChainedJsonException { private final ShaderCompileException trueException; public FakeChainedJsonException(ShaderCompileException e) { - super(""); + super("", e); this.trueException = e; } From 2a0dd70224d6bae54df89ed08801120cb9361ece Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sat, 16 Dec 2023 11:30:12 -0800 Subject: [PATCH 08/17] Minor optimizations --- .../MixinGlStateManager_FramebufferBinding.java | 10 ++++++++++ .../coderbot/iris/postprocess/CompositeRenderer.java | 7 +++++-- .../coderbot/iris/postprocess/FinalPassRenderer.java | 7 +++++-- .../mixin/shader_overrides/MixinGlProgram.java | 12 ++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_FramebufferBinding.java b/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_FramebufferBinding.java index 91c5b7141b..1ec636a8f0 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_FramebufferBinding.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_FramebufferBinding.java @@ -16,6 +16,7 @@ public class MixinGlStateManager_FramebufferBinding { private static int iris$drawFramebuffer = 0; private static int iris$readFramebuffer = 0; + private static int iris$program = 0; @Inject(method = "_glBindFramebuffer(II)V", at = @At("HEAD"), cancellable = true, remap = false) private static void iris$avoidRedundantBind(int target, int framebuffer, CallbackInfo ci) { @@ -43,6 +44,15 @@ public class MixinGlStateManager_FramebufferBinding { } } + @Inject(method = "_glUseProgram", at = @At("HEAD"), cancellable = true, remap = false) + private static void iris$avoidRedundantBind2(int pInt0, CallbackInfo ci) { + if (iris$program == pInt0) { + ci.cancel(); + } else { + iris$program = pInt0; + } + } + @Inject(method = "_glDeleteFramebuffers(I)V", at = @At("HEAD"), remap = false) private static void iris$trackFramebufferDelete(int framebuffer, CallbackInfo ci) { if (iris$drawFramebuffer == framebuffer) { diff --git a/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java b/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java index 9b3c67b432..18473dc9d2 100644 --- a/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java +++ b/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java @@ -26,6 +26,7 @@ import net.coderbot.iris.gl.program.ProgramUniforms; import net.coderbot.iris.gl.sampler.SamplerLimits; import net.coderbot.iris.gl.texture.TextureAccess; +import net.coderbot.iris.mixin.GlStateManagerAccessor; import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline; import net.coderbot.iris.pipeline.WorldRenderingPipeline; import net.coderbot.iris.rendertarget.RenderTarget; @@ -302,8 +303,10 @@ public void renderAll() { for (int i = 0; i < SamplerLimits.get().getMaxTextureUnits(); i++) { // Unbind all textures that we may have used. // NB: This is necessary for shader pack reloading to work propely - RenderSystem.activeTexture(GL15C.GL_TEXTURE0 + i); - RenderSystem.bindTexture(0); + if (GlStateManagerAccessor.getTEXTURES()[i].binding != 0) { + RenderSystem.activeTexture(GL15C.GL_TEXTURE0 + i); + RenderSystem.bindTexture(0); + } } RenderSystem.activeTexture(GL15C.GL_TEXTURE0); diff --git a/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java b/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java index b272e2b7a3..304580be3c 100644 --- a/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java +++ b/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java @@ -17,6 +17,7 @@ import net.coderbot.iris.gl.program.ProgramUniforms; import net.coderbot.iris.gl.sampler.SamplerLimits; import net.coderbot.iris.gl.texture.TextureAccess; +import net.coderbot.iris.mixin.GlStateManagerAccessor; import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline; import net.coderbot.iris.pipeline.ShaderPrinter; import net.coderbot.iris.pipeline.WorldRenderingPipeline; @@ -274,8 +275,10 @@ public void renderFinalPass() { for (int i = 0; i < SamplerLimits.get().getMaxTextureUnits(); i++) { // Unbind all textures that we may have used. // NB: This is necessary for shader pack reloading to work properly - RenderSystem.activeTexture(GL15C.GL_TEXTURE0 + i); - RenderSystem.bindTexture(0); + if (GlStateManagerAccessor.getTEXTURES()[i].binding != 0) { + RenderSystem.activeTexture(GL15C.GL_TEXTURE0 + i); + RenderSystem.bindTexture(0); + } } RenderSystem.activeTexture(GL15C.GL_TEXTURE0); diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java index 8c7603e187..f96d9a8002 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java @@ -8,6 +8,8 @@ import net.coderbot.iris.compat.sodium.impl.shader_overrides.ShaderBindingContextExt; import net.coderbot.iris.gl.IrisRenderSystem; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; import java.util.function.IntFunction; @@ -22,6 +24,16 @@ public > U bindUniformIfPresent(String name, IntFunction< } } + @Redirect(method = "bind", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL20C;glUseProgram(I)V")) + private void iris$useGlStateManager(int i) { + GlStateManager._glUseProgram(i); + } + + @Redirect(method = "unbind", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL20C;glUseProgram(I)V")) + private void iris$useGlStateManager2(int i) { + GlStateManager._glUseProgram(i); + } + public GlUniformBlock bindUniformBlockIfPresent(String name, int bindingPoint) { int index = IrisRenderSystem.getUniformBlockIndex(this.handle(), name); if (index < 0) { From d339b861b2a1fac475327eebf5e02440031ed25c Mon Sep 17 00:00:00 2001 From: IMS212 Date: Tue, 19 Dec 2023 13:47:44 -0800 Subject: [PATCH 09/17] Add tesselation shader feature flag --- .../coderbot/iris/features/FeatureFlags.java | 1 + .../coderbot/iris/gl/IrisRenderSystem.java | 6 ++ .../coderbot/iris/shaderpack/ProgramSet.java | 92 ++++++++++--------- 3 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/main/java/net/coderbot/iris/features/FeatureFlags.java b/src/main/java/net/coderbot/iris/features/FeatureFlags.java index 99a9ef7dff..01ca0059ff 100644 --- a/src/main/java/net/coderbot/iris/features/FeatureFlags.java +++ b/src/main/java/net/coderbot/iris/features/FeatureFlags.java @@ -14,6 +14,7 @@ public enum FeatureFlags { CUSTOM_IMAGES(() -> true, IrisRenderSystem::supportsImageLoadStore), PER_BUFFER_BLENDING(() -> true, IrisRenderSystem::supportsBufferBlending), COMPUTE_SHADERS(() -> true, IrisRenderSystem::supportsCompute), + TESSELATION_SHADERS(() -> true, IrisRenderSystem::supportsTesselation), ENTITY_TRANSLUCENT(() -> true, () -> true), REVERSED_CULLING(() -> true, () -> true), SSBO(() -> true, IrisRenderSystem::supportsSSBO), diff --git a/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java b/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java index 971fd3a48d..5014a30f36 100644 --- a/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java +++ b/src/main/java/net/coderbot/iris/gl/IrisRenderSystem.java @@ -41,6 +41,7 @@ public class IrisRenderSystem { private static DSAAccess dsaState; private static boolean hasMultibind; private static boolean supportsCompute; + private static boolean supportsTesselation; private static int polygonMode = GL43C.GL_FILL; private static int backupPolygonMode = GL43C.GL_FILL; private static int[] samplers; @@ -60,6 +61,7 @@ public static void initRenderer() { hasMultibind = GL.getCapabilities().OpenGL45 || GL.getCapabilities().GL_ARB_multi_bind; supportsCompute = GL.getCapabilities().glDispatchCompute != MemoryUtil.NULL; + supportsTesselation = GL.getCapabilities().GL_ARB_tessellation_shader || GL.getCapabilities().OpenGL40; samplers = new int[SamplerLimits.get().getMaxTextureUnits()]; } @@ -366,6 +368,10 @@ public static boolean supportsCompute() { return supportsCompute; } + public static boolean supportsTesselation() { + return supportsTesselation; + } + public static int genSampler() { return GL33C.glGenSamplers(); } diff --git a/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java b/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java index e7794cfd3d..d82f658523 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java +++ b/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java @@ -1,6 +1,7 @@ package net.coderbot.iris.shaderpack; import net.coderbot.iris.Iris; +import net.coderbot.iris.features.FeatureFlags; import net.coderbot.iris.gl.blending.BlendMode; import net.coderbot.iris.gl.blending.BlendModeFunction; import net.coderbot.iris.gl.blending.BlendModeOverride; @@ -82,11 +83,13 @@ public ProgramSet(AbsolutePackPath directory, Function // // - https://github.com/IrisShaders/Iris/issues/483 // - https://github.com/IrisShaders/Iris/issues/987 + boolean readTesselation = pack.hasFeature(FeatureFlags.TESSELATION_SHADERS); + this.shadow = readProgramSource(directory, sourceProvider, "shadow", this, shaderProperties, - BlendModeOverride.OFF); + BlendModeOverride.OFF, readTesselation); this.shadowCompute = readComputeArray(directory, sourceProvider, "shadow"); - this.shadowcomp = readProgramArray(directory, sourceProvider, "shadowcomp", shaderProperties); + this.shadowcomp = readProgramArray(directory, sourceProvider, "shadowcomp", shaderProperties, readTesselation); this.shadowCompCompute = new ComputeSource[shadowcomp.length][]; for (int i = 0; i < shadowcomp.length; i++) { @@ -95,57 +98,57 @@ public ProgramSet(AbsolutePackPath directory, Function this.setup = readProgramArray(directory, sourceProvider, "setup"); - this.begin = readProgramArray(directory, sourceProvider, "begin", shaderProperties); + this.begin = readProgramArray(directory, sourceProvider, "begin", shaderProperties, readTesselation); this.beginCompute = new ComputeSource[begin.length][]; for (int i = 0; i < begin.length; i++) { this.beginCompute[i] = readComputeArray(directory, sourceProvider, "begin" + ((i == 0) ? "" : i)); } - this.prepare = readProgramArray(directory, sourceProvider, "prepare", shaderProperties); + this.prepare = readProgramArray(directory, sourceProvider, "prepare", shaderProperties, readTesselation); this.prepareCompute = new ComputeSource[prepare.length][]; for (int i = 0; i < prepare.length; i++) { this.prepareCompute[i] = readComputeArray(directory, sourceProvider, "prepare" + ((i == 0) ? "" : i)); } - this.gbuffersBasic = readProgramSource(directory, sourceProvider, "gbuffers_basic", this, shaderProperties); - this.gbuffersLine = readProgramSource(directory, sourceProvider, "gbuffers_line", this, shaderProperties); - this.gbuffersBeaconBeam = readProgramSource(directory, sourceProvider, "gbuffers_beaconbeam", this, shaderProperties); - this.gbuffersTextured = readProgramSource(directory, sourceProvider, "gbuffers_textured", this, shaderProperties); - this.gbuffersTexturedLit = readProgramSource(directory, sourceProvider, "gbuffers_textured_lit", this, shaderProperties); - this.gbuffersTerrain = readProgramSource(directory, sourceProvider, "gbuffers_terrain", this, shaderProperties); - this.gbuffersTerrainSolid = readProgramSource(directory, sourceProvider, "gbuffers_terrain_solid", this, shaderProperties); - this.gbuffersTerrainCutout = readProgramSource(directory, sourceProvider, "gbuffers_terrain_cutout", this, shaderProperties); - this.gbuffersDamagedBlock = readProgramSource(directory, sourceProvider, "gbuffers_damagedblock", this, shaderProperties); - this.gbuffersSkyBasic = readProgramSource(directory, sourceProvider, "gbuffers_skybasic", this, shaderProperties); - this.gbuffersSkyTextured = readProgramSource(directory, sourceProvider, "gbuffers_skytextured", this, shaderProperties); - this.gbuffersClouds = readProgramSource(directory, sourceProvider, "gbuffers_clouds", this, shaderProperties); - this.gbuffersWeather = readProgramSource(directory, sourceProvider, "gbuffers_weather", this, shaderProperties); - this.gbuffersEntities = readProgramSource(directory, sourceProvider, "gbuffers_entities", this, shaderProperties); - this.gbuffersEntitiesTrans = readProgramSource(directory, sourceProvider, "gbuffers_entities_translucent", this, shaderProperties); - this.gbuffersParticles = readProgramSource(directory, sourceProvider, "gbuffers_particles", this, shaderProperties); - this.gbuffersParticlesTrans = readProgramSource(directory, sourceProvider, "gbuffers_particles_translucent", this, shaderProperties); - this.gbuffersEntitiesGlowing = readProgramSource(directory, sourceProvider, "gbuffers_entities_glowing", this, shaderProperties); - this.gbuffersGlint = readProgramSource(directory, sourceProvider, "gbuffers_armor_glint", this, shaderProperties); - this.gbuffersEntityEyes = readProgramSource(directory, sourceProvider, "gbuffers_spidereyes", this, shaderProperties); - this.gbuffersBlock = readProgramSource(directory, sourceProvider, "gbuffers_block", this, shaderProperties); - this.gbuffersBlockTrans = readProgramSource(directory, sourceProvider, "gbuffers_block_translucent", this, shaderProperties); - this.gbuffersHand = readProgramSource(directory, sourceProvider, "gbuffers_hand", this, shaderProperties); - - this.deferred = readProgramArray(directory, sourceProvider, "deferred", shaderProperties); + this.gbuffersBasic = readProgramSource(directory, sourceProvider, "gbuffers_basic", this, shaderProperties, readTesselation); + this.gbuffersLine = readProgramSource(directory, sourceProvider, "gbuffers_line", this, shaderProperties, readTesselation); + this.gbuffersBeaconBeam = readProgramSource(directory, sourceProvider, "gbuffers_beaconbeam", this, shaderProperties, readTesselation); + this.gbuffersTextured = readProgramSource(directory, sourceProvider, "gbuffers_textured", this, shaderProperties, readTesselation); + this.gbuffersTexturedLit = readProgramSource(directory, sourceProvider, "gbuffers_textured_lit", this, shaderProperties, readTesselation); + this.gbuffersTerrain = readProgramSource(directory, sourceProvider, "gbuffers_terrain", this, shaderProperties, readTesselation); + this.gbuffersTerrainSolid = readProgramSource(directory, sourceProvider, "gbuffers_terrain_solid", this, shaderProperties, readTesselation); + this.gbuffersTerrainCutout = readProgramSource(directory, sourceProvider, "gbuffers_terrain_cutout", this, shaderProperties, readTesselation); + this.gbuffersDamagedBlock = readProgramSource(directory, sourceProvider, "gbuffers_damagedblock", this, shaderProperties, readTesselation); + this.gbuffersSkyBasic = readProgramSource(directory, sourceProvider, "gbuffers_skybasic", this, shaderProperties, readTesselation); + this.gbuffersSkyTextured = readProgramSource(directory, sourceProvider, "gbuffers_skytextured", this, shaderProperties, readTesselation); + this.gbuffersClouds = readProgramSource(directory, sourceProvider, "gbuffers_clouds", this, shaderProperties, readTesselation); + this.gbuffersWeather = readProgramSource(directory, sourceProvider, "gbuffers_weather", this, shaderProperties, readTesselation); + this.gbuffersEntities = readProgramSource(directory, sourceProvider, "gbuffers_entities", this, shaderProperties, readTesselation); + this.gbuffersEntitiesTrans = readProgramSource(directory, sourceProvider, "gbuffers_entities_translucent", this, shaderProperties, readTesselation); + this.gbuffersParticles = readProgramSource(directory, sourceProvider, "gbuffers_particles", this, shaderProperties, readTesselation); + this.gbuffersParticlesTrans = readProgramSource(directory, sourceProvider, "gbuffers_particles_translucent", this, shaderProperties, readTesselation); + this.gbuffersEntitiesGlowing = readProgramSource(directory, sourceProvider, "gbuffers_entities_glowing", this, shaderProperties, readTesselation); + this.gbuffersGlint = readProgramSource(directory, sourceProvider, "gbuffers_armor_glint", this, shaderProperties, readTesselation); + this.gbuffersEntityEyes = readProgramSource(directory, sourceProvider, "gbuffers_spidereyes", this, shaderProperties, readTesselation); + this.gbuffersBlock = readProgramSource(directory, sourceProvider, "gbuffers_block", this, shaderProperties, readTesselation); + this.gbuffersBlockTrans = readProgramSource(directory, sourceProvider, "gbuffers_block_translucent", this, shaderProperties, readTesselation); + this.gbuffersHand = readProgramSource(directory, sourceProvider, "gbuffers_hand", this, shaderProperties, readTesselation); + + this.deferred = readProgramArray(directory, sourceProvider, "deferred", shaderProperties, readTesselation); this.deferredCompute = new ComputeSource[deferred.length][]; for (int i = 0; i < deferred.length; i++) { this.deferredCompute[i] = readComputeArray(directory, sourceProvider, "deferred" + ((i == 0) ? "" : i)); } - this.gbuffersWater = readProgramSource(directory, sourceProvider, "gbuffers_water", this, shaderProperties); - this.gbuffersHandWater = readProgramSource(directory, sourceProvider, "gbuffers_hand_water", this, shaderProperties); + this.gbuffersWater = readProgramSource(directory, sourceProvider, "gbuffers_water", this, shaderProperties, readTesselation); + this.gbuffersHandWater = readProgramSource(directory, sourceProvider, "gbuffers_hand_water", this, shaderProperties, readTesselation); - this.composite = readProgramArray(directory, sourceProvider, "composite", shaderProperties); + this.composite = readProgramArray(directory, sourceProvider, "composite", shaderProperties, readTesselation); this.compositeCompute = new ComputeSource[composite.length][]; for (int i = 0; i < deferred.length; i++) { this.compositeCompute[i] = readComputeArray(directory, sourceProvider, "composite" + ((i == 0) ? "" : i)); } - this.compositeFinal = readProgramSource(directory, sourceProvider, "final", this, shaderProperties); + this.compositeFinal = readProgramSource(directory, sourceProvider, "final", this, shaderProperties, readTesselation); this.finalCompute = readComputeArray(directory, sourceProvider, "final"); locateDirectives(); @@ -174,13 +177,13 @@ private static Optional first(Optional... candidates) { private ProgramSource[] readProgramArray(AbsolutePackPath directory, Function sourceProvider, String name, - ShaderProperties shaderProperties) { + ShaderProperties shaderProperties, boolean readTesselation) { ProgramSource[] programs = new ProgramSource[100]; for (int i = 0; i < programs.length; i++) { String suffix = i == 0 ? "" : Integer.toString(i); - programs[i] = readProgramSource(directory, sourceProvider, name + suffix, this, shaderProperties); + programs[i] = readProgramSource(directory, sourceProvider, name + suffix, this, shaderProperties, readTesselation); } return programs; @@ -502,25 +505,30 @@ public ShaderPack getPack() { private static ProgramSource readProgramSource(AbsolutePackPath directory, Function sourceProvider, String program, - ProgramSet programSet, ShaderProperties properties) { - return readProgramSource(directory, sourceProvider, program, programSet, properties, null); + ProgramSet programSet, ShaderProperties properties, boolean readTesselation) { + return readProgramSource(directory, sourceProvider, program, programSet, properties, null, readTesselation); } private static ProgramSource readProgramSource(AbsolutePackPath directory, Function sourceProvider, String program, ProgramSet programSet, ShaderProperties properties, - BlendModeOverride defaultBlendModeOverride) { + BlendModeOverride defaultBlendModeOverride, boolean readTesselation) { AbsolutePackPath vertexPath = directory.resolve(program + ".vsh"); String vertexSource = sourceProvider.apply(vertexPath); AbsolutePackPath geometryPath = directory.resolve(program + ".gsh"); String geometrySource = sourceProvider.apply(geometryPath); - AbsolutePackPath tessControlPath = directory.resolve(program + ".tcs"); - String tessControlSource = sourceProvider.apply(tessControlPath); + String tessControlSource = null; + String tessEvalSource = null; + + if (readTesselation) { + AbsolutePackPath tessControlPath = directory.resolve(program + ".tcs"); + tessControlSource = sourceProvider.apply(tessControlPath); - AbsolutePackPath tessEvalPath = directory.resolve(program + ".tes"); - String tessEvalSource = sourceProvider.apply(tessEvalPath); + AbsolutePackPath tessEvalPath = directory.resolve(program + ".tes"); + tessEvalSource = sourceProvider.apply(tessEvalPath); + } AbsolutePackPath fragmentPath = directory.resolve(program + ".fsh"); String fragmentSource = sourceProvider.apply(fragmentPath); From 64d3dfa22dfa5333467e22de12fbd5ca1b0e3169 Mon Sep 17 00:00:00 2001 From: snowfallin <140451338+snowfallin@users.noreply.github.com> Date: Thu, 21 Dec 2023 21:08:16 -0500 Subject: [PATCH 10/17] Added support for armor as a uniform -currentArmor uniform -maxArmor uniform (50) --- .../iris/uniforms/IrisExclusiveUniforms.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java b/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java index fa60aa597a..83f6273f4d 100644 --- a/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java +++ b/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java @@ -31,8 +31,10 @@ public static void addIrisExclusiveUniforms(UniformHolder uniforms) { uniforms.uniform1f(UniformUpdateFrequency.PER_FRAME, "thunderStrength", IrisExclusiveUniforms::getThunderStrength); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerHealth", IrisExclusiveUniforms::getCurrentHealth); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "maxPlayerHealth", IrisExclusiveUniforms::getMaxHealth); - uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerHunger", IrisExclusiveUniforms::getCurrentHunger); + uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerHunger", IrisExclusiveUniforms::getCurrentHunger); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "maxPlayerHunger", () -> 20); + uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerArmor", IrisExclusiveUniforms::getCurrentArmor); + uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "maxPlayerArmor", () -> 50); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerAir", IrisExclusiveUniforms::getCurrentAir); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "maxPlayerAir", IrisExclusiveUniforms::getMaxAir); uniforms.uniform1b(UniformUpdateFrequency.PER_FRAME, "firstPersonCamera", IrisExclusiveUniforms::isFirstPersonCamera); @@ -91,6 +93,14 @@ private static float getCurrentAir() { return (float) Minecraft.getInstance().player.getAirSupply() / (float) Minecraft.getInstance().player.getMaxAirSupply(); } + private static float getCurrentArmor() { + if (Minecraft.getInstance().player == null || !Minecraft.getInstance().gameMode.getPlayerMode().isSurvival()) { + return -1; + } + + return (float) Minecraft.getInstance().player.getArmor() / (float) 50.0); + } + private static float getMaxAir() { if (Minecraft.getInstance().player == null || !Minecraft.getInstance().gameMode.getPlayerMode().isSurvival()) { return -1; @@ -107,6 +117,8 @@ private static float getMaxHealth() { return Minecraft.getInstance().player.getMaxHealth(); } + + private static boolean isFirstPersonCamera() { // If camera type is not explicitly third-person, assume it's first-person. switch (Minecraft.getInstance().options.getCameraType()) { From 0b8ff9927c7dbcef016ccf3a4bfbdff076c36026 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sat, 23 Dec 2023 15:42:26 -0800 Subject: [PATCH 11/17] Fix my own sins --- src/main/java/net/coderbot/iris/Iris.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/net/coderbot/iris/Iris.java b/src/main/java/net/coderbot/iris/Iris.java index 5ee77b93bc..830f4e1c1c 100644 --- a/src/main/java/net/coderbot/iris/Iris.java +++ b/src/main/java/net/coderbot/iris/Iris.java @@ -3,6 +3,7 @@ import com.google.common.base.Throwables; import com.mojang.blaze3d.platform.GlDebug; import com.mojang.blaze3d.platform.InputConstants; +import com.sun.jna.platform.unix.LibC; import net.coderbot.iris.compat.sodium.SodiumVersionCheck; import net.coderbot.iris.config.IrisConfig; import net.coderbot.iris.gl.GLDebug; @@ -29,12 +30,14 @@ import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.Version; import net.minecraft.ChatFormatting; +import net.minecraft.Util; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.network.chat.TranslatableComponent; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; +import org.lwjgl.system.Configuration; import java.io.IOException; import java.io.InputStream; @@ -91,6 +94,13 @@ public class Iris { private static UpdateChecker updateChecker; private static boolean fallback; + static { + // Custom fix only for me for Plasma 6 + if (FabricLoader.getInstance().isDevelopmentEnvironment() && Util.getPlatform() == Util.OS.LINUX && System.getProperty("user.name").contains("ims")) { + LibC.INSTANCE.setenv("__GL_THREADED_OPTIMIZATIONS", "0", 1); + Configuration.GLFW_LIBRARY_NAME.set("/usr/lib/libglfw.so"); + } + } /** * Called very early on in Minecraft initialization. At this point we *cannot* safely access OpenGL, but we can do * some very basic setup, config loading, and environment checks. From dbbb3debe59b7efa741829aefa5dfb25ff2bfd18 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sun, 24 Dec 2023 08:58:52 -0800 Subject: [PATCH 12/17] Fix tesselation --- .../pipeline/newshader/ExtendedShader.java | 28 ++++++++++++++++++- .../pipeline/newshader/NewShaderTests.java | 10 +++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java b/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java index e536c4798b..1e10c602f0 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/ExtendedShader.java @@ -259,7 +259,7 @@ public void attachToProgram() { } @Override - public void iris$createGeometryShader(ResourceProvider factory, String name) throws IOException { + public void iris$createExtraShaders(ResourceProvider factory, String name) throws IOException { factory.getResource(new ResourceLocation("minecraft", name + "_geometry.gsh")).ifPresent(geometry -> { try { this.geometry = Program.compileShader(IrisProgramTypes.GEOMETRY, name, geometry.open(), geometry.sourcePackId(), new GlslPreprocessor() { @@ -273,6 +273,32 @@ public String applyImport(boolean bl, String string) { e.printStackTrace(); } }); + factory.getResource(new ResourceLocation("minecraft", name + "_tessControl.tcs")).ifPresent(tessControl -> { + try { + this.tessControl = Program.compileShader(IrisProgramTypes.TESS_CONTROL, name, tessControl.open(), tessControl.sourcePackId(), new GlslPreprocessor() { + @Nullable + @Override + public String applyImport(boolean bl, String string) { + return null; + } + }); + } catch (IOException e) { + e.printStackTrace(); + } + }); + factory.getResource(new ResourceLocation("minecraft", name + "_tessEval.tes")).ifPresent(tessEval -> { + try { + this.tessEval = Program.compileShader(IrisProgramTypes.TESS_EVAL, name, tessEval.open(), tessEval.sourcePackId(), new GlslPreprocessor() { + @Nullable + @Override + public String applyImport(boolean bl, String string) { + return null; + } + }); + } catch (IOException e) { + e.printStackTrace(); + } + }); } public Program getGeometry() { diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java b/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java index 19d3a87f4e..2545c3b7ab 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/NewShaderTests.java @@ -205,6 +205,16 @@ public Optional getResource(ResourceLocation id) { return Optional.empty(); } return Optional.of(new StringResource(id, geometry)); + } else if (path.endsWith("tcs")) { + if (tessControl == null) { + return Optional.empty(); + } + return Optional.of(new StringResource(id, tessControl)); + } else if (path.endsWith("tes")) { + if (tessEval == null) { + return Optional.empty(); + } + return Optional.of(new StringResource(id, tessEval)); } else if (path.endsWith("fsh")) { return Optional.of(new StringResource(id, fragment)); } From cc4d2bed0cc7e58cbb6de1011fbfb1d05a23c38e Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sun, 24 Dec 2023 09:02:41 -0800 Subject: [PATCH 13/17] Fixed tesselation compat patcher --- .../transform/transformer/CompatibilityTransformer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/CompatibilityTransformer.java b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/CompatibilityTransformer.java index a6f4c13a7b..bf669988b0 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/CompatibilityTransformer.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/CompatibilityTransformer.java @@ -307,7 +307,7 @@ public boolean matchesExtract(ExternalDeclaration tree) { } } - private static final ShaderType[] pipeline = { ShaderType.VERTEX, ShaderType.GEOMETRY, ShaderType.FRAGMENT }; + private static final ShaderType[] pipeline = { ShaderType.VERTEX, ShaderType.TESSELATION_CONTROL, ShaderType.TESSELATION_EVAL, ShaderType.GEOMETRY, ShaderType.FRAGMENT }; private static final Matcher outDeclarationMatcher = new DeclarationMatcher( StorageType.OUT); private static final Matcher inDeclarationMatcher = new DeclarationMatcher( From 8cfda32749e4bf4acfa6e7ce0d3acba4b5777458 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 25 Dec 2023 05:45:20 -0800 Subject: [PATCH 14/17] Basic debug anticheat --- src/main/java/net/coderbot/iris/Iris.java | 7 ++++++- .../iris/mixin/MixinGlStateManager_DepthColorOverride.java | 4 ++-- .../sodium/mixin/shader_overrides/MixinGlProgram.java | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/coderbot/iris/Iris.java b/src/main/java/net/coderbot/iris/Iris.java index 830f4e1c1c..d3e4579a77 100644 --- a/src/main/java/net/coderbot/iris/Iris.java +++ b/src/main/java/net/coderbot/iris/Iris.java @@ -34,6 +34,7 @@ import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; @@ -249,11 +250,15 @@ public static void handleKeybinds(Minecraft minecraft) { } } else if (shaderpackScreenKeybind.consumeClick()) { minecraft.setScreen(new ShaderPackScreen(null)); + } else if (wireframeKeybind.consumeClick()) { + if (irisConfig.areDebugOptionsEnabled() && minecraft.player != null && !Minecraft.getInstance().isLocalServer()) { + minecraft.player.displayClientMessage(new TextComponent("No cheating; wireframe only in singleplayer!"), false); + } } } public static boolean shouldActivateWireframe() { - return wireframeKeybind.isDown(); + return irisConfig.areDebugOptionsEnabled() && wireframeKeybind.isDown(); } public static void toggleShaders(Minecraft minecraft, boolean enabled) throws IOException { diff --git a/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java b/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java index 6834b94547..3eca1cf158 100644 --- a/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java +++ b/src/main/java/net/coderbot/iris/mixin/MixinGlStateManager_DepthColorOverride.java @@ -28,7 +28,7 @@ public class MixinGlStateManager_DepthColorOverride { } } - @Redirect(method = "_drawElements", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glDrawElements(IIIJ)V")) + @Redirect(method = "_drawElements", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glDrawElements(IIIJ)V"), remap = false) private static void iris$modify(int mode, int count, int type, long indices) { if (mode == GL43C.GL_TRIANGLES && ImmediateState.usingTessellation) { mode = GL43C.GL_PATCHES; @@ -37,7 +37,7 @@ public class MixinGlStateManager_DepthColorOverride { GL43C.glDrawElements(mode, count, type, indices); } - @Inject(method = "_glUseProgram", at = @At("TAIL")) + @Inject(method = "_glUseProgram", at = @At("TAIL"), remap = false) private static void iris$resetTessellation(int pInt0, CallbackInfo ci) { ImmediateState.usingTessellation = false; } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java index f96d9a8002..9fdb33ff51 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/shader_overrides/MixinGlProgram.java @@ -13,7 +13,7 @@ import java.util.function.IntFunction; -@Mixin(GlProgram.class) +@Mixin(value = GlProgram.class, remap = false) public class MixinGlProgram extends GlObject implements ShaderBindingContextExt { public > U bindUniformIfPresent(String name, IntFunction factory) { int index = GlStateManager._glGetUniformLocation(this.handle(), name); From 7c90451188df79271a91ac6d1c290fbb60ebb6e7 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 25 Dec 2023 15:30:22 -0800 Subject: [PATCH 15/17] Fix build --- src/main/java/net/coderbot/iris/Iris.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/coderbot/iris/Iris.java b/src/main/java/net/coderbot/iris/Iris.java index 03edb851d0..f5d719b766 100644 --- a/src/main/java/net/coderbot/iris/Iris.java +++ b/src/main/java/net/coderbot/iris/Iris.java @@ -255,7 +255,7 @@ public static void handleKeybinds(Minecraft minecraft) { minecraft.setScreen(new ShaderPackScreen(null)); } else if (wireframeKeybind.consumeClick()) { if (irisConfig.areDebugOptionsEnabled() && minecraft.player != null && !Minecraft.getInstance().isLocalServer()) { - minecraft.player.displayClientMessage(new TextComponent("No cheating; wireframe only in singleplayer!"), false); + minecraft.player.displayClientMessage(Component.literal("No cheating; wireframe only in singleplayer!"), false); } } } From af6897c3cb5abde8fb969735e408ff6d53707825 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 25 Dec 2023 21:39:31 -0800 Subject: [PATCH 16/17] Add viewport offsets --- .../iris/gl/framebuffer/ViewportData.java | 9 +++++++++ .../iris/postprocess/CompositeRenderer.java | 11 +++++++---- .../iris/shaderpack/ProgramDirectives.java | 11 ++++++----- .../iris/shaderpack/ShaderProperties.java | 19 +++++++++++++------ .../iris/shadows/ShadowCompositeRenderer.java | 11 +++++++---- 5 files changed, 42 insertions(+), 19 deletions(-) create mode 100644 src/main/java/net/coderbot/iris/gl/framebuffer/ViewportData.java diff --git a/src/main/java/net/coderbot/iris/gl/framebuffer/ViewportData.java b/src/main/java/net/coderbot/iris/gl/framebuffer/ViewportData.java new file mode 100644 index 0000000000..0b33fdbd69 --- /dev/null +++ b/src/main/java/net/coderbot/iris/gl/framebuffer/ViewportData.java @@ -0,0 +1,9 @@ +package net.coderbot.iris.gl.framebuffer; + +public record ViewportData(float scale, float viewportX, float viewportY) { + private static ViewportData DEFAULT = new ViewportData(1.0f, 0.0f, 0.0f); + + public static ViewportData defaultValue() { + return DEFAULT; + } +} diff --git a/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java b/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java index 18473dc9d2..649217797e 100644 --- a/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java +++ b/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java @@ -18,6 +18,7 @@ import net.coderbot.iris.gl.IrisRenderSystem; import net.coderbot.iris.gl.blending.BlendModeOverride; import net.coderbot.iris.gl.framebuffer.GlFramebuffer; +import net.coderbot.iris.gl.framebuffer.ViewportData; import net.coderbot.iris.gl.image.GlImage; import net.coderbot.iris.gl.program.ComputeProgram; import net.coderbot.iris.gl.program.Program; @@ -212,7 +213,7 @@ private static class Pass { ImmutableSet flippedAtLeastOnce; ImmutableSet stageReadsFromAlt; ImmutableSet mipmappedBuffers; - float viewportScale; + ViewportData viewportScale; protected void destroy() { this.program.destroy(); @@ -270,9 +271,11 @@ public void renderAll() { } } - float scaledWidth = renderPass.viewWidth * renderPass.viewportScale; - float scaledHeight = renderPass.viewHeight * renderPass.viewportScale; - RenderSystem.viewport(0, 0, (int) scaledWidth, (int) scaledHeight); + float scaledWidth = renderPass.viewWidth * renderPass.viewportScale.scale(); + float scaledHeight = renderPass.viewHeight * renderPass.viewportScale.scale(); + int beginWidth = (int) (renderPass.viewWidth * renderPass.viewportScale.viewportX()); + int beginHeight = (int) (renderPass.viewHeight * renderPass.viewportScale.viewportY()); + RenderSystem.viewport(beginWidth, beginHeight, (int) scaledWidth, (int) scaledHeight); renderPass.framebuffer.bind(); renderPass.program.use(); diff --git a/src/main/java/net/coderbot/iris/shaderpack/ProgramDirectives.java b/src/main/java/net/coderbot/iris/shaderpack/ProgramDirectives.java index 618977d06f..6f93cea169 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/ProgramDirectives.java +++ b/src/main/java/net/coderbot/iris/shaderpack/ProgramDirectives.java @@ -11,6 +11,7 @@ import net.coderbot.iris.gl.blending.BlendMode; import net.coderbot.iris.gl.blending.BlendModeOverride; import net.coderbot.iris.gl.blending.BufferBlendInformation; +import net.coderbot.iris.gl.framebuffer.ViewportData; import org.jetbrains.annotations.Nullable; import java.util.Arrays; @@ -24,7 +25,7 @@ public class ProgramDirectives { private static final ImmutableList LEGACY_RENDER_TARGETS = PackRenderTargetDirectives.LEGACY_RENDER_TARGETS; private final int[] drawBuffers; - private final float viewportScale; + private final ViewportData viewportScale; @Nullable private final AlphaTest alphaTestOverride; @@ -34,7 +35,7 @@ public class ProgramDirectives { private final ImmutableMap explicitFlips; private boolean unknownDrawBuffers; - private ProgramDirectives(int[] drawBuffers, float viewportScale, @Nullable AlphaTest alphaTestOverride, + private ProgramDirectives(int[] drawBuffers, ViewportData viewportScale, @Nullable AlphaTest alphaTestOverride, Optional blendModeOverride, List bufferBlendInformations, ImmutableSet mipmappedBuffers, ImmutableMap explicitFlips) { this.drawBuffers = drawBuffers; @@ -74,7 +75,7 @@ private ProgramDirectives(int[] drawBuffers, float viewportScale, @Nullable Alph }); if (properties != null) { - viewportScale = properties.getViewportScaleOverrides().getOrDefault(source.getName(), 1.0f); + viewportScale = properties.getViewportScaleOverrides().getOrDefault(source.getName(), ViewportData.defaultValue()); alphaTestOverride = properties.getAlphaTestOverrides().get(source.getName()); BlendModeOverride blendModeOverride = properties.getBlendModeOverrides().get(source.getName()); @@ -84,7 +85,7 @@ private ProgramDirectives(int[] drawBuffers, float viewportScale, @Nullable Alph explicitFlips = source.getParent().getPackDirectives().getExplicitFlips(source.getName()); } else { - viewportScale = 1.0f; + viewportScale = ViewportData.defaultValue(); alphaTestOverride = null; blendModeOverride = Optional.ofNullable(defaultBlendOverride); bufferBlendInformations = Collections.emptyList(); @@ -173,7 +174,7 @@ public boolean hasUnknownDrawBuffers() { return unknownDrawBuffers; } - public float getViewportScale() { + public ViewportData getViewportScale() { return viewportScale; } diff --git a/src/main/java/net/coderbot/iris/shaderpack/ShaderProperties.java b/src/main/java/net/coderbot/iris/shaderpack/ShaderProperties.java index 6276c953e3..732750bb83 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/ShaderProperties.java +++ b/src/main/java/net/coderbot/iris/shaderpack/ShaderProperties.java @@ -17,6 +17,7 @@ import net.coderbot.iris.gl.blending.BlendModeFunction; import net.coderbot.iris.gl.blending.BlendModeOverride; import net.coderbot.iris.gl.buffer.ShaderStorageInfo; +import net.coderbot.iris.gl.framebuffer.ViewportData; import net.coderbot.iris.gl.texture.InternalTextureFormat; import net.coderbot.iris.gl.texture.PixelFormat; import net.coderbot.iris.gl.texture.PixelType; @@ -92,7 +93,7 @@ public class ShaderProperties { // TODO: private Map optifineVersionRequirements; // TODO: Parse custom uniforms / variables private final Object2ObjectMap alphaTestOverrides = new Object2ObjectOpenHashMap<>(); - private final Object2FloatMap viewportScaleOverrides = new Object2FloatOpenHashMap<>(); + private final Object2ObjectMap viewportScaleOverrides = new Object2ObjectOpenHashMap<>(); private final Object2ObjectMap textureScaleOverrides = new Object2ObjectOpenHashMap<>(); private final Object2ObjectMap blendModeOverrides = new Object2ObjectOpenHashMap<>(); private final Object2ObjectMap> bufferBlendOverrides = new Object2ObjectOpenHashMap<>(); @@ -212,16 +213,22 @@ public ShaderProperties(String contents, ShaderPackOptions shaderPackOptions, It // TODO: Custom uniforms handlePassDirective("scale.", key, value, pass -> { - float scale; + float scale, offsetX = 0.0f, offsetY = 0.0f; + String[] parts = value.split(" "); try { - scale = Float.parseFloat(value); - } catch (NumberFormatException e) { + scale = Float.parseFloat(parts[0]); + + if (parts.length > 1) { + offsetX = Float.parseFloat(parts[1]); + offsetY = Float.parseFloat(parts[2]); + } + } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { Iris.logger.error("Unable to parse scale directive for " + pass + ": " + value, e); return; } - viewportScaleOverrides.put(pass, scale); + viewportScaleOverrides.put(pass, new ViewportData(scale, offsetX, offsetY)); }); handlePassDirective("size.buffer.", key, value, pass -> { @@ -793,7 +800,7 @@ public OptionalBoolean getPrepareBeforeShadow() { return prepareBeforeShadow; } - public Object2FloatMap getViewportScaleOverrides() { + public Object2ObjectMap getViewportScaleOverrides() { return viewportScaleOverrides; } diff --git a/src/main/java/net/coderbot/iris/shadows/ShadowCompositeRenderer.java b/src/main/java/net/coderbot/iris/shadows/ShadowCompositeRenderer.java index 7e4a096d95..a6efdd83bc 100644 --- a/src/main/java/net/coderbot/iris/shadows/ShadowCompositeRenderer.java +++ b/src/main/java/net/coderbot/iris/shadows/ShadowCompositeRenderer.java @@ -7,6 +7,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import net.coderbot.iris.Iris; +import net.coderbot.iris.gl.framebuffer.ViewportData; import net.coderbot.iris.gl.image.GlImage; import net.coderbot.iris.features.FeatureFlags; import net.coderbot.iris.gl.IrisRenderSystem; @@ -154,7 +155,7 @@ private static class Pass { ImmutableSet flippedAtLeastOnce; ImmutableSet stageReadsFromAlt; ImmutableSet mipmappedBuffers; - float viewportScale; + ViewportData viewportScale; ComputeProgram[] computes; protected void destroy() { @@ -213,9 +214,11 @@ public void renderAll() { } } - float scaledWidth = renderTargets.getResolution() * renderPass.viewportScale; - float scaledHeight = renderTargets.getResolution() * renderPass.viewportScale; - RenderSystem.viewport(0, 0, (int) scaledWidth, (int) scaledHeight); + float scaledWidth = renderTargets.getResolution() * renderPass.viewportScale.scale(); + float scaledHeight = renderTargets.getResolution() * renderPass.viewportScale.scale(); + int beginWidth = (int) (renderTargets.getResolution() * renderPass.viewportScale.viewportX()); + int beginHeight = (int) (renderTargets.getResolution() * renderPass.viewportScale.viewportY()); + RenderSystem.viewport(beginWidth, beginHeight, (int) scaledWidth, (int) scaledHeight); renderPass.framebuffer.bind(); renderPass.program.use(); From 6c880cd377d97ffd5de648ba4dfac7ea88897b4f Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 25 Dec 2023 21:51:02 -0800 Subject: [PATCH 17/17] Fix armor uniform --- .../net/coderbot/iris/uniforms/IrisExclusiveUniforms.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java b/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java index 83f6273f4d..1037ae4fb5 100644 --- a/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java +++ b/src/main/java/net/coderbot/iris/uniforms/IrisExclusiveUniforms.java @@ -31,7 +31,7 @@ public static void addIrisExclusiveUniforms(UniformHolder uniforms) { uniforms.uniform1f(UniformUpdateFrequency.PER_FRAME, "thunderStrength", IrisExclusiveUniforms::getThunderStrength); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerHealth", IrisExclusiveUniforms::getCurrentHealth); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "maxPlayerHealth", IrisExclusiveUniforms::getMaxHealth); - uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerHunger", IrisExclusiveUniforms::getCurrentHunger); + uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerHunger", IrisExclusiveUniforms::getCurrentHunger); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "maxPlayerHunger", () -> 20); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "currentPlayerArmor", IrisExclusiveUniforms::getCurrentArmor); uniforms.uniform1f(UniformUpdateFrequency.PER_TICK, "maxPlayerArmor", () -> 50); @@ -98,7 +98,7 @@ private static float getCurrentArmor() { return -1; } - return (float) Minecraft.getInstance().player.getArmor() / (float) 50.0); + return (float) (Minecraft.getInstance().player.getArmorValue() / 50.0f); } private static float getMaxAir() { @@ -117,7 +117,7 @@ private static float getMaxHealth() { return Minecraft.getInstance().player.getMaxHealth(); } - + private static boolean isFirstPersonCamera() { // If camera type is not explicitly third-person, assume it's first-person.