Merge branch 'Vulkan' into liteCraft
commit
a5817d31be
|
@ -19,6 +19,7 @@ import org.lwjgl.vulkan.*;
|
||||||
import com.github.hydos.ginger.engine.common.info.RenderAPI;
|
import com.github.hydos.ginger.engine.common.info.RenderAPI;
|
||||||
import com.github.hydos.ginger.engine.common.io.Window;
|
import com.github.hydos.ginger.engine.common.io.Window;
|
||||||
import com.github.hydos.ginger.engine.vulkan.utils.*;
|
import com.github.hydos.ginger.engine.vulkan.utils.*;
|
||||||
|
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils.Pipeline;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author hydos06
|
* @author hydos06
|
||||||
|
@ -265,7 +266,7 @@ public class VulkanStarter
|
||||||
return new VkCommandBuffer(commandBuffer, device);
|
return new VkCommandBuffer(commandBuffer, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Swapchain
|
public static class Swapchain
|
||||||
{
|
{
|
||||||
long swapchainHandle;
|
long swapchainHandle;
|
||||||
long[] images;
|
long[] images;
|
||||||
|
@ -313,13 +314,13 @@ public class VulkanStarter
|
||||||
int currentHeight = currentExtent.height();
|
int currentHeight = currentExtent.height();
|
||||||
if (currentWidth != -1 && currentHeight != -1)
|
if (currentWidth != -1 && currentHeight != -1)
|
||||||
{
|
{
|
||||||
width = currentWidth;
|
Window.width = currentWidth;
|
||||||
height = currentHeight;
|
Window.height = currentHeight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = newWidth;
|
Window.width = newWidth;
|
||||||
height = newHeight;
|
Window.height = newHeight;
|
||||||
}
|
}
|
||||||
int preTransform;
|
int preTransform;
|
||||||
if ((surfCaps.supportedTransforms() & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) != 0)
|
if ((surfCaps.supportedTransforms() & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) != 0)
|
||||||
|
@ -346,8 +347,8 @@ public class VulkanStarter
|
||||||
.clipped(true)
|
.clipped(true)
|
||||||
.compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
.compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
||||||
swapchainCI.imageExtent()
|
swapchainCI.imageExtent()
|
||||||
.width(width)
|
.width(Window.getWidth())
|
||||||
.height(height);
|
.height(Window.getHeight());
|
||||||
LongBuffer pSwapChain = memAllocLong(1);
|
LongBuffer pSwapChain = memAllocLong(1);
|
||||||
err = vkCreateSwapchainKHR(device, swapchainCI, null, pSwapChain);
|
err = vkCreateSwapchainKHR(device, swapchainCI, null, pSwapChain);
|
||||||
swapchainCI.free();
|
swapchainCI.free();
|
||||||
|
@ -415,7 +416,7 @@ public class VulkanStarter
|
||||||
.samples(VK_SAMPLE_COUNT_1_BIT)
|
.samples(VK_SAMPLE_COUNT_1_BIT)
|
||||||
.tiling(VK_IMAGE_TILING_OPTIMAL)
|
.tiling(VK_IMAGE_TILING_OPTIMAL)
|
||||||
.usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
|
.usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
|
||||||
imageCreateInfo.extent().width(width).height(height).depth(1);
|
imageCreateInfo.extent().width(Window.getWidth()).height(Window.getHeight()).depth(1);
|
||||||
VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.calloc()
|
VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.calloc()
|
||||||
.sType(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
.sType(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
||||||
VkImageViewCreateInfo depthStencilViewCreateInfo = VkImageViewCreateInfo.calloc()
|
VkImageViewCreateInfo depthStencilViewCreateInfo = VkImageViewCreateInfo.calloc()
|
||||||
|
@ -848,12 +849,6 @@ public class VulkanStarter
|
||||||
return descriptorSetLayout;
|
return descriptorSetLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Pipeline
|
|
||||||
{
|
|
||||||
long pipeline;
|
|
||||||
long layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Pipeline createPipeline(VkDevice device, long renderPass, VkPipelineVertexInputStateCreateInfo vi, long descriptorSetLayout) throws IOException
|
private static Pipeline createPipeline(VkDevice device, long renderPass, VkPipelineVertexInputStateCreateInfo vi, long descriptorSetLayout) throws IOException
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -964,98 +959,11 @@ public class VulkanStarter
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static VkCommandBuffer[] createRenderCommandBuffers(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height,
|
|
||||||
Pipeline pipeline, long descriptorSet, long verticesBuf)
|
|
||||||
{
|
|
||||||
// Create the render command buffers (one command buffer per framebuffer image)
|
|
||||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc()
|
|
||||||
.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO)
|
|
||||||
.commandPool(commandPool)
|
|
||||||
.level(VK_COMMAND_BUFFER_LEVEL_PRIMARY)
|
|
||||||
.commandBufferCount(framebuffers.length);
|
|
||||||
PointerBuffer pCommandBuffer = memAllocPointer(framebuffers.length);
|
|
||||||
int err = vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
|
|
||||||
if (err != VK_SUCCESS)
|
|
||||||
{ throw new AssertionError("Failed to allocate render command buffer: " + VKUtils.translateVulkanResult(err)); }
|
|
||||||
VkCommandBuffer[] renderCommandBuffers = new VkCommandBuffer[framebuffers.length];
|
|
||||||
for (int i = 0; i < framebuffers.length; i++)
|
|
||||||
{ renderCommandBuffers[i] = new VkCommandBuffer(pCommandBuffer.get(i), device); }
|
|
||||||
memFree(pCommandBuffer);
|
|
||||||
cmdBufAllocateInfo.free();
|
|
||||||
// Create the command buffer begin structure
|
|
||||||
VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc()
|
|
||||||
.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
|
|
||||||
// Specify clear color (cornflower blue)
|
|
||||||
VkClearValue.Buffer clearValues = VkClearValue.calloc(2);
|
|
||||||
clearValues.get(0).color()
|
|
||||||
.float32(0, 100 / 255.0f)
|
|
||||||
.float32(1, 149 / 255.0f)
|
|
||||||
.float32(2, 237 / 255.0f)
|
|
||||||
.float32(3, 1.0f);
|
|
||||||
// Specify clear depth-stencil
|
|
||||||
clearValues.get(1).depthStencil().depth(1.0f).stencil(0);
|
|
||||||
// Specify everything to begin a render pass
|
|
||||||
VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.calloc()
|
|
||||||
.sType(VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO)
|
|
||||||
.renderPass(renderPass)
|
|
||||||
.pClearValues(clearValues);
|
|
||||||
VkRect2D renderArea = renderPassBeginInfo.renderArea();
|
|
||||||
renderArea.offset().set(0, 0);
|
|
||||||
renderArea.extent().set(width, height);
|
|
||||||
for (int i = 0; i < renderCommandBuffers.length; ++i)
|
|
||||||
{
|
|
||||||
// Set target frame buffer
|
|
||||||
renderPassBeginInfo.framebuffer(framebuffers[i]);
|
|
||||||
err = vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
|
|
||||||
if (err != VK_SUCCESS)
|
|
||||||
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(err)); }
|
|
||||||
vkCmdBeginRenderPass(renderCommandBuffers[i], renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
|
||||||
// Update dynamic viewport state
|
|
||||||
VkViewport.Buffer viewport = VkViewport.calloc(1)
|
|
||||||
.height(height)
|
|
||||||
.width(width)
|
|
||||||
.minDepth(0.0f)
|
|
||||||
.maxDepth(1.0f);
|
|
||||||
vkCmdSetViewport(renderCommandBuffers[i], 0, viewport);
|
|
||||||
viewport.free();
|
|
||||||
// Update dynamic scissor state
|
|
||||||
VkRect2D.Buffer scissor = VkRect2D.calloc(1);
|
|
||||||
scissor.extent().set(width, height);
|
|
||||||
scissor.offset().set(0, 0);
|
|
||||||
vkCmdSetScissor(renderCommandBuffers[i], 0, scissor);
|
|
||||||
scissor.free();
|
|
||||||
// Bind descriptor sets describing shader binding points
|
|
||||||
LongBuffer descriptorSets = memAllocLong(1).put(0, descriptorSet);
|
|
||||||
vkCmdBindDescriptorSets(renderCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, descriptorSets, null);
|
|
||||||
memFree(descriptorSets);
|
|
||||||
// Bind the rendering pipeline (including the shaders)
|
|
||||||
vkCmdBindPipeline(renderCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
|
|
||||||
// Bind triangle vertices
|
|
||||||
LongBuffer offsets = memAllocLong(1);
|
|
||||||
offsets.put(0, 0L);
|
|
||||||
LongBuffer pBuffers = memAllocLong(1);
|
|
||||||
pBuffers.put(0, verticesBuf);
|
|
||||||
vkCmdBindVertexBuffers(renderCommandBuffers[i], 0, pBuffers, offsets);
|
|
||||||
memFree(pBuffers);
|
|
||||||
memFree(offsets);
|
|
||||||
// Draw triangle
|
|
||||||
vkCmdDraw(renderCommandBuffers[i], 6, 1, 0, 0);
|
|
||||||
vkCmdEndRenderPass(renderCommandBuffers[i]);
|
|
||||||
err = vkEndCommandBuffer(renderCommandBuffers[i]);
|
|
||||||
if (err != VK_SUCCESS)
|
|
||||||
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(err)); }
|
|
||||||
}
|
|
||||||
renderPassBeginInfo.free();
|
|
||||||
clearValues.free();
|
|
||||||
cmdBufInfo.free();
|
|
||||||
return renderCommandBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateUbo(VkDevice device, UboDescriptor ubo, float angle)
|
private static void updateUbo(VkDevice device, UboDescriptor ubo, float angle)
|
||||||
{ //a UBO is a uniform buffer object
|
{ //a UBO is a uniform buffer object
|
||||||
Matrix4f m = new Matrix4f()
|
Matrix4f m = new Matrix4f()
|
||||||
.scale(1, -1, 1) // <- correcting viewport transformation (what Direct3D does, too)
|
.scale(1, -1, 1) // <- correcting viewport transformation (what Direct3D does, too)
|
||||||
.perspective((float) Math.toRadians(45.0f), (float) width / height, 0.1f, 10.0f, true)
|
.perspective((float) Math.toRadians(45.0f), (float) Window.getWidth() / Window.getHeight(), 0.1f, 10.0f, true)
|
||||||
.lookAt(0, 1, 3,
|
.lookAt(0, 1, 3,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
0, 1, 0)
|
0, 1, 0)
|
||||||
|
@ -1077,29 +985,19 @@ public class VulkanStarter
|
||||||
private static Swapchain swapchain;
|
private static Swapchain swapchain;
|
||||||
private static long[] framebuffers;
|
private static long[] framebuffers;
|
||||||
private static VkCommandBuffer[] renderCommandBuffers;
|
private static VkCommandBuffer[] renderCommandBuffers;
|
||||||
private static int width, height;
|
|
||||||
private static DepthStencil depthStencil;
|
private static DepthStencil depthStencil;
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException
|
public static void main(String[] args) throws IOException
|
||||||
{
|
{
|
||||||
Window.create(1200, 600, "Vulkan Ginger3D", 60, RenderAPI.Vulkan);
|
Window.create(1200, 600, "Vulkan Ginger3D", 60, RenderAPI.Vulkan);
|
||||||
width = Window.getWidth();
|
|
||||||
height = Window.getHeight();
|
|
||||||
/* Look for instance extensions */
|
/* Look for instance extensions */
|
||||||
PointerBuffer requiredExtensions = glfwGetRequiredInstanceExtensions();
|
PointerBuffer requiredExtensions = glfwGetRequiredInstanceExtensions();
|
||||||
if (requiredExtensions == null)
|
if (requiredExtensions == null)
|
||||||
{ throw new AssertionError("Failed to find list of required Vulkan extensions"); }
|
{ throw new AssertionError("Failed to find list of required Vulkan extensions"); }
|
||||||
// Create the Vulkan instance
|
// Create the Vulkan instance
|
||||||
final VkInstance instance = VKLoader.createInstance(requiredExtensions);
|
final VkInstance instance = VKLoader.createInstance(requiredExtensions);
|
||||||
final VkDebugReportCallbackEXT debugCallback = new VkDebugReportCallbackEXT()
|
VKUtils.setupVulkanDebugCallback();
|
||||||
{
|
final long debugCallbackHandle = VKUtils.startVulkanDebugging(instance, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, VKConstants.debugCallback);
|
||||||
public int invoke(int flags, int objectType, long object, long location, int messageCode, long pLayerPrefix, long pMessage, long pUserData)
|
|
||||||
{
|
|
||||||
System.err.println("ERROR OCCURED: " + VkDebugReportCallbackEXT.getString(pMessage));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
final long debugCallbackHandle = VKUtils.startVulkanDebugging(instance, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, debugCallback);
|
|
||||||
final VkPhysicalDevice physicalDevice = getFirstPhysicalDevice(instance);
|
final VkPhysicalDevice physicalDevice = getFirstPhysicalDevice(instance);
|
||||||
final DeviceAndGraphicsQueueFamily deviceAndGraphicsQueueFamily = createDeviceAndGetGraphicsQueueFamily(physicalDevice);
|
final DeviceAndGraphicsQueueFamily deviceAndGraphicsQueueFamily = createDeviceAndGetGraphicsQueueFamily(physicalDevice);
|
||||||
final VkDevice device = deviceAndGraphicsQueueFamily.device;
|
final VkDevice device = deviceAndGraphicsQueueFamily.device;
|
||||||
|
@ -1150,7 +1048,7 @@ public class VulkanStarter
|
||||||
long oldChain = swapchain != null ? swapchain.swapchainHandle : VK_NULL_HANDLE;
|
long oldChain = swapchain != null ? swapchain.swapchainHandle : VK_NULL_HANDLE;
|
||||||
// Create the swapchain (this will also add a memory barrier to initialize the framebuffer images)
|
// Create the swapchain (this will also add a memory barrier to initialize the framebuffer images)
|
||||||
swapchain = createSwapChain(device, physicalDevice, surface, oldChain, setupCommandBuffer,
|
swapchain = createSwapChain(device, physicalDevice, surface, oldChain, setupCommandBuffer,
|
||||||
width, height, colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.colorSpace);
|
Window.getWidth(), Window.getHeight(), colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.colorSpace);
|
||||||
// Create depth-stencil image
|
// Create depth-stencil image
|
||||||
depthStencil = createDepthStencil(device, memoryProperties, colorAndDepthFormatAndSpace.depthFormat, setupCommandBuffer);
|
depthStencil = createDepthStencil(device, memoryProperties, colorAndDepthFormatAndSpace.depthFormat, setupCommandBuffer);
|
||||||
err = vkEndCommandBuffer(setupCommandBuffer);
|
err = vkEndCommandBuffer(setupCommandBuffer);
|
||||||
|
@ -1161,11 +1059,11 @@ public class VulkanStarter
|
||||||
if (framebuffers != null)
|
if (framebuffers != null)
|
||||||
{ for (int i = 0; i < framebuffers.length; i++)
|
{ for (int i = 0; i < framebuffers.length; i++)
|
||||||
vkDestroyFramebuffer(device, framebuffers[i], null); }
|
vkDestroyFramebuffer(device, framebuffers[i], null); }
|
||||||
framebuffers = createFramebuffers(device, swapchain, renderPass, width, height, depthStencil);
|
framebuffers = createFramebuffers(device, swapchain, renderPass, Window.getWidth(), Window.getHeight(), depthStencil);
|
||||||
// Create render command buffers
|
// Create render command buffers
|
||||||
if (renderCommandBuffers != null)
|
if (renderCommandBuffers != null)
|
||||||
{ vkResetCommandPool(device, renderCommandPool, VKUtils.VK_FLAGS_NONE); }
|
{ vkResetCommandPool(device, renderCommandPool, VKUtils.VK_FLAGS_NONE); }
|
||||||
renderCommandBuffers = createRenderCommandBuffers(device, renderCommandPool, framebuffers, renderPass, width, height, pipeline, descriptorSet,
|
renderCommandBuffers = VKUtils.initRenderCommandBuffers(device, renderCommandPool, framebuffers, renderPass, Window.getWidth(), Window.getHeight(), pipeline, descriptorSet,
|
||||||
vertices.verticesBuf);
|
vertices.verticesBuf);
|
||||||
mustRecreate = false;
|
mustRecreate = false;
|
||||||
}
|
}
|
||||||
|
@ -1179,8 +1077,6 @@ public class VulkanStarter
|
||||||
if (width <= 0 || height <= 0)
|
if (width <= 0 || height <= 0)
|
||||||
return;
|
return;
|
||||||
swapchainRecreator.mustRecreate = true;
|
swapchainRecreator.mustRecreate = true;
|
||||||
VulkanStarter.width = width;
|
|
||||||
VulkanStarter.height = height;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
glfwSetFramebufferSizeCallback(Window.getWindow(), framebufferSizeCallback);
|
glfwSetFramebufferSizeCallback(Window.getWindow(), framebufferSizeCallback);
|
||||||
|
@ -1273,7 +1169,5 @@ public class VulkanStarter
|
||||||
keyCallback.free();
|
keyCallback.free();
|
||||||
glfwDestroyWindow(Window.getWindow());
|
glfwDestroyWindow(Window.getWindow());
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
// We don't bother disposing of all Vulkan resources.
|
|
||||||
// Let the OS process manager take care of it.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,7 +31,8 @@ public class Window
|
||||||
{ return fullscreen; }
|
{ return fullscreen; }
|
||||||
|
|
||||||
public static RenderAPI renderAPI;
|
public static RenderAPI renderAPI;
|
||||||
private static int width, height;
|
public static int width;
|
||||||
|
public static int height;
|
||||||
private static String title;
|
private static String title;
|
||||||
private static long window;
|
private static long window;
|
||||||
private static Vector3f backgroundColour = new Vector3f(118f, 215f, 234f);
|
private static Vector3f backgroundColour = new Vector3f(118f, 215f, 234f);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.github.hydos.ginger.engine.opengl.render.tools;
|
package com.github.hydos.ginger.engine.common.tools;
|
||||||
|
|
||||||
import static org.lwjgl.BufferUtils.createByteBuffer;
|
import static org.lwjgl.BufferUtils.createByteBuffer;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.github.hydos.ginger.engine.opengl.render.tools;
|
package com.github.hydos.ginger.engine.common.tools;
|
||||||
|
|
||||||
import org.joml.*;
|
import org.joml.*;
|
||||||
|
|
|
@ -12,9 +12,9 @@ import com.github.hydos.ginger.engine.common.elements.objects.Player;
|
||||||
import com.github.hydos.ginger.engine.common.font.*;
|
import com.github.hydos.ginger.engine.common.font.*;
|
||||||
import com.github.hydos.ginger.engine.common.io.Window;
|
import com.github.hydos.ginger.engine.common.io.Window;
|
||||||
import com.github.hydos.ginger.engine.common.screen.Screen;
|
import com.github.hydos.ginger.engine.common.screen.Screen;
|
||||||
|
import com.github.hydos.ginger.engine.common.tools.MousePicker;
|
||||||
import com.github.hydos.ginger.engine.opengl.postprocessing.*;
|
import com.github.hydos.ginger.engine.opengl.postprocessing.*;
|
||||||
import com.github.hydos.ginger.engine.opengl.render.MasterRenderer;
|
import com.github.hydos.ginger.engine.opengl.render.MasterRenderer;
|
||||||
import com.github.hydos.ginger.engine.opengl.render.tools.MousePicker;
|
|
||||||
import com.github.hydos.ginger.engine.opengl.utils.GlLoader;
|
import com.github.hydos.ginger.engine.opengl.utils.GlLoader;
|
||||||
|
|
||||||
public class GingerGL
|
public class GingerGL
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.nio.*;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
|
||||||
import com.github.hydos.ginger.engine.opengl.render.tools.IOUtil;
|
import com.github.hydos.ginger.engine.common.tools.IOUtil;
|
||||||
|
|
||||||
public class Image
|
public class Image
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.github.hydos.ginger.engine.vulkan.utils;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
import org.lwjgl.vulkan.VkDebugReportCallbackEXT;
|
||||||
|
|
||||||
public class VKConstants
|
public class VKConstants
|
||||||
{
|
{
|
||||||
|
@ -11,5 +12,6 @@ public class VKConstants
|
||||||
{
|
{
|
||||||
MemoryUtil.memUTF8("VK_LAYER_LUNARG_standard_validation"),
|
MemoryUtil.memUTF8("VK_LAYER_LUNARG_standard_validation"),
|
||||||
};
|
};
|
||||||
|
public static VkDebugReportCallbackEXT debugCallback;
|
||||||
public static final long MAX_UNSIGNED_INT = -1L;
|
public static final long MAX_UNSIGNED_INT = -1L;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,23 +4,22 @@ import static org.lwjgl.system.MemoryUtil.*;
|
||||||
import static org.lwjgl.util.shaderc.Shaderc.*;
|
import static org.lwjgl.util.shaderc.Shaderc.*;
|
||||||
import static org.lwjgl.vulkan.EXTDebugReport.*;
|
import static org.lwjgl.vulkan.EXTDebugReport.*;
|
||||||
import static org.lwjgl.vulkan.KHRSurface.*;
|
import static org.lwjgl.vulkan.KHRSurface.*;
|
||||||
import static org.lwjgl.vulkan.NVRayTracing.*;
|
|
||||||
import static org.lwjgl.vulkan.VK10.VK_SUCCESS;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
|
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.*;
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
import org.lwjgl.util.shaderc.*;
|
import org.lwjgl.util.shaderc.*;
|
||||||
import org.lwjgl.vulkan.*;
|
import org.lwjgl.vulkan.*;
|
||||||
|
|
||||||
import com.github.hydos.ginger.engine.opengl.render.tools.IOUtil;
|
import com.github.hydos.ginger.engine.common.tools.IOUtil;
|
||||||
|
|
||||||
/** @author hydos06
|
/** @author hydos06
|
||||||
* a util library for Vulkan */
|
* a util library for Vulkan */
|
||||||
public class VKUtils
|
public class VKUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
public static final int VK_FLAGS_NONE = 0;
|
public static final int VK_FLAGS_NONE = 0;
|
||||||
|
|
||||||
public static long startVulkanDebugging(VkInstance instance, int flags, VkDebugReportCallbackEXT callback)
|
public static long startVulkanDebugging(VkInstance instance, int flags, VkDebugReportCallbackEXT callback)
|
||||||
|
@ -34,7 +33,7 @@ public class VKUtils
|
||||||
long callbackHandle = pCallback.get(0);
|
long callbackHandle = pCallback.get(0);
|
||||||
memFree(pCallback);
|
memFree(pCallback);
|
||||||
dbgCreateInfo.free();
|
dbgCreateInfo.free();
|
||||||
if (err != VK_SUCCESS)
|
if (err != VK12.VK_SUCCESS)
|
||||||
{ throw new AssertionError("Failed to create VkInstance: " + VKUtils.translateVulkanResult(err)); }
|
{ throw new AssertionError("Failed to create VkInstance: " + VKUtils.translateVulkanResult(err)); }
|
||||||
return callbackHandle;
|
return callbackHandle;
|
||||||
}
|
}
|
||||||
|
@ -47,13 +46,13 @@ public class VKUtils
|
||||||
return shaderc_vertex_shader;
|
return shaderc_vertex_shader;
|
||||||
case VK10.VK_SHADER_STAGE_FRAGMENT_BIT:
|
case VK10.VK_SHADER_STAGE_FRAGMENT_BIT:
|
||||||
return shaderc_fragment_shader;
|
return shaderc_fragment_shader;
|
||||||
case VK_SHADER_STAGE_RAYGEN_BIT_NV:
|
case NVRayTracing.VK_SHADER_STAGE_RAYGEN_BIT_NV:
|
||||||
return shaderc_raygen_shader;
|
return shaderc_raygen_shader;
|
||||||
case VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV:
|
case NVRayTracing.VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV:
|
||||||
return shaderc_closesthit_shader;
|
return shaderc_closesthit_shader;
|
||||||
case VK_SHADER_STAGE_MISS_BIT_NV:
|
case NVRayTracing.VK_SHADER_STAGE_MISS_BIT_NV:
|
||||||
return shaderc_miss_shader;
|
return shaderc_miss_shader;
|
||||||
case VK_SHADER_STAGE_ANY_HIT_BIT_NV:
|
case NVRayTracing.VK_SHADER_STAGE_ANY_HIT_BIT_NV:
|
||||||
return shaderc_anyhit_shader;
|
return shaderc_anyhit_shader;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Shader stage: " + stage);
|
throw new IllegalArgumentException("Shader stage: " + stage);
|
||||||
|
@ -164,4 +163,109 @@ public class VKUtils
|
||||||
return String.format("%s [%d]", "Is an unknown vulkan result", Integer.valueOf(vulkanResult));
|
return String.format("%s [%d]", "Is an unknown vulkan result", Integer.valueOf(vulkanResult));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Pipeline
|
||||||
|
{
|
||||||
|
public long pipeline;
|
||||||
|
public long layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VkCommandBuffer[] initRenderCommandBuffers(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height,
|
||||||
|
Pipeline pipeline, long descriptorSet, long verticesBuf)
|
||||||
|
{
|
||||||
|
// Create the render command buffers (one command buffer per framebuffer image)
|
||||||
|
VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc()
|
||||||
|
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO)
|
||||||
|
.commandPool(commandPool)
|
||||||
|
.level(VK12.VK_COMMAND_BUFFER_LEVEL_PRIMARY)
|
||||||
|
.commandBufferCount(framebuffers.length);
|
||||||
|
PointerBuffer pCommandBuffer = memAllocPointer(framebuffers.length);
|
||||||
|
int err = VK12.vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
|
||||||
|
if (err != VK12.VK_SUCCESS)
|
||||||
|
{ throw new AssertionError("Failed to create render command buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||||
|
VkCommandBuffer[] renderCommandBuffers = new VkCommandBuffer[framebuffers.length];
|
||||||
|
for (int i = 0; i < framebuffers.length; i++)
|
||||||
|
{ renderCommandBuffers[i] = new VkCommandBuffer(pCommandBuffer.get(i), device); }
|
||||||
|
memFree(pCommandBuffer);
|
||||||
|
cmdBufAllocateInfo.free();
|
||||||
|
// Create the command buffer begin structure
|
||||||
|
VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc()
|
||||||
|
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
|
||||||
|
// Specify clear color (cornflower blue)
|
||||||
|
VkClearValue.Buffer clearValues = VkClearValue.calloc(2);
|
||||||
|
clearValues.get(0).color()
|
||||||
|
.float32(0, 100 / 255.0f)
|
||||||
|
.float32(1, 149 / 255.0f)
|
||||||
|
.float32(2, 237 / 255.0f)
|
||||||
|
.float32(3, 1.0f);
|
||||||
|
// Specify clear depth-stencil
|
||||||
|
clearValues.get(1).depthStencil().depth(1.0f).stencil(0);
|
||||||
|
// Specify everything to begin a render pass
|
||||||
|
VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.calloc()
|
||||||
|
.sType(VK12.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO)
|
||||||
|
.renderPass(renderPass)
|
||||||
|
.pClearValues(clearValues);
|
||||||
|
VkRect2D renderArea = renderPassBeginInfo.renderArea();
|
||||||
|
renderArea.offset().set(0, 0);
|
||||||
|
renderArea.extent().set(width, height);
|
||||||
|
for (int i = 0; i < renderCommandBuffers.length; ++i)
|
||||||
|
{
|
||||||
|
// Set target frame buffer
|
||||||
|
renderPassBeginInfo.framebuffer(framebuffers[i]);
|
||||||
|
err = VK12.vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
|
||||||
|
if (err != VK12.VK_SUCCESS)
|
||||||
|
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||||
|
VK12.vkCmdBeginRenderPass(renderCommandBuffers[i], renderPassBeginInfo, VK12.VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
// Update dynamic viewport state
|
||||||
|
VkViewport.Buffer viewport = VkViewport.calloc(1)
|
||||||
|
.height(height)
|
||||||
|
.width(width)
|
||||||
|
.minDepth(0.0f)
|
||||||
|
.maxDepth(1.0f);
|
||||||
|
VK12.vkCmdSetViewport(renderCommandBuffers[i], 0, viewport);
|
||||||
|
viewport.free();
|
||||||
|
// Update dynamic scissor state
|
||||||
|
VkRect2D.Buffer scissor = VkRect2D.calloc(1);
|
||||||
|
scissor.extent().set(width, height);
|
||||||
|
scissor.offset().set(0, 0);
|
||||||
|
VK12.vkCmdSetScissor(renderCommandBuffers[i], 0, scissor);
|
||||||
|
scissor.free();
|
||||||
|
// Bind descriptor sets describing shader binding points
|
||||||
|
LongBuffer descriptorSets = memAllocLong(1).put(0, descriptorSet);
|
||||||
|
VK12.vkCmdBindDescriptorSets(renderCommandBuffers[i], VK12.VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, descriptorSets, null);
|
||||||
|
memFree(descriptorSets);
|
||||||
|
// Bind the rendering pipeline (including the shaders)
|
||||||
|
VK12.vkCmdBindPipeline(renderCommandBuffers[i], VK12.VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
|
||||||
|
// Bind triangle vertices
|
||||||
|
LongBuffer offsets = memAllocLong(1);
|
||||||
|
offsets.put(0, 0L);
|
||||||
|
LongBuffer pBuffers = memAllocLong(1);
|
||||||
|
pBuffers.put(0, verticesBuf);
|
||||||
|
VK12.vkCmdBindVertexBuffers(renderCommandBuffers[i], 0, pBuffers, offsets);
|
||||||
|
memFree(pBuffers);
|
||||||
|
memFree(offsets);
|
||||||
|
// Draw triangle
|
||||||
|
VK12.vkCmdDraw(renderCommandBuffers[i], 6, 1, 0, 0);
|
||||||
|
VK12.vkCmdEndRenderPass(renderCommandBuffers[i]);
|
||||||
|
err = VK12.vkEndCommandBuffer(renderCommandBuffers[i]);
|
||||||
|
if (err != VK12.VK_SUCCESS)
|
||||||
|
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||||
|
}
|
||||||
|
renderPassBeginInfo.free();
|
||||||
|
clearValues.free();
|
||||||
|
cmdBufInfo.free();
|
||||||
|
return renderCommandBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setupVulkanDebugCallback()
|
||||||
|
{
|
||||||
|
VKConstants.debugCallback = new VkDebugReportCallbackEXT()
|
||||||
|
{
|
||||||
|
public int invoke(int flags, int objectType, long object, long location, int messageCode, long pLayerPrefix, long pMessage, long pUserData)
|
||||||
|
{
|
||||||
|
System.err.println("ERROR OCCURED: " + VkDebugReportCallbackEXT.getString(pMessage));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue