From 09638e714e75c348e597a7020f05d51256dd75e8 Mon Sep 17 00:00:00 2001
From: Stenzek <stenzek@gmail.com>
Date: Sat, 13 Aug 2016 15:16:31 +1000
Subject: [PATCH] VideoCommon: Extend DriverDetails to support both OpenGL and
 Vulkan

---
 Source/Core/VideoBackends/OGL/Render.cpp  |   2 +-
 Source/Core/VideoCommon/DriverDetails.cpp | 103 +++++++++++++++-------
 Source/Core/VideoCommon/DriverDetails.h   |  14 ++-
 3 files changed, 87 insertions(+), 32 deletions(-)

diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp
index 95be3867a7..3fb9ebb755 100644
--- a/Source/Core/VideoBackends/OGL/Render.cpp
+++ b/Source/Core/VideoBackends/OGL/Render.cpp
@@ -327,7 +327,7 @@ static void InitDriverInfo()
   default:
     break;
   }
-  DriverDetails::Init(vendor, driver, version, family);
+  DriverDetails::Init(DriverDetails::API_OPENGL, vendor, driver, version, family);
 }
 
 // Init functions
diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp
index 6da311c4e2..cf167f7d8d 100644
--- a/Source/Core/VideoCommon/DriverDetails.cpp
+++ b/Source/Core/VideoCommon/DriverDetails.cpp
@@ -11,6 +11,7 @@ namespace DriverDetails
 {
 struct BugInfo
 {
+  API m_api;              // Which API has the issue
   u32 m_os;               // Which OS has the issue
   Vendor m_vendor;        // Which vendor has the error
   Driver m_driver;        // Which driver has the error
@@ -36,6 +37,7 @@ const u32 m_os = OS_ALL | OS_FREEBSD;
 const u32 m_os = OS_ALL | OS_OPENBSD;
 #endif
 
+static API m_api = API_OPENGL;
 static Vendor m_vendor = VENDOR_UNKNOWN;
 static Driver m_driver = DRIVER_UNKNOWN;
 static Family m_family = Family::UNKNOWN;
@@ -44,49 +46,58 @@ static double m_version = 0.0;
 // This is a list of all known bugs for each vendor
 // We use this to check if the device and driver has a issue
 static BugInfo m_known_bugs[] = {
-    {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM, -1.0, -1.0,
-     true},
-    {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENNEGATEDBOOLEAN, -1.0,
+    {API_OPENGL, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM,
+     -1.0, -1.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN,
+     BUG_BROKENNEGATEDBOOLEAN, -1.0, -1.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENEXPLICITFLUSH,
+     -1.0, -1.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM, -1.0,
      -1.0, true},
-    {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENEXPLICITFLUSH, -1.0, -1.0,
+    {API_OPENGL, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKENVSYNC, -1.0, -1.0,
      true},
-    {OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM, -1.0, -1.0, true},
-    {OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKENVSYNC, -1.0, -1.0, true},
-    {OS_ALL, VENDOR_IMGTEC, DRIVER_IMGTEC, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM, -1.0, -1.0,
+    {API_OPENGL, OS_ALL, VENDOR_IMGTEC, DRIVER_IMGTEC, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM,
+     -1.0, -1.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_NOUVEAU, Family::UNKNOWN, BUG_BROKENUBO, 900, 916,
      true},
-    {OS_ALL, VENDOR_MESA, DRIVER_NOUVEAU, Family::UNKNOWN, BUG_BROKENUBO, 900, 916, true},
-    {OS_ALL, VENDOR_MESA, DRIVER_R600, Family::UNKNOWN, BUG_BROKENUBO, 900, 913, true},
-    {OS_ALL, VENDOR_MESA, DRIVER_R600, Family::UNKNOWN, BUG_BROKENGEOMETRYSHADERS, -1.0, 1112.0,
-     true},
-    {OS_ALL, VENDOR_MESA, DRIVER_I965, Family::INTEL_SANDY, BUG_BROKENGEOMETRYSHADERS, -1.0, 1120.0,
-     true},
-    {OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKENUBO, 900, 920, true},
-    {OS_ALL, VENDOR_MESA, DRIVER_ALL, Family::UNKNOWN, BUG_BROKENCOPYIMAGE, -1.0, 1064.0, true},
-    {OS_LINUX, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_BROKENPINNEDMEMORY, -1.0, -1.0, true},
-    {OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKENBUFFERSTORAGE, -1.0,
-     33138.0, true},
-    {OS_OSX, VENDOR_INTEL, DRIVER_INTEL, Family::INTEL_SANDY, BUG_PRIMITIVERESTART, -1.0, -1.0,
-     true},
-    {OS_WINDOWS, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKENUNSYNCMAPPING, -1.0, -1.0,
-     true},
-    {OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKENUNSYNCMAPPING, -1.0, -1.0,
-     true},
-    {OS_WINDOWS, VENDOR_INTEL, DRIVER_INTEL, Family::UNKNOWN, BUG_INTELBROKENBUFFERSTORAGE,
-     101810.3907, 101810.3960, true},
-    {OS_ALL, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_SLOWGETBUFFERSUBDATA, -1.0, -1.0, true},
-    {OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKENCLIPDISTANCE, -1.0, -1.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_R600, Family::UNKNOWN, BUG_BROKENUBO, 900, 913, true},
+    {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_R600, Family::UNKNOWN, BUG_BROKENGEOMETRYSHADERS, -1.0,
+     1112.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::INTEL_SANDY, BUG_BROKENGEOMETRYSHADERS,
+     -1.0, 1120.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKENUBO, 900, 920, true},
+    {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_ALL, Family::UNKNOWN, BUG_BROKENCOPYIMAGE, -1.0,
+     1064.0, true},
+    {API_OPENGL, OS_LINUX, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_BROKENPINNEDMEMORY, -1.0,
+     -1.0, true},
+    {API_OPENGL, OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKENBUFFERSTORAGE,
+     -1.0, 33138.0, true},
+    {API_OPENGL, OS_OSX, VENDOR_INTEL, DRIVER_INTEL, Family::INTEL_SANDY, BUG_PRIMITIVERESTART,
+     -1.0, -1.0, true},
+    {API_OPENGL, OS_WINDOWS, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKENUNSYNCMAPPING,
+     -1.0, -1.0, true},
+    {API_OPENGL, OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKENUNSYNCMAPPING,
+     -1.0, -1.0, true},
+    {API_OPENGL, OS_WINDOWS, VENDOR_INTEL, DRIVER_INTEL, Family::UNKNOWN,
+     BUG_INTELBROKENBUFFERSTORAGE, 101810.3907, 101810.3960, true},
+    {API_OPENGL, OS_ALL, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_SLOWGETBUFFERSUBDATA, -1.0,
+     -1.0, true},
+    {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKENCLIPDISTANCE, -1.0,
+     -1.0, true},
 };
 
 static std::map<Bug, BugInfo> m_bugs;
 
-void Init(Vendor vendor, Driver driver, const double version, const Family family)
+void Init(API api, Vendor vendor, Driver driver, const double version, const Family family)
 {
+  m_api = api;
   m_vendor = vendor;
   m_driver = driver;
   m_version = version;
   m_family = family;
 
   if (driver == DRIVER_UNKNOWN)
+  {
     switch (vendor)
     {
     case VENDOR_NVIDIA:
@@ -108,10 +119,15 @@ void Init(Vendor vendor, Driver driver, const double version, const Family famil
     default:
       break;
     }
+  }
+
+  // Clear bug list, as the API may have changed
+  m_bugs.clear();
 
   for (auto& bug : m_known_bugs)
   {
-    if ((bug.m_os & m_os) && (bug.m_vendor == m_vendor || bug.m_vendor == VENDOR_ALL) &&
+    if ((bug.m_api & api) && (bug.m_os & m_os) &&
+        (bug.m_vendor == m_vendor || bug.m_vendor == VENDOR_ALL) &&
         (bug.m_driver == m_driver || bug.m_driver == DRIVER_ALL) &&
         (bug.m_family == m_family || bug.m_family == Family::UNKNOWN) &&
         (bug.m_versionstart <= m_version || bug.m_versionstart == -1) &&
@@ -127,4 +143,31 @@ bool HasBug(Bug bug)
     return false;
   return it->second.m_hasbug;
 }
+
+Vendor TranslatePCIVendorID(u32 vendor_id)
+{
+  switch (vendor_id)
+  {
+  case 0x10DE:
+    return VENDOR_NVIDIA;
+
+  case 0x1002:
+  case 0x1022:
+    return VENDOR_ATI;
+
+  case 0x8086:
+  case 0x8087:
+    return VENDOR_INTEL;
+
+  // TODO: Is this correct for Mali?
+  case 0x13B6:
+    return VENDOR_ARM;
+
+  case 0x5143:
+    return VENDOR_QUALCOMM;
+
+  default:
+    return VENDOR_UNKNOWN;
+  }
+}
 }
diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h
index b6dcf87963..86a365d578 100644
--- a/Source/Core/VideoCommon/DriverDetails.h
+++ b/Source/Core/VideoCommon/DriverDetails.h
@@ -8,6 +8,15 @@
 
 namespace DriverDetails
 {
+// API types supported by driver details
+// This is separate to APIType in VideoConfig.h due to the fact that a bug
+// can affect multiple APIs.
+enum API
+{
+  API_OPENGL = (1 << 0),
+  API_VULKAN = (1 << 1)
+};
+
 // Enum of supported operating systems
 enum OS
 {
@@ -216,9 +225,12 @@ enum Bug
 };
 
 // Initializes our internal vendor, device family, and driver version
-void Init(Vendor vendor, Driver driver, const double version, const Family family);
+void Init(API api, Vendor vendor, Driver driver, const double version, const Family family);
 
 // Once Vendor and driver version is set, this will return if it has the applicable bug passed to
 // it.
 bool HasBug(Bug bug);
+
+// Attempts to map a PCI vendor ID to our Vendor enumeration
+Vendor TranslatePCIVendorID(u32 vendor_id);
 }