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 <EntityScriptServerLogClient.h>
|
||||
#include <FramebufferCache.h>
|
||||
#include <gl/GLHelpers.h>
|
||||
#include <GPUIdent.h>
|
||||
#include <graphics-scripting/GraphicsScriptingInterface.h>
|
||||
#include <hfm/ModelFormatRegistry.h>
|
||||
|
@ -56,6 +57,9 @@
|
|||
#include <networking/CloseEventSender.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <PickManager.h>
|
||||
#include <platform/Platform.h>
|
||||
#include <platform/PlatformKeys.h>
|
||||
#include <platform/backend/PlatformInstance.h>
|
||||
#include <plugins/OculusPlatformPlugin.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <plugins/PluginUtils.h>
|
||||
|
@ -1890,13 +1894,32 @@ void Application::idle() {
|
|||
|
||||
_gameLoopCounter.increment();
|
||||
|
||||
// Perform one-time startup checks in case we need to show warnings
|
||||
{
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [] {
|
||||
std::call_once(once, [this] {
|
||||
const QString& bookmarksError = DependencyManager::get<AvatarBookmarks>()->getBookmarkError();
|
||||
if (!bookmarksError.isEmpty()) {
|
||||
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 handleFileOpenEvent(QFileOpenEvent* event);
|
||||
|
||||
void processDriverBlocklistReply(const QString& fullDriverToTest, const QString& os, const QString& vendor, const QString& renderer, const QString& api,
|
||||
const QString& driver);
|
||||
|
||||
|
||||
// Entities
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType);
|
||||
|
@ -906,6 +909,7 @@ private:
|
|||
std::shared_ptr<GraphicsEngine> _graphicsEngine;
|
||||
glm::uvec2 _renderResolution;
|
||||
|
||||
Setting::Handle<QString> _prevCheckedDriver { "prevCheckedDriver", "" };
|
||||
bool _isGLInitialized { false };
|
||||
|
||||
|
||||
|
|
|
@ -929,3 +929,99 @@ bool Application::handleFileOpenEvent(QFileOpenEvent* fileEvent) {
|
|||
}
|
||||
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