diff --git a/src/main/java/net/coderbot/iris/pipeline/ClearPassCreator.java b/src/main/java/net/coderbot/iris/pipeline/ClearPassCreator.java index 05f96e7491..c0f649745f 100644 --- a/src/main/java/net/coderbot/iris/pipeline/ClearPassCreator.java +++ b/src/main/java/net/coderbot/iris/pipeline/ClearPassCreator.java @@ -45,6 +45,7 @@ public static ImmutableList createClearPasses(RenderTargets renderTar } RenderTarget target = renderTargets.get(buffer); + if (target == null) return; Vector4f clearColor = settings.getClearColor().orElse(defaultClearColor); clearByColor.computeIfAbsent(new Vector2i(target.getWidth(), target.getHeight()), size -> new HashMap<>()).computeIfAbsent(new ClearPassInformation(clearColor, target.getWidth(), target.getHeight()), color -> new IntArrayList()).add(buffer); } diff --git a/src/main/java/net/coderbot/iris/pipeline/newshader/NewWorldRenderingPipeline.java b/src/main/java/net/coderbot/iris/pipeline/newshader/NewWorldRenderingPipeline.java index 51ab37a74c..40cd61647e 100644 --- a/src/main/java/net/coderbot/iris/pipeline/newshader/NewWorldRenderingPipeline.java +++ b/src/main/java/net/coderbot/iris/pipeline/newshader/NewWorldRenderingPipeline.java @@ -448,11 +448,6 @@ public NewWorldRenderingPipeline(ProgramSet programSet) throws IOException { BlockRenderingSettings.INSTANCE.setSeparateEntityDraws(programSet.getPackDirectives().shouldUseSeparateEntityDraws()); BlockRenderingSettings.INSTANCE.setUseExtendedVertexFormat(true); - this.clearPassesFull = ClearPassCreator.createClearPasses(renderTargets, true, - programSet.getPackDirectives().getRenderTargetDirectives()); - this.clearPasses = ClearPassCreator.createClearPasses(renderTargets, false, - programSet.getPackDirectives().getRenderTargetDirectives()); - if (shadowRenderTargets == null && shadowDirectives.isShadowEnabled() == OptionalBoolean.TRUE) { shadowRenderTargets = new ShadowRenderTargets(this, shadowMapResolution, shadowDirectives); } @@ -498,6 +493,11 @@ public NewWorldRenderingPipeline(ProgramSet programSet) throws IOException { this.customUniforms.optimise(); boolean hasRun = false; + this.clearPassesFull = ClearPassCreator.createClearPasses(renderTargets, true, + programSet.getPackDirectives().getRenderTargetDirectives()); + this.clearPasses = ClearPassCreator.createClearPasses(renderTargets, false, + programSet.getPackDirectives().getRenderTargetDirectives()); + for (ComputeProgram program : setup) { if (program != null) { if (!hasRun) { diff --git a/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java b/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java index 032b8783a2..3397351ead 100644 --- a/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java +++ b/src/main/java/net/coderbot/iris/postprocess/CompositeRenderer.java @@ -130,6 +130,8 @@ public CompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives packDir // Flip the buffers that this shader wrote to, and set pass width and height ImmutableMap explicitFlips = directives.getExplicitFlips(); + GlFramebuffer framebuffer = renderTargets.createColorFramebuffer(flipped, drawBuffers); + for (int buffer : drawBuffers) { RenderTarget target = renderTargets.get(buffer); if ((passWidth > 0 && passWidth != target.getWidth()) || (passHeight > 0 && passHeight != target.getHeight())) { @@ -147,8 +149,6 @@ public CompositeRenderer(WorldRenderingPipeline pipeline, PackDirectives packDir flippedAtLeastOnce.add(buffer); } - GlFramebuffer framebuffer = renderTargets.createColorFramebuffer(flipped, drawBuffers); - explicitFlips.forEach((buffer, shouldFlip) -> { if (shouldFlip) { bufferFlipper.flip(buffer); @@ -308,6 +308,8 @@ public void renderAll() { } private static void setupMipmapping(net.coderbot.iris.rendertarget.RenderTarget target, boolean readFromAlt) { + if (target == null) return; + int texture = readFromAlt ? target.getAltTexture() : target.getMainTexture(); // TODO: Only generate the mipmap if a valid mipmap hasn't been generated or if we've written to the buffer diff --git a/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java b/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java index 706298e669..b272e2b7a3 100644 --- a/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java +++ b/src/main/java/net/coderbot/iris/postprocess/FinalPassRenderer.java @@ -129,7 +129,7 @@ public FinalPassRenderer(WorldRenderingPipeline pipeline, ProgramSet pack, Rende } SwapPass swap = new SwapPass(); - RenderTarget target1 = renderTargets.get(target); + RenderTarget target1 = renderTargets.getOrCreate(target); swap.target = target; swap.width = target1.getWidth(); swap.height = target1.getHeight(); @@ -293,6 +293,8 @@ public void recalculateSwapPassSize() { } private static void setupMipmapping(RenderTarget target, boolean readFromAlt) { + if (target == null) return; + int texture = readFromAlt ? target.getAltTexture() : target.getMainTexture(); // TODO: Only generate the mipmap if a valid mipmap hasn't been generated or if we've written to the buffer @@ -317,6 +319,7 @@ private static void setupMipmapping(RenderTarget target, boolean readFromAlt) { } private static void resetRenderTarget(RenderTarget target) { + if (target == null) return; // Resets the sampling mode of the given render target and then unbinds it to prevent accidental sampling of it // elsewhere. int filter = GL20C.GL_LINEAR; diff --git a/src/main/java/net/coderbot/iris/rendertarget/RenderTargets.java b/src/main/java/net/coderbot/iris/rendertarget/RenderTargets.java index 5976d4d4a8..948f5b98a0 100644 --- a/src/main/java/net/coderbot/iris/rendertarget/RenderTargets.java +++ b/src/main/java/net/coderbot/iris/rendertarget/RenderTargets.java @@ -30,6 +30,8 @@ public class RenderTargets { private DepthCopyStrategy copyStrategy; private final List ownedFramebuffers; + private final Map targetSettingsMap; + private final PackDirectives packDirectives; private int cachedWidth; private int cachedHeight; @@ -43,13 +45,8 @@ public class RenderTargets { public RenderTargets(int width, int height, int depthTexture, int depthBufferVersion, DepthBufferFormat depthFormat, Map renderTargets, PackDirectives packDirectives) { targets = new RenderTarget[renderTargets.size()]; - renderTargets.forEach((index, settings) -> { - // TODO: Handle mipmapping? - Vector2i dimensions = packDirectives.getTextureScaleOverride(index, width, height); - targets[index] = RenderTarget.builder().setDimensions(dimensions.x, dimensions.y) - .setInternalFormat(settings.getInternalFormat()) - .setPixelFormat(settings.getInternalFormat().getPixelFormat()).build(); - }); + targetSettingsMap = renderTargets; + this.packDirectives = packDirectives; this.currentDepthTexture = depthTexture; this.currentDepthFormat = depthFormat; @@ -88,7 +85,9 @@ public void destroy() { } for (RenderTarget target : targets) { - target.destroy(); + if (target != null) { + target.destroy(); + } } noTranslucents.destroy(); @@ -104,9 +103,33 @@ public RenderTarget get(int index) { throw new IllegalStateException("Tried to use destroyed RenderTargets"); } + if (targets[index] == null) { + return null; + } + return targets[index]; } + public RenderTarget getOrCreate(int index) { + if (destroyed) { + throw new IllegalStateException("Tried to use destroyed RenderTargets"); + } + + if (targets[index] != null) return targets[index]; + + create(index); + + return targets[index]; + } + + private void create(int index) { + PackRenderTargetDirectives.RenderTargetSettings settings = targetSettingsMap.get(index); + Vector2i dimensions = packDirectives.getTextureScaleOverride(index, cachedWidth, cachedHeight); + targets[index] = RenderTarget.builder().setDimensions(dimensions.x, dimensions.y) + .setInternalFormat(settings.getInternalFormat()) + .setPixelFormat(settings.getInternalFormat().getPixelFormat()).build(); + } + public int getDepthTexture() { return currentDepthTexture; } @@ -174,7 +197,9 @@ public boolean resizeIfNeeded(int newDepthBufferVersion, int newDepthTextureId, cachedHeight = newHeight; for (int i = 0; i < targets.length; i++) { - targets[i].resize(packDirectives.getTextureScaleOverride(i, newWidth, newHeight)); + if (targets[i] != null) { + targets[i].resize(packDirectives.getTextureScaleOverride(i, newWidth, newHeight)); + } } fullClearRequired = true; @@ -253,7 +278,7 @@ private GlFramebuffer createEmptyFramebuffer() { // NB: Before OpenGL 3.0, all framebuffers are required to have a color // attachment no matter what. - framebuffer.addColorAttachment(0, get(0).getMainTexture()); + framebuffer.addColorAttachment(0, getOrCreate(0).getMainTexture()); framebuffer.noDrawBuffers(); return framebuffer; @@ -316,7 +341,7 @@ public GlFramebuffer createColorFramebuffer(ImmutableSet stageWritesToM + getRenderTargetCount() + " render targets are supported."); } - RenderTarget target = this.get(drawBuffers[i]); + RenderTarget target = this.getOrCreate(drawBuffers[i]); int textureId = stageWritesToMain.contains(drawBuffers[i]) ? target.getMainTexture() : target.getAltTexture(); diff --git a/src/main/java/net/coderbot/iris/samplers/IrisImages.java b/src/main/java/net/coderbot/iris/samplers/IrisImages.java index 4edaf888dc..3cd91f0c22 100644 --- a/src/main/java/net/coderbot/iris/samplers/IrisImages.java +++ b/src/main/java/net/coderbot/iris/samplers/IrisImages.java @@ -19,10 +19,14 @@ public static void addRenderTargetImages(ImageHolder images, Supplier { ImmutableSet flippedBuffers = flipped.get(); - RenderTarget target = renderTargets.get(index); + RenderTarget target = renderTargets.getOrCreate(index); if (flippedBuffers.contains(index)) { return target.getAltTexture(); @@ -31,8 +35,7 @@ public static void addRenderTargetImages(ImageHolder images, Supplier { ImmutableSet flippedBuffers = flipped.get(); - RenderTarget target = renderTargets.get(index); + RenderTarget target = renderTargets.getOrCreate(index); if (flippedBuffers.contains(index)) { return target.getAltTexture(); @@ -71,8 +71,6 @@ public static void addRenderTargetSamplers(SamplerHolder samplers, Supplier