Search in sources :

Example 1 with VkInstance

use of org.lwjgl.vulkan.VkInstance in project lwjgl3-demos by LWJGL.

the class ClearScreenDemo method createInstance.

/**
 * Create a Vulkan {@link VkInstance} using LWJGL 3.
 * <p>
 * The {@link VkInstance} represents a handle to the Vulkan API and we need that instance for about everything we do.
 *
 * @return the VkInstance handle
 */
private static VkInstance createInstance(PointerBuffer requiredExtensions) {
    // Here we say what the name of our application is and which Vulkan version we are targetting (having this is optional)
    VkApplicationInfo appInfo = VkApplicationInfo.calloc().sType(VK_STRUCTURE_TYPE_APPLICATION_INFO).pApplicationName(memUTF8("GLFW Vulkan Demo")).pEngineName(memUTF8("")).apiVersion(VK_MAKE_VERSION(1, 0, 2));
    // We also need to tell Vulkan which extensions we would like to use.
    // Those include the platform-dependent required extensions we are being told by GLFW to use.
    // This includes stuff like the Window System Interface extensions to actually render something on a window.
    // 
    // We also add the debug extension so that validation layers and other things can send log messages to us.
    ByteBuffer VK_EXT_DEBUG_REPORT_EXTENSION = memUTF8(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
    PointerBuffer ppEnabledExtensionNames = memAllocPointer(requiredExtensions.remaining() + 1);
    // <- platform-dependent required extensions
    ppEnabledExtensionNames.put(requiredExtensions).put(// <- the debug extensions
    VK_EXT_DEBUG_REPORT_EXTENSION).flip();
    // Now comes the validation layers. These layers sit between our application (the Vulkan client) and the
    // Vulkan driver. Those layers will check whether we make any mistakes in using the Vulkan API and yell
    // at us via the debug extension.
    PointerBuffer ppEnabledLayerNames = memAllocPointer(layers.length);
    for (int i = 0; validation && i < layers.length; i++) ppEnabledLayerNames.put(layers[i]);
    ppEnabledLayerNames.flip();
    // Vulkan uses many struct/record types when creating something. This ensures that every information is available
    // at the callsite of the creation and allows for easier validation and also for immutability of the created object.
    // 
    // The following struct defines everything that is needed to create a VkInstance
    VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo.calloc().sType(// <- identifies what kind of struct this is (this is useful for extending the struct type later)
    VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO).pNext(// <- must always be NULL until any next Vulkan version tells otherwise
    NULL).pApplicationInfo(// <- the application info we created above
    appInfo).ppEnabledExtensionNames(// <- and the extension names themselves
    ppEnabledExtensionNames).ppEnabledLayerNames(// <- and the layer names themselves
    ppEnabledLayerNames);
    // <- create a PointerBuffer which will hold the handle to the created VkInstance
    PointerBuffer pInstance = memAllocPointer(1);
    // <- actually create the VkInstance now!
    int err = vkCreateInstance(pCreateInfo, null, pInstance);
    // <- get the VkInstance handle
    long instance = pInstance.get(0);
    // <- free the PointerBuffer
    memFree(pInstance);
    // Check whether we succeeded in creating the VkInstance
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to create VkInstance: " + translateVulkanResult(err));
    }
    // Create an object-oriented wrapper around the simple VkInstance long handle
    // This is needed by LWJGL to later "dispatch" (i.e. direct calls to) the right Vukan functions.
    VkInstance ret = new VkInstance(instance, pCreateInfo);
    // Now we can free/deallocate everything
    pCreateInfo.free();
    memFree(ppEnabledLayerNames);
    memFree(VK_EXT_DEBUG_REPORT_EXTENSION);
    memFree(ppEnabledExtensionNames);
    memFree(appInfo.pApplicationName());
    memFree(appInfo.pEngineName());
    appInfo.free();
    return ret;
}
Also used : VkApplicationInfo(org.lwjgl.vulkan.VkApplicationInfo) PointerBuffer(org.lwjgl.PointerBuffer) ByteBuffer(java.nio.ByteBuffer) VkInstance(org.lwjgl.vulkan.VkInstance) VkInstanceCreateInfo(org.lwjgl.vulkan.VkInstanceCreateInfo)

Example 2 with VkInstance

use of org.lwjgl.vulkan.VkInstance in project lwjgl3-demos by LWJGL.

the class ColoredRotatingQuadDemo method createInstance.

/**
 * Create a Vulkan instance using LWJGL 3.
 *
 * @return the VkInstance handle
 */
private static VkInstance createInstance(PointerBuffer requiredExtensions) {
    VkApplicationInfo appInfo = VkApplicationInfo.calloc().sType(VK_STRUCTURE_TYPE_APPLICATION_INFO).pApplicationName(memUTF8("GLFW Vulkan Demo")).pEngineName(memUTF8("")).apiVersion(VK_MAKE_VERSION(1, 0, 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(layers.length);
    for (int i = 0; validation && i < layers.length; i++) ppEnabledLayerNames.put(layers[i]);
    ppEnabledLayerNames.flip();
    VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo.calloc().sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO).pNext(NULL).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: " + 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;
}
Also used : VkApplicationInfo(org.lwjgl.vulkan.VkApplicationInfo) PointerBuffer(org.lwjgl.PointerBuffer) ByteBuffer(java.nio.ByteBuffer) VkInstance(org.lwjgl.vulkan.VkInstance) VkInstanceCreateInfo(org.lwjgl.vulkan.VkInstanceCreateInfo)

Example 3 with VkInstance

use of org.lwjgl.vulkan.VkInstance in project lwjgl3-demos by LWJGL.

the class ColoredRotatingQuadDemo method main.

public static void main(String[] args) throws IOException {
    if (!glfwInit()) {
        throw new RuntimeException("Failed to initialize GLFW");
    }
    if (!glfwVulkanSupported()) {
        throw new AssertionError("GLFW failed to find the Vulkan loader");
    }
    /* Look for instance extensions */
    PointerBuffer requiredExtensions = glfwGetRequiredInstanceExtensions();
    if (requiredExtensions == null) {
        throw new AssertionError("Failed to find list of required Vulkan extensions");
    }
    // Create the Vulkan instance
    final VkInstance instance = createInstance(requiredExtensions);
    final VkDebugReportCallbackEXT 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;
        }
    };
    final long debugCallbackHandle = setupDebugging(instance, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, debugCallback);
    final VkPhysicalDevice physicalDevice = getFirstPhysicalDevice(instance);
    final DeviceAndGraphicsQueueFamily deviceAndGraphicsQueueFamily = createDeviceAndGetGraphicsQueueFamily(physicalDevice);
    final VkDevice device = deviceAndGraphicsQueueFamily.device;
    int queueFamilyIndex = deviceAndGraphicsQueueFamily.queueFamilyIndex;
    final VkPhysicalDeviceMemoryProperties memoryProperties = deviceAndGraphicsQueueFamily.memoryProperties;
    // Create GLFW window
    glfwDefaultWindowHints();
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    long window = glfwCreateWindow(800, 600, "GLFW Vulkan Demo", NULL, NULL);
    GLFWKeyCallback keyCallback;
    glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {

        public void invoke(long window, int key, int scancode, int action, int mods) {
            if (action != GLFW_RELEASE)
                return;
            if (key == GLFW_KEY_ESCAPE)
                glfwSetWindowShouldClose(window, true);
        }
    });
    LongBuffer pSurface = memAllocLong(1);
    int err = glfwCreateWindowSurface(instance, window, null, pSurface);
    final long surface = pSurface.get(0);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to create surface: " + translateVulkanResult(err));
    }
    // Create static Vulkan resources
    final ColorFormatAndSpace colorFormatAndSpace = getColorFormatAndSpace(physicalDevice, surface);
    final long commandPool = createCommandPool(device, queueFamilyIndex);
    final VkCommandBuffer setupCommandBuffer = createCommandBuffer(device, commandPool);
    final VkCommandBuffer postPresentCommandBuffer = createCommandBuffer(device, commandPool);
    final VkQueue queue = createDeviceQueue(device, queueFamilyIndex);
    final long renderPass = createRenderPass(device, colorFormatAndSpace.colorFormat);
    final long renderCommandPool = createCommandPool(device, queueFamilyIndex);
    final 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 class SwapchainRecreator {

        boolean mustRecreate = true;

        void recreate() {
            // Begin the setup command buffer (the one we will use for swapchain/framebuffer creation)
            VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO).pNext(NULL);
            int err = vkBeginCommandBuffer(setupCommandBuffer, cmdBufInfo);
            cmdBufInfo.free();
            if (err != VK_SUCCESS) {
                throw new AssertionError("Failed to begin setup command buffer: " + translateVulkanResult(err));
            }
            long oldChain = swapchain != null ? swapchain.swapchainHandle : VK_NULL_HANDLE;
            // Create the swapchain (this will also add a memory barrier to initialize the framebuffer images)
            swapchain = createSwapChain(device, physicalDevice, surface, oldChain, setupCommandBuffer, width, height, colorFormatAndSpace.colorFormat, colorFormatAndSpace.colorSpace);
            err = vkEndCommandBuffer(setupCommandBuffer);
            if (err != VK_SUCCESS) {
                throw new AssertionError("Failed to end setup command buffer: " + translateVulkanResult(err));
            }
            submitCommandBuffer(queue, setupCommandBuffer);
            vkQueueWaitIdle(queue);
            if (framebuffers != null) {
                for (int i = 0; i < framebuffers.length; i++) vkDestroyFramebuffer(device, framebuffers[i], null);
            }
            framebuffers = createFramebuffers(device, swapchain, renderPass, width, height);
            // Create render command buffers
            if (renderCommandBuffers != null) {
                vkResetCommandPool(device, renderCommandPool, VK_FLAGS_NONE);
            }
            renderCommandBuffers = createRenderCommandBuffers(device, renderCommandPool, framebuffers, renderPass, width, height, pipeline, descriptorSet, vertices.verticesBuf);
            mustRecreate = false;
        }
    }
    final SwapchainRecreator swapchainRecreator = new SwapchainRecreator();
    // Handle canvas resize
    GLFWWindowSizeCallback windowSizeCallback = new GLFWWindowSizeCallback() {

        public void invoke(long window, int width, int height) {
            if (width <= 0 || height <= 0)
                return;
            ColoredRotatingQuadDemo.width = width;
            ColoredRotatingQuadDemo.height = height;
            swapchainRecreator.mustRecreate = true;
        }
    };
    glfwSetWindowSizeCallback(window, windowSizeCallback);
    glfwShowWindow(window);
    // Pre-allocate everything needed in the render loop
    IntBuffer pImageIndex = memAllocInt(1);
    int currentBuffer = 0;
    PointerBuffer pCommandBuffers = memAllocPointer(1);
    LongBuffer pSwapchains = memAllocLong(1);
    LongBuffer pImageAcquiredSemaphore = memAllocLong(1);
    LongBuffer pRenderCompleteSemaphore = memAllocLong(1);
    // Info struct to create a semaphore
    VkSemaphoreCreateInfo semaphoreCreateInfo = VkSemaphoreCreateInfo.calloc().sType(VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO).pNext(NULL).flags(VK_FLAGS_NONE);
    // Info struct to submit a command buffer which will wait on the semaphore
    IntBuffer pWaitDstStageMask = memAllocInt(1);
    pWaitDstStageMask.put(0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
    VkSubmitInfo submitInfo = VkSubmitInfo.calloc().sType(VK_STRUCTURE_TYPE_SUBMIT_INFO).pNext(NULL).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(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR).pNext(NULL).pWaitSemaphores(pRenderCompleteSemaphore).swapchainCount(pSwapchains.remaining()).pSwapchains(pSwapchains).pImageIndices(pImageIndex).pResults(null);
    // The render loop
    long lastTime = System.nanoTime();
    float time = 0.0f;
    while (!glfwWindowShouldClose(window)) {
        // Handle window messages. Resize events happen exactly here.
        // So it is safe to use the new swapchain images and framebuffers afterwards.
        glfwPollEvents();
        if (swapchainRecreator.mustRecreate)
            swapchainRecreator.recreate();
        // Create a semaphore to wait for the swapchain to acquire the next image
        err = vkCreateSemaphore(device, semaphoreCreateInfo, null, pImageAcquiredSemaphore);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to create image acquired semaphore: " + translateVulkanResult(err));
        }
        // Create a semaphore to wait for the render to complete, before presenting
        err = vkCreateSemaphore(device, semaphoreCreateInfo, null, pRenderCompleteSemaphore);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to create render complete semaphore: " + 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 = vkAcquireNextImageKHR(device, swapchain.swapchainHandle, UINT64_MAX, pImageAcquiredSemaphore.get(0), VK_NULL_HANDLE, pImageIndex);
        currentBuffer = pImageIndex.get(0);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to acquire next swapchain image: " + 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;
        updateUbo(device, uboDescriptor, time);
        // Submit to the graphics queue
        err = vkQueueSubmit(queue, submitInfo, VK_NULL_HANDLE);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to submit render queue: " + translateVulkanResult(err));
        }
        // Present the current buffer to the swap chain
        // This will display the image
        pSwapchains.put(0, swapchain.swapchainHandle);
        err = vkQueuePresentKHR(queue, presentInfo);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to present the swapchain image: " + translateVulkanResult(err));
        }
        // Create and submit post present barrier
        vkQueueWaitIdle(queue);
        // Destroy this semaphore (we will create a new one in the next frame)
        vkDestroySemaphore(device, pImageAcquiredSemaphore.get(0), null);
        vkDestroySemaphore(device, pRenderCompleteSemaphore.get(0), null);
        submitPostPresentBarrier(swapchain.images[currentBuffer], postPresentCommandBuffer, queue);
    }
    presentInfo.free();
    memFree(pWaitDstStageMask);
    submitInfo.free();
    memFree(pImageAcquiredSemaphore);
    memFree(pRenderCompleteSemaphore);
    semaphoreCreateInfo.free();
    memFree(pSwapchains);
    memFree(pCommandBuffers);
    vkDestroyDebugReportCallbackEXT(instance, debugCallbackHandle, null);
    windowSizeCallback.free();
    keyCallback.free();
    glfwDestroyWindow(window);
    glfwTerminate();
