From f0dc8d6f38f4d6e5ef873fcf1366d50c083b69cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Tue, 5 Mar 2019 08:59:40 +0100 Subject: [PATCH] Cleanup on Samples (#295) - introduced samples/utils functions in namespace vk::su (vulkan sample utils) - introduced usage of debugReportCallback --- samples/01_InitInstance/01_InitInstance.cpp | 9 +- .../02_EnumerateDevices.cpp | 9 +- samples/02_EnumerateDevices/CMakeLists.txt | 4 +- samples/03_InitDevice/03_InitDevice.cpp | 10 +- samples/03_InitDevice/CMakeLists.txt | 4 +- .../04_InitCommandBuffer.cpp | 24 +- samples/04_InitCommandBuffer/CMakeLists.txt | 4 +- samples/05_InitSwapchain/05_InitSwapchain.cpp | 147 ++------- samples/05_InitSwapchain/CMakeLists.txt | 4 +- .../06_InitDepthBuffer/06_InitDepthBuffer.cpp | 171 +---------- samples/06_InitDepthBuffer/CMakeLists.txt | 4 +- .../07_InitUniformBuffer.cpp | 24 +- samples/07_InitUniformBuffer/CMakeLists.txt | 4 +- .../08_InitPipelineLayout.cpp | 24 +- samples/08_InitPipelineLayout/CMakeLists.txt | 4 +- .../09_InitDescriptorSet.cpp | 40 +-- samples/09_InitDescriptorSet/CMakeLists.txt | 4 +- .../10_InitRenderPass/10_InitRenderPass.cpp | 210 ++----------- samples/10_InitRenderPass/CMakeLists.txt | 4 +- samples/11_InitShaders/11_InitShaders.cpp | 65 +--- samples/11_InitShaders/CMakeLists.txt | 2 + samples/utils/utils.cpp | 284 ++++++++++++++++++ samples/utils/utils.hpp | 59 ++++ 23 files changed, 487 insertions(+), 627 deletions(-) create mode 100644 samples/utils/utils.cpp create mode 100644 samples/utils/utils.hpp diff --git a/samples/01_InitInstance/01_InitInstance.cpp b/samples/01_InitInstance/01_InitInstance.cpp index 6dafbb6..ed4a716 100644 --- a/samples/01_InitInstance/01_InitInstance.cpp +++ b/samples/01_InitInstance/01_InitInstance.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,10 +28,13 @@ int main(int /*argc*/, char * /*argv[]*/) try { // initialize the vk::ApplicationInfo structure - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); + vk::ApplicationInfo applicationInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); + + // initialize the vk::InstanceCreateInfo + vk::InstanceCreateInfo instanceCreateInfo({}, &applicationInfo); // create a UniqueInstance - vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo(vk::InstanceCreateFlags(), &appInfo)); + vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); // Note: No need to explicitly destroy the instance, as the corresponding destroy function is // called by the destructor of the UniqueInstance on leaving this scope. diff --git a/samples/02_EnumerateDevices/02_EnumerateDevices.cpp b/samples/02_EnumerateDevices/02_EnumerateDevices.cpp index fffd15e..461dc68 100644 --- a/samples/02_EnumerateDevices/02_EnumerateDevices.cpp +++ b/samples/02_EnumerateDevices/02_EnumerateDevices.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ // VulkanHpp Samples : 02_EnumerateDevices // Enumerate physical devices +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" #include @@ -25,8 +26,10 @@ int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo({}, &appInfo)); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif /* VULKAN_HPP_KEY_START */ diff --git a/samples/02_EnumerateDevices/CMakeLists.txt b/samples/02_EnumerateDevices/CMakeLists.txt index 8fd3de3..87edabf 100644 --- a/samples/02_EnumerateDevices/CMakeLists.txt +++ b/samples/02_EnumerateDevices/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(02_EnumerateDevices) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 02_EnumerateDevices.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/03_InitDevice/03_InitDevice.cpp b/samples/03_InitDevice/03_InitDevice.cpp index 96ac9cf..f2caa6a 100644 --- a/samples/03_InitDevice/03_InitDevice.cpp +++ b/samples/03_InitDevice/03_InitDevice.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ // VulkanHpp Samples : 03_InitDevice // Create and destroy a device +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" #include @@ -25,8 +26,11 @@ int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo({}, &appInfo)); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif + std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); diff --git a/samples/03_InitDevice/CMakeLists.txt b/samples/03_InitDevice/CMakeLists.txt index e035f89..db1e880 100644 --- a/samples/03_InitDevice/CMakeLists.txt +++ b/samples/03_InitDevice/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(03_InitDevice) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 03_InitDevice.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/04_InitCommandBuffer/04_InitCommandBuffer.cpp b/samples/04_InitCommandBuffer/04_InitCommandBuffer.cpp index ef365e6..38133c9 100644 --- a/samples/04_InitCommandBuffer/04_InitCommandBuffer.cpp +++ b/samples/04_InitCommandBuffer/04_InitCommandBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ // VulkanHpp Samples : 04_InitCommandBuffer // Create command buffer +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" #include @@ -25,24 +26,21 @@ int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo({}, &appInfo)); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif + std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); - assert(graphicsQueueFamilyIndex < queueFamilyProperties.size()); - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo)); + + uint32_t graphicsQueueFamilyIndex = vk::su::findGraphicsQueueFamilyIndex(physicalDevices[0].getQueueFamilyProperties()); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsQueueFamilyIndex); /* VULKAN_HPP_KEY_START */ // create a UniqueCommandPool to allocate a CommandBuffer from - vk::UniqueCommandPool commandPool = device->createCommandPoolUnique(vk::CommandPoolCreateInfo(vk::CommandPoolCreateFlags(), deviceQueueCreateInfo.queueFamilyIndex)); + vk::UniqueCommandPool commandPool = device->createCommandPoolUnique(vk::CommandPoolCreateInfo(vk::CommandPoolCreateFlags(), graphicsQueueFamilyIndex)); // allocate a CommandBuffer from the CommandPool std::vector commandBuffers = device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(commandPool.get(), vk::CommandBufferLevel::ePrimary, 1)); diff --git a/samples/04_InitCommandBuffer/CMakeLists.txt b/samples/04_InitCommandBuffer/CMakeLists.txt index aa94628..a6e1895 100644 --- a/samples/04_InitCommandBuffer/CMakeLists.txt +++ b/samples/04_InitCommandBuffer/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(04_InitCommandBuffer) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 04_InitCommandBuffer.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/05_InitSwapchain/05_InitSwapchain.cpp b/samples/05_InitSwapchain/05_InitSwapchain.cpp index 805f2de..4ca3e35 100644 --- a/samples/05_InitSwapchain/05_InitSwapchain.cpp +++ b/samples/05_InitSwapchain/05_InitSwapchain.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,147 +15,40 @@ // VulkanHpp Samples : 05_InitSwapchain // Initialize a swapchain +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" #include static char const* AppName = "05_InitSwapchain"; static char const* EngineName = "Vulkan.hpp"; -template -constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp) -{ - return assert(!comp(hi, lo)), - comp(v, lo) ? lo : comp(hi, v) ? hi : v; -} - -template -constexpr const T& clamp(const T& v, const T& lo, const T& hi) -{ - return clamp(v, lo, hi, std::less<>()); -} - -static std::vector getDeviceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - return extensions; -} - -static std::vector getInstanceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_IOS_MVK) - extensions.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MACOS_MVK) - extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MIR_KHR) - extensions.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_VI_NN) - extensions.push_back(VK_NN_VI_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WIN32_KHR) - extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XCB_KHR) - extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_KHR) - extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) - extensions.push_back(VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME); -#endif - - return extensions; -} - -#if defined(VK_USE_PLATFORM_WIN32_KHR) -LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_CLOSE: - PostQuitMessage(0); - break; - default: - break; - } - return (DefWindowProc(hWnd, uMsg, wParam, lParam)); -} - -HWND initializeWindow(std::string const& className, std::string const& windowName, LONG width, LONG height) -{ - WNDCLASSEX windowClass; - memset(&windowClass, 0, sizeof(WNDCLASSEX)); - - HINSTANCE instance = GetModuleHandle(nullptr); - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = instance; - windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - windowClass.lpszClassName = className.c_str(); - windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); - - if (!RegisterClassEx(&windowClass)) - { - throw std::runtime_error("Failed to register WNDCLASSEX -> terminating"); - } - - RECT windowRect = { 0, 0, width, height }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - HWND window = CreateWindowEx(0, className.c_str(), windowName.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU, 100, 100, windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, nullptr, nullptr, instance, nullptr); - if (!window) - { - throw std::runtime_error("Failed to create window -> terminating"); - } - - return window; -} -#else -#pragma error "unhandled platform" -#endif - - int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - std::vector instanceExtensions = getInstanceExtensions(); - vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo, 0, nullptr, static_cast(instanceExtensions.size()), instanceExtensions.data()); - vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions()); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); + std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); + uint32_t graphicsQueueFamilyIndex = vk::su::findGraphicsQueueFamilyIndex(queueFamilyProperties); + /* VULKAN_HPP_KEY_START */ - uint32_t width = 50; - uint32_t height = 50; + uint32_t width = 64; + uint32_t height = 64; #if defined(VK_USE_PLATFORM_WIN32_KHR) - HWND window = initializeWindow(AppName, "Sample", width, height); + HWND window = vk::su::initializeWindow(AppName, AppName, width, height); vk::UniqueSurfaceKHR surface = instance->createWin32SurfaceKHRUnique(vk::Win32SurfaceCreateInfoKHR(vk::Win32SurfaceCreateFlagsKHR(), GetModuleHandle(nullptr), window)); #else #pragma error "unhandled platform" #endif - // determine a queueFamilyIndex that supports graphics - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); - // determine a queueFamilyIndex that suports present // first check if the graphicsQueueFamiliyIndex is good enough size_t presentQueueFamilyIndex = physicalDevices[0].getSurfaceSupportKHR(static_cast(graphicsQueueFamilyIndex), surface.get()) ? graphicsQueueFamilyIndex : queueFamilyProperties.size(); @@ -166,7 +59,7 @@ int main(int /*argc*/, char * /*argv[]*/) { if ((queueFamilyProperties[i].queueFlags & vk::QueueFlagBits::eGraphics) && physicalDevices[0].getSurfaceSupportKHR(static_cast(i), surface.get())) { - graphicsQueueFamilyIndex = i; + graphicsQueueFamilyIndex = vk::su::checked_cast(i); presentQueueFamilyIndex = i; break; } @@ -190,10 +83,7 @@ int main(int /*argc*/, char * /*argv[]*/) } // create a device - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - std::vector deviceExtensionNames = getDeviceExtensions(); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo, 0, nullptr, static_cast(deviceExtensionNames.size()), deviceExtensionNames.data())); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsQueueFamilyIndex, vk::su::getDeviceExtensions()); // get the supported VkFormats std::vector formats = physicalDevices[0].getSurfaceFormatsKHR(surface.get()); @@ -201,13 +91,12 @@ int main(int /*argc*/, char * /*argv[]*/) vk::Format format = (formats[0].format == vk::Format::eUndefined) ? vk::Format::eB8G8R8A8Unorm : formats[0].format; vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevices[0].getSurfaceCapabilitiesKHR(surface.get()); - VkExtent2D swapchainExtent; if (surfaceCapabilities.currentExtent.width == std::numeric_limits::max()) { // If the surface size is undefined, the size is set to the size of the images requested. - swapchainExtent.width = clamp(width, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width); - swapchainExtent.height = clamp(height, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height); + swapchainExtent.width = vk::su::clamp(width, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width); + swapchainExtent.height = vk::su::clamp(height, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height); } else { @@ -244,10 +133,10 @@ int main(int /*argc*/, char * /*argv[]*/) std::vector imageViews; imageViews.reserve(swapChainImages.size()); + vk::ComponentMapping componentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA); + vk::ImageSubresourceRange subResourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1); for (auto image : swapChainImages) { - vk::ComponentMapping componentMapping(vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA); - vk::ImageSubresourceRange subResourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1); vk::ImageViewCreateInfo imageViewCreateInfo(vk::ImageViewCreateFlags(), image, vk::ImageViewType::e2D, format, componentMapping, subResourceRange); imageViews.push_back(device->createImageViewUnique(imageViewCreateInfo)); } diff --git a/samples/05_InitSwapchain/CMakeLists.txt b/samples/05_InitSwapchain/CMakeLists.txt index 9d99e45..0356011 100644 --- a/samples/05_InitSwapchain/CMakeLists.txt +++ b/samples/05_InitSwapchain/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(05_InitSwapchain) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 05_InitSwapchain.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp b/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp index 136553c..ebb85cf 100644 --- a/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp +++ b/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,183 +15,36 @@ // VulkanHpp Samples : 06_InitDepthBuffer // Initialize a depth buffer +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" #include static char const* AppName = "06_InitDepthBuffer"; static char const* EngineName = "Vulkan.hpp"; -template -constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp) -{ - return assert(!comp(hi, lo)), - comp(v, lo) ? lo : comp(hi, v) ? hi : v; -} - -template -constexpr const T& clamp(const T& v, const T& lo, const T& hi) -{ - return clamp(v, lo, hi, std::less<>()); -} - -static std::vector getDeviceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - return extensions; -} - -static std::vector getInstanceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_IOS_MVK) - extensions.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MACOS_MVK) - extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MIR_KHR) - extensions.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_VI_NN) - extensions.push_back(VK_NN_VI_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WIN32_KHR) - extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XCB_KHR) - extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_KHR) - extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) - extensions.push_back(VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME); -#endif - - return extensions; -} - -#if defined(VK_USE_PLATFORM_WIN32_KHR) -LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_CLOSE: - PostQuitMessage(0); - break; - default: - break; - } - return (DefWindowProc(hWnd, uMsg, wParam, lParam)); -} - -HWND initializeWindow(std::string const& className, std::string const& windowName, LONG width, LONG height) -{ - WNDCLASSEX windowClass; - memset(&windowClass, 0, sizeof(WNDCLASSEX)); - - HINSTANCE instance = GetModuleHandle(nullptr); - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = instance; - windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - windowClass.lpszClassName = className.c_str(); - windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); - - if (!RegisterClassEx(&windowClass)) - { - throw std::runtime_error("Failed to register WNDCLASSEX -> terminating"); - } - - RECT windowRect = { 0, 0, width, height }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - HWND window = CreateWindowEx(0, className.c_str(), windowName.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU, 100, 100, windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, nullptr, nullptr, instance, nullptr); - if (!window) - { - throw std::runtime_error("Failed to create window -> terminating"); - } - - return window; -} -#else -#pragma error "unhandled platform" -#endif - - int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - std::vector instanceExtensions = getInstanceExtensions(); - vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo, 0, nullptr, static_cast(instanceExtensions.size()), instanceExtensions.data()); - vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions()); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); - uint32_t width = 50; - uint32_t height = 50; + uint32_t width = 500; + uint32_t height = 500; #if defined(VK_USE_PLATFORM_WIN32_KHR) - HWND window = initializeWindow(AppName, "Sample", width, height); - - vk::UniqueSurfaceKHR surface = instance->createWin32SurfaceKHRUnique(vk::Win32SurfaceCreateInfoKHR(vk::Win32SurfaceCreateFlagsKHR(), GetModuleHandle(nullptr), window)); + HWND window = vk::su::initializeWindow(AppName, AppName, width, height); + vk::UniqueSurfaceKHR surface = instance->createWin32SurfaceKHRUnique(vk::Win32SurfaceCreateInfoKHR({}, GetModuleHandle(nullptr), window)); #else #pragma error "unhandled platform" #endif - // determine a queueFamilyIndex that supports graphics - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); - - // determine a queueFamilyIndex that suports present - // first check if the graphicsQueueFamiliyIndex is good enough - size_t presentQueueFamilyIndex = physicalDevices[0].getSurfaceSupportKHR(static_cast(graphicsQueueFamilyIndex), surface.get()) ? graphicsQueueFamilyIndex : queueFamilyProperties.size(); - if (presentQueueFamilyIndex == queueFamilyProperties.size()) - { - // the graphicsQueueFamilyIndex doesn't support present -> look for an other family index that supports both graphics and present - for (size_t i = 0; i < queueFamilyProperties.size(); i++) - { - if ((queueFamilyProperties[i].queueFlags & vk::QueueFlagBits::eGraphics) && physicalDevices[0].getSurfaceSupportKHR(static_cast(i), surface.get())) - { - graphicsQueueFamilyIndex = i; - presentQueueFamilyIndex = i; - break; - } - } - if (presentQueueFamilyIndex == queueFamilyProperties.size()) - { - // there's nothing like a single family index that supports both graphics and present -> look for an other family index that supports present - for (size_t i = 0; i < queueFamilyProperties.size(); i++) - { - if (physicalDevices[0].getSurfaceSupportKHR(static_cast(i), surface.get())) - { - presentQueueFamilyIndex = i; - break; - } - } - } - } - if ((graphicsQueueFamilyIndex == queueFamilyProperties.size()) || (presentQueueFamilyIndex == queueFamilyProperties.size())) - { - throw std::runtime_error("Could not find a queue for graphics or present -> terminating"); - } - - // create a device - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - std::vector deviceExtensionNames = getDeviceExtensions(); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo, 0, nullptr, static_cast(deviceExtensionNames.size()), deviceExtensionNames.data())); + std::pair graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex(physicalDevices[0], surface); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions()); /* VULKAN_HPP_KEY_START */ diff --git a/samples/06_InitDepthBuffer/CMakeLists.txt b/samples/06_InitDepthBuffer/CMakeLists.txt index 30cea1c..7111c13 100644 --- a/samples/06_InitDepthBuffer/CMakeLists.txt +++ b/samples/06_InitDepthBuffer/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(06_InitDepthBuffer) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 06_InitDepthBuffer.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp b/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp index 91e94c8..70ef593 100644 --- a/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp +++ b/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,9 @@ // VulkanHpp Samples : 07_InitUniformBuffer // Initialize a uniform buffer -#include +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" +#include #define GLM_FORCE_RADIANS #pragma warning(disable:4201) // disable warning C4201: nonstandard extension used: nameless struct/union; needed to get glm/detail/type_vec?.hpp without warnings @@ -29,24 +30,15 @@ int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo); - vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); - // determine a queueFamilyIndex that supports graphics - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); - - // create a device - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo, 0, nullptr)); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], vk::su::findGraphicsQueueFamilyIndex(physicalDevices[0].getQueueFamilyProperties())); /* VULKAN_HPP_KEY_START */ diff --git a/samples/07_InitUniformBuffer/CMakeLists.txt b/samples/07_InitUniformBuffer/CMakeLists.txt index 99c6ed4..3c13b37 100644 --- a/samples/07_InitUniformBuffer/CMakeLists.txt +++ b/samples/07_InitUniformBuffer/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(07_InitUniformBuffer) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 07_InitUniformBuffer.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/08_InitPipelineLayout/08_InitPipelineLayout.cpp b/samples/08_InitPipelineLayout/08_InitPipelineLayout.cpp index b3f39a3..304c35c 100644 --- a/samples/08_InitPipelineLayout/08_InitPipelineLayout.cpp +++ b/samples/08_InitPipelineLayout/08_InitPipelineLayout.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,9 @@ // VulkanHpp Samples : 08_InitPipelineLayout // Initialize a descriptor and pipeline layout -#include +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" +#include static char const* AppName = "08_InitPipelineLayout"; static char const* EngineName = "Vulkan.hpp"; @@ -25,24 +26,15 @@ int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo); - vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); - // determine a queueFamilyIndex that supports graphics - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); - - // create a device - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo, 0, nullptr)); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], vk::su::findGraphicsQueueFamilyIndex(physicalDevices[0].getQueueFamilyProperties())); /* VULKAN_HPP_KEY_START */ diff --git a/samples/08_InitPipelineLayout/CMakeLists.txt b/samples/08_InitPipelineLayout/CMakeLists.txt index ac6b2f9..91c9690 100644 --- a/samples/08_InitPipelineLayout/CMakeLists.txt +++ b/samples/08_InitPipelineLayout/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(08_InitPipelineLayout) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 08_InitPipelineLayout.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/09_InitDescriptorSet/09_InitDescriptorSet.cpp b/samples/09_InitDescriptorSet/09_InitDescriptorSet.cpp index 742e85e..d8337d7 100644 --- a/samples/09_InitDescriptorSet/09_InitDescriptorSet.cpp +++ b/samples/09_InitDescriptorSet/09_InitDescriptorSet.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,9 @@ // VulkanHpp Samples : 09_InitDescriptorSet // Initialize a descriptor set -#include +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" +#include #define GLM_FORCE_RADIANS #pragma warning(disable:4201) // disable warning C4201: nonstandard extension used: nameless struct/union; needed to get glm/detail/type_vec?.hpp without warnings @@ -29,46 +30,31 @@ int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo); - vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); - // determine a queueFamilyIndex that supports graphics - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], vk::su::findGraphicsQueueFamilyIndex(physicalDevices[0].getQueueFamilyProperties())); - // create a device - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo, 0, nullptr)); + vk::UniqueBuffer buffer = device->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(), sizeof(glm::mat4x4), vk::BufferUsageFlagBits::eUniformBuffer)); + vk::UniqueDeviceMemory deviceMemory = vk::su::allocateMemory(device, physicalDevices[0].getMemoryProperties(), device->getBufferMemoryRequirements(buffer.get()), vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); - glm::mat4x4 projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f); - glm::mat4x4 view = glm::lookAt(glm::vec3(-5.0f, 3.0f, -10.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)); - glm::mat4x4 model = glm::mat4x4(1.0f); - glm::mat4x4 clip = glm::mat4x4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f); // vulkan clip space has inverted y and half z ! - glm::mat4x4 mvpc = clip * projection * view * model; - - vk::UniqueBuffer buffer = device->createBufferUnique(vk::BufferCreateInfo(vk::BufferCreateFlags(), sizeof(mvpc), vk::BufferUsageFlagBits::eUniformBuffer)); - - // create a DescriptorSetLayout - vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(0, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex); - vk::UniqueDescriptorSetLayout descriptorSetLayout = device->createDescriptorSetLayoutUnique(vk::DescriptorSetLayoutCreateInfo({}, 1, &descriptorSetLayoutBinding)); + vk::UniqueDescriptorSetLayout descriptorSetLayout = vk::su::createDescriptorSetLayout(device); /* VULKAN_HPP_KEY_START */ // create a descriptor pool vk::DescriptorPoolSize poolSize(vk::DescriptorType::eUniformBuffer, 1); - vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(vk::DescriptorPoolCreateInfo(vk::DescriptorPoolCreateFlags(), 1, 1, &poolSize)); + vk::UniqueDescriptorPool descriptorPool = device->createDescriptorPoolUnique(vk::DescriptorPoolCreateInfo(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, 1, &poolSize)); // allocate a descriptor set std::vector descriptorSets = device->allocateDescriptorSetsUnique(vk::DescriptorSetAllocateInfo(descriptorPool.get(), 1, &descriptorSetLayout.get())); + device->bindBufferMemory(buffer.get(), deviceMemory.get(), 0); vk::DescriptorBufferInfo descriptorBufferInfo(buffer.get(), 0, sizeof(glm::mat4x4)); device->updateDescriptorSets(vk::WriteDescriptorSet(descriptorSets[0].get(), 0, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, &descriptorBufferInfo), {}); diff --git a/samples/09_InitDescriptorSet/CMakeLists.txt b/samples/09_InitDescriptorSet/CMakeLists.txt index 0ce4a3a..5988249 100644 --- a/samples/09_InitDescriptorSet/CMakeLists.txt +++ b/samples/09_InitDescriptorSet/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(09_InitDescriptorSet) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 09_InitDescriptorSet.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/10_InitRenderPass/10_InitRenderPass.cpp b/samples/10_InitRenderPass/10_InitRenderPass.cpp index ef78427..0b1fa59 100644 --- a/samples/10_InitRenderPass/10_InitRenderPass.cpp +++ b/samples/10_InitRenderPass/10_InitRenderPass.cpp @@ -1,4 +1,4 @@ -// Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,8 +15,9 @@ // VulkanHpp Samples : 10_InitRenderPass // Initialize a render pass -#include +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" +#include #define GLM_FORCE_RADIANS #pragma warning(disable:4201) // disable warning C4201: nonstandard extension used: nameless struct/union; needed to get glm/detail/type_vec?.hpp without warnings @@ -25,219 +26,46 @@ static char const* AppName = "10_InitRenderPass"; static char const* EngineName = "Vulkan.hpp"; -static std::vector getDeviceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - return extensions; -} - -static std::vector getInstanceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_IOS_MVK) - extensions.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MACOS_MVK) - extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MIR_KHR) - extensions.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_VI_NN) - extensions.push_back(VK_NN_VI_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WIN32_KHR) - extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XCB_KHR) - extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_KHR) - extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) - extensions.push_back(VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME); -#endif - - return extensions; -} - -#if defined(VK_USE_PLATFORM_WIN32_KHR) -LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_CLOSE: - PostQuitMessage(0); - break; - default: - break; - } - return (DefWindowProc(hWnd, uMsg, wParam, lParam)); -} - -HWND initializeWindow(std::string const& className, std::string const& windowName, LONG width, LONG height) -{ - WNDCLASSEX windowClass; - memset(&windowClass, 0, sizeof(WNDCLASSEX)); - - HINSTANCE instance = GetModuleHandle(nullptr); - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = WindowProc; - windowClass.hInstance = instance; - windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - windowClass.lpszClassName = className.c_str(); - windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); - - if (!RegisterClassEx(&windowClass)) - { - throw std::runtime_error("Failed to register WNDCLASSEX -> terminating"); - } - - RECT windowRect = { 0, 0, width, height }; - AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); - - HWND window = CreateWindowEx(0, className.c_str(), windowName.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU, 100, 100, windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, nullptr, nullptr, instance, nullptr); - if (!window) - { - throw std::runtime_error("Failed to create window -> terminating"); - } - - return window; -} -#else -#pragma error "unhandled platform" -#endif - int main(int /*argc*/, char * /*argv[]*/) { try { - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - std::vector instanceExtensions = getInstanceExtensions(); - vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo, 0, nullptr, static_cast(instanceExtensions.size()), instanceExtensions.data()); - vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions()); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); - uint32_t width = 50; - uint32_t height = 50; + uint32_t width = 64; + uint32_t height = 64; #if defined(VK_USE_PLATFORM_WIN32_KHR) - HWND window = initializeWindow(AppName, "Sample", width, height); + HWND window = vk::su::initializeWindow(AppName, AppName, width, height); vk::UniqueSurfaceKHR surface = instance->createWin32SurfaceKHRUnique(vk::Win32SurfaceCreateInfoKHR({}, GetModuleHandle(nullptr), window)); #else #pragma error "unhandled platform" #endif - // determine a queueFamilyIndex that supports graphics - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); - - // determine a queueFamilyIndex that suports present - // first check if the graphicsQueueFamiliyIndex is good enough - size_t presentQueueFamilyIndex = physicalDevices[0].getSurfaceSupportKHR(static_cast(graphicsQueueFamilyIndex), surface.get()) ? graphicsQueueFamilyIndex : queueFamilyProperties.size(); - if (presentQueueFamilyIndex == queueFamilyProperties.size()) - { - // the graphicsQueueFamilyIndex doesn't support present -> look for an other family index that supports both graphics and present - for (size_t i = 0; i < queueFamilyProperties.size(); i++) - { - if ((queueFamilyProperties[i].queueFlags & vk::QueueFlagBits::eGraphics) && physicalDevices[0].getSurfaceSupportKHR(static_cast(i), surface.get())) - { - graphicsQueueFamilyIndex = i; - presentQueueFamilyIndex = i; - break; - } - } - if (presentQueueFamilyIndex == queueFamilyProperties.size()) - { - // there's nothing like a single family index that supports both graphics and present -> look for an other family index that supports present - for (size_t i = 0; i < queueFamilyProperties.size(); i++) - { - if (physicalDevices[0].getSurfaceSupportKHR(static_cast(i), surface.get())) - { - presentQueueFamilyIndex = i; - break; - } - } - } - } - if ((graphicsQueueFamilyIndex == queueFamilyProperties.size()) || (presentQueueFamilyIndex == queueFamilyProperties.size())) - { - throw std::runtime_error("Could not find a queue for graphics or present -> terminating"); - } - - // create a device - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - std::vector deviceExtensionNames = getDeviceExtensions(); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo, 0, nullptr, static_cast(deviceExtensionNames.size()), deviceExtensionNames.data())); - - // get the supported VkFormats - vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevices[0].getSurfaceCapabilitiesKHR(surface.get()); - std::vector formats = physicalDevices[0].getSurfaceFormatsKHR(surface.get()); - assert(!formats.empty()); - vk::Format format = (formats[0].format == vk::Format::eUndefined) ? vk::Format::eB8G8R8A8Unorm : formats[0].format; - - VkExtent2D swapchainExtent; - if (surfaceCapabilities.currentExtent.width == std::numeric_limits::max()) - { - // If the surface size is undefined, the size is set to the size of the images requested. - swapchainExtent.width = glm::clamp(width, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width); - swapchainExtent.height = glm::clamp(height, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height); - } - else - { - // If the surface size is defined, the swap chain size must match - swapchainExtent = surfaceCapabilities.currentExtent; - } - - vk::SurfaceTransformFlagBitsKHR preTransform = (surfaceCapabilities.supportedTransforms & vk::SurfaceTransformFlagBitsKHR::eIdentity) ? vk::SurfaceTransformFlagBitsKHR::eIdentity : surfaceCapabilities.currentTransform; - - vk::CompositeAlphaFlagBitsKHR compositeAlpha = - (surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePreMultiplied) ? vk::CompositeAlphaFlagBitsKHR::ePreMultiplied : - (surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePostMultiplied) ? vk::CompositeAlphaFlagBitsKHR::ePostMultiplied : - (surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eInherit) ? vk::CompositeAlphaFlagBitsKHR::eInherit : vk::CompositeAlphaFlagBitsKHR::eOpaque; - - vk::SwapchainCreateInfoKHR swapChainCreateInfo({}, surface.get(), surfaceCapabilities.minImageCount, format, vk::ColorSpaceKHR::eSrgbNonlinear, swapchainExtent, 1, - vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc, vk::SharingMode::eExclusive, 0, nullptr, preTransform, compositeAlpha, vk::PresentModeKHR::eFifo, true, - nullptr); - - uint32_t queueFamilyIndices[2] = { static_cast(graphicsQueueFamilyIndex), static_cast(presentQueueFamilyIndex) }; - if (graphicsQueueFamilyIndex != presentQueueFamilyIndex) - { - // If the graphics and present queues are from different queue families, we either have to explicitly transfer ownership of images between - // the queues, or we have to create the swapchain with imageSharingMode as VK_SHARING_MODE_CONCURRENT - swapChainCreateInfo.imageSharingMode = vk::SharingMode::eConcurrent; - swapChainCreateInfo.queueFamilyIndexCount = 2; - swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices; - } - vk::UniqueSwapchainKHR swapChain = device->createSwapchainKHRUnique(swapChainCreateInfo); + std::pair graphicsAndPresentQueueFamilyIndex = vk::su::findGraphicsAndPresentQueueFamilyIndex(physicalDevices[0], surface); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions()); + vk::Format colorFormat = vk::su::pickColorFormat(physicalDevices[0].getSurfaceFormatsKHR(surface.get())); const vk::Format depthFormat = vk::Format::eD16Unorm; /* VULKAN_HPP_KEY_START */ - vk::AttachmentDescription attachments[2]; - attachments[0] = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), format, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, - vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR); - attachments[1] = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), depthFormat, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare, - vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal); + vk::AttachmentDescription attachmentDescriptions[2]; + attachmentDescriptions[0] = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), colorFormat, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, + vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR); + attachmentDescriptions[1] = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), depthFormat, vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, + vk::AttachmentStoreOp::eDontCare, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal); vk::AttachmentReference colorReference(0, vk::ImageLayout::eColorAttachmentOptimal); vk::AttachmentReference depthReference(1, vk::ImageLayout::eDepthStencilAttachmentOptimal); vk::SubpassDescription subpass(vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, 0, nullptr, 1, &colorReference, nullptr, &depthReference); - vk::UniqueRenderPass renderPass = device->createRenderPassUnique(vk::RenderPassCreateInfo(vk::RenderPassCreateFlags(), 2, attachments, 1, &subpass)); + vk::UniqueRenderPass renderPass = device->createRenderPassUnique(vk::RenderPassCreateInfo(vk::RenderPassCreateFlags(), 2, attachmentDescriptions, 1, &subpass)); // Note: No need to explicitly destroy the RenderPass or the Semaphore, as the corresponding destroy // functions are called by the destructor of the UniqueRenderPass and the UniqueSemaphore on leaving this scope. diff --git a/samples/10_InitRenderPass/CMakeLists.txt b/samples/10_InitRenderPass/CMakeLists.txt index 09e1b8c..97ddf87 100644 --- a/samples/10_InitRenderPass/CMakeLists.txt +++ b/samples/10_InitRenderPass/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(c) 2018, NVIDIA CORPORATION. All rights reserved. +# Copyright(c) 2018-2019, NVIDIA CORPORATION. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(10_InitRenderPass) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 10_InitRenderPass.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/11_InitShaders/11_InitShaders.cpp b/samples/11_InitShaders/11_InitShaders.cpp index 41affcf..9feea7f 100644 --- a/samples/11_InitShaders/11_InitShaders.cpp +++ b/samples/11_InitShaders/11_InitShaders.cpp @@ -15,52 +15,14 @@ // VulkanHpp Samples : 11_InitShaders // Initialize vertex and fragment shaders -#include +#include "..\utils\utils.hpp" #include "vulkan/vulkan.hpp" #include "SPIRV/GlslangToSpv.h" +#include static char const* AppName = "11_InitShaders"; static char const* EngineName = "Vulkan.hpp"; -static std::vector getDeviceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - return extensions; -} - -static std::vector getInstanceExtensions() -{ - std::vector extensions; - - extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_IOS_MVK) - extensions.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MACOS_MVK) - extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_MIR_KHR) - extensions.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_VI_NN) - extensions.push_back(VK_NN_VI_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_WIN32_KHR) - extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XCB_KHR) - extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_KHR) - extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); -#elif defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) - extensions.push_back(VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME); -#endif - - return extensions; -} - EShLanguage translateShaderStage(vk::ShaderStageFlagBits stage) { switch (stage) @@ -219,28 +181,15 @@ int main(int /*argc*/, char * /*argv[]*/) { try { - // create an instance - vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); - std::vector instanceExtensions = getInstanceExtensions(); - vk::InstanceCreateInfo instanceCreateInfo({}, &appInfo, 0, nullptr, static_cast(instanceExtensions.size()), instanceExtensions.data()); - vk::UniqueInstance instance = vk::createInstanceUnique(instanceCreateInfo); + vk::UniqueInstance instance = vk::su::createInstance(AppName, EngineName, vk::su::getInstanceExtensions()); +#if !defined(NDEBUG) + vk::UniqueDebugReportCallbackEXT debugReportCallback = vk::su::createDebugReportCallback(instance); +#endif - // get the physical devices std::vector physicalDevices = instance->enumeratePhysicalDevices(); assert(!physicalDevices.empty()); - // determine a queueFamilyIndex that supports graphics - std::vector queueFamilyProperties = physicalDevices[0].getQueueFamilyProperties(); - size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), - std::find_if(queueFamilyProperties.begin(), - queueFamilyProperties.end(), - [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); - - // create a device - float queuePriority = 0.0f; - vk::DeviceQueueCreateInfo deviceQueueCreateInfo({}, static_cast(graphicsQueueFamilyIndex), 1, &queuePriority); - std::vector deviceExtensionNames = getDeviceExtensions(); - vk::UniqueDevice device = physicalDevices[0].createDeviceUnique(vk::DeviceCreateInfo({}, 1, &deviceQueueCreateInfo, 0, nullptr, static_cast(deviceExtensionNames.size()), deviceExtensionNames.data())); + vk::UniqueDevice device = vk::su::createDevice(physicalDevices[0], vk::su::findGraphicsQueueFamilyIndex(physicalDevices[0].getQueueFamilyProperties()), vk::su::getDeviceExtensions()); /* VULKAN_HPP_KEY_START */ diff --git a/samples/11_InitShaders/CMakeLists.txt b/samples/11_InitShaders/CMakeLists.txt index ea19349..9d94308 100644 --- a/samples/11_InitShaders/CMakeLists.txt +++ b/samples/11_InitShaders/CMakeLists.txt @@ -17,10 +17,12 @@ cmake_minimum_required(VERSION 3.2) project(11_InitShaders) set(HEADERS + ../utils/utils.hpp ) set(SOURCES 11_InitShaders.cpp + ../utils/utils.cpp ) source_group(headers FILES ${HEADERS}) diff --git a/samples/utils/utils.cpp b/samples/utils/utils.cpp new file mode 100644 index 0000000..b4a195f --- /dev/null +++ b/samples/utils/utils.cpp @@ -0,0 +1,284 @@ +// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "utils.hpp" +#include "vulkan/vulkan.hpp" + +PFN_vkCreateDebugReportCallbackEXT pfnVkCreateDebugReportCallbackEXT; +PFN_vkDestroyDebugReportCallbackEXT pfnVkDestroyDebugReportCallbackEXT; + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) +{ + return pfnVkCreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback); +} + +VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) +{ + pfnVkDestroyDebugReportCallbackEXT(instance, callback, pAllocator); +} + +namespace vk +{ + namespace su + { + vk::UniqueDeviceMemory allocateMemory(vk::UniqueDevice &device, vk::PhysicalDeviceMemoryProperties const& memoryProperties, vk::MemoryRequirements const& memoryRequirements, vk::MemoryPropertyFlags memoryPropertyFlags) + { + uint32_t memoryTypeBits = memoryRequirements.memoryTypeBits; + uint32_t memoryTypeIndex = static_cast(~0); + for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) + { + if ((memoryTypeBits & 1) == 1) + { + if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertyFlags) == memoryPropertyFlags) + { + memoryTypeIndex = i; + break; + } + } + memoryTypeBits >>= 1; + } + assert(memoryTypeIndex != ~0); + + return device->allocateMemoryUnique(vk::MemoryAllocateInfo(memoryRequirements.size, memoryTypeIndex)); + } + + vk::UniqueDebugReportCallbackEXT createDebugReportCallback(vk::UniqueInstance &instance) + { + vk::DebugReportFlagsEXT flags(vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning | vk::DebugReportFlagBitsEXT::eError); + return instance->createDebugReportCallbackEXTUnique(vk::DebugReportCallbackCreateInfoEXT(flags, &vk::su::debugReportCallback)); + } + + vk::UniqueDescriptorSetLayout createDescriptorSetLayout(vk::UniqueDevice &device) + { + vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(0, vk::DescriptorType::eUniformBuffer, 1, vk::ShaderStageFlagBits::eVertex); + return device->createDescriptorSetLayoutUnique(vk::DescriptorSetLayoutCreateInfo({}, 1, &descriptorSetLayoutBinding)); + } + + vk::UniqueDevice createDevice(vk::PhysicalDevice physicalDevice, uint32_t queueFamilyIndex, std::vector const& extensions) + { + std::vector enabledExtensions; + enabledExtensions.reserve(extensions.size()); + for (auto const& ext : extensions) + { + enabledExtensions.push_back(ext.data()); + } + + // create a UniqueDevice + float queuePriority = 0.0f; + vk::DeviceQueueCreateInfo deviceQueueCreateInfo(vk::DeviceQueueCreateFlags(), queueFamilyIndex, 1, &queuePriority); + vk::DeviceCreateInfo deviceCreateInfo(vk::DeviceCreateFlags(), 1, &deviceQueueCreateInfo, 0, nullptr, checked_cast(enabledExtensions.size()), enabledExtensions.data()); + return physicalDevice.createDeviceUnique(deviceCreateInfo); + } + + vk::UniqueInstance createInstance(std::string const& appName, std::string const& engineName, std::vector const& extensions) + { + std::vector enabledLayers; +#if !defined(NDEBUG) + // Enable standard validation layer to find as much errors as possible! + enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation"); +#endif + + std::vector enabledExtensions; + enabledExtensions.reserve(extensions.size()); + for (auto const& ext : extensions) + { + enabledExtensions.push_back(ext.data()); + } +#if !defined(NDEBUG) + if (std::find(extensions.begin(), extensions.end(), VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == extensions.end()) + { + enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + } +#endif + + // create a UniqueInstance + vk::ApplicationInfo applicationInfo(appName.c_str(), 1, engineName.c_str(), 1, VK_API_VERSION_1_1); + vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo({}, &applicationInfo, checked_cast(enabledLayers.size()), enabledLayers.data(), + checked_cast(enabledExtensions.size()), enabledExtensions.data())); + +#if !defined(NDEBUG) + static bool initialized = false; + if (!initialized) + { + pfnVkCreateDebugReportCallbackEXT = reinterpret_cast(instance->getProcAddr("vkCreateDebugReportCallbackEXT")); + pfnVkDestroyDebugReportCallbackEXT = reinterpret_cast(instance->getProcAddr("vkDestroyDebugReportCallbackEXT")); + assert(pfnVkCreateDebugReportCallbackEXT && pfnVkDestroyDebugReportCallbackEXT); + initialized = true; + } +#endif + + return instance; + } + + VkBool32 debugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT /*objectType*/, uint64_t /*object*/, size_t /*location*/, int32_t /*messageCode*/, const char* /*pLayerPrefix*/, const char* pMessage, void* /*pUserData*/) + { + switch (flags) + { + case VK_DEBUG_REPORT_INFORMATION_BIT_EXT: + std::cerr << "INFORMATION: "; + break; + case VK_DEBUG_REPORT_WARNING_BIT_EXT: + std::cerr << "WARNING: "; + break; + case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT: + std::cerr << "PERFORMANCE WARNING: "; + break; + case VK_DEBUG_REPORT_ERROR_BIT_EXT: + std::cerr << "ERROR: "; + break; + case VK_DEBUG_REPORT_DEBUG_BIT_EXT: + std::cerr << "DEBUG: "; + break; + default: + std::cerr << "unknown flag (" << flags << "): "; + break; + } + std::cerr << pMessage << std::endl; + return VK_TRUE; + } + + uint32_t findGraphicsQueueFamilyIndex(std::vector const& queueFamilyProperties) + { + // get the first index into queueFamiliyProperties which supports graphics + size_t graphicsQueueFamilyIndex = std::distance(queueFamilyProperties.begin(), std::find_if(queueFamilyProperties.begin(), queueFamilyProperties.end(), + [](vk::QueueFamilyProperties const& qfp) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; })); + assert(graphicsQueueFamilyIndex < queueFamilyProperties.size()); + + return checked_cast(graphicsQueueFamilyIndex); + } + + std::pair findGraphicsAndPresentQueueFamilyIndex(vk::PhysicalDevice physicalDevice, vk::UniqueSurfaceKHR & surface) + { + std::vector queueFamilyProperties = physicalDevice.getQueueFamilyProperties(); + assert(queueFamilyProperties.size() < std::numeric_limits::max()); + + uint32_t graphicsQueueFamilyIndex = findGraphicsQueueFamilyIndex(queueFamilyProperties); + if (physicalDevice.getSurfaceSupportKHR(graphicsQueueFamilyIndex, surface.get())) + { + return std::make_pair(graphicsQueueFamilyIndex, graphicsQueueFamilyIndex); // the first graphicsQueueFamilyIndex does also support presents + } + + // the graphicsQueueFamilyIndex doesn't support present -> look for an other family index that supports both graphics and present + for (size_t i = 0; i < queueFamilyProperties.size(); i++) + { + if ((queueFamilyProperties[i].queueFlags & vk::QueueFlagBits::eGraphics) && physicalDevice.getSurfaceSupportKHR(static_cast(i), surface.get())) + { + return std::make_pair(static_cast(i), static_cast(i)); + } + } + + // there's nothing like a single family index that supports both graphics and present -> look for an other family index that supports present + for (size_t i = 0; i < queueFamilyProperties.size(); i++) + { + if (physicalDevice.getSurfaceSupportKHR(static_cast(i), surface.get())) + { + return std::make_pair(graphicsQueueFamilyIndex, static_cast(i)); + } + } + + throw std::runtime_error("Could not find queues for both graphics or present -> terminating"); + } + + std::vector getDeviceExtensions() + { + return{ VK_KHR_SWAPCHAIN_EXTENSION_NAME }; + } + + std::vector getInstanceExtensions() + { + std::vector extensions; + extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_IOS_MVK) + extensions.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_MACOS_MVK) + extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_MIR_KHR) + extensions.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_VI_NN) + extensions.push_back(VK_NN_VI_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_WIN32_KHR) + extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_XCB_KHR) + extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_XLIB_KHR) + extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) + extensions.push_back(VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME); +#endif + return extensions; + } + + vk::Format pickColorFormat(std::vector const& formats) + { + assert(!formats.empty()); + return (formats[0].format == vk::Format::eUndefined) ? vk::Format::eB8G8R8A8Unorm : formats[0].format; + } + +#if defined(VK_USE_PLATFORM_WIN32_KHR) + LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch (uMsg) + { + case WM_CLOSE: + PostQuitMessage(0); + break; + default: + break; + } + return (DefWindowProc(hWnd, uMsg, wParam, lParam)); + } + + HWND initializeWindow(std::string const& className, std::string const& windowName, LONG width, LONG height) + { + WNDCLASSEX windowClass; + memset(&windowClass, 0, sizeof(WNDCLASSEX)); + + HINSTANCE instance = GetModuleHandle(nullptr); + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = WindowProc; + windowClass.hInstance = instance; + windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + windowClass.lpszClassName = className.c_str(); + windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); + + if (!RegisterClassEx(&windowClass)) + { + throw std::runtime_error("Failed to register WNDCLASSEX -> terminating"); + } + + RECT windowRect = { 0, 0, width, height }; + AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); + + HWND window = CreateWindowEx(0, className.c_str(), windowName.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU, 100, 100, windowRect.right - windowRect.left, + windowRect.bottom - windowRect.top, nullptr, nullptr, instance, nullptr); + if (!window) + { + throw std::runtime_error("Failed to create window -> terminating"); + } + + return window; + } +#else +#pragma error "unhandled platform" +#endif + } +} diff --git a/samples/utils/utils.hpp b/samples/utils/utils.hpp new file mode 100644 index 0000000..6425975 --- /dev/null +++ b/samples/utils/utils.hpp @@ -0,0 +1,59 @@ +// Copyright(c) 2019, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "vulkan/vulkan.hpp" +#include + +namespace vk +{ + namespace su + { + const uint64_t FenceTimeout = 100000000; + + template + VULKAN_HPP_INLINE TargetType checked_cast(SourceType value) + { + static_assert(sizeof(TargetType) <= sizeof(SourceType), "No need to cast from smaller to larger type!"); + static_assert(!std::numeric_limits::is_signed, "Only unsigned types supported!"); + static_assert(!std::numeric_limits::is_signed, "Only unsigned types supported!"); + assert(value <= std::numeric_limits::max()); + return static_cast(value); + } + + template + VULKAN_HPP_INLINE constexpr const T& clamp(const T& v, const T& lo, const T& hi) + { + return v < lo ? lo : hi < v ? hi : v; + } + + vk::UniqueDeviceMemory allocateMemory(vk::UniqueDevice &device, vk::PhysicalDeviceMemoryProperties const& memoryProperties, vk::MemoryRequirements const& memoryRequirements, vk::MemoryPropertyFlags memoryPropertyFlags); + vk::UniqueDebugReportCallbackEXT createDebugReportCallback(vk::UniqueInstance &instance); + vk::UniqueDescriptorSetLayout createDescriptorSetLayout(vk::UniqueDevice &device); + vk::UniqueDevice createDevice(vk::PhysicalDevice physicalDevice, uint32_t queueFamilyIndex, std::vector const& extensions = {}); + vk::UniqueInstance createInstance(std::string const& appName, std::string const& engineName, std::vector const& extensions = {}); + VkBool32 debugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData); + uint32_t findGraphicsQueueFamilyIndex(std::vector const& queueFamilyProperties); + std::pair findGraphicsAndPresentQueueFamilyIndex(vk::PhysicalDevice physicalDevice, vk::UniqueSurfaceKHR & surface); + std::vector getDeviceExtensions(); + std::vector getInstanceExtensions(); + vk::Format pickColorFormat(std::vector const& formats); + +#if defined(VK_USE_PLATFORM_WIN32_KHR) + HWND initializeWindow(std::string const& className, std::string const& windowName, LONG width, LONG height); +#else +#pragma error "unhandled platform" +#endif + } +}