VulkanShader_1.21.10-0.0.4-alpha.jar
Download file
package net.vulkanmod.vulkan.memory;
import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
import java.nio.LongBuffer;
import java.util.List;
import java.util.function.Consumer;
import net.vulkanmod.Initializer;
import net.vulkanmod.render.chunk.buffer.AreaBuffer;
import net.vulkanmod.vulkan.Vulkan;
import net.vulkanmod.vulkan.device.DeviceManager;
import net.vulkanmod.vulkan.memory.buffer.Buffer;
import net.vulkanmod.vulkan.queue.Queue;
import net.vulkanmod.vulkan.texture.VulkanImage;
import net.vulkanmod.vulkan.util.Pair;
import net.vulkanmod.vulkan.util.VkResult;
import org.apache.commons.lang3.Validate;
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.util.vma.Vma;
import org.lwjgl.util.vma.VmaAllocationCreateInfo;
import org.lwjgl.util.vma.VmaAllocationInfo;
import org.lwjgl.util.vma.VmaBudget;
import org.lwjgl.vulkan.VkBufferCreateInfo;
import org.lwjgl.vulkan.VkImageCreateInfo;
public class MemoryManager {
private static final boolean DEBUG = false;
public static final long BYTES_IN_MB = 1048576L;
private static MemoryManager INSTANCE;
private static final long ALLOCATOR = Vulkan.getAllocator();
private static final Long2ReferenceOpenHashMap<Buffer> buffers = new Long2ReferenceOpenHashMap();
private static final Long2ReferenceOpenHashMap<VulkanImage> images = new Long2ReferenceOpenHashMap();
static int Frames;
private static long deviceMemory = 0L;
private static long nativeMemory = 0L;
private int currentFrame = 0;
private final ObjectArrayList<Buffer.BufferInfo>[] freeableBuffers;
private final ObjectArrayList<VulkanImage>[] freeableImages;
private final ObjectArrayList<Runnable>[] frameOps;
private final ObjectArrayList<Pair<AreaBuffer, Integer>>[] segmentsToFree;
private ObjectArrayList<StackTraceElement[]>[] stackTraces;
public static MemoryManager getInstance() {
return INSTANCE;
}
public static void createInstance(int frames) {
Frames = frames;
INSTANCE = new MemoryManager();
}
MemoryManager() {
this.freeableBuffers = new ObjectArrayList[Frames];
this.freeableImages = new ObjectArrayList[Frames];
this.frameOps = new ObjectArrayList[Frames];
this.segmentsToFree = new ObjectArrayList[Frames];
for(int i = 0; i < Frames; ++i) {
this.freeableBuffers[i] = new ObjectArrayList();
this.freeableImages[i] = new ObjectArrayList();
this.frameOps[i] = new ObjectArrayList();
this.segmentsToFree[i] = new ObjectArrayList();
}
}
public synchronized void initFrame(int frame) {
this.setCurrentFrame(frame);
this.freeBuffers(frame);
this.freeImages(frame);
this.doFrameOps(frame);
this.freeSegments(frame);
}
public void setCurrentFrame(int frame) {
Validate.isTrue(frame < Frames, "Out of bounds frame index", new Object[0]);
this.currentFrame = frame;
}
public void freeAllBuffers() {
for(int frame = 0; frame < Frames; ++frame) {
this.freeBuffers(frame);
this.freeImages(frame);
this.doFrameOps(frame);
}
}
public void createBuffer(long size, int usage, int properties, LongBuffer pBuffer, PointerBuffer pBufferMemory) {
MemoryStack stack = MemoryStack.stackPush();
try {
VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.calloc(stack);
bufferInfo.sType(12);
bufferInfo.size(size);
bufferInfo.usage(usage);
VmaAllocationCreateInfo allocationInfo = VmaAllocationCreateInfo.calloc(stack);
allocationInfo.requiredFlags(properties);
int result = Vma.vmaCreateBuffer(ALLOCATOR, bufferInfo, allocationInfo, pBuffer, pBufferMemory, (VmaAllocationInfo)null);
if (result != 0) {
Initializer.LOGGER.info(String.format("Failed to create buffer with size: %.3f MB", (float)size / 1048576.0F));
Initializer.LOGGER.info(String.format("Tracked Device Memory used: %d/%d MB", this.getAllocatedDeviceMemoryMB(), this.getDeviceMemoryMB()));
Initializer.LOGGER.info(this.getHeapStats());
throw new RuntimeException("Failed to create buffer: %s".formatted(VkResult.decode(result)));
}
} catch (Throwable var12) {
if (stack != null) {
try {
stack.close();
} catch (Throwable var11) {
var12.addSuppressed(var11);
}
}
throw var12;
}
if (stack != null) {
stack.close();
}
}
public synchronized void createBuffer(Buffer buffer, long size, int usage, int properties) {
MemoryStack stack = MemoryStack.stackPush();
try {
LongBuffer pBuffer = stack.mallocLong(1);
PointerBuffer pAllocation = stack.pointers(0L);
this.createBuffer(size, usage, properties, pBuffer, pAllocation);
buffer.setId(pBuffer.get(0));
buffer.setAllocation(pAllocation.get(0));
buffer.setBufferSize(size);
if ((properties & 1) != 0) {
deviceMemory += size;
} else {
nativeMemory += size;
}
buffers.putIfAbsent(buffer.getId(), buffer);
} catch (Throwable var10) {
if (stack != null) {
try {
stack.close();
} catch (Throwable var9) {
var10.addSuppressed(var9);
}
}
throw var10;
}
if (stack != null) {
stack.close();
}
}
public void createImage(int width, int height, int arrayLayers, int mipLevels, int format, int tiling, int usage, int flags, int memProperties, LongBuffer pTextureImage, PointerBuffer pTextureImageMemory) {
MemoryStack stack = MemoryStack.stackPush();
try {
VkImageCreateInfo imageInfo = VkImageCreateInfo.calloc(stack);
imageInfo.sType(14);
imageInfo.imageType(1);
imageInfo.extent().width(width);
imageInfo.extent().height(height);
imageInfo.extent().depth(1);
imageInfo.mipLevels(mipLevels);
imageInfo.arrayLayers(arrayLayers);
imageInfo.format(format);
imageInfo.tiling(tiling);
imageInfo.initialLayout(0);
imageInfo.usage(usage);
imageInfo.samples(1);
imageInfo.flags(flags);
imageInfo.pQueueFamilyIndices(stack.ints(Queue.getQueueFamilies().graphicsFamily, Queue.getQueueFamilies().computeFamily));
VmaAllocationCreateInfo allocationInfo = VmaAllocationCreateInfo.calloc(stack);
allocationInfo.requiredFlags(memProperties);
int result = Vma.vmaCreateImage(ALLOCATOR, imageInfo, allocationInfo, pTextureImage, pTextureImageMemory, (VmaAllocationInfo)null);
if (result != 0) {
Initializer.LOGGER.info(String.format("Failed to create image with size: %dx%d", width, height));
throw new RuntimeException("Failed to create image: %s".formatted(VkResult.decode(result)));
}
} catch (Throwable var17) {
if (stack != null) {
try {
stack.close();
} catch (Throwable var16) {
var17.addSuppressed(var16);
}
}
throw var17;
}
if (stack != null) {
stack.close();
}
}
public static void addImage(VulkanImage image) {
images.putIfAbsent(image.getId(), image);
deviceMemory += (long)image.size;
}
public static void MapAndCopy(long allocation, Consumer<PointerBuffer> consumer) {
MemoryStack stack = MemoryStack.stackPush();
try {
PointerBuffer data = stack.mallocPointer(1);
Vma.vmaMapMemory(ALLOCATOR, allocation, data);
consumer.accept(data);
Vma.vmaUnmapMemory(ALLOCATOR, allocation);
} catch (Throwable var7) {
if (stack != null) {
try {
stack.close();
} catch (Throwable var6) {
var7.addSuppressed(var6);
}
}
throw var7;
}
if (stack != null) {
stack.close();
}
}
public PointerBuffer Map(long allocation) {
PointerBuffer data = MemoryUtil.memAllocPointer(1);
Vma.vmaMapMemory(ALLOCATOR, allocation, data);
return data;
}
public static void freeBuffer(long buffer, long allocation) {
Vma.vmaDestroyBuffer(ALLOCATOR, buffer, allocation);
buffers.remove(buffer);
}
private static void freeBuffer(Buffer.BufferInfo bufferInfo) {
Vma.vmaDestroyBuffer(ALLOCATOR, bufferInfo.id(), bufferInfo.allocation());
if (bufferInfo.type() == MemoryType.Type.DEVICE_LOCAL) {
deviceMemory -= bufferInfo.bufferSize();
} else {
nativeMemory -= bufferInfo.bufferSize();
}
buffers.remove(bufferInfo.id());
}
public static void freeImage(long imageId, long allocation) {
Vma.vmaDestroyImage(ALLOCATOR, imageId, allocation);
VulkanImage image = (VulkanImage)images.remove(imageId);
deviceMemory -= (long)image.size;
}
public synchronized void addToFreeable(Buffer buffer) {
Buffer.BufferInfo bufferInfo = buffer.getBufferInfo();
this.checkBuffer(bufferInfo);
this.freeableBuffers[this.currentFrame].add(bufferInfo);
}
public synchronized void addToFreeable(VulkanImage image) {
this.freeableImages[this.currentFrame].add(image);
}
public synchronized void addFrameOp(Runnable runnable) {
this.frameOps[this.currentFrame].add(runnable);
}
public void doFrameOps(int frame) {
ObjectListIterator var2 = this.frameOps[frame].iterator();
while(var2.hasNext()) {
Runnable runnable = (Runnable)var2.next();
runnable.run();
}
this.frameOps[frame].clear();
}
private void freeBuffers(int frame) {
List<Buffer.BufferInfo> bufferList = this.freeableBuffers[frame];
for(Buffer.BufferInfo bufferInfo : bufferList) {
freeBuffer(bufferInfo);
}
bufferList.clear();
}
private void freeImages(int frame) {
List<VulkanImage> bufferList = this.freeableImages[frame];
for(VulkanImage image : bufferList) {
image.doFree();
}
bufferList.clear();
}
private void checkBuffer(Buffer.BufferInfo bufferInfo) {
if (buffers.get(bufferInfo.id()) == null) {
throw new RuntimeException("trying to free not present buffer");
}
}
private void freeSegments(int frame) {
ObjectArrayList<Pair<AreaBuffer, Integer>> list = this.segmentsToFree[frame];
ObjectListIterator var3 = list.iterator();
while(var3.hasNext()) {
Pair<AreaBuffer, Integer> pair = (Pair)var3.next();
((AreaBuffer)pair.first).setSegmentFree((Integer)pair.second);
}
list.clear();
}
public void addToFreeSegment(AreaBuffer areaBuffer, int offset) {
this.segmentsToFree[this.currentFrame].add(new Pair(areaBuffer, offset));
}
public int getNativeMemoryMB() {
return this.bytesInMb(nativeMemory);
}
public int getAllocatedDeviceMemoryMB() {
return this.bytesInMb(deviceMemory);
}
public int getDeviceMemoryMB() {
return this.bytesInMb(MemoryTypes.GPU_MEM.vkMemoryHeap.size());
}
int bytesInMb(long bytes) {
return (int)(bytes / 1048576L);
}
public String getHeapStats() {
MemoryStack stack = MemoryStack.stackPush();
String var8;
try {
VmaBudget.Buffer vmaBudgets = VmaBudget.calloc(DeviceManager.memoryProperties.memoryHeapCount(), stack);
Vma.vmaGetHeapBudgets(ALLOCATOR, vmaBudgets);
VmaBudget vmaBudget = (VmaBudget)vmaBudgets.get(MemoryTypes.GPU_MEM.vkMemoryType.heapIndex());
long usage = vmaBudget.usage();
long budget = vmaBudget.budget();
var8 = String.format("Device Memory Heap Usage: %d/%dMB", this.bytesInMb(usage), this.bytesInMb(budget));
} catch (Throwable var10) {
if (stack != null) {
try {
stack.close();
} catch (Throwable var9) {
var10.addSuppressed(var9);
}
}
throw var10;
}
if (stack != null) {
stack.close();
}
return var8;
}
}
Download file