// We don't bother disposing of all Vulkan resources.
// Let the OS process manager take care of it.
}
Also used : PointerBuffer(org.lwjgl.PointerBuffer) VkSemaphoreCreateInfo(org.lwjgl.vulkan.VkSemaphoreCreateInfo) VkPhysicalDevice(org.lwjgl.vulkan.VkPhysicalDevice) GLFWWindowSizeCallback(org.lwjgl.glfw.GLFWWindowSizeCallback) VkCommandBufferBeginInfo(org.lwjgl.vulkan.VkCommandBufferBeginInfo) VkSubmitInfo(org.lwjgl.vulkan.VkSubmitInfo) VkDebugReportCallbackEXT(org.lwjgl.vulkan.VkDebugReportCallbackEXT) GLFWKeyCallback(org.lwjgl.glfw.GLFWKeyCallback) LongBuffer(java.nio.LongBuffer) VkDevice(org.lwjgl.vulkan.VkDevice) VkQueue(org.lwjgl.vulkan.VkQueue) VkPresentInfoKHR(org.lwjgl.vulkan.VkPresentInfoKHR) VkCommandBuffer(org.lwjgl.vulkan.VkCommandBuffer) VkPhysicalDeviceMemoryProperties(org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties) IntBuffer(java.nio.IntBuffer) VkInstance(org.lwjgl.vulkan.VkInstance)

