1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
|
// Copyright 2013 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "VideoCommon/DriverDetails.h"
#include <map>
#include "Common/Logging/LogManager.h"
#include "Core/DolphinAnalytics.h"
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
Family m_family; // Which family of hardware has the issue
Bug m_bug; // Which bug it is
double m_versionstart; // When it started
double m_versionend; // When it ended
bool m_hasbug; // Does it have it?
};
// Local members
#ifdef _WIN32
constexpr u32 m_os = OS_ALL | OS_WINDOWS;
#elif ANDROID
constexpr u32 m_os = OS_ALL | OS_ANDROID;
#elif __APPLE__
constexpr u32 m_os = OS_ALL | OS_OSX;
#elif __linux__
constexpr u32 m_os = OS_ALL | OS_LINUX;
#elif __FreeBSD__
constexpr u32 m_os = OS_ALL | OS_FREEBSD;
#elif __OpenBSD__
constexpr u32 m_os = OS_ALL | OS_OPENBSD;
#elif __NetBSD__
constexpr u32 m_os = OS_ALL | OS_NETBSD;
#elif __HAIKU__
constexpr u32 m_os = OS_ALL | OS_HAIKU;
#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;
static double m_version = 0.0;
static std::string m_name;
// This is a list of all known bugs for each vendor
// We use this to check if the device and driver has a issue
constexpr BugInfo m_known_bugs[] = {
{API_OPENGL, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN,
BUG_BROKEN_BUFFER_STREAM, -1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN,
BUG_BROKEN_NEGATED_BOOLEAN, -1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_BUFFER_STREAM, -1.0,
-1.0, true},
{API_OPENGL, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_VSYNC, -1.0, -1.0,
true},
{API_OPENGL, OS_ALL, VENDOR_IMGTEC, DRIVER_IMGTEC, Family::UNKNOWN, BUG_BROKEN_BUFFER_STREAM,
-1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_NOUVEAU, Family::UNKNOWN, BUG_BROKEN_UBO, 900, 916,
true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_R600, Family::UNKNOWN, BUG_BROKEN_UBO, 900, 913, true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_R600, Family::UNKNOWN, BUG_BROKEN_GEOMETRY_SHADERS,
-1.0, 1112.0, true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::INTEL_SANDY, BUG_BROKEN_GEOMETRY_SHADERS,
-1.0, 1120.0, true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKEN_UBO, 900, 920, true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_ALL, Family::UNKNOWN, BUG_BROKEN_COPYIMAGE, -1.0,
1064.0, true},
{API_OPENGL, OS_LINUX, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_BROKEN_PINNED_MEMORY, -1.0,
-1.0, true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_R600, Family::UNKNOWN, BUG_BROKEN_PINNED_MEMORY, -1.0,
-1.0, true},
{API_OPENGL, OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKEN_BUFFER_STORAGE,
-1.0, 33138.0, true},
{API_OPENGL, OS_OSX, VENDOR_INTEL, DRIVER_INTEL, Family::INTEL_SANDY, BUG_PRIMITIVE_RESTART,
-1.0, -1.0, true},
{API_OPENGL, OS_WINDOWS, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN,
BUG_BROKEN_UNSYNC_MAPPING, -1.0, -1.0, true},
{API_OPENGL, OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKEN_UNSYNC_MAPPING,
-1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_UNSYNC_MAPPING, -1.0,
-1.0, true},
{API_OPENGL, OS_WINDOWS, VENDOR_INTEL, DRIVER_INTEL, Family::UNKNOWN,
BUG_INTEL_BROKEN_BUFFER_STORAGE, 101810.3907, 101810.3960, true},
{API_OPENGL, OS_ALL, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_SLOW_GETBUFFERSUBDATA, -1.0,
-1.0, true},
{API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKEN_CLIP_DISTANCE, -1.0,
-1.0, true},
{API_OPENGL, OS_WINDOWS, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN,
BUG_BROKEN_DUAL_SOURCE_BLENDING, -1.0, -1.0, true},
{API_OPENGL, OS_OSX, VENDOR_INTEL, DRIVER_INTEL, Family::UNKNOWN,
BUG_BROKEN_DUAL_SOURCE_BLENDING, -1.0, -1.0, true},
{API_VULKAN, OS_OSX, VENDOR_INTEL, DRIVER_PORTABILITY, Family::UNKNOWN,
BUG_BROKEN_DUAL_SOURCE_BLENDING, -1.0, -1.0, true},
{API_METAL, OS_OSX, VENDOR_INTEL, DRIVER_APPLE, Family::UNKNOWN,
BUG_BROKEN_DUAL_SOURCE_BLENDING, -1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_IMGTEC, DRIVER_IMGTEC, Family::UNKNOWN,
BUG_BROKEN_BITWISE_OP_NEGATION, -1.0, 108.4693462, true},
{API_VULKAN, OS_WINDOWS, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_PRIMITIVE_RESTART, -1.0,
-1.0, true},
{API_VULKAN, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_PRIMITIVE_RESTART, -1.0, -1.0,
true},
{API_OPENGL, OS_LINUX, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN,
BUG_SHARED_CONTEXT_SHADER_COMPILATION, -1.0, -1.0, true},
{API_OPENGL, OS_LINUX, VENDOR_MESA, DRIVER_NOUVEAU, Family::UNKNOWN,
BUG_SHARED_CONTEXT_SHADER_COMPILATION, -1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, BUG_BROKEN_MSAA_CLEAR, -1.0,
-1.0, true},
{API_VULKAN, OS_ALL, VENDOR_IMGTEC, DRIVER_IMGTEC, Family::UNKNOWN,
BUG_BROKEN_CLEAR_LOADOP_RENDERPASS, -1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKEN_D32F_CLEAR,
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKEN_REVERSED_DEPTH_RANGE,
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN,
BUG_BROKEN_REVERSED_DEPTH_RANGE, -1.0, -1.0, true},
{API_VULKAN, OS_OSX, VENDOR_ALL, DRIVER_PORTABILITY, Family::UNKNOWN,
BUG_BROKEN_REVERSED_DEPTH_RANGE, -1.0, -1.0, true},
{API_METAL, OS_OSX, VENDOR_ALL, DRIVER_APPLE, Family::UNKNOWN, BUG_BROKEN_REVERSED_DEPTH_RANGE,
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_SLOW_CACHED_READBACK_MEMORY,
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN,
BUG_SLOW_CACHED_READBACK_MEMORY, -1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_VECTOR_BITWISE_AND,
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_VECTOR_BITWISE_AND,
-1.0, -1.0, true},
{API_VULKAN, OS_OSX, VENDOR_ATI, DRIVER_PORTABILITY, Family::UNKNOWN, BUG_INVERTED_IS_HELPER,
-1.0, -1.0, true},
{API_METAL, OS_OSX, VENDOR_ATI, DRIVER_APPLE, Family::UNKNOWN, BUG_INVERTED_IS_HELPER, -1.0,
-1.0, true},
{API_VULKAN, OS_OSX, VENDOR_INTEL, DRIVER_PORTABILITY, Family::UNKNOWN,
BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD, -1.0, -1.0, true},
{API_METAL, OS_OSX, VENDOR_INTEL, DRIVER_APPLE, Family::UNKNOWN,
BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD, -1.0, -1.0, true},
{API_OPENGL, OS_ANDROID, VENDOR_ALL, DRIVER_ALL, Family::UNKNOWN,
BUG_BROKEN_MULTITHREADED_SHADER_PRECOMPILATION, -1.0, -1.0, true},
{API_VULKAN, OS_ANDROID, VENDOR_ALL, DRIVER_ALL, Family::UNKNOWN,
BUG_BROKEN_MULTITHREADED_SHADER_PRECOMPILATION, -1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_PRIMITIVE_RESTART,
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_PRIMITIVE_RESTART,
-1.0, -1.0, true},
{API_VULKAN, OS_OSX, VENDOR_APPLE, DRIVER_PORTABILITY, Family::UNKNOWN,
BUG_BROKEN_DISCARD_WITH_EARLY_Z, -1.0, -1.0, true},
{API_METAL, OS_OSX, VENDOR_APPLE, DRIVER_APPLE, Family::UNKNOWN,
BUG_BROKEN_DISCARD_WITH_EARLY_Z, -1.0, -1.0, true},
{API_VULKAN, OS_OSX, VENDOR_INTEL, DRIVER_PORTABILITY, Family::UNKNOWN,
BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING, -1.0, -1.0, true},
{API_METAL, OS_OSX, VENDOR_INTEL, DRIVER_APPLE, Family::UNKNOWN,
BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING, -1.0, -1.0, true},
{API_VULKAN, OS_ANDROID, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN,
BUG_SLOW_OPTIMAL_IMAGE_TO_BUFFER_COPY, -1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_BROKEN_DEPTH_CLAMP_CONTROL,
-1.0, -1.0, true},
};
static std::map<Bug, BugInfo> m_bugs;
void Init(API api, Vendor vendor, Driver driver, const double version, const Family family,
std::string name)
{
m_api = api;
m_vendor = vendor;
m_driver = driver;
m_version = version;
m_family = family;
m_name = std::move(name);
if (driver == DRIVER_UNKNOWN)
{
switch (vendor)
{
case VENDOR_NVIDIA:
case VENDOR_TEGRA:
m_driver = DRIVER_NVIDIA;
break;
case VENDOR_ATI:
m_driver = DRIVER_ATI;
break;
case VENDOR_INTEL:
m_driver = DRIVER_INTEL;
break;
case VENDOR_IMGTEC:
m_driver = DRIVER_IMGTEC;
break;
case VENDOR_VIVANTE:
m_driver = DRIVER_VIVANTE;
break;
default:
break;
}
}
// Clear bug list, as the API may have changed
m_bugs.clear();
for (const auto& bug : m_known_bugs)
{
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) &&
(bug.m_versionend > m_version || bug.m_versionend == -1))
{
m_bugs.emplace(bug.m_bug, bug);
}
}
}
bool HasBug(Bug bug)
{
const auto it = m_bugs.find(bug);
if (it == m_bugs.end())
return false;
return it->second.m_hasbug;
}
#ifdef __clang__
// Make sure we handle all these switch cases
#pragma clang diagnostic error "-Wswitch"
#pragma clang diagnostic error "-Wcovered-switch-default"
#endif
// clang-format off
static const char* to_string(API api)
{
switch (api)
{
case API_OPENGL: return "OpenGL";
case API_VULKAN: return "Vulkan";
case API_METAL: return "Metal";
}
return "Unknown";
}
static const char* to_string(Driver driver)
{
switch (driver)
{
case DRIVER_ALL: return "All";
case DRIVER_NVIDIA: return "Nvidia";
case DRIVER_NOUVEAU: return "Nouveau";
case DRIVER_ATI: return "ATI";
case DRIVER_R600: return "R600";
case DRIVER_INTEL: return "Intel";
case DRIVER_I965: return "I965";
case DRIVER_ARM: return "ARM";
case DRIVER_LIMA: return "Lima";
case DRIVER_QUALCOMM: return "Qualcomm";
case DRIVER_FREEDRENO: return "Freedreno";
case DRIVER_IMGTEC: return "Imgtech";
case DRIVER_VIVANTE: return "Vivante";
case DRIVER_PORTABILITY: return "Portability";
case DRIVER_APPLE: return "Apple";
case DRIVER_UNKNOWN: return "Unknown";
}
return "Unknown";
}
static const char* to_string(Bug bug)
{
switch (bug)
{
case BUG_BROKEN_UBO: return "broken-ubo";
case BUG_BROKEN_PINNED_MEMORY: return "broken-pinned-memory";
case BUG_BROKEN_BUFFER_STREAM: return "broken-buffer-stream";
case BUG_BROKEN_BUFFER_STORAGE: return "broken-buffer-storage";
case BUG_PRIMITIVE_RESTART: return "primitive-restart";
case BUG_BROKEN_UNSYNC_MAPPING: return "broken-unsync-mapping";
case BUG_INTEL_BROKEN_BUFFER_STORAGE: return "intel-broken-buffer-storage";
case BUG_BROKEN_NEGATED_BOOLEAN: return "broken-negated-boolean";
case BUG_BROKEN_COPYIMAGE: return "broken-copyimage";
case BUG_BROKEN_VSYNC: return "broken-vsync";
case BUG_BROKEN_GEOMETRY_SHADERS: return "broken-geometry-shaders";
case BUG_SLOW_GETBUFFERSUBDATA: return "slow-getBufferSubData";
case BUG_BROKEN_CLIP_DISTANCE: return "broken-clip-distance";
case BUG_BROKEN_DUAL_SOURCE_BLENDING: return "broken-dual-source-blending";
case BUG_BROKEN_BITWISE_OP_NEGATION: return "broken-bitwise-op-negation";
case BUG_SHARED_CONTEXT_SHADER_COMPILATION: return "shared-context-shader-compilation";
case BUG_BROKEN_MSAA_CLEAR: return "broken-msaa-clear";
case BUG_BROKEN_CLEAR_LOADOP_RENDERPASS: return "broken-clear-loadop-renderpass";
case BUG_BROKEN_D32F_CLEAR: return "broken-d32f-clear";
case BUG_BROKEN_REVERSED_DEPTH_RANGE: return "broken-reversed-depth-range";
case BUG_SLOW_CACHED_READBACK_MEMORY: return "slow-cached-readback-memory";
case BUG_BROKEN_VECTOR_BITWISE_AND: return "broken-vector-bitwise-and";
case BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD: return "broken-subgroup-ops-with-discard";
case BUG_INVERTED_IS_HELPER: return "inverted-is-helper";
case BUG_BROKEN_MULTITHREADED_SHADER_PRECOMPILATION: return "broken-multithreaded-shader-precompilation";
case BUG_BROKEN_DISCARD_WITH_EARLY_Z: return "broken-discard-with-early-z";
case BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING: return "broken-dynamic-sampler-indexing";
case BUG_SLOW_OPTIMAL_IMAGE_TO_BUFFER_COPY: return "slow-optimal-image-to-buffer-copy";
case BUG_BROKEN_DEPTH_CLAMP_CONTROL: return "broken-depth-clamp-control";
}
return "Unknown";
}
// clang-format on
void OverrideBug(Bug bug, bool new_value)
{
const auto [it, added] = m_bugs.try_emplace(
bug, BugInfo{m_api, m_os, m_vendor, m_driver, m_family, bug, -1, -1, false});
if (it->second.m_hasbug != new_value)
{
DolphinAnalytics& analytics = DolphinAnalytics::Instance();
Common::AnalyticsReportBuilder builder(analytics.BaseBuilder());
builder.AddData("type", "gpu-bug-override");
builder.AddData("bug", to_string(bug));
builder.AddData("value", new_value);
builder.AddData("gpu", m_name);
builder.AddData("api", to_string(m_api));
builder.AddData("driver", to_string(m_driver));
builder.AddData("version", std::to_string(m_version));
analytics.Send(builder);
it->second.m_hasbug = new_value;
}
}
} // namespace DriverDetails
|