From 4d535799eb8ae2b4c0f6acd13e84f914e55769a0 Mon Sep 17 00:00:00 2001
From: ameerj <52414509+ameerj@users.noreply.github.com>
Date: Tue, 24 Aug 2021 21:22:41 -0400
Subject: [PATCH] vulkan_device: Add a check for int8 support

Silences validation errors when shaders use int8 without specifying its support to the API
---
 .../renderer_vulkan/vk_pipeline_cache.cpp        |  2 +-
 src/video_core/vulkan_common/vulkan_device.cpp   | 16 ++++++++++------
 src/video_core/vulkan_common/vulkan_device.h     | 10 ++++++++--
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index a37ca1fdf1..f316c4f922 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -281,7 +281,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw
         .supported_spirv = device.IsKhrSpirv1_4Supported() ? 0x00010400U : 0x00010000U,
         .unified_descriptor_binding = true,
         .support_descriptor_aliasing = true,
-        .support_int8 = true,
+        .support_int8 = device.IsInt8Supported(),
         .support_int16 = device.IsShaderInt16Supported(),
         .support_int64 = device.IsShaderInt64Supported(),
         .support_vertex_instance_id = false,
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 8e56a89e10..86ca4be54e 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -368,18 +368,21 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
     };
     SetNext(next, demote);
 
-    VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8;
-    if (is_float16_supported) {
-        float16_int8 = {
+    if (is_int8_supported || is_float16_supported) {
+        VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8{
             .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR,
             .pNext = nullptr,
-            .shaderFloat16 = true,
-            .shaderInt8 = false,
+            .shaderFloat16 = is_float16_supported,
+            .shaderInt8 = is_int8_supported,
         };
         SetNext(next, float16_int8);
-    } else {
+    }
+    if (!is_float16_supported) {
         LOG_INFO(Render_Vulkan, "Device doesn't support float16 natively");
     }
+    if (!is_int8_supported) {
+        LOG_INFO(Render_Vulkan, "Device doesn't support int8 natively");
+    }
 
     if (!nv_viewport_swizzle) {
         LOG_INFO(Render_Vulkan, "Device doesn't support viewport swizzles");
@@ -909,6 +912,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
 
         physical.GetFeatures2KHR(features);
         is_float16_supported = float16_int8_features.shaderFloat16;
+        is_int8_supported = float16_int8_features.shaderInt8;
         extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
     }
     if (has_ext_subgroup_size_control) {
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index c19f40746d..234d741293 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -139,11 +139,16 @@ public:
         return is_optimal_astc_supported;
     }
 
-    /// Returns true if the device supports float16 natively
+    /// Returns true if the device supports float16 natively.
     bool IsFloat16Supported() const {
         return is_float16_supported;
     }
 
+    /// Returns true if the device supports int8 natively.
+    bool IsInt8Supported() const {
+        return is_int8_supported;
+    }
+
     /// Returns true if the device warp size can potentially be bigger than guest's warp size.
     bool IsWarpSizePotentiallyBiggerThanGuest() const {
         return is_warp_potentially_bigger;
@@ -367,7 +372,8 @@ private:
     u64 device_access_memory{};                 ///< Total size of device local memory in bytes.
     u32 max_push_descriptors{};                 ///< Maximum number of push descriptors
     bool is_optimal_astc_supported{};           ///< Support for native ASTC.
-    bool is_float16_supported{};                ///< Support for float16 arithmetics.
+    bool is_float16_supported{};                ///< Support for float16 arithmetic.
+    bool is_int8_supported{};                   ///< Support for int8 arithmetic.
     bool is_warp_potentially_bigger{};          ///< Host warp size can be bigger than guest.
     bool is_formatless_image_load_supported{};  ///< Support for shader image read without format.
     bool is_depth_bounds_supported{};           ///< Support for depth bounds.