summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-07-10 15:43:42 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-07-10 15:43:42 -0400
commit54a34a2d55f691a55abdcc4e147148d62bdd53b0 (patch)
treec81835a5299207f4bca12400b1a135032420c15c /src
parent32f251204754fd51f04d11e29d17b62f9d1d7058 (diff)
create surface and pick physical device
Diffstat (limited to 'src')
-rw-r--r--src/window.cpp97
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) {