minecraft-src/net/minecraft/client/renderer/MappableRingBuffer.java
2025-09-18 12:27:44 +00:00

66 lines
1.8 KiB
Java

package net.minecraft.client.renderer;
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuFence;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.function.Supplier;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class MappableRingBuffer implements AutoCloseable {
private static final int BUFFER_COUNT = 3;
private final GpuBuffer[] buffers = new GpuBuffer[3];
private final GpuFence[] fences = new GpuFence[3];
private final int size;
private int current = 0;
public MappableRingBuffer(Supplier<String> label, int usage, int size) {
GpuDevice gpuDevice = RenderSystem.getDevice();
if ((usage & 1) == 0 && (usage & 2) == 0) {
throw new IllegalArgumentException("MappableRingBuffer requires at least one of USAGE_MAP_READ or USAGE_MAP_WRITE");
} else {
for (int i = 0; i < 3; i++) {
int j = i;
this.buffers[i] = gpuDevice.createBuffer(() -> (String)label.get() + " #" + j, usage, size);
this.fences[i] = null;
}
this.size = size;
}
}
public int size() {
return this.size;
}
public GpuBuffer currentBuffer() {
GpuFence gpuFence = this.fences[this.current];
if (gpuFence != null) {
gpuFence.awaitCompletion(Long.MAX_VALUE);
gpuFence.close();
this.fences[this.current] = null;
}
return this.buffers[this.current];
}
public void rotate() {
if (this.fences[this.current] != null) {
this.fences[this.current].close();
}
this.fences[this.current] = RenderSystem.getDevice().createCommandEncoder().createFence();
this.current = (this.current + 1) % 3;
}
public void close() {
for (int i = 0; i < 3; i++) {
this.buffers[i].close();
if (this.fences[i] != null) {
this.fences[i].close();
}
}
}
}