Search in sources :

Example 21 with VkCommandBufferBeginInfo

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

the class ColoredTriangleDemo 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);
    final long pipeline = createPipeline(device, renderPass, vertices.createInfo);
    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, 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;
            ColoredTriangleDemo.width = width;
            ColoredTriangleDemo.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
    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]);
        // 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 : 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) PointerBuffer(org.lwjgl.PointerBuffer) VkSemaphoreCreateInfo(org.lwjgl.vulkan.VkSemaphoreCreateInfo) VkPhysicalDevice(org.lwjgl.vulkan.VkPhysicalDevice) VkPhysicalDeviceMemoryProperties(org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties) GLFWWindowSizeCallback(org.lwjgl.glfw.GLFWWindowSizeCallback) IntBuffer(java.nio.IntBuffer) VkCommandBufferBeginInfo(org.lwjgl.vulkan.VkCommandBufferBeginInfo) VkSubmitInfo(org.lwjgl.vulkan.VkSubmitInfo) VkInstance(org.lwjgl.vulkan.VkInstance) VkDebugReportCallbackEXT(org.lwjgl.vulkan.VkDebugReportCallbackEXT)

Aggregations

VkCommandBufferBeginInfo (org.lwjgl.vulkan.VkCommandBufferBeginInfo)21 PointerBuffer (org.lwjgl.PointerBuffer)14 VkCommandBuffer (org.lwjgl.vulkan.VkCommandBuffer)14 VkImageMemoryBarrier (org.lwjgl.vulkan.VkImageMemoryBarrier)14 LongBuffer (java.nio.LongBuffer)13 IntBuffer (java.nio.IntBuffer)7 GLFWKeyCallback (org.lwjgl.glfw.GLFWKeyCallback)7 VkClearValue (org.lwjgl.vulkan.VkClearValue)7 VkCommandBufferAllocateInfo (org.lwjgl.vulkan.VkCommandBufferAllocateInfo)7 VkDebugReportCallbackEXT (org.lwjgl.vulkan.VkDebugReportCallbackEXT)7 VkDevice (org.lwjgl.vulkan.VkDevice)7 VkInstance (org.lwjgl.vulkan.VkInstance)7 VkPhysicalDevice (org.lwjgl.vulkan.VkPhysicalDevice)7 VkPresentInfoKHR (org.lwjgl.vulkan.VkPresentInfoKHR)7 VkQueue (org.lwjgl.vulkan.VkQueue)7 VkRect2D (org.lwjgl.vulkan.VkRect2D)7 VkRenderPassBeginInfo (org.lwjgl.vulkan.VkRenderPassBeginInfo)7 VkSemaphoreCreateInfo (org.lwjgl.vulkan.VkSemaphoreCreateInfo)7 VkSubmitInfo (org.lwjgl.vulkan.VkSubmitInfo)7 VkViewport (org.lwjgl.vulkan.VkViewport)7