Skip to content

Commit

Permalink
Mesa 23.1.4 driver workaround path - disables morphing and changes us…
Browse files Browse the repository at this point in the history
…age of gl_MultiTexCoord0 in the precense of the offending driver version - investigation in progress
  • Loading branch information
gwaldron committed Dec 12, 2023
1 parent 5280c3c commit 300ffd2
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 17 deletions.
19 changes: 14 additions & 5 deletions src/osgEarth/Capabilities
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@
#define OSGEARTH_CAPABILITIES_H 1

#include <osgEarth/Common>
#include <osgEarth/Version>
#include <osg/Uniform>
#include <osg/Texture>

namespace osgEarth
{
class VirtualProgram;

/**
* Stores information about the hardware and graphics system capbilities.
* The osgEarth::Registry stores a singleton Capabilities object that you can
Expand Down Expand Up @@ -70,15 +69,21 @@ namespace osgEarth
/** Are we running OpenGLES? */
bool isGLES() const { return _isGLES; }

/** the GPU vendor */
//! Reported GL_VENDOR
const std::string& getVendor() const { return _vendor;}

/** the GPU renderer */
//! Reported GL_RENDERER
const std::string& getRenderer() const { return _renderer;}

/** the GPU driver version */
//! the GL_VERSION string, which include the GL version, driver vendor, and driver version
const std::string& getVersion() const { return _version;}

//! GPU driver version extracted from GL_VERSION
const Version& getDriverVersion() const { return _driverVersion; }

//! GPU driver vendor extracted from GL_VERSION
const std::string& getDriverVendor() const { return _driverVendor; }

/** whether the GPU supports DEPTH_PACKED_STENCIL buffer */
bool supportsDepthPackedStencilBuffer() const { return _supportsDepthPackedStencilBuffer; }

Expand Down Expand Up @@ -133,6 +138,10 @@ namespace osgEarth
std::string _vendor;
std::string _renderer;
std::string _version;

std::string _driverVendor;
Version _driverVersion;

bool _supportsS3TC;
bool _supportsPVRTC;
bool _supportsARBTC;
Expand Down
19 changes: 15 additions & 4 deletions src/osgEarth/Capabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,25 @@ Capabilities::Capabilities() :
_GLSLversion = GL2->glslLanguageVersion;

_vendor = std::string( reinterpret_cast<const char*>(glGetString(GL_VENDOR)) );
OE_DEBUG << LC << "GPU Vendor: " << _vendor << std::endl;
OE_INFO << LC << "GL_VENDOR: " << _vendor << std::endl;

_renderer = std::string( reinterpret_cast<const char*>(glGetString(GL_RENDERER)) );
OE_INFO << LC << "GPU Renderer: " << _renderer << std::endl;
OE_INFO << LC << "GL_RENDERER: " << _renderer << std::endl;

_version = std::string( reinterpret_cast<const char*>(glGetString(GL_VERSION)) );
OE_INFO << LC << "GL Context/Driver: " << _version <<
" (" << getGLSLVersionInt() << ")" << std::endl;
OE_INFO << LC << "GL_VERSION: " << _version << std::endl;
//OE_INFO << LC << "GLSL: " << getGLSLVersionInt() << std::endl;

// assemble the driver version if possible.
std::vector<std::string> version_tokens;
Strings::StringTokenizer parse_glversion(_version, version_tokens, " ", "", false, true);
if (version_tokens.size() >= 2)
{
_driverVendor = version_tokens[1];
_driverVersion = parseVersion(version_tokens[2].c_str());
//OE_INFO << LC << "GL_VERSION vendor: " << _driverVendor << std::endl;
//OE_INFO << LC << "GL_VERSION driver: " << _driverVersion.major << "." << _driverVersion.minor << "." << _driverVersion.patch << std::endl;
}

// Detect core profile by investigating GL_CONTEXT_PROFILE_MASK
if ( GL2->glVersion < 3.2f )
Expand Down
13 changes: 13 additions & 0 deletions src/osgEarth/ImGui/SystemGUI
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <osgEarth/GLUtils>
#include <osgEarth/ShaderLoader>
#include <osgEarth/Registry>
#include <osgEarth/Capabilities>
#include <chrono>
#include <list>

Expand Down Expand Up @@ -140,6 +141,18 @@ namespace osgEarth

ImGui::Checkbox("Unref image data after apply",
&Registry::instance()->unRefImageDataAfterApply().mutable_value());

ImGui::Separator();
if (ImGuiLTable::Begin("caps"))
{
auto& caps = osgEarth::Registry::capabilities();
ImGuiLTable::Text("osgEarth", osgEarthGetVersion());
ImGuiLTable::Text("OSG", osgGetVersion());
ImGuiLTable::Text("GL_VENDOR", caps.getVendor().c_str());
ImGuiLTable::Text("GL_RENDERER", caps.getRenderer().c_str());
ImGuiLTable::Text("GL_VERSION", caps.getVersion().c_str());
ImGuiLTable::End();
}
}
ImGui::End();
}
Expand Down
7 changes: 7 additions & 0 deletions src/osgEarth/Version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,10 @@ extern "C" {
}

}

