Created
March 29, 2018 22:21
-
-
Save thennequin/6005f51023a088a52adeecb83353d60d to your computer and use it in GitHub Desktop.
vulkan_util.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Need implementation, use: | |
#define VULKAN_UTILS_IMPLEMENT | |
*/ | |
#include <vulkan/vulkan.h> | |
VkResult vkFindBestPhysicalDevice(VkInstance vkInstance, VkSurfaceKHR vkSurface, VkPhysicalDevice* pOutVkPhysicalDevice, int* pOutVkPhysicalDeviceScore); | |
////////////////////////////////// | |
//IMPLEMENTATION | |
////////////////////////////////// | |
#if defined(VULKAN_UTILS_IMPLEMENT) | |
VkResult vkFindBestPhysicalDevice(VkInstance vkInstance, VkSurfaceKHR vkSurface, VkPhysicalDevice* pOutVkPhysicalDevice, int* pOutVkPhysicalDeviceScore) | |
{ | |
if (pOutVkPhysicalDevice == 0) | |
return VK_INCOMPLETE; | |
uint32_t iPhysicalDeviceCount = 0; | |
VkResult iResult = vkEnumeratePhysicalDevices(vkInstance, &iPhysicalDeviceCount, 0); | |
if (iResult != VK_SUCCESS) | |
return iResult; | |
if (iPhysicalDeviceCount == 0) | |
return VK_NOT_READY; | |
VkPhysicalDevice oPhysicalDevices[64]; | |
iResult = vkEnumeratePhysicalDevices(vkInstance, &iPhysicalDeviceCount, &oPhysicalDevices[0]); | |
if (iResult != VK_SUCCESS) | |
return VK_NOT_READY; | |
int iBestIndex = -1; | |
int iBestScore; | |
VkPhysicalDeviceProperties oDeviceProperties; | |
for (uint32_t iPhysicalDeviceIndex = 0; iPhysicalDeviceIndex < iPhysicalDeviceCount; iPhysicalDeviceIndex++) | |
{ | |
int iPhysicalDeviceScore = 0; | |
VkPhysicalDevice vkPhysicalDevice = oPhysicalDevices[iPhysicalDeviceIndex]; | |
memset(&oDeviceProperties, 0, sizeof oDeviceProperties); | |
vkGetPhysicalDeviceProperties(vkPhysicalDevice, &oDeviceProperties); | |
switch (oDeviceProperties.deviceType) | |
{ | |
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: | |
iPhysicalDeviceScore += 500; | |
break; | |
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: | |
iPhysicalDeviceScore += 250; | |
break; | |
case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: | |
iPhysicalDeviceScore += 100; | |
break; | |
case VK_PHYSICAL_DEVICE_TYPE_CPU: | |
iPhysicalDeviceScore += 50; | |
break; | |
default: | |
// Null score for others | |
break; | |
} | |
uint32_t iQueueFamilyCount = 0; | |
vkGetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice, &iQueueFamilyCount, 0); | |
VkQueueFamilyProperties oFamilyProperties[128]; | |
vkGetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice, &iQueueFamilyCount, &oFamilyProperties[0]); | |
int iGraphicsQueueFamily = -1; | |
int iPresentQueueFamily = -1; | |
int iComputeQueueFamily = -1; | |
int iTransfertQueueFamily = -1; | |
for (int32_t iQueueFamilyIndex = 0; iQueueFamilyIndex < (int32_t)iQueueFamilyCount; ++iQueueFamilyIndex) | |
{ | |
VkBool32 bSurfaceSupport = false; | |
vkGetPhysicalDeviceSurfaceSupportKHR(oPhysicalDevices[iPhysicalDeviceIndex], iQueueFamilyIndex, vkSurface, &bSurfaceSupport); | |
VkQueueFlags eQueueFlags = oFamilyProperties[iQueueFamilyIndex].queueFlags; | |
if (eQueueFlags & VK_QUEUE_GRAPHICS_BIT && iGraphicsQueueFamily == -1) | |
iGraphicsQueueFamily = iQueueFamilyIndex; | |
if (iGraphicsQueueFamily == iQueueFamilyIndex && bSurfaceSupport && iPresentQueueFamily == -1) | |
iPresentQueueFamily = iQueueFamilyIndex; | |
if (eQueueFlags & VK_QUEUE_COMPUTE_BIT && iComputeQueueFamily == -1) | |
iComputeQueueFamily = iQueueFamilyIndex; | |
if (eQueueFlags & VK_QUEUE_TRANSFER_BIT && iTransfertQueueFamily == -1) | |
iTransfertQueueFamily = iQueueFamilyIndex; | |
iPhysicalDeviceScore += oFamilyProperties[iQueueFamilyIndex].queueCount; | |
} | |
if (iGraphicsQueueFamily == -1 || iPresentQueueFamily == -1 || iComputeQueueFamily == -1 || iTransfertQueueFamily == -1) | |
iPhysicalDeviceScore -= 1000; | |
VkSurfaceCapabilitiesKHR vkSurfaceCapabilitiesKHR; | |
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vkPhysicalDevice, vkSurface, &vkSurfaceCapabilitiesKHR); | |
uint32_t iFormatCount; | |
vkGetPhysicalDeviceSurfaceFormatsKHR(vkPhysicalDevice, vkSurface, &iFormatCount, 0); | |
if (iFormatCount == 0) | |
iPhysicalDeviceScore -= 1000; | |
uint32_t iPresentModeCount; | |
vkGetPhysicalDeviceSurfacePresentModesKHR(vkPhysicalDevice, vkSurface, &iPresentModeCount, 0); | |
if (iPresentModeCount == 0) | |
iPhysicalDeviceScore -= 1000; | |
VkPhysicalDeviceMemoryProperties vkPhysicalDeviceMemoryProperties; | |
vkGetPhysicalDeviceMemoryProperties(vkPhysicalDevice, &vkPhysicalDeviceMemoryProperties); | |
uint64_t iMemoryHeapSize = 0; | |
for (uint32_t iMemoryHeapIndex = 0; iMemoryHeapIndex < vkPhysicalDeviceMemoryProperties.memoryHeapCount; ++iMemoryHeapIndex) | |
{ | |
if (vkPhysicalDeviceMemoryProperties.memoryHeaps[iMemoryHeapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) | |
iMemoryHeapSize += vkPhysicalDeviceMemoryProperties.memoryHeaps[iMemoryHeapIndex].size; | |
} | |
iPhysicalDeviceScore += (uint32_t)(iMemoryHeapSize / (1024 * 1024 * 1024)) * 25; | |
if (iBestIndex == -1 || iPhysicalDeviceScore > iBestScore) | |
{ | |
iBestIndex = iPhysicalDeviceIndex; | |
iBestScore = iPhysicalDeviceScore; | |
} | |
} | |
if (iBestIndex == -1) | |
{ | |
return VK_NOT_READY; | |
} | |
*pOutVkPhysicalDevice = oPhysicalDevices[iBestIndex]; | |
if (pOutVkPhysicalDeviceScore != 0) | |
*pOutVkPhysicalDeviceScore = iBestScore; | |
return VK_SUCCESS; | |
} | |
#endif //VULKAN_UTILS_IMPLEMENT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment