From e5b2fbf25ddd4810f4f6ae96d812117f9d4254ed Mon Sep 17 00:00:00 2001 From: hayden v <haydenv06@gmail.com> Date: Tue, 3 Mar 2020 11:10:59 +1000 Subject: [PATCH] moved around shader code and other vulkan stuff --- .classpath | 2 +- .../github/hydos/ginger/VulkanStarter.java | 411 ++++++++---------- .../vulkan/{utils => }/VKConstants.java | 2 +- .../engine/vulkan/shaders/Pipeline.java | 166 +++++++ .../vulkan/shaders/VKShaderManager.java | 48 ++ .../vulkan/utils/VKDeviceProperties.java | 98 +++++ .../ginger/engine/vulkan/utils/VKLoader.java | 2 + .../ginger/engine/vulkan/utils/VKUtils.java | 68 ++- .../vulkan/utils/VulkanFuncWrapper.java | 7 +- 9 files changed, 560 insertions(+), 244 deletions(-) rename src/main/java/com/github/hydos/ginger/engine/vulkan/{utils => }/VKConstants.java (88%) create mode 100644 src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/Pipeline.java create mode 100644 src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/VKShaderManager.java create mode 100644 src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKDeviceProperties.java diff --git a/.classpath b/.classpath index febc371..a93fc90 100644 --- a/.classpath +++ b/.classpath @@ -5,7 +5,7 @@ <attribute name="maven.pomderived" value="true"/> </attributes> </classpathentry> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-13"> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> <attributes> <attribute name="module" value="true"/> <attribute name="maven.pomderived" value="true"/> diff --git a/src/main/java/com/github/hydos/ginger/VulkanStarter.java b/src/main/java/com/github/hydos/ginger/VulkanStarter.java index 4dc3d3a..e85842e 100644 --- a/src/main/java/com/github/hydos/ginger/VulkanStarter.java +++ b/src/main/java/com/github/hydos/ginger/VulkanStarter.java @@ -1,25 +1,194 @@ package com.github.hydos.ginger; -import static org.lwjgl.glfw.GLFW.*; -import static org.lwjgl.glfw.GLFWVulkan.*; -import static org.lwjgl.system.MemoryUtil.*; -import static org.lwjgl.vulkan.EXTDebugReport.*; -import static org.lwjgl.vulkan.KHRSurface.*; -import static org.lwjgl.vulkan.KHRSwapchain.*; -import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE; +import static org.lwjgl.glfw.GLFW.GLFW_RELEASE; +import static org.lwjgl.glfw.GLFW.glfwDestroyWindow; +import static org.lwjgl.glfw.GLFW.glfwPollEvents; +import static org.lwjgl.glfw.GLFW.glfwSetFramebufferSizeCallback; +import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose; +import static org.lwjgl.glfw.GLFW.glfwShowWindow; +import static org.lwjgl.glfw.GLFW.glfwTerminate; +import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose; +import static org.lwjgl.glfw.GLFWVulkan.glfwCreateWindowSurface; +import static org.lwjgl.glfw.GLFWVulkan.glfwGetRequiredInstanceExtensions; +import static org.lwjgl.system.MemoryUtil.NULL; +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.memByteBuffer; +import static org.lwjgl.system.MemoryUtil.memCopy; +import static org.lwjgl.system.MemoryUtil.memFree; +import static org.lwjgl.system.MemoryUtil.memUTF8; +import static org.lwjgl.vulkan.EXTDebugReport.VK_DEBUG_REPORT_ERROR_BIT_EXT; +import static org.lwjgl.vulkan.EXTDebugReport.VK_DEBUG_REPORT_WARNING_BIT_EXT; +import static org.lwjgl.vulkan.EXTDebugReport.vkDestroyDebugReportCallbackEXT; +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_IMAGE_LAYOUT_PRESENT_SRC_KHR; +import static org.lwjgl.vulkan.KHRSwapchain.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; +import static org.lwjgl.vulkan.KHRSwapchain.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; +import static org.lwjgl.vulkan.KHRSwapchain.vkAcquireNextImageKHR; +import static org.lwjgl.vulkan.KHRSwapchain.vkCreateSwapchainKHR; +import static org.lwjgl.vulkan.KHRSwapchain.vkDestroySwapchainKHR; +import static org.lwjgl.vulkan.KHRSwapchain.vkGetSwapchainImagesKHR; +import static org.lwjgl.vulkan.KHRSwapchain.vkQueuePresentKHR; +import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_LOAD_OP_CLEAR; +import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_LOAD_OP_DONT_CARE; +import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_DONT_CARE; +import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_STORE; +import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; +import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; +import static org.lwjgl.vulkan.VK10.VK_COMMAND_BUFFER_LEVEL_PRIMARY; +import static org.lwjgl.vulkan.VK10.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; +import static org.lwjgl.vulkan.VK10.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_B8G8R8A8_UNORM; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_D16_UNORM; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_D16_UNORM_S8_UINT; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_D24_UNORM_S8_UINT; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_D32_SFLOAT; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_D32_SFLOAT_S8_UINT; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32B32_SFLOAT; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_UNDEFINED; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_COLOR_BIT; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_DEPTH_BIT; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_STENCIL_BIT; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_UNDEFINED; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_TILING_OPTIMAL; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_TYPE_2D; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_TRANSFER_SRC_BIT; +import static org.lwjgl.vulkan.VK10.VK_IMAGE_VIEW_TYPE_2D; +import static org.lwjgl.vulkan.VK10.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; +import static org.lwjgl.vulkan.VK10.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; +import static org.lwjgl.vulkan.VK10.VK_NULL_HANDLE; +import static org.lwjgl.vulkan.VK10.VK_PIPELINE_BIND_POINT_GRAPHICS; +import static org.lwjgl.vulkan.VK10.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; +import static org.lwjgl.vulkan.VK10.VK_QUEUE_GRAPHICS_BIT; +import static org.lwjgl.vulkan.VK10.VK_SAMPLE_COUNT_1_BIT; +import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_VERTEX_BIT; +import static org.lwjgl.vulkan.VK10.VK_SHARING_MODE_EXCLUSIVE; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_SUBMIT_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; +import static org.lwjgl.vulkan.VK10.VK_SUCCESS; +import static org.lwjgl.vulkan.VK10.VK_TRUE; +import static org.lwjgl.vulkan.VK10.VK_VERTEX_INPUT_RATE_VERTEX; +import static org.lwjgl.vulkan.VK10.vkAllocateCommandBuffers; +import static org.lwjgl.vulkan.VK10.vkAllocateDescriptorSets; +import static org.lwjgl.vulkan.VK10.vkAllocateMemory; +import static org.lwjgl.vulkan.VK10.vkBeginCommandBuffer; +import static org.lwjgl.vulkan.VK10.vkBindBufferMemory; +import static org.lwjgl.vulkan.VK10.vkBindImageMemory; +import static org.lwjgl.vulkan.VK10.vkCreateBuffer; +import static org.lwjgl.vulkan.VK10.vkCreateCommandPool; +import static org.lwjgl.vulkan.VK10.vkCreateDescriptorPool; +import static org.lwjgl.vulkan.VK10.vkCreateDescriptorSetLayout; +import static org.lwjgl.vulkan.VK10.vkCreateFramebuffer; +import static org.lwjgl.vulkan.VK10.vkCreateImage; +import static org.lwjgl.vulkan.VK10.vkCreateImageView; +import static org.lwjgl.vulkan.VK10.vkCreateRenderPass; +import static org.lwjgl.vulkan.VK10.vkCreateSemaphore; +import static org.lwjgl.vulkan.VK10.vkDestroyFramebuffer; +import static org.lwjgl.vulkan.VK10.vkDestroySemaphore; +import static org.lwjgl.vulkan.VK10.vkEndCommandBuffer; +import static org.lwjgl.vulkan.VK10.vkGetBufferMemoryRequirements; +import static org.lwjgl.vulkan.VK10.vkGetDeviceQueue; +import static org.lwjgl.vulkan.VK10.vkGetImageMemoryRequirements; +import static org.lwjgl.vulkan.VK10.vkGetPhysicalDeviceFormatProperties; +import static org.lwjgl.vulkan.VK10.vkGetPhysicalDeviceQueueFamilyProperties; +import static org.lwjgl.vulkan.VK10.vkMapMemory; +import static org.lwjgl.vulkan.VK10.vkQueueSubmit; +import static org.lwjgl.vulkan.VK10.vkQueueWaitIdle; +import static org.lwjgl.vulkan.VK10.vkResetCommandPool; +import static org.lwjgl.vulkan.VK10.vkUnmapMemory; +import static org.lwjgl.vulkan.VK10.vkUpdateDescriptorSets; import java.io.IOException; -import java.nio.*; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; import org.joml.Matrix4f; import org.lwjgl.PointerBuffer; -import org.lwjgl.glfw.*; -import org.lwjgl.vulkan.*; +import org.lwjgl.glfw.GLFWFramebufferSizeCallback; +import org.lwjgl.glfw.GLFWKeyCallback; +import org.lwjgl.vulkan.VkAttachmentDescription; +import org.lwjgl.vulkan.VkAttachmentReference; +import org.lwjgl.vulkan.VkBufferCreateInfo; +import org.lwjgl.vulkan.VkCommandBuffer; +import org.lwjgl.vulkan.VkCommandBufferAllocateInfo; +import org.lwjgl.vulkan.VkCommandBufferBeginInfo; +import org.lwjgl.vulkan.VkCommandPoolCreateInfo; +import org.lwjgl.vulkan.VkDescriptorBufferInfo; +import org.lwjgl.vulkan.VkDescriptorPoolCreateInfo; +import org.lwjgl.vulkan.VkDescriptorPoolSize; +import org.lwjgl.vulkan.VkDescriptorSetAllocateInfo; +import org.lwjgl.vulkan.VkDescriptorSetLayoutBinding; +import org.lwjgl.vulkan.VkDescriptorSetLayoutCreateInfo; +import org.lwjgl.vulkan.VkDevice; +import org.lwjgl.vulkan.VkExtent2D; +import org.lwjgl.vulkan.VkFormatProperties; +import org.lwjgl.vulkan.VkFramebufferCreateInfo; +import org.lwjgl.vulkan.VkImageCreateInfo; +import org.lwjgl.vulkan.VkImageViewCreateInfo; +import org.lwjgl.vulkan.VkInstance; +import org.lwjgl.vulkan.VkMemoryAllocateInfo; +import org.lwjgl.vulkan.VkMemoryRequirements; +import org.lwjgl.vulkan.VkPhysicalDevice; +import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties; +import org.lwjgl.vulkan.VkPipelineShaderStageCreateInfo; +import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo; +import org.lwjgl.vulkan.VkPresentInfoKHR; +import org.lwjgl.vulkan.VkQueue; +import org.lwjgl.vulkan.VkQueueFamilyProperties; +import org.lwjgl.vulkan.VkRenderPassCreateInfo; +import org.lwjgl.vulkan.VkSemaphoreCreateInfo; +import org.lwjgl.vulkan.VkSubmitInfo; +import org.lwjgl.vulkan.VkSubpassDescription; +import org.lwjgl.vulkan.VkSurfaceCapabilitiesKHR; +import org.lwjgl.vulkan.VkSurfaceFormatKHR; +import org.lwjgl.vulkan.VkSwapchainCreateInfoKHR; +import org.lwjgl.vulkan.VkVertexInputAttributeDescription; +import org.lwjgl.vulkan.VkVertexInputBindingDescription; +import org.lwjgl.vulkan.VkWriteDescriptorSet; import com.github.hydos.ginger.engine.common.info.RenderAPI; import com.github.hydos.ginger.engine.common.io.Window; -import com.github.hydos.ginger.engine.vulkan.utils.*; -import com.github.hydos.ginger.engine.vulkan.utils.VKUtils.Pipeline; +import com.github.hydos.ginger.engine.vulkan.VKConstants; +import com.github.hydos.ginger.engine.vulkan.shaders.Pipeline; +import com.github.hydos.ginger.engine.vulkan.shaders.VKShaderManager; +import com.github.hydos.ginger.engine.vulkan.utils.VKDeviceProperties; +import com.github.hydos.ginger.engine.vulkan.utils.VKLoader; +import com.github.hydos.ginger.engine.vulkan.utils.VKUtils; /** * * @author hydos06 @@ -28,80 +197,6 @@ import com.github.hydos.ginger.engine.vulkan.utils.VKUtils.Pipeline; */ public class VulkanStarter { - private static VkPhysicalDevice getFirstPhysicalDevice(VkInstance instance) - { - IntBuffer pPhysicalDeviceCount = memAllocInt(1); - int err = vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, null); - if (err != VK_SUCCESS) - { throw new AssertionError("Failed to get number of physical devices: " + VKUtils.translateVulkanResult(err)); } - PointerBuffer pPhysicalDevices = memAllocPointer(pPhysicalDeviceCount.get(0)); - err = vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); - long physicalDevice = pPhysicalDevices.get(0); - memFree(pPhysicalDeviceCount); - memFree(pPhysicalDevices); - if (err != VK_SUCCESS) - { throw new AssertionError("Failed to get physical devices: " + VKUtils.translateVulkanResult(err)); } - return new VkPhysicalDevice(physicalDevice, instance); - } - - private static class DeviceAndGraphicsQueueFamily - { - VkDevice device; - int queueFamilyIndex; - VkPhysicalDeviceMemoryProperties memoryProperties; - } - - private static DeviceAndGraphicsQueueFamily createDeviceAndGetGraphicsQueueFamily(VkPhysicalDevice physicalDevice) - { - IntBuffer pQueueFamilyPropertyCount = memAllocInt(1); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, null); - int queueCount = pQueueFamilyPropertyCount.get(0); - VkQueueFamilyProperties.Buffer queueProps = VkQueueFamilyProperties.calloc(queueCount); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, queueProps); - memFree(pQueueFamilyPropertyCount); - int graphicsQueueFamilyIndex; - for (graphicsQueueFamilyIndex = 0; graphicsQueueFamilyIndex < queueCount; graphicsQueueFamilyIndex++) - { if ((queueProps.get(graphicsQueueFamilyIndex).queueFlags() & VK_QUEUE_GRAPHICS_BIT) != 0) - break; } - queueProps.free(); - FloatBuffer pQueuePriorities = memAllocFloat(1).put(0.0f); - pQueuePriorities.flip(); - VkDeviceQueueCreateInfo.Buffer queueCreateInfo = VkDeviceQueueCreateInfo.calloc(1) - .sType(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(VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO) - .pQueueCreateInfos(queueCreateInfo) - .ppEnabledExtensionNames(extensions) - .ppEnabledLayerNames(ppEnabledLayerNames); - PointerBuffer pDevice = memAllocPointer(1); - int err = vkCreateDevice(physicalDevice, deviceCreateInfo, null, pDevice); - long device = pDevice.get(0); - memFree(pDevice); - if (err != VK_SUCCESS) - { throw new AssertionError("Failed to create device: " + VKUtils.translateVulkanResult(err)); } - VkPhysicalDeviceMemoryProperties memoryProperties = VkPhysicalDeviceMemoryProperties.calloc(); - vkGetPhysicalDeviceMemoryProperties(physicalDevice, memoryProperties); - DeviceAndGraphicsQueueFamily ret = new DeviceAndGraphicsQueueFamily(); - 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; - } private static boolean getSupportedDepthFormat(VkPhysicalDevice physicalDevice, IntBuffer depthFormat) { @@ -562,32 +657,6 @@ public class VulkanStarter { throw new AssertionError("Failed to submit command buffer: " + VKUtils.translateVulkanResult(err)); } } - private 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; - } - - private 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(loadShader(classPath, device, stage)) - .pName(memUTF8("main")); - return shaderStage; - } - private static boolean getMemoryType(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, int typeBits, int properties, IntBuffer typeIndex) { int bits = typeBits; @@ -849,116 +918,6 @@ public class VulkanStarter return descriptorSetLayout; } - private 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(loadShader(device, "/vulkan/shaders/entityVertexShader.glsl", VK_SHADER_STAGE_VERTEX_BIT)); - shaderStages.get(1).set(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)); } - Pipeline ret = new Pipeline(); - ret.layout = layout; - ret.pipeline = pipeline; - return ret; - } - private static void updateUbo(VkDevice device, UboDescriptor ubo, float angle) { //a UBO is a uniform buffer object Matrix4f m = new Matrix4f() @@ -998,8 +957,8 @@ public class VulkanStarter final VkInstance instance = VKLoader.createInstance(requiredExtensions); VKUtils.setupVulkanDebugCallback(); final long debugCallbackHandle = VKUtils.startVulkanDebugging(instance, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, VKConstants.debugCallback); - final VkPhysicalDevice physicalDevice = getFirstPhysicalDevice(instance); - final DeviceAndGraphicsQueueFamily deviceAndGraphicsQueueFamily = createDeviceAndGetGraphicsQueueFamily(physicalDevice); + final VkPhysicalDevice physicalDevice = VKDeviceProperties.getFirstPhysicalDevice(instance); + final VKDeviceProperties deviceAndGraphicsQueueFamily = VKDeviceProperties.initDeviceProperties(physicalDevice); final VkDevice device = deviceAndGraphicsQueueFamily.device; int queueFamilyIndex = deviceAndGraphicsQueueFamily.queueFamilyIndex; final VkPhysicalDeviceMemoryProperties memoryProperties = deviceAndGraphicsQueueFamily.memoryProperties; @@ -1026,12 +985,12 @@ public class VulkanStarter final VkQueue queue = createDeviceQueue(device, queueFamilyIndex); final long renderPass = createRenderPass(device, colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.depthFormat); final long renderCommandPool = createCommandPool(device, queueFamilyIndex); - final Vertices vertices = createVertices(memoryProperties, device); + Vertices vertices = createVertices(memoryProperties, device); UboDescriptor uboDescriptor = createUniformBuffer(memoryProperties, device); final long descriptorPool = createDescriptorPool(device); final long descriptorSetLayout = createDescriptorSetLayout(device); final long descriptorSet = createDescriptorSet(device, descriptorPool, descriptorSetLayout, uboDescriptor); - final Pipeline pipeline = createPipeline(device, renderPass, vertices.createInfo, descriptorSetLayout); + final Pipeline pipeline = Pipeline.createPipeline(device, renderPass, vertices.createInfo, descriptorSetLayout); final class SwapchainRecreator { boolean mustRecreate = true; diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKConstants.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/VKConstants.java similarity index 88% rename from src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKConstants.java rename to src/main/java/com/github/hydos/ginger/engine/vulkan/VKConstants.java index 07987b2..c1d7647 100644 --- a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKConstants.java +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/VKConstants.java @@ -1,4 +1,4 @@ -package com.github.hydos.ginger.engine.vulkan.utils; +package com.github.hydos.ginger.engine.vulkan; import java.nio.ByteBuffer; diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/Pipeline.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/Pipeline.java new file mode 100644 index 0000000..ee04e31 --- /dev/null +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/Pipeline.java @@ -0,0 +1,166 @@ +package com.github.hydos.ginger.engine.vulkan.shaders; + +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.VK10.VK_COMPARE_OP_ALWAYS; +import static org.lwjgl.vulkan.VK10.VK_COMPARE_OP_LESS_OR_EQUAL; +import static org.lwjgl.vulkan.VK10.VK_CULL_MODE_NONE; +import static org.lwjgl.vulkan.VK10.VK_DYNAMIC_STATE_SCISSOR; +import static org.lwjgl.vulkan.VK10.VK_DYNAMIC_STATE_VIEWPORT; +import static org.lwjgl.vulkan.VK10.VK_FRONT_FACE_COUNTER_CLOCKWISE; +import static org.lwjgl.vulkan.VK10.VK_NULL_HANDLE; +import static org.lwjgl.vulkan.VK10.VK_POLYGON_MODE_FILL; +import static org.lwjgl.vulkan.VK10.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; +import static org.lwjgl.vulkan.VK10.VK_SAMPLE_COUNT_1_BIT; +import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT; +import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_VERTEX_BIT; +import static org.lwjgl.vulkan.VK10.VK_STENCIL_OP_KEEP; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_SUCCESS; +import static org.lwjgl.vulkan.VK10.vkCreateGraphicsPipelines; +import static org.lwjgl.vulkan.VK10.vkCreatePipelineLayout; + +import java.io.IOException; +import java.nio.IntBuffer; +import java.nio.LongBuffer; + +import org.lwjgl.vulkan.VkDevice; +import org.lwjgl.vulkan.VkGraphicsPipelineCreateInfo; +import org.lwjgl.vulkan.VkPipelineColorBlendAttachmentState; +import org.lwjgl.vulkan.VkPipelineColorBlendStateCreateInfo; +import org.lwjgl.vulkan.VkPipelineDepthStencilStateCreateInfo; +import org.lwjgl.vulkan.VkPipelineDynamicStateCreateInfo; +import org.lwjgl.vulkan.VkPipelineInputAssemblyStateCreateInfo; +import org.lwjgl.vulkan.VkPipelineLayoutCreateInfo; +import org.lwjgl.vulkan.VkPipelineMultisampleStateCreateInfo; +import org.lwjgl.vulkan.VkPipelineRasterizationStateCreateInfo; +import org.lwjgl.vulkan.VkPipelineShaderStageCreateInfo; +import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo; +import org.lwjgl.vulkan.VkPipelineViewportStateCreateInfo; + +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; + } +} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/VKShaderManager.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/VKShaderManager.java new file mode 100644 index 0000000..51e4b63 --- /dev/null +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/shaders/VKShaderManager.java @@ -0,0 +1,48 @@ +package com.github.hydos.ginger.engine.vulkan.shaders; + +import static org.lwjgl.system.MemoryUtil.memAllocLong; +import static org.lwjgl.system.MemoryUtil.memFree; +import static org.lwjgl.system.MemoryUtil.memUTF8; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_SUCCESS; +import static org.lwjgl.vulkan.VK10.vkCreateShaderModule; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; + +import org.lwjgl.vulkan.VkDevice; +import org.lwjgl.vulkan.VkPipelineShaderStageCreateInfo; +import org.lwjgl.vulkan.VkShaderModuleCreateInfo; + +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; + } +} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKDeviceProperties.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKDeviceProperties.java new file mode 100644 index 0000000..d9f0c16 --- /dev/null +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKDeviceProperties.java @@ -0,0 +1,98 @@ +package com.github.hydos.ginger.engine.vulkan.utils; + +import static org.lwjgl.system.MemoryUtil.memAllocFloat; +import static org.lwjgl.system.MemoryUtil.memAllocInt; +import static org.lwjgl.system.MemoryUtil.memAllocPointer; +import static org.lwjgl.system.MemoryUtil.memFree; +import static org.lwjgl.system.MemoryUtil.memUTF8; +import static org.lwjgl.vulkan.KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.PointerBuffer; +import org.lwjgl.vulkan.VK12; +import org.lwjgl.vulkan.VkDevice; +import org.lwjgl.vulkan.VkDeviceCreateInfo; +import org.lwjgl.vulkan.VkDeviceQueueCreateInfo; +import org.lwjgl.vulkan.VkInstance; +import org.lwjgl.vulkan.VkPhysicalDevice; +import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties; +import org.lwjgl.vulkan.VkQueueFamilyProperties; + +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; + } +} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKLoader.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKLoader.java index 880298d..58c3e64 100644 --- a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKLoader.java +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKLoader.java @@ -10,6 +10,8 @@ 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 diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKUtils.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKUtils.java index 6a7fa22..f11cc66 100644 --- a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKUtils.java +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VKUtils.java @@ -1,21 +1,65 @@ 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 static org.lwjgl.system.MemoryUtil.memAllocLong; +import static org.lwjgl.system.MemoryUtil.memAllocPointer; +import static org.lwjgl.system.MemoryUtil.memFree; +import static org.lwjgl.system.MemoryUtil.memUTF8; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_anyhit_shader; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_closesthit_shader; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compilation_status_success; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compile_into_spv; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compile_options_initialize; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compile_options_set_include_callbacks; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compile_options_set_optimization_level; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compiler_initialize; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compiler_release; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_fragment_shader; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_miss_shader; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_optimization_level_performance; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_raygen_shader; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_result_get_bytes; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_result_get_compilation_status; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_result_get_error_message; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_result_get_length; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_vertex_shader; +import static org.lwjgl.vulkan.EXTDebugReport.VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; +import static org.lwjgl.vulkan.EXTDebugReport.vkCreateDebugReportCallbackEXT; +import static org.lwjgl.vulkan.KHRSurface.VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; +import static org.lwjgl.vulkan.KHRSurface.VK_ERROR_SURFACE_LOST_KHR; import java.io.IOException; -import java.nio.*; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; -import org.lwjgl.*; +import org.lwjgl.BufferUtils; +import org.lwjgl.PointerBuffer; import org.lwjgl.system.MemoryStack; -import org.lwjgl.util.shaderc.*; -import org.lwjgl.vulkan.*; +import org.lwjgl.util.shaderc.ShadercIncludeResolve; +import org.lwjgl.util.shaderc.ShadercIncludeResult; +import org.lwjgl.util.shaderc.ShadercIncludeResultRelease; +import org.lwjgl.vulkan.EXTDebugReport; +import org.lwjgl.vulkan.KHRDisplaySwapchain; +import org.lwjgl.vulkan.KHRSwapchain; +import org.lwjgl.vulkan.NVRayTracing; +import org.lwjgl.vulkan.VK10; +import org.lwjgl.vulkan.VK12; +import org.lwjgl.vulkan.VkClearValue; +import org.lwjgl.vulkan.VkCommandBuffer; +import org.lwjgl.vulkan.VkCommandBufferAllocateInfo; +import org.lwjgl.vulkan.VkCommandBufferBeginInfo; +import org.lwjgl.vulkan.VkDebugReportCallbackCreateInfoEXT; +import org.lwjgl.vulkan.VkDebugReportCallbackEXT; +import org.lwjgl.vulkan.VkDevice; +import org.lwjgl.vulkan.VkInstance; +import org.lwjgl.vulkan.VkRect2D; +import org.lwjgl.vulkan.VkRenderPassBeginInfo; +import org.lwjgl.vulkan.VkViewport; import com.github.hydos.ginger.engine.common.tools.IOUtil; +import com.github.hydos.ginger.engine.vulkan.VKConstants; +import com.github.hydos.ginger.engine.vulkan.shaders.Pipeline; -/** @author hydos06 +/** @author hydos * a util library for Vulkan */ public class VKUtils { @@ -164,12 +208,6 @@ public class VKUtils } } - public static class Pipeline - { - public long pipeline; - public long layout; - } - public static VkCommandBuffer[] initRenderCommandBuffers(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height, Pipeline pipeline, long descriptorSet, long verticesBuf) { diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VulkanFuncWrapper.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VulkanFuncWrapper.java index b8dea9d..64f1163 100644 --- a/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VulkanFuncWrapper.java +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/utils/VulkanFuncWrapper.java @@ -12,7 +12,12 @@ 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)