diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java index d62a0ed..b9967de 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java @@ -2,11 +2,48 @@ package net.halbear.Terrain4J.EngineCore.Display; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandPool; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Fence; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Semaphore; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender; +import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; public class Render { - private final VulkanContext RendererContext; + + private final CommandBuffer[] CommandBuffers; + private final CommandPool[] CommandPools; + private final Fence[] Fences; + private final Queue.GraphicsQueue GraphicsQueue; + private final Semaphore[] PresentCompleteSemaphores; + private final Queue.PresentQueue PresentQueue; + private final Semaphore[] RenderCompleteSemaphores; + private final SceneRender sceneRender; + private int CurrentFrame; + private final VulkanContext RendererContext; + public Render(EngineInstance engineInstance) { RendererContext = new VulkanContext(engineInstance.window()); + + GraphicsQueue = new Queue.GraphicsQueue(RendererContext, 0); + PresentQueue = new Queue.PresentQueue(RendererContext, 0); + CommandPools= new CommandPool[VulkanUtils.MAX_IN_FLIGHT]; + CommandBuffers= new CommandBuffer[VulkanUtils.MAX_IN_FLIGHT]; + Fences= new Fence[VulkanUtils.MAX_IN_FLIGHT]; + PresentCompleteSemaphores = new Semaphore[VulkanUtils.MAX_IN_FLIGHT]; + int SwapChainImageCount = RendererContext.GetSwapChain().GetImageCount(); + RenderCompleteSemaphores = new Semaphore[SwapChainImageCount]; + for(int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++){ + CommandPools[i] = new CommandPool(RendererContext, GraphicsQueue.GetQueueFamilyIndex(), false); + CommandBuffers[i] = new CommandBuffer(RendererContext, CommandPools[i],true, true); + PresentCompleteSemaphores[i] = new Semaphore(RendererContext); + Fences[i] = new Fence(RendererContext, true); + } + for(int i = 0; i < SwapChainImageCount; i++){ + RenderCompleteSemaphores[i] = new Semaphore(RendererContext); + } + sceneRender = new SceneRender(); } public void cleanup() { RendererContext.cleanup(); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java index 973c7b4..ac1e4e6 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java @@ -35,6 +35,9 @@ public class VulkanContext { Logger.debug("Render Thread Finished ending Vulkan Processes\nVulkan Layers Open:[{}]", VulkanContext.VulkanLayersOpen < 0 ? "All processes closed and vulkan instance removed" : VulkanContext.VulkanLayersOpen); VulkanLayersOpen--; } + public SwapChain GetSwapChain(){ + return swapChain; + } public Device GetDevice(){ return device; } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/CommandBuffer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/CommandBuffer.java index 8fb9b1a..9ece880 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/CommandBuffer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/CommandBuffer.java @@ -1,6 +1,8 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers; import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Fence; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.*; @@ -64,6 +66,20 @@ public class CommandBuffer { vkCheck(vkBeginCommandBuffer(VulkanCommandBuffer, CommandBufferInfo),"Failed to begin Command Buffer"); } } + + public void SubmitAndWait(VulkanContext vulkanContext, Queue queue){ + Fence fence = new Fence(vulkanContext, true); + fence.Reset(vulkanContext); + try(var MemStack = MemoryStack.stackPush()){ + var Commands = VkCommandBufferSubmitInfo.calloc(1, MemStack) + .sType$Default() + .commandBuffer(VulkanCommandBuffer); + queue.Sumbit(Commands, null, null, fence); + } + fence.FenceWait(vulkanContext); + fence.cleanup(vulkanContext); + } + public record InheritanceInfo(int DepthFormat, int[] ColourFormats, int RasterizationSamples){} public void cleanup(VulkanContext vulkanContext,CommandPool commandPool){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/Queues/Queue.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/Queues/Queue.java index 53f4b40..5186a1d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/Queues/Queue.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DeviceLayers/Queues/Queue.java @@ -1,12 +1,13 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues; import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Fence; import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; -import org.lwjgl.vulkan.VkQueue; -import org.lwjgl.vulkan.VkQueueFamilyProperties; +import org.lwjgl.vulkan.*; import org.tinylog.Logger; +import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck; import static org.lwjgl.vulkan.VK13.*; public class Queue { @@ -24,6 +25,7 @@ public class Queue { VulkanQueue = new VkQueue(Queue, vkContext.GetDevice().FetchVulkanDevice()); } } + public int GetQueueFamilyIndex(){ return QueueFamilyIndex; } @@ -34,6 +36,29 @@ public class Queue { vkQueueWaitIdle(VulkanQueue); } + public void Sumbit(VkCommandBufferSubmitInfo.Buffer CommandBuffers, VkSemaphoreSubmitInfo.Buffer WaitSemaphores, VkSemaphoreSubmitInfo.Buffer SignalSemaphores, Fence fence){ + try(var MemStack = MemoryStack.stackPush()){ + var SubmitInfo = VkSubmitInfo2.calloc(1, MemStack) + .sType$Default() + .pCommandBufferInfos(CommandBuffers) + .pSignalSemaphoreInfos(SignalSemaphores); + if (WaitSemaphores != null){ + SubmitInfo.pWaitSemaphoreInfos(WaitSemaphores); + } + long FenceHandle = fence != null ? fence.GetVulkanFence() : VK_NULL_HANDLE; + vkCheck(vkQueueSubmit2(VulkanQueue, SubmitInfo, FenceHandle),"Failed to submit command queue"); + } + } + + public static class PresentQueue extends Queue{ + public PresentQueue(VulkanContext vulkanContext, int QueueIndex){ + super(vulkanContext, GetPresentQueueFamilyIndex(vulkanContext), QueueIndex); + } + private static int GetPresentQueueFamilyIndex(VulkanContext vulkanContext){ + return -1; + } + } + public static class GraphicsQueue extends Queue { public GraphicsQueue(VulkanContext vulkanContext, int QueueIndex){ super(vulkanContext, GetGraphicsQueueFamilyIndex(vulkanContext),QueueIndex); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java index 05caf71..b04edff 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java @@ -1,4 +1,7 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen; public class SceneRender { + public SceneRender(){ + + } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java index 0f5df88..12c2073 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java @@ -5,6 +5,7 @@ import java.util.Locale; import static org.lwjgl.vulkan.VK10.*; public class VulkanUtils { + public static final int MAX_IN_FLIGHT = 2; public enum OSType {WINDOWS, MACOS, LINUX, UNSUPPORTED} public static OSType getOS() { OSType result;