osgEarth::Version osgEarth::parseVersion(const char* in)
{
osgEarth::Version v;
sscanf(in, "%d.%d.%d", &v.major, &v.minor, &v.patch);
return v;
}
27 changes: 23 additions & 4 deletions src/osgEarth/Version.in
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,32 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/

#ifndef OSGEARTH_VERSION
#define OSGEARTH_VERSION 1
#pragma once

#include <osgEarth/Export>

namespace osgEarth
{
struct Version
{
int v[3] = { 0, 0, 0 };
inline bool lessThan(int major, int minor, int patch) const {
return v[0] < major || (v[0] == major && (v[1] < minor || (v[1] == minor && v[2] < patch)));
}
inline bool lessThanOrEqualTo(int major, int minor, int patch) const {
return v[0] < major || (v[0] == major && (v[1] < minor || (v[1] == minor && v[2] <= patch)));
}
inline bool greaterThan(int major, int minor, int patch) const {
return v[0] > major || (v[0] == major && (v[1] > minor || (v[1] == minor && v[2] > patch)));
}
inline bool greaterThanOrEqualTo(int major, int minor, int patch) const {
return v[0] > major || (v[0] == major && (v[1] > minor || (v[1] == minor && v[2] >= patch)));
}
};

OSGEARTH_EXPORT Version parseVersion(const char*);
}

extern "C" {

#define OSGEARTH_MAJOR_VERSION @OSGEARTH_MAJOR_VERSION@
Expand Down Expand Up @@ -61,4 +81,3 @@ extern OSGEARTH_EXPORT const char* osgEarthGetLibraryName();
#define OSGEARTH_VERSION_REVISION 0
}

#endif
11 changes: 9 additions & 2 deletions src/osgEarthDrivers/engine_rex/RexEngine.ImageLayer.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
#pragma vp_location vertex_view
#pragma vp_order 0.4

#pragma import_defines(OE_MESA_23_WORKAROUND)
#ifdef OE_MESA_23_WORKAROUND
#define TILE_COORDS gl_MultiTexCoord0
#else
#define TILE_COORDS oe_layer_tilec
#endif

// Stage globals
vec4 oe_layer_tilec;
vec2 oe_layer_texc;
Expand All @@ -14,8 +21,8 @@ uniform mat4 oe_layer_texParentMatrix;
void oe_rex_imageLayer_VS(inout vec4 vertexView)
{
// calculate the texture coordinates:
oe_layer_texc = (oe_layer_texMatrix * oe_layer_tilec).st;
oe_layer_texcParent = (oe_layer_texParentMatrix * oe_layer_tilec).st;
oe_layer_texc = (oe_layer_texMatrix * TILE_COORDS).st;
oe_layer_texcParent = (oe_layer_texParentMatrix * TILE_COORDS).st;
}


Expand Down
11 changes: 9 additions & 2 deletions src/osgEarthDrivers/engine_rex/RexEngine.SDK.glsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#pragma vp_name Rex Terrain SDK

#pragma import_defines(OE_MESA_23_WORKAROUND)
#ifdef OE_MESA_23_WORKAROUND
#define TILE_COORDS gl_MultiTexCoord0
#else
#define TILE_COORDS oe_layer_tilec
#endif

uniform sampler2D oe_tile_elevationTex;
uniform mat4 oe_tile_elevationTexMatrix;
uniform sampler2D oe_tile_normalTex;
Expand Down Expand Up @@ -31,7 +38,7 @@ float oe_terrain_getElevation(in vec2 uv)
// Read the elevation at the build-in tile coordinates (convenience)
float oe_terrain_getElevation()
{
return oe_terrain_getElevation(oe_layer_tilec.st);
return oe_terrain_getElevation(TILE_COORDS.st);
}

// Read the normal vector and curvature at resolved UV tile coordinates.
Expand All @@ -50,7 +57,7 @@ vec4 oe_terrain_getNormalAndCurvature(in vec2 uv_scaledBiased)

vec4 oe_terrain_getNormalAndCurvature()
{
vec2 uv_scaledBiased = oe_layer_tilec.st
vec2 uv_scaledBiased = TILE_COORDS.st
* oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[0][0]
+ oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[3].st
+ oe_tile_elevTexelCoeff.y;
Expand Down
12 changes: 12 additions & 0 deletions src/osgEarthDrivers/engine_rex/RexTerrainEngineNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,18 @@ RexTerrainEngineNode::onSetMap()
_morphingSupported = false;
}

// There is an (apparent) bug in the mesa 23.1.4 driver that causes display artifacts
// when doing morphing; this code will attempt to detect that condition and disable
// the offending code until we can find a workaround.
auto vendor = Registry::capabilities().getDriverVendor();
auto version = Registry::capabilities().getDriverVersion();
if (vendor == "Mesa" && version.greaterThanOrEqualTo(23, 1, 4))
{
OE_WARN << LC << "Detected Mesa >= 23.1.4 driver; disabling terrain & imagery morphing" << std::endl;
_morphingSupported = false;
getOrCreateStateSet()->setDefine("OE_MESA_23_WORKAROUND");
}

// morphing imagery LODs requires we bind parent textures to their own unit.
if (options.getMorphImagery() && _morphingSupported)
{
Expand Down

0 comments on commit 300ffd2

Please sign in to comment.