VTK/OpenGL Driver Information

From KitwarePublic
Jump to navigationJump to search

With VTK's extensive use of OpenGL extensions and broad cross platform support it's inevitable that occasionally driver bugs are encountered for specific combinations of GPU, GL driver, and operating system. This page describes additions to vtkOpenGLExtenstionManager for uniformly dealing with OpenGL driver bugs in such a way that they may be easily located and re-evaluated periodically. For example when new drivers are released.

Identifying Driver Bugs

A rendering bug should be considered an OpenGL driver bug when a VTK class fails to render properly and the following conditions are met:

  • the class renders correctly on a number of other devices, OS's, or driver versions, but fails on specific devices or driver versions.
  • the class makes use of OpenGL functions as documented in the OpenGL spec for the version associated with the rendering context used by VTK.
  • no OpenGL errors are reported by VTK's GL error checking macros or errors are reported that do not match the behavior required by the OpenGL spec.

Verifying these conditions can require some substantial effort in reproducing the bug and reading both the source code and OpenGL spec. However, it's worth looking closely at the problematic code skeptically. For example some drivers, such as NVidia's, are generously fault tolerant and run cleanly on code that's not following the GL spec to the letter. In this case the bug is in the VTK code but it looks like a driver bug because it runs cleanly on one vendors hardware. For common features or popular GPU's it's worth the effort to see if the problem can be avoided by a slight refactoring rather than disabling the feature altogether, even when the bug is in the driver.

Identifying Driver

<source lang="cpp">

 // Description:
 // Return the driver's version parts. This may be used for
 // fine grained feature testing.
 virtual int GetDriverVersionMajor();
 virtual int GetDriverVersionMinor();
 virtual int GetDriverVersionPatch();
 // Description:
 // Get GL API version that the driver provides. This is
 // often different than the GL version that VTK recognizes
 // so only use this for identifying a specific driver.
 virtual int GetDriverGLVersionMajor();
 virtual int GetDriverGLVersionMinor();
 virtual int GetDriverGLVersionPatch();
 // Description:
 // Test's for common implementors of rendering drivers. This may be used for
 // fine grained feature testing. Note: DriverIsMesa succeeds for OS Mesa,
 // use DriverGLRendererIsOSMessa to differentiate.
 virtual bool DriverIsATI();
 virtual bool DriverIsNvidia();
 virtual bool DriverIsIntel();
 virtual bool DriverIsMesa();
 virtual bool DriverIsMicrosoft();
 // Description:
 // Test for a specific driver version.
 virtual bool DriverVersionIs(int major);
 virtual bool DriverVersionIs(int major, int minor);
 virtual bool DriverVersionIs(int major, int minor, int patch);
 // Description:
 // Test for driver version greater than or equal
 // to the named version.
 virtual bool DriverVersionAtLeast(int major);
 virtual bool DriverVersionAtLeast(int major, int minor);
 virtual bool DriverVersionAtLeast(int major, int minor, int patch);
 // Description:
 // Test for the driver's GL version as reported in
 // its GL_VERSION string. This is intended for driver
 // identification only, use ExtensionSuppported
 // to test for VTK support of a specific GL version.
 virtual bool DriverGLVersionIs(int major, int minor, int patch);
 virtual bool DriverGLVersionIs(int major, int minor);
 // Description:
 // Test for a specific renderer. This could be used
 // in some cases to identify the graphics card or
 // specific driver. Use HasToken to prevent false
 // matches eg. avoid GeForce4 matching GeForce400
 virtual bool DriverGLRendererIs(const char *str);
 virtual bool DriverGLRendererHas(const char *str);
 virtual bool DriverGLRendererHasToken(const char *str);
 // Description:
 // Test for Mesa's offscreen renderer.
 virtual bool DriverGLRendererIsOSMesa();
 // Description:
 // Get the OpenGL version, vendor and renderer strings. These can
 // be used to idnetify a specific driver.
 virtual const char *GetDriverGLVendor();
 virtual const char *GetDriverGLVersion();
 virtual const char *GetDriverGLRenderer();

</source>

Disabling a Feature

When a feature is disabled because of a driver bug it's important that the feature not remain disabled indefinitely. It's important to be able to locate features in VTK that have been disabled due to driver bugs and periodically reevaluate the situation as new hardware and drivers are released.

<source lang="cpp">

 // Description:
 // When set known driver bugs are ignored during driver feature
 // detection. This is used to evaluate the status of a new driver
 // release to see if the bugs have been fixed. The function takes
 // a description argument which, is sent to VTK's warning stream
 // when the ignore flag is set. This makes the test output searchable
 // for tests which have problems with certain drivers. The CMakeLists
 // variable VTK_IGNORE_GLDRIVER_BUGS can be used to set this at
 // build time. Default OFF.
 bool GetIgnoreDriverBugs(const char *description);
 vtkSetMacro(IgnoreDriverBugs, bool);
 vtkBooleanMacro(IgnoreDriverBugs, bool);

</source>

Example

<source lang="cpp">

 vtkOpenGLExtensionManager *extensions = context->GetExtensionManager();
 if ( extensions->DriverIsATI()
    && !extensions->GetIgnoreDriverBugs("ATI proxy query bug.") )
   {
   // The ATI Radeon HD drivers currently choke on the proxy
   // query, but depth peeling has been confirmed to work. For
   // those driver fall back on the weaker max texture size
   // check.
   ...
   }
 else
   {
   // Not a buggy ATI driver, it's OK to make the proxy query.
   ...
   }

</source>