diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-07-10 15:43:42 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-07-10 15:43:42 -0400 |
| commit | 54a34a2d55f691a55abdcc4e147148d62bdd53b0 (patch) | |
| tree | c81835a5299207f4bca12400b1a135032420c15c /src/window.cpp | |
| parent | 32f251204754fd51f04d11e29d17b62f9d1d7058 (diff) | |
create surface and pick physical device
Diffstat (limited to 'src/window.cpp')
| -rw-r--r-- | src/window.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/window.cpp b/src/window.cpp index d79b61d..0f63349 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,4 +1,7 @@ +#define GLFW_INCLUDE_NONE +#define GLFW_INCLUDE_VULKAN +#include <cstring> #include <cstdio> #include <vector> #include <cassert> @@ -16,6 +19,10 @@ VkDebugReportCallbackEXT vkDebugReport = nullptr; const bool ENABLE_VALIDATION_LAYERS = true; const bool VULKAN_DEBUG_REPORT = true; +const std::vector<const char *> REQUIRED_EXTENSIONS = std::vector<const char *> { + VK_KHR_SWAPCHAIN_EXTENSION_NAME +}; + VkBool32 UserDebugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, @@ -35,6 +42,37 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DebugReport(VkDebugReportFlagsEXT flags, V return VK_FALSE; } +unsigned int FindQueueFamilyIndex(VkPhysicalDevice device, short hasPresentSupport = -1, VkQueueFlagBits includeBits = (VkQueueFlagBits)0U, VkQueueFlagBits excludeBits = (VkQueueFlagBits)0U) { + + if (hasPresentSupport == -1 && includeBits == 0 && excludeBits == 0) { + return 0U; + } + + unsigned int queueFamilyPropertyCount = 0U; + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyPropertyCount, nullptr); + std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyPropertyCount); + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyPropertyCount, queueFamilyProperties.data()); + + for (unsigned int i = 0; i < queueFamilyProperties.size(); i++) { + if (includeBits != 0 && (queueFamilyProperties[i].queueFlags & includeBits) == 0) { + continue; + } + if (excludeBits != 0 && (queueFamilyProperties[i].queueFlags & excludeBits) != 0) { + continue; + } + if (hasPresentSupport != -1) { + VkBool32 presentSupport; + vkGetPhysicalDeviceSurfaceSupportKHR(device, i, vkSurfaceKHR, &presentSupport); + if (presentSupport != hasPresentSupport) { + continue; + } + } + return i; + } + + return 0xFFFFFFFF; +} + void InitVulkan() { if (ENABLE_VALIDATION_LAYERS) { @@ -143,6 +181,65 @@ void InitVulkan() { } } + // create surface + if (glfwCreateWindowSurface(vkInstance, window, nullptr, &vkSurfaceKHR) != VK_SUCCESS) { + throw "Failed to create window surface"; + } + + // pick physical device + unsigned int physicalDeviceCount = 0; + vkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, nullptr); + assert(physicalDeviceCount > 0); + std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount); + vkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, physicalDevices.data()); + for (const auto &device : physicalDevices) + { + // check queue families + auto graphicsFamilyIndex = FindQueueFamilyIndex(device, -1, VK_QUEUE_GRAPHICS_BIT); + auto presentFamilyIndex = FindQueueFamilyIndex(device, 1); + if (graphicsFamilyIndex == 0xFFFFFFFF || presentFamilyIndex == 0xFFFFFFFF) { + continue; + } + + // check device extension support + std::vector<const char *> requiredExtensions(REQUIRED_EXTENSIONS.begin(), REQUIRED_EXTENSIONS.end()); + unsigned int extensionCount = 0; + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); + std::vector<VkExtensionProperties> extensionProperties(extensionCount); + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, extensionProperties.data()); + for (const auto &property : extensionProperties) { + auto it = requiredExtensions.begin(); + while (it != requiredExtensions.end()) { + if (strcmp(*it.base(), property.extensionName)) { + requiredExtensions.erase(it); + } else { + it++; + } + } + } + if (requiredExtensions.empty() == false) { + continue; + } + + // surface formats + unsigned int surfaceCount = 0; + vkGetPhysicalDeviceSurfaceFormatsKHR(device, vkSurfaceKHR, &surfaceCount, nullptr); + if (surfaceCount == 0) { + continue; + } + + // check present modes + unsigned int presentModeCount = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR(device, vkSurfaceKHR, &presentModeCount, nullptr); + if (presentModeCount == 0) { + continue; + } + + vkPhysicalDevice = device; + break; + } + assert(vkPhysicalDevice != nullptr && "Failed to find suitable physical device"); + } void CreateWindow(PKEWindowProperties *wp) { |
