renderer_vulkan: Throw when enumerating devices fails

Report device enumeration errors with exceptions to be consistent with
other initialization related function calls. Reduces the amount of code
to maintain.
merge-requests/60/head
ReinUsesLisp 2020-12-25 02:27:57 +07:00
parent 11f0f7598d
commit 085adfea00
5 changed files with 21 additions and 33 deletions

@ -170,7 +170,6 @@ void RendererVulkan::ShutDown() {
if (const auto& dev = device->GetLogical()) {
dev.WaitIdle();
}
rasterizer.reset();
blit_screen.reset();
scheduler.reset();
@ -180,19 +179,13 @@ void RendererVulkan::ShutDown() {
}
bool RendererVulkan::PickDevices() {
const auto devices = instance.EnumeratePhysicalDevices();
if (!devices) {
LOG_ERROR(Render_Vulkan, "Failed to enumerate physical devices");
return false;
}
const std::vector<VkPhysicalDevice> devices = instance.EnumeratePhysicalDevices();
const s32 device_index = Settings::values.vulkan_device.GetValue();
if (device_index < 0 || device_index >= static_cast<s32>(devices->size())) {
if (device_index < 0 || device_index >= static_cast<s32>(devices.size())) {
LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index);
return false;
}
const vk::PhysicalDevice physical_device((*devices)[static_cast<std::size_t>(device_index)],
dld);
const vk::PhysicalDevice physical_device(devices[static_cast<std::size_t>(device_index)], dld);
if (!VKDevice::IsSuitable(physical_device, *surface)) {
return false;
}
@ -224,23 +217,21 @@ void RendererVulkan::Report() const {
telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions);
}
std::vector<std::string> RendererVulkan::EnumerateDevices() {
std::vector<std::string> RendererVulkan::EnumerateDevices() try {
vk::InstanceDispatch dld;
Common::DynamicLibrary library = OpenLibrary();
vk::Instance instance = CreateInstance(library, dld).first;
if (!instance) {
return {};
}
const std::optional physical_devices = instance.EnumeratePhysicalDevices();
if (!physical_devices) {
return {};
}
const Common::DynamicLibrary library = OpenLibrary();
const vk::Instance instance = CreateInstance(library, dld).first;
const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices();
std::vector<std::string> names;
names.reserve(physical_devices->size());
for (const auto& device : *physical_devices) {
names.reserve(physical_devices.size());
for (const VkPhysicalDevice device : physical_devices) {
names.push_back(vk::PhysicalDevice(device, dld).GetProperties().deviceName);
}
return names;
} catch (const vk::Exception& exception) {
LOG_ERROR(Render_Vulkan, "Failed to enumerate devices with error: {}", exception.what());
return {};
}
} // namespace Vulkan

@ -111,7 +111,7 @@ void RemoveUnavailableLayers(const vk::InstanceDispatch& dld, std::vector<const
}
} // Anonymous namespace
std::pair<vk::Instance, u32> CreateInstance(Common::DynamicLibrary& library,
std::pair<vk::Instance, u32> CreateInstance(const Common::DynamicLibrary& library,
vk::InstanceDispatch& dld,
Core::Frontend::WindowSystemType window_type,
bool enable_debug_utils, bool enable_layers) {

@ -14,7 +14,7 @@
namespace Vulkan {
[[nodiscard]] std::pair<vk::Instance, u32> CreateInstance(
Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
const Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
Core::Frontend::WindowSystemType window_type = Core::Frontend::WindowSystemType::Headless,
bool enable_debug_utils = false, bool enable_layers = false);

@ -465,17 +465,13 @@ Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char
return Instance(instance, dispatch);
}
std::optional<std::vector<VkPhysicalDevice>> Instance::EnumeratePhysicalDevices() const {
std::vector<VkPhysicalDevice> Instance::EnumeratePhysicalDevices() const {
u32 num;
if (dld->vkEnumeratePhysicalDevices(handle, &num, nullptr) != VK_SUCCESS) {
return std::nullopt;
}
Check(dld->vkEnumeratePhysicalDevices(handle, &num, nullptr));
std::vector<VkPhysicalDevice> physical_devices(num);
if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) {
return std::nullopt;
}
Check(dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()));
SortPhysicalDevices(physical_devices, *dld);
return std::make_optional(std::move(physical_devices));
return physical_devices;
}
DebugUtilsMessenger Instance::CreateDebugUtilsMessenger(

@ -580,7 +580,8 @@ public:
/// Enumerates physical devices.
/// @return Physical devices and an empty handle on failure.
std::optional<std::vector<VkPhysicalDevice>> EnumeratePhysicalDevices() const;
/// @throw Exception on Vulkan error.
std::vector<VkPhysicalDevice> EnumeratePhysicalDevices() const;
/// Creates a debug callback messenger.
/// @throw Exception on creation failure.