diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index 831603e872..07edf556de 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -210,6 +210,7 @@ VKDevice::VKDevice(VkInstance instance_, u32 instance_version_, vk::PhysicalDevi
                    VkSurfaceKHR surface, const vk::InstanceDispatch& dld_)
     : instance{instance_}, dld{dld_}, physical{physical_}, properties{physical.GetProperties()},
       instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} {
+    CheckSuitability();
     SetupFamilies(surface);
     SetupFeatures();
 
@@ -548,64 +549,41 @@ bool VKDevice::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wa
     return (supported_usage & wanted_usage) == wanted_usage;
 }
 
-bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) {
-    bool is_suitable = true;
+void VKDevice::CheckSuitability() const {
     std::bitset<REQUIRED_EXTENSIONS.size()> available_extensions;
-
-    for (const auto& prop : physical.EnumerateDeviceExtensionProperties()) {
+    for (const VkExtensionProperties& property : physical.EnumerateDeviceExtensionProperties()) {
         for (std::size_t i = 0; i < REQUIRED_EXTENSIONS.size(); ++i) {
             if (available_extensions[i]) {
                 continue;
             }
-            const std::string_view name{prop.extensionName};
+            const std::string_view name{property.extensionName};
             available_extensions[i] = name == REQUIRED_EXTENSIONS[i];
         }
     }
-    if (!available_extensions.all()) {
-        for (std::size_t i = 0; i < REQUIRED_EXTENSIONS.size(); ++i) {
-            if (available_extensions[i]) {
-                continue;
-            }
-            LOG_ERROR(Render_Vulkan, "Missing required extension: {}", REQUIRED_EXTENSIONS[i]);
-            is_suitable = false;
-        }
-    }
-
-    bool has_graphics{}, has_present{};
-    const std::vector queue_family_properties = physical.GetQueueFamilyProperties();
-    for (u32 i = 0; i < static_cast<u32>(queue_family_properties.size()); ++i) {
-        const auto& family = queue_family_properties[i];
-        if (family.queueCount == 0) {
+    for (size_t i = 0; i < REQUIRED_EXTENSIONS.size(); ++i) {
+        if (available_extensions[i]) {
             continue;
         }
-        has_graphics |= family.queueFlags & VK_QUEUE_GRAPHICS_BIT;
-        has_present |= physical.GetSurfaceSupportKHR(i, surface);
+        LOG_ERROR(Render_Vulkan, "Missing required extension: {}", REQUIRED_EXTENSIONS[i]);
+        throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT);
     }
-    if (!has_graphics || !has_present) {
-        LOG_ERROR(Render_Vulkan, "Device lacks a graphics and present queue");
-        is_suitable = false;
-    }
-
     // TODO(Rodrigo): Check if the device matches all requeriments.
-    const auto properties{physical.GetProperties()};
-    const auto& limits{properties.limits};
+    const VkPhysicalDeviceLimits& limits{properties.limits};
 
     constexpr u32 required_ubo_size = 65536;
     if (limits.maxUniformBufferRange < required_ubo_size) {
         LOG_ERROR(Render_Vulkan, "Device UBO size {} is too small, {} is required",
                   limits.maxUniformBufferRange, required_ubo_size);
-        is_suitable = false;
+        throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
     }
-
     constexpr u32 required_num_viewports = 16;
     if (limits.maxViewports < required_num_viewports) {
         LOG_INFO(Render_Vulkan, "Device number of viewports {} is too small, {} is required",
                  limits.maxViewports, required_num_viewports);
-        is_suitable = false;
+        throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
     }
-
-    const auto features{physical.GetFeatures()};
-    const std::array feature_report = {
+    const VkPhysicalDeviceFeatures features{physical.GetFeatures()};
+    const std::array feature_report{
         std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"),
         std::make_pair(features.imageCubeArray, "imageCubeArray"),
         std::make_pair(features.independentBlend, "independentBlend"),
@@ -623,19 +601,13 @@ bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) {
         std::make_pair(features.shaderStorageImageWriteWithoutFormat,
                        "shaderStorageImageWriteWithoutFormat"),
     };
-    for (const auto& [supported, name] : feature_report) {
-        if (supported) {
+    for (const auto& [is_supported, name] : feature_report) {
+        if (is_supported) {
             continue;
         }
         LOG_ERROR(Render_Vulkan, "Missing required feature: {}", name);
-        is_suitable = false;
+        throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
     }
-
-    if (!is_suitable) {
-        LOG_ERROR(Render_Vulkan, "{} is not suitable", properties.deviceName);
-    }
-
-    return is_suitable;
 }
 
 std::vector<const char*> VKDevice::LoadExtensions() {
@@ -794,28 +766,34 @@ std::vector<const char*> VKDevice::LoadExtensions() {
 }
 
 void VKDevice::SetupFamilies(VkSurfaceKHR surface) {
-    std::optional<u32> graphics_family_, present_family_;
-
     const std::vector queue_family_properties = physical.GetQueueFamilyProperties();
-    for (u32 i = 0; i < static_cast<u32>(queue_family_properties.size()); ++i) {
-        if (graphics_family_ && present_family_)
+    std::optional<u32> graphics;
+    std::optional<u32> present;
+    for (u32 index = 0; index < static_cast<u32>(queue_family_properties.size()); ++index) {
+        if (graphics && present) {
             break;
-
-        const auto& queue_family = queue_family_properties[i];
-        if (queue_family.queueCount == 0)
-            continue;
-
-        if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
-            graphics_family_ = i;
         }
-        if (physical.GetSurfaceSupportKHR(i, surface)) {
-            present_family_ = i;
+        const VkQueueFamilyProperties& queue_family = queue_family_properties[index];
+        if (queue_family.queueCount == 0) {
+            continue;
+        }
+        if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+            graphics = index;
+        }
+        if (physical.GetSurfaceSupportKHR(index, surface)) {
+            present = index;
         }
     }
-    ASSERT(graphics_family_ && present_family_);
-
-    graphics_family = *graphics_family_;
-    present_family = *present_family_;
+    if (!graphics) {
+        LOG_ERROR(Render_Vulkan, "Device lacks a graphics queue");
+        throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
+    }
+    if (!present) {
+        LOG_ERROR(Render_Vulkan, "Device lacks a present queue");
+        throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
+    }
+    graphics_family = *graphics;
+    present_family = *present;
 }
 
 void VKDevice::SetupFeatures() {
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h
index 67617f86d4..63e123d022 100644
--- a/src/video_core/renderer_vulkan/vk_device.h
+++ b/src/video_core/renderer_vulkan/vk_device.h
@@ -229,10 +229,10 @@ public:
         return use_asynchronous_shaders;
     }
 
-    /// Checks if the physical device is suitable.
-    static bool IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface);
-
 private:
+    /// Checks if the physical device is suitable.
+    void CheckSuitability() const;
+
     /// Loads extensions into a vector and stores available ones in this object.
     std::vector<const char*> LoadExtensions();