25 bool QueueFamilyIndices::isValid() {
26 return graphics >= 0 && presentation >= 0;
29 std::vector<PhysicalDevice*> PhysicalDevice::getAvailablePhysicalDevices(
Surface* surface) {
30 Instance* instance = VulkanContext::getCurrent()->getInstance();
34 vector<PhysicalDevice*> physicalDevices(devices.size());
35 for (uint32_t i = 0; i < devices.size(); i++) {
39 return physicalDevices;
42 PhysicalDevice* PhysicalDevice::getSuitablePhysicalDevice(std::vector<PhysicalDevice*> physicalDevices) {
45 for (uint32_t i = 0; i < physicalDevices.size(); i++) {
47 VkPhysicalDeviceProperties currentProperties = suitablePhysicalDevice->
getProperties();
48 VkPhysicalDeviceProperties candidateProperties = physicalDevices[i]->getProperties();
51 if (candidateProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
52 currentProperties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
53 if (suitablePhysicalDevice->queueFamilyIndices.
isValid()) {
54 suitablePhysicalDevice = physicalDevices[i];
61 suitablePhysicalDevice->validate();
63 return suitablePhysicalDevice;
66 PhysicalDevice::PhysicalDevice(VkPhysicalDevice handle,
Surface* surface) {
67 this->handle = handle;
68 queueFamilyIndices.graphics = -1;
69 queueFamilyIndices.presentation = -1;
72 vector<VkQueueFamilyProperties> queueFamilyProperties = getQueueFamilyProperties();
73 for (uint32_t i = 0; i < queueFamilyProperties.size(); i++) {
75 bool graphicsSupport = queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT;
76 if (queueFamilyProperties[i].queueCount > 0 && graphicsSupport) {
77 queueFamilyIndices.graphics = i;
81 VkBool32 presentationSupport = VK_FALSE;
82 vkGetPhysicalDeviceSurfaceSupportKHR(handle, i, surface->
getHandle(), &presentationSupport);
83 if (queueFamilyProperties[i].queueCount > 0 && presentationSupport) {
84 queueFamilyIndices.presentation = i;
88 if (queueFamilyIndices.isValid()) {
94 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(handle, surface->
getHandle(), &swapchainSupportDetails.surfaceCapabilities);
97 uint32_t surfaceFormatCount = 0;
98 vkGetPhysicalDeviceSurfaceFormatsKHR(handle, surface->
getHandle(), &surfaceFormatCount,
nullptr);
101 if (surfaceFormatCount > 0) {
102 swapchainSupportDetails.surfaceFormats.resize(surfaceFormatCount);
103 vkGetPhysicalDeviceSurfaceFormatsKHR(handle, surface->
getHandle(), &surfaceFormatCount, swapchainSupportDetails.surfaceFormats.data());
107 uint32_t presentModeCount = 0;
108 vkGetPhysicalDeviceSurfacePresentModesKHR(handle, surface->
getHandle(), &presentModeCount,
nullptr);
111 if (presentModeCount > 0) {
112 swapchainSupportDetails.presentModes.resize(presentModeCount);
113 vkGetPhysicalDeviceSurfacePresentModesKHR(handle, surface->
getHandle(), &presentModeCount, swapchainSupportDetails.presentModes.data());
117 PhysicalDevice::~PhysicalDevice(
void) {
121 VkPhysicalDevice PhysicalDevice::getHandle() {
126 return queueFamilyIndices;
130 return swapchainSupportDetails;
133 VkPhysicalDeviceProperties PhysicalDevice::getProperties() {
134 VkPhysicalDeviceProperties properties;
135 vkGetPhysicalDeviceProperties(handle, &properties);
140 VkPhysicalDeviceFeatures PhysicalDevice::getFeatures() {
141 VkPhysicalDeviceFeatures features;
142 vkGetPhysicalDeviceFeatures(handle, &features);
147 std::vector<VkQueueFamilyProperties> PhysicalDevice::getQueueFamilyProperties() {
149 uint32_t queueFamilyCount = 0;
150 vkGetPhysicalDeviceQueueFamilyProperties(handle, &queueFamilyCount,
nullptr);
153 vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);
154 vkGetPhysicalDeviceQueueFamilyProperties(handle, &queueFamilyCount, queueFamilyProperties.data());
156 return queueFamilyProperties;
159 void PhysicalDevice::validate() {
161 if (queueFamilyIndices.graphics < 0) {
162 throw runtime_error(
"Could not find a queue family that supports graphics!");
163 }
else if (queueFamilyIndices.presentation < 0) {
164 throw runtime_error(
"Could not find a queue family that supports presentation!");
168 uint32_t availableExtensionCount = 0;
169 vkEnumerateDeviceExtensionProperties(handle,
nullptr, &availableExtensionCount,
nullptr);
172 vector<VkExtensionProperties> availableExtensions(availableExtensionCount);
173 vkEnumerateDeviceExtensionProperties(handle,
nullptr, &availableExtensionCount, availableExtensions.data());
176 vector<const char*> requiredExtensions;
177 requiredExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
180 for (uint32_t i = 0; i < requiredExtensions.size(); i++) {
182 for (uint32_t j = 0; j < availableExtensions.size(); j++) {
183 if (strcmp(requiredExtensions[i], availableExtensions[j].extensionName)) {
189 Logger::logInfo(
string(requiredExtensions[i]) +
" is supported!");
191 Logger::logError(
string(requiredExtensions[i]) +
" is not supported.");
197 if (swapchainSupportDetails.surfaceFormats.empty()) {
198 throw runtime_error(
"Could not find a supported surface format!");
199 }
else if (swapchainSupportDetails.presentModes.empty()) {
200 throw runtime_error(
"Could not find a supported present mode!");
This class wraps a Vulkan instance.
This class wraps a Vulkan physical device and represents a graphics card.
This struct stores relevant queue family indices.
This struct stores necessary data for swapchain support.
Generic namespace for the SimpleGL framework.
VkSurfaceKHR getHandle()
Returns the hande of the surface.
std::vector< VkPhysicalDevice > enumeratePhysicalDevices()
Enumerates the physical devices accessible to this instance.
bool isValid()
Checks if the queue family indices are valid.
This class wraps a Vulkan surface.
VkPhysicalDeviceProperties getProperties()
Returns the properties of this physical device.