diff --git a/externals/Vulkan-Headers b/externals/Vulkan-Headers
index d05c8df88da98ec1ab3bc600d7f5783b4060895b..fd568d51ed3d9bc6132e1639d7492453a08fe1bc 160000
--- a/externals/Vulkan-Headers
+++ b/externals/Vulkan-Headers
@@ -1 +1 @@
-Subproject commit d05c8df88da98ec1ab3bc600d7f5783b4060895b
+Subproject commit fd568d51ed3d9bc6132e1639d7492453a08fe1bc
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index 3b966ddc3c7ce170c6ae5c67141dcbbb9d98d428..897cbb4e880d3be9be4d49f20a9773260e579324 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -2,9 +2,10 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include <map>
+#include <bitset>
 #include <optional>
 #include <set>
+#include <string_view>
 #include <vector>
 #include "common/assert.h"
 #include "video_core/renderer_vulkan/declarations.h"
@@ -12,13 +13,32 @@
 
 namespace Vulkan {
 
+namespace {
+
+template <typename T>
+void SetNext(void**& next, T& data) {
+    *next = &data;
+    next = &data.pNext;
+}
+
+template <typename T>
+T GetFeatures(vk::PhysicalDevice physical, vk::DispatchLoaderDynamic dldi) {
+    vk::PhysicalDeviceFeatures2 features;
+    T extension_features;
+    features.pNext = &extension_features;
+    physical.getFeatures2(&features, dldi);
+    return extension_features;
+}
+
+} // Anonymous namespace
+
 namespace Alternatives {
 
-constexpr std::array<vk::Format, 3> Depth24UnormS8Uint = {
-    vk::Format::eD32SfloatS8Uint, vk::Format::eD16UnormS8Uint, {}};
-constexpr std::array<vk::Format, 3> Depth16UnormS8Uint = {
-    vk::Format::eD24UnormS8Uint, vk::Format::eD32SfloatS8Uint, {}};
-constexpr std::array<vk::Format, 2> Astc = {vk::Format::eA8B8G8R8UnormPack32, {}};
+constexpr std::array Depth24UnormS8Uint = {vk::Format::eD32SfloatS8Uint,
+                                           vk::Format::eD16UnormS8Uint, vk::Format{}};
+constexpr std::array Depth16UnormS8Uint = {vk::Format::eD24UnormS8Uint,
+                                           vk::Format::eD32SfloatS8Uint, vk::Format{}};
+constexpr std::array Astc = {vk::Format::eA8B8G8R8UnormPack32, vk::Format{}};
 
 } // namespace Alternatives
 
@@ -58,16 +78,53 @@ VKDevice::VKDevice(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice phy
 VKDevice::~VKDevice() = default;
 
 bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instance) {
-    vk::PhysicalDeviceFeatures device_features;
-    device_features.vertexPipelineStoresAndAtomics = true;
-    device_features.independentBlend = true;
-    device_features.textureCompressionASTC_LDR = is_optimal_astc_supported;
-
     const auto queue_cis = GetDeviceQueueCreateInfos();
-    const std::vector<const char*> extensions = LoadExtensions(dldi);
-    const vk::DeviceCreateInfo device_ci({}, static_cast<u32>(queue_cis.size()), queue_cis.data(),
-                                         0, nullptr, static_cast<u32>(extensions.size()),
-                                         extensions.data(), &device_features);
+    const std::vector extensions = LoadExtensions(dldi);
+
+    vk::PhysicalDeviceFeatures2 features2;
+    void** next = &features2.pNext;
+    auto& features = features2.features;
+    features.vertexPipelineStoresAndAtomics = true;
+    features.independentBlend = true;
+    features.depthClamp = true;
+    features.samplerAnisotropy = true;
+    features.largePoints = true;
+    features.textureCompressionASTC_LDR = is_optimal_astc_supported;
+
+    vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor;
+    vertex_divisor.vertexAttributeInstanceRateDivisor = true;
+    vertex_divisor.vertexAttributeInstanceRateZeroDivisor = true;
+    SetNext(next, vertex_divisor);
+
+    vk::PhysicalDeviceFloat16Int8FeaturesKHR float16_int8;
+    if (is_float16_supported) {
+        float16_int8.shaderFloat16 = true;
+        SetNext(next, float16_int8);
+    } else {
+        LOG_INFO(Render_Vulkan, "Device doesn't support float16 natively");
+    }
+
+    vk::PhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout;
+    if (khr_uniform_buffer_standard_layout) {
+        std430_layout.uniformBufferStandardLayout = true;
+        SetNext(next, std430_layout);
+    } else {
+        LOG_INFO(Render_Vulkan, "Device doesn't support packed UBOs");
+    }
+
+    vk::PhysicalDeviceIndexTypeUint8FeaturesEXT index_type_uint8;
+    if (ext_index_type_uint8) {
+        index_type_uint8.indexTypeUint8 = true;
+        SetNext(next, index_type_uint8);
+    } else {
+        LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes");
+    }
+
+    vk::DeviceCreateInfo device_ci({}, static_cast<u32>(queue_cis.size()), queue_cis.data(), 0,
+                                   nullptr, static_cast<u32>(extensions.size()), extensions.data(),
+                                   nullptr);
+    device_ci.pNext = &features2;
+
     vk::Device dummy_logical;
     if (physical.createDevice(&device_ci, nullptr, &dummy_logical, dldi) != vk::Result::eSuccess) {
         LOG_CRITICAL(Render_Vulkan, "Logical device failed to be created!");
@@ -78,6 +135,17 @@ bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instan
     logical = UniqueDevice(
         dummy_logical, vk::ObjectDestroy<vk::NoParent, vk::DispatchLoaderDynamic>(nullptr, dld));
 
+    if (khr_driver_properties) {
+        vk::PhysicalDeviceDriverPropertiesKHR driver;
+        vk::PhysicalDeviceProperties2 properties;
+        properties.pNext = &driver;
+        physical.getProperties2(&properties, dld);
+        driver_id = driver.driverID;
+        LOG_INFO(Render_Vulkan, "Driver: {} {}", driver.driverName, driver.driverInfo);
+    } else {
+        LOG_INFO(Render_Vulkan, "Driver: Unknown");
+    }
+
     graphics_queue = logical->getQueue(graphics_family, 0, dld);
     present_queue = logical->getQueue(present_family, 0, dld);
     return true;
@@ -92,20 +160,19 @@ vk::Format VKDevice::GetSupportedFormat(vk::Format wanted_format,
     // The wanted format is not supported by hardware, search for alternatives
     const vk::Format* alternatives = GetFormatAlternatives(wanted_format);
     if (alternatives == nullptr) {
-        LOG_CRITICAL(Render_Vulkan,
-                     "Format={} with usage={} and type={} has no defined alternatives and host "
-                     "hardware does not support it",
-                     vk::to_string(wanted_format), vk::to_string(wanted_usage),
-                     static_cast<u32>(format_type));
-        UNREACHABLE();
+        UNREACHABLE_MSG("Format={} with usage={} and type={} has no defined alternatives and host "
+                        "hardware does not support it",
+                        vk::to_string(wanted_format), vk::to_string(wanted_usage),
+                        static_cast<u32>(format_type));
         return wanted_format;
     }
 
     std::size_t i = 0;
     for (vk::Format alternative = alternatives[0]; alternative != vk::Format{};
          alternative = alternatives[++i]) {
-        if (!IsFormatSupported(alternative, wanted_usage, format_type))
+        if (!IsFormatSupported(alternative, wanted_usage, format_type)) {
             continue;
+        }
         LOG_WARNING(Render_Vulkan,
                     "Emulating format={} with alternative format={} with usage={} and type={}",
                     static_cast<u32>(wanted_format), static_cast<u32>(alternative),
@@ -114,12 +181,10 @@ vk::Format VKDevice::GetSupportedFormat(vk::Format wanted_format,
     }
 
     // No alternatives found, panic
-    LOG_CRITICAL(Render_Vulkan,
-                 "Format={} with usage={} and type={} is not supported by the host hardware and "
-                 "doesn't support any of the alternatives",
-                 static_cast<u32>(wanted_format), static_cast<u32>(wanted_usage),
-                 static_cast<u32>(format_type));
-    UNREACHABLE();
+    UNREACHABLE_MSG("Format={} with usage={} and type={} is not supported by the host hardware and "
+                    "doesn't support any of the alternatives",
+                    static_cast<u32>(wanted_format), static_cast<u32>(wanted_usage),
+                    static_cast<u32>(format_type));
     return wanted_format;
 }
 
@@ -132,7 +197,7 @@ bool VKDevice::IsOptimalAstcSupported(const vk::PhysicalDeviceFeatures& features
         vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eBlitSrc |
         vk::FormatFeatureFlagBits::eBlitDst | vk::FormatFeatureFlagBits::eTransferSrc |
         vk::FormatFeatureFlagBits::eTransferDst};
-    constexpr std::array<vk::Format, 9> astc_formats = {
+    constexpr std::array astc_formats = {
         vk::Format::eAstc4x4UnormBlock, vk::Format::eAstc4x4SrgbBlock,
         vk::Format::eAstc8x8SrgbBlock,  vk::Format::eAstc8x6SrgbBlock,
         vk::Format::eAstc5x4SrgbBlock,  vk::Format::eAstc5x5UnormBlock,
@@ -151,76 +216,120 @@ bool VKDevice::IsFormatSupported(vk::Format wanted_format, vk::FormatFeatureFlag
                                  FormatType format_type) const {
     const auto it = format_properties.find(wanted_format);
     if (it == format_properties.end()) {
-        LOG_CRITICAL(Render_Vulkan, "Unimplemented format query={}", vk::to_string(wanted_format));
-        UNREACHABLE();
+        UNIMPLEMENTED_MSG("Unimplemented format query={}", vk::to_string(wanted_format));
         return true;
     }
-    const vk::FormatFeatureFlags supported_usage = GetFormatFeatures(it->second, format_type);
+    const auto supported_usage = GetFormatFeatures(it->second, format_type);
     return (supported_usage & wanted_usage) == wanted_usage;
 }
 
 bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical,
                           vk::SurfaceKHR surface) {
-    bool has_swapchain{};
+    LOG_INFO(Render_Vulkan, "{}", physical.getProperties(dldi).deviceName);
+    bool is_suitable = true;
+
+    constexpr std::array required_extensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+                                                VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME};
+    std::bitset<required_extensions.size()> available_extensions{};
+
     for (const auto& prop : physical.enumerateDeviceExtensionProperties(nullptr, dldi)) {
-        has_swapchain |= prop.extensionName == std::string(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
+        for (std::size_t i = 0; i < required_extensions.size(); ++i) {
+            if (available_extensions[i]) {
+                continue;
+            }
+            available_extensions[i] =
+                required_extensions[i] == std::string_view{prop.extensionName};
+        }
     }
-    if (!has_swapchain) {
-        // The device doesn't support creating swapchains.
-        return false;
+    if (!available_extensions.all()) {
+        for (std::size_t i = 0; i < required_extensions.size(); ++i) {
+            if (available_extensions[i]) {
+                continue;
+            }
+            LOG_INFO(Render_Vulkan, "Missing required extension: {}", required_extensions[i]);
+            is_suitable = false;
+        }
     }
 
     bool has_graphics{}, has_present{};
     const auto queue_family_properties = physical.getQueueFamilyProperties(dldi);
     for (u32 i = 0; i < static_cast<u32>(queue_family_properties.size()); ++i) {
         const auto& family = queue_family_properties[i];
-        if (family.queueCount == 0)
+        if (family.queueCount == 0) {
             continue;
-
+        }
         has_graphics |=
             (family.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlagBits>(0);
         has_present |= physical.getSurfaceSupportKHR(i, surface, dldi) != 0;
     }
     if (!has_graphics || !has_present) {
-        // The device doesn't have a graphics and present queue.
-        return false;
+        LOG_INFO(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(dldi)};
-    const auto limits{properties.limits};
-    if (limits.maxUniformBufferRange < 65536) {
-        return false;
+    const auto& limits{properties.limits};
+
+    constexpr u32 required_ubo_size = 65536;
+    if (limits.maxUniformBufferRange < required_ubo_size) {
+        LOG_INFO(Render_Vulkan, "Device UBO size {} is too small, {} is required)",
+                 limits.maxUniformBufferRange, required_ubo_size);
+        is_suitable = false;
     }
 
-    const vk::PhysicalDeviceFeatures features{physical.getFeatures(dldi)};
-    if (!features.vertexPipelineStoresAndAtomics || !features.independentBlend) {
-        return false;
+    const auto features{physical.getFeatures(dldi)};
+    const std::array feature_report = {
+        std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"),
+        std::make_pair(features.independentBlend, "independentBlend"),
+        std::make_pair(features.depthClamp, "depthClamp"),
+        std::make_pair(features.samplerAnisotropy, "samplerAnisotropy"),
+        std::make_pair(features.largePoints, "largePoints"),
+    };
+    for (const auto& [supported, name] : feature_report) {
+        if (supported) {
+            continue;
+        }
+        LOG_INFO(Render_Vulkan, "Missing required feature: {}", name);
+        is_suitable = false;
     }
 
-    // Device is suitable.
-    return true;
+    return is_suitable;
 }
 
 std::vector<const char*> VKDevice::LoadExtensions(const vk::DispatchLoaderDynamic& dldi) {
     std::vector<const char*> extensions;
-    extensions.reserve(2);
+    extensions.reserve(7);
     extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
+    extensions.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
 
     const auto Test = [&](const vk::ExtensionProperties& extension,
                           std::optional<std::reference_wrapper<bool>> status, const char* name,
-                          u32 revision) {
-        if (extension.extensionName != std::string(name)) {
+                          bool push) {
+        if (extension.extensionName != std::string_view(name)) {
             return;
         }
-        extensions.push_back(name);
+        if (push) {
+            extensions.push_back(name);
+        }
         if (status) {
             status->get() = true;
         }
     };
 
+    bool khr_shader_float16_int8{};
     for (const auto& extension : physical.enumerateDeviceExtensionProperties(nullptr, dldi)) {
-        Test(extension, ext_scalar_block_layout, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, 1);
+        Test(extension, khr_uniform_buffer_standard_layout,
+             VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true);
+        Test(extension, ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true);
+        Test(extension, khr_driver_properties, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, true);
+        Test(extension, khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false);
+    }
+
+    if (khr_shader_float16_int8) {
+        is_float16_supported =
+            GetFeatures<vk::PhysicalDeviceFloat16Int8FeaturesKHR>(physical, dldi).shaderFloat16;
+        extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
     }
 
     return extensions;
@@ -250,9 +359,10 @@ void VKDevice::SetupFamilies(const vk::DispatchLoaderDynamic& dldi, vk::SurfaceK
 }
 
 void VKDevice::SetupProperties(const vk::DispatchLoaderDynamic& dldi) {
-    const vk::PhysicalDeviceProperties props = physical.getProperties(dldi);
+    const auto props = physical.getProperties(dldi);
     device_type = props.deviceType;
     uniform_buffer_alignment = static_cast<u64>(props.limits.minUniformBufferOffsetAlignment);
+    storage_buffer_alignment = static_cast<u64>(props.limits.minStorageBufferOffsetAlignment);
     max_storage_buffer_range = static_cast<u64>(props.limits.maxStorageBufferRange);
 }
 
@@ -273,42 +383,53 @@ std::vector<vk::DeviceQueueCreateInfo> VKDevice::GetDeviceQueueCreateInfos() con
     return queue_cis;
 }
 
-std::map<vk::Format, vk::FormatProperties> VKDevice::GetFormatProperties(
+std::unordered_map<vk::Format, vk::FormatProperties> VKDevice::GetFormatProperties(
     const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical) {
-    static constexpr std::array formats{vk::Format::eA8B8G8R8UnormPack32,
-                                        vk::Format::eB5G6R5UnormPack16,
-                                        vk::Format::eA2B10G10R10UnormPack32,
-                                        vk::Format::eR32G32B32A32Sfloat,
-                                        vk::Format::eR16G16Unorm,
-                                        vk::Format::eR16G16Snorm,
-                                        vk::Format::eR8G8B8A8Srgb,
-                                        vk::Format::eR8Unorm,
-                                        vk::Format::eB10G11R11UfloatPack32,
-                                        vk::Format::eR32Sfloat,
-                                        vk::Format::eR16Sfloat,
-                                        vk::Format::eR16G16B16A16Sfloat,
-                                        vk::Format::eD32Sfloat,
-                                        vk::Format::eD16Unorm,
-                                        vk::Format::eD16UnormS8Uint,
-                                        vk::Format::eD24UnormS8Uint,
-                                        vk::Format::eD32SfloatS8Uint,
-                                        vk::Format::eBc1RgbaUnormBlock,
-                                        vk::Format::eBc2UnormBlock,
-                                        vk::Format::eBc3UnormBlock,
-                                        vk::Format::eBc4UnormBlock,
-                                        vk::Format::eBc5UnormBlock,
-                                        vk::Format::eBc5SnormBlock,
-                                        vk::Format::eBc7UnormBlock,
-                                        vk::Format::eAstc4x4UnormBlock,
-                                        vk::Format::eAstc4x4SrgbBlock,
-                                        vk::Format::eAstc8x8SrgbBlock,
-                                        vk::Format::eAstc8x6SrgbBlock,
-                                        vk::Format::eAstc5x4SrgbBlock,
-                                        vk::Format::eAstc5x5UnormBlock,
-                                        vk::Format::eAstc5x5SrgbBlock,
-                                        vk::Format::eAstc10x8UnormBlock,
-                                        vk::Format::eAstc10x8SrgbBlock};
-    std::map<vk::Format, vk::FormatProperties> format_properties;
+    constexpr std::array formats{vk::Format::eA8B8G8R8UnormPack32,
+                                 vk::Format::eA8B8G8R8SnormPack32,
+                                 vk::Format::eA8B8G8R8SrgbPack32,
+                                 vk::Format::eB5G6R5UnormPack16,
+                                 vk::Format::eA2B10G10R10UnormPack32,
+                                 vk::Format::eR32G32B32A32Sfloat,
+                                 vk::Format::eR16G16B16A16Uint,
+                                 vk::Format::eR16G16Unorm,
+                                 vk::Format::eR16G16Snorm,
+                                 vk::Format::eR16G16Sfloat,
+                                 vk::Format::eR16Unorm,
+                                 vk::Format::eR8G8B8A8Srgb,
+                                 vk::Format::eR8G8Unorm,
+                                 vk::Format::eR8G8Snorm,
+                                 vk::Format::eR8Unorm,
+                                 vk::Format::eB10G11R11UfloatPack32,
+                                 vk::Format::eR32Sfloat,
+                                 vk::Format::eR16Sfloat,
+                                 vk::Format::eR16G16B16A16Sfloat,
+                                 vk::Format::eB8G8R8A8Unorm,
+                                 vk::Format::eD32Sfloat,
+                                 vk::Format::eD16Unorm,
+                                 vk::Format::eD16UnormS8Uint,
+                                 vk::Format::eD24UnormS8Uint,
+                                 vk::Format::eD32SfloatS8Uint,
+                                 vk::Format::eBc1RgbaUnormBlock,
+                                 vk::Format::eBc2UnormBlock,
+                                 vk::Format::eBc3UnormBlock,
+                                 vk::Format::eBc4UnormBlock,
+                                 vk::Format::eBc5UnormBlock,
+                                 vk::Format::eBc5SnormBlock,
+                                 vk::Format::eBc7UnormBlock,
+                                 vk::Format::eBc1RgbaSrgbBlock,
+                                 vk::Format::eBc3SrgbBlock,
+                                 vk::Format::eBc7SrgbBlock,
+                                 vk::Format::eAstc4x4UnormBlock,
+                                 vk::Format::eAstc4x4SrgbBlock,
+                                 vk::Format::eAstc8x8SrgbBlock,
+                                 vk::Format::eAstc8x6SrgbBlock,
+                                 vk::Format::eAstc5x4SrgbBlock,
+                                 vk::Format::eAstc5x5UnormBlock,
+                                 vk::Format::eAstc5x5SrgbBlock,
+                                 vk::Format::eAstc10x8UnormBlock,
+                                 vk::Format::eAstc10x8SrgbBlock};
+    std::unordered_map<vk::Format, vk::FormatProperties> format_properties;
     for (const auto format : formats) {
         format_properties.emplace(format, physical.getFormatProperties(format, dldi));
     }
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h
index 537825d8bf59551ad0a082d59ede3f9efb3cf231..010d4c3d6ea15128279b7c5edbe416969cb9427e 100644
--- a/src/video_core/renderer_vulkan/vk_device.h
+++ b/src/video_core/renderer_vulkan/vk_device.h
@@ -4,7 +4,7 @@
 
 #pragma once
 
-#include <map>
+#include <unordered_map>
 #include <vector>
 #include "common/common_types.h"
 #include "video_core/renderer_vulkan/declarations.h"
@@ -69,16 +69,26 @@ public:
         return present_family;
     }
 
-    /// Returns if the device is integrated with the host CPU.
+    /// Returns true if the device is integrated with the host CPU.
     bool IsIntegrated() const {
         return device_type == vk::PhysicalDeviceType::eIntegratedGpu;
     }
 
+    /// Returns the driver ID.
+    vk::DriverIdKHR GetDriverID() const {
+        return driver_id;
+    }
+
     /// Returns uniform buffer alignment requeriment.
     u64 GetUniformBufferAlignment() const {
         return uniform_buffer_alignment;
     }
 
+    /// Returns storage alignment requeriment.
+    u64 GetStorageBufferAlignment() const {
+        return storage_buffer_alignment;
+    }
+
     /// Returns the maximum range for storage buffers.
     u64 GetMaxStorageBufferRange() const {
         return max_storage_buffer_range;
@@ -89,9 +99,19 @@ public:
         return is_optimal_astc_supported;
     }
 
+    /// Returns true if the device supports float16 natively
+    bool IsFloat16Supported() const {
+        return is_float16_supported;
+    }
+
     /// Returns true if the device supports VK_EXT_scalar_block_layout.
-    bool IsExtScalarBlockLayoutSupported() const {
-        return ext_scalar_block_layout;
+    bool IsKhrUniformBufferStandardLayoutSupported() const {
+        return khr_uniform_buffer_standard_layout;
+    }
+
+    /// Returns true if the device supports VK_EXT_index_type_uint8.
+    bool IsExtIndexTypeUint8Supported() const {
+        return ext_index_type_uint8;
     }
 
     /// Checks if the physical device is suitable.
@@ -123,22 +143,28 @@ private:
                            FormatType format_type) const;
 
     /// Returns the device properties for Vulkan formats.
-    static std::map<vk::Format, vk::FormatProperties> GetFormatProperties(
+    static std::unordered_map<vk::Format, vk::FormatProperties> GetFormatProperties(
         const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical);
 
-    const vk::PhysicalDevice physical;  ///< Physical device.
-    vk::DispatchLoaderDynamic dld;      ///< Device function pointers.
-    UniqueDevice logical;               ///< Logical device.
-    vk::Queue graphics_queue;           ///< Main graphics queue.
-    vk::Queue present_queue;            ///< Main present queue.
-    u32 graphics_family{};              ///< Main graphics queue family index.
-    u32 present_family{};               ///< Main present queue family index.
-    vk::PhysicalDeviceType device_type; ///< Physical device type.
-    u64 uniform_buffer_alignment{};     ///< Uniform buffer alignment requeriment.
-    u64 max_storage_buffer_range{};     ///< Max storage buffer size.
-    bool is_optimal_astc_supported{};   ///< Support for native ASTC.
-    bool ext_scalar_block_layout{};     ///< Support for VK_EXT_scalar_block_layout.
-    std::map<vk::Format, vk::FormatProperties> format_properties; ///< Format properties dictionary.
+    const vk::PhysicalDevice physical;         ///< Physical device.
+    vk::DispatchLoaderDynamic dld;             ///< Device function pointers.
+    UniqueDevice logical;                      ///< Logical device.
+    vk::Queue graphics_queue;                  ///< Main graphics queue.
+    vk::Queue present_queue;                   ///< Main present queue.
+    u32 graphics_family{};                     ///< Main graphics queue family index.
+    u32 present_family{};                      ///< Main present queue family index.
+    vk::PhysicalDeviceType device_type;        ///< Physical device type.
+    vk::DriverIdKHR driver_id{};               ///< Driver ID.
+    u64 uniform_buffer_alignment{};            ///< Uniform buffer alignment requeriment.
+    u64 storage_buffer_alignment{};            ///< Storage buffer alignment requeriment.
+    u64 max_storage_buffer_range{};            ///< Max storage buffer size.
+    bool is_optimal_astc_supported{};          ///< Support for native ASTC.
+    bool is_float16_supported{};               ///< Support for float16 arithmetics.
+    bool khr_uniform_buffer_standard_layout{}; ///< Support for std430 on UBOs.
+    bool ext_index_type_uint8{};               ///< Support for VK_EXT_index_type_uint8.
+    bool khr_driver_properties{};              ///< Support for VK_KHR_driver_properties.
+    std::unordered_map<vk::Format, vk::FormatProperties>
+        format_properties; ///< Format properties dictionary.
 };
 
 } // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 7675fc7b396c5c014aa25c2aac6892d4bee73a0b..b9153934e112ff6dd2c8283da2403cec7bb44865 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -370,8 +370,8 @@ private:
         u32 binding = const_buffers_base_binding;
         for (const auto& entry : ir.GetConstantBuffers()) {
             const auto [index, size] = entry;
-            const Id type =
-                device.IsExtScalarBlockLayoutSupported() ? t_cbuf_scalar_ubo : t_cbuf_std140_ubo;
+            const Id type = device.IsKhrUniformBufferStandardLayoutSupported() ? t_cbuf_scalar_ubo
+                                                                               : t_cbuf_std140_ubo;
             const Id id = OpVariable(type, spv::StorageClass::Uniform);
             AddGlobalVariable(Name(id, fmt::format("cbuf_{}", index)));
 
@@ -565,7 +565,7 @@ private:
             const Id buffer_id = constant_buffers.at(cbuf->GetIndex());
 
             Id pointer{};
-            if (device.IsExtScalarBlockLayoutSupported()) {
+            if (device.IsKhrUniformBufferStandardLayoutSupported()) {
                 const Id buffer_offset = Emit(OpShiftRightLogical(
                     t_uint, BitcastTo<Type::Uint>(Visit(offset)), Constant(t_uint, 2u)));
                 pointer = Emit(