Skip to content

Instantly share code, notes, and snippets.

@thennequin
Created March 29, 2018 22:21
Show Gist options
  • Save thennequin/6005f51023a088a52adeecb83353d60d to your computer and use it in GitHub Desktop.
Save thennequin/6005f51023a088a52adeecb83353d60d to your computer and use it in GitHub Desktop.
vulkan_util.h
/*
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