5 #include <ThirdParty/EASTL-master/include/EASTL/map.h> 6 #include <ThirdParty/EASTL-master/include/EASTL/vector.h> 7 #include <ThirdParty/EASTL-master/include/EASTL/utility.h> 8 #include <ThirdParty/EASTL-master/include/EASTL/algorithm.h> 9 #include <ThirdParty/EASTL-master/include/EASTL/numeric_limits.h> 13 static VulkanDeviceQueueFamilies_t GetDeviceQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface) {
14 VulkanDeviceQueueFamilies_t families = {};
16 uint32_t familyCount = 0;
17 vkGetPhysicalDeviceQueueFamilyProperties(device, &familyCount,
nullptr);
18 eastl::vector<VkQueueFamilyProperties> properties(familyCount);
19 vkGetPhysicalDeviceQueueFamilyProperties(device, &familyCount, properties.data());
21 for (
int i = 0; i < static_cast<int>(properties.size()); i++) {
22 if (properties[i].queueCount > 0 && properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
23 families.graphics = i;
25 if (properties[i].queueCount > 0 && properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
28 if (properties[i].queueCount > 0 && properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT) {
29 families.transfere = i;
31 if (properties[i].queueCount > 0 && properties[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) {
32 families.sparseBinding = i;
35 VkBool32 presentSupport =
false;
37 vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
39 if (presentSupport && properties[i].queueCount > 0)
42 if (families.graphics >= 0 && families.compute >= 0 && families.transfere >= 0 && families.sparseBinding >= 0 && families.present >= 0)
50 static VulkanSwapChainSupportDetails_t GetDeviceSwapChainSupportDetails(VkPhysicalDevice device, VkSurfaceKHR surface) {
51 VulkanSwapChainSupportDetails_t details = {};
53 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
55 uint32_t formatCount = 0;
56 vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount,
nullptr);
57 if (formatCount != 0) {
58 details.formats.resize(formatCount);
59 vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
62 uint32_t presentModeCount = 0;
63 vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount,
nullptr);
64 if (presentModeCount != 0) {
65 details.presentModes.resize(presentModeCount);
66 vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
72 VulkanPhysicalDevice * VulkanPhysicalDevice::GetBestPhysicalDevice(VulkanInstance * instance, VkSurfaceKHR surface, eastl::vector<const char*> requiredExtensions, VulkanDeviceFeatures_t requiredFeatures, VulkanDeviceFeatures_t optionalFeatures, VulkanDeviceQueueRequestedFamilies_t requestedQueueFamilies,
bool GPU)
75 uint32_t deviceCount = 0;
76 vkEnumeratePhysicalDevices(instance->GetInstance(), &deviceCount,
nullptr);
79 eastl::vector<VkPhysicalDevice> devices(deviceCount);
80 vkEnumeratePhysicalDevices(instance->GetInstance(), &deviceCount, devices.data());
81 eastl::multimap<float, VkPhysicalDevice> selectedDevices;
82 for (
int i = 0; i < static_cast<int>(devices.size()); i++) {
83 VkPhysicalDeviceProperties deviceProperties;
84 VkPhysicalDeviceFeatures deviceFeatures;
85 vkGetPhysicalDeviceProperties(devices[i], &deviceProperties);
86 vkGetPhysicalDeviceFeatures(devices[i], &deviceFeatures);
89 if (GPU && !(deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU || deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)) {
93 uint32_t extensionCount = 0;
94 vkEnumerateDeviceExtensionProperties(devices[i], NULL, &extensionCount,
nullptr);
95 eastl::vector<VkExtensionProperties> extensions(extensionCount);
96 vkEnumerateDeviceExtensionProperties(devices[i], NULL, &extensionCount, extensions.data());
98 bool extensionNotFound =
false;
99 for (
int i = 0; i < static_cast<int>(requiredExtensions.size()); i++) {
100 bool extensionFound =
false;
101 for (
int j = 0; j < static_cast<int>(extensions.size()); j++) {
102 if (strcmp(extensions[j].extensionName, requiredExtensions[i]) == 0) {
103 extensionFound =
true;
107 if (extensionFound ==
false) {
108 extensionNotFound =
true;
113 if (extensionNotFound)
116 VulkanDeviceQueueFamilies_t families = GetDeviceQueueFamilies(devices[i], surface);
118 if (requestedQueueFamilies.graphics ==
true && families.graphics < 0)
120 if (requestedQueueFamilies.compute ==
true && families.compute < 0)
122 if (requestedQueueFamilies.transfere ==
true && families.transfere < 0)
124 if (requestedQueueFamilies.sparseBinding ==
true && families.sparseBinding < 0)
126 if (requestedQueueFamilies.present ==
true && families.present < 0)
129 VulkanSwapChainSupportDetails_t details = GetDeviceSwapChainSupportDetails(devices[i], surface);
131 if (details.formats.size() == 0 || details.presentModes.size() == 0)
134 float* requiredFeaturesValues = (
float*)&requiredFeatures;
135 VkBool32* requiredFeaturesFoundValues = (VkBool32*)&deviceFeatures;
137 for (
int j = 0; j <
sizeof(VulkanDeviceFeatures_t) /
sizeof(
float); j++) {
138 if (requiredFeaturesValues[j] > 0.f&&requiredFeaturesFoundValues[j] != VK_TRUE) {
142 if (requiredFeaturesValues[j] < 0.f&&requiredFeaturesFoundValues[j] == VK_TRUE) {
148 float* optionalFeaturesValues = (
float*)&optionalFeatures;
150 for (
int j = 0; j <
sizeof(VulkanDeviceFeatures_t) /
sizeof(
float); j++) {
151 if (optionalFeaturesValues[j] != 0.f) {
152 if (optionalFeaturesValues[j] > 0.f&&requiredFeaturesFoundValues[j] == VK_TRUE)
153 score += optionalFeaturesValues[j];
154 if (optionalFeaturesValues[j] < 0.f&&requiredFeaturesFoundValues[j] != VK_TRUE)
155 score += -1.f*optionalFeaturesValues[j];
158 selectedDevices.insert(eastl::make_pair(score, devices[i]));
161 if (selectedDevices.rbegin()->first > 0.f) {
162 return new VulkanPhysicalDevice(selectedDevices.rbegin()->second, surface);
166 eastl::vector<VulkanPhysicalDevice*> VulkanPhysicalDevice::GetAllPhysicalDevices(VulkanInstance* instance, VkSurfaceKHR surface)
168 uint32_t deviceCount = 0;
169 vkEnumeratePhysicalDevices(instance->GetInstance(), &deviceCount,
nullptr);
170 eastl::vector<VulkanPhysicalDevice*> Vulkandevices(deviceCount);
171 eastl::vector<VkPhysicalDevice> devices(deviceCount);
172 vkEnumeratePhysicalDevices(instance->GetInstance(), &deviceCount, devices.data());
173 for (
int i = 0; i < static_cast<int>(devices.size()); i++) {
174 Vulkandevices[i] =
new VulkanPhysicalDevice(devices[i], surface);
176 return Vulkandevices;
179 VulkanDeviceQueueFamilies_t VulkanPhysicalDevice::GetQueueFamilies()
182 QueueFamilies = GetDeviceQueueFamilies(device, surface);
183 queueFamiliesFound =
true;
185 return QueueFamilies;
188 VulkanSwapChainSupportDetails_t VulkanPhysicalDevice::GetSwapChainSupportDetails()
190 if (!swapChainDetailsFound) {
191 details = GetDeviceSwapChainSupportDetails(device, surface);
192 swapChainDetailsFound =
true;
196 VulkanSwapChainSupportDetails_t VulkanPhysicalDevice::ReloadSwapChainSupportDetails()
198 details = GetDeviceSwapChainSupportDetails(device, surface);
202 VkSurfaceFormatKHR VulkanPhysicalDevice::ChooseSwapSurfaceFormat(
const eastl::vector<VkSurfaceFormatKHR>& availableFormats)
205 if (availableFormats.size() == 1 && availableFormats[0].format == VK_FORMAT_UNDEFINED) {
206 return { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
209 for (
const auto& availableFormat : availableFormats) {
210 if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
211 return availableFormat;
215 return availableFormats[0];
219 VkPresentModeKHR VulkanPhysicalDevice::ChooseSwapPresentMode(
const eastl::vector<VkPresentModeKHR> availablePresentModes)
221 VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
223 for (
const auto& availablePresentMode : availablePresentModes) {
224 if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
225 return availablePresentMode;
227 else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
236 VkExtent2D VulkanPhysicalDevice::ChooseSwapExtent(
const VkSurfaceCapabilitiesKHR & capabilities,
int width,
int height)
238 if (capabilities.currentExtent.width != eastl::numeric_limits<uint32_t>::max()) {
239 return capabilities.currentExtent;
242 VkExtent2D actualExtend = {
static_cast<uint32_t
>(width), static_cast<uint32_t>(height) };
244 uint32_t minWidth = actualExtend.width < capabilities.maxImageExtent.width ? actualExtend.width : capabilities.maxImageExtent.width;
245 actualExtend.width = capabilities.minImageExtent.width < minWidth ? minWidth : capabilities.minImageExtent.width;
247 uint32_t minHeight = actualExtend.height < capabilities.maxImageExtent.height ? actualExtend.height : capabilities.maxImageExtent.height;
248 actualExtend.height = capabilities.minImageExtent.height < minHeight ? minHeight : capabilities.minImageExtent.height;
254 VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice device, VkSurfaceKHR surface): queueFamiliesFound(false),
255 swapChainDetailsFound(false)
257 this->device = device;
258 this->surface = surface;
262 VulkanPhysicalDevice::~VulkanPhysicalDevice()
267 #endif // USING_VULKAN