|
@@ -199,6 +199,63 @@ static const char* getVulkanErrorString(VkResult r) {
|
|
|
} \
|
|
|
} while(false)
|
|
|
|
|
|
+static VkResult findSuitablePhysicalDevice(VkInstance instance,
|
|
|
+ VkPhysicalDevice* pd) {
|
|
|
+ u32 deviceCount = 0;
|
|
|
+ VkResult r = vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
|
|
+ if(r != VK_SUCCESS) {
|
|
|
+ return r;
|
|
|
+ } else if(deviceCount == 0) {
|
|
|
+ return VK_ERROR_INITIALIZATION_FAILED;
|
|
|
+ }
|
|
|
+ VkPhysicalDevice* devices =
|
|
|
+ cAllocate(sizeof(VkPhysicalDevice) * deviceCount);
|
|
|
+ r = vkEnumeratePhysicalDevices(instance, &deviceCount, devices);
|
|
|
+ if(r != VK_SUCCESS) {
|
|
|
+ cFree(devices);
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+ int bestPoints = 0;
|
|
|
+ LOG_INFO("Found %u devices", deviceCount);
|
|
|
+ for(u32 i = 0; i < deviceCount; i++) {
|
|
|
+ int points = 0;
|
|
|
+ VkPhysicalDeviceProperties p;
|
|
|
+ vkGetPhysicalDeviceProperties(devices[i], &p);
|
|
|
+ if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
|
|
|
+ points += 100;
|
|
|
+ } else if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
|
|
|
+ points += 50;
|
|
|
+ } else if(p.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
|
|
|
+ points += 20;
|
|
|
+ }
|
|
|
+ if(points > bestPoints) {
|
|
|
+ bestPoints = points;
|
|
|
+ *pd = devices[i];
|
|
|
+ LOG_INFO("Best Device: %s", p.deviceName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cFree(devices);
|
|
|
+ return bestPoints > 0 ? VK_SUCCESS : VK_ERROR_INITIALIZATION_FAILED;
|
|
|
+}
|
|
|
+
|
|
|
+static u32 findQueueFamilies(VkPhysicalDevice pd, VkQueueFlags flags) {
|
|
|
+ u32 count = 0;
|
|
|
+ vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, nullptr);
|
|
|
+ VkQueueFamilyProperties* properties =
|
|
|
+ cAllocate(sizeof(VkQueueFamilyProperties) * count);
|
|
|
+ vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, properties);
|
|
|
+ for(u32 i = 0; i < count; i++) {
|
|
|
+ if(properties[i].queueCount != 0 &&
|
|
|
+ (properties[i].queueFlags & flags) == flags) {
|
|
|
+ LOG_INFO("Queue family bits: %x", properties[i].queueFlags);
|
|
|
+ cFree(properties);
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cFree(properties);
|
|
|
+ return (u32)-1;
|
|
|
+}
|
|
|
+
|
|
|
bool openWindow(const WindowOptions* o) {
|
|
|
if(!glfwInit()) {
|
|
|
LOG_ERROR("could not initialize GLFW");
|
|
@@ -246,13 +303,22 @@ bool openWindow(const WindowOptions* o) {
|
|
|
VK_EXT_DEBUG_REPORT_EXTENSION_NAME}};
|
|
|
VK_ASSERT(vkCreateInstance(&instanceCreateInfo, nullptr, &instance));
|
|
|
|
|
|
- u32 graphicsFamily = 0;
|
|
|
+ VkPhysicalDevice physicalDevice = {0};
|
|
|
+ VK_ASSERT(findSuitablePhysicalDevice(instance, &physicalDevice));
|
|
|
VkPhysicalDeviceFeatures deviceFeatures = {0};
|
|
|
- VkDeviceQueueCreateInfo dqInfo = {.sType =
|
|
|
- VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
|
|
- .queueFamilyIndex = graphicsFamily,
|
|
|
- .queueCount = 1,
|
|
|
- .pQueuePriorities = (float[]){1.0f}};
|
|
|
+ vkGetPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
|
|
|
+
|
|
|
+ u32 graphicsFamily =
|
|
|
+ findQueueFamilies(physicalDevice, VK_QUEUE_GRAPHICS_BIT);
|
|
|
+ if(graphicsFamily == (u32)-1) {
|
|
|
+ LOG_ERROR("Cannot find queue family");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ VkDeviceQueueCreateInfo dqInfo = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
|
|
+ .queueFamilyIndex = graphicsFamily,
|
|
|
+ .queueCount = 1,
|
|
|
+ .pQueuePriorities = (float[]){1.0f}};
|
|
|
VkDeviceCreateInfo deviceCreateInfo = {
|
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
|
|
.queueCreateInfoCount = 1,
|
|
@@ -261,7 +327,6 @@ bool openWindow(const WindowOptions* o) {
|
|
|
.ppEnabledExtensionNames =
|
|
|
(const char*[]){VK_KHR_SWAPCHAIN_EXTENSION_NAME},
|
|
|
.pEnabledFeatures = &deviceFeatures};
|
|
|
- VkPhysicalDevice physicalDevice = {0};
|
|
|
VkDevice device = {0};
|
|
|
VK_ASSERT(
|
|
|
vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device));
|