Added physical device picker
This commit is contained in:
parent
6ee062cca6
commit
e5f420a238
2 changed files with 89 additions and 1 deletions
|
|
@ -1,9 +1,13 @@
|
|||
#include "yave_vulkan_instance.hpp"
|
||||
#include <cstdint>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace yave {
|
||||
|
||||
YaveVulkanInstance::YaveVulkanInstance() { createInstance(); }
|
||||
YaveVulkanInstance::YaveVulkanInstance() {
|
||||
createInstance();
|
||||
pickPhysicalDevice();
|
||||
}
|
||||
YaveVulkanInstance::~YaveVulkanInstance() { destroyInstance(); }
|
||||
|
||||
void YaveVulkanInstance::createInstance() {
|
||||
|
|
@ -76,4 +80,71 @@ bool YaveVulkanInstance::checkLayersValidSuppport(
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO: Create way to pick the most powerful and feature rich device
|
||||
//(maybe use a suitability score rather than bool)
|
||||
// Right now we're settling for the first device with queue family support
|
||||
bool YaveVulkanInstance::isDeviceSuitable(VkPhysicalDevice device) {
|
||||
QueueFamilyIndices indices = findQueueFamilies(device);
|
||||
|
||||
return indices.isComplete();
|
||||
}
|
||||
|
||||
void YaveVulkanInstance::pickPhysicalDevice() {
|
||||
physicalDevice = VK_NULL_HANDLE;
|
||||
|
||||
// Get number of vulken enabled devices on system
|
||||
uint32_t deviceCount = 0;
|
||||
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
||||
|
||||
// No point in running vulkan if it's not supported on any devices
|
||||
if (deviceCount == 0) {
|
||||
throw std::runtime_error("failed to find GPUs with Vulkan support!");
|
||||
}
|
||||
|
||||
// Now we have the number of devices we can create a vector to store them for
|
||||
// evaluation
|
||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
||||
|
||||
// Use our suitability function to see if a device is suitable
|
||||
for (const auto &device : devices) {
|
||||
if (isDeviceSuitable(device)) {
|
||||
physicalDevice = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we couldn't select a device throw an error
|
||||
if (physicalDevice == VK_NULL_HANDLE) {
|
||||
throw std::runtime_error("failed to find a suitable GPU!");
|
||||
}
|
||||
}
|
||||
|
||||
QueueFamilyIndices
|
||||
YaveVulkanInstance::findQueueFamilies(VkPhysicalDevice device) {
|
||||
// Get number of queues
|
||||
QueueFamilyIndices indices;
|
||||
uint32_t queueFamilyCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
|
||||
|
||||
// Put queues into vector
|
||||
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount,
|
||||
queueFamilies.data());
|
||||
|
||||
// iterate over the devices ques and see if it has a graphics bit
|
||||
int i = 0;
|
||||
for (const auto &queueFamily : queueFamilies) {
|
||||
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
indices.graphicsFamily = i;
|
||||
}
|
||||
// If we know we have support we don't need to look for anything more
|
||||
if(indices.isComplete()){
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
} // namespace yave
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
|
@ -9,13 +10,29 @@
|
|||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace yave {
|
||||
|
||||
struct QueueFamilyIndices {
|
||||
std::optional<uint32_t> graphicsFamily;
|
||||
|
||||
bool isComplete() { return graphicsFamily.has_value(); }
|
||||
};
|
||||
|
||||
class YaveVulkanInstance {
|
||||
|
||||
private:
|
||||
VkInstance instance;
|
||||
VkPhysicalDevice physicalDevice;
|
||||
|
||||
// Vulkan instance
|
||||
void createInstance();
|
||||
void destroyInstance();
|
||||
|
||||
// TODO: Move Physical device code to it's own class
|
||||
// Physical device
|
||||
void pickPhysicalDevice();
|
||||
bool isDeviceSuitable(VkPhysicalDevice device);
|
||||
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
||||
|
||||
// Validation support
|
||||
bool checkLayersValidSuppport(VkInstanceCreateInfo &createInfo);
|
||||
const std::vector<const char *> validationLayers = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue