| 108 | } |
| 109 | |
| 110 | int main(int argc, char* argv[]) |
| 111 | { |
| 112 | // Make sure asset folder is present from the current working directory |
| 113 | if (!std::filesystem::is_directory("assets")) { |
| 114 | std::cerr << "Could not locate assets folder from current working directory\n"; |
| 115 | exit(-1); |
| 116 | } |
| 117 | chk(SDL_Init(SDL_INIT_VIDEO)); |
| 118 | chk(SDL_Vulkan_LoadLibrary(NULL)); |
| 119 | volkInitialize(); |
| 120 | // Instance |
| 121 | VkApplicationInfo appInfo{ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pApplicationName = "How to Vulkan", .apiVersion = VK_API_VERSION_1_3 }; |
| 122 | uint32_t instanceExtensionsCount{ 0 }; |
| 123 | char const* const* instanceExtensions{ SDL_Vulkan_GetInstanceExtensions(&instanceExtensionsCount) }; |
| 124 | VkInstanceCreateInfo instanceCI{ |
| 125 | .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, |
| 126 | .pApplicationInfo = &appInfo, |
| 127 | .enabledExtensionCount = instanceExtensionsCount, |
| 128 | .ppEnabledExtensionNames = instanceExtensions, |
| 129 | }; |
| 130 | chk(vkCreateInstance(&instanceCI, nullptr, &instance)); |
| 131 | volkLoadInstance(instance); |
| 132 | // Device |
| 133 | uint32_t deviceCount{ 0 }; |
| 134 | chk(vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr)); |
| 135 | std::vector<VkPhysicalDevice> devices(deviceCount); |
| 136 | chk(vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data())); |
| 137 | uint32_t deviceIndex{ 0 }; |
| 138 | if (argc > 1) { |
| 139 | deviceIndex = std::stoi(argv[1]); |
| 140 | assert(deviceIndex < deviceCount); |
| 141 | } |
| 142 | VkPhysicalDeviceProperties2 deviceProperties{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; |
| 143 | vkGetPhysicalDeviceProperties2(devices[deviceIndex], &deviceProperties); |
| 144 | std::cout << "Selected device: " << deviceProperties.properties.deviceName << "\n"; |
| 145 | // Find a queue family for graphics |
| 146 | uint32_t queueFamilyCount{ 0 }; |
| 147 | vkGetPhysicalDeviceQueueFamilyProperties(devices[deviceIndex], &queueFamilyCount, nullptr); |
| 148 | std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount); |
| 149 | vkGetPhysicalDeviceQueueFamilyProperties(devices[deviceIndex], &queueFamilyCount, queueFamilies.data()); |
| 150 | uint32_t queueFamily{ 0 }; |
| 151 | for (size_t i = 0; i < queueFamilies.size(); i++) { |
| 152 | if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { |
| 153 | queueFamily = i; |
| 154 | break; |
| 155 | } |
| 156 | } |
| 157 | chk(SDL_Vulkan_GetPresentationSupport(instance, devices[deviceIndex], queueFamily)); |
| 158 | // Logical device |
| 159 | const float qfpriorities{ 1.0f }; |
| 160 | VkDeviceQueueCreateInfo queueCI{ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .queueFamilyIndex = queueFamily, .queueCount = 1, .pQueuePriorities = &qfpriorities }; |
| 161 | VkPhysicalDeviceVulkan12Features enabledVk12Features{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, .descriptorIndexing = true, .shaderSampledImageArrayNonUniformIndexing = true, .descriptorBindingVariableDescriptorCount = true, .runtimeDescriptorArray = true, .bufferDeviceAddress = true }; |
| 162 | VkPhysicalDeviceVulkan13Features enabledVk13Features{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, .pNext = &enabledVk12Features, .synchronization2 = true, .dynamicRendering = true }; |
| 163 | VkPhysicalDeviceFeatures enabledVk10Features{ .samplerAnisotropy = VK_TRUE }; |
| 164 | const std::vector<const char*> deviceExtensions{ VK_KHR_SWAPCHAIN_EXTENSION_NAME }; |
| 165 | VkDeviceCreateInfo deviceCI{ |
| 166 | .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, |
| 167 | .pNext = &enabledVk13Features, |
nothing calls this directly
no test coverage detected