Skip to content

Commit

Permalink
Revert "add arena content caching", prune diffs
Browse files Browse the repository at this point in the history
  • Loading branch information
douira committed Feb 9, 2025
1 parent cfe09fc commit ea64305
Show file tree
Hide file tree
Showing 9 changed files with 12 additions and 101 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package net.caffeinemc.mods.sodium.client.gl.arena;

import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
import net.caffeinemc.mods.sodium.client.gl.arena.staging.StagingBuffer;
import net.caffeinemc.mods.sodium.client.gl.buffer.GlBuffer;
import net.caffeinemc.mods.sodium.client.gl.buffer.GlBufferUsage;
import net.caffeinemc.mods.sodium.client.gl.buffer.GlMutableBuffer;
import net.caffeinemc.mods.sodium.client.gl.device.CommandList;
import net.jpountz.xxhash.XXHash64;
import net.jpountz.xxhash.XXHashFactory;

import java.nio.ByteBuffer;
import java.util.ArrayList;
Expand All @@ -29,17 +26,12 @@ public class GlBufferArena {

private GlBufferSegment head;

private static final XXHash64 NATIVE_HASH = XXHashFactory.fastestInstance().hash64();
private static final XXHash64 JAVA_HASH = XXHashFactory.fastestJavaInstance().hash64();
private static final int NATIVE_HASH_BYTES_THRESHOLD = 512; // TODO: tune this?
private final Long2ReferenceOpenHashMap<GlBufferSegment> cache;

private long capacity;
private long used;

private final int stride;

public GlBufferArena(CommandList commands, int initialCapacity, int stride, StagingBuffer stagingBuffer, boolean enableCache) {
public GlBufferArena(CommandList commands, int initialCapacity, int stride, StagingBuffer stagingBuffer) {
this.capacity = initialCapacity;
this.resizeIncrement = initialCapacity / 16;

Expand All @@ -52,12 +44,6 @@ public GlBufferArena(CommandList commands, int initialCapacity, int stride, Stag
commands.allocateStorage(this.arenaBuffer, this.capacity * stride, BUFFER_USAGE);

this.stagingBuffer = stagingBuffer;

if (enableCache) {
this.cache = new Long2ReferenceOpenHashMap<>();
} else {
this.cache = null;
}
}

private void resize(CommandList commandList, long newCapacity) {
Expand Down Expand Up @@ -240,10 +226,6 @@ public void free(GlBufferSegment entry) {
throw new IllegalStateException("Already freed");
}

if (entry.isHashed()) {
this.cache.remove(entry.getHash());
}

entry.setFree(true);

this.used -= entry.getLength();
Expand Down Expand Up @@ -283,7 +265,7 @@ public boolean upload(CommandList commandList, Stream<PendingUpload> stream) {
// A linked list is used as we'll be randomly removing elements and want O(1) performance
List<PendingUpload> queue = stream.collect(Collectors.toCollection(LinkedList::new));

// Try to upload all the data into free segments first
// Try to upload all of the data into free segments first
this.tryUploads(commandList, queue);

// If we weren't able to upload some buffers, they will have been left behind in the queue
Expand Down Expand Up @@ -315,46 +297,18 @@ private void tryUploads(CommandList commandList, List<PendingUpload> queue) {
this.stagingBuffer.flush(commandList);
}

private long getBufferHash(ByteBuffer data) {
var seed = System.identityHashCode(this);
var length = data.remaining();
if (length < NATIVE_HASH_BYTES_THRESHOLD) {
return JAVA_HASH.hash(data, 0, length, seed);
} else {
return NATIVE_HASH.hash(data, 0, length, seed);
}
}

private boolean tryUpload(CommandList commandList, PendingUpload upload) {
ByteBuffer data = upload.getDataBuffer().getDirectBuffer();
ByteBuffer data = upload.getDataBuffer()
.getDirectBuffer();

int elementCount = data.remaining() / this.stride;

// return a buffer segment with the same content if there is one based on the hash of the incoming content
GlBufferSegment matchingSegment = null;
long hash = 0;
if (this.cache != null) {
hash = this.getBufferHash(data);
matchingSegment = this.cache.get(hash);
}
if (matchingSegment != null) {
upload.setResult(matchingSegment);
matchingSegment.addRef();
return true;
}

GlBufferSegment dst = this.alloc(elementCount);

if (dst == null) {
return false;
}

// if a new segment was needed (cache miss), set the calculated hash on the segment
if (this.cache != null) {
dst.setHash(hash);
this.cache.put(hash, dst);
}

// Copy the data into our staging buffer, then copy it into the arena's buffer
this.stagingBuffer.enqueueCopy(commandList, data, this.arenaBuffer, dst.getOffset() * this.stride);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ public class GlBufferSegment {
private final GlBufferArena arena;

private boolean free = false;
private int refCount = 1;
private long hash;
private boolean isHashed = false;

private int offset; /* Uint32 */
private int length; /* Uint32 */
Expand Down Expand Up @@ -45,33 +42,8 @@ protected void setLength(long length /* Uint32 */) {
this.length = UInt32.downcast(length);
}

public void setHash(long hash) {
this.hash = hash;
this.isHashed = true;
}

public long getHash() {
return this.hash;
}

public boolean isHashed() {
return this.isHashed;
}

public void addRef() {
if (this.isFree()) {
throw new IllegalStateException("Cannot add ref to free segment");
}
this.refCount++;
}

protected void setFree(boolean free) {
this.free = free;
if (this.free) {
this.refCount = 0;
} else {
this.refCount = Math.max(this.refCount, 1);
}
}

protected boolean isFree() {
Expand All @@ -95,11 +67,7 @@ protected void setPrev(GlBufferSegment prev) {
}

public void delete() {
// only actually free if there's no more users
if (--this.refCount == 0) {
this.arena.free(this);
this.isHashed = false;
}
this.arena.free(this);
}

protected void mergeInto(GlBufferSegment entry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public boolean isEmpty() {
public int getIndexBufferSize() {
int elements = 0;

// since there's command combining, all facings might be rendered at the same time with a single command which requires a bigger index buffer
for (var index = 0; index < this.size; index++) {
elements = Math.max(elements, MemoryUtil.memGetInt(this.pElementCount + ((long) index * Integer.BYTES)));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.caffeinemc.mods.sodium.client.render.chunk;

import net.caffeinemc.mods.sodium.client.SodiumClientMod;
import net.caffeinemc.mods.sodium.client.gl.attribute.GlVertexAttributeBinding;
import net.caffeinemc.mods.sodium.client.gl.device.CommandList;
import net.caffeinemc.mods.sodium.client.gl.device.DrawCommandList;
import net.caffeinemc.mods.sodium.client.gl.device.MultiDrawBatch;
Expand All @@ -16,7 +15,6 @@
import net.caffeinemc.mods.sodium.client.render.chunk.lists.ChunkRenderList;
import net.caffeinemc.mods.sodium.client.render.chunk.lists.ChunkRenderListIterable;
import net.caffeinemc.mods.sodium.client.render.chunk.region.RenderRegion;
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderBindingPoints;
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderInterface;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortBehavior;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -701,8 +701,9 @@ public Collection<String> getDebugStrings() {
count++;
}

list.add(String.format("Geometry Pool: %d/%d MiB (%d buffers)", MathUtil.toMib(geometryDeviceUsed), MathUtil.toMib(geometryDeviceAllocated), count));
list.add(String.format("Index Pool: %d/%d MiB", MathUtil.toMib(indexDeviceUsed), MathUtil.toMib(indexDeviceAllocated)));
list.add(String.format("Pools: Geometry %d/%d MiB, Index %d/%d MiB (%d buffers)",
MathUtil.toMib(geometryDeviceUsed), MathUtil.toMib(geometryDeviceAllocated),
MathUtil.toMib(indexDeviceUsed), MathUtil.toMib(indexDeviceAllocated), count));
list.add(String.format("Transfer Queue: %s", this.regions.getStagingBuffer().toString()));

list.add(String.format("Chunk Builder: Permits=%02d (E %03d) | Busy=%02d | Total=%02d",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,6 @@ public void delete(CommandList commandList) {
commandList.deleteBuffer(this.buffer);
}

public GlIndexType getIndexFormat() {
return this.indexType.getFormat();
}

public IndexType getIndexType() {
return this.indexType;
}

public enum IndexType {
SHORT(GlIndexType.UNSIGNED_SHORT, 64 * 1024) {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder;
import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionInfo;
import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionMeshParts;
import net.caffeinemc.mods.sodium.client.render.chunk.data.SectionRenderDataUnsafe;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.DefaultTerrainRenderPasses;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.Material;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public class SectionRenderDataUnsafe {
private static final long OFFSET_SLICE_MASK = 16;
private static final long OFFSET_ELEMENT_COUNTS = 20;

private static final long ALIGNMENT = 64;
private static final long STRIDE = 64; // cache-line friendly! :)
private static final long ALIGNMENT = 8;
private static final long STRIDE = 48; // cache-line friendly! :)

public static long allocateHeap(int count) {
final var bytes = STRIDE * count;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ public DeviceResources(CommandList commandList, StagingBuffer stagingBuffer) {

// the magic number 756 for the initial size is arbitrary, it was made up.
var initialVertices = 756;
this.geometryArena = new GlBufferArena(commandList, REGION_SIZE * initialVertices, stride, stagingBuffer, false);
this.geometryArena = new GlBufferArena(commandList, REGION_SIZE * initialVertices, stride, stagingBuffer);
var initialIndices = (initialVertices / 4) * 6;
this.indexArena = new GlBufferArena(commandList, REGION_SIZE * initialIndices, Integer.BYTES, stagingBuffer, true);
this.indexArena = new GlBufferArena(commandList, REGION_SIZE * initialIndices, Integer.BYTES, stagingBuffer);
}

public void updateTessellation(CommandList commandList, GlTessellation tessellation) {
Expand Down

0 comments on commit ea64305

Please sign in to comment.