More work on update types + hacky add override to dummy render everything as true

This commit is contained in:
mcrcortex
2024-08-09 22:15:20 +10:00
parent 6450069d8a
commit f055234463
7 changed files with 70 additions and 34 deletions

View File

@@ -2,7 +2,6 @@ package me.cortex.voxy.client.core.rendering;
import me.cortex.voxy.client.core.model.ModelBakerySubsystem;
import me.cortex.voxy.client.core.model.ModelStore;
import me.cortex.voxy.client.core.rendering.building.BuiltSection;
import me.cortex.voxy.client.core.rendering.building.RenderGenerationService;
import me.cortex.voxy.client.core.rendering.building.SectionPositionUpdateFilterer;
import me.cortex.voxy.client.core.rendering.building.SectionUpdate;
@@ -54,7 +53,13 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
this.viewportSelector = new ViewportSelector<>(this.sectionRenderer::createViewport);
this.renderGen = new RenderGenerationService(world, this.modelService, serviceThreadPool, this.sectionUpdateQueue::add, this.sectionRenderer.getGeometryManager() instanceof IUsesMeshlets);
positionFilterForwarder.setCallback(this.renderGen::enqueueTask);
positionFilterForwarder.setCallbacks(this.renderGen::enqueueTask, section -> {
long time = System.nanoTime();
byte childExistence = section.getNonEmptyChildren();
this.sectionUpdateQueue.add(new SectionUpdate(section.key, time, null, childExistence));
});
this.traversal = new HierarchicalOcclusionTraverser(this.nodeManager, 512);
@@ -62,6 +67,16 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
Arrays.stream(world.getMapper().getBiomeEntries()).forEach(this.modelService::addBiome);
world.getMapper().setBiomeCallback(this.modelService::addBiome);
for (int x = -10; x <= 10; x++) {
for (int y = -3; y <= 3; y++) {
for (int z = -10; z <= 10; z++) {
positionFilterForwarder.watch(0, x, y ,z);
}
}
}
}
public void setup(Camera camera) {
@@ -94,7 +109,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
DownloadStream.INSTANCE.tick();
//Process the build results here (this is done atomically/on the render thread)
while (!this.sectionUpdateQueue.isEmpty()) {
this.nodeManager.processBuildResult(this.sectionUpdateQueue.poll());
this.nodeManager.processResult(this.sectionUpdateQueue.poll());
}
}
UploadStream.INSTANCE.tick();

View File

