ogl: rework DriverDetails framework + detect UBO mesa bug
This commit is contained in:
parent
d9485cbf23
commit
7a5374258e
|
@ -11,8 +11,9 @@ namespace DriverDetails
|
||||||
{
|
{
|
||||||
struct BugInfo
|
struct BugInfo
|
||||||
{
|
{
|
||||||
|
Vendor m_vendor; // which vendor has the error
|
||||||
|
Driver m_driver; // which driver has the error
|
||||||
Bug m_bug; // Which bug it is
|
Bug m_bug; // Which bug it is
|
||||||
u32 m_devfamily; // Which device(family) has the error
|
|
||||||
double m_versionstart; // When it started
|
double m_versionstart; // When it started
|
||||||
double m_versionend; // When it ended
|
double m_versionend; // When it ended
|
||||||
bool m_hasbug; // Does it have it?
|
bool m_hasbug; // Does it have it?
|
||||||
|
@ -21,40 +22,27 @@ namespace DriverDetails
|
||||||
// Local members
|
// Local members
|
||||||
Vendor m_vendor = VENDOR_UNKNOWN;
|
Vendor m_vendor = VENDOR_UNKNOWN;
|
||||||
Driver m_driver = DRIVER_UNKNOWN;
|
Driver m_driver = DRIVER_UNKNOWN;
|
||||||
u32 m_devfamily = 0;
|
|
||||||
double m_version = 0.0;
|
double m_version = 0.0;
|
||||||
|
|
||||||
// This is a list of all known bugs for each vendor
|
// This is a list of all known bugs for each vendor
|
||||||
// We use this to check if the device and driver has a issue
|
// We use this to check if the device and driver has a issue
|
||||||
BugInfo m_qualcommbugs[] = {
|
BugInfo m_known_bugs[] = {
|
||||||
{BUG_NODYNUBOACCESS, 300, 14.0, -1.0},
|
{VENDOR_QUALCOMM, DRIVER_QUALCOMM_3XX, BUG_NODYNUBOACCESS, 14.0, -1.0, true},
|
||||||
{BUG_BROKENCENTROID, 300, 14.0, -1.0},
|
{VENDOR_QUALCOMM, DRIVER_QUALCOMM_3XX, BUG_BROKENCENTROID, 14.0, -1.0, true},
|
||||||
{BUG_BROKENINFOLOG, 300, -1.0, -1.0},
|
{VENDOR_QUALCOMM, DRIVER_QUALCOMM_3XX, BUG_BROKENINFOLOG, -1.0, -1.0, true},
|
||||||
|
{VENDOR_MESA, DRIVER_NOUVEAU, BUG_BROKENUBO, 900, 916, true},
|
||||||
|
{VENDOR_MESA, DRIVER_R600, BUG_BROKENUBO, 900, 913, true},
|
||||||
|
{VENDOR_MESA, DRIVER_I965, BUG_BROKENUBO, 900, 920, true},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<std::pair<Vendor, Bug>, BugInfo> m_bugs;
|
std::map<Bug, BugInfo> m_bugs;
|
||||||
|
|
||||||
// Private function
|
|
||||||
void InitBugMap()
|
|
||||||
{
|
|
||||||
switch(m_driver)
|
|
||||||
{
|
|
||||||
case DRIVER_QUALCOMM:
|
|
||||||
for (unsigned int a = 0; a < (sizeof(m_qualcommbugs) / sizeof(BugInfo)); ++a)
|
|
||||||
m_bugs[std::make_pair(m_vendor, m_qualcommbugs[a].m_bug)] = m_qualcommbugs[a];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init(Vendor vendor, Driver driver, const u32 devfamily, const double version)
|
void Init(Vendor vendor, Driver driver, const double version)
|
||||||
{
|
{
|
||||||
m_vendor = vendor;
|
m_vendor = vendor;
|
||||||
m_driver = driver;
|
m_driver = driver;
|
||||||
m_devfamily = devfamily;
|
|
||||||
m_version = version;
|
m_version = version;
|
||||||
InitBugMap();
|
|
||||||
if (driver == DRIVER_UNKNOWN)
|
if (driver == DRIVER_UNKNOWN)
|
||||||
switch(vendor)
|
switch(vendor)
|
||||||
{
|
{
|
||||||
|
@ -68,12 +56,6 @@ namespace DriverDetails
|
||||||
case VENDOR_INTEL:
|
case VENDOR_INTEL:
|
||||||
m_driver = DRIVER_INTEL;
|
m_driver = DRIVER_INTEL;
|
||||||
break;
|
break;
|
||||||
case VENDOR_ARM:
|
|
||||||
m_driver = DRIVER_ARM;
|
|
||||||
break;
|
|
||||||
case VENDOR_QUALCOMM:
|
|
||||||
m_driver = DRIVER_QUALCOMM;
|
|
||||||
break;
|
|
||||||
case VENDOR_IMGTEC:
|
case VENDOR_IMGTEC:
|
||||||
m_driver = DRIVER_IMGTEC;
|
m_driver = DRIVER_IMGTEC;
|
||||||
break;
|
break;
|
||||||
|
@ -83,16 +65,22 @@ namespace DriverDetails
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = m_bugs.begin(); it != m_bugs.end(); ++it)
|
for(unsigned int a = 0; a < (sizeof(m_known_bugs) / sizeof(BugInfo)); ++a)
|
||||||
if (it->second.m_devfamily == m_devfamily)
|
{
|
||||||
if (it->second.m_versionend == -1.0 || (it->second.m_versionstart <= m_version && it->second.m_versionend > m_version))
|
if(
|
||||||
it->second.m_hasbug = true;
|
( m_known_bugs[a].m_vendor == m_vendor || m_known_bugs[a].m_vendor == VENDOR_ALL ) &&
|
||||||
|
( m_known_bugs[a].m_driver == m_driver || m_known_bugs[a].m_driver == DRIVER_ALL ) &&
|
||||||
|
( m_known_bugs[a].m_versionstart <= m_version || m_known_bugs[a].m_versionstart == -1 ) &&
|
||||||
|
( m_known_bugs[a].m_versionend > m_version || m_known_bugs[a].m_versionend == -1 )
|
||||||
|
)
|
||||||
|
m_bugs.insert(std::make_pair(m_known_bugs[a].m_bug, m_known_bugs[a]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasBug(Bug bug)
|
bool HasBug(Bug bug)
|
||||||
{
|
{
|
||||||
auto it = m_bugs.find(std::make_pair(m_vendor, bug));
|
auto it = m_bugs.find(bug);
|
||||||
if (it == m_bugs.end())
|
if (it == m_bugs.end())
|
||||||
return false;
|
return false;
|
||||||
return it->second.m_hasbug;
|
return it->second.m_hasbug;
|
||||||
|
|
|
@ -10,7 +10,8 @@ namespace DriverDetails
|
||||||
// Tegra and Nvidia are separated out due to such substantial differences
|
// Tegra and Nvidia are separated out due to such substantial differences
|
||||||
enum Vendor
|
enum Vendor
|
||||||
{
|
{
|
||||||
VENDOR_NVIDIA = 0,
|
VENDOR_ALL = 0,
|
||||||
|
VENDOR_NVIDIA,
|
||||||
VENDOR_ATI,
|
VENDOR_ATI,
|
||||||
VENDOR_INTEL,
|
VENDOR_INTEL,
|
||||||
VENDOR_ARM,
|
VENDOR_ARM,
|
||||||
|
@ -18,20 +19,25 @@ namespace DriverDetails
|
||||||
VENDOR_IMGTEC,
|
VENDOR_IMGTEC,
|
||||||
VENDOR_TEGRA,
|
VENDOR_TEGRA,
|
||||||
VENDOR_VIVANTE,
|
VENDOR_VIVANTE,
|
||||||
|
VENDOR_MESA,
|
||||||
VENDOR_UNKNOWN
|
VENDOR_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enum of known drivers
|
// Enum of known drivers
|
||||||
enum Driver
|
enum Driver
|
||||||
{
|
{
|
||||||
DRIVER_NVIDIA = 0, // Official Nvidia, including mobile GPU
|
DRIVER_ALL = 0,
|
||||||
|
DRIVER_NVIDIA, // Official Nvidia, including mobile GPU
|
||||||
DRIVER_NOUVEAU, // OSS nouveau
|
DRIVER_NOUVEAU, // OSS nouveau
|
||||||
DRIVER_ATI, // Official ATI
|
DRIVER_ATI, // Official ATI
|
||||||
DRIVER_RADEONHD, // OSS Radeon
|
DRIVER_R600, // OSS Radeon
|
||||||
DRIVER_INTEL, // Official Intel
|
DRIVER_INTEL, // Official Intel
|
||||||
DRIVER_ARM, // Official Mali driver
|
DRIVER_I965, // OSS Intel
|
||||||
|
DRIVER_ARM_4XX, // Official Mali driver
|
||||||
|
DRIVER_ARM_T6XX, // Official Mali driver
|
||||||
DRIVER_LIMA, // OSS Mali driver
|
DRIVER_LIMA, // OSS Mali driver
|
||||||
DRIVER_QUALCOMM, // Official Adreno driver
|
DRIVER_QUALCOMM_3XX, // Official Adreno driver 3xx
|
||||||
|
DRIVER_QUALCOMM_2XX, // Official Adreno driver 2xx
|
||||||
DRIVER_FREEDRENO, // OSS Adreno driver
|
DRIVER_FREEDRENO, // OSS Adreno driver
|
||||||
DRIVER_IMGTEC, // OSS PowerVR driver
|
DRIVER_IMGTEC, // OSS PowerVR driver
|
||||||
DRIVER_VIVANTE, // Official vivante driver
|
DRIVER_VIVANTE, // Official vivante driver
|
||||||
|
@ -69,10 +75,18 @@ namespace DriverDetails
|
||||||
// Adreno devices /always/ return 0 when querying GL_INFO_LOG_LENGTH
|
// Adreno devices /always/ return 0 when querying GL_INFO_LOG_LENGTH
|
||||||
// They also max out at 1024 bytes(1023 characters + null terminator) for the log
|
// They also max out at 1024 bytes(1023 characters + null terminator) for the log
|
||||||
BUG_BROKENINFOLOG,
|
BUG_BROKENINFOLOG,
|
||||||
|
// Bug: UBO buffer offset broken
|
||||||
|
// Affected devices: all mesa drivers
|
||||||
|
// Started Version: 9.0 (mesa doesn't support ubo before)
|
||||||
|
// Ended Version: up to 9.2
|
||||||
|
// The offset of glBindBufferRange was ignored on all Mesa Gallium3D drivers until 9.1.3
|
||||||
|
// Nouveau stored the offset as u16 which isn't enough for all cases with range until 9.1.6
|
||||||
|
// I965 has broken data fetches from uniform buffers which results in a dithering until 9.2.0
|
||||||
|
BUG_BROKENUBO,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initializes our internal vendor, device family, and driver version
|
// Initializes our internal vendor, device family, and driver version
|
||||||
void Init(Vendor vendor, Driver driver, const u32 devfamily, const double version);
|
void Init(Vendor vendor, Driver driver, const double version);
|
||||||
|
|
||||||
// Once Vendor and driver version is set, this will return if it has the applicable bug passed to it.
|
// Once Vendor and driver version is set, this will return if it has the applicable bug passed to it.
|
||||||
bool HasBug(Bug bug);
|
bool HasBug(Bug bug);
|
||||||
|
|
|
@ -538,8 +538,8 @@ void ProgramShaderCache::CreateHeader ( void )
|
||||||
|
|
||||||
, v==GLSL_120 ? "attribute" : "in"
|
, v==GLSL_120 ? "attribute" : "in"
|
||||||
, v==GLSL_120 ? "attribute" : "out"
|
, v==GLSL_120 ? "attribute" : "out"
|
||||||
, DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "in" : v==GLSL_120 ? "varying" : "centroid in"
|
, v==GLSL_120 ? "varying" : DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "in" : "centroid in"
|
||||||
, DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "out" : v==GLSL_120 ? "varying" : "centroid out"
|
, v==GLSL_120 ? "varying" : DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "out" : "centroid out"
|
||||||
|
|
||||||
, v==GLSL_120 ? "#define texture texture2D" : ""
|
, v==GLSL_120 ? "#define texture texture2D" : ""
|
||||||
, v==GLSL_120 ? "#define round(x) floor((x)+0.5f)" : ""
|
, v==GLSL_120 ? "#define round(x) floor((x)+0.5f)" : ""
|
||||||
|
|
|
@ -271,9 +271,9 @@ void InitDriverInfo()
|
||||||
{
|
{
|
||||||
std::string svendor = std::string(g_ogl_config.gl_vendor);
|
std::string svendor = std::string(g_ogl_config.gl_vendor);
|
||||||
std::string srenderer = std::string(g_ogl_config.gl_renderer);
|
std::string srenderer = std::string(g_ogl_config.gl_renderer);
|
||||||
|
std::string sversion = std::string(g_ogl_config.gl_version);
|
||||||
DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
|
DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
|
||||||
DriverDetails::Driver driver = DriverDetails::DRIVER_UNKNOWN;
|
DriverDetails::Driver driver = DriverDetails::DRIVER_UNKNOWN;
|
||||||
u32 devfamily = 0;
|
|
||||||
double version = 0.0;
|
double version = 0.0;
|
||||||
|
|
||||||
// Get the vendor first
|
// Get the vendor first
|
||||||
|
@ -281,13 +281,12 @@ void InitDriverInfo()
|
||||||
vendor = DriverDetails::VENDOR_NVIDIA;
|
vendor = DriverDetails::VENDOR_NVIDIA;
|
||||||
else if (svendor == "ATI Technologies Inc." || svendor == "Advanced Micro Devices, Inc.")
|
else if (svendor == "ATI Technologies Inc." || svendor == "Advanced Micro Devices, Inc.")
|
||||||
vendor = DriverDetails::VENDOR_ATI;
|
vendor = DriverDetails::VENDOR_ATI;
|
||||||
|
else if (std::string::npos != sversion.find("Mesa"))
|
||||||
|
vendor = DriverDetails::VENDOR_MESA;
|
||||||
else if (std::string::npos != svendor.find("Intel"))
|
else if (std::string::npos != svendor.find("Intel"))
|
||||||
vendor = DriverDetails::VENDOR_INTEL;
|
vendor = DriverDetails::VENDOR_INTEL;
|
||||||
else if (svendor == "ARM")
|
else if (svendor == "ARM")
|
||||||
{
|
|
||||||
vendor = DriverDetails::VENDOR_ARM;
|
vendor = DriverDetails::VENDOR_ARM;
|
||||||
driver = DriverDetails::DRIVER_ARM;
|
|
||||||
}
|
|
||||||
else if (svendor == "http://limadriver.org/")
|
else if (svendor == "http://limadriver.org/")
|
||||||
{
|
{
|
||||||
vendor = DriverDetails::VENDOR_ARM;
|
vendor = DriverDetails::VENDOR_ARM;
|
||||||
|
@ -308,24 +307,40 @@ void InitDriverInfo()
|
||||||
case DriverDetails::VENDOR_QUALCOMM:
|
case DriverDetails::VENDOR_QUALCOMM:
|
||||||
{
|
{
|
||||||
if (std::string::npos != srenderer.find("Adreno (TM) 3"))
|
if (std::string::npos != srenderer.find("Adreno (TM) 3"))
|
||||||
devfamily = 300;
|
driver = DriverDetails::DRIVER_QUALCOMM_3XX;
|
||||||
else
|
else
|
||||||
devfamily = 200;
|
driver = DriverDetails::DRIVER_QUALCOMM_2XX;
|
||||||
double glVersion;
|
double glVersion;
|
||||||
sscanf(g_ogl_config.gl_version, "OpenGL ES %lg V@%lg", &glVersion, &version);
|
sscanf(g_ogl_config.gl_version, "OpenGL ES %lg V@%lg", &glVersion, &version);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DriverDetails::VENDOR_ARM:
|
case DriverDetails::VENDOR_ARM:
|
||||||
if (std::string::npos != srenderer.find("Mali-T6"))
|
if (std::string::npos != srenderer.find("Mali-T6"))
|
||||||
devfamily = 600;
|
driver = DriverDetails::DRIVER_ARM_T6XX;
|
||||||
else if(std::string::npos != srenderer.find("Mali-4"))
|
else if(std::string::npos != srenderer.find("Mali-4"))
|
||||||
devfamily = 400;
|
driver = DriverDetails::DRIVER_ARM_4XX;
|
||||||
|
break;
|
||||||
|
case DriverDetails::VENDOR_MESA:
|
||||||
|
{
|
||||||
|
if(svendor == "nouveau")
|
||||||
|
driver = DriverDetails::DRIVER_NOUVEAU;
|
||||||
|
else if(svendor == "Intel Open Source Technology Center")
|
||||||
|
driver = DriverDetails::DRIVER_I965;
|
||||||
|
else if(std::string::npos != srenderer.find("AMD") || std::string::npos != srenderer.find("ATI"))
|
||||||
|
driver = DriverDetails::DRIVER_R600;
|
||||||
|
|
||||||
|
int major = 0;
|
||||||
|
int minor = 0;
|
||||||
|
int release = 0;
|
||||||
|
sscanf(g_ogl_config.gl_version, "%*s Mesa %d.%d.%d", &major, &minor, &release);
|
||||||
|
version = 100*major + 10*minor + release;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// We don't care about these
|
// We don't care about these
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DriverDetails::Init(vendor, driver, devfamily, version);
|
DriverDetails::Init(vendor, driver, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init functions
|
// Init functions
|
||||||
|
@ -491,18 +506,12 @@ Renderer::Renderer()
|
||||||
if(g_ogl_config.max_samples < 1)
|
if(g_ogl_config.max_samples < 1)
|
||||||
g_ogl_config.max_samples = 1;
|
g_ogl_config.max_samples = 1;
|
||||||
|
|
||||||
if(g_Config.backend_info.bSupportsGLSLUBO && (
|
if(g_Config.backend_info.bSupportsGLSLUBO && DriverDetails::HasBug(DriverDetails::BUG_BROKENUBO))
|
||||||
// hd3000 get corruption, hd4000 also and a big slowdown
|
{
|
||||||
!strcmp(g_ogl_config.gl_vendor, "Intel Open Source Technology Center") && (
|
|
||||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.0") ||
|
|
||||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.1") ||
|
|
||||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.2") ||
|
|
||||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.3") ||
|
|
||||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.1.0") ||
|
|
||||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.1.1") )
|
|
||||||
)) {
|
|
||||||
g_Config.backend_info.bSupportsGLSLUBO = false;
|
g_Config.backend_info.bSupportsGLSLUBO = false;
|
||||||
ERROR_LOG(VIDEO, "Buggy driver detected. Disable UBO");
|
ERROR_LOG(VIDEO, "Buggy driver detected. Disable UBO");
|
||||||
|
OSD::AddMessage("Major performance warning: Buggy GPU driver detected.", 20000);
|
||||||
|
OSD::AddMessage("Please either install the closed-source GPU driver or update your Mesa 3D version.", 20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
|
Loading…
Reference in New Issue