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.ModelBakerySubsystem;
import me.cortex.voxy.client.core.model.ModelStore; 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.RenderGenerationService;
import me.cortex.voxy.client.core.rendering.building.SectionPositionUpdateFilterer; 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.building.SectionUpdate;
@@ -54,7 +53,13 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
this.viewportSelector = new ViewportSelector<>(this.sectionRenderer::createViewport); this.viewportSelector = new ViewportSelector<>(this.sectionRenderer::createViewport);
this.renderGen = new RenderGenerationService(world, this.modelService, serviceThreadPool, this.sectionUpdateQueue::add, this.sectionRenderer.getGeometryManager() instanceof IUsesMeshlets); 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); 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); Arrays.stream(world.getMapper().getBiomeEntries()).forEach(this.modelService::addBiome);
world.getMapper().setBiomeCallback(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) { public void setup(Camera camera) {
@@ -94,7 +109,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
DownloadStream.INSTANCE.tick(); DownloadStream.INSTANCE.tick();
//Process the build results here (this is done atomically/on the render thread) //Process the build results here (this is done atomically/on the render thread)
while (!this.sectionUpdateQueue.isEmpty()) { while (!this.sectionUpdateQueue.isEmpty()) {
this.nodeManager.processBuildResult(this.sectionUpdateQueue.poll()); this.nodeManager.processResult(this.sectionUpdateQueue.poll());
} }
} }
UploadStream.INSTANCE.tick(); UploadStream.INSTANCE.tick();

View File

@@ -8,6 +8,8 @@ import java.util.function.LongConsumer;
public class SectionPositionUpdateFilterer { public class SectionPositionUpdateFilterer {
private static final int SLICES = 1<<2; private static final int SLICES = 1<<2;
public interface IChildUpdate {void accept(WorldSection section);}
private final LongOpenHashSet[] slices = new LongOpenHashSet[SLICES]; private final LongOpenHashSet[] slices = new LongOpenHashSet[SLICES];
{ {
for (int i = 0; i < this.slices.length; i++) { 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) { public void setCallbacks(LongConsumer forwardTo, IChildUpdate childUpdateCallback) {
if (this.forwardTo != null) { if (this.renderForwardTo != null) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
this.forwardTo = forwardTo; this.renderForwardTo = forwardTo;
this.childUpdateCallback = childUpdateCallback;
} }
public boolean watch(int lvl, int x, int y, int z) { public boolean watch(int lvl, int x, int y, int z) {
@@ -36,7 +40,7 @@ public class SectionPositionUpdateFilterer {
} }
if (added) { if (added) {
//If we added it, immediately invoke for an update //If we added it, immediately invoke for an update
this.forwardTo.accept(position); this.renderForwardTo.accept(position);
} }
return added; return added;
} }
@@ -52,18 +56,23 @@ public class SectionPositionUpdateFilterer {
} }
} }
public void maybeForward(WorldSection section, int updateType) { public void maybeForward(WorldSection section, int type) {
this.maybeForward(section.key); final long position = section.key;
}
public void maybeForward(long position) {
var set = this.slices[getSliceIndex(position)]; var set = this.slices[getSliceIndex(position)];
boolean contains; boolean contains;
synchronized (set) { synchronized (set) {
contains = set.contains(position); contains = set.contains(position);
} }
if (contains) { 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 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.SectionPositionUpdateFilterer;
import me.cortex.voxy.client.core.rendering.building.SectionUpdate; import me.cortex.voxy.client.core.rendering.building.SectionUpdate;
import me.cortex.voxy.client.core.rendering.section.AbstractSectionGeometryManager; import me.cortex.voxy.client.core.rendering.section.AbstractSectionGeometryManager;
@@ -84,20 +83,24 @@ public class HierarchicalNodeManager {
} }
} }
public void processBuildResult(SectionUpdate section) { public void processResult(SectionUpdate update) {
if (section.geometry() != null) { if (update.geometry() != null) {
section.geometry().free(); if (!update.geometry().isEmpty()) {
} HierarchicalOcclusionTraverser.HACKY_SECTION_COUNT++;
/* this.geometryManager.uploadSection(update.geometry());
if (!section.isEmpty()) {
this.geometryManager.uploadSection(section);
} else { } 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) { 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 { } else {
//Part of a request (top bit is set to 1) //Part of a request (top bit is set to 1)
if ((nodeId&(1<<31))!=0) { 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 // 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) { 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) { public void doTraversal(Viewport<?> viewport, int depthBuffer) {
//Compute the mip chain //Compute the mip chain
this.hiZBuffer.buildMipChain(depthBuffer, viewport.width, viewport.height); 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 //Use a chain of glDispatchComputeIndirect (5 times) with alternating read/write buffers
// TODO: swap to persistent gpu thread instead // 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, HACKY_SECTION_COUNT);
for (int i = 1; i < HACKY_SECTION_COUNT+1; i++) {
MemoryUtil.memPutInt(uploadPtr, 1024/4-1); MemoryUtil.memPutInt(uploadPtr + 4L * i, i - 1);
for (int i = 1; i < 1024/4; i++) {
MemoryUtil.memPutInt(uploadPtr + 4*i, i-1);
} }
UploadStream.INSTANCE.commit(); UploadStream.INSTANCE.commit();
}
this.downloadResetRequestQueue(); this.downloadResetRequestQueue();
} }

View File

@@ -31,4 +31,10 @@ public final class NodeStore {
return false; 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() { public void free() {
this.frames.forEach(a->a.fence.free());
this.downloadBuffer.free(); this.downloadBuffer.free();
} }
} }

View File

@@ -5,7 +5,7 @@ import java.lang.ref.Cleaner;
public abstract class TrackedObject { public abstract class TrackedObject {
//TODO: maybe make this false? for performance overhead? //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_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; private final Ref ref;
protected TrackedObject() { protected TrackedObject() {