/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.mojang.logging.LogUtils * org.jspecify.annotations.Nullable * org.slf4j.Logger */ package net.minecraft.client.renderer; import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.logging.LogUtils; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import net.minecraft.client.renderer.MappableRingBuffer; import net.minecraft.util.Mth; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; public class DynamicUniformStorage implements AutoCloseable { private static final Logger LOGGER = LogUtils.getLogger(); private final List oldBuffers = new ArrayList(); private final int blockSize; private MappableRingBuffer ringBuffer; private int nextBlock; private int capacity; private @Nullable T lastUniform; private final String label; public DynamicUniformStorage(String label, int uboSize, int initialCapacity) { GpuDevice device = RenderSystem.getDevice(); this.blockSize = Mth.roundToward(uboSize, device.getUniformOffsetAlignment()); this.capacity = Mth.smallestEncompassingPowerOfTwo(initialCapacity); this.nextBlock = 0; this.ringBuffer = new MappableRingBuffer(() -> label + " x" + this.blockSize, 130, this.blockSize * this.capacity); this.label = label; } public void endFrame() { this.nextBlock = 0; this.lastUniform = null; this.ringBuffer.rotate(); if (!this.oldBuffers.isEmpty()) { for (MappableRingBuffer oldBuffer : this.oldBuffers) { oldBuffer.close(); } this.oldBuffers.clear(); } } private void resizeBuffers(int newCapacity) { this.capacity = newCapacity; this.nextBlock = 0; this.lastUniform = null; this.oldBuffers.add(this.ringBuffer); this.ringBuffer = new MappableRingBuffer(() -> this.label + " x" + this.blockSize, 130, this.blockSize * this.capacity); } public GpuBufferSlice writeUniform(T uniform) { if (this.lastUniform != null && this.lastUniform.equals(uniform)) { return this.ringBuffer.currentBuffer().slice((this.nextBlock - 1) * this.blockSize, this.blockSize); } if (this.nextBlock >= this.capacity) { int newCapacity = this.capacity * 2; LOGGER.info("Resizing {}, capacity limit of {} reached during a single frame. New capacity will be {}.", new Object[]{this.label, this.capacity, newCapacity}); this.resizeBuffers(newCapacity); } int offset = this.nextBlock * this.blockSize; try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.ringBuffer.currentBuffer().slice(offset, this.blockSize), false, true);){ uniform.write(view.data()); } ++this.nextBlock; this.lastUniform = uniform; return this.ringBuffer.currentBuffer().slice(offset, this.blockSize); } public GpuBufferSlice[] writeUniforms(T[] uniforms) { if (uniforms.length == 0) { return new GpuBufferSlice[0]; } if (this.nextBlock + uniforms.length > this.capacity) { int newCapacity = Mth.smallestEncompassingPowerOfTwo(Math.max(this.capacity + 1, uniforms.length)); LOGGER.info("Resizing {}, capacity limit of {} reached during a single frame. New capacity will be {}.", new Object[]{this.label, this.capacity, newCapacity}); this.resizeBuffers(newCapacity); } int firstOffset = this.nextBlock * this.blockSize; GpuBufferSlice[] result = new GpuBufferSlice[uniforms.length]; try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.ringBuffer.currentBuffer().slice(firstOffset, uniforms.length * this.blockSize), false, true);){ ByteBuffer byteBuffer = view.data(); for (int i = 0; i < uniforms.length; ++i) { T uniform = uniforms[i]; result[i] = this.ringBuffer.currentBuffer().slice(firstOffset + i * this.blockSize, this.blockSize); byteBuffer.position(i * this.blockSize); uniform.write(byteBuffer); } } this.nextBlock += uniforms.length; this.lastUniform = uniforms[uniforms.length - 1]; return result; } @Override public void close() { for (MappableRingBuffer oldBuffer : this.oldBuffers) { oldBuffer.close(); } this.ringBuffer.close(); } public static interface DynamicUniform { public void write(ByteBuffer var1); } }