Example 4 with VkInstance

use of org.lwjgl.vulkan.VkInstance in project lwjgl3-demos by LWJGL.

the class InstancedSpheresDemo method main.

public static void main(String[] args) throws IOException {
    if (!glfwInit()) {
        throw new RuntimeException("Failed to initialize GLFW");
    }
    if (!glfwVulkanSupported()) {
        throw new AssertionError("GLFW failed to find the Vulkan loader");
    }
    /* Look for instance extensions */
    PointerBuffer requiredExtensions = glfwGetRequiredInstanceExtensions();
    if (requiredExtensions == null) {
        throw new AssertionError("Failed to find list of required Vulkan extensions");
    }
    // Create the Vulkan instance
    final VkInstance instance = createInstance(requiredExtensions);
    final VkDebugReportCallbackEXT 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;
        }
    };
    final long debugCallbackHandle = setupDebugging(instance, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, debugCallback);
    final VkPhysicalDevice physicalDevice = getFirstPhysicalDevice(instance);
    final DeviceAndGraphicsQueueFamily deviceAndGraphicsQueueFamily = createDeviceAndGetGraphicsQueueFamily(physicalDevice);
    final VkDevice device = deviceAndGraphicsQueueFamily.device;
    int queueFamilyIndex = deviceAndGraphicsQueueFamily.queueFamilyIndex;
    final VkPhysicalDeviceMemoryProperties memoryProperties = deviceAndGraphicsQueueFamily.memoryProperties;
    // Create GLFW window
    glfwDefaultWindowHints();
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    long window = glfwCreateWindow(800, 600, "GLFW Vulkan Demo", NULL, NULL);
    GLFWKeyCallback keyCallback;
    glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {

        public void invoke(long window, int key, int scancode, int action, int mods) {
            if (action != GLFW_RELEASE)
                return;
            if (key == GLFW_KEY_ESCAPE)
                glfwSetWindowShouldClose(window, true);
        }
    });
    LongBuffer pSurface = memAllocLong(1);
    int err = glfwCreateWindowSurface(instance, window, null, pSurface);
    final long surface = pSurface.get(0);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to create surface: " + translateVulkanResult(err));
    }
    // Create static Vulkan resources
    final ColorAndDepthFormatAndSpace colorAndDepthFormatAndSpace = getColorFormatAndSpace(physicalDevice, surface);
    final long commandPool = createCommandPool(device, queueFamilyIndex);
    final VkCommandBuffer setupCommandBuffer = createCommandBuffer(device, commandPool);
    final VkCommandBuffer postPresentCommandBuffer = createCommandBuffer(device, commandPool);
    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);
    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 class SwapchainRecreator {

        boolean mustRecreate = true;

        void recreate() {
            // Begin the setup command buffer (the one we will use for swapchain/framebuffer creation)
            VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO).pNext(NULL);
            int err = vkBeginCommandBuffer(setupCommandBuffer, cmdBufInfo);
            cmdBufInfo.free();
            if (err != VK_SUCCESS) {
                throw new AssertionError("Failed to begin setup command buffer: " + translateVulkanResult(err));
            }
            long oldChain = swapchain != null ? swapchain.swapchainHandle : VK_NULL_HANDLE;
            // Create the swapchain (this will also add a memory barrier to initialize the framebuffer images)
            swapchain = createSwapChain(device, physicalDevice, surface, oldChain, setupCommandBuffer, width, height, colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.colorSpace);
            // Create depth-stencil image
            depthStencil = createDepthStencil(device, memoryProperties, colorAndDepthFormatAndSpace.depthFormat, setupCommandBuffer);
            err = vkEndCommandBuffer(setupCommandBuffer);
            if (err != VK_SUCCESS) {
                throw new AssertionError("Failed to end setup command buffer: " + translateVulkanResult(err));
            }
            submitCommandBuffer(queue, setupCommandBuffer);
            vkQueueWaitIdle(queue);
            if (framebuffers != null) {
                for (int i = 0; i < framebuffers.length; i++) vkDestroyFramebuffer(device, framebuffers[i], null);
            }
            framebuffers = createFramebuffers(device, swapchain, renderPass, width, height, depthStencil);
            // Create render command buffers
            if (renderCommandBuffers != null) {
                vkResetCommandPool(device, renderCommandPool, VK_FLAGS_NONE);
            }
            renderCommandBuffers = createRenderCommandBuffers(device, renderCommandPool, framebuffers, renderPass, width, height, pipeline, descriptorSet, vertices.verticesBuf);
            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;
            InstancedSpheresDemo.width = width;
            InstancedSpheresDemo.height = height;
        }
    };
    glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
    glfwShowWindow(window);
    // Pre-allocate everything needed in the render loop
    IntBuffer pImageIndex = memAllocInt(1);
    int currentBuffer = 0;
    PointerBuffer pCommandBuffers = memAllocPointer(1);
    LongBuffer pSwapchains = memAllocLong(1);
    LongBuffer pImageAcquiredSemaphore = memAllocLong(1);
    LongBuffer pRenderCompleteSemaphore = memAllocLong(1);
    // Info struct to create a semaphore
    VkSemaphoreCreateInfo semaphoreCreateInfo = VkSemaphoreCreateInfo.calloc().sType(VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO).pNext(NULL).flags(VK_FLAGS_NONE);
    // Info struct to submit a command buffer which will wait on the semaphore
    IntBuffer pWaitDstStageMask = memAllocInt(1);
    pWaitDstStageMask.put(0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
    VkSubmitInfo submitInfo = VkSubmitInfo.calloc().sType(VK_STRUCTURE_TYPE_SUBMIT_INFO).pNext(NULL).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(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR).pNext(NULL).pWaitSemaphores(pRenderCompleteSemaphore).swapchainCount(pSwapchains.remaining()).pSwapchains(pSwapchains).pImageIndices(pImageIndex).pResults(null);
    // The render loop
    long lastTime = System.nanoTime();
    float time = 0.0f;
    while (!glfwWindowShouldClose(window)) {
        // Handle window messages. Resize events happen exactly here.
        // So it is safe to use the new swapchain images and framebuffers afterwards.
        glfwPollEvents();
        if (swapchainRecreator.mustRecreate)
            swapchainRecreator.recreate();
        // Create a semaphore to wait for the swapchain to acquire the next image
        err = vkCreateSemaphore(device, semaphoreCreateInfo, null, pImageAcquiredSemaphore);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to create image acquired semaphore: " + translateVulkanResult(err));
        }
        // Create a semaphore to wait for the render to complete, before presenting
        err = vkCreateSemaphore(device, semaphoreCreateInfo, null, pRenderCompleteSemaphore);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to create render complete semaphore: " + 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 = vkAcquireNextImageKHR(device, swapchain.swapchainHandle, UINT64_MAX, pImageAcquiredSemaphore.get(0), VK_NULL_HANDLE, pImageIndex);
        currentBuffer = pImageIndex.get(0);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to acquire next swapchain image: " + 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;
        updateUbo(device, uboDescriptor, time);
        // Submit to the graphics queue
        err = vkQueueSubmit(queue, submitInfo, VK_NULL_HANDLE);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to submit render queue: " + translateVulkanResult(err));
        }
        // Present the current buffer to the swap chain
        // This will display the image
        pSwapchains.put(0, swapchain.swapchainHandle);
        err = vkQueuePresentKHR(queue, presentInfo);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to present the swapchain image: " + translateVulkanResult(err));
        }
        // Create and submit post present barrier
        vkQueueWaitIdle(queue);
        // Destroy this semaphore (we will create a new one in the next frame)
        vkDestroySemaphore(device, pImageAcquiredSemaphore.get(0), null);
        vkDestroySemaphore(device, pRenderCompleteSemaphore.get(0), null);
        submitPostPresentBarrier(swapchain.images[currentBuffer], postPresentCommandBuffer, queue);
    }
    presentInfo.free();
    memFree(pWaitDstStageMask);
    submitInfo.free();
    memFree(pImageAcquiredSemaphore);
    memFree(pRenderCompleteSemaphore);
    semaphoreCreateInfo.free();
    memFree(pSwapchains);
    memFree(pCommandBuffers);
    vkDestroyDebugReportCallbackEXT(instance, debugCallbackHandle, null);
    framebufferSizeCallback.free();
    keyCallback.free();
    glfwDestroyWindow(window);
    glfwTerminate();
