Browse Source

GL: make use of unmasked renderer string in Context::detectedDriver().

pull/240/head
Vladimír Vondruš 5 years ago
parent
commit
7ad928ae42
  1. 3
      doc/changelog.dox
  2. 4
      src/Magnum/GL/Context.cpp
  3. 41
      src/Magnum/GL/Context.h
  4. 66
      src/Magnum/GL/Implementation/driverSpecific.cpp

3
doc/changelog.dox

@ -88,7 +88,8 @@ See also:
- Implemented @webgl_extension{WEBGL,debug_renderer_info} as
@ref GL::Context::rendererStringUnmasked() and
@relativeref{GL::Context,vendorStringUnmasked()} together with printing
those in the engine startup log if the extension is available. It also
those in the engine startup log if the extension is available and expanding
the capabilities of @ref GL::Context::detectedDriver() on WebGL. It also
resulted in a new @cpp "firefox-deprecated-debug-renderer-info" @ce
workaround being added, see @ref opengl-workarounds for more info.
- Recognizing @webgl_extension{EXT,float_blend} and

4
src/Magnum/GL/Context.cpp

@ -1317,13 +1317,10 @@ Debug& operator<<(Debug& debug, const Context::DetectedDriver value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case Context::DetectedDriver::value: return debug << "::" #value;
#ifndef MAGNUM_TARGET_WEBGL
_c(Amd)
#endif
#ifdef MAGNUM_TARGET_GLES
_c(Angle)
#endif
#ifndef MAGNUM_TARGET_WEBGL
_c(IntelWindows)
_c(Mesa)
_c(NVidia)
@ -1331,7 +1328,6 @@ Debug& operator<<(Debug& debug, const Context::DetectedDriver value) {
#ifdef MAGNUM_TARGET_GLES
_c(SwiftShader)
#endif
#endif
#ifdef CORRADE_TARGET_ANDROID
_c(ArmMali)
#endif

41
src/Magnum/GL/Context.h

@ -409,54 +409,45 @@ class MAGNUM_GL_EXPORT Context {
/**
* @brief Detected driver
*
* @see @ref DetectedDriver, @ref detectedDriver()
* On WebGL, if @webgl_extension{WEBGL,debug_renderer_info} is not
* available and the browser doesn't report the real values through
* @ref vendorString() and @ref rendererString(), driver detection can
* be performed only for limited cases --- see documentation of
* particular values for more information.
* @see @ref DetectedDrivers, @ref detectedDriver()
*/
enum class DetectedDriver: UnsignedShort {
#ifndef MAGNUM_TARGET_WEBGL
/**
* Proprietary AMD desktop drivers on Windows and Linux. In
* contrast, AMDGPU Mesa drivers report as
* @ref DetectedDriver::Mesa instead.
* @requires_gles Not detectable on WebGL, as browsers
* intentionally hide most of the driver information.
*/
Amd = 1 << 0,
#endif
#if defined(MAGNUM_TARGET_GLES) || defined(DOXYGEN_GENERATING_OUTPUT)
/**
* OpenGL ES implementation by ANGLE (translated to D3D), used by
* browsers on Windows for WebGL. As the WebGL specification
* explicitly disallows exposing driver information to the
* application, this check cannot be done reliably. See also
* @ref DetectedDriver::SwiftShader.
* browsers on Windows for WebGL. See also
* @ref DetectedDriver::SwiftShader. On WebGL, if
* @webgl_extension{WEBGL,debug_renderer_info} is not available,
* the detection is done by checking if the line size range is just
* 1, which is always the case on D3D but not always on GL.
* @requires_gles ANGLE doesn't support desktop OpenGL contexts.
*/
Angle = 1 << 1,
#endif
#ifndef MAGNUM_TARGET_WEBGL
/**
* Intel desktop drivers on Windows
* @requires_gles Not detectable on WebGL, as browsers
* intentionally hide most of the driver information.
*/
/** Intel desktop drivers on Windows */
IntelWindows = 1 << 2,
/**
* Mesa drivers on Windows and Linux. In particular, Intel, AMD
* and NVidia Mesa drivers match as this. See also
* @ref DetectedDriver::Svga3D.
* @requires_gles Not detectable on WebGL, as browsers
* intentionally hide most of the driver information.
*/
Mesa = 1 << 3,
/**
* Proprietary NVidia drivers on Windows and Linux
* @requires_gles Not detectable on WebGL, as browsers
* intentionally hide most of the driver information.
*/
/** Proprietary NVidia drivers on Windows and Linux */
NVidia = 1 << 4,
/**
@ -464,8 +455,6 @@ class MAGNUM_GL_EXPORT Context {
* Windows and Linux guests. See https://www.mesa3d.org/vmware-guest.html
* for more information. Detected in combination with
* @ref DetectedDriver::Mesa.
* @requires_gles Not detectable on WebGL, as browsers
* intentionally hide most of the driver information.
*/
Svga3D = 1 << 5,
@ -475,13 +464,11 @@ class MAGNUM_GL_EXPORT Context {
* renderer for OpenGL ES. Usually used by browsers in cases where
* a GPU isn't available. See also @ref DetectedDriver::Angle.
* @requires_gles SwiftShader doesn't support desktop OpenGL
* contexts. Not detectable on WebGL, as browsers
* intentionally hide most of the driver information.
* contexts.
* @m_since{2019,10}
*/
SwiftShader = 1 << 6,
#endif
#endif
#if defined(CORRADE_TARGET_ANDROID) || defined(DOXYGEN_GENERATING_OUTPUT)
/**

66
src/Magnum/GL/Implementation/driverSpecific.cpp

@ -429,68 +429,90 @@ auto Context::detectedDriver() -> DetectedDrivers {
_detectedDrivers = DetectedDrivers{};
#if !defined(MAGNUM_TARGET_WEBGL) && !defined(CORRADE_TARGET_APPLE)
const Containers::StringView renderer = rendererString();
#ifndef CORRADE_TARGET_APPLE
const Containers::StringView renderer =
#ifndef MAGNUM_TARGET_WEBGL
rendererString()
#else
rendererStringUnmasked()
#endif
;
#endif
#if !defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_WEBGL)
const Containers::StringView version = versionString();
#endif
#if (!defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_WEBGL)) || defined(MAGNUM_TARGET_GLES)
const Containers::StringView vendor = vendorString();
#if !defined(CORRADE_TARGET_APPLE) || defined(MAGNUM_TARGET_GLES)
const Containers::StringView vendor =
#ifndef MAGNUM_TARGET_WEBGL
vendorString()
#else
vendorStringUnmasked()
#endif
;
#endif
/* In some cases we can have a combination of drivers (e.g. ANGLE running
on top of Mesa, Mesa Zink running on top of NVidia drivers...) so the
detection has no early returns. */
/* Apple has its own drivers */
#if !defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_WEBGL)
/** @todo when Zink on Apple is a thing, this needs an update */
#ifndef CORRADE_TARGET_APPLE
/* AMD binary desktop drivers */
if(vendor.contains("ATI Technologies Inc."_s))
return *_detectedDrivers |= DetectedDriver::Amd;
*_detectedDrivers |= DetectedDriver::Amd;
#ifdef CORRADE_TARGET_WINDOWS
/* Intel Windows drivers */
if(vendor.contains("Intel"_s))
return *_detectedDrivers |= DetectedDriver::IntelWindows;
*_detectedDrivers |= DetectedDriver::IntelWindows;
#endif
/* Mesa drivers */
if(version.contains("Mesa"_s)) {
#ifndef MAGNUM_TARGET_WEBGL
if(version.contains("Mesa"_s))
#else
if(renderer.contains("Mesa"_s))
#endif
{
*_detectedDrivers |= DetectedDriver::Mesa;
if(renderer.contains("SVGA3D"_s))
*_detectedDrivers |= DetectedDriver::Svga3D;
return *_detectedDrivers;
*_detectedDrivers;
}
if(vendor.contains("NVIDIA Corporation"_s))
return *_detectedDrivers |= DetectedDriver::NVidia;
*_detectedDrivers |= DetectedDriver::NVidia;
#endif
/** @todo there is also D3D9/D3D11 distinction on webglreport.com, is it useful? */
#ifdef MAGNUM_TARGET_GLES
/* ANGLE. Can detect easily on ES, have to resort to hacks on WebGL.
Sources: http://stackoverflow.com/a/20149090 + http://webglreport.com */
#ifndef MAGNUM_TARGET_WEBGL
/* ANGLE. On WebGL only if we are so lucky and have access to the unmasked
renderer string. */
if(renderer.contains("ANGLE"_s))
return *_detectedDrivers |= DetectedDriver::Angle;
#else
{
*_detectedDrivers |= DetectedDriver::Angle;
#ifdef MAGNUM_TARGET_WEBGL
/* Otherwise try to detect a D3D ANGLE backend by querying line width. It's
always exactly just 1 on D3D, usually more on GL, not sure about Metal.
so this is not a 100% match. Sources: http://stackoverflow.com/a/20149090
and http://webglreport.com */
else {
Range1Di range;
glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range.data());
if(range.min() == 1 && range.max() == 1 && vendor != "Internet Explorer"_s)
return *_detectedDrivers |= DetectedDriver::Angle;
*_detectedDrivers |= DetectedDriver::Angle;
}
#endif
#ifndef MAGNUM_TARGET_WEBGL
/* SwiftShader */
if(renderer.contains("SwiftShader"_s))
return *_detectedDrivers |= DetectedDriver::SwiftShader;
#endif
*_detectedDrivers |= DetectedDriver::SwiftShader;
#endif
#ifdef CORRADE_TARGET_ANDROID
if(vendor.contains("ARM"_s) && renderer.contains("Mali"_s))
return *_detectedDrivers |= DetectedDriver::ArmMali;
*_detectedDrivers |= DetectedDriver::ArmMali;
#endif
return *_detectedDrivers;

Loading…
Cancel
Save