mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 13:44:32 +02:00
Merge pull request #1413 from HifiExperiments/driverBlocklist
add GPU driver blocklist
This commit is contained in:
commit
6aa7030af3
3 changed files with 124 additions and 1 deletions
|
@ -42,6 +42,7 @@
|
||||||
#include <DomainAccountManager.h>
|
#include <DomainAccountManager.h>
|
||||||
#include <EntityScriptServerLogClient.h>
|
#include <EntityScriptServerLogClient.h>
|
||||||
#include <FramebufferCache.h>
|
#include <FramebufferCache.h>
|
||||||
|
#include <gl/GLHelpers.h>
|
||||||
#include <GPUIdent.h>
|
#include <GPUIdent.h>
|
||||||
#include <graphics-scripting/GraphicsScriptingInterface.h>
|
#include <graphics-scripting/GraphicsScriptingInterface.h>
|
||||||
#include <hfm/ModelFormatRegistry.h>
|
#include <hfm/ModelFormatRegistry.h>
|
||||||
|
@ -56,6 +57,9 @@
|
||||||
#include <networking/CloseEventSender.h>
|
#include <networking/CloseEventSender.h>
|
||||||
#include <OffscreenUi.h>
|
#include <OffscreenUi.h>
|
||||||
#include <PickManager.h>
|
#include <PickManager.h>
|
||||||
|
#include <platform/Platform.h>
|
||||||
|
#include <platform/PlatformKeys.h>
|
||||||
|
#include <platform/backend/PlatformInstance.h>
|
||||||
#include <plugins/OculusPlatformPlugin.h>
|
#include <plugins/OculusPlatformPlugin.h>
|
||||||
#include <plugins/PluginManager.h>
|
#include <plugins/PluginManager.h>
|
||||||
#include <plugins/PluginUtils.h>
|
#include <plugins/PluginUtils.h>
|
||||||
|
@ -1890,13 +1894,32 @@ void Application::idle() {
|
||||||
|
|
||||||
_gameLoopCounter.increment();
|
_gameLoopCounter.increment();
|
||||||
|
|
||||||
|
// Perform one-time startup checks in case we need to show warnings
|
||||||
{
|
{
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, [] {
|
std::call_once(once, [this] {
|
||||||
const QString& bookmarksError = DependencyManager::get<AvatarBookmarks>()->getBookmarkError();
|
const QString& bookmarksError = DependencyManager::get<AvatarBookmarks>()->getBookmarkError();
|
||||||
if (!bookmarksError.isEmpty()) {
|
if (!bookmarksError.isEmpty()) {
|
||||||
OffscreenUi::asyncWarning("Avatar Bookmarks Error", "JSON parse error: " + bookmarksError, QMessageBox::Ok, QMessageBox::Ok);
|
OffscreenUi::asyncWarning("Avatar Bookmarks Error", "JSON parse error: " + bookmarksError, QMessageBox::Ok, QMessageBox::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString os = platform::getComputer()[platform::keys::computer::OS].dump().c_str();
|
||||||
|
os = os.replace("\"", "");
|
||||||
|
GPUIdent* gpuIdent = GPUIdent::getInstance();
|
||||||
|
QString vendor = platform::Instance::findGPUVendorInDescription(gpuIdent->getName().toStdString());
|
||||||
|
QString renderer = gl::ContextInfo::get().renderer.c_str();
|
||||||
|
QString api = _graphicsEngine->getGPUContext()->getBackendVersion().c_str();
|
||||||
|
QString driver = gpuIdent->getDriver();
|
||||||
|
QString fullDriverToTest = os + " " + vendor + " " + renderer + " " + api + " " + driver;
|
||||||
|
if (fullDriverToTest != _prevCheckedDriver.get()) {
|
||||||
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
QNetworkRequest request(QUrl("https://mv.overte.org/gpu_driver_blocklist.json"));
|
||||||
|
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||||
|
request.setHeader(QNetworkRequest::UserAgentHeader, NetworkingConstants::OVERTE_USER_AGENT);
|
||||||
|
QNetworkReply* reply = networkAccessManager.get(request);
|
||||||
|
auto onFinished = std::bind(&Application::processDriverBlocklistReply, this, fullDriverToTest, os, vendor, renderer, api, driver.replace(" ", "."));
|
||||||
|
connect(reply, &QNetworkReply::finished, this, onFinished);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -655,6 +655,9 @@ private:
|
||||||
bool handleKeyEventForFocusedEntity(QEvent* event);
|
bool handleKeyEventForFocusedEntity(QEvent* event);
|
||||||
bool handleFileOpenEvent(QFileOpenEvent* event);
|
bool handleFileOpenEvent(QFileOpenEvent* event);
|
||||||
|
|
||||||
|
void processDriverBlocklistReply(const QString& fullDriverToTest, const QString& os, const QString& vendor, const QString& renderer, const QString& api,
|
||||||
|
const QString& driver);
|
||||||
|
|
||||||
|
|
||||||
// Entities
|
// Entities
|
||||||
void queryOctree(NodeType_t serverType, PacketType packetType);
|
void queryOctree(NodeType_t serverType, PacketType packetType);
|
||||||
|
@ -906,6 +909,7 @@ private:
|
||||||
std::shared_ptr<GraphicsEngine> _graphicsEngine;
|
std::shared_ptr<GraphicsEngine> _graphicsEngine;
|
||||||
glm::uvec2 _renderResolution;
|
glm::uvec2 _renderResolution;
|
||||||
|
|
||||||
|
Setting::Handle<QString> _prevCheckedDriver { "prevCheckedDriver", "" };
|
||||||
bool _isGLInitialized { false };
|
bool _isGLInitialized { false };
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -929,3 +929,99 @@ bool Application::handleFileOpenEvent(QFileOpenEvent* fileEvent) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::processDriverBlocklistReply(const QString& fullDriverToTest, const QString& os, const QString& vendor, const QString& renderer, const QString& api,
|
||||||
|
const QString& driver) {
|
||||||
|
// The driver blocklist is a JSON array of objects where each object contains:
|
||||||
|
// - os (e.g. Windows, Linux): The system OS
|
||||||
|
// - vendor (e.g. NVIDIA, AMD): The GPU maker
|
||||||
|
// - renderer (optional) (e.g. AMD, Panfrost): The driver stack, if specified
|
||||||
|
// - api (e.g GL45, GLES): The backend version
|
||||||
|
// - version (optional) (e.g. 32.0.15.6070): The driver version, if just a single version is problematic
|
||||||
|
// - first_version (optional) (e.g. 32.0.15.6070): If a range is problematic, the first problematic version
|
||||||
|
// - last_version (optional) (e.g. 32.0.15.6070): If a range is problematic, the final problematic version. If this is not provided,
|
||||||
|
// all versions above first_version will trigger a warning.
|
||||||
|
// - description: Description of the issue.
|
||||||
|
// String values are *case insensitive*
|
||||||
|
QNetworkReply* reply = static_cast<QNetworkReply*>(sender());
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument json = QJsonDocument::fromJson(data, &error);
|
||||||
|
if (json.isNull() || !json.isArray()) {
|
||||||
|
OffscreenUi::asyncWarning("Driver Blocklist Error", "There is a problem with the GPU driver blocklist: " + error.errorString(),
|
||||||
|
QMessageBox::Ok, QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
_prevCheckedDriver.set(fullDriverToTest);
|
||||||
|
|
||||||
|
QJsonArray driverArray = json.array();
|
||||||
|
for (QJsonValueRef driverJSON : driverArray) {
|
||||||
|
if (!driverJSON.isObject()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject driverObject = driverJSON.toObject();
|
||||||
|
if (os.toLower() != driverObject["os"].toString().toLower()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (vendor.toLower() != driverObject["vendor"].toString().toLower()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (driverObject.contains("renderer")) {
|
||||||
|
if (renderer.toLower().contains(driverObject["renderer"].toString().toLower())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (api.toLower() != driverObject["api"].toString().toLower()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString minDriver;
|
||||||
|
QString maxDriver;
|
||||||
|
|
||||||
|
if (driverObject.contains("version")) {
|
||||||
|
QString driverString = driverObject["version"].toString();
|
||||||
|
minDriver = driverString;
|
||||||
|
maxDriver = driverString;
|
||||||
|
} else {
|
||||||
|
minDriver = driverObject["first_version"].toString();
|
||||||
|
|
||||||
|
if (driverObject.contains("last_version")) {
|
||||||
|
QString driverString = driverObject["last_version"].toString();
|
||||||
|
maxDriver = driverString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minDriver = minDriver.replace(" ", ".");
|
||||||
|
maxDriver = maxDriver.replace(" ", ".");
|
||||||
|
|
||||||
|
const auto compareDriver = [] (const QStringList& driver1, const QStringList& driver2, std::function<bool(int, int)> func) {
|
||||||
|
if (driver1.size() != driver2.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < driver1.size(); i++) {
|
||||||
|
if (!func(driver1[i].toInt(), driver2[i].toInt())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
QStringList driverParts = driver.split(".");
|
||||||
|
bool inErrorRange = compareDriver(driverParts, minDriver.split("."), [] (int driverPart1, int driverPart2) { return driverPart1 >= driverPart2; });
|
||||||
|
if (!maxDriver.isEmpty()) {
|
||||||
|
inErrorRange &= compareDriver(driverParts, maxDriver.split("."), [] (int driverPart1, int driverPart2) { return driverPart1 <= driverPart2; });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inErrorRange) {
|
||||||
|
QString issue = driverObject["description"].toString();
|
||||||
|
OffscreenUi::asyncWarning(
|
||||||
|
"GPU Driver Warning", "Your GPU driver (" + driver + ") has been reported as problematic (Issue: " + issue + "). If you encounter issues, consider trying a different version.",
|
||||||
|
QMessageBox::Ok, QMessageBox::Ok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue