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 "yave_vulkan_instance.hpp"
|
||||||
|
#include <cstdint>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace yave {
|
namespace yave {
|
||||||
|
|
||||||
YaveVulkanInstance::YaveVulkanInstance() { createInstance(); }
|
YaveVulkanInstance::YaveVulkanInstance() {
|
||||||
|
createInstance();
|
||||||
|
pickPhysicalDevice();
|
||||||
|
}
|
||||||
YaveVulkanInstance::~YaveVulkanInstance() { destroyInstance(); }
|
YaveVulkanInstance::~YaveVulkanInstance() { destroyInstance(); }
|
||||||
|
|
||||||
void YaveVulkanInstance::createInstance() {
|
void YaveVulkanInstance::createInstance() {
|
||||||
|
|
@ -76,4 +80,71 @@ bool YaveVulkanInstance::checkLayersValidSuppport(
|
||||||
return true;
|
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
|
} // namespace yave
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
@ -9,13 +10,29 @@
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
namespace yave {
|
namespace yave {
|
||||||
|
|
||||||
|
struct QueueFamilyIndices {
|
||||||
|
std::optional<uint32_t> graphicsFamily;
|
||||||
|
|
||||||
|
bool isComplete() { return graphicsFamily.has_value(); }
|
||||||
|
};
|
||||||
|
|
||||||
class YaveVulkanInstance {
|
class YaveVulkanInstance {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
|
VkPhysicalDevice physicalDevice;
|
||||||
|
|
||||||
|
// Vulkan instance
|
||||||
void createInstance();
|
void createInstance();
|
||||||
void destroyInstance();
|
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
|
// Validation support
|
||||||
bool checkLayersValidSuppport(VkInstanceCreateInfo &createInfo);
|
bool checkLayersValidSuppport(VkInstanceCreateInfo &createInfo);
|
||||||
const std::vector<const char *> validationLayers = {
|
const std::vector<const char *> validationLayers = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue