Ginger3D/src/main/java/com/github/hydos/ginger/engine/vulkan/swapchain/VKSwapchainManager.java

126 lines
6.1 KiB
Java

package com.github.hydos.ginger.engine.vulkan.swapchain;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.vulkan.KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
import static org.lwjgl.vulkan.KHRSwapchain.*;
import static org.lwjgl.vulkan.VK10.*;
import java.nio.*;
import java.util.ArrayList;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.vulkan.*;
import com.github.hydos.ginger.VulkanExample.VulkanDemoGinger2;
import com.github.hydos.ginger.VulkanExample.VulkanDemoGinger2.*;
import com.github.hydos.ginger.engine.common.io.Window;
import com.github.hydos.ginger.engine.vulkan.render.pipelines.VKPipelineManager;
public class VKSwapchainManager
{
public static void cleanupSwapChain()
{
vkDestroyImageView(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImageView, null);
vkDestroyImage(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImage, null);
vkFreeMemory(VulkanDemoGinger2.device, VulkanDemoGinger2.colorImageMemory, null);
vkDestroyImageView(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImageView, null);
vkDestroyImage(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImage, null);
vkFreeMemory(VulkanDemoGinger2.device, VulkanDemoGinger2.depthImageMemory, null);
VulkanDemoGinger2.uniformBuffers.forEach(ubo -> vkDestroyBuffer(VulkanDemoGinger2.device, ubo, null));
VulkanDemoGinger2.uniformBuffersMemory.forEach(uboMemory -> vkFreeMemory(VulkanDemoGinger2.device, uboMemory, null));
vkDestroyDescriptorPool(VulkanDemoGinger2.device, VulkanDemoGinger2.descriptorPool, null);
VulkanDemoGinger2.swapChainFramebuffers.forEach(framebuffer -> vkDestroyFramebuffer(VulkanDemoGinger2.device, framebuffer, null));
vkFreeCommandBuffers(VulkanDemoGinger2.device, VulkanDemoGinger2.commandPool, VulkanDemoGinger2.asPointerBuffer(VulkanDemoGinger2.commandBuffers));
vkDestroyPipeline(VulkanDemoGinger2.device, VulkanDemoGinger2.graphicsPipeline, null);
vkDestroyPipelineLayout(VulkanDemoGinger2.device, VulkanDemoGinger2.pipelineLayout, null);
vkDestroyRenderPass(VulkanDemoGinger2.device, VulkanDemoGinger2.renderPass, null);
VulkanDemoGinger2.swapChainImageViews.forEach(imageView -> vkDestroyImageView(VulkanDemoGinger2.device, imageView, null));
vkDestroySwapchainKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, null);
}
public static void recreateSwapChain()
{
try (MemoryStack stack = stackPush())
{
IntBuffer width = stack.ints(0);
IntBuffer height = stack.ints(0);
while (width.get(0) == 0 && height.get(0) == 0)
{
glfwGetFramebufferSize(Window.getWindow(), width, height);
glfwWaitEvents();
}
}
vkDeviceWaitIdle(VulkanDemoGinger2.device);
VKSwapchainManager.cleanupSwapChain();
createSwapChainObjects();
}
public static void createSwapChain()
{
try (MemoryStack stack = stackPush())
{
SwapChainSupportDetails swapChainSupport = VulkanDemoGinger2.querySwapChainSupport(VulkanDemoGinger2.physicalDevice, stack);
VkSurfaceFormatKHR surfaceFormat = VulkanDemoGinger2.chooseSwapSurfaceFormat(swapChainSupport.formats);
int presentMode = VulkanDemoGinger2.chooseSwapPresentMode(swapChainSupport.presentModes);
VkExtent2D extent = VulkanDemoGinger2.chooseSwapExtent(swapChainSupport.capabilities);
IntBuffer imageCount = stack.ints(swapChainSupport.capabilities.minImageCount() + 1);
if (swapChainSupport.capabilities.maxImageCount() > 0 && imageCount.get(0) > swapChainSupport.capabilities.maxImageCount())
{ imageCount.put(0, swapChainSupport.capabilities.maxImageCount()); }
VkSwapchainCreateInfoKHR createInfo = VkSwapchainCreateInfoKHR.callocStack(stack);
createInfo.sType(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
createInfo.surface(VulkanDemoGinger2.surface);
// Image settings
createInfo.minImageCount(imageCount.get(0));
createInfo.imageFormat(surfaceFormat.format());
createInfo.imageColorSpace(surfaceFormat.colorSpace());
createInfo.imageExtent(extent);
createInfo.imageArrayLayers(1);
createInfo.imageUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
QueueFamilyIndices indices = VulkanDemoGinger2.findQueueFamilies(VulkanDemoGinger2.physicalDevice);
if (!indices.graphicsFamily.equals(indices.presentFamily))
{
createInfo.imageSharingMode(VK_SHARING_MODE_CONCURRENT);
createInfo.pQueueFamilyIndices(stack.ints(indices.graphicsFamily, indices.presentFamily));
}
else
{
createInfo.imageSharingMode(VK_SHARING_MODE_EXCLUSIVE);
}
createInfo.preTransform(swapChainSupport.capabilities.currentTransform());
createInfo.compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
createInfo.presentMode(presentMode);
createInfo.clipped(true);
createInfo.oldSwapchain(VK_NULL_HANDLE);
LongBuffer pSwapChain = stack.longs(VK_NULL_HANDLE);
if (vkCreateSwapchainKHR(VulkanDemoGinger2.device, createInfo, null, pSwapChain) != VK_SUCCESS)
{ throw new RuntimeException("Failed to create swap chain"); }
VulkanDemoGinger2.swapChain = pSwapChain.get(0);
vkGetSwapchainImagesKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, imageCount, null);
LongBuffer pSwapchainImages = stack.mallocLong(imageCount.get(0));
vkGetSwapchainImagesKHR(VulkanDemoGinger2.device, VulkanDemoGinger2.swapChain, imageCount, pSwapchainImages);
VulkanDemoGinger2.swapChainImages = new ArrayList<>(imageCount.get(0));
for (int i = 0; i < pSwapchainImages.capacity(); i++)
{ VulkanDemoGinger2.swapChainImages.add(pSwapchainImages.get(i)); }
VulkanDemoGinger2.swapChainImageFormat = surfaceFormat.format();
VulkanDemoGinger2.swapChainExtent = VkExtent2D.create().set(extent);
}
}
/** i tried organising it but if i change the order everything breaks */
public static void createSwapChainObjects()
{
createSwapChain();
VulkanDemoGinger2.createImageViews();
VulkanDemoGinger2.createRenderPass();
VKPipelineManager.createGraphicsPipeline();
VulkanDemoGinger2.createColorResources();
VulkanDemoGinger2.createDepthResources();
VulkanDemoGinger2.createFramebuffers();
VulkanDemoGinger2.createUniformBuffers();
VulkanDemoGinger2.createDescriptorPool();
VulkanDemoGinger2.createDescriptorSets();
VulkanDemoGinger2.createCommandBuffers();
}
}