@@ -8,6 +8,8 @@ import java.util.function.LongConsumer;
public class SectionPositionUpdateFilterer {
private static final int SLICES = 1<<2;
public interface IChildUpdate {void accept(WorldSection section);}
private final LongOpenHashSet[] slices = new LongOpenHashSet[SLICES];
{
for (int i = 0; i < this.slices.length; i++) {
@@ -15,13 +17,15 @@ public class SectionPositionUpdateFilterer {
}
}
private LongConsumer forwardTo;
private LongConsumer renderForwardTo;
private IChildUpdate childUpdateCallback;
public void setCallback(LongConsumer forwardTo) {
if (this.forwardTo != null) {
public void setCallbacks(LongConsumer forwardTo, IChildUpdate childUpdateCallback) {
if (this.renderForwardTo != null) {
throw new IllegalStateException();
}
this.forwardTo = forwardTo;
this.renderForwardTo = forwardTo;
this.childUpdateCallback = childUpdateCallback;
}
public boolean watch(int lvl, int x, int y, int z) {
@@ -36,7 +40,7 @@ public class SectionPositionUpdateFilterer {
}
if (added) {
//If we added it, immediately invoke for an update
this.forwardTo.accept(position);
this.renderForwardTo.accept(position);
}
return added;
}
@@ -52,18 +56,23 @@ public class SectionPositionUpdateFilterer {
}
}
public void maybeForward(WorldSection section, int updateType) {
this.maybeForward(section.key);
}
public void maybeForward(long position) {
public void maybeForward(WorldSection section, int type) {
final long position = section.key;
var set = this.slices[getSliceIndex(position)];
boolean contains;
synchronized (set) {
contains = set.contains(position);
}
if (contains) {
this.forwardTo.accept(position);
if (type == 3) {//If its both, propagate to the render service
this.renderForwardTo.accept(position);
} else {
if (type == 2) {//If its only a existance update
this.childUpdateCallback.accept(section);
} else {//If its only a geometry update
this.renderForwardTo.accept(position);
}
}
}
}

View File

@@ -2,7 +2,6 @@ package me.cortex.voxy.client.core.rendering.hierachical2;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import me.cortex.voxy.client.core.rendering.building.BuiltSection;
import me.cortex.voxy.client.core.rendering.building.SectionPositionUpdateFilterer;
import me.cortex.voxy.client.core.rendering.building.SectionUpdate;
import me.cortex.voxy.client.core.rendering.section.AbstractSectionGeometryManager;
@@ -84,20 +83,24 @@ public class HierarchicalNodeManager {
}
}
public void processBuildResult(SectionUpdate section) {
if (section.geometry() != null) {
section.geometry().free();
}
/*
if (!section.isEmpty()) {
this.geometryManager.uploadSection(section);
public void processResult(SectionUpdate update) {
if (update.geometry() != null) {
if (!update.geometry().isEmpty()) {
HierarchicalOcclusionTraverser.HACKY_SECTION_COUNT++;
this.geometryManager.uploadSection(update.geometry());
} else {
section.free();
update.geometry().free();
}
}
if (true)
return;
int nodeId = this.activeSectionMap.get(section.position);
int nodeId = this.activeSectionMap.get(update.position());
if (nodeId == -1) {
//Not tracked or mapped to a node!!!
//Not tracked or mapped to a node!, discard it, it was probably in progress when it was removed from the map
if (update.geometry() != null) {
update.geometry().free();
}
} else {
//Part of a request (top bit is set to 1)
if ((nodeId&(1<<31))!=0) {
@@ -107,7 +110,7 @@ public class HierarchicalNodeManager {
// however could result in a reallocation if it needs to mark a child position as being possibly visible
}
}*/
}
}
private static long makeChildPos(long basePos, int addin) {

View File

@@ -40,6 +40,7 @@ public class HierarchicalOcclusionTraverser {
}
public static int HACKY_SECTION_COUNT = 0;
public void doTraversal(Viewport<?> viewport, int depthBuffer) {
//Compute the mip chain
this.hiZBuffer.buildMipChain(depthBuffer, viewport.width, viewport.height);
@@ -50,15 +51,16 @@ public class HierarchicalOcclusionTraverser {
//Use a chain of glDispatchComputeIndirect (5 times) with alternating read/write buffers
// TODO: swap to persistent gpu thread instead
if (HACKY_SECTION_COUNT != 0) {
long uploadPtr = UploadStream.INSTANCE.upload(this.renderList, 0, HACKY_SECTION_COUNT*4L+4);
long uploadPtr = UploadStream.INSTANCE.upload(this.renderList, 0, 1024);
MemoryUtil.memPutInt(uploadPtr, 1024/4-1);
for (int i = 1; i < 1024/4; i++) {
MemoryUtil.memPutInt(uploadPtr + 4*i, i-1);
MemoryUtil.memPutInt(uploadPtr, HACKY_SECTION_COUNT);
for (int i = 1; i < HACKY_SECTION_COUNT+1; i++) {
MemoryUtil.memPutInt(uploadPtr + 4L * i, i - 1);
}
UploadStream.INSTANCE.commit();
}
this.downloadResetRequestQueue();
}

View File

@@ -31,4 +31,10 @@ public final class NodeStore {
return false;
}
//Writes out a nodes data to the ptr in the compacted/reduced format
public void writeNode(long ptr, int nodeId) {
}
}

View File

@@ -77,6 +77,7 @@ public class RawDownloadStream {
}
public void free() {
this.frames.forEach(a->a.fence.free());
this.downloadBuffer.free();
}
}

View File

@@ -5,7 +5,7 @@ import java.lang.ref.Cleaner;
public abstract class TrackedObject {
//TODO: maybe make this false? for performance overhead?
public static final boolean TRACK_OBJECT_ALLOCATIONS = System.getProperty("voxy.ensureTrackedObjectsAreFreed", "true").equals("true");
public static final boolean TRACK_OBJECT_ALLOCATION_STACKS = System.getProperty("voxy.trackObjectAllocationStacks", "false").equals("true");
public static final boolean TRACK_OBJECT_ALLOCATION_STACKS = System.getProperty("voxy.trackObjectAllocationStacks", "true").equals("true");
private final Ref ref;
protected TrackedObject() {