Choose Vulkan physical device
This commit is contained in:
parent
d53fb94e4c
commit
89cdf712b8
@ -10,13 +10,17 @@ namespace nf::cli::render {
|
|||||||
, m_display(display)
|
, m_display(display)
|
||||||
, m_instance()
|
, m_instance()
|
||||||
, m_surface()
|
, m_surface()
|
||||||
|
, m_physicalDevice()
|
||||||
|
, m_queueFIGraphics()
|
||||||
|
, m_queueFIPresent()
|
||||||
{
|
{
|
||||||
NFLog("Initializing render engine");
|
NFLog("Initializing render engine");
|
||||||
createInstance();
|
|
||||||
createSurface(m_window->getHandle());
|
|
||||||
|
|
||||||
m_window->setDisplay(m_display);
|
m_window->setDisplay(m_display);
|
||||||
m_window->show();
|
m_window->show();
|
||||||
|
|
||||||
|
createInstance();
|
||||||
|
createSurface(m_window->getHandle());
|
||||||
|
pickPhysicalDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEngine::createInstance() {
|
void RenderEngine::createInstance() {
|
||||||
@ -44,6 +48,83 @@ namespace nf::cli::render {
|
|||||||
NFError("Could not create Vulkan surface");
|
NFError("Could not create Vulkan surface");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderEngine::pickPhysicalDevice() {
|
||||||
|
// TODO: Save GPU choice in DisplayConfig
|
||||||
|
// First, get list of all GPUs
|
||||||
|
uint32_t numPhysicalDevices = 0;
|
||||||
|
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, nullptr);
|
||||||
|
if (numPhysicalDevices == 0)
|
||||||
|
NFError("No Vulkan GPUs found");
|
||||||
|
|
||||||
|
std::vector<VkPhysicalDevice> physicalDevices(numPhysicalDevices);
|
||||||
|
vkEnumeratePhysicalDevices(m_instance, &numPhysicalDevices, physicalDevices.data());
|
||||||
|
|
||||||
|
// Then gather information on them and save first dedicated
|
||||||
|
std::optional<int> firstDedicatedPhysicalDeviceIndex;
|
||||||
|
std::vector<VkPhysicalDeviceProperties> physicalDeviceProperties;
|
||||||
|
for (int i = 0; i < numPhysicalDevices; i++) {
|
||||||
|
VkPhysicalDeviceProperties currentPhysicalDeviceProperties = {};
|
||||||
|
vkGetPhysicalDeviceProperties(physicalDevices[i], ¤tPhysicalDeviceProperties);
|
||||||
|
if (currentPhysicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && !firstDedicatedPhysicalDeviceIndex.has_value())
|
||||||
|
firstDedicatedPhysicalDeviceIndex = i;
|
||||||
|
|
||||||
|
physicalDeviceProperties.push_back(currentPhysicalDeviceProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try dedicated first, then try every GPU in order
|
||||||
|
if (firstDedicatedPhysicalDeviceIndex.has_value()) {
|
||||||
|
int dedicatedIndex = firstDedicatedPhysicalDeviceIndex.value();
|
||||||
|
physicalDevices.insert(physicalDevices.begin(), physicalDevices[dedicatedIndex]);
|
||||||
|
physicalDevices.erase(physicalDevices.begin() + dedicatedIndex + 1);
|
||||||
|
physicalDeviceProperties.insert(physicalDeviceProperties.begin(), physicalDeviceProperties[dedicatedIndex]);
|
||||||
|
physicalDeviceProperties.erase(physicalDeviceProperties.begin() + dedicatedIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PhysicalDeviceQueueFamilyIndices {
|
||||||
|
uint32_t graphics, present;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getQueueFamilyIndices = [&](int currentPhysicalDeviceIndex) -> std::optional<PhysicalDeviceQueueFamilyIndices> {
|
||||||
|
uint32_t numQueueFamilies = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevices[currentPhysicalDeviceIndex], &numQueueFamilies, nullptr);
|
||||||
|
std::vector<VkQueueFamilyProperties> queueFamilyProperties(numQueueFamilies);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevices[currentPhysicalDeviceIndex], &numQueueFamilies, queueFamilyProperties.data());
|
||||||
|
std::optional<uint32_t> graphicsIndex, presentIndex;
|
||||||
|
|
||||||
|
for (int i = 0; i < numQueueFamilies; i++) {
|
||||||
|
if (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT && !graphicsIndex.has_value())
|
||||||
|
graphicsIndex = i;
|
||||||
|
|
||||||
|
VkBool32 hasPresentSupport = VK_FALSE;
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevices[currentPhysicalDeviceIndex], i, m_surface, &hasPresentSupport);
|
||||||
|
if (hasPresentSupport && !presentIndex.has_value())
|
||||||
|
presentIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (graphicsIndex.has_value() && presentIndex.has_value())
|
||||||
|
return PhysicalDeviceQueueFamilyIndices{ graphicsIndex.value(), presentIndex.value() };
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<PhysicalDeviceQueueFamilyIndices> chosenPhysicalDeviceIndices;
|
||||||
|
for (int i = 0; i < numPhysicalDevices; i++) {
|
||||||
|
chosenPhysicalDeviceIndices = getQueueFamilyIndices(i);
|
||||||
|
if (chosenPhysicalDeviceIndices.has_value()) {
|
||||||
|
// GPU found!
|
||||||
|
m_physicalDevice = physicalDevices[i];
|
||||||
|
m_queueFIGraphics = chosenPhysicalDeviceIndices->graphics;
|
||||||
|
m_queueFIPresent = chosenPhysicalDeviceIndices->present;
|
||||||
|
|
||||||
|
NFLog(std::format("GPU - {}", physicalDeviceProperties[i].deviceName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_physicalDevice == nullptr)
|
||||||
|
NFError("No Vulkan GPUs were found to be compatible");
|
||||||
|
}
|
||||||
|
|
||||||
RenderEngine::~RenderEngine() {
|
RenderEngine::~RenderEngine() {
|
||||||
vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
|
vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
|
||||||
vkDestroyInstance(m_instance, nullptr);
|
vkDestroyInstance(m_instance, nullptr);
|
||||||
|
@ -13,11 +13,14 @@ namespace nf::cli::render {
|
|||||||
private:
|
private:
|
||||||
void createInstance();
|
void createInstance();
|
||||||
void createSurface(HWND window);
|
void createSurface(HWND window);
|
||||||
|
void pickPhysicalDevice();
|
||||||
|
|
||||||
std::shared_ptr<Window> m_window;
|
std::shared_ptr<Window> m_window;
|
||||||
DisplayConfig m_display;
|
DisplayConfig m_display;
|
||||||
|
|
||||||
VkInstance m_instance;
|
VkInstance m_instance;
|
||||||
VkSurfaceKHR m_surface;
|
VkSurfaceKHR m_surface;
|
||||||
|
VkPhysicalDevice m_physicalDevice;
|
||||||
|
uint32_t m_queueFIGraphics, m_queueFIPresent;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user