// We don't bother disposing of all Vulkan resources.
// Let the OS process manager take care of it.
}
Also used : PointerBuffer(org.lwjgl.PointerBuffer) VkSemaphoreCreateInfo(org.lwjgl.vulkan.VkSemaphoreCreateInfo) VkPhysicalDevice(org.lwjgl.vulkan.VkPhysicalDevice) GLFWFramebufferSizeCallback(org.lwjgl.glfw.GLFWFramebufferSizeCallback) VkCommandBufferBeginInfo(org.lwjgl.vulkan.VkCommandBufferBeginInfo) VkSubmitInfo(org.lwjgl.vulkan.VkSubmitInfo) VkDebugReportCallbackEXT(org.lwjgl.vulkan.VkDebugReportCallbackEXT) GLFWKeyCallback(org.lwjgl.glfw.GLFWKeyCallback) LongBuffer(java.nio.LongBuffer) VkDevice(org.lwjgl.vulkan.VkDevice) VkQueue(org.lwjgl.vulkan.VkQueue) VkPresentInfoKHR(org.lwjgl.vulkan.VkPresentInfoKHR) VkCommandBuffer(org.lwjgl.vulkan.VkCommandBuffer) VkPhysicalDeviceMemoryProperties(org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties) IntBuffer(java.nio.IntBuffer) VkInstance(org.lwjgl.vulkan.VkInstance)

Example 5 with VkInstance

use of org.lwjgl.vulkan.VkInstance in project lwjgl3-demos by LWJGL.

the class TriangleDemo method createInstance.

/**
 * Create a Vulkan instance using LWJGL 3.
 *
 * @return the VkInstance handle
 */
private static VkInstance createInstance(PointerBuffer requiredExtensions) {
    VkApplicationInfo appInfo = VkApplicationInfo.calloc().sType(VK_STRUCTURE_TYPE_APPLICATION_INFO).pApplicationName(memUTF8("GLFW Vulkan Demo")).pEngineName(memUTF8("")).apiVersion(VK_MAKE_VERSION(1, 0, 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(layers.length);
    for (int i = 0; validation && i < layers.length; i++) ppEnabledLayerNames.put(layers[i]);
    ppEnabledLayerNames.flip();
    VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo.calloc().sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO).pNext(NULL).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: " + 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;
}
Also used : VkApplicationInfo(org.lwjgl.vulkan.VkApplicationInfo) PointerBuffer(org.lwjgl.PointerBuffer) ByteBuffer(java.nio.ByteBuffer) VkInstance(org.lwjgl.vulkan.VkInstance) VkInstanceCreateInfo(org.lwjgl.vulkan.VkInstanceCreateInfo)

Aggregations

PointerBuffer (org.lwjgl.PointerBuffer)14 VkInstance (org.lwjgl.vulkan.VkInstance)14 ByteBuffer (java.nio.ByteBuffer)7 IntBuffer (java.nio.IntBuffer)7 LongBuffer (java.nio.LongBuffer)7 GLFWKeyCallback (org.lwjgl.glfw.GLFWKeyCallback)7 VkApplicationInfo (org.lwjgl.vulkan.VkApplicationInfo)7 VkCommandBuffer (org.lwjgl.vulkan.VkCommandBuffer)7 VkCommandBufferBeginInfo (org.lwjgl.vulkan.VkCommandBufferBeginInfo)7 VkDebugReportCallbackEXT (org.lwjgl.vulkan.VkDebugReportCallbackEXT)7 VkDevice (org.lwjgl.vulkan.VkDevice)7 VkInstanceCreateInfo (org.lwjgl.vulkan.VkInstanceCreateInfo)7 VkPhysicalDevice (org.lwjgl.vulkan.VkPhysicalDevice)7 VkPresentInfoKHR (org.lwjgl.vulkan.VkPresentInfoKHR)7 VkQueue (org.lwjgl.vulkan.VkQueue)7 VkSemaphoreCreateInfo (org.lwjgl.vulkan.VkSemaphoreCreateInfo)7 VkSubmitInfo (org.lwjgl.vulkan.VkSubmitInfo)7 VkPhysicalDeviceMemoryProperties (org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties)6 GLFWWindowSizeCallback (org.lwjgl.glfw.GLFWWindowSizeCallback)4 GLFWFramebufferSizeCallback (org.lwjgl.glfw.GLFWFramebufferSizeCallback)3