Search in sources :

Example 1 with VkCommandBuffer

use of org.lwjgl.vulkan.VkCommandBuffer 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 2 with VkCommandBuffer

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

the class ColoredRotatingQuadDemo method createRenderCommandBuffers.

private static VkCommandBuffer[] createRenderCommandBuffers(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height, Pipeline pipeline, long descriptorSet, long verticesBuf) {
    // Create the render command buffers (one command buffer per framebuffer image)
    VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO).commandPool(commandPool).level(VK_COMMAND_BUFFER_LEVEL_PRIMARY).commandBufferCount(framebuffers.length);
    PointerBuffer pCommandBuffer = memAllocPointer(framebuffers.length);
    int err = vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to allocate render command buffer: " + translateVulkanResult(err));
    }
    VkCommandBuffer[] renderCommandBuffers = new VkCommandBuffer[framebuffers.length];
    for (int i = 0; i < framebuffers.length; i++) {
        renderCommandBuffers[i] = new VkCommandBuffer(pCommandBuffer.get(i), device);
    }
    memFree(pCommandBuffer);
    cmdBufAllocateInfo.free();
    // Create the command buffer begin structure
    VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO).pNext(NULL);
    // Specify clear color (cornflower blue)
    VkClearValue.Buffer clearValues = VkClearValue.calloc(1);
    clearValues.color().float32(0, 100 / 255.0f).float32(1, 149 / 255.0f).float32(2, 237 / 255.0f).float32(3, 1.0f);
    // Specify everything to begin a render pass
    VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO).pNext(NULL).renderPass(renderPass).pClearValues(clearValues);
    VkRect2D renderArea = renderPassBeginInfo.renderArea();
    renderArea.offset().set(0, 0);
    renderArea.extent().set(width, height);
    for (int i = 0; i < renderCommandBuffers.length; ++i) {
        // Set target frame buffer
        renderPassBeginInfo.framebuffer(framebuffers[i]);
        err = vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to begin render command buffer: " + translateVulkanResult(err));
        }
        vkCmdBeginRenderPass(renderCommandBuffers[i], renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
        // Update dynamic viewport state
        VkViewport.Buffer viewport = VkViewport.calloc(1).height(height).width(width).minDepth(0.0f).maxDepth(1.0f);
        vkCmdSetViewport(renderCommandBuffers[i], 0, viewport);
        viewport.free();
        // Update dynamic scissor state
        VkRect2D.Buffer scissor = VkRect2D.calloc(1);
        scissor.extent().set(width, height);
        scissor.offset().set(0, 0);
        vkCmdSetScissor(renderCommandBuffers[i], 0, scissor);
        scissor.free();
        // Bind descriptor sets describing shader binding points
        LongBuffer descriptorSets = memAllocLong(1).put(0, descriptorSet);
        vkCmdBindDescriptorSets(renderCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, descriptorSets, null);
        memFree(descriptorSets);
        // Bind the rendering pipeline (including the shaders)
        vkCmdBindPipeline(renderCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
        // Bind triangle vertices
        LongBuffer offsets = memAllocLong(1);
        offsets.put(0, 0L);
        LongBuffer pBuffers = memAllocLong(1);
        pBuffers.put(0, verticesBuf);
        vkCmdBindVertexBuffers(renderCommandBuffers[i], 0, pBuffers, offsets);
        memFree(pBuffers);
        memFree(offsets);
        // Draw triangle
        vkCmdDraw(renderCommandBuffers[i], 6, 1, 0, 0);
        vkCmdEndRenderPass(renderCommandBuffers[i]);
        // Add a present memory barrier to the end of the command buffer
        // This will transform the frame buffer color attachment to a
        // new layout for presenting it to the windowing system integration
        VkImageMemoryBarrier.Buffer prePresentBarrier = createPrePresentBarrier(swapchain.images[i]);
        vkCmdPipelineBarrier(renderCommandBuffers[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FLAGS_NONE, // No memory barriers
        null, // No buffer memory barriers
        null, // One image memory barrier
        prePresentBarrier);
        prePresentBarrier.free();
        err = vkEndCommandBuffer(renderCommandBuffers[i]);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to begin render command buffer: " + translateVulkanResult(err));
        }
    }
    renderPassBeginInfo.free();
    clearValues.free();
    cmdBufInfo.free();
    return renderCommandBuffers;
}
Also used : VkRect2D(org.lwjgl.vulkan.VkRect2D) LongBuffer(java.nio.LongBuffer) VkCommandBuffer(org.lwjgl.vulkan.VkCommandBuffer) PointerBuffer(org.lwjgl.PointerBuffer) VkViewport(org.lwjgl.vulkan.VkViewport) VkCommandBufferAllocateInfo(org.lwjgl.vulkan.VkCommandBufferAllocateInfo) VkRenderPassBeginInfo(org.lwjgl.vulkan.VkRenderPassBeginInfo) VkClearValue(org.lwjgl.vulkan.VkClearValue) VkCommandBufferBeginInfo(org.lwjgl.vulkan.VkCommandBufferBeginInfo) VkImageMemoryBarrier(org.lwjgl.vulkan.VkImageMemoryBarrier)

Example 3 with VkCommandBuffer

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

the class ColoredTriangleDemo method createRenderCommandBuffers.

private static VkCommandBuffer[] createRenderCommandBuffers(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height, long pipeline, long verticesBuf) {
    // Create the render command buffers (one command buffer per framebuffer image)
    VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO).commandPool(commandPool).level(VK_COMMAND_BUFFER_LEVEL_PRIMARY).commandBufferCount(framebuffers.length);
    PointerBuffer pCommandBuffer = memAllocPointer(framebuffers.length);
    int err = vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to allocate render command buffer: " + translateVulkanResult(err));
    }
    VkCommandBuffer[] renderCommandBuffers = new VkCommandBuffer[framebuffers.length];
    for (int i = 0; i < framebuffers.length; i++) {
        renderCommandBuffers[i] = new VkCommandBuffer(pCommandBuffer.get(i), device);
    }
    memFree(pCommandBuffer);
    cmdBufAllocateInfo.free();
    // Create the command buffer begin structure
    VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO).pNext(NULL);
    // Specify clear color (cornflower blue)
    VkClearValue.Buffer clearValues = VkClearValue.calloc(1);
    clearValues.color().float32(0, 100 / 255.0f).float32(1, 149 / 255.0f).float32(2, 237 / 255.0f).float32(3, 1.0f);
    // Specify everything to begin a render pass
    VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO).pNext(NULL).renderPass(renderPass).pClearValues(clearValues);
    VkRect2D renderArea = renderPassBeginInfo.renderArea();
    renderArea.offset().set(0, 0);
    renderArea.extent().set(width, height);
    for (int i = 0; i < renderCommandBuffers.length; ++i) {
        // Set target frame buffer
        renderPassBeginInfo.framebuffer(framebuffers[i]);
        err = vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to begin render command buffer: " + translateVulkanResult(err));
        }
        vkCmdBeginRenderPass(renderCommandBuffers[i], renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
        // Update dynamic viewport state
        VkViewport.Buffer viewport = VkViewport.calloc(1).height(height).width(width).minDepth(0.0f).maxDepth(1.0f);
        vkCmdSetViewport(renderCommandBuffers[i], 0, viewport);
        viewport.free();
        // Update dynamic scissor state
        VkRect2D.Buffer scissor = VkRect2D.calloc(1);
        scissor.extent().set(width, height);
        scissor.offset().set(0, 0);
        vkCmdSetScissor(renderCommandBuffers[i], 0, scissor);
        scissor.free();
        // Bind the rendering pipeline (including the shaders)
        vkCmdBindPipeline(renderCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
        // Bind triangle vertices
        LongBuffer offsets = memAllocLong(1);
        offsets.put(0, 0L);
        LongBuffer pBuffers = memAllocLong(1);
        pBuffers.put(0, verticesBuf);
        vkCmdBindVertexBuffers(renderCommandBuffers[i], 0, pBuffers, offsets);
        memFree(pBuffers);
        memFree(offsets);
        // Draw triangle
        vkCmdDraw(renderCommandBuffers[i], 3, 1, 0, 0);
        vkCmdEndRenderPass(renderCommandBuffers[i]);
        // Add a present memory barrier to the end of the command buffer
        // This will transform the frame buffer color attachment to a
        // new layout for presenting it to the windowing system integration
        VkImageMemoryBarrier.Buffer prePresentBarrier = createPrePresentBarrier(swapchain.images[i]);
        vkCmdPipelineBarrier(renderCommandBuffers[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FLAGS_NONE, // No memory barriers
        null, // No buffer memory barriers
        null, // One image memory barrier
        prePresentBarrier);
        prePresentBarrier.free();
        err = vkEndCommandBuffer(renderCommandBuffers[i]);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to begin render command buffer: " + translateVulkanResult(err));
        }
    }
    renderPassBeginInfo.free();
    clearValues.free();
    cmdBufInfo.free();
    return renderCommandBuffers;
}
Also used : VkRect2D(org.lwjgl.vulkan.VkRect2D) LongBuffer(java.nio.LongBuffer) VkCommandBuffer(org.lwjgl.vulkan.VkCommandBuffer) PointerBuffer(org.lwjgl.PointerBuffer) VkViewport(org.lwjgl.vulkan.VkViewport) VkCommandBufferAllocateInfo(org.lwjgl.vulkan.VkCommandBufferAllocateInfo) VkRenderPassBeginInfo(org.lwjgl.vulkan.VkRenderPassBeginInfo) VkClearValue(org.lwjgl.vulkan.VkClearValue) VkCommandBufferBeginInfo(org.lwjgl.vulkan.VkCommandBufferBeginInfo) VkImageMemoryBarrier(org.lwjgl.vulkan.VkImageMemoryBarrier)

Example 4 with VkCommandBuffer

use of org.lwjgl.vulkan.VkCommandBuffer 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 VkCommandBuffer

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

the class TriangleDemo method createRenderCommandBuffers.

private static VkCommandBuffer[] createRenderCommandBuffers(VkDevice device, long commandPool, long[] framebuffers, long renderPass, int width, int height, long pipeline, long verticesBuf) {
    // Create the render command buffers (one command buffer per framebuffer image)
    VkCommandBufferAllocateInfo cmdBufAllocateInfo = VkCommandBufferAllocateInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO).commandPool(commandPool).level(VK_COMMAND_BUFFER_LEVEL_PRIMARY).commandBufferCount(framebuffers.length);
    PointerBuffer pCommandBuffer = memAllocPointer(framebuffers.length);
    int err = vkAllocateCommandBuffers(device, cmdBufAllocateInfo, pCommandBuffer);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to allocate render command buffer: " + translateVulkanResult(err));
    }
    VkCommandBuffer[] renderCommandBuffers = new VkCommandBuffer[framebuffers.length];
    for (int i = 0; i < framebuffers.length; i++) {
        renderCommandBuffers[i] = new VkCommandBuffer(pCommandBuffer.get(i), device);
    }
    memFree(pCommandBuffer);
    cmdBufAllocateInfo.free();
    // Create the command buffer begin structure
    VkCommandBufferBeginInfo cmdBufInfo = VkCommandBufferBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO).pNext(NULL);
    // Specify clear color (cornflower blue)
    VkClearValue.Buffer clearValues = VkClearValue.calloc(1);
    clearValues.color().float32(0, 100 / 255.0f).float32(1, 149 / 255.0f).float32(2, 237 / 255.0f).float32(3, 1.0f);
    // Specify everything to begin a render pass
    VkRenderPassBeginInfo renderPassBeginInfo = VkRenderPassBeginInfo.calloc().sType(VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO).pNext(NULL).renderPass(renderPass).pClearValues(clearValues);
    VkRect2D renderArea = renderPassBeginInfo.renderArea();
    renderArea.offset().set(0, 0);
    renderArea.extent().set(width, height);
    for (int i = 0; i < renderCommandBuffers.length; ++i) {
        // Set target frame buffer
        renderPassBeginInfo.framebuffer(framebuffers[i]);
        err = vkBeginCommandBuffer(renderCommandBuffers[i], cmdBufInfo);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to begin render command buffer: " + translateVulkanResult(err));
        }
        vkCmdBeginRenderPass(renderCommandBuffers[i], renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
        // Update dynamic viewport state
        VkViewport.Buffer viewport = VkViewport.calloc(1).height(height).width(width).minDepth(0.0f).maxDepth(1.0f);
        vkCmdSetViewport(renderCommandBuffers[i], 0, viewport);
        viewport.free();
        // Update dynamic scissor state
        VkRect2D.Buffer scissor = VkRect2D.calloc(1);
        scissor.extent().set(width, height);
        scissor.offset().set(0, 0);
        vkCmdSetScissor(renderCommandBuffers[i], 0, scissor);
        scissor.free();
        // Bind the rendering pipeline (including the shaders)
        vkCmdBindPipeline(renderCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
        // Bind triangle vertices
        LongBuffer offsets = memAllocLong(1);
        offsets.put(0, 0L);
        LongBuffer pBuffers = memAllocLong(1);
        pBuffers.put(0, verticesBuf);
        vkCmdBindVertexBuffers(renderCommandBuffers[i], 0, pBuffers, offsets);
        memFree(pBuffers);
        memFree(offsets);
        // Draw triangle
        vkCmdDraw(renderCommandBuffers[i], 3, 1, 0, 0);
        vkCmdEndRenderPass(renderCommandBuffers[i]);
        // Add a present memory barrier to the end of the command buffer
        // This will transform the frame buffer color attachment to a
        // new layout for presenting it to the windowing system integration
        VkImageMemoryBarrier.Buffer prePresentBarrier = createPrePresentBarrier(swapchain.images[i]);
        vkCmdPipelineBarrier(renderCommandBuffers[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FLAGS_NONE, // No memory barriers
        null, // No buffer memory barriers
        null, // One image memory barrier
        prePresentBarrier);
        prePresentBarrier.free();
        err = vkEndCommandBuffer(renderCommandBuffers[i]);
        if (err != VK_SUCCESS) {
            throw new AssertionError("Failed to begin render command buffer: " + translateVulkanResult(err));
        }
    }
    renderPassBeginInfo.free();
    clearValues.free();
    cmdBufInfo.free();
    return renderCommandBuffers;
}
Also used : VkRect2D(org.lwjgl.vulkan.VkRect2D) LongBuffer(java.nio.LongBuffer) VkCommandBuffer(org.lwjgl.vulkan.VkCommandBuffer) PointerBuffer(org.lwjgl.PointerBuffer) VkViewport(org.lwjgl.vulkan.VkViewport) VkCommandBufferAllocateInfo(org.lwjgl.vulkan.VkCommandBufferAllocateInfo) VkRenderPassBeginInfo(org.lwjgl.vulkan.VkRenderPassBeginInfo) VkClearValue(org.lwjgl.vulkan.VkClearValue) VkCommandBufferBeginInfo(org.lwjgl.vulkan.VkCommandBufferBeginInfo) VkImageMemoryBarrier(org.lwjgl.vulkan.VkImageMemoryBarrier)

Aggregations

PointerBuffer (org.lwjgl.PointerBuffer)21 VkCommandBuffer (org.lwjgl.vulkan.VkCommandBuffer)21 VkCommandBufferAllocateInfo (org.lwjgl.vulkan.VkCommandBufferAllocateInfo)14 VkCommandBufferBeginInfo (org.lwjgl.vulkan.VkCommandBufferBeginInfo)14 LongBuffer (java.nio.LongBuffer)13 IntBuffer (java.nio.IntBuffer)7 GLFWKeyCallback (org.lwjgl.glfw.GLFWKeyCallback)7 VkClearValue (org.lwjgl.vulkan.VkClearValue)7 VkDebugReportCallbackEXT (org.lwjgl.vulkan.VkDebugReportCallbackEXT)7 VkDevice (org.lwjgl.vulkan.VkDevice)7 VkImageMemoryBarrier (org.lwjgl.vulkan.VkImageMemoryBarrier)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