Use onthread bakery until all the issues related to offthread baking can be resolved (related to tile entity baking)
This commit is contained in:
@@ -2,10 +2,7 @@ package me.cortex.voxy.client.core;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import me.cortex.voxy.client.Voxy;
|
||||
import me.cortex.voxy.client.config.VoxyConfig;
|
||||
import me.cortex.voxy.client.core.model.OffThreadModelBakerySystem;
|
||||
import me.cortex.voxy.client.core.rendering.*;
|
||||
import me.cortex.voxy.client.core.rendering.building.RenderGenerationService;
|
||||
import me.cortex.voxy.client.core.rendering.post.PostProcessing;
|
||||
import me.cortex.voxy.client.core.rendering.util.DownloadStream;
|
||||
import me.cortex.voxy.client.core.util.IrisUtil;
|
||||
|
||||
@@ -101,21 +101,26 @@ public class BakedBlockEntityModel {
|
||||
}
|
||||
|
||||
public void renderOut() {
|
||||
var vc = Tessellator.getInstance();
|
||||
for (var layer : this.layers) {
|
||||
if (layer.isEmpty()) continue;
|
||||
var bb = vc.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||
if (layer.layer instanceof RenderLayer.MultiPhase mp) {
|
||||
Identifier textureId = mp.phases.texture.getId().orElse(null);
|
||||
if (textureId == null) {
|
||||
System.err.println("ERROR: Empty texture id for layer: " + layer);
|
||||
} else {
|
||||
var texture = MinecraftClient.getInstance().getTextureManager().getTexture(textureId);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.getGlId());
|
||||
//TODO:FIXME: CANT RUN ON RENDER THREAD
|
||||
if (false) {
|
||||
System.err.println("Model entity baking not yet supported offthread baking");
|
||||
} else {
|
||||
var vc = Tessellator.getInstance();
|
||||
for (var layer : this.layers) {
|
||||
if (layer.isEmpty()) continue;
|
||||
var bb = vc.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||
if (layer.layer instanceof RenderLayer.MultiPhase mp) {
|
||||
Identifier textureId = mp.phases.texture.getId().orElse(null);
|
||||
if (textureId == null) {
|
||||
System.err.println("ERROR: Empty texture id for layer: " + layer);
|
||||
} else {
|
||||
var texture = MinecraftClient.getInstance().getTextureManager().getTexture(textureId);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.getGlId());
|
||||
}
|
||||
}
|
||||
layer.putInto(bb);
|
||||
BufferRenderer.draw(bb.end());
|
||||
}
|
||||
layer.putInto(bb);
|
||||
BufferRenderer.draw(bb.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,6 @@ public class ModelFactory {
|
||||
|
||||
public void addEntry(int blockId) {
|
||||
if (this.idMappings[blockId] != -1) {
|
||||
System.err.println("Block id already added: " + blockId);
|
||||
return;
|
||||
}
|
||||
this.addEntry(blockId, this.mapper.getBlockStateFromBlockId(blockId));
|
||||
@@ -156,7 +155,7 @@ public class ModelFactory {
|
||||
// while the depth is computed from the depth buffer data
|
||||
public void addEntry(int blockId, BlockState blockState) {
|
||||
if (this.idMappings[blockId] != -1) {
|
||||
System.err.println("Block id already added: " + blockId + " for state: " + blockState);
|
||||
//System.err.println("Block id already added: " + blockId + " for state: " + blockState);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gl.GlUniform;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.BufferAllocator;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.util.Identifier;
|
||||
@@ -118,15 +119,14 @@ public class ModelTextureBakery {
|
||||
var entityModel = state.hasBlockEntity()?BakedBlockEntityModel.bake(state):null;
|
||||
|
||||
int oldFB = GlStateManager.getBoundFramebuffer();
|
||||
var oldProjection = new Matrix4f(RenderSystem.getProjectionMatrix());
|
||||
GL11C.glViewport(0, 0, this.width, this.height);
|
||||
|
||||
RenderSystem.setProjectionMatrix(new Matrix4f().identity().set(new float[]{
|
||||
var projection = new Matrix4f().identity().set(new float[]{
|
||||
2,0,0,0,
|
||||
0, 2,0,0,
|
||||
0,0, -1f,0,
|
||||
-1,-1,0,1,
|
||||
}), VertexSorter.BY_Z);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ public class ModelTextureBakery {
|
||||
|
||||
var faces = new ColourDepthTextureData[FACE_VIEWS.size()];
|
||||
for (int i = 0; i < faces.length; i++) {
|
||||
faces[i] = captureView(state, model, entityModel, FACE_VIEWS.get(i), randomValue, i, renderFluid, texId);
|
||||
faces[i] = captureView(state, model, entityModel, FACE_VIEWS.get(i), randomValue, i, renderFluid, texId, projection);
|
||||
//glBlitNamedFramebuffer(this.framebuffer.id, oldFB, 0,0,16,16,300*(i>>1),300*(i&1),300*(i>>1)+256,300*(i&1)+256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
@@ -184,7 +184,6 @@ public class ModelTextureBakery {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
RenderSystem.setProjectionMatrix(oldProjection, VertexSorter.BY_DISTANCE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, oldFB);
|
||||
GL11C.glViewport(GlStateManager.Viewport.getX(), GlStateManager.Viewport.getY(), GlStateManager.Viewport.getWidth(), GlStateManager.Viewport.getHeight());
|
||||
|
||||
@@ -194,13 +193,11 @@ public class ModelTextureBakery {
|
||||
return faces;
|
||||
}
|
||||
|
||||
|
||||
private ColourDepthTextureData captureView(BlockState state, BakedModel model, BakedBlockEntityModel blockEntityModel, MatrixStack stack, long randomValue, int face, boolean renderFluid, int textureId) {
|
||||
var vc = Tessellator.getInstance();
|
||||
private final BufferAllocator allocator = new BufferAllocator(786432);
|
||||
private ColourDepthTextureData captureView(BlockState state, BakedModel model, BakedBlockEntityModel blockEntityModel, MatrixStack stack, long randomValue, int face, boolean renderFluid, int textureId, Matrix4f projection) {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
float[] mat = new float[4*4];
|
||||
new Matrix4f(RenderSystem.getProjectionMatrix()).mul(stack.peek().getPositionMatrix()).get(mat);
|
||||
new Matrix4f(projection).mul(stack.peek().getPositionMatrix()).get(mat);
|
||||
glUniformMatrix4fv(1, false, mat);
|
||||
|
||||
|
||||
@@ -208,7 +205,7 @@ public class ModelTextureBakery {
|
||||
blockEntityModel.renderOut();
|
||||
}
|
||||
|
||||
var bb = vc.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||
var bb = new BufferBuilder(this.allocator, VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||
if (!renderFluid) {
|
||||
renderQuads(bb, state, model, new MatrixStack(), randomValue);
|
||||
} else {
|
||||
@@ -282,6 +279,7 @@ public class ModelTextureBakery {
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
try {
|
||||
//System.err.println("REPLACE THE UPLOADING WITH THREAD SAFE VARIENT");
|
||||
BufferRenderer.draw(bb.end());
|
||||
} catch (IllegalStateException e) {
|
||||
System.err.println("Got empty buffer builder! for block " + state);
|
||||
@@ -311,5 +309,6 @@ public class ModelTextureBakery {
|
||||
this.colourTex.free();
|
||||
this.depthTex.free();
|
||||
this.rasterShader.free();
|
||||
this.allocator.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ package me.cortex.voxy.client.core.model;
|
||||
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayFIFOQueue;
|
||||
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
|
||||
import me.cortex.voxy.common.world.other.Mapper;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.util.List;
|
||||
@@ -16,13 +18,16 @@ import java.util.concurrent.Semaphore;
|
||||
public class OffThreadModelBakerySystem {
|
||||
//NOTE: Create a static final context offthread and dont close it, just reuse the context, since context creation is expensive
|
||||
private static final long GL_CTX;
|
||||
private static final GLCapabilities GL_CAPS;
|
||||
static {
|
||||
var caps = GL.getCapabilities();
|
||||
GLFW.glfwMakeContextCurrent(0L);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, 0);
|
||||
GL_CTX = GLFW.glfwCreateWindow(1, 1, "", 0, MinecraftClient.getInstance().getWindow().getHandle());
|
||||
GLFW.glfwMakeContextCurrent(GL_CTX);
|
||||
GL.createCapabilities();
|
||||
GL_CAPS = GL.createCapabilities();
|
||||
GLFW.glfwMakeContextCurrent(MinecraftClient.getInstance().getWindow().getHandle());
|
||||
GL.setCapabilities(caps);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +35,7 @@ public class OffThreadModelBakerySystem {
|
||||
private final ModelStore storage = new ModelStore(16);
|
||||
public final ModelFactory factory;
|
||||
private final ConcurrentLinkedDeque<NewModelBufferDelta> bufferDeltas = new ConcurrentLinkedDeque<>();
|
||||
private final IntArrayFIFOQueue blockQueue = new IntArrayFIFOQueue();
|
||||
private final IntLinkedOpenHashSet blockIdQueue = new IntLinkedOpenHashSet();
|
||||
private final Semaphore queueCounter = new Semaphore(0);
|
||||
|
||||
|
||||
@@ -47,14 +52,15 @@ public class OffThreadModelBakerySystem {
|
||||
|
||||
private void bakeryThread() {
|
||||
GLFW.glfwMakeContextCurrent(GL_CTX);
|
||||
GL.setCapabilities(GL_CAPS);
|
||||
|
||||
//FIXME: tile entities will probably need to be baked on the main render thread
|
||||
while (true) {
|
||||
this.queueCounter.acquireUninterruptibly();
|
||||
if (!this.running) break;
|
||||
int blockId;
|
||||
synchronized (this.blockQueue) {
|
||||
blockId = this.blockQueue.dequeueInt();
|
||||
synchronized (this.blockIdQueue) {
|
||||
blockId = this.blockIdQueue.removeFirstInt();
|
||||
VarHandle.fullFence();//Ensure memory coherancy
|
||||
}
|
||||
|
||||
@@ -80,10 +86,11 @@ public class OffThreadModelBakerySystem {
|
||||
}
|
||||
|
||||
public void requestBlockBake(int blockId) {
|
||||
synchronized (this.blockQueue) {
|
||||
this.blockQueue.enqueue(blockId);
|
||||
VarHandle.fullFence();//Ensure memory coherancy
|
||||
this.queueCounter.release(1);
|
||||
synchronized (this.blockIdQueue) {
|
||||
if (this.blockIdQueue.add(blockId)) {
|
||||
VarHandle.fullFence();//Ensure memory coherancy
|
||||
this.queueCounter.release(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package me.cortex.voxy.client.core.model;
|
||||
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
|
||||
import me.cortex.voxy.common.world.other.Mapper;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.Semaphore;
|
||||
public class OnThreadModelBakerySystem {
|
||||
|
||||
private final ModelStore storage = new ModelStore(16);
|
||||
public final ModelFactory factory;
|
||||
private final IntLinkedOpenHashSet blockIdQueue = new IntLinkedOpenHashSet();
|
||||
|
||||
public OnThreadModelBakerySystem(Mapper mapper) {
|
||||
this.factory = new ModelFactory(mapper);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (!this.blockIdQueue.isEmpty()) {
|
||||
int blockId = -1;
|
||||
synchronized (this.blockIdQueue) {
|
||||
if (!this.blockIdQueue.isEmpty()) {
|
||||
blockId = this.blockIdQueue.removeFirstInt();
|
||||
VarHandle.fullFence();//Ensure memory coherancy
|
||||
}
|
||||
}
|
||||
if (blockId != -1) {
|
||||
this.factory.addEntry(blockId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
this.factory.free();
|
||||
this.storage.free();
|
||||
}
|
||||
|
||||
public void requestBlockBake(int blockId) {
|
||||
synchronized (this.blockIdQueue) {
|
||||
if (this.blockIdQueue.add(blockId)) {
|
||||
VarHandle.fullFence();//Ensure memory coherancy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addDebugData(List<String> debug) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package me.cortex.voxy.client.core.rendering;
|
||||
|
||||
import me.cortex.voxy.client.config.VoxyConfig;
|
||||
import me.cortex.voxy.client.core.model.OffThreadModelBakerySystem;
|
||||
import me.cortex.voxy.client.core.model.OnThreadModelBakerySystem;
|
||||
import me.cortex.voxy.client.core.rendering.building.BuiltSection;
|
||||
import me.cortex.voxy.client.core.rendering.building.RenderGenerationService;
|
||||
import me.cortex.voxy.common.world.WorldEngine;
|
||||
@@ -10,14 +11,19 @@ import net.minecraft.client.render.Camera;
|
||||
import java.util.List;
|
||||
|
||||
public class RenderService {
|
||||
private final OffThreadModelBakerySystem modelService;
|
||||
private final OnThreadModelBakerySystem modelService;
|
||||
private final RenderGenerationService renderGen;
|
||||
|
||||
public RenderService(WorldEngine world) {
|
||||
this.modelService = new OffThreadModelBakerySystem(world.getMapper());
|
||||
this.modelService = new OnThreadModelBakerySystem(world.getMapper());
|
||||
this.renderGen = new RenderGenerationService(world, this.modelService, VoxyConfig.CONFIG.renderThreads, this::consumeRenderBuildResult, false);
|
||||
|
||||
this.renderGen.enqueueTask(0,0,0,0);
|
||||
for(int x = -10; x<=10;x++) {
|
||||
for (int z = -10; z <= 10; z++) {
|
||||
for (int y = -3; y <= 3; y++) {
|
||||
this.renderGen.enqueueTask(0, x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void consumeRenderBuildResult(BuiltSection section) {
|
||||
@@ -26,7 +32,7 @@ public class RenderService {
|
||||
}
|
||||
|
||||
public void setup(Camera camera) {
|
||||
this.modelService.syncChanges();
|
||||
this.modelService.tick();
|
||||
}
|
||||
|
||||
public void renderFarAwayOpaque(Viewport viewport) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||
import me.cortex.voxy.client.core.model.IdNotYetComputedException;
|
||||
import me.cortex.voxy.client.core.model.ModelFactory;
|
||||
import me.cortex.voxy.client.core.model.OffThreadModelBakerySystem;
|
||||
import me.cortex.voxy.client.core.model.OnThreadModelBakerySystem;
|
||||
import me.cortex.voxy.common.world.WorldEngine;
|
||||
import me.cortex.voxy.common.world.WorldSection;
|
||||
import me.cortex.voxy.common.world.other.Mapper;
|
||||
@@ -29,12 +30,12 @@ public class RenderGenerationService {
|
||||
|
||||
private final Semaphore taskCounter = new Semaphore(0);
|
||||
private final WorldEngine world;
|
||||
private final OffThreadModelBakerySystem modelBakery;
|
||||
private final OnThreadModelBakerySystem modelBakery;
|
||||
private final Consumer<BuiltSection> resultConsumer;
|
||||
private final BuiltSectionMeshCache meshCache = new BuiltSectionMeshCache();
|
||||
private final boolean emitMeshlets;
|
||||
|
||||
public RenderGenerationService(WorldEngine world, OffThreadModelBakerySystem modelBakery, int workers, Consumer<BuiltSection> consumer, boolean emitMeshlets) {
|
||||
public RenderGenerationService(WorldEngine world, OnThreadModelBakerySystem modelBakery, int workers, Consumer<BuiltSection> consumer, boolean emitMeshlets) {
|
||||
this.emitMeshlets = emitMeshlets;
|
||||
this.world = world;
|
||||
this.modelBakery = modelBakery;
|
||||
|
||||
Reference in New Issue
Block a user