mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-22 05:15:51 +12:00
Add initial vulkan instance creation
Headlessly creates a new vulkan instance, with conditional MacOS support, and enables the `VK_EXT_debug_utils` instance-extension with a debug-messenger to hook onto validation layer messages.
This commit is contained in:
parent
d2241a25bc
commit
870b6a21bf
6 changed files with 336 additions and 5 deletions
|
@ -1,5 +1,8 @@
|
|||
#include "renderer_vk/renderer_vk.hpp"
|
||||
|
||||
#include "helpers.hpp"
|
||||
#include "renderer_vk/vk_debug.hpp"
|
||||
|
||||
RendererVK::RendererVK(GPU& gpu, const std::array<u32, regNum>& internalRegs) : Renderer(gpu, internalRegs) {}
|
||||
|
||||
RendererVK::~RendererVK() {}
|
||||
|
@ -8,7 +11,125 @@ void RendererVK::reset() {}
|
|||
|
||||
void RendererVK::display() {}
|
||||
|
||||
void RendererVK::initGraphicsContext() { static vk::DynamicLoader dl; }
|
||||
void RendererVK::initGraphicsContext() {
|
||||
// Resolve all function pointers
|
||||
static vk::DynamicLoader dl;
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr"));
|
||||
|
||||
// Create Instance
|
||||
vk::ApplicationInfo applicationInfo = {};
|
||||
applicationInfo.apiVersion = VK_API_VERSION_1_1;
|
||||
|
||||
applicationInfo.pEngineName = "Alber";
|
||||
applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
|
||||
applicationInfo.pApplicationName = "Alber";
|
||||
applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
|
||||
vk::InstanceCreateInfo instanceInfo = {};
|
||||
|
||||
instanceInfo.pApplicationInfo = &applicationInfo;
|
||||
|
||||
static const std::array instanceExtensions = std::to_array({
|
||||
#if defined(__APPLE__)
|
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME
|
||||
#endif
|
||||
VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
|
||||
});
|
||||
|
||||
#if defined(__APPLE__)
|
||||
InstanceInfo.flags |= vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR;
|
||||
#endif
|
||||
|
||||
instanceInfo.ppEnabledExtensionNames = instanceExtensions.data();
|
||||
instanceInfo.enabledExtensionCount = instanceExtensions.size();
|
||||
|
||||
if (auto createResult = vk::createInstanceUnique(instanceInfo); createResult.result == vk::Result::eSuccess) {
|
||||
instance = std::move(createResult.value);
|
||||
} else {
|
||||
Helpers::panic("Error creating Vulkan instance: %s\n", vk::to_string(createResult.result).c_str());
|
||||
}
|
||||
// Initialize instance-specific function pointers
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance.get());
|
||||
|
||||
// Enable debug messenger if the instance was able to be created with debug_utils
|
||||
if (std::find(
|
||||
instanceExtensions.begin(), instanceExtensions.end(),
|
||||
// std::string_view has a way to compare itself to `const char*`
|
||||
// so by casting it, we get the actual string comparisons
|
||||
// and not pointer-comparisons
|
||||
std::string_view(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)
|
||||
) != instanceExtensions.end()) {
|
||||
vk::DebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
|
||||
debugCreateInfo.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning;
|
||||
debugCreateInfo.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral;
|
||||
debugCreateInfo.pfnUserCallback = &Vulkan::debugMessageCallback;
|
||||
if (auto createResult = instance->createDebugUtilsMessengerEXTUnique(debugCreateInfo); createResult.result == vk::Result::eSuccess) {
|
||||
debugMessenger = std::move(createResult.value);
|
||||
} else {
|
||||
Helpers::warn("Error registering debug messenger: %s", vk::to_string(createResult.result).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Pick physical device
|
||||
if (auto EnumerateResult = instance->enumeratePhysicalDevices(); EnumerateResult.result == vk::Result::eSuccess) {
|
||||
std::vector<vk::PhysicalDevice> PhysicalDevices = std::move(EnumerateResult.value);
|
||||
|
||||
// Prefer Discrete GPUs
|
||||
const auto IsDiscrete = [](const vk::PhysicalDevice& PhysicalDevice) -> bool {
|
||||
return PhysicalDevice.getProperties().deviceType == vk::PhysicalDeviceType::eDiscreteGpu;
|
||||
};
|
||||
|
||||
std::partition(PhysicalDevices.begin(), PhysicalDevices.end(), IsDiscrete);
|
||||
|
||||
// Pick the "best" out of all of the previous criteria
|
||||
physicalDevice = PhysicalDevices.front();
|
||||
} else {
|
||||
Helpers::panic("Error enumerating physical devices: %s\n", vk::to_string(EnumerateResult.result).c_str());
|
||||
}
|
||||
|
||||
// Create Device
|
||||
vk::DeviceCreateInfo deviceInfo = {};
|
||||
|
||||
static const char* deviceExtensions[] = {
|
||||
#if defined(__APPLE__)
|
||||
"VK_KHR_portability_subset",
|
||||
#endif
|
||||
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME
|
||||
};
|
||||
deviceInfo.ppEnabledExtensionNames = deviceExtensions;
|
||||
deviceInfo.enabledExtensionCount = std::size(deviceExtensions);
|
||||
|
||||
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceTimelineSemaphoreFeatures> deviceFeatureChain = {};
|
||||
|
||||
auto& deviceFeatures = deviceFeatureChain.get<vk::PhysicalDeviceFeatures2>().features;
|
||||
|
||||
auto& deviceTimelineFeatures = deviceFeatureChain.get<vk::PhysicalDeviceTimelineSemaphoreFeatures>();
|
||||
deviceTimelineFeatures.timelineSemaphore = true;
|
||||
|
||||
deviceInfo.pNext = &deviceFeatureChain.get();
|
||||
|
||||
static const float queuePriority = 1.0f;
|
||||
|
||||
vk::DeviceQueueCreateInfo queueInfo = {};
|
||||
queueInfo.queueFamilyIndex = 0;
|
||||
queueInfo.queueCount = 1;
|
||||
queueInfo.pQueuePriorities = &queuePriority;
|
||||
|
||||
deviceInfo.queueCreateInfoCount = 1;
|
||||
deviceInfo.pQueueCreateInfos = &queueInfo;
|
||||
|
||||
if (auto createResult = physicalDevice.createDeviceUnique(deviceInfo); createResult.result == vk::Result::eSuccess) {
|
||||
device = std::move(createResult.value);
|
||||
} else {
|
||||
Helpers::panic("Error creating logical device: %s\n", vk::to_string(createResult.result).c_str());
|
||||
}
|
||||
|
||||
// Initialize device-specific function pointers
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(device.get());
|
||||
}
|
||||
|
||||
void RendererVK::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue