diff --git a/include/osg/Notify b/include/osg/Notify index ae0d37e22..dbd7d2233 100644 --- a/include/osg/Notify +++ b/include/osg/Notify @@ -44,6 +44,9 @@ extern OSG_EXPORT void setNotifyLevel(NotifySeverity severity); /** get the notify level. */ extern OSG_EXPORT NotifySeverity getNotifyLevel(); +/** is notification enabled, given the current setNotifyLevel() setting? */ +extern OSG_EXPORT bool isNotifyEnabled(NotifySeverity severity); + /** initialize notify level. */ extern OSG_EXPORT bool initNotifyLevel(); diff --git a/include/osg/Program b/include/osg/Program index 0bb9b77b5..c608f388f 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -12,7 +12,7 @@ */ /* file: include/osg/Program - * author: Mike Weiblen 2005-05-05 + * author: Mike Weiblen 2005-07-01 */ #ifndef OSG_PROGRAM @@ -132,6 +132,7 @@ class OSG_EXPORT Program : public osg::StateAttribute void requestLink(); void linkProgram(); + void validateProgram(); bool needsLink() const {return _needsLink;} bool isLinked() const {return _isLinked;} bool getInfoLog( std::string& infoLog ) const; diff --git a/src/osg/Notify.cpp b/src/osg/Notify.cpp index f151dbe45..3cd3b3a12 100644 --- a/src/osg/Notify.cpp +++ b/src/osg/Notify.cpp @@ -77,6 +77,11 @@ bool osg::initNotifyLevel() } +bool osg::isNotifyEnabled( osg::NotifySeverity severity ) +{ + return severity<=g_NotifyLevel; +} + #if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW32__)) const char* NullStreamName = "nul"; #else diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index b8b6804d3..14ad61e34 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -13,7 +13,7 @@ */ /* file: src/osg/Program.cpp - * author: Mike Weiblen 2005-05-05 + * author: Mike Weiblen 2005-07-01 */ #include @@ -2064,6 +2064,12 @@ void Program::apply( osg::State& state ) const if( pcp->needsLink() ) compileGLObjects( state ); if( pcp->isLinked() ) { + // for shader debugging: to minimize performance impact, + // optionally validate based on notify level. + // TODO: enable this using notify level, or perhaps its own getenv()? + if( osg::isNotifyEnabled(osg::INFO) ) + pcp->validateProgram(); + pcp->useProgram(); state.setLastAppliedProgramObject(pcp); } @@ -2152,6 +2158,7 @@ void Program::PerContextProgram::linkProgram() osg::notify(osg::INFO) << "Linking osg::Program \"" << _program->getName() << "\"" << " id=" << _glProgramHandle + << " contextID=" << _contextID << std::endl; _uniformInfoMap.clear(); @@ -2258,6 +2265,27 @@ void Program::PerContextProgram::linkProgram() osg::notify(osg::INFO) << std::endl; } +void Program::PerContextProgram::validateProgram() +{ + GLint validated = GL_FALSE; + _extensions->glValidateProgram( _glProgramHandle ); + _extensions->glGetProgramiv( _glProgramHandle, GL_VALIDATE_STATUS, &validated ); + if( validated == GL_TRUE) + return; + + osg::notify(osg::INFO) + << "glValidateProgram FAILED \"" << _program->getName() << "\"" + << " id=" << _glProgramHandle + << " contextID=" << _contextID + << std::endl; + + std::string infoLog; + if( getInfoLog(infoLog) ) + osg::notify(osg::INFO) << "infolog:\n" << infoLog << std::endl; + + osg::notify(osg::INFO) << std::endl; +} + bool Program::PerContextProgram::getInfoLog( std::string& infoLog ) const { return _extensions->getProgramInfoLog( _glProgramHandle, infoLog );