diff --git a/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java b/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java index 7fbbe1f..779b884 100644 --- a/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java +++ b/src/main/java/me/cortex/vulkanite/acceleration/AccelerationTLASManager.java @@ -22,7 +22,6 @@ import org.lwjgl.vulkan.*; import java.util.*; -import java.util.concurrent.LinkedBlockingDeque; import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; @@ -335,7 +334,11 @@ private final class TLASSectionManager extends TLASGeometryManager { private int setCapacity = 0; private record DescUpdateJob(int binding, int dstArrayElement, List buffers) {} - private final LinkedBlockingDeque descUpdateJobs = new LinkedBlockingDeque<>(); + private record ArenaDeallocJob(int index, int count, List geometryBuffers) {} + + private final Deque descUpdateJobs = new ArrayDeque<>(); + private final Deque arenaDeallocJobs = new ArrayDeque<>(); + private final Deque descPoolsToRelease = new ArrayDeque<>(); public void resizeBindlessSet(int newSize, VFence fence) { if (geometryBufferSetLayout == null) { @@ -364,13 +367,7 @@ public void resizeBindlessSet(int newSize, VFence fence) { vkUpdateDescriptorSets(context.device, null, setCopy); } - // This breaks the shit out of it - // context.sync.addCallback(fence, () -> { - // geometryBufferDescPool.free(); - // }); - - vkDeviceWaitIdle(context.device); - geometryBufferDescPool.free(); + descPoolsToRelease.add(geometryBufferDescPool); } geometryBufferDescPool = newGeometryBufferDescPool; @@ -396,6 +393,9 @@ public void setGeometryUpdateMemory(VCmdBuff cmd, VFence fence, VkAccelerationSt dub.buffer(job.binding, job.dstArrayElement, job.buffers); } dub.apply(); + + // Queue up the arena dealloc jobs to be done after the fence is done + Vulkanite.INSTANCE.addSyncedCallback(() -> { fenceTick(); }); } //TODO: mixinto RenderSection and add a reference to a holder for us, its much faster than a hashmap @@ -415,6 +415,17 @@ private Holder(int id, RenderSection section) { Map tmp = new HashMap<>(); + public void fenceTick() { + while (!arenaDeallocJobs.isEmpty()) { + var job = arenaDeallocJobs.poll(); + arena.free(job.index, job.count); + job.geometryBuffers.forEach(buffer -> buffer.free()); + } + while (!descPoolsToRelease.isEmpty()) { + descPoolsToRelease.poll().free(); + } + } + public void update(AccelerationBlasBuilder.BLASBuildResult result) { var data = result.data(); var holder = tmp.computeIfAbsent(data.section().getPosition(), a -> new Holder(alloc(), data.section())); @@ -424,8 +435,7 @@ public void update(AccelerationBlasBuilder.BLASBuildResult result) { holder.structure = result.structure(); if (holder.geometryIndex != -1) { - arena.free(holder.geometryIndex, holder.geometryBuffers.size()); - holder.geometryBuffers.forEach(buffer -> Vulkanite.INSTANCE.addSyncedCallback(buffer::free)); + arenaDeallocJobs.add(new ArenaDeallocJob(holder.geometryIndex, holder.geometryBuffers.size(), holder.geometryBuffers)); } holder.geometryBuffers = data.geometryBuffers(); holder.geometryIndex = arena.allocate(holder.geometryBuffers.size()); @@ -461,9 +471,8 @@ public void remove(RenderSection section) { } if (holder.geometryIndex != -1) { - arena.free(holder.geometryIndex, holder.geometryBuffers.size()); + arenaDeallocJobs.add(new ArenaDeallocJob(holder.geometryIndex, holder.geometryBuffers.size(), holder.geometryBuffers)); } - holder.geometryBuffers.forEach(buffer -> Vulkanite.INSTANCE.addSyncedCallback(buffer::free)); } } diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java b/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java index 692be8d..4804e83 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java @@ -22,6 +22,7 @@ import static org.lwjgl.opengl.EXTMemoryObjectFD.GL_HANDLE_TYPE_OPAQUE_FD_EXT; import static org.lwjgl.opengl.EXTMemoryObjectFD.glImportMemoryFdEXT; import static org.lwjgl.opengl.EXTMemoryObjectWin32.glImportMemoryWin32HandleEXT; +import static org.lwjgl.opengl.EXTMemoryObjectWin32.GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT; import static org.lwjgl.opengl.EXTSemaphoreWin32.GL_HANDLE_TYPE_OPAQUE_WIN32_EXT; import static org.lwjgl.opengl.GL11C.*; import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D; @@ -35,10 +36,10 @@ import static org.lwjgl.vulkan.VK10.*; import static org.lwjgl.vulkan.VK11.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; import static org.lwjgl.vulkan.VK11.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; -import static org.lwjgl.vulkan.VK12.VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; +import static org.lwjgl.vulkan.VK11.VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT; public class MemoryManager { - private static final int EXTERNAL_MEMORY_HANDLE_TYPE = Vulkanite.IS_WINDOWS?VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; + private static final int EXTERNAL_MEMORY_HANDLE_TYPE = Vulkanite.IS_WINDOWS?VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; private final VkDevice device; private final VmaAllocator allocator; private final boolean hasDeviceAddresses; @@ -72,7 +73,7 @@ public static int acquire(VmaAllocator.Allocation allocation, VkDevice device) { _CHECK_(vkGetMemoryWin32HandleKHR(device, VkMemoryGetWin32HandleInfoKHR.calloc(stack) .sType$Default() .memory(vkMemory) - .handleType(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT), pb)); + .handleType(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT), pb)); nativeHandle = pb.get(0); } else { IntBuffer pb = stack.callocInt(1); @@ -93,7 +94,7 @@ public static int acquire(VmaAllocator.Allocation allocation, VkDevice device) { if (Vulkanite.IS_WINDOWS) { glImportMemoryWin32HandleEXT(newMemoryObject, memorySize, - GL_HANDLE_TYPE_OPAQUE_WIN32_EXT, nativeHandle); + GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT, nativeHandle); _CHECK_GL_ERROR_(); } else { glImportMemoryFdEXT(newMemoryObject, memorySize, @@ -131,16 +132,16 @@ public static void release(long memory) { glDeleteMemoryObjectsEXT(tracked.desc.glMemoryObj); _CHECK_GL_ERROR_(); if (Vulkanite.IS_WINDOWS) { - if (!Kernel32.INSTANCE.CloseHandle(new WinNT.HANDLE(new Pointer(tracked.desc.handle)))) { - int error = Kernel32.INSTANCE.GetLastError(); - System.err.println("STATE MIGHT BE BROKEN! Failed to close handle: " + error); - // throw new IllegalStateException(); - } + // if (!Kernel32.INSTANCE.CloseHandle(new WinNT.HANDLE(new Pointer(tracked.desc.handle)))) { + // int error = Kernel32.INSTANCE.GetLastError(); + // System.err.println("STATE MIGHT BE BROKEN! Failed to close handle: " + error); + // throw new IllegalStateException(); + // } } else { int code = 0; if ((code = LibC.INSTANCE.close((int) tracked.desc.handle)) != 0) { System.err.println("STATE MIGHT BE BROKEN! Failed to close FD: " + code); - // throw new IllegalStateException(); + throw new IllegalStateException(); } } MEMORY_TO_HANDLES.remove(memory);