Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ public class IrisVoxyRenderPipeline extends AbstractRenderPipeline {
public IrisVoxyRenderPipeline(IrisVoxyRenderPipelineData data, AsyncNodeManager nodeManager, NodeCleaner nodeCleaner, HierarchicalOcclusionTraverser traversal, BooleanSupplier frexSupplier) {
super(nodeManager, nodeCleaner, traversal, frexSupplier, data.shouldDeferTranslucency());
this.data = data;
if (this.data.thePipeline != null) {
throw new IllegalStateException("Pipeline data already bound");
}
this.data.thePipeline = this;

//Bind the drawbuffers
var oDT = this.data.opaqueDrawTargets;
Expand Down Expand Up @@ -80,10 +76,6 @@ public void setupExtraModelBakeryData(ModelBakerySubsystem modelService) {

@Override
public void free() {
if (this.data.thePipeline != this) {
throw new IllegalStateException();
}
this.data.thePipeline = null;

this.depthBlit.delete();
this.fbTranslucent.free();
Expand Down
108 changes: 102 additions & 6 deletions src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import me.cortex.voxy.common.world.WorldEngine;
import me.cortex.voxy.commonImpl.VoxyCommon;
import net.caffeinemc.mods.sodium.client.render.chunk.ChunkRenderMatrices;
import net.irisshaders.iris.Iris;
import net.irisshaders.iris.pipeline.WorldRenderingPipeline;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import org.joml.Matrix4f;
Expand Down Expand Up @@ -68,11 +70,20 @@ public class VoxyRenderSystem {


private final RenderDistanceTracker renderDistanceTracker;
public final ChunkBoundRenderer chunkBoundRenderer;
public ChunkBoundRenderer chunkBoundRenderer;

private final ViewportSelector<?> viewportSelector;
private ViewportSelector<?> viewportSelector;

private final AbstractRenderPipeline pipeline;
private AbstractRenderPipeline pipeline;

private WorldRenderingPipeline lastIrisPipeline;

private final Object pipelineLock = new Object();

private boolean pipelineUpdatePending = false;
private ViewportSelector<?> pendingViewportSelector;
private ChunkBoundRenderer pendingChunkBoundRenderer;
private AbstractRenderPipeline oldPipelinePendingFree;

// Fog parameters captured before modification by MixinFogRenderer, for Voxy's own fog pass
private float capturedFogStart;
Expand Down Expand Up @@ -236,10 +247,75 @@ public Viewport<?> setupViewport(ChunkRenderMatrices matrices, double cameraX, d
return viewport;
}

private void setupNewPipeline() {
this.oldPipelinePendingFree = this.pipeline;

this.pipeline = RenderPipelineFactory.createPipeline(this.nodeManager, this.nodeCleaner, this.traversal, this::frexStillHasWork);
this.pipeline.setupExtraModelBakeryData(this.modelService);

var backendFactory = getRenderBackendFactory();
var sectionRenderer = backendFactory.create(this.pipeline, this.modelService.getStore(), this.geometryData);
this.pipeline.setSectionRenderer(sectionRenderer);

this.pendingViewportSelector = new ViewportSelector<>(sectionRenderer::createViewport);
this.pendingChunkBoundRenderer = new ChunkBoundRenderer(this.pipeline);
this.pipelineUpdatePending = true;

this.traversal.lateStageCompile(this.pipeline);
}

private boolean checkAndUpdatePipeline() {
if (!IrisUtil.IRIS_INSTALLED || !IrisUtil.SHADER_SUPPORT) {
return false;
}

synchronized (pipelineLock) {
WorldRenderingPipeline currentIrisPipeline = Iris.getPipelineManager().getPipelineNullable();

if (currentIrisPipeline != lastIrisPipeline) {
Logger.info("Iris pipeline changed, updating Voxy pipeline");

try {
setupNewPipeline();
lastIrisPipeline = currentIrisPipeline;
Logger.info("Voxy pipeline updated successfully (viewport swap deferred)");
return true;
} catch (Exception e) {
Logger.error("Failed to create new pipeline during update", e);
}
}
}
return false;
}

private void commitDeferredPipelineUpdate() {
if (!this.pipelineUpdatePending) return;
this.pipelineUpdatePending = false;

if (this.pendingViewportSelector != null) {
this.viewportSelector.free();
this.viewportSelector = this.pendingViewportSelector;
this.pendingViewportSelector = null;
}

if (this.pendingChunkBoundRenderer != null) {
this.chunkBoundRenderer.free();
this.chunkBoundRenderer = this.pendingChunkBoundRenderer;
this.pendingChunkBoundRenderer = null;
}

if (this.oldPipelinePendingFree != null) {
this.oldPipelinePendingFree.free();
this.oldPipelinePendingFree = null;
}
}

public void renderOpaque(Viewport<?> viewport) {
if (viewport == null) {
return;
}

checkAndUpdatePipeline();
if (viewport.width <= 0 || viewport.height <= 0) {
return;//Only render on valid viewport
}
Expand Down Expand Up @@ -461,6 +537,7 @@ public Viewport<?> getViewport() {
if (IrisUtil.irisShadowActive()) {
return null;
}
commitDeferredPipelineUpdate();
return this.viewportSelector.getViewport();
}

Expand Down Expand Up @@ -499,16 +576,31 @@ public void shutdown() {
this.traversal.free();
this.nodeCleaner.free();
this.geometryData.free();
if (((BasicSectionGeometryData)this.geometryData).isExternalGeometryBuffer) {
if (((BasicSectionGeometryData)this.geometryData).isExternalGeometryBuffer) {
RenderResourceReuse.giveBackGeometryBuffer(((BasicSectionGeometryData)this.geometryData).getGeometryBuffer());
}

this.chunkBoundRenderer.free();

this.viewportSelector.free();
this.viewportSelector.free();
} catch (Exception e) {Logger.error("Error shutting down renderer components", e);}

if (this.pendingViewportSelector != null) {
this.pendingViewportSelector.free();
this.pendingViewportSelector = null;
}
if (this.pendingChunkBoundRenderer != null) {
this.pendingChunkBoundRenderer.free();
this.pendingChunkBoundRenderer = null;
}

if (this.oldPipelinePendingFree != null) {
this.oldPipelinePendingFree.free();
this.oldPipelinePendingFree = null;
}

Logger.info("Shutting down render pipeline");
try {this.pipeline.free();} catch (Exception e){Logger.error("Error releasing render pipeline", e);}
try {if (this.pipeline != null) this.pipeline.free();} catch (Exception e){Logger.error("Error releasing render pipeline", e);}



Expand All @@ -523,4 +615,8 @@ public void shutdown() {
public WorldEngine getEngine() {
return this.worldIn;
}

public AbstractRenderPipeline getPipeline() {
return this.pipeline;
}
}
5 changes: 2 additions & 3 deletions src/main/java/me/cortex/voxy/client/core/model/MipGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@ public class MipGen {
static {
if (MODEL_TEXTURE_SIZE>16) throw new IllegalStateException("TODO: THIS MUST BE UPDATED, IT CURRENTLY ASSUMES 16 OR SMALLER SIZE");
}
private static final short[] SCRATCH = new short[MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE];
private static final ByteArrayFIFOQueue QUEUE = new ByteArrayFIFOQueue(MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE);

private static long getOffset(int bx, int by, int i) {
bx += i&(MODEL_TEXTURE_SIZE-1);
by += i/MODEL_TEXTURE_SIZE;
return bx+by*MODEL_TEXTURE_SIZE*3;
}

private static void solidify(long baseAddr, byte msk) {
short[] SCRATCH = new short[MODEL_TEXTURE_SIZE * MODEL_TEXTURE_SIZE];
ByteArrayFIFOQueue QUEUE = new ByteArrayFIFOQueue(MODEL_TEXTURE_SIZE * MODEL_TEXTURE_SIZE);
for (int idx = 0; idx < 6; idx++) {
if (((msk>>idx)&1)==0) continue;
int bx = (idx>>1)*MODEL_TEXTURE_SIZE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ public HierarchicalOcclusionTraverser(AsyncNodeManager nodeManager, NodeCleaner
}

public void lateStageCompile(AbstractRenderPipeline pipeline) {
if (this.traversal != null) {
this.traversal.free();
}
String taa = pipeline.taaFunction("getTAA");
var scr = ShaderLoader.parse("voxy:lod/hierarchical/traversal_dev.comp");
if (taa != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import static org.lwjgl.opengl.GL43C.GL_SHADER_STORAGE_BUFFER;

public class IrisVoxyRenderPipelineData {
public IrisVoxyRenderPipeline thePipeline;
public final int[] opaqueDrawTargets;
public final int[] translucentDrawTargets;
private final String opaquePatch;
Expand Down
30 changes: 19 additions & 11 deletions src/main/java/me/cortex/voxy/client/iris/VoxySamplers.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package me.cortex.voxy.client.iris;

import me.cortex.voxy.client.core.IGetVoxyRenderSystem;
import me.cortex.voxy.client.core.IrisVoxyRenderPipeline;
import net.irisshaders.iris.gl.sampler.GlSampler;
import net.irisshaders.iris.gl.sampler.SamplerHolder;
import net.irisshaders.iris.gl.texture.TextureType;
import net.irisshaders.iris.pipeline.IrisRenderingPipeline;
import net.minecraft.client.Minecraft;

public class VoxySamplers {
public static void addSamplers(IrisRenderingPipeline pipeline, SamplerHolder samplers) {
Expand All @@ -17,34 +20,39 @@ public static void addSamplers(IrisRenderingPipeline pipeline, SamplerHolder sam
translucentNames = new String[]{"vxDepthTexTrans", "dhDepthTex", "dhDepthTex0"};
}*/

//TODO replace ()->0 with the actual depth texture id
//Access the current pipeline through the VoxyRenderSystem
samplers.addDynamicSampler(TextureType.TEXTURE_2D, () -> {
var pipeData = ((IGetIrisVoxyPipelineData)pipeline).voxy$getPipelineData();
if (pipeData == null) {
var voxyRenderSystem = ((IGetVoxyRenderSystem) Minecraft.getInstance().levelRenderer).voxy$getRenderSystem();
if (voxyRenderSystem == null) {
return 0;
}
if (pipeData.thePipeline == null) {

var currentPipeline = voxyRenderSystem.getPipeline();
if (currentPipeline == null || !(currentPipeline instanceof IrisVoxyRenderPipeline irisPipeline)) {
return 0;
}

//In theory the first frame could be null
var dt = pipeData.thePipeline.fb.getDepthTex();
//Get the depth texture from the current pipeline's framebuffer
var dt = irisPipeline.fb.getDepthTex();
if (dt == null) {
return 0;
}
return dt.id;
}, new GlSampler(false, true, false, false), opaqueNames);

samplers.addDynamicSampler(TextureType.TEXTURE_2D, () -> {
var pipeData = ((IGetIrisVoxyPipelineData)pipeline).voxy$getPipelineData();
if (pipeData == null) {
var voxyRenderSystem = ((IGetVoxyRenderSystem) Minecraft.getInstance().levelRenderer).voxy$getRenderSystem();
if (voxyRenderSystem == null) {
return 0;
}
if (pipeData.thePipeline == null) {

var currentPipeline = voxyRenderSystem.getPipeline();
if (currentPipeline == null || !(currentPipeline instanceof IrisVoxyRenderPipeline irisPipeline)) {
return 0;
}
//In theory the first frame could be null
var dt = pipeData.thePipeline.fbTranslucent.getDepthTex();

//Get the depth texture from the current pipeline's translucent framebuffer
var dt = irisPipeline.fbTranslucent.getDepthTex();
if (dt == null) {
return 0;
}
Expand Down