Search in sources :

Example 6 with VkPhysicalDevice

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

the class TwoRotatingTrianglesInvDepthDemo 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;
            TwoRotatingTrianglesInvDepthDemo.width = width;
            TwoRotatingTrianglesInvDepthDemo.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 7 with VkPhysicalDevice

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

the class TriangleDemo 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;
            TriangleDemo.width = width;
            TriangleDemo.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)

Example 8 with VkPhysicalDevice

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

the class TriangleDemo method getFirstPhysicalDevice.

private static VkPhysicalDevice getFirstPhysicalDevice(VkInstance instance) {
    IntBuffer pPhysicalDeviceCount = memAllocInt(1);
    int err = vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, null);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to get number of physical devices: " + translateVulkanResult(err));
    }
    PointerBuffer pPhysicalDevices = memAllocPointer(pPhysicalDeviceCount.get(0));
    err = vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
    long physicalDevice = pPhysicalDevices.get(0);
    memFree(pPhysicalDeviceCount);
    memFree(pPhysicalDevices);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to get physical devices: " + translateVulkanResult(err));
    }
    return new VkPhysicalDevice(physicalDevice, instance);
}
Also used : IntBuffer(java.nio.IntBuffer) PointerBuffer(org.lwjgl.PointerBuffer) VkPhysicalDevice(org.lwjgl.vulkan.VkPhysicalDevice)

Example 9 with VkPhysicalDevice

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

the class TwoRotatingTrianglesDemo 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;
            TwoRotatingTrianglesDemo.width = width;
            TwoRotatingTrianglesDemo.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 10 with VkPhysicalDevice

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

the class TwoRotatingTrianglesInvDepthDemo method getFirstPhysicalDevice.

private static VkPhysicalDevice getFirstPhysicalDevice(VkInstance instance) {
    IntBuffer pPhysicalDeviceCount = memAllocInt(1);
    int err = vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, null);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to get number of physical devices: " + translateVulkanResult(err));
    }
    PointerBuffer pPhysicalDevices = memAllocPointer(pPhysicalDeviceCount.get(0));
    err = vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
    long physicalDevice = pPhysicalDevices.get(0);
    memFree(pPhysicalDeviceCount);
    memFree(pPhysicalDevices);
    if (err != VK_SUCCESS) {
        throw new AssertionError("Failed to get physical devices: " + translateVulkanResult(err));
    }
    return new VkPhysicalDevice(physicalDevice, instance);
}
Also used : IntBuffer(java.nio.IntBuffer) PointerBuffer(org.lwjgl.PointerBuffer) VkPhysicalDevice(org.lwjgl.vulkan.VkPhysicalDevice)

Aggregations

IntBuffer (java.nio.IntBuffer)14 PointerBuffer (org.lwjgl.PointerBuffer)14 VkPhysicalDevice (org.lwjgl.vulkan.VkPhysicalDevice)14 LongBuffer (java.nio.LongBuffer)7 GLFWKeyCallback (org.lwjgl.glfw.GLFWKeyCallback)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 VkInstance (org.lwjgl.vulkan.VkInstance)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