working on colour rendering
This commit is contained in:
parent
2486270c96
commit
4e606e094a
8 changed files with 192 additions and 15 deletions
|
|
@ -13,6 +13,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
|||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VkCommandBufferSubmitInfo;
|
||||
import org.lwjgl.vulkan.VkSemaphoreSubmitInfo;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -53,7 +54,7 @@ public class Render {
|
|||
for(int i = 0; i < SwapChainImageCount; i++){
|
||||
RenderCompleteSemaphores[i] = new Semaphore(RendererContext);
|
||||
}
|
||||
sceneRender = new SceneRender();
|
||||
sceneRender = new SceneRender(RendererContext);
|
||||
}
|
||||
|
||||
private void RecordingStart(CommandPool commandPool, CommandBuffer commandBuffer){
|
||||
|
|
@ -66,7 +67,7 @@ public class Render {
|
|||
}
|
||||
|
||||
public void cleanup() {
|
||||
RendererContext.WaitIdle();
|
||||
RendererContext.GetDevice().waitIdle();
|
||||
sceneRender.cleanup();
|
||||
Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
|
||||
Arrays.asList(PresentCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
|
||||
|
|
@ -87,7 +88,7 @@ public class Render {
|
|||
if (ImageIndex < 0){
|
||||
return;
|
||||
}
|
||||
sceneRender.render(RendererContext,CommandBuffer,ImageIndex);
|
||||
sceneRender.Render(RendererContext,CommandBuffer,ImageIndex);
|
||||
RecordingStop(CommandBuffer);
|
||||
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
||||
swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,9 @@ public class PrimaryRuntime {
|
|||
if (ThreadsOpen > 0 || VulkanContext.VulkanLayersOpen > -1) {
|
||||
Logger.debug("Waiting to close Primary Thread, making sure vulkan has shut down properly first and Engine Threads are closed\nThreads Open:[{}]\nVulkan Layers Open:[{}]", ThreadsOpen, VulkanContext.VulkanLayersOpen < 0 ? "All processes closed and vulkan instance removed" : VulkanContext.VulkanLayersOpen);
|
||||
while ((ThreadsOpen > 0 || VulkanContext.VulkanLayersOpen > 0) && VulkanContext.VulkanLayersOpen > -1 && !CanClose) {
|
||||
|
||||
if (!DrawingThread.FetchRenderThread().isAlive() && !PrimaryThread.FetchMainThread().isAlive() && ThreadsOpen >0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger.debug("Closing Primary Thread, Thread: [{}]",Thread.currentThread().toString());
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
|||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VkDevice;
|
||||
import org.lwjgl.vulkan.VkDeviceCreateInfo;
|
||||
import org.lwjgl.vulkan.VkDeviceQueueCreateInfo;
|
||||
import org.lwjgl.vulkan.VkExtensionProperties;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.awt.*;
|
||||
|
|
@ -39,11 +36,21 @@ public class Device {
|
|||
.queueFamilyIndex(i)
|
||||
.pQueuePriorities(Priorities);
|
||||
}
|
||||
|
||||
var features13 = VkPhysicalDeviceVulkan13Features.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.dynamicRendering(true)
|
||||
.synchronization2(true);
|
||||
var features2 = VkPhysicalDeviceFeatures2.calloc(MemStack).sType$Default();
|
||||
features2.pNext(features13.address());
|
||||
|
||||
var DeviceCreateInfo = VkDeviceCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pNext(features2.address())
|
||||
.ppEnabledExtensionNames(RequiredExtensions)
|
||||
.pQueueCreateInfos(QueueCreationInfoBuffer);
|
||||
PointerBuffer pp = MemStack.mallocPointer(1);
|
||||
|
||||
vkCheck(vkCreateDevice(PhysDevice.GetPhysicalDevice(), DeviceCreateInfo, null, pp), "Failed to create device");
|
||||
VulkanDevice = new VkDevice(pp.get(0), PhysDevice.GetPhysicalDevice(), DeviceCreateInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import org.lwjgl.system.MemoryStack;
|
|||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
|
|
@ -55,7 +57,24 @@ public class Queue {
|
|||
super(vulkanContext, GetPresentQueueFamilyIndex(vulkanContext), QueueIndex);
|
||||
}
|
||||
private static int GetPresentQueueFamilyIndex(VulkanContext vulkanContext){
|
||||
return -1;
|
||||
int Index = -1;
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
var QueuePropertiesBuffer = vulkanContext.GetPhysicalDevice().GetQueueFamilyProperties();
|
||||
int QueueFamilyCount = QueuePropertiesBuffer.capacity();
|
||||
IntBuffer intBuffer = MemStack.mallocInt(1);
|
||||
for(int i = 0; i < QueueFamilyCount; i++){
|
||||
KHRSurface.vkGetPhysicalDeviceSurfaceSupportKHR(vulkanContext.GetPhysicalDevice().GetPhysicalDevice(), i, vulkanContext.GetSurface().GetVkSurface(), intBuffer);
|
||||
boolean SupportsPresentation = intBuffer.get(0) == VK_TRUE;
|
||||
if(SupportsPresentation){
|
||||
Index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Index < 0){
|
||||
throw new RuntimeException("Could Not Present Image Queue Family Index");
|
||||
}
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public class ImageView {
|
|||
public long GetVulkanImageView(){
|
||||
return VulkanImageView;
|
||||
}
|
||||
public long GetVulkanImage(){return VulkanImage;}
|
||||
|
||||
public static class ImageViewData{
|
||||
private int AspectMask;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,87 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
|
||||
|
||||
public class SceneRender {
|
||||
public SceneRender(){
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Render;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSynchronization2.VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSynchronization2.VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class SceneRender { //dynamic rendering;
|
||||
private final VkClearValue ClearValueColour;
|
||||
private VkRenderingAttachmentInfo.Buffer[] AttachmentInfoColour;
|
||||
private VkRenderingInfo[] RenderInfo;
|
||||
public SceneRender(VulkanContext vulkanContext){
|
||||
ClearValueColour = VkClearValue.calloc().color(c->c.float32(0,0.5f).float32(1,0.7f).float32(2,0.9f).float32(3,1.0f));
|
||||
AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour);
|
||||
}
|
||||
|
||||
public void Render(VulkanContext vulkanContext, CommandBuffer commandBuffer, int ImageIndex){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
SwapChain swapChain = vulkanContext.GetSwapChain();
|
||||
long SwapChainImage = swapChain.GetVulkanImageView(ImageIndex).GetVulkanImage();
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SwapChainImage,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
vkCmdBeginRendering(CommandHandle, RenderInfo[ImageIndex]);
|
||||
vkCmdEndRendering(CommandHandle);
|
||||
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SwapChainImage,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_2_NONE,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
private static VkRenderingInfo[] CreateRenderInfo(VulkanContext vulkanContext, VkRenderingAttachmentInfo.Buffer[] ColourAttachments){
|
||||
SwapChain swapChain = vulkanContext.GetSwapChain();
|
||||
int ImageCount = swapChain.GetImageCount();
|
||||
var Result = new VkRenderingInfo[ImageCount];
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VkExtent2D Extent = swapChain.GetSwapChainExtent();
|
||||
var RenderArea = VkRect2D.calloc(MemStack).extent(Extent);
|
||||
for(int i = 0; i < ImageCount; i++){
|
||||
var RenderInfo = VkRenderingInfo.calloc()
|
||||
.sType$Default()
|
||||
.renderArea(RenderArea)
|
||||
.layerCount(1)
|
||||
.pColorAttachments(ColourAttachments[i]);
|
||||
Result[i] = RenderInfo;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
private static VkRenderingAttachmentInfo.Buffer[] CreateColourAttachmentsInfo(VulkanContext vulkanContext, VkClearValue CLearValue){
|
||||
SwapChain swapChain = vulkanContext.GetSwapChain();
|
||||
int ImageCount = swapChain.GetImageCount();
|
||||
var result = new VkRenderingAttachmentInfo.Buffer[ImageCount];
|
||||
for(int i = 0; i < ImageCount; i++){
|
||||
var Attachments = VkRenderingAttachmentInfo.calloc(1)
|
||||
.sType$Default()
|
||||
.imageView(swapChain.GetVulkanImageView(i).GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.clearValue(CLearValue);
|
||||
result[i] = Attachments;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public void cleanup(){
|
||||
Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free);
|
||||
Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
ClearValueColour.free();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import net.halbear.Terrain4J.EngineCore.Display.Window;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Semaphore;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
|
|
@ -13,8 +15,7 @@ import java.nio.LongBuffer;
|
|||
import java.util.Arrays;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
public class SwapChain {
|
||||
private final ImageView[] ImageViewArray;
|
||||
|
|
@ -100,7 +101,41 @@ public class SwapChain {
|
|||
}
|
||||
|
||||
public int FetchNextImage(Device device, Semaphore ImageFetchSemaphore){
|
||||
return 0; //testing smth with the git rq
|
||||
int ImageIndex;
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
IntBuffer IntPointer = MemStack.mallocInt(1);
|
||||
int Error = KHRSwapchain.vkAcquireNextImageKHR(device.FetchVulkanDevice(), VulkanSwapChain, ~0L, ImageFetchSemaphore.GetSemaphore(), MemoryUtil.NULL, IntPointer);
|
||||
if (Error == KHRSwapchain.VK_ERROR_OUT_OF_DATE_KHR){
|
||||
return -1;
|
||||
}
|
||||
else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){
|
||||
Logger.warn("Suboptimal surface properties match, not fatal");
|
||||
} else if (Error != VK_SUCCESS){
|
||||
throw new RuntimeException("Failed to fetch next image in the swapchain: " + Error);
|
||||
}
|
||||
ImageIndex = IntPointer.get(0);
|
||||
}
|
||||
return ImageIndex;
|
||||
}
|
||||
public boolean PresentImage(Queue queue,Semaphore RenderCompleteSemaphores, int ImageIndex){
|
||||
boolean resize = false;
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VkPresentInfoKHR Present = VkPresentInfoKHR.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pWaitSemaphores(MemStack.longs(RenderCompleteSemaphores.GetSemaphore()))
|
||||
.swapchainCount(1)
|
||||
.pSwapchains(MemStack.longs(VulkanSwapChain))
|
||||
.pImageIndices(MemStack.ints(ImageIndex));
|
||||
int Error = KHRSwapchain.vkQueuePresentKHR(queue.GetVulkanQueue(), Present);
|
||||
if (Error == KHRSwapchain.VK_ERROR_OUT_OF_DATE_KHR){
|
||||
resize = true;
|
||||
} else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){
|
||||
Logger.warn("Suboptimal surface properties match, not fatal");
|
||||
} else if (Error != VK_SUCCESS){
|
||||
throw new RuntimeException("failed to present KHR: " + Error);
|
||||
}
|
||||
}
|
||||
return resize;
|
||||
}
|
||||
|
||||
public void cleanup(Device device){
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Util;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VkCommandBuffer;
|
||||
import org.lwjgl.vulkan.VkDependencyInfo;
|
||||
import org.lwjgl.vulkan.VkImageMemoryBarrier;
|
||||
import org.lwjgl.vulkan.VkImageMemoryBarrier2;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2;
|
||||
|
||||
public class VulkanUtils {
|
||||
public static final int MAX_IN_FLIGHT = 2;
|
||||
|
|
@ -21,7 +29,31 @@ public class VulkanUtils {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void ImageBarrier(MemoryStack MemStack, VkCommandBuffer CommandHandle, long Image, int OldLayout,
|
||||
int NewLayout, long SrcStage, long DstStage, long SrcAccess, long DstAccess,
|
||||
int AspectMask){
|
||||
var ImageBarrier = VkImageMemoryBarrier2.calloc(1, MemStack)
|
||||
.sType$Default()
|
||||
.oldLayout(OldLayout)
|
||||
.newLayout(NewLayout)
|
||||
.srcStageMask(SrcStage)
|
||||
.dstStageMask(DstStage)
|
||||
.srcAccessMask(SrcAccess)
|
||||
.dstAccessMask(DstAccess)
|
||||
.srcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED)
|
||||
.dstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED)
|
||||
.subresourceRange(it -> it
|
||||
.aspectMask(AspectMask)
|
||||
.baseMipLevel(0)
|
||||
.levelCount(VK_REMAINING_MIP_LEVELS)
|
||||
.baseArrayLayer(0)
|
||||
.layerCount(VK_REMAINING_ARRAY_LAYERS))
|
||||
.image(Image);
|
||||
VkDependencyInfo DependencyInfo = VkDependencyInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pImageMemoryBarriers(ImageBarrier);
|
||||
vkCmdPipelineBarrier2(CommandHandle, DependencyInfo);
|
||||
}
|
||||
public static void vkCheck(int Error, String ErrorMessage) {
|
||||
if (Error != VK_SUCCESS) {
|
||||
String ErrorCode = switch (Error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue