1/4 vulkan implementation
parent
991f576df6
commit
e4a4beb787
4
pom.xml
4
pom.xml
|
@ -10,8 +10,8 @@
|
|||
<description>A voxel game implementation of the Ginger3D engine by hYdos</description>
|
||||
<url>http://maven.apache.org</url>
|
||||
<properties>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>13</maven.compiler.target>
|
||||
<maven.compiler.source>13</maven.compiler.source>
|
||||
<lwjgl.version>3.2.4-SNAPSHOT</lwjgl.version>
|
||||
<joml.version>1.9.20</joml.version>
|
||||
</properties>
|
||||
|
|
|
@ -22,8 +22,6 @@ import com.github.hydos.ginger.engine.opengl.postprocessing.PostProcessing;
|
|||
import com.github.hydos.ginger.engine.opengl.render.MasterRenderer;
|
||||
import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel;
|
||||
import com.github.hydos.ginger.engine.opengl.utils.GLLoader;
|
||||
import com.github.hydos.ginger.engine.vulkan.api.GingerVK;
|
||||
|
||||
import tk.valoeghese.gateways.client.io.*;
|
||||
|
||||
public class Litecraft extends Game
|
||||
|
@ -152,7 +150,6 @@ public class Litecraft extends Game
|
|||
}
|
||||
case Vulkan:
|
||||
{
|
||||
this.engine = new GingerVK();
|
||||
// TODO: Setup Vulkan
|
||||
exit();
|
||||
break;
|
||||
|
|
|
@ -1,406 +1,60 @@
|
|||
package com.github.hydos.ginger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.*;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.*;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
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.obj.ModelLoader;
|
||||
import com.github.hydos.ginger.engine.vulkan.*;
|
||||
import com.github.hydos.ginger.engine.vulkan.api.GingerVK;
|
||||
import com.github.hydos.ginger.engine.vulkan.model.*;
|
||||
import com.github.hydos.ginger.engine.vulkan.registers.VKRegister;
|
||||
import com.github.hydos.ginger.engine.vulkan.render.RenderUtils;
|
||||
import com.github.hydos.ginger.engine.vulkan.render.renderers.*;
|
||||
import com.github.hydos.ginger.engine.vulkan.render.ubo.*;
|
||||
import com.github.hydos.ginger.engine.vulkan.shaders.*;
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.*;
|
||||
import com.github.hydos.ginger.engine.vulkan.api.GingerVk;
|
||||
|
||||
/** @author hydos06
|
||||
* the non ARR vulkan test example */
|
||||
public class VulkanStarter
|
||||
{
|
||||
public static boolean getSupportedDepthFormat(VkPhysicalDevice physicalDevice, IntBuffer depthFormat)
|
||||
{
|
||||
// Since all depth formats may be optional, we need to find a suitable depth format to use
|
||||
// Start with the highest precision packed format
|
||||
int[] depthFormats =
|
||||
{
|
||||
VK12.VK_FORMAT_D32_SFLOAT_S8_UINT,
|
||||
VK12.VK_FORMAT_D32_SFLOAT,
|
||||
VK12.VK_FORMAT_D24_UNORM_S8_UINT,
|
||||
VK12.VK_FORMAT_D16_UNORM_S8_UINT,
|
||||
VK12.VK_FORMAT_D16_UNORM
|
||||
};
|
||||
VkFormatProperties formatProps = VkFormatProperties.calloc();
|
||||
for (int format : depthFormats)
|
||||
{
|
||||
VK12.vkGetPhysicalDeviceFormatProperties(physicalDevice, format, formatProps);
|
||||
// Format must support depth stencil attachment for optimal tiling
|
||||
if ((formatProps.optimalTilingFeatures() & VK12.VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
|
||||
{
|
||||
depthFormat.put(0, format);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static class HelloTriangleApplication {
|
||||
|
||||
public static class ColorAndDepthFormatAndSpace
|
||||
{
|
||||
public int colorFormat;
|
||||
public int colorSpace;
|
||||
public int depthFormat;
|
||||
}
|
||||
private static final int WIDTH = 800;
|
||||
private static final int HEIGHT = 600;
|
||||
|
||||
private static long createCommandPool(VkDevice device, int queueNodeIndex)
|
||||
{
|
||||
VkCommandPoolCreateInfo cmdPoolInfo = VkCommandPoolCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO)
|
||||
.queueFamilyIndex(queueNodeIndex)
|
||||
.flags(VK12.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
LongBuffer pCmdPool = MemoryUtil.memAllocLong(1);
|
||||
int err = VK12.vkCreateCommandPool(device, cmdPoolInfo, null, pCmdPool);
|
||||
long commandPool = pCmdPool.get(0);
|
||||
cmdPoolInfo.free();
|
||||
MemoryUtil.memFree(pCmdPool);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create command pool: " + VKUtils.translateVulkanResult(err)); }
|
||||
return commandPool;
|
||||
}
|
||||
// ======= FIELDS ======= //
|
||||
|
||||
private static VkQueue createDeviceQueue(VkDevice device, int queueFamilyIndex)
|
||||
{
|
||||
PointerBuffer pQueue = MemoryUtil.memAllocPointer(1);
|
||||
VK12.vkGetDeviceQueue(device, queueFamilyIndex, 0, pQueue);
|
||||
long queue = pQueue.get(0);
|
||||
MemoryUtil.memFree(pQueue);
|
||||
return new VkQueue(queue, device);
|
||||
}
|
||||
private long window;
|
||||
|
||||
private static VkCommandBuffer createCommandBuffer(VkDevice device, long commandPool)
|
||||
{
|
||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO)
|
||||
.commandPool(commandPool)
|
||||
.level(VK12.VK_COMMAND_BUFFER_LEVEL_PRIMARY)
|
||||
.commandBufferCount(1);
|
||||
PointerBuffer pCommandBuffer = MemoryUtil.memAllocPointer(1);
|
||||
int err = VK12.vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
|
||||
cmdBufAllocateInfo.free();
|
||||
long commandBuffer = pCommandBuffer.get(0);
|
||||
MemoryUtil.memFree(pCommandBuffer);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to allocate command buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
return new VkCommandBuffer(commandBuffer, device);
|
||||
}
|
||||
// ======= METHODS ======= //
|
||||
|
||||
public static class Swapchain
|
||||
{
|
||||
public long swapchainHandle;
|
||||
public long[] images;
|
||||
public long[] imageViews;
|
||||
}
|
||||
public void run() {
|
||||
Window.create(WIDTH, HEIGHT, "V u l k a n", 60, RenderAPI.Vulkan);
|
||||
initVulkan();
|
||||
mainLoop();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
public static class DepthStencil
|
||||
{
|
||||
public long view;
|
||||
}
|
||||
private void initVulkan() {
|
||||
new GingerVk().start("Vulkan demo");
|
||||
}
|
||||
|
||||
private static void submitCommandBuffer(VkQueue queue, VkCommandBuffer commandBuffer)
|
||||
{
|
||||
if (commandBuffer == null || commandBuffer.address() == MemoryUtil.NULL)
|
||||
return;
|
||||
VkSubmitInfo submitInfo = VkSubmitInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_SUBMIT_INFO);
|
||||
PointerBuffer pCommandBuffers = MemoryUtil.memAllocPointer(1)
|
||||
.put(commandBuffer)
|
||||
.flip();
|
||||
submitInfo.pCommandBuffers(pCommandBuffers);
|
||||
int err = VK12.vkQueueSubmit(queue, submitInfo, VK12.VK_NULL_HANDLE);
|
||||
MemoryUtil.memFree(pCommandBuffers);
|
||||
submitInfo.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to submit command buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
}
|
||||
private void mainLoop() {
|
||||
|
||||
private static long createDescriptorPool(VkDevice device)
|
||||
{
|
||||
// We need to tell the API the number of max. requested descriptors per type
|
||||
VkDescriptorPoolSize.Buffer typeCounts = VkDescriptorPoolSize.calloc(1)
|
||||
// This example only uses one descriptor type (uniform buffer) and only
|
||||
// requests one descriptor of this type
|
||||
.type(VK12.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||
.descriptorCount(1);
|
||||
// For additional types you need to add new entries in the type count list
|
||||
// E.g. for two combined image samplers :
|
||||
// typeCounts[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
// typeCounts[1].descriptorCount = 2;
|
||||
// Create the global descriptor pool
|
||||
// All descriptors used in this example are allocated from this pool
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo = VkDescriptorPoolCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
|
||||
.pPoolSizes(typeCounts)
|
||||
// Set the max. number of sets that can be requested
|
||||
// Requesting descriptors beyond maxSets will result in an error
|
||||
.maxSets(1);
|
||||
LongBuffer pDescriptorPool = MemoryUtil.memAllocLong(1);
|
||||
int err = VK12.vkCreateDescriptorPool(device, descriptorPoolInfo, null, pDescriptorPool);
|
||||
long descriptorPool = pDescriptorPool.get(0);
|
||||
MemoryUtil.memFree(pDescriptorPool);
|
||||
descriptorPoolInfo.free();
|
||||
typeCounts.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create descriptor pool: " + VKUtils.translateVulkanResult(err)); }
|
||||
return descriptorPool;
|
||||
}
|
||||
while(!Window.closed()) {
|
||||
if(Window.shouldRender()) {
|
||||
Window.update();
|
||||
}
|
||||
}
|
||||
|
||||
private static long createDescriptorSet(VkDevice device, long descriptorPool, long descriptorSetLayout, UboDescriptor uniformDataVSDescriptor)
|
||||
{
|
||||
LongBuffer pDescriptorSetLayout = MemoryUtil.memAllocLong(1);
|
||||
pDescriptorSetLayout.put(0, descriptorSetLayout);
|
||||
VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO)
|
||||
.descriptorPool(descriptorPool)
|
||||
.pSetLayouts(pDescriptorSetLayout);
|
||||
LongBuffer pDescriptorSet = MemoryUtil.memAllocLong(1);
|
||||
int err = VK12.vkAllocateDescriptorSets(device, allocInfo, pDescriptorSet);
|
||||
long descriptorSet = pDescriptorSet.get(0);
|
||||
MemoryUtil.memFree(pDescriptorSet);
|
||||
allocInfo.free();
|
||||
MemoryUtil.memFree(pDescriptorSetLayout);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create descriptor set: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Update descriptor sets determining the shader binding points
|
||||
// For every binding point used in a shader there needs to be one
|
||||
// descriptor set matching that binding point
|
||||
VkDescriptorBufferInfo.Buffer descriptor = VkDescriptorBufferInfo.calloc(1)
|
||||
.buffer(uniformDataVSDescriptor.buffer)
|
||||
.range(uniformDataVSDescriptor.range)
|
||||
.offset(uniformDataVSDescriptor.offset);
|
||||
// Binding 0 : Uniform buffer
|
||||
VkWriteDescriptorSet.Buffer writeDescriptorSet = VkWriteDescriptorSet.calloc(1)
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET)
|
||||
.dstSet(descriptorSet)
|
||||
.descriptorCount(1)
|
||||
.descriptorType(VK12.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||
.pBufferInfo(descriptor)
|
||||
.dstBinding(0); // Binds this uniform buffer to binding point 0
|
||||
VK12.vkUpdateDescriptorSets(device, writeDescriptorSet, null);
|
||||
writeDescriptorSet.free();
|
||||
descriptor.free();
|
||||
return descriptorSet;
|
||||
}
|
||||
}
|
||||
|
||||
private static long createDescriptorSetLayout(VkDevice device)
|
||||
{
|
||||
int err;
|
||||
// One binding for a UBO used in a vertex shader
|
||||
VkDescriptorSetLayoutBinding.Buffer layoutBinding = VkDescriptorSetLayoutBinding.calloc(1)
|
||||
.binding(ShaderType.vertexShader) // <- Binding 0 : Uniform buffer (Vertex shader)
|
||||
.descriptorType(VK12.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||
.descriptorCount(1)
|
||||
.stageFlags(VK12.VK_SHADER_STAGE_VERTEX_BIT);
|
||||
// Build a create-info struct to create the descriptor set layout
|
||||
VkDescriptorSetLayoutCreateInfo descriptorLayout = VkDescriptorSetLayoutCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)
|
||||
.pBindings(layoutBinding);
|
||||
LongBuffer pDescriptorSetLayout = MemoryUtil.memAllocLong(1);
|
||||
err = VK12.vkCreateDescriptorSetLayout(device, descriptorLayout, null, pDescriptorSetLayout);
|
||||
long descriptorSetLayout = pDescriptorSetLayout.get(0);
|
||||
MemoryUtil.memFree(pDescriptorSetLayout);
|
||||
descriptorLayout.free();
|
||||
layoutBinding.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create descriptor set layout: " + VKUtils.translateVulkanResult(err)); }
|
||||
return descriptorSetLayout;
|
||||
}
|
||||
private void cleanup() {
|
||||
|
||||
/*
|
||||
* All resources that must be reallocated on window resize.
|
||||
*/
|
||||
private static Swapchain swapchain;
|
||||
private static long[] framebuffers;
|
||||
private static VkCommandBuffer[] renderCommandBuffers;
|
||||
private static DepthStencil depthStencil;
|
||||
GLFW.glfwDestroyWindow(window);
|
||||
|
||||
public static void main(String[] args) throws IOException
|
||||
{
|
||||
Window.create(1200, 600, "Litecraft Vulkan", 60, RenderAPI.Vulkan);
|
||||
new GingerVK();
|
||||
VKRegister.exampleVKModel = new VKModelData();
|
||||
/* Look for instance extensions */
|
||||
PointerBuffer requiredExtensions = GLFWVulkan.glfwGetRequiredInstanceExtensions();
|
||||
if (requiredExtensions == null)
|
||||
{ throw new AssertionError("Failed to find list of required Vulkan extensions"); }
|
||||
// Create the Vulkan instance
|
||||
final VkInstance vulkanInstance = VKLoader.createInstance(requiredExtensions);
|
||||
VKUtils.setupVulkanDebugCallback();
|
||||
final long debugCallbackHandle = VKUtils.startVulkanDebugging(vulkanInstance, EXTDebugReport.VK_DEBUG_REPORT_ERROR_BIT_EXT | EXTDebugReport.VK_DEBUG_REPORT_WARNING_BIT_EXT, VKConstants.debugCallback);
|
||||
VKRegister.physicalDevice = VKDeviceProperties.getFirstPhysicalDevice(vulkanInstance);
|
||||
final VKDeviceProperties deviceAndGraphicsQueueFamily = VKDeviceProperties.initDeviceProperties(VKRegister.physicalDevice);
|
||||
VKRegister.device = deviceAndGraphicsQueueFamily.device;
|
||||
int queueFamilyIndex = deviceAndGraphicsQueueFamily.queueFamilyIndex;
|
||||
final VkPhysicalDeviceMemoryProperties memoryProperties = deviceAndGraphicsQueueFamily.memoryProperties;
|
||||
GLFWKeyCallback keyCallback;
|
||||
GLFW.glfwSetKeyCallback(Window.getWindow(), keyCallback = new GLFWKeyCallback()
|
||||
{
|
||||
public void invoke(long window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (action != GLFW.GLFW_RELEASE)
|
||||
return;
|
||||
if (key == GLFW.GLFW_KEY_ESCAPE)
|
||||
GLFW.glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
});
|
||||
LongBuffer pSurface = MemoryUtil.memAllocLong(1);
|
||||
int err = GLFWVulkan.glfwCreateWindowSurface(vulkanInstance, Window.getWindow(), null, pSurface);
|
||||
final long surface = pSurface.get(0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create surface: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Create static Vulkan resources
|
||||
final ColorAndDepthFormatAndSpace colorAndDepthFormatAndSpace = VKMasterRenderer.getColorFormatAndSpace(VKRegister.physicalDevice, surface);
|
||||
VKRegister.commandPool = createCommandPool(VKRegister.device, queueFamilyIndex);
|
||||
final VkCommandBuffer setupCommandBuffer = createCommandBuffer(VKRegister.device, VKRegister.commandPool);
|
||||
VKRegister.queue = createDeviceQueue(VKRegister.device, queueFamilyIndex);
|
||||
final long renderPass = RenderUtils.createRenderPass(VKRegister.device, colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.depthFormat);
|
||||
final long renderCommandPool = createCommandPool(VKRegister.device, queueFamilyIndex);
|
||||
VKVertices vertices = VKModelConverter.convertModel(ModelLoader.getCubeMesh(), memoryProperties, VKRegister.device);
|
||||
Ubo ubo = new Ubo(memoryProperties, VKRegister.device);
|
||||
final long descriptorPool = createDescriptorPool(VKRegister.device);
|
||||
final long descriptorSetLayout = createDescriptorSetLayout(VKRegister.device);
|
||||
final long descriptorSet = createDescriptorSet(VKRegister.device, descriptorPool, descriptorSetLayout, ubo.uboData);
|
||||
final Pipeline pipeline = Pipeline.createPipeline(VKRegister.device, renderPass, vertices.createInfo, descriptorSetLayout);
|
||||
VKRegister.exampleVKModel.loadModel();
|
||||
final class SwapchainRecreator
|
||||
{
|
||||
boolean mustRecreate = true;
|
||||
GLFW.glfwTerminate();
|
||||
}
|
||||
|
||||
void recreate()
|
||||
{
|
||||
// Begin the setup command buffer (the one we will use for swapchain/framebuffer creation)
|
||||
VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
|
||||
int err = VK12.vkBeginCommandBuffer(setupCommandBuffer, cmdBufInfo);
|
||||
cmdBufInfo.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to begin setup command buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
long oldChain = swapchain != null ? swapchain.swapchainHandle : VK12.VK_NULL_HANDLE;
|
||||
// Create the swapchain (this will also add a memory barrier to initialize the framebuffer images)
|
||||
swapchain = VKMasterRenderer.createSwapChain(VKRegister.device, VKRegister.physicalDevice, surface, oldChain, setupCommandBuffer,
|
||||
Window.getWidth(), Window.getHeight(), colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.colorSpace);
|
||||
// Create depth-stencil image
|
||||
depthStencil = VKMasterRenderer.createDepthStencil(VKRegister.device, memoryProperties, colorAndDepthFormatAndSpace.depthFormat, setupCommandBuffer);
|
||||
err = VK12.vkEndCommandBuffer(setupCommandBuffer);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to end setup command buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
submitCommandBuffer(VKRegister.queue, setupCommandBuffer);
|
||||
VK12.vkQueueWaitIdle(VKRegister.queue);
|
||||
if (framebuffers != null)
|
||||
{ for (int i = 0; i < framebuffers.length; i++)
|
||||
VK12.vkDestroyFramebuffer(VKRegister.device, framebuffers[i], null); }
|
||||
framebuffers = RenderUtils.createFramebuffers(VKRegister.device, swapchain, renderPass, Window.getWidth(), Window.getHeight(), depthStencil);
|
||||
// Create render command buffers
|
||||
if (renderCommandBuffers != null)
|
||||
{ VK12.vkResetCommandPool(VKRegister.device, renderCommandPool, VKUtils.VK_FLAGS_NONE); }
|
||||
renderCommandBuffers = VKUtils.setupRenderCommandBuffer(VKRegister.device, renderCommandPool, framebuffers, renderPass, Window.getWidth(), Window.getHeight(), pipeline, descriptorSet,
|
||||
vertices.vkVerticiesBuffer);
|
||||
mustRecreate = false;
|
||||
}
|
||||
}
|
||||
final SwapchainRecreator swapchainRecreator = new SwapchainRecreator();
|
||||
// Handle canvas resize
|
||||
GLFWFramebufferSizeCallback framebufferSizeCallback = new GLFWFramebufferSizeCallback()
|
||||
{
|
||||
public void invoke(long window, int width, int height)
|
||||
{
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
swapchainRecreator.mustRecreate = true;
|
||||
}
|
||||
};
|
||||
GLFW.glfwSetFramebufferSizeCallback(Window.getWindow(), framebufferSizeCallback);
|
||||
GLFW.glfwShowWindow(Window.getWindow());
|
||||
// Pre-allocate everything needed in the render loop
|
||||
IntBuffer pImageIndex = MemoryUtil.memAllocInt(1);
|
||||
int currentBuffer = 0;
|
||||
PointerBuffer pCommandBuffers = MemoryUtil.memAllocPointer(1);
|
||||
LongBuffer pSwapchains = MemoryUtil.memAllocLong(1);
|
||||
LongBuffer pImageAcquiredSemaphore = MemoryUtil.memAllocLong(1);
|
||||
LongBuffer pRenderCompleteSemaphore = MemoryUtil.memAllocLong(1);
|
||||
// Info struct to create a semaphore
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = VkSemaphoreCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO);
|
||||
// Info struct to submit a command buffer which will wait on the semaphore
|
||||
IntBuffer pWaitDstStageMask = MemoryUtil.memAllocInt(1);
|
||||
pWaitDstStageMask.put(0, VK12.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
VkSubmitInfo submitInfo = VkSubmitInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_SUBMIT_INFO)
|
||||
.waitSemaphoreCount(pImageAcquiredSemaphore.remaining())
|
||||
.pWaitSemaphores(pImageAcquiredSemaphore)
|
||||
.pWaitDstStageMask(pWaitDstStageMask)
|
||||
.pCommandBuffers(pCommandBuffers)
|
||||
.pSignalSemaphores(pRenderCompleteSemaphore);
|
||||
// Info struct to present the current swapchain image to the display
|
||||
VkPresentInfoKHR presentInfo = VkPresentInfoKHR.calloc()
|
||||
.sType(KHRSwapchain.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR)
|
||||
.pWaitSemaphores(pRenderCompleteSemaphore)
|
||||
.swapchainCount(pSwapchains.remaining())
|
||||
.pSwapchains(pSwapchains)
|
||||
.pImageIndices(pImageIndex)
|
||||
.pResults(null);
|
||||
// The render loop
|
||||
long lastTime = System.nanoTime();
|
||||
float time = 0.0f;
|
||||
while (!GLFW.glfwWindowShouldClose(Window.getWindow()))
|
||||
{
|
||||
Window.update();
|
||||
if (swapchainRecreator.mustRecreate)
|
||||
swapchainRecreator.recreate();
|
||||
|
||||
|
||||
err = VK12.vkCreateSemaphore(VKRegister.device, semaphoreCreateInfo, null, pImageAcquiredSemaphore);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create image acquired semaphore: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Create a semaphore to wait for the render to complete, before presenting
|
||||
err = VK12.vkCreateSemaphore(VKRegister.device, semaphoreCreateInfo, null, pRenderCompleteSemaphore);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create render complete semaphore: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Get next image from the swap chain (back/front buffer).
|
||||
// This will setup the imageAquiredSemaphore to be signalled when the operation is complete
|
||||
err = KHRSwapchain.vkAcquireNextImageKHR(VKRegister.device, swapchain.swapchainHandle, VKConstants.MAX_UNSIGNED_INT, pImageAcquiredSemaphore.get(0), VK12.VK_NULL_HANDLE, pImageIndex);
|
||||
currentBuffer = pImageIndex.get(0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to acquire next swapchain image: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Select the command buffer for the current framebuffer image/attachment
|
||||
pCommandBuffers.put(0, renderCommandBuffers[currentBuffer]);
|
||||
// Update UBO
|
||||
long thisTime = System.nanoTime();
|
||||
time += (thisTime - lastTime) / 1E9f;
|
||||
lastTime = thisTime;
|
||||
ubo.updateUbo(VKRegister.device, time);
|
||||
// Submit to the graphics queue
|
||||
|
||||
err = VK12.vkQueueSubmit(VKRegister.queue, submitInfo, VK12.VK_NULL_HANDLE);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to submit render queue: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Present the current buffer to the swap chain
|
||||
// This will display the image
|
||||
pSwapchains.put(0, swapchain.swapchainHandle);
|
||||
err = KHRSwapchain.vkQueuePresentKHR(VKRegister.queue, presentInfo);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to present the swapchain image: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Create and submit post present barrier
|
||||
VK12.vkQueueWaitIdle(VKRegister.queue);
|
||||
// Destroy this semaphore (we will create a new one in the next frame)
|
||||
VK12.vkDestroySemaphore(VKRegister.device, pImageAcquiredSemaphore.get(0), null);
|
||||
VK12.vkDestroySemaphore(VKRegister.device, pRenderCompleteSemaphore.get(0), null);
|
||||
}
|
||||
((GingerVK)GingerVK.getInstance()).end(pWaitDstStageMask, pImageAcquiredSemaphore, pRenderCompleteSemaphore, pSwapchains, pCommandBuffers, semaphoreCreateInfo, submitInfo, presentInfo, vulkanInstance, debugCallbackHandle, framebufferSizeCallback, keyCallback);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
HelloTriangleApplication app = new HelloTriangleApplication();
|
||||
|
||||
app.run();
|
||||
}
|
||||
}
|
|
@ -23,4 +23,9 @@ public class ModelLoader
|
|||
Mesh data = OBJFileLoader.loadModel(objPath);
|
||||
return new GLTexturedModel(GLLoader.loadToVAO(data.getVertices(), data.getIndices(), data.getNormals(), data.getTextureCoords()), new ModelTexture(texturePath));
|
||||
}
|
||||
|
||||
public static Mesh loadMesh(String meshPath) {
|
||||
Mesh data = OBJFileLoader.loadModel(meshPath);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.lwjgl.assimp.AIVector3D.Buffer;
|
|||
|
||||
public class OBJFileLoader
|
||||
{
|
||||
public static String resourceLocation = "~/Desktop/Ginger3D/src/main/resources/models/";
|
||||
public static String resourceLocation = "C:/Users/Hayden/Desktop/Litecraft3D/src/main/resources/models/";
|
||||
|
||||
public static Mesh loadModel(String filePath)
|
||||
{
|
||||
|
@ -15,7 +15,10 @@ public class OBJFileLoader
|
|||
{
|
||||
scene = Assimp.aiImportFile(resourceLocation + filePath, Assimp.aiProcess_JoinIdenticalVertices | Assimp.aiProcess_Triangulate);
|
||||
if (scene == null)
|
||||
{ return new Mesh(new float[0], new float[0], new float[0], new int[0], 1F); }
|
||||
{
|
||||
System.err.println("The model " + resourceLocation + filePath + " has failed to load");
|
||||
return new Mesh(new float[0], new float[0], new float[0], new int[0], 1F);
|
||||
}
|
||||
AIMesh mesh = AIMesh.create(scene.mMeshes().get(0));
|
||||
int vertexCount = mesh.mNumVertices();
|
||||
AIVector3D.Buffer vertices = mesh.mVertices();
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
package com.github.hydos.ginger.engine.vulkan;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.VkDebugReportCallbackEXT;
|
||||
|
||||
public class VKConstants
|
||||
public class VkConstants
|
||||
{
|
||||
public static boolean debug = System.getProperty("NDEBUG") == null;
|
||||
public static ByteBuffer[] layers =
|
||||
{
|
||||
MemoryUtil.memUTF8("VK_LAYER_LUNARG_standard_validation"),
|
||||
};
|
||||
public static VkDebugReportCallbackEXT debugCallback;
|
||||
public static final long MAX_UNSIGNED_INT = -1L;
|
||||
}
|
||||
|
||||
public static VkInstance vulkanInstance;
|
||||
public static VkPhysicalDevice physicalDevice;
|
||||
public static VkDevice device;
|
||||
public static VkQueue graphicsQueue;
|
||||
public static long windowSurface;
|
||||
public static VkQueue presentQueue;
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan;
|
||||
|
||||
import org.lwjgl.vulkan.VkQueue;
|
||||
|
||||
public class VKRenderRegister
|
||||
{
|
||||
public static VkQueue renderQueue;//used for queueing up render updates
|
||||
|
||||
|
||||
}
|
|
@ -1,64 +1,18 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.api;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import com.github.hydos.ginger.engine.vulkan.io.VkWindow;
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VkUtils;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
|
||||
import org.lwjgl.glfw.GLFWKeyCallback;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.EXTDebugReport;
|
||||
import org.lwjgl.vulkan.VkInstance;
|
||||
import org.lwjgl.vulkan.VkPresentInfoKHR;
|
||||
import org.lwjgl.vulkan.VkSemaphoreCreateInfo;
|
||||
import org.lwjgl.vulkan.VkSubmitInfo;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.api.GingerEngine;
|
||||
import com.github.hydos.ginger.engine.common.api.game.Game;
|
||||
import com.github.hydos.ginger.engine.common.io.Window;
|
||||
import com.github.hydos.ginger.engine.common.screen.Screen;
|
||||
|
||||
public class GingerVK extends GingerEngine
|
||||
public class GingerVk
|
||||
{
|
||||
public GingerVK()
|
||||
{
|
||||
INSTANCE = this;
|
||||
|
||||
public void start(String gameName) {
|
||||
System.out.println("Game " + gameName + " successfuly started in Vulkan mode.");
|
||||
VkUtils.createInstance();
|
||||
VkWindow.createSurface();
|
||||
VkUtils.createPhysicalDevice();
|
||||
VkUtils.createLogicalDevice();
|
||||
}
|
||||
|
||||
public void end(IntBuffer pWaitDstStageMask, LongBuffer pImageAcquiredSemaphore, LongBuffer pRenderCompleteSemaphore, LongBuffer pSwapchains, PointerBuffer pCommandBuffers, VkSemaphoreCreateInfo semaphoreCreateInfo, VkSubmitInfo submitInfo, VkPresentInfoKHR presentInfo, VkInstance vulkanInstance, long debugCallbackHandle, GLFWFramebufferSizeCallback framebufferSizeCallback, GLFWKeyCallback keyCallback)
|
||||
{
|
||||
MemoryUtil.memFree(pWaitDstStageMask);
|
||||
MemoryUtil.memFree(pImageAcquiredSemaphore);
|
||||
MemoryUtil.memFree(pRenderCompleteSemaphore);
|
||||
MemoryUtil.memFree(pSwapchains);
|
||||
MemoryUtil.memFree(pCommandBuffers);
|
||||
semaphoreCreateInfo.free();
|
||||
submitInfo.free();
|
||||
presentInfo.free();
|
||||
EXTDebugReport.vkDestroyDebugReportCallbackEXT(vulkanInstance, debugCallbackHandle, null);
|
||||
framebufferSizeCallback.free();
|
||||
keyCallback.free();
|
||||
GLFW.glfwDestroyWindow(Window.getWindow());
|
||||
GLFW.glfwTerminate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openScreen(Screen screen)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderOverlays(Game game)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.io;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import org.lwjgl.glfw.GLFWVulkan;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VK12;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.io.Window;
|
||||
import com.github.hydos.ginger.engine.vulkan.VkConstants;
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VkUtils;
|
||||
|
||||
/**
|
||||
* used for window related vulkan only things
|
||||
* @author hydos
|
||||
*
|
||||
*/
|
||||
public class VkWindow
|
||||
{
|
||||
public static void createSurface()
|
||||
{
|
||||
try(MemoryStack stack = MemoryStack.stackPush())
|
||||
{
|
||||
LongBuffer pSurface = stack.longs(VK12.VK_NULL_HANDLE);
|
||||
|
||||
int status = GLFWVulkan.glfwCreateWindowSurface(VkConstants.vulkanInstance, Window.getWindow(), null, pSurface);
|
||||
if(status != VK12.VK_SUCCESS)
|
||||
{
|
||||
throw new VulkanException("Failed to create vulkan surface for window reason: " + VkUtils.translateVulkanResult(status));
|
||||
}
|
||||
|
||||
VkConstants.windowSurface = pSurface.get(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.io;
|
||||
|
||||
public class VulkanException extends RuntimeException
|
||||
{
|
||||
|
||||
public VulkanException(String string)
|
||||
{
|
||||
super(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* the exception type thrown when a vulkan error is thrown
|
||||
*/
|
||||
private static final long serialVersionUID = -6985060773180054456L;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.memory;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties;
|
||||
|
||||
public class VKMemory {
|
||||
|
||||
public static boolean getMemoryType(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, int typeBits, int properties, IntBuffer typeIndex)
|
||||
{
|
||||
int bits = typeBits;
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if ((bits & 1) == 1)
|
||||
{
|
||||
if ((deviceMemoryProperties.memoryTypes(i).propertyFlags() & properties) == properties)
|
||||
{
|
||||
typeIndex.put(0, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bits >>= 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.model;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
|
||||
import java.nio.*;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.obj.Mesh;
|
||||
import com.github.hydos.ginger.engine.vulkan.memory.VKMemory;
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
|
||||
|
||||
public class VKModelConverter
|
||||
{
|
||||
|
||||
public static VKVertices convertModel(Mesh mesh, VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device)
|
||||
{
|
||||
ByteBuffer vertexBuffer = memAlloc(mesh.getVertices().length * 4);
|
||||
FloatBuffer bufferVertices = vertexBuffer.asFloatBuffer();
|
||||
for(float vertex: mesh.getVertices()) {
|
||||
bufferVertices.put(vertex);
|
||||
}
|
||||
VkMemoryAllocateInfo memAlloc = VkMemoryAllocateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
||||
VkMemoryRequirements memReqs = VkMemoryRequirements.calloc();
|
||||
int err;
|
||||
// Generate vertex buffer
|
||||
// Setup
|
||||
VkBufferCreateInfo bufInfo = VkBufferCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
|
||||
.size(vertexBuffer.remaining())
|
||||
.usage(VK12.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
LongBuffer pBuffer = memAllocLong(1);
|
||||
err = VK12.vkCreateBuffer(device, bufInfo, null, pBuffer);
|
||||
long verticesBuf = pBuffer.get(0);
|
||||
memFree(pBuffer);
|
||||
bufInfo.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create vertex buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
VK12.vkGetBufferMemoryRequirements(device, verticesBuf, memReqs);
|
||||
memAlloc.allocationSize(memReqs.size());
|
||||
IntBuffer memoryTypeIndex = memAllocInt(1);
|
||||
VKMemory.getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK12.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex);
|
||||
memAlloc.memoryTypeIndex(memoryTypeIndex.get(0));
|
||||
memFree(memoryTypeIndex);
|
||||
memReqs.free();
|
||||
LongBuffer pMemory = memAllocLong(1);
|
||||
err = VK12.vkAllocateMemory(device, memAlloc, null, pMemory);
|
||||
long verticesMem = pMemory.get(0);
|
||||
memFree(pMemory);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to allocate vertex memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
PointerBuffer pData = memAllocPointer(1);
|
||||
err = VK12.vkMapMemory(device, verticesMem, 0, vertexBuffer.remaining(), 0, pData);
|
||||
memAlloc.free();
|
||||
long data = pData.get(0);
|
||||
memFree(pData);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to map vertex memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
memCopy(memAddress(vertexBuffer), data, vertexBuffer.remaining());
|
||||
memFree(vertexBuffer);
|
||||
VK12.vkUnmapMemory(device, verticesMem);
|
||||
err = VK12.vkBindBufferMemory(device, verticesBuf, verticesMem, 0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to bind memory to vertex buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Binding description
|
||||
VkVertexInputBindingDescription.Buffer bindingDescriptor = VkVertexInputBindingDescription.calloc(1)
|
||||
.binding(0) // <- we bind our vertex buffer to point 0
|
||||
.stride((3 + 3) * 4)
|
||||
.inputRate(VK12.VK_VERTEX_INPUT_RATE_VERTEX);
|
||||
// Attribute descriptions
|
||||
// Describes memory layout and shader attribute locations
|
||||
VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(2);
|
||||
// Location 0 : Position
|
||||
attributeDescriptions.get(0)
|
||||
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
|
||||
.location(0) // <- location in the shader's attribute layout (inside the shader source)
|
||||
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(0);
|
||||
// Location 1 : Color
|
||||
attributeDescriptions.get(1)
|
||||
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
|
||||
.location(1) // <- location in the shader's attribute layout (inside the shader source)
|
||||
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(3 * 4);
|
||||
// Assign to vertex buffer
|
||||
VkPipelineVertexInputStateCreateInfo vi = VkPipelineVertexInputStateCreateInfo.calloc();
|
||||
vi.sType(VK12.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
vi.pVertexBindingDescriptions(bindingDescriptor);
|
||||
vi.pVertexAttributeDescriptions(attributeDescriptions);
|
||||
VKVertices ret = new VKVertices();
|
||||
ret.createInfo = vi;
|
||||
ret.vkVerticiesBuffer = verticesBuf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,243 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.model;
|
||||
|
||||
import static org.lwjgl.system.MemoryStack.stackPush;
|
||||
|
||||
import java.nio.*;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.obj.*;
|
||||
import com.github.hydos.ginger.engine.vulkan.registers.VKRegister;
|
||||
|
||||
public class VKModelData
|
||||
{
|
||||
|
||||
public Mesh mesh;
|
||||
public long vertexBuffer;
|
||||
public long vertexBufferMemory;
|
||||
public long indexBuffer;
|
||||
public long indexBufferMemory;
|
||||
|
||||
public void loadModel() {
|
||||
this.mesh = ModelLoader.getCubeMesh();
|
||||
createVertexBuffer();
|
||||
createIndexBuffer();
|
||||
}
|
||||
|
||||
public int findMemoryType(int typeFilter, int properties) {
|
||||
|
||||
VkPhysicalDeviceMemoryProperties memProperties = VkPhysicalDeviceMemoryProperties.mallocStack();
|
||||
VK12.vkGetPhysicalDeviceMemoryProperties(VKRegister.physicalDevice, memProperties);
|
||||
|
||||
for(int i = 0;i < memProperties.memoryTypeCount();i++) {
|
||||
if((typeFilter & (1 << i)) != 0 && (memProperties.memoryTypes(i).propertyFlags() & properties) == properties) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Failed to find suitable memory type");
|
||||
}
|
||||
|
||||
public void createBuffer(long size, int usage, int properties, LongBuffer pBuffer, LongBuffer pBufferMemory) {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.callocStack(stack);
|
||||
bufferInfo.sType(VK12.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
|
||||
bufferInfo.size(size);
|
||||
bufferInfo.usage(usage);
|
||||
bufferInfo.sharingMode(VK12.VK_SHARING_MODE_EXCLUSIVE);
|
||||
|
||||
if(VK12.vkCreateBuffer(VKRegister.device, bufferInfo, null, pBuffer) != VK12.VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create vertex buffer");
|
||||
}
|
||||
|
||||
VkMemoryRequirements memRequirements = VkMemoryRequirements.mallocStack(stack);
|
||||
VK12.vkGetBufferMemoryRequirements(VKRegister.device, pBuffer.get(0), memRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo = VkMemoryAllocateInfo.callocStack(stack);
|
||||
allocInfo.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
||||
allocInfo.allocationSize(memRequirements.size());
|
||||
allocInfo.memoryTypeIndex(findMemoryType(memRequirements.memoryTypeBits(), properties));
|
||||
|
||||
if(VK12.vkAllocateMemory(VKRegister.device, allocInfo, null, pBufferMemory) != VK12.VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to allocate vertex buffer memory");
|
||||
}
|
||||
|
||||
VK12.vkBindBufferMemory(VKRegister.device, pBuffer.get(0), pBufferMemory.get(0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void endSingleTimeCommands(VkCommandBuffer commandBuffer) {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
VK12.vkEndCommandBuffer(commandBuffer);
|
||||
|
||||
VkSubmitInfo.Buffer submitInfo = VkSubmitInfo.callocStack(1, stack);
|
||||
submitInfo.sType(VK12.VK_STRUCTURE_TYPE_SUBMIT_INFO);
|
||||
submitInfo.pCommandBuffers(stack.pointers(commandBuffer));
|
||||
|
||||
VK12.vkQueueSubmit(VKRegister.queue, submitInfo, VK12.VK_NULL_HANDLE);
|
||||
VK12.vkQueueWaitIdle(VKRegister.queue);
|
||||
|
||||
VK12.vkFreeCommandBuffers(VKRegister.device, VKRegister.commandPool, commandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
private VkCommandBuffer beginSingleTimeCommands() {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.callocStack(stack);
|
||||
allocInfo.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO);
|
||||
allocInfo.level(VK12.VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
||||
allocInfo.commandPool(VKRegister.commandPool);
|
||||
allocInfo.commandBufferCount(1);
|
||||
|
||||
PointerBuffer pCommandBuffer = stack.mallocPointer(1);
|
||||
VK12.vkAllocateCommandBuffers(VKRegister.device, allocInfo, pCommandBuffer);
|
||||
VkCommandBuffer commandBuffer = new VkCommandBuffer(pCommandBuffer.get(0), VKRegister.device);
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.callocStack(stack);
|
||||
beginInfo.sType(VK12.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO);
|
||||
beginInfo.flags(VK12.VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
|
||||
VK12.vkBeginCommandBuffer(commandBuffer, beginInfo);
|
||||
|
||||
return commandBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private void copyBuffer(long srcBuffer, long dstBuffer, long size) {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
|
||||
|
||||
VkBufferCopy.Buffer copyRegion = VkBufferCopy.callocStack(1, stack);
|
||||
copyRegion.size(size);
|
||||
|
||||
VK12.vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, copyRegion);
|
||||
|
||||
endSingleTimeCommands(commandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void memcpy(ByteBuffer buffer, float[] vertices) {
|
||||
|
||||
// buffer.putFloat(vertex.color.x());
|
||||
// buffer.putFloat(vertex.color.y());
|
||||
// buffer.putFloat(vertex.color.z());
|
||||
//
|
||||
// buffer.putFloat(vertex.texCoords.x());
|
||||
// buffer.putFloat(vertex.texCoords.y());
|
||||
int i = 0;
|
||||
for(float vertex : vertices) {
|
||||
buffer.putFloat(vertex);
|
||||
if(i == 2) {
|
||||
i = 0;
|
||||
buffer.putFloat(1);
|
||||
buffer.putFloat(1);
|
||||
buffer.putFloat(1);
|
||||
}
|
||||
i++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void createVertexBuffer() {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
long bufferSize = ((3 + 3 + 2) * Float.BYTES) * mesh.getVertices().length;
|
||||
|
||||
LongBuffer pBuffer = stack.mallocLong(1);
|
||||
LongBuffer pBufferMemory = stack.mallocLong(1);
|
||||
createBuffer(bufferSize,
|
||||
VK12.VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK12.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK12.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
pBuffer,
|
||||
pBufferMemory);
|
||||
|
||||
long stagingBuffer = pBuffer.get(0);
|
||||
long stagingBufferMemory = pBufferMemory.get(0);
|
||||
|
||||
PointerBuffer data = stack.mallocPointer(1);
|
||||
|
||||
VK12.vkMapMemory(VKRegister.device, stagingBufferMemory, 0, bufferSize, 0, data);
|
||||
{
|
||||
memcpy(data.getByteBuffer(0, (int) bufferSize), mesh.getVertices());
|
||||
}
|
||||
VK12.vkUnmapMemory(VKRegister.device, stagingBufferMemory);
|
||||
|
||||
createBuffer(bufferSize,
|
||||
VK12.VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK12.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
VK12.VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
||||
pBuffer,
|
||||
pBufferMemory);
|
||||
|
||||
vertexBuffer = pBuffer.get(0);
|
||||
vertexBufferMemory = pBufferMemory.get(0);
|
||||
|
||||
copyBuffer(stagingBuffer, vertexBuffer, bufferSize);
|
||||
|
||||
VK12.vkDestroyBuffer(VKRegister.device, stagingBuffer, null);
|
||||
VK12.vkFreeMemory(VKRegister.device, stagingBufferMemory, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void memcpy(ByteBuffer buffer, int[] indices) {
|
||||
|
||||
for(int index : indices) {
|
||||
buffer.putInt(index);
|
||||
}
|
||||
|
||||
buffer.rewind();
|
||||
}
|
||||
|
||||
private void createIndexBuffer() {
|
||||
|
||||
try(MemoryStack stack = stackPush()) {
|
||||
|
||||
long bufferSize = Integer.BYTES * mesh.getIndices().length;
|
||||
|
||||
LongBuffer pBuffer = stack.mallocLong(1);
|
||||
LongBuffer pBufferMemory = stack.mallocLong(1);
|
||||
createBuffer(bufferSize,
|
||||
VK12.VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK12.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK12.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
pBuffer,
|
||||
pBufferMemory);
|
||||
|
||||
long stagingBuffer = pBuffer.get(0);
|
||||
long stagingBufferMemory = pBufferMemory.get(0);
|
||||
|
||||
PointerBuffer data = stack.mallocPointer(1);
|
||||
|
||||
VK12.vkMapMemory(VKRegister.device, stagingBufferMemory, 0, bufferSize, 0, data);
|
||||
{
|
||||
memcpy(data.getByteBuffer(0, (int) bufferSize), mesh.getIndices());
|
||||
}
|
||||
VK12.vkUnmapMemory(VKRegister.device, stagingBufferMemory);
|
||||
|
||||
createBuffer(bufferSize,
|
||||
VK12.VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK12.VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||
VK12.VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
||||
pBuffer,
|
||||
pBufferMemory);
|
||||
|
||||
indexBuffer = pBuffer.get(0);
|
||||
indexBufferMemory = pBufferMemory.get(0);
|
||||
|
||||
copyBuffer(stagingBuffer, indexBuffer, bufferSize);
|
||||
|
||||
VK12.vkDestroyBuffer(VKRegister.device, stagingBuffer, null);
|
||||
VK12.vkFreeMemory(VKRegister.device, stagingBufferMemory, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.model;
|
||||
|
||||
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
||||
|
||||
public class VKVertices
|
||||
{
|
||||
public long vkVerticiesBuffer;
|
||||
public VkPipelineVertexInputStateCreateInfo createInfo;
|
||||
public float[] commonVerticies;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.registers;
|
||||
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.vulkan.model.VKModelData;
|
||||
|
||||
public class VKRegister
|
||||
{
|
||||
|
||||
public static VkDevice device;
|
||||
public static VkQueue queue;
|
||||
public static long commandPool;
|
||||
public static VkPhysicalDevice physicalDevice;
|
||||
public static VKModelData exampleVKModel;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,207 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.render;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.memAddress;
|
||||
import static org.lwjgl.system.MemoryUtil.memAlloc;
|
||||
import static org.lwjgl.system.MemoryUtil.memAllocInt;
|
||||
import static org.lwjgl.system.MemoryUtil.memAllocLong;
|
||||
import static org.lwjgl.system.MemoryUtil.memAllocPointer;
|
||||
import static org.lwjgl.system.MemoryUtil.memCopy;
|
||||
import static org.lwjgl.system.MemoryUtil.memFree;
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.vulkan.VK12;
|
||||
import org.lwjgl.vulkan.VkAttachmentDescription;
|
||||
import org.lwjgl.vulkan.VkAttachmentReference;
|
||||
import org.lwjgl.vulkan.VkBufferCreateInfo;
|
||||
import org.lwjgl.vulkan.VkDevice;
|
||||
import org.lwjgl.vulkan.VkFramebufferCreateInfo;
|
||||
import org.lwjgl.vulkan.VkMemoryAllocateInfo;
|
||||
import org.lwjgl.vulkan.VkMemoryRequirements;
|
||||
import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties;
|
||||
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
||||
import org.lwjgl.vulkan.VkRenderPassCreateInfo;
|
||||
import org.lwjgl.vulkan.VkSubpassDescription;
|
||||
import org.lwjgl.vulkan.VkVertexInputAttributeDescription;
|
||||
import org.lwjgl.vulkan.VkVertexInputBindingDescription;
|
||||
|
||||
import com.github.hydos.ginger.VulkanStarter.DepthStencil;
|
||||
import com.github.hydos.ginger.VulkanStarter.Swapchain;
|
||||
import com.github.hydos.ginger.engine.vulkan.memory.VKMemory;
|
||||
import com.github.hydos.ginger.engine.vulkan.model.VKVertices;
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
|
||||
|
||||
public class RenderUtils
|
||||
{
|
||||
|
||||
public static long createRenderPass(VkDevice device, int colorFormat, int depthFormat)
|
||||
{
|
||||
VkAttachmentDescription.Buffer attachments = VkAttachmentDescription.calloc(2);
|
||||
attachments.get(0) // <- color attachment
|
||||
.format(colorFormat)
|
||||
.samples(VK12.VK_SAMPLE_COUNT_1_BIT)
|
||||
.loadOp(VK12.VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK12.VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.stencilLoadOp(VK12.VK_ATTACHMENT_LOAD_OP_DONT_CARE)
|
||||
.stencilStoreOp(VK12.VK_ATTACHMENT_STORE_OP_DONT_CARE)
|
||||
.initialLayout(VK12.VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
.finalLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
attachments.get(1) // <- depth-stencil attachment
|
||||
.format(depthFormat)
|
||||
.samples(VK12.VK_SAMPLE_COUNT_1_BIT)
|
||||
.loadOp(VK12.VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK12.VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.stencilLoadOp(VK12.VK_ATTACHMENT_LOAD_OP_DONT_CARE)
|
||||
.stencilStoreOp(VK12.VK_ATTACHMENT_STORE_OP_DONT_CARE)
|
||||
.initialLayout(VK12.VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
.finalLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
VkAttachmentReference.Buffer colorReference = VkAttachmentReference.calloc(1)
|
||||
.attachment(0)
|
||||
.layout(VK12.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
VkAttachmentReference depthReference = VkAttachmentReference.calloc()
|
||||
.attachment(1)
|
||||
.layout(VK12.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
VkSubpassDescription.Buffer subpass = VkSubpassDescription.calloc(1)
|
||||
.pipelineBindPoint(VK12.VK_PIPELINE_BIND_POINT_GRAPHICS)
|
||||
.colorAttachmentCount(colorReference.remaining())
|
||||
.pColorAttachments(colorReference) // <- only color attachment
|
||||
.pDepthStencilAttachment(depthReference) // <- and depth-stencil
|
||||
;
|
||||
VkRenderPassCreateInfo renderPassInfo = VkRenderPassCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO)
|
||||
.pAttachments(attachments)
|
||||
.pSubpasses(subpass);
|
||||
LongBuffer pRenderPass = memAllocLong(1);
|
||||
int err = VK12.vkCreateRenderPass(device, renderPassInfo, null, pRenderPass);
|
||||
long renderPass = pRenderPass.get(0);
|
||||
memFree(pRenderPass);
|
||||
renderPassInfo.free();
|
||||
depthReference.free();
|
||||
colorReference.free();
|
||||
subpass.free();
|
||||
attachments.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create clear render pass: " + VKUtils.translateVulkanResult(err)); }
|
||||
return renderPass;
|
||||
}
|
||||
|
||||
public static long[] createFramebuffers(VkDevice device, Swapchain swapchain, long renderPass, int width, int height, DepthStencil depthStencil)
|
||||
{
|
||||
LongBuffer attachments = memAllocLong(2);
|
||||
attachments.put(1, depthStencil.view);
|
||||
VkFramebufferCreateInfo fci = VkFramebufferCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO)
|
||||
.pAttachments(attachments)
|
||||
.height(height)
|
||||
.width(width)
|
||||
.layers(1)
|
||||
.renderPass(renderPass);
|
||||
// Create a framebuffer for each swapchain image
|
||||
long[] framebuffers = new long[swapchain.images.length];
|
||||
LongBuffer pFramebuffer = memAllocLong(1);
|
||||
for (int i = 0; i < swapchain.images.length; i++)
|
||||
{
|
||||
attachments.put(0, swapchain.imageViews[i]);
|
||||
int err = VK12.vkCreateFramebuffer(device, fci, null, pFramebuffer);
|
||||
long framebuffer = pFramebuffer.get(0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create framebuffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
framebuffers[i] = framebuffer;
|
||||
}
|
||||
memFree(attachments);
|
||||
memFree(pFramebuffer);
|
||||
fci.free();
|
||||
return framebuffers;
|
||||
}
|
||||
|
||||
public static VKVertices createVertices(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device)
|
||||
{
|
||||
ByteBuffer vertexBuffer = memAlloc(2 * 3 * (3 + 3) * 4);
|
||||
FloatBuffer fb = vertexBuffer.asFloatBuffer();
|
||||
// first triangle
|
||||
fb.put(-0.5f).put(-0.5f).put(0.5f).put(1.0f).put(0.0f).put(0.0f);
|
||||
fb.put(0.5f).put(-0.5f).put(0.5f).put(0.0f).put(1.0f).put(0.0f);
|
||||
fb.put(0.0f).put(0.5f).put(0.5f).put(0.0f).put(0.0f).put(1.0f);
|
||||
// second triangle
|
||||
fb.put(0.5f).put(-0.5f).put(-0.5f).put(1.0f).put(1.0f).put(0.0f);
|
||||
fb.put(-0.5f).put(-0.5f).put(-0.5f).put(0.0f).put(1.0f).put(1.0f);
|
||||
fb.put(0.0f).put(0.5f).put(-0.5f).put(1.0f).put(0.0f).put(1.0f);
|
||||
VkMemoryAllocateInfo memAlloc = VkMemoryAllocateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
||||
VkMemoryRequirements memReqs = VkMemoryRequirements.calloc();
|
||||
int err;
|
||||
// Generate vertex buffer
|
||||
// Setup
|
||||
VkBufferCreateInfo bufInfo = VkBufferCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
|
||||
.size(vertexBuffer.remaining())
|
||||
.usage(VK12.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
LongBuffer pBuffer = memAllocLong(1);
|
||||
err = VK12.vkCreateBuffer(device, bufInfo, null, pBuffer);
|
||||
long verticesBuf = pBuffer.get(0);
|
||||
memFree(pBuffer);
|
||||
bufInfo.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create vertex buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
VK12.vkGetBufferMemoryRequirements(device, verticesBuf, memReqs);
|
||||
memAlloc.allocationSize(memReqs.size());
|
||||
IntBuffer memoryTypeIndex = memAllocInt(1);
|
||||
VKMemory.getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK12.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex);
|
||||
memAlloc.memoryTypeIndex(memoryTypeIndex.get(0));
|
||||
memFree(memoryTypeIndex);
|
||||
memReqs.free();
|
||||
LongBuffer pMemory = memAllocLong(1);
|
||||
err = VK12.vkAllocateMemory(device, memAlloc, null, pMemory);
|
||||
long verticesMem = pMemory.get(0);
|
||||
memFree(pMemory);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to allocate vertex memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
PointerBuffer pData = memAllocPointer(1);
|
||||
err = VK12.vkMapMemory(device, verticesMem, 0, vertexBuffer.remaining(), 0, pData);
|
||||
memAlloc.free();
|
||||
long data = pData.get(0);
|
||||
memFree(pData);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to map vertex memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
memCopy(memAddress(vertexBuffer), data, vertexBuffer.remaining());
|
||||
memFree(vertexBuffer);
|
||||
VK12.vkUnmapMemory(device, verticesMem);
|
||||
err = VK12.vkBindBufferMemory(device, verticesBuf, verticesMem, 0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to bind memory to vertex buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Binding description
|
||||
VkVertexInputBindingDescription.Buffer bindingDescriptor = VkVertexInputBindingDescription.calloc(1)
|
||||
.binding(0) // <- we bind our vertex buffer to point 0
|
||||
.stride((3 + 3) * 4)
|
||||
.inputRate(VK12.VK_VERTEX_INPUT_RATE_VERTEX);
|
||||
// Attribute descriptions
|
||||
// Describes memory layout and shader attribute locations
|
||||
VkVertexInputAttributeDescription.Buffer attributeDescriptions = VkVertexInputAttributeDescription.calloc(2);
|
||||
// Location 0 : Position
|
||||
attributeDescriptions.get(0)
|
||||
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
|
||||
.location(0) // <- location in the shader's attribute layout (inside the shader source)
|
||||
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(0);
|
||||
// Location 1 : Color
|
||||
attributeDescriptions.get(1)
|
||||
.binding(0) // <- binding point used in the VkVertexInputBindingDescription
|
||||
.location(1) // <- location in the shader's attribute layout (inside the shader source)
|
||||
.format(VK12.VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(3 * 4);
|
||||
// Assign to vertex buffer
|
||||
VkPipelineVertexInputStateCreateInfo vi = VkPipelineVertexInputStateCreateInfo.calloc();
|
||||
vi.sType(VK12.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
vi.pVertexBindingDescriptions(bindingDescriptor);
|
||||
vi.pVertexAttributeDescriptions(attributeDescriptions);
|
||||
VKVertices ret = new VKVertices();
|
||||
ret.createInfo = vi;
|
||||
ret.vkVerticiesBuffer = verticesBuf;
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.render.renderers;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.vulkan.registers.VKRegister;
|
||||
|
||||
public class EntityRenderer extends VKRenderer
|
||||
{
|
||||
|
||||
@Override
|
||||
public void render(MemoryStack stack, VkCommandBuffer renderCommandBuffer)
|
||||
{
|
||||
// //Bind the models buffers
|
||||
// LongBuffer offsets = memAllocLong(1);
|
||||
// offsets.put(0, 0L);
|
||||
// LongBuffer vertexBuffers = stack.longs(VKRegister.exampleVKModel.vertexBuffer);
|
||||
// VK12.vkCmdBindVertexBuffers(renderCommandBuffer, 0, vertexBuffers, offsets);
|
||||
// VK12.vkCmdBindIndexBuffer(renderCommandBuffer, VKRegister.exampleVKModel.indexBuffer, 0, 3);// 3 = VK_INDEX_TYPE_UINT32
|
||||
// memFree(offsets);
|
||||
//
|
||||
// //Render the texture
|
||||
// VK12.vkCmdDrawIndexed(renderCommandBuffer, VKRegister.exampleVKModel.mesh.getIndices().length, 1, 0, 0, 0);
|
||||
// FIXME: make master render get instance render with this instead, etc u get the point
|
||||
}
|
||||
|
||||
public static void tempStaticRender(MemoryStack stack, VkCommandBuffer renderCommandBuffer)
|
||||
{
|
||||
//Bind the models buffers
|
||||
LongBuffer offsets = memAllocLong(1);
|
||||
offsets.put(0, 0L);
|
||||
LongBuffer vertexBuffers = stack.longs(VKRegister.exampleVKModel.vertexBuffer);
|
||||
VK12.vkCmdBindVertexBuffers(renderCommandBuffer, 0, vertexBuffers, offsets);
|
||||
VK12.vkCmdBindIndexBuffer(renderCommandBuffer, VKRegister.exampleVKModel.indexBuffer, 0, 0);// 3 = VK_INDEX_TYPE_UINT32
|
||||
memFree(offsets);
|
||||
|
||||
//Render the texture
|
||||
VK12.vkCmdDrawIndexed(renderCommandBuffer, VKRegister.exampleVKModel.mesh.getIndices().length, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,324 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.render.renderers;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.memAllocInt;
|
||||
import static org.lwjgl.system.MemoryUtil.memAllocLong;
|
||||
import static org.lwjgl.system.MemoryUtil.memFree;
|
||||
import static org.lwjgl.vulkan.KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.VK_PRESENT_MODE_FIFO_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfaceFormatsKHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfacePresentModesKHR;
|
||||
import static org.lwjgl.vulkan.KHRSurface.vkGetPhysicalDeviceSurfaceSupportKHR;
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.vkCreateSwapchainKHR;
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.vkDestroySwapchainKHR;
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.vkGetSwapchainImagesKHR;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import org.lwjgl.vulkan.VK12;
|
||||
import org.lwjgl.vulkan.VkCommandBuffer;
|
||||
import org.lwjgl.vulkan.VkDevice;
|
||||
import org.lwjgl.vulkan.VkExtent2D;
|
||||
import org.lwjgl.vulkan.VkImageCreateInfo;
|
||||
import org.lwjgl.vulkan.VkImageViewCreateInfo;
|
||||
import org.lwjgl.vulkan.VkMemoryAllocateInfo;
|
||||
import org.lwjgl.vulkan.VkMemoryRequirements;
|
||||
import org.lwjgl.vulkan.VkPhysicalDevice;
|
||||
import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties;
|
||||
import org.lwjgl.vulkan.VkQueueFamilyProperties;
|
||||
import org.lwjgl.vulkan.VkSurfaceCapabilitiesKHR;
|
||||
import org.lwjgl.vulkan.VkSurfaceFormatKHR;
|
||||
import org.lwjgl.vulkan.VkSwapchainCreateInfoKHR;
|
||||
|
||||
import com.github.hydos.ginger.VulkanStarter;
|
||||
import com.github.hydos.ginger.VulkanStarter.ColorAndDepthFormatAndSpace;
|
||||
import com.github.hydos.ginger.VulkanStarter.DepthStencil;
|
||||
import com.github.hydos.ginger.VulkanStarter.Swapchain;
|
||||
import com.github.hydos.ginger.engine.common.io.Window;
|
||||
import com.github.hydos.ginger.engine.vulkan.memory.VKMemory;
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
|
||||
|
||||
public class VKMasterRenderer
|
||||
{
|
||||
|
||||
public static ColorAndDepthFormatAndSpace getColorFormatAndSpace(VkPhysicalDevice physicalDevice, long surface)
|
||||
{
|
||||
IntBuffer pQueueFamilyPropertyCount = memAllocInt(1);
|
||||
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, null);
|
||||
int queueCount = pQueueFamilyPropertyCount.get(0);
|
||||
VkQueueFamilyProperties.Buffer queueProps = VkQueueFamilyProperties.calloc(queueCount);
|
||||
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, queueProps);
|
||||
memFree(pQueueFamilyPropertyCount);
|
||||
// Iterate over each queue to learn whether it supports presenting:
|
||||
IntBuffer supportsPresent = memAllocInt(queueCount);
|
||||
for (int i = 0; i < queueCount; i++)
|
||||
{
|
||||
supportsPresent.position(i);
|
||||
int err = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, supportsPresent);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to physical device surface support: " + VKUtils.translateVulkanResult(err)); }
|
||||
}
|
||||
// Search for a graphics and a present queue in the array of queue families, try to find one that supports both
|
||||
int graphicsQueueNodeIndex = Integer.MAX_VALUE;
|
||||
int presentQueueNodeIndex = Integer.MAX_VALUE;
|
||||
for (int i = 0; i < queueCount; i++)
|
||||
{
|
||||
if ((queueProps.get(i).queueFlags() & VK12.VK_QUEUE_GRAPHICS_BIT) != 0)
|
||||
{
|
||||
if (graphicsQueueNodeIndex == Integer.MAX_VALUE)
|
||||
{ graphicsQueueNodeIndex = i; }
|
||||
if (supportsPresent.get(i) == VK12.VK_TRUE)
|
||||
{
|
||||
graphicsQueueNodeIndex = i;
|
||||
presentQueueNodeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
queueProps.free();
|
||||
if (presentQueueNodeIndex == Integer.MAX_VALUE)
|
||||
{
|
||||
// If there's no queue that supports both present and graphics try to find a separate present queue
|
||||
for (int i = 0; i < queueCount; ++i)
|
||||
{
|
||||
if (supportsPresent.get(i) == VK12.VK_TRUE)
|
||||
{
|
||||
presentQueueNodeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
memFree(supportsPresent);
|
||||
// Generate error if could not find both a graphics and a present queue
|
||||
if (graphicsQueueNodeIndex == Integer.MAX_VALUE)
|
||||
{ throw new AssertionError("No graphics queue found"); }
|
||||
if (presentQueueNodeIndex == Integer.MAX_VALUE)
|
||||
{ throw new AssertionError("No presentation queue found"); }
|
||||
if (graphicsQueueNodeIndex != presentQueueNodeIndex)
|
||||
{ throw new AssertionError("Presentation queue != graphics queue"); }
|
||||
// Get list of supported formats
|
||||
IntBuffer pFormatCount = memAllocInt(1);
|
||||
int err = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pFormatCount, null);
|
||||
int formatCount = pFormatCount.get(0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to query number of physical device surface formats: " + VKUtils.translateVulkanResult(err)); }
|
||||
VkSurfaceFormatKHR.Buffer surfFormats = VkSurfaceFormatKHR.calloc(formatCount);
|
||||
err = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pFormatCount, surfFormats);
|
||||
memFree(pFormatCount);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to query physical device surface formats: " + VKUtils.translateVulkanResult(err)); }
|
||||
int colorFormat;
|
||||
if (formatCount == 1 && surfFormats.get(0).format() == VK12.VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
colorFormat = VK12.VK_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorFormat = surfFormats.get(0).format();
|
||||
}
|
||||
int colorSpace = surfFormats.get(0).colorSpace();
|
||||
surfFormats.free();
|
||||
// Find suitable depth format
|
||||
IntBuffer pDepthFormat = memAllocInt(1).put(0, -1);
|
||||
VulkanStarter.getSupportedDepthFormat(physicalDevice, pDepthFormat);
|
||||
int depthFormat = pDepthFormat.get(0);
|
||||
ColorAndDepthFormatAndSpace ret = new ColorAndDepthFormatAndSpace();
|
||||
ret.colorFormat = colorFormat;
|
||||
ret.colorSpace = colorSpace;
|
||||
ret.depthFormat = depthFormat;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static DepthStencil createDepthStencil(VkDevice device, VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties, int depthFormat, VkCommandBuffer setupCmdBuffer)
|
||||
{
|
||||
VkImageCreateInfo imageCreateInfo = VkImageCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO)
|
||||
.imageType(VK12.VK_IMAGE_TYPE_2D)
|
||||
.format(depthFormat)
|
||||
.mipLevels(1)
|
||||
.arrayLayers(1)
|
||||
.samples(VK12.VK_SAMPLE_COUNT_1_BIT)
|
||||
.tiling(VK12.VK_IMAGE_TILING_OPTIMAL)
|
||||
.usage(VK12.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK12.VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
|
||||
imageCreateInfo.extent().width(Window.getWidth()).height(Window.getHeight()).depth(1);
|
||||
VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
||||
VkImageViewCreateInfo depthStencilViewCreateInfo = VkImageViewCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO)
|
||||
.viewType(VK12.VK_IMAGE_VIEW_TYPE_2D)
|
||||
.format(depthFormat);
|
||||
depthStencilViewCreateInfo.subresourceRange()
|
||||
.aspectMask(VK12.VK_IMAGE_ASPECT_DEPTH_BIT | VK12.VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
.levelCount(1)
|
||||
.layerCount(1);
|
||||
VkMemoryRequirements memReqs = VkMemoryRequirements.calloc();
|
||||
int err;
|
||||
LongBuffer pDepthStencilImage = memAllocLong(1);
|
||||
err = VK12.vkCreateImage(device, imageCreateInfo, null, pDepthStencilImage);
|
||||
long depthStencilImage = pDepthStencilImage.get(0);
|
||||
memFree(pDepthStencilImage);
|
||||
imageCreateInfo.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create depth-stencil image: " + VKUtils.translateVulkanResult(err)); }
|
||||
VK12.vkGetImageMemoryRequirements(device, depthStencilImage, memReqs);
|
||||
mem_alloc.allocationSize(memReqs.size());
|
||||
IntBuffer pMemoryTypeIndex = memAllocInt(1);
|
||||
VKMemory.getMemoryType(physicalDeviceMemoryProperties, memReqs.memoryTypeBits(), VK12.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pMemoryTypeIndex);
|
||||
mem_alloc.memoryTypeIndex(pMemoryTypeIndex.get(0));
|
||||
memFree(pMemoryTypeIndex);
|
||||
LongBuffer pDepthStencilMem = memAllocLong(1);
|
||||
err = VK12.vkAllocateMemory(device, mem_alloc, null, pDepthStencilMem);
|
||||
long depthStencilMem = pDepthStencilMem.get(0);
|
||||
memFree(pDepthStencilMem);
|
||||
mem_alloc.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create depth-stencil memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
err = VK12.vkBindImageMemory(device, depthStencilImage, depthStencilMem, 0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to bind depth-stencil image to memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
depthStencilViewCreateInfo.image(depthStencilImage);
|
||||
LongBuffer pDepthStencilView = memAllocLong(1);
|
||||
err = VK12.vkCreateImageView(device, depthStencilViewCreateInfo, null, pDepthStencilView);
|
||||
long depthStencilView = pDepthStencilView.get(0);
|
||||
memFree(pDepthStencilView);
|
||||
depthStencilViewCreateInfo.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create depth-stencil image view: " + VKUtils.translateVulkanResult(err)); }
|
||||
DepthStencil ret = new DepthStencil();
|
||||
ret.view = depthStencilView;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Swapchain createSwapChain(VkDevice device, VkPhysicalDevice physicalDevice, long surface, long oldSwapChain, VkCommandBuffer commandBuffer, int newWidth,
|
||||
int newHeight, int colorFormat, int colorSpace)
|
||||
{
|
||||
int err;
|
||||
// Get physical device surface properties and formats
|
||||
VkSurfaceCapabilitiesKHR surfCaps = VkSurfaceCapabilitiesKHR.calloc();
|
||||
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, surfCaps);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to get physical device surface capabilities: " + VKUtils.translateVulkanResult(err)); }
|
||||
IntBuffer pPresentModeCount = memAllocInt(1);
|
||||
err = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, null);
|
||||
int presentModeCount = pPresentModeCount.get(0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to get number of physical device surface presentation modes: " + VKUtils.translateVulkanResult(err)); }
|
||||
IntBuffer pPresentModes = memAllocInt(presentModeCount);
|
||||
err = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes);
|
||||
memFree(pPresentModeCount);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to get physical device surface presentation modes: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Try to use mailbox mode. Low latency and non-tearing
|
||||
int swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
for (int i = 0; i < presentModeCount; i++)
|
||||
{
|
||||
if (pPresentModes.get(i) == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||
{
|
||||
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
break;
|
||||
}
|
||||
if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (pPresentModes.get(i) == VK_PRESENT_MODE_IMMEDIATE_KHR))
|
||||
{ swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; }
|
||||
}
|
||||
memFree(pPresentModes);
|
||||
// Determine the number of images
|
||||
int desiredNumberOfSwapchainImages = surfCaps.minImageCount() + 1;
|
||||
if ((surfCaps.maxImageCount() > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount()))
|
||||
{ desiredNumberOfSwapchainImages = surfCaps.maxImageCount(); }
|
||||
VkExtent2D currentExtent = surfCaps.currentExtent();
|
||||
int currentWidth = currentExtent.width();
|
||||
int currentHeight = currentExtent.height();
|
||||
if (currentWidth != -1 && currentHeight != -1)
|
||||
{
|
||||
Window.width = currentWidth;
|
||||
Window.height = currentHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
Window.width = newWidth;
|
||||
Window.height = newHeight;
|
||||
}
|
||||
int preTransform;
|
||||
if ((surfCaps.supportedTransforms() & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) != 0)
|
||||
{
|
||||
preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||
}
|
||||
else
|
||||
{
|
||||
preTransform = surfCaps.currentTransform();
|
||||
}
|
||||
surfCaps.free();
|
||||
VkSwapchainCreateInfoKHR swapchainCI = VkSwapchainCreateInfoKHR.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR)
|
||||
.surface(surface)
|
||||
.minImageCount(desiredNumberOfSwapchainImages)
|
||||
.imageFormat(colorFormat)
|
||||
.imageColorSpace(colorSpace)
|
||||
.imageUsage(VK12.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
.preTransform(preTransform)
|
||||
.imageArrayLayers(1)
|
||||
.imageSharingMode(VK12.VK_SHARING_MODE_EXCLUSIVE)
|
||||
.presentMode(swapchainPresentMode)
|
||||
.oldSwapchain(oldSwapChain)
|
||||
.clipped(true)
|
||||
.compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
||||
swapchainCI.imageExtent()
|
||||
.width(Window.getWidth())
|
||||
.height(Window.getHeight());
|
||||
LongBuffer pSwapChain = memAllocLong(1);
|
||||
err = vkCreateSwapchainKHR(device, swapchainCI, null, pSwapChain);
|
||||
swapchainCI.free();
|
||||
long swapChain = pSwapChain.get(0);
|
||||
memFree(pSwapChain);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create swap chain: " + VKUtils.translateVulkanResult(err)); }
|
||||
// If we just re-created an existing swapchain, we should destroy the old swapchain at this point.
|
||||
// Note: destroying the swapchain also cleans up all its associated presentable images once the platform is done with them.
|
||||
if (oldSwapChain != VK12.VK_NULL_HANDLE)
|
||||
{ vkDestroySwapchainKHR(device, oldSwapChain, null); }
|
||||
IntBuffer pImageCount = memAllocInt(1);
|
||||
err = vkGetSwapchainImagesKHR(device, swapChain, pImageCount, null);
|
||||
int imageCount = pImageCount.get(0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to get number of swapchain images: " + VKUtils.translateVulkanResult(err)); }
|
||||
LongBuffer pSwapchainImages = memAllocLong(imageCount);
|
||||
err = vkGetSwapchainImagesKHR(device, swapChain, pImageCount, pSwapchainImages);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to get swapchain images: " + VKUtils.translateVulkanResult(err)); }
|
||||
memFree(pImageCount);
|
||||
long[] images = new long[imageCount];
|
||||
long[] imageViews = new long[imageCount];
|
||||
LongBuffer pBufferView = memAllocLong(1);
|
||||
VkImageViewCreateInfo colorAttachmentView = VkImageViewCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO)
|
||||
.format(colorFormat)
|
||||
.viewType(VK12.VK_IMAGE_VIEW_TYPE_2D);
|
||||
colorAttachmentView.subresourceRange()
|
||||
.aspectMask(VK12.VK_IMAGE_ASPECT_COLOR_BIT)
|
||||
.levelCount(1)
|
||||
.layerCount(1);
|
||||
for (int i = 0; i < imageCount; i++)
|
||||
{
|
||||
images[i] = pSwapchainImages.get(i);
|
||||
colorAttachmentView.image(images[i]);
|
||||
err = VK12.vkCreateImageView(device, colorAttachmentView, null, pBufferView);
|
||||
imageViews[i] = pBufferView.get(0);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create image view: " + VKUtils.translateVulkanResult(err)); }
|
||||
}
|
||||
colorAttachmentView.free();
|
||||
memFree(pBufferView);
|
||||
memFree(pSwapchainImages);
|
||||
Swapchain ret = new Swapchain();
|
||||
ret.images = images;
|
||||
ret.imageViews = imageViews;
|
||||
ret.swapchainHandle = swapChain;
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.render.renderers;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VkCommandBuffer;
|
||||
|
||||
public abstract class VKRenderer
|
||||
{
|
||||
|
||||
public abstract void render(MemoryStack stack, VkCommandBuffer renderCommandBuffer);
|
||||
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.render.ubo;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
import java.nio.*;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.io.Window;
|
||||
import com.github.hydos.ginger.engine.vulkan.memory.VKMemory;
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
|
||||
/**
|
||||
* A UBO is a uniform buffer object
|
||||
* i believe its used to give data from code to the shaders
|
||||
* @author hydos
|
||||
*
|
||||
*/
|
||||
public class Ubo {
|
||||
|
||||
public UboDescriptor uboData;
|
||||
|
||||
public Ubo(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device)
|
||||
{
|
||||
int err;
|
||||
// Create a new buffer
|
||||
VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
|
||||
.size(16 * 4)
|
||||
.usage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
LongBuffer pUniformDataVSBuffer = memAllocLong(1);
|
||||
err = vkCreateBuffer(device, bufferInfo, null, pUniformDataVSBuffer);
|
||||
long uniformDataVSBuffer = pUniformDataVSBuffer.get(0);
|
||||
memFree(pUniformDataVSBuffer);
|
||||
bufferInfo.free();
|
||||
if (err != VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create UBO buffer: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Get memory requirements including size, alignment and memory type
|
||||
VkMemoryRequirements memReqs = VkMemoryRequirements.calloc();
|
||||
vkGetBufferMemoryRequirements(device, uniformDataVSBuffer, memReqs);
|
||||
long memSize = memReqs.size();
|
||||
int memoryTypeBits = memReqs.memoryTypeBits();
|
||||
memReqs.free();
|
||||
// Gets the appropriate memory type for this type of buffer allocation
|
||||
// Only memory types that are visible to the host
|
||||
IntBuffer pMemoryTypeIndex = memAllocInt(1);
|
||||
VKMemory.getMemoryType(deviceMemoryProperties, memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, pMemoryTypeIndex);
|
||||
int memoryTypeIndex = pMemoryTypeIndex.get(0);
|
||||
memFree(pMemoryTypeIndex);
|
||||
// Allocate memory for the uniform buffer
|
||||
LongBuffer pUniformDataVSMemory = memAllocLong(1);
|
||||
VkMemoryAllocateInfo allocInfo = VkMemoryAllocateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO)
|
||||
.allocationSize(memSize)
|
||||
.memoryTypeIndex(memoryTypeIndex);
|
||||
err = vkAllocateMemory(device, allocInfo, null, pUniformDataVSMemory);
|
||||
long uniformDataVSMemory = pUniformDataVSMemory.get(0);
|
||||
memFree(pUniformDataVSMemory);
|
||||
allocInfo.free();
|
||||
if (err != VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to allocate UBO memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Bind memory to buffer
|
||||
err = vkBindBufferMemory(device, uniformDataVSBuffer, uniformDataVSMemory, 0);
|
||||
if (err != VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to bind UBO memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
UboDescriptor ret = new UboDescriptor();
|
||||
ret.memory = uniformDataVSMemory;
|
||||
ret.buffer = uniformDataVSBuffer;
|
||||
ret.offset = 0L;
|
||||
ret.range = 16 * 4;
|
||||
this.uboData = ret;
|
||||
}
|
||||
|
||||
public void updateUbo(VkDevice device, float angle)
|
||||
{
|
||||
Matrix4f m = new Matrix4f()
|
||||
.scale(1, -1, 1) // <- correcting viewport transformation (what Direct3D does, too)
|
||||
.perspective((float) Math.toRadians(45.0f), (float) Window.getWidth() / Window.getHeight(), 0.1f, 10.0f, true)
|
||||
.lookAt(0, 1, 3,
|
||||
0, 0, 0,
|
||||
0, 1, 0)
|
||||
.rotateY(angle);
|
||||
PointerBuffer pData = memAllocPointer(1);
|
||||
int err = vkMapMemory(device, uboData.memory, 0, 16 * 4, 0, pData);
|
||||
long data = pData.get(0);
|
||||
memFree(pData);
|
||||
if (err != VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to map UBO memory: " + VKUtils.translateVulkanResult(err)); }
|
||||
ByteBuffer matrixBuffer = memByteBuffer(data, 16 * 4);
|
||||
m.get(matrixBuffer);
|
||||
vkUnmapMemory(device, uboData.memory);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.render.ubo;
|
||||
|
||||
public class UboDescriptor
|
||||
{
|
||||
public long memory; //Memory location
|
||||
public long buffer; //the Buffer?
|
||||
public long offset; //some offset from the memory location
|
||||
public long range; // the size
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.shaders;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.*;
|
||||
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
|
||||
|
||||
public class Pipeline
|
||||
{
|
||||
public long pipeline;
|
||||
public long layout;
|
||||
|
||||
public static Pipeline createPipeline(VkDevice device, long renderPass, VkPipelineVertexInputStateCreateInfo vi, long descriptorSetLayout) throws IOException
|
||||
{
|
||||
int err;
|
||||
// Vertex input state
|
||||
// Describes the topoloy used with this pipeline
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = VkPipelineInputAssemblyStateCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO)
|
||||
.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||
// Rasterization state
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO)
|
||||
.polygonMode(VK_POLYGON_MODE_FILL)
|
||||
.cullMode(VK_CULL_MODE_NONE) // <- VK_CULL_MODE_BACK_BIT would work here, too!
|
||||
.frontFace(VK_FRONT_FACE_COUNTER_CLOCKWISE)
|
||||
.lineWidth(1.0f);
|
||||
// Color blend state
|
||||
// Describes blend modes and color masks
|
||||
VkPipelineColorBlendAttachmentState.Buffer colorWriteMask = VkPipelineColorBlendAttachmentState.calloc(1)
|
||||
.colorWriteMask(0xF); // <- RGBA
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendState = VkPipelineColorBlendStateCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO)
|
||||
.pAttachments(colorWriteMask);
|
||||
// Viewport state
|
||||
VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO)
|
||||
.viewportCount(1) // <- one viewport
|
||||
.scissorCount(1); // <- one scissor rectangle
|
||||
// Enable dynamic states
|
||||
// Describes the dynamic states to be used with this pipeline
|
||||
// Dynamic states can be set even after the pipeline has been created
|
||||
// So there is no need to create new pipelines just for changing
|
||||
// a viewport's dimensions or a scissor box
|
||||
IntBuffer pDynamicStates = memAllocInt(2);
|
||||
pDynamicStates.put(VK_DYNAMIC_STATE_VIEWPORT).put(VK_DYNAMIC_STATE_SCISSOR).flip();
|
||||
VkPipelineDynamicStateCreateInfo dynamicState = VkPipelineDynamicStateCreateInfo.calloc()
|
||||
// The dynamic state properties themselves are stored in the command buffer
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO)
|
||||
.pDynamicStates(pDynamicStates);
|
||||
// Depth and stencil state
|
||||
// Describes depth and stenctil test and compare ops
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState = VkPipelineDepthStencilStateCreateInfo.calloc()
|
||||
// No depth test/write and no stencil used
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
|
||||
.depthTestEnable(true)
|
||||
.depthWriteEnable(true)
|
||||
.depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||
depthStencilState.back()
|
||||
.failOp(VK_STENCIL_OP_KEEP)
|
||||
.passOp(VK_STENCIL_OP_KEEP)
|
||||
.compareOp(VK_COMPARE_OP_ALWAYS);
|
||||
depthStencilState.front(depthStencilState.back());
|
||||
// Multi sampling state
|
||||
// No multi sampling used in this example
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState = VkPipelineMultisampleStateCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO)
|
||||
.rasterizationSamples(VK_SAMPLE_COUNT_1_BIT);
|
||||
// Load shaders
|
||||
VkPipelineShaderStageCreateInfo.Buffer shaderStages = VkPipelineShaderStageCreateInfo.calloc(2);
|
||||
shaderStages.get(0).set(VKShaderManager.loadShader(device, "/vulkan/shaders/entityVertexShader.glsl", VK_SHADER_STAGE_VERTEX_BIT));
|
||||
shaderStages.get(1).set(VKShaderManager.loadShader(device, "/vulkan/shaders/entityFragmentShader.glsl", VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
// Create the pipeline layout that is used to generate the rendering pipelines that
|
||||
// are based on this descriptor set layout
|
||||
LongBuffer pDescriptorSetLayout = memAllocLong(1).put(0, descriptorSetLayout);
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = VkPipelineLayoutCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO)
|
||||
.pSetLayouts(pDescriptorSetLayout);
|
||||
LongBuffer pPipelineLayout = memAllocLong(1);
|
||||
err = vkCreatePipelineLayout(device, pipelineLayoutCreateInfo, null, pPipelineLayout);
|
||||
long layout = pPipelineLayout.get(0);
|
||||
memFree(pPipelineLayout);
|
||||
pipelineLayoutCreateInfo.free();
|
||||
memFree(pDescriptorSetLayout);
|
||||
if (err != VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create pipeline layout: " + VKUtils.translateVulkanResult(err)); }
|
||||
// Assign states
|
||||
VkGraphicsPipelineCreateInfo.Buffer pipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1)
|
||||
.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO)
|
||||
.layout(layout) // <- the layout used for this pipeline (NEEDS TO BE SET! even though it is basically empty)
|
||||
.renderPass(renderPass) // <- renderpass this pipeline is attached to
|
||||
.pVertexInputState(vi)
|
||||
.pInputAssemblyState(inputAssemblyState)
|
||||
.pRasterizationState(rasterizationState)
|
||||
.pColorBlendState(colorBlendState)
|
||||
.pMultisampleState(multisampleState)
|
||||
.pViewportState(viewportState)
|
||||
.pDepthStencilState(depthStencilState)
|
||||
.pStages(shaderStages)
|
||||
.pDynamicState(dynamicState);
|
||||
// Create rendering pipeline
|
||||
LongBuffer pPipelines = memAllocLong(1);
|
||||
err = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, pipelineCreateInfo, null, pPipelines);
|
||||
long pipeline = pPipelines.get(0);
|
||||
shaderStages.free();
|
||||
multisampleState.free();
|
||||
depthStencilState.free();
|
||||
dynamicState.free();
|
||||
memFree(pDynamicStates);
|
||||
viewportState.free();
|
||||
colorBlendState.free();
|
||||
colorWriteMask.free();
|
||||
rasterizationState.free();
|
||||
inputAssemblyState.free();
|
||||
if (err != VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create pipeline: " + VKUtils.translateVulkanResult(err)); }
|
||||
com.github.hydos.ginger.engine.vulkan.shaders.Pipeline ret = new com.github.hydos.ginger.engine.vulkan.shaders.Pipeline();
|
||||
ret.layout = layout;
|
||||
ret.pipeline = pipeline;
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.shaders;
|
||||
|
||||
public class ShaderType
|
||||
{
|
||||
public final static int vertexShader = 0;
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.shaders;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.*;
|
||||
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.vulkan.utils.VKUtils;
|
||||
|
||||
public class VKShaderManager {
|
||||
|
||||
public static VkPipelineShaderStageCreateInfo loadShader(VkDevice device, String classPath, int stage) throws IOException
|
||||
{
|
||||
VkPipelineShaderStageCreateInfo shaderStage = VkPipelineShaderStageCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO)
|
||||
.stage(stage)
|
||||
.module(VKShaderManager.loadShader(classPath, device, stage))
|
||||
.pName(memUTF8("main"));
|
||||
return shaderStage;
|
||||
}
|
||||
|
||||
public static long loadShader(String classPath, VkDevice device, int stage) throws IOException
|
||||
{
|
||||
ByteBuffer shaderCode = VKUtils.glslToSpirv(classPath, stage);
|
||||
int err;
|
||||
VkShaderModuleCreateInfo moduleCreateInfo = VkShaderModuleCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO)
|
||||
.pCode(shaderCode);
|
||||
LongBuffer pShaderModule = memAllocLong(1);
|
||||
err = vkCreateShaderModule(device, moduleCreateInfo, null, pShaderModule);
|
||||
long shaderModule = pShaderModule.get(0);
|
||||
memFree(pShaderModule);
|
||||
if (err != VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create shader module: " + VKUtils.translateVulkanResult(err)); }
|
||||
return shaderModule;
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.utils;
|
||||
|
||||
public class VKBufferUtils
|
||||
{
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.utils;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME;
|
||||
|
||||
import java.nio.*;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.vulkan.VKConstants;
|
||||
|
||||
public class VKDeviceProperties {
|
||||
public VkDevice device;
|
||||
public int queueFamilyIndex;
|
||||
public VkPhysicalDeviceMemoryProperties memoryProperties;
|
||||
|
||||
public static VkPhysicalDevice getFirstPhysicalDevice(VkInstance instance)
|
||||
{
|
||||
IntBuffer pPhysicalDeviceCount = memAllocInt(1);
|
||||
int err = VK12.vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, null);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to get number of physical devices: " + VKUtils.translateVulkanResult(err)); }
|
||||
PointerBuffer pPhysicalDevices = memAllocPointer(pPhysicalDeviceCount.get(0));
|
||||
err = VK12.vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
|
||||
long physicalDevice = pPhysicalDevices.get(0);
|
||||
memFree(pPhysicalDeviceCount);
|
||||
memFree(pPhysicalDevices);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to get physical devices: " + VKUtils.translateVulkanResult(err)); }
|
||||
return new VkPhysicalDevice(physicalDevice, instance);
|
||||
}
|
||||
|
||||
public static VKDeviceProperties initDeviceProperties(VkPhysicalDevice physicalDevice)
|
||||
{
|
||||
IntBuffer pQueueFamilyPropertyCount = memAllocInt(1);
|
||||
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, null);
|
||||
int queueCount = pQueueFamilyPropertyCount.get(0);
|
||||
VkQueueFamilyProperties.Buffer queueProps = VkQueueFamilyProperties.calloc(queueCount);
|
||||
VK12.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, queueProps);
|
||||
memFree(pQueueFamilyPropertyCount);
|
||||
int graphicsQueueFamilyIndex;
|
||||
for (graphicsQueueFamilyIndex = 0; graphicsQueueFamilyIndex < queueCount; graphicsQueueFamilyIndex++)
|
||||
{ if ((queueProps.get(graphicsQueueFamilyIndex).queueFlags() & VK12.VK_QUEUE_GRAPHICS_BIT) != 0)
|
||||
break; }
|
||||
queueProps.free();
|
||||
FloatBuffer pQueuePriorities = memAllocFloat(1).put(0.0f);
|
||||
pQueuePriorities.flip();
|
||||
VkDeviceQueueCreateInfo.Buffer queueCreateInfo = VkDeviceQueueCreateInfo.calloc(1)
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO)
|
||||
.queueFamilyIndex(graphicsQueueFamilyIndex)
|
||||
.pQueuePriorities(pQueuePriorities);
|
||||
PointerBuffer extensions = memAllocPointer(1);
|
||||
ByteBuffer VK_KHR_SWAPCHAIN_EXTENSION = memUTF8(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
extensions.put(VK_KHR_SWAPCHAIN_EXTENSION);
|
||||
extensions.flip();
|
||||
PointerBuffer ppEnabledLayerNames = memAllocPointer(VKConstants.layers.length);
|
||||
for (int i = 0; VKConstants.debug && i < VKConstants.layers.length; i++)
|
||||
ppEnabledLayerNames.put(VKConstants.layers[i]);
|
||||
ppEnabledLayerNames.flip();
|
||||
VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.calloc()
|
||||
.sType(VK12.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO)
|
||||
.pQueueCreateInfos(queueCreateInfo)
|
||||
.ppEnabledExtensionNames(extensions)
|
||||
.ppEnabledLayerNames(ppEnabledLayerNames);
|
||||
PointerBuffer pDevice = memAllocPointer(1);
|
||||
int err = VK12.vkCreateDevice(physicalDevice, deviceCreateInfo, null, pDevice);
|
||||
long device = pDevice.get(0);
|
||||
memFree(pDevice);
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create device: " + VKUtils.translateVulkanResult(err)); }
|
||||
VkPhysicalDeviceMemoryProperties memoryProperties = VkPhysicalDeviceMemoryProperties.calloc();
|
||||
VK12.vkGetPhysicalDeviceMemoryProperties(physicalDevice, memoryProperties);
|
||||
VKDeviceProperties ret = new VKDeviceProperties();
|
||||
ret.device = new VkDevice(device, physicalDevice, deviceCreateInfo);
|
||||
ret.queueFamilyIndex = graphicsQueueFamilyIndex;
|
||||
ret.memoryProperties = memoryProperties;
|
||||
deviceCreateInfo.free();
|
||||
memFree(ppEnabledLayerNames);
|
||||
memFree(VK_KHR_SWAPCHAIN_EXTENSION);
|
||||
memFree(extensions);
|
||||
memFree(pQueuePriorities);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.utils;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
import static org.lwjgl.vulkan.EXTDebugReport.VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK12.VK_API_VERSION_1_2;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.vulkan.VKConstants;
|
||||
|
||||
/** @author hydos
|
||||
* used to load vulkan related objects such as textures */
|
||||
public class VKLoader
|
||||
{
|
||||
public static VkInstance createInstance(PointerBuffer requiredExtensions) {
|
||||
VkApplicationInfo appInfo = VkApplicationInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_APPLICATION_INFO)
|
||||
.apiVersion(VK_API_VERSION_1_2);
|
||||
PointerBuffer ppEnabledExtensionNames = memAllocPointer(requiredExtensions.remaining() + 1);
|
||||
ppEnabledExtensionNames.put(requiredExtensions);
|
||||
ByteBuffer VK_EXT_DEBUG_REPORT_EXTENSION = memUTF8(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||
ppEnabledExtensionNames.put(VK_EXT_DEBUG_REPORT_EXTENSION);
|
||||
ppEnabledExtensionNames.flip();
|
||||
PointerBuffer ppEnabledLayerNames = memAllocPointer(VKConstants.layers.length);
|
||||
for (int i = 0; VKConstants.debug && i < VKConstants.layers.length; i++)
|
||||
ppEnabledLayerNames.put(VKConstants.layers[i]);
|
||||
ppEnabledLayerNames.flip();
|
||||
VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO)
|
||||
.pApplicationInfo(appInfo)
|
||||
.ppEnabledExtensionNames(ppEnabledExtensionNames)
|
||||
.ppEnabledLayerNames(ppEnabledLayerNames);
|
||||
PointerBuffer pInstance = memAllocPointer(1);
|
||||
int err = vkCreateInstance(pCreateInfo, null, pInstance);
|
||||
long instance = pInstance.get(0);
|
||||
memFree(pInstance);
|
||||
if (err != VK_SUCCESS) {
|
||||
throw new AssertionError("Failed to create VkInstance: " + VKUtils.translateVulkanResult(err));
|
||||
}
|
||||
VkInstance ret = new VkInstance(instance, pCreateInfo);
|
||||
pCreateInfo.free();
|
||||
memFree(ppEnabledLayerNames);
|
||||
memFree(VK_EXT_DEBUG_REPORT_EXTENSION);
|
||||
memFree(ppEnabledExtensionNames);
|
||||
memFree(appInfo.pApplicationName());
|
||||
memFree(appInfo.pEngineName());
|
||||
appInfo.free();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void setupVulkan()
|
||||
{}
|
||||
}
|
|
@ -1,266 +1,242 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.utils;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
import static org.lwjgl.util.shaderc.Shaderc.*;
|
||||
import static org.lwjgl.vulkan.EXTDebugReport.*;
|
||||
import static org.lwjgl.vulkan.KHRSurface.*;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.*;
|
||||
|
||||
import org.lwjgl.*;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.*;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.shaderc.*;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.common.io.Window;
|
||||
import com.github.hydos.ginger.engine.common.tools.IOUtil;
|
||||
import com.github.hydos.ginger.engine.vulkan.VKConstants;
|
||||
import com.github.hydos.ginger.engine.vulkan.render.renderers.EntityRenderer;
|
||||
import com.github.hydos.ginger.engine.vulkan.shaders.Pipeline;
|
||||
import com.github.hydos.ginger.engine.vulkan.VkConstants;
|
||||
|
||||
/** @author hydos
|
||||
* a util library for Vulkan */
|
||||
public class VKUtils
|
||||
public class VkUtils
|
||||
{
|
||||
|
||||
public static final int VK_FLAGS_NONE = 0;
|
||||
private static PointerBuffer getRequiredExtensions() {
|
||||
|
||||
public static long startVulkanDebugging(VkInstance instance, int flags, VkDebugReportCallbackEXT callback)
|
||||
{
|
||||
VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = VkDebugReportCallbackCreateInfoEXT.calloc()
|
||||
.sType(VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT)
|
||||
.pfnCallback(callback)
|
||||
.flags(flags);
|
||||
LongBuffer pCallback = memAllocLong(1);
|
||||
int err = vkCreateDebugReportCallbackEXT(instance, dbgCreateInfo, null, pCallback);
|
||||
long callbackHandle = pCallback.get(0);
|
||||
memFree(pCallback);
|
||||
dbgCreateInfo.free();
|
||||
if (err != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create VkInstance: " + VKUtils.translateVulkanResult(err)); }
|
||||
return callbackHandle;
|
||||
PointerBuffer glfwExtensions = GLFWVulkan.glfwGetRequiredInstanceExtensions();
|
||||
|
||||
return glfwExtensions;
|
||||
}
|
||||
|
||||
|
||||
public static void createInstance() {
|
||||
|
||||
try(MemoryStack stack = MemoryStack.stackPush()) {
|
||||
|
||||
// Use calloc to initialize the structs with 0s. Otherwise, the program can crash due to random values
|
||||
|
||||
VkApplicationInfo appInfo = VkApplicationInfo.callocStack(stack);
|
||||
|
||||
appInfo.sType(VK12.VK_STRUCTURE_TYPE_APPLICATION_INFO);
|
||||
appInfo.pApplicationName(stack.UTF8Safe("GingerGame"));
|
||||
appInfo.applicationVersion(VK12.VK_MAKE_VERSION(1, 0, 0));
|
||||
appInfo.pEngineName(stack.UTF8Safe("Ginger2"));
|
||||
appInfo.engineVersion(VK12.VK_MAKE_VERSION(2, 0, 0));
|
||||
appInfo.apiVersion(VK12.VK_API_VERSION_1_2);
|
||||
|
||||
VkInstanceCreateInfo createInfo = VkInstanceCreateInfo.callocStack(stack);
|
||||
|
||||
createInfo.sType(VK12.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
|
||||
createInfo.pApplicationInfo(appInfo);
|
||||
// enabledExtensionCount is implicitly set when you call ppEnabledExtensionNames
|
||||
createInfo.ppEnabledExtensionNames(getRequiredExtensions());
|
||||
|
||||
// We need to retrieve the pointer of the created instance
|
||||
PointerBuffer instancePtr = stack.mallocPointer(1);
|
||||
|
||||
if(VK12.vkCreateInstance(createInfo, null, instancePtr) != VK12.VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create instance");
|
||||
}
|
||||
|
||||
VkConstants.vulkanInstance = new VkInstance(instancePtr.get(0), createInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createPhysicalDevice() {
|
||||
try(MemoryStack stack = MemoryStack.stackPush()) {
|
||||
|
||||
IntBuffer deviceCount = stack.ints(0);
|
||||
|
||||
VK12.vkEnumeratePhysicalDevices(VkConstants.vulkanInstance, deviceCount, null);
|
||||
|
||||
if(deviceCount.get(0) == 0) {
|
||||
throw new RuntimeException("Failed to find GPUs with Vulkan support");
|
||||
}
|
||||
|
||||
PointerBuffer ppPhysicalDevices = stack.mallocPointer(deviceCount.get(0));
|
||||
|
||||
VK12.vkEnumeratePhysicalDevices(VkConstants.vulkanInstance, deviceCount, ppPhysicalDevices);
|
||||
|
||||
VkPhysicalDevice device = null;
|
||||
|
||||
for(int i = 0;i < ppPhysicalDevices.capacity();i++) {
|
||||
|
||||
device = new VkPhysicalDevice(ppPhysicalDevices.get(i), VkConstants.vulkanInstance);
|
||||
|
||||
}
|
||||
|
||||
if(device == null) {
|
||||
throw new RuntimeException("Failed to find a suitable GPU");
|
||||
}
|
||||
|
||||
VkConstants.physicalDevice = device;
|
||||
}
|
||||
}
|
||||
|
||||
private static int vulkanStageToShaderc(int stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case VK10.VK_SHADER_STAGE_VERTEX_BIT:
|
||||
return shaderc_vertex_shader;
|
||||
case VK10.VK_SHADER_STAGE_FRAGMENT_BIT:
|
||||
return shaderc_fragment_shader;
|
||||
case NVRayTracing.VK_SHADER_STAGE_RAYGEN_BIT_NV:
|
||||
return shaderc_raygen_shader;
|
||||
case NVRayTracing.VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV:
|
||||
return shaderc_closesthit_shader;
|
||||
case NVRayTracing.VK_SHADER_STAGE_MISS_BIT_NV:
|
||||
return shaderc_miss_shader;
|
||||
case NVRayTracing.VK_SHADER_STAGE_ANY_HIT_BIT_NV:
|
||||
return shaderc_anyhit_shader;
|
||||
default:
|
||||
throw new IllegalArgumentException("Shader stage: " + stage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class QueueFamilyIndices {
|
||||
|
||||
public static ByteBuffer glslToSpirv(String classPath, int vulkanStage) throws IOException
|
||||
{
|
||||
System.out.println("Converting shader: " + classPath + " to SPIRV");
|
||||
ByteBuffer src = IOUtil.ioResourceToByteBuffer(classPath, 1024);
|
||||
long compiler = shaderc_compiler_initialize();
|
||||
long options = shaderc_compile_options_initialize();
|
||||
ShadercIncludeResolve resolver;
|
||||
ShadercIncludeResultRelease releaser;
|
||||
shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_performance);
|
||||
shaderc_compile_options_set_include_callbacks(options, resolver = new ShadercIncludeResolve()
|
||||
{
|
||||
public long invoke(long user_data, long requested_source, int type, long requesting_source, long include_depth)
|
||||
{
|
||||
ShadercIncludeResult res = ShadercIncludeResult.calloc();
|
||||
try
|
||||
{
|
||||
String src = classPath.substring(0, classPath.lastIndexOf('/')) + "/" + memUTF8(requested_source);
|
||||
res.content(IOUtil.ioResourceToByteBuffer(src, 1024));
|
||||
res.source_name(memUTF8(src));
|
||||
return res.address();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AssertionError("Failed to resolve include: " + src);
|
||||
}
|
||||
}
|
||||
}, releaser = new ShadercIncludeResultRelease()
|
||||
{
|
||||
public void invoke(long user_data, long include_result)
|
||||
{
|
||||
ShadercIncludeResult result = ShadercIncludeResult.create(include_result);
|
||||
memFree(result.source_name());
|
||||
result.free();
|
||||
}
|
||||
}, 0L);
|
||||
long res;
|
||||
try (MemoryStack stack = MemoryStack.stackPush())
|
||||
{
|
||||
res = shaderc_compile_into_spv(compiler, src, vulkanStageToShaderc(vulkanStage),
|
||||
stack.UTF8(classPath), stack.UTF8("main"), options);
|
||||
if (res == 0L)
|
||||
throw new AssertionError("Internal error during compilation!");
|
||||
}
|
||||
if (shaderc_result_get_compilation_status(res) != shaderc_compilation_status_success)
|
||||
{ throw new AssertionError("Shader compilation failed: " + shaderc_result_get_error_message(res)); }
|
||||
int size = (int) shaderc_result_get_length(res);
|
||||
ByteBuffer resultBytes = BufferUtils.createByteBuffer(size);
|
||||
resultBytes.put(shaderc_result_get_bytes(res));
|
||||
resultBytes.flip();
|
||||
shaderc_compiler_release(res);
|
||||
shaderc_compiler_release(compiler);
|
||||
releaser.free();
|
||||
resolver.free();
|
||||
return resultBytes;
|
||||
}
|
||||
// We use Integer to use null as the empty value
|
||||
private Integer graphicsFamily;
|
||||
private Integer presentFamily;
|
||||
|
||||
public static String translateVulkanResult(int vulkanResult)
|
||||
public boolean isComplete() {
|
||||
return graphicsFamily != null && presentFamily != null;
|
||||
}
|
||||
|
||||
public int[] unique() {
|
||||
return IntStream.of(graphicsFamily, presentFamily).distinct().toArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void createLogicalDevice()
|
||||
{
|
||||
switch (vulkanResult)
|
||||
try(MemoryStack stack = MemoryStack.stackPush())
|
||||
{
|
||||
case VK10.VK_SUCCESS:
|
||||
return "Command successfully completed.";
|
||||
case VK10.VK_NOT_READY:
|
||||
return "A query has not yet been completed.";
|
||||
case VK10.VK_TIMEOUT:
|
||||
return "A wait operation has timed out.";
|
||||
case VK10.VK_INCOMPLETE:
|
||||
return "A return array was too small for the result.";
|
||||
case KHRSwapchain.VK_SUBOPTIMAL_KHR:
|
||||
return "A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully.";
|
||||
case VK10.VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "A host memory allocation has failed.";
|
||||
case VK10.VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "A device memory allocation has failed.";
|
||||
case VK10.VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "Initialization of an object could not be completed for implementation-specific reasons.";
|
||||
case VK10.VK_ERROR_DEVICE_LOST:
|
||||
return "The logical or physical device has been lost.";
|
||||
case VK10.VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "Mapping of a memory object has failed.";
|
||||
case VK10.VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "A requested layer is not present or could not be loaded.";
|
||||
case VK10.VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "A requested extension is not supported.";
|
||||
case VK10.VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "A requested feature is not supported.";
|
||||
case VK10.VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons.";
|
||||
case VK10.VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "Too many objects of the same type have already been created.";
|
||||
case VK10.VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "The requested format is not supported.";
|
||||
case VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "The window is no longer available.";
|
||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API.";
|
||||
case KHRDisplaySwapchain.VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an" + " image.";
|
||||
case EXTDebugReport.VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "A validation layer found an error.";
|
||||
default:
|
||||
return String.format("%s [%d]", "Is an unknown vulkan result", Integer.valueOf(vulkanResult));
|
||||
QueueFamilyIndices indices = findQueueFamilies();
|
||||
|
||||
int[] uniqueQueueFamilies = indices.unique();
|
||||
|
||||
VkDeviceQueueCreateInfo.Buffer queueCreateInfos = VkDeviceQueueCreateInfo.callocStack(uniqueQueueFamilies.length, stack);
|
||||
|
||||
for(int i = 0;i < uniqueQueueFamilies.length;i++) {
|
||||
VkDeviceQueueCreateInfo queueCreateInfo = queueCreateInfos.get(i);
|
||||
queueCreateInfo.sType(VK12.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO);
|
||||
queueCreateInfo.queueFamilyIndex(uniqueQueueFamilies[i]);
|
||||
queueCreateInfo.pQueuePriorities(stack.floats(1.0f));
|
||||
}
|
||||
|
||||
|
||||
VkDeviceCreateInfo createInfo = VkDeviceCreateInfo.callocStack(stack);
|
||||
|
||||
createInfo.sType(VK12.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
||||
createInfo.pQueueCreateInfos(queueCreateInfos);
|
||||
// queueCreateInfoCount is automatically set
|
||||
|
||||
|
||||
PointerBuffer pDevice = stack.pointers(VK12.VK_NULL_HANDLE);
|
||||
|
||||
if(VK12.vkCreateDevice(VkConstants.physicalDevice, createInfo, null, pDevice) != VK12.VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create logical device");
|
||||
}
|
||||
|
||||
VkConstants.device = new VkDevice(pDevice.get(0), VkConstants.physicalDevice, createInfo);
|
||||
|
||||
PointerBuffer pQueue = stack.pointers(VK12.VK_NULL_HANDLE);
|
||||
|
||||
VK12.vkGetDeviceQueue(VkConstants.device, indices.graphicsFamily, 0, pQueue);
|
||||
VkConstants.graphicsQueue = new VkQueue(pQueue.get(0), VkConstants.device);
|
||||
|
||||
VK12.vkGetDeviceQueue(VkConstants.device, indices.presentFamily, 0, pQueue);
|
||||
VkConstants.presentQueue = new VkQueue(pQueue.get(0), VkConstants.device);
|
||||
}
|
||||
}
|
||||
|
||||
public static VkCommandBuffer[] setupRenderCommandBuffer(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height,
|
||||
Pipeline pipeline, long descriptorSet, long verticesBuf)
|
||||
{
|
||||
try (MemoryStack stack = MemoryStack.stackPush())
|
||||
{
|
||||
// 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 result = VK12.vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
|
||||
if (result != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to create render command buffer: " + VKUtils.translateVulkanResult(result)); }
|
||||
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 colour
|
||||
VkClearValue.Buffer clearValues = VkClearValue.calloc(2);
|
||||
clearValues.get(0).color()
|
||||
.float32(0, Window.getColour().x() / 255.0f)
|
||||
.float32(1, Window.getColour().y() / 255.0f)
|
||||
.float32(2, Window.getColour().z() / 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]);
|
||||
result = VK12.vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
|
||||
if (result != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(result)); }
|
||||
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);
|
||||
EntityRenderer.tempStaticRender(stack, renderCommandBuffers[i]);
|
||||
private static QueueFamilyIndices findQueueFamilies() {
|
||||
|
||||
VK12.vkCmdEndRenderPass(renderCommandBuffers[i]);
|
||||
result = VK12.vkEndCommandBuffer(renderCommandBuffers[i]);
|
||||
if (result != VK12.VK_SUCCESS)
|
||||
{ throw new AssertionError("Failed to begin render command buffer: " + VKUtils.translateVulkanResult(result)); }
|
||||
}
|
||||
renderPassBeginInfo.free();
|
||||
clearValues.free();
|
||||
cmdBufInfo.free();
|
||||
return renderCommandBuffers;
|
||||
}
|
||||
|
||||
QueueFamilyIndices indices = new QueueFamilyIndices();
|
||||
|
||||
}
|
||||
try(MemoryStack stack = MemoryStack.stackPush()) {
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
IntBuffer queueFamilyCount = stack.ints(0);
|
||||
|
||||
VK12.vkGetPhysicalDeviceQueueFamilyProperties(VkConstants.physicalDevice, queueFamilyCount, null);
|
||||
|
||||
VkQueueFamilyProperties.Buffer queueFamilies = VkQueueFamilyProperties.mallocStack(queueFamilyCount.get(0), stack);
|
||||
|
||||
VK12.vkGetPhysicalDeviceQueueFamilyProperties(VkConstants.physicalDevice, queueFamilyCount, queueFamilies);
|
||||
|
||||
IntBuffer presentSupport = stack.ints(VK12.VK_FALSE);
|
||||
|
||||
for(int i = 0;i < queueFamilies.capacity() || !indices.isComplete();i++) {
|
||||
|
||||
if((queueFamilies.get(i).queueFlags() & VK12.VK_QUEUE_GRAPHICS_BIT) != 0) {
|
||||
indices.graphicsFamily = i;
|
||||
}
|
||||
|
||||
KHRSurface.vkGetPhysicalDeviceSurfaceSupportKHR(
|
||||
VkConstants.physicalDevice,
|
||||
i, VkConstants.windowSurface,
|
||||
presentSupport);
|
||||
|
||||
if(presentSupport.get(0) == VK12.VK_TRUE) {
|
||||
indices.presentFamily = i;
|
||||
}
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
}
|
||||
|
||||
//some code from LWJGL examples for debugging (has changes)
|
||||
public static String translateVulkanResult(int result) {
|
||||
switch (result) {
|
||||
// Success codes
|
||||
case VK12.VK_SUCCESS:
|
||||
return "Command successfully completed.";
|
||||
case VK12.VK_NOT_READY:
|
||||
return "A fence or query has not yet completed.";
|
||||
case VK12.VK_TIMEOUT:
|
||||
return "A wait operation has not completed in the specified time.";
|
||||
case VK12.VK_EVENT_SET:
|
||||
return "An event is signaled.";
|
||||
case VK12.VK_EVENT_RESET:
|
||||
return "An event is unsignaled.";
|
||||
case VK12.VK_INCOMPLETE:
|
||||
return "A return array was too small for the result.";
|
||||
case KHRSwapchain.VK_SUBOPTIMAL_KHR:
|
||||
return "A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully.";
|
||||
|
||||
// Error codes
|
||||
case VK12.VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "A host memory allocation has failed.";
|
||||
case VK12.VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "A device memory allocation has failed.";
|
||||
case VK12.VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "Initialization of an object could not be completed for implementation-specific reasons.";
|
||||
case VK12.VK_ERROR_DEVICE_LOST:
|
||||
return "The logical or physical device has been lost.";
|
||||
case VK12.VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "Mapping of a memory object has failed.";
|
||||
case VK12.VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "A requested layer is not present or could not be loaded.";
|
||||
case VK12.VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "A requested extension is not supported.";
|
||||
case VK12.VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "A requested feature is not supported.";
|
||||
case VK12.VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons.";
|
||||
case VK12.VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "Too many objects of the type have already been created.";
|
||||
case VK12.VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "A requested format is not supported on this device.";
|
||||
case KHRSurface.VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "A surface is no longer available.";
|
||||
case KHRSurface.VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API.";
|
||||
case KHRSwapchain.VK_ERROR_OUT_OF_DATE_KHR:
|
||||
return "A surface has changed in such a way that it is no longer compatible with the swapchain, and further presentation requests using the "
|
||||
+ "swapchain will fail. Applications must query the new surface properties and recreate their swapchain if they wish to continue" + "presenting to the surface.";
|
||||
case KHRDisplaySwapchain.VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an" + " image.";
|
||||
case EXTDebugReport.VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "A validation layer found an error.";
|
||||
default:
|
||||
return String.format("%s [%d]", "Unknown", Integer.valueOf(result));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,301 +0,0 @@
|
|||
package com.github.hydos.ginger.engine.vulkan.utils;
|
||||
|
||||
import static org.lwjgl.vulkan.EXTDebugReport.VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
||||
import static org.lwjgl.vulkan.KHR8bitStorage.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
|
||||
import static org.lwjgl.vulkan.KHRGetMemoryRequirements2.VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR;
|
||||
import static org.lwjgl.vulkan.KHRGetPhysicalDeviceProperties2.*;
|
||||
import static org.lwjgl.vulkan.KHRShaderFloat16Int8.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.*;
|
||||
import static org.lwjgl.vulkan.NVRayTracing.*;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.vma.*;
|
||||
import org.lwjgl.vulkan.*;
|
||||
/**
|
||||
*
|
||||
* @author hydos
|
||||
* used to make the vulkan api more readable
|
||||
*
|
||||
*/
|
||||
public class VulkanFuncWrapper
|
||||
{
|
||||
public static VmaVulkanFunctions VmaVulkanFunctions(MemoryStack stack)
|
||||
{ return VmaVulkanFunctions.callocStack(stack); }
|
||||
|
||||
public static VmaAllocatorCreateInfo VmaAllocatorCreateInfo(MemoryStack stack)
|
||||
{ return VmaAllocatorCreateInfo.callocStack(stack); }
|
||||
|
||||
public static VkInstanceCreateInfo VkInstanceCreateInfo(MemoryStack stack)
|
||||
{ return VkInstanceCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO); }
|
||||
|
||||
public static VkApplicationInfo VkApplicationInfo(MemoryStack stack)
|
||||
{ return VkApplicationInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_APPLICATION_INFO); }
|
||||
|
||||
public static VkDebugReportCallbackCreateInfoEXT VkDebugReportCallbackCreateInfoEXT(MemoryStack stack)
|
||||
{ return VkDebugReportCallbackCreateInfoEXT.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT); }
|
||||
|
||||
public static VkDeviceCreateInfo VkDeviceCreateInfo(MemoryStack stack)
|
||||
{ return VkDeviceCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); }
|
||||
|
||||
public static VkDeviceQueueCreateInfo.Buffer VkDeviceQueueCreateInfo(MemoryStack stack)
|
||||
{ return VkDeviceQueueCreateInfo.callocStack(1, stack).sType(VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO); }
|
||||
|
||||
public static VkPhysicalDevice8BitStorageFeaturesKHR VkPhysicalDevice8BitStorageFeaturesKHR(MemoryStack stack)
|
||||
{ return VkPhysicalDevice8BitStorageFeaturesKHR.callocStack(stack).sType(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR); }
|
||||
|
||||
public static VkPhysicalDeviceFloat16Int8FeaturesKHR VkPhysicalDeviceFloat16Int8FeaturesKHR(MemoryStack stack)
|
||||
{ return VkPhysicalDeviceFloat16Int8FeaturesKHR.callocStack(stack).sType(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR); }
|
||||
|
||||
public static VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties2(MemoryStack stack)
|
||||
{ return VkPhysicalDeviceProperties2.callocStack(stack).sType(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR); }
|
||||
|
||||
public static VkPhysicalDeviceRayTracingPropertiesNV VkPhysicalDeviceRayTracingPropertiesNV(MemoryStack stack)
|
||||
{ return VkPhysicalDeviceRayTracingPropertiesNV.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV); }
|
||||
|
||||
public static VkSwapchainCreateInfoKHR VkSwapchainCreateInfoKHR(MemoryStack stack)
|
||||
{ return VkSwapchainCreateInfoKHR.callocStack(stack).sType(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); }
|
||||
|
||||
public static VkImageViewCreateInfo VkImageViewCreateInfo(MemoryStack stack)
|
||||
{ return VkImageViewCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); }
|
||||
|
||||
public static VkCommandPoolCreateInfo VkCommandPoolCreateInfo(MemoryStack stack)
|
||||
{ return VkCommandPoolCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO); }
|
||||
|
||||
public static VkMemoryRequirements VkMemoryRequirements(MemoryStack stack)
|
||||
{ return VkMemoryRequirements.callocStack(stack); }
|
||||
|
||||
public static VkImageCreateInfo VkImageCreateInfo(MemoryStack stack)
|
||||
{ return VkImageCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); }
|
||||
|
||||
public static VkImageMemoryBarrier.Buffer VkImageMemoryBarrier(MemoryStack stack)
|
||||
{ return VkImageMemoryBarrier.callocStack(1, stack).sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); }
|
||||
|
||||
public static VkFenceCreateInfo VkFenceCreateInfo(MemoryStack stack)
|
||||
{ return VkFenceCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); }
|
||||
|
||||
public static VkSubmitInfo VkSubmitInfo(MemoryStack stack)
|
||||
{ return VkSubmitInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_SUBMIT_INFO); }
|
||||
|
||||
public static VkCommandBufferBeginInfo VkCommandBufferBeginInfo(MemoryStack stack)
|
||||
{ return VkCommandBufferBeginInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); }
|
||||
|
||||
public static VkCommandBufferAllocateInfo VkCommandBufferAllocateInfo(MemoryStack stack)
|
||||
{ return VkCommandBufferAllocateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO); }
|
||||
|
||||
public static VkMemoryAllocateInfo VkMemoryAllocateInfo(MemoryStack stack)
|
||||
{ return VkMemoryAllocateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); }
|
||||
|
||||
public static VkBufferCreateInfo VkBufferCreateInfo(MemoryStack stack)
|
||||
{ return VkBufferCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); }
|
||||
|
||||
public static VkGeometryAABBNV VkGeometryAABBNV(VkGeometryAABBNV geometry)
|
||||
{ return geometry.sType(VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV); }
|
||||
|
||||
public static VkGeometryTrianglesNV VkGeometryTrianglesNV(VkGeometryTrianglesNV geometry)
|
||||
{ return geometry.sType(VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV); }
|
||||
|
||||
public static VkGeometryNV VkGeometryNV(MemoryStack stack)
|
||||
{ return VkGeometryNV.callocStack(stack).sType(VK_STRUCTURE_TYPE_GEOMETRY_NV); }
|
||||
|
||||
public static VkMemoryBarrier.Buffer VkMemoryBarrier(MemoryStack stack)
|
||||
{ return VkMemoryBarrier.callocStack(1, stack).sType(VK_STRUCTURE_TYPE_MEMORY_BARRIER); }
|
||||
|
||||
public static VkBindAccelerationStructureMemoryInfoNV.Buffer VkBindAccelerationStructureMemoryInfoNV(MemoryStack stack)
|
||||
{ return VkBindAccelerationStructureMemoryInfoNV.callocStack(1, stack)
|
||||
.sType(VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV); }
|
||||
|
||||
public static VkAccelerationStructureInfoNV VkAccelerationStructureInfoNV(MemoryStack stack)
|
||||
{ return VkAccelerationStructureInfoNV.callocStack(stack).sType(VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV); }
|
||||
|
||||
public static VkMemoryRequirements2KHR VkMemoryRequirements2KHR(MemoryStack stack)
|
||||
{ return VkMemoryRequirements2KHR.callocStack(stack).sType(VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR); }
|
||||
|
||||
public static VkAccelerationStructureMemoryRequirementsInfoNV VkAccelerationStructureMemoryRequirementsInfoNV(
|
||||
MemoryStack stack)
|
||||
{ return VkAccelerationStructureMemoryRequirementsInfoNV.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV); }
|
||||
|
||||
public static VkAccelerationStructureCreateInfoNV VkAccelerationStructureCreateInfoNV(MemoryStack stack)
|
||||
{ return VkAccelerationStructureCreateInfoNV.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV); }
|
||||
|
||||
public static VkPipelineShaderStageCreateInfo.Buffer VkPipelineShaderStageCreateInfo(MemoryStack stack, int count)
|
||||
{
|
||||
VkPipelineShaderStageCreateInfo.Buffer ret = VkPipelineShaderStageCreateInfo.callocStack(count, stack);
|
||||
ret.forEach(sci -> sci.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static VkDescriptorSetLayoutBinding.Buffer VkDescriptorSetLayoutBinding(MemoryStack stack, int count)
|
||||
{ return VkDescriptorSetLayoutBinding.callocStack(count, stack); }
|
||||
|
||||
public static VkDescriptorSetLayoutBinding VkDescriptorSetLayoutBinding(MemoryStack stack)
|
||||
{ return VkDescriptorSetLayoutBinding.callocStack(stack); }
|
||||
|
||||
public static VkRayTracingPipelineCreateInfoNV.Buffer VkRayTracingPipelineCreateInfoNV(MemoryStack stack)
|
||||
{ return VkRayTracingPipelineCreateInfoNV.callocStack(1, stack)
|
||||
.sType(VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV); }
|
||||
|
||||
public static VkRayTracingShaderGroupCreateInfoNV.Buffer VkRayTracingShaderGroupCreateInfoNV(int size, MemoryStack stack)
|
||||
{
|
||||
VkRayTracingShaderGroupCreateInfoNV.Buffer buf = VkRayTracingShaderGroupCreateInfoNV.callocStack(size, stack);
|
||||
buf.forEach(info -> info.sType(VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV)
|
||||
.anyHitShader(VK_SHADER_UNUSED_NV)
|
||||
.closestHitShader(VK_SHADER_UNUSED_NV)
|
||||
.generalShader(VK_SHADER_UNUSED_NV)
|
||||
.intersectionShader(VK_SHADER_UNUSED_NV));
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static VkPipelineLayoutCreateInfo VkPipelineLayoutCreateInfo(MemoryStack stack)
|
||||
{ return VkPipelineLayoutCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); }
|
||||
|
||||
public static VkDescriptorSetLayoutCreateInfo VkDescriptorSetLayoutCreateInfo(MemoryStack stack)
|
||||
{ return VkDescriptorSetLayoutCreateInfo.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); }
|
||||
|
||||
public static VkDescriptorBufferInfo.Buffer VkDescriptorBufferInfo(MemoryStack stack, int count)
|
||||
{ return VkDescriptorBufferInfo.callocStack(count, stack); }
|
||||
|
||||
public static VkDescriptorImageInfo.Buffer VkDescriptorImageInfo(MemoryStack stack, int count)
|
||||
{ return VkDescriptorImageInfo.callocStack(count, stack); }
|
||||
|
||||
public static VkDescriptorPoolSize.Buffer VkDescriptorPoolSize(MemoryStack stack, int count)
|
||||
{ return VkDescriptorPoolSize.callocStack(count, stack); }
|
||||
|
||||
public static VkWriteDescriptorSetAccelerationStructureNV VkWriteDescriptorSetAccelerationStructureNV(MemoryStack stack)
|
||||
{ return VkWriteDescriptorSetAccelerationStructureNV.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV); }
|
||||
|
||||
public static VkWriteDescriptorSet VkWriteDescriptorSet(MemoryStack stack)
|
||||
{ return VkWriteDescriptorSet.callocStack(stack).sType(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET); }
|
||||
|
||||
public static VkDescriptorSetAllocateInfo VkDescriptorSetAllocateInfo(MemoryStack stack)
|
||||
{ return VkDescriptorSetAllocateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO); }
|
||||
|
||||
public static VkDescriptorPoolCreateInfo VkDescriptorPoolCreateInfo(MemoryStack stack)
|
||||
{ return VkDescriptorPoolCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO); }
|
||||
|
||||
public static VkPresentInfoKHR VkPresentInfoKHR(MemoryStack stack)
|
||||
{ return VkPresentInfoKHR.callocStack(stack).sType(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR); }
|
||||
|
||||
public static VkSemaphoreCreateInfo VkSemaphoreCreateInfo(MemoryStack stack)
|
||||
{ return VkSemaphoreCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO); }
|
||||
|
||||
public static VkQueueFamilyProperties.Buffer VkQueueFamilyProperties(int count)
|
||||
{ return VkQueueFamilyProperties.callocStack(count); }
|
||||
|
||||
public static VkPhysicalDeviceFeatures VkPhysicalDeviceFeatures(MemoryStack stack)
|
||||
{ return VkPhysicalDeviceFeatures.callocStack(stack); }
|
||||
|
||||
public static VkPhysicalDeviceFeatures2 VkPhysicalDeviceFeatures2(MemoryStack stack)
|
||||
{ return VkPhysicalDeviceFeatures2.callocStack(stack).sType(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR); }
|
||||
|
||||
public static VkPhysicalDeviceProperties VkPhysicalDeviceProperties(MemoryStack stack)
|
||||
{ return VkPhysicalDeviceProperties.callocStack(stack); }
|
||||
|
||||
public static VkGeometryNV.Buffer VkGeometryNV(MemoryStack stack, int count)
|
||||
{
|
||||
VkGeometryNV.Buffer buf = VkGeometryNV.callocStack(count, stack);
|
||||
buf.forEach(info -> info.sType(VK_STRUCTURE_TYPE_GEOMETRY_NV));
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static VkPipelineShaderStageCreateInfo VkPipelineShaderStageCreateInfo(MemoryStack stack)
|
||||
{ return VkPipelineShaderStageCreateInfo.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO); }
|
||||
|
||||
public static VkShaderModuleCreateInfo VkShaderModuleCreateInfo(MemoryStack stack)
|
||||
{ return VkShaderModuleCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); }
|
||||
|
||||
public static VkSurfaceCapabilitiesKHR VkSurfaceCapabilitiesKHR(MemoryStack stack)
|
||||
{ return VkSurfaceCapabilitiesKHR.callocStack(stack); }
|
||||
|
||||
public static VkSurfaceFormatKHR.Buffer VkSurfaceFormatKHR(MemoryStack stack, int count)
|
||||
{ return VkSurfaceFormatKHR.callocStack(count, stack); }
|
||||
|
||||
public static VmaAllocationCreateInfo VmaAllocationCreateInfo(MemoryStack stack)
|
||||
{ return VmaAllocationCreateInfo.callocStack(stack); }
|
||||
|
||||
public static VmaAllocationInfo VmaAllocationInfo(MemoryStack stack)
|
||||
{ return VmaAllocationInfo.callocStack(stack); }
|
||||
|
||||
public static VkBufferCopy.Buffer VkBufferCopy(MemoryStack stack, int count)
|
||||
{ return VkBufferCopy.callocStack(count, stack); }
|
||||
|
||||
public static VkSamplerCreateInfo VkSamplerCreateInfo(MemoryStack stack)
|
||||
{ return VkSamplerCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); }
|
||||
|
||||
public static VkBufferImageCopy.Buffer VkBufferImageCopy(MemoryStack stack)
|
||||
{ return VkBufferImageCopy.callocStack(1, stack); }
|
||||
|
||||
public static VkImageSubresourceRange VkImageSubresourceRange(MemoryStack stack)
|
||||
{ return VkImageSubresourceRange.callocStack(stack); }
|
||||
|
||||
public static VkComponentMapping VkComponentMapping(MemoryStack stack)
|
||||
{ return VkComponentMapping.callocStack(stack); }
|
||||
|
||||
public static VkAttachmentReference VkAttachmentReference(MemoryStack stack)
|
||||
{ return VkAttachmentReference.callocStack(stack); }
|
||||
|
||||
public static VkAttachmentReference.Buffer VkAttachmentReference(MemoryStack stack, int count)
|
||||
{ return VkAttachmentReference.callocStack(count, stack); }
|
||||
|
||||
public static VkSubpassDescription.Buffer VkSubpassDescription(MemoryStack stack, int count)
|
||||
{ return VkSubpassDescription.callocStack(count, stack); }
|
||||
|
||||
public static VkAttachmentDescription.Buffer VkAttachmentDescription(MemoryStack stack, int count)
|
||||
{ return VkAttachmentDescription.callocStack(count, stack); }
|
||||
|
||||
public static VkRenderPassCreateInfo VkRenderPassCreateInfo(MemoryStack stack)
|
||||
{ return VkRenderPassCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO); }
|
||||
|
||||
public static VkOffset3D VkOffset3D(MemoryStack stack)
|
||||
{ return VkOffset3D.callocStack(stack); }
|
||||
|
||||
public static VkGeometryNV.Buffer VkGeometryNV(int count)
|
||||
{ return VkGeometryNV.calloc(count).sType(VK_STRUCTURE_TYPE_GEOMETRY_NV); }
|
||||
|
||||
public static VkFramebufferCreateInfo VkFramebufferCreateInfo(MemoryStack stack)
|
||||
{ return VkFramebufferCreateInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); }
|
||||
|
||||
public static VkPipelineRasterizationStateCreateInfo VkPipelineRasterizationStateCreateInfo(MemoryStack stack)
|
||||
{ return VkPipelineRasterizationStateCreateInfo.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO); }
|
||||
|
||||
public static VkPipelineDepthStencilStateCreateInfo VkPipelineDepthStencilStateCreateInfo(MemoryStack stack)
|
||||
{ return VkPipelineDepthStencilStateCreateInfo.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO); }
|
||||
|
||||
public static VkPipelineMultisampleStateCreateInfo VkPipelineMultisampleStateCreateInfo(MemoryStack stack)
|
||||
{ return VkPipelineMultisampleStateCreateInfo.callocStack(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO); }
|
||||
|
||||
public static VkGraphicsPipelineCreateInfo.Buffer VkGraphicsPipelineCreateInfo(MemoryStack stack, int count)
|
||||
{
|
||||
VkGraphicsPipelineCreateInfo.Buffer ret = VkGraphicsPipelineCreateInfo.callocStack(count, stack);
|
||||
ret.forEach(pci -> pci.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static VkClearValue.Buffer VkClearValue(MemoryStack stack, int count)
|
||||
{ return VkClearValue.callocStack(count, stack); }
|
||||
|
||||
public static VkRenderPassBeginInfo VkRenderPassBeginInfo(MemoryStack stack)
|
||||
{ return VkRenderPassBeginInfo.callocStack(stack).sType(VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO); }
|
||||
|
||||
public static VkViewport.Buffer VkViewport(MemoryStack stack, int count)
|
||||
{ return VkViewport.callocStack(count, stack); }
|
||||
|
||||
public static VkFormatProperties VkFormatProperties(MemoryStack stack)
|
||||
{ return VkFormatProperties.callocStack(stack); }
|
||||
|
||||
public static VkSubpassDependency.Buffer VkSubpassDependency(MemoryStack stack, int count)
|
||||
{ return VkSubpassDependency.callocStack(count, stack); }
|
||||
|
||||
public static VkImageCopy.Buffer VkImageCopy(MemoryStack stack, int count)
|
||||
{ return VkImageCopy.callocStack(count, stack); }
|
||||
}
|
Loading…
Reference in New Issue