From 18369bed2d888f26b104e834381ddee7530f5fb8 Mon Sep 17 00:00:00 2001 From: d-a-heitbrink Date: Fri, 13 Jan 2017 09:33:49 -0600 Subject: [PATCH] added code to deal with #extension for shader, added int64 and uint64 support --- src/osg/GLExtensions.cpp | 27 +++++++ src/osg/State.cpp | 7 ++ src/osg/Uniform.cpp | 169 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 200 insertions(+), 3 deletions(-) diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index 7a4b038a3..58068cf22 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -637,6 +638,25 @@ GLExtensions::GLExtensions(unsigned int in_contextID): setGLExtensionFuncPtr(glUniform2uiv, "glUniform2uiv", "glUniform2uivEXT", validContext); setGLExtensionFuncPtr(glUniform3uiv, "glUniform3uiv", "glUniform3uivEXT", validContext); setGLExtensionFuncPtr(glUniform4uiv, "glUniform4uiv", "glUniform4uivEXT", validContext); + + // ARB_gpu_shader_int64 + setGLExtensionFuncPtr(glUniform1i64, "glUniform1i64", "glUniform1i64ARB", validContext); + setGLExtensionFuncPtr(glUniform1ui64, "glUniform1ui64", "glUniform1ui64ARB", validContext); + setGLExtensionFuncPtr(glUniform2i64, "glUniform2i64", "glUniform2i64ARB", validContext); + setGLExtensionFuncPtr(glUniform2ui64, "glUniform2ui64", "glUniform2ui64ARB", validContext); + setGLExtensionFuncPtr(glUniform3i64, "glUniform3i64", "glUniform3i64ARB", validContext); + setGLExtensionFuncPtr(glUniform3ui64, "glUniform3ui64", "glUniform3ui64ARB", validContext); + setGLExtensionFuncPtr(glUniform4i64, "glUniform4i64", "glUniform4i64ARB", validContext); + setGLExtensionFuncPtr(glUniform4ui64, "glUniform4ui64", "glUniform4ui64ARB", validContext); + setGLExtensionFuncPtr(glUniform1i64v, "glUniform1i64v", "glUniform1i64vARB", validContext); + setGLExtensionFuncPtr(glUniform1ui64v,"glUniform1ui64v","glUniform1ui64vARB",validContext); + setGLExtensionFuncPtr(glUniform2i64v, "glUniform2i64v", "glUniform2i64vARB", validContext); + setGLExtensionFuncPtr(glUniform2ui64v,"glUniform2ui64v","glUniform2ui64vARB",validContext); + setGLExtensionFuncPtr(glUniform3i64v, "glUniform3i64v", "glUniform3i64vARB", validContext); + setGLExtensionFuncPtr(glUniform3ui64v,"glUniform3ui64v","glUniform3ui64vARB",validContext); + setGLExtensionFuncPtr(glUniform4i64v, "glUniform4i64v", "glUniform4i64vARB", validContext); + setGLExtensionFuncPtr(glUniform4ui64v,"glUniform4ui64v","glUniform4ui64vARB",validContext); + // ARB_uniform_buffer_object setGLExtensionFuncPtr(glGetUniformIndices, "glGetUniformIndices", validContext); setGLExtensionFuncPtr(glGetActiveUniformsiv, "glGetActiveUniformsiv", validContext); @@ -937,6 +957,13 @@ GLExtensions::GLExtensions(unsigned int in_contextID): maxLayerCount = 0; if (validContext) glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &maxLayerCount); + // Bindless textures + setGLExtensionFuncPtr(glGetTextureHandle, "glGetTextureHandle", "glGetTextureHandleARB","glGetTextureHandleNV", validContext); + setGLExtensionFuncPtr(glMakeTextureHandleResident, "glMakeTextureHandleResident", "glMakeTextureHandleResidentARB","glMakeTextureHandleResidentNV", validContext); + setGLExtensionFuncPtr(glMakeTextureHandleNonResident, "glMakeTextureHandleNonResident", "glMakeTextureHandleNonResidentARB", "glMakeTextureHandleNonResidentNV",validContext); + setGLExtensionFuncPtr(glUniformHandleui64, "glUniformHandleui64", "glUniformHandleui64ARB","glUniformHandleui64NV", validContext); + setGLExtensionFuncPtr(glIsTextureHandleResident, "glIsTextureHandleResident","glIsTextureHandleResidentARB", "glIsTextureHandleResidentNV", validContext); + // Blending isBlendColorSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_blend_color") || diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 030a57e5c..e0ddf6a0b 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -1226,6 +1226,13 @@ bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const declPos = 0; } + std::string::size_type extPos = source.rfind( "#extension " ); + if ( extPos != std::string::npos ) + { + // found the string, now find the next linefeed and set the insertion point after it. + declPos = source.find( '\n', extPos ); + declPos = declPos != std::string::npos ? declPos+1 : source.length(); + } if (_useModelViewAndProjectionUniforms) { // replace ftransform as it only works with built-ins diff --git a/src/osg/Uniform.cpp b/src/osg/Uniform.cpp index 2c0b103d7..50ab08552 100644 --- a/src/osg/Uniform.cpp +++ b/src/osg/Uniform.cpp @@ -168,6 +168,8 @@ bool Uniform::setArray( FloatArray* array ) _doubleArray = 0; _intArray = 0; _uintArray = 0; + _int64Array = 0; + _uint64Array = 0; dirty(); return true; } @@ -187,6 +189,8 @@ bool Uniform::setArray( DoubleArray* array ) _floatArray = 0; _intArray = 0; _uintArray = 0; + _int64Array = 0; + _uint64Array = 0; dirty(); return true; } @@ -206,6 +210,8 @@ bool Uniform::setArray( IntArray* array ) _floatArray = 0; _doubleArray = 0; _uintArray = 0; + _int64Array = 0; + _uint64Array = 0; dirty(); return true; } @@ -225,6 +231,49 @@ bool Uniform::setArray( UIntArray* array ) _floatArray = 0; _doubleArray = 0; _intArray = 0; + _int64Array = 0; + _uint64Array = 0; + dirty(); + return true; +} +bool Uniform::setArray( UInt64Array* array ) +{ + if( !array ) return false; + + // incoming array must match configuration of the Uniform + if( getInternalArrayType(getType())!=GL_UNSIGNED_INT || getInternalArrayNumElements()!=array->getNumElements() ) + { + OSG_WARN << "Uniform::setArray : incompatible array" << std::endl; + return false; + } + + _uint64Array = array; + _floatArray = 0; + _doubleArray = 0; + _intArray = 0; + _uintArray = 0; + _int64Array =0; + dirty(); + return true; +} + +bool Uniform::setArray( Int64Array* array ) +{ + if( !array ) return false; + + // incoming array must match configuration of the Uniform + if( getInternalArrayType(getType())!=GL_UNSIGNED_INT || getInternalArrayNumElements()!=array->getNumElements() ) + { + OSG_WARN << "Uniform::setArray : incompatible array" << std::endl; + return false; + } + + _int64Array = array; + _floatArray = 0; + _doubleArray = 0; + _intArray = 0; + _uintArray = 0; + _uint64Array =0; dirty(); return true; } @@ -282,6 +331,22 @@ int Uniform::compareData(const Uniform& rhs) const return memcmp( _uintArray->getDataPointer(), rhs._uintArray->getDataPointer(), _uintArray->getTotalDataSize() ); } + + else if( _uint64Array.valid() ) + { + if( ! rhs._uint64Array ) return 1; + if( _uint64Array == rhs._uint64Array ) return 0; + return memcmp( _uint64Array->getDataPointer(), rhs._uint64Array->getDataPointer(), + _uint64Array->getTotalDataSize() ); + } + + else if( _int64Array.valid() ) + { + if( ! rhs._int64Array ) return 1; + if( _int64Array == rhs._int64Array ) return 0; + return memcmp( _int64Array->getDataPointer(), rhs._int64Array->getDataPointer(), + _int64Array->getTotalDataSize() ); + } return -1; // how got here? } @@ -296,6 +361,8 @@ void Uniform::copyData(const Uniform& rhs) if( _doubleArray.valid() && rhs._doubleArray.valid() ) *_doubleArray = *rhs._doubleArray; if( _intArray.valid() && rhs._intArray.valid() ) *_intArray = *rhs._intArray; if( _uintArray.valid() && rhs._uintArray.valid() ) *_uintArray = *rhs._uintArray; + if( _int64Array.valid() && rhs._int64Array.valid() ) *_int64Array = *rhs._int64Array; + if( _uint64Array.valid() && rhs._uint64Array.valid() ) *_uint64Array = *rhs._uint64Array; dirty(); } @@ -361,6 +428,9 @@ const char* Uniform::getTypename( Type t ) case BOOL_VEC3: return "bvec3"; case BOOL_VEC4: return "bvec4"; + case INT64: return "int64_t"; + case UNSIGNED_INT64: return "uint64_t"; + case FLOAT_MAT2: return "mat2"; case FLOAT_MAT3: return "mat3"; case FLOAT_MAT4: return "mat4"; @@ -473,6 +543,8 @@ int Uniform::getTypeNumComponents( Type t ) case INT: case UNSIGNED_INT: case BOOL: + case UNSIGNED_INT64: + case INT64: case SAMPLER_1D: case SAMPLER_2D: @@ -635,6 +707,9 @@ Uniform::Type Uniform::getTypeId( const std::string& tname ) if( tname == "bvec3" ) return BOOL_VEC3; if( tname == "bvec4" ) return BOOL_VEC4; + if( tname == "uint64_t" ) return UNSIGNED_INT64; + if( tname == "int64_t" ) return INT64; + if( tname == "mat2" || tname == "mat2x2" ) return FLOAT_MAT2; if( tname == "mat3" || tname == "mat3x3" ) return FLOAT_MAT3; if( tname == "mat4" || tname == "mat4x4" ) return FLOAT_MAT4; @@ -832,6 +907,12 @@ Uniform::Type Uniform::getGlApiType( Type t ) case BOOL_VEC4: return INT_VEC4; + case UNSIGNED_INT64: + return UNSIGNED_INT64; + + case INT64: + return INT64; + default: return t; } @@ -965,6 +1046,12 @@ GLenum Uniform::getInternalArrayType( Type t ) case UNSIGNED_INT_VEC4: return GL_UNSIGNED_INT; + case UNSIGNED_INT64: + return GL_UNSIGNED_INT64_ARB; + + case INT64: + return GL_INT64_ARB; + default: return 0; } @@ -1298,8 +1385,21 @@ Uniform::Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 ) : allocateDataArray(); set( b0, b1, b2, b3 ); } - -/////////////////////////////////////////////////////////////////////////// +Uniform::Uniform( const char* name, unsigned long long ull) : + _type(UNSIGNED_INT64), _numElements(1), _modifiedCount(0) +{ + setName(name); + allocateDataArray(); + set( ull ); +} +Uniform::Uniform( const char* name, long long ll) : + _type(INT64), _numElements(1), _modifiedCount(0) +{ + setName(name); + allocateDataArray(); + set( ll ); +} +//////////////////////////////////////////////////////////////////////// // Value assignment for single-element (ie: non-array) uniforms. // (For backwards compatibility, if not already configured, set the // Uniform's _numElements=1) @@ -1532,6 +1632,17 @@ bool Uniform::set( bool b0, bool b1, bool b2, bool b3 ) return isScalar() ? setElement(0,b0,b1,b2,b3) : false; } + +bool Uniform::set( unsigned long long ull ) +{ + if( getNumElements() == 0 ) setNumElements(1); + return isScalar() ? setElement(0,ull) : false; +} +bool Uniform::set( long long ll ) +{ + if( getNumElements() == 0 ) setNumElements(1); + return isScalar() ? setElement(0,ll) : false; +} /////////////////////////////////////////////////////////////////////////// // Value query for single-element (ie: non-array) uniforms. @@ -1725,6 +1836,14 @@ bool Uniform::get( bool& b0, bool& b1, bool& b2, bool& b3 ) const return isScalar() ? getElement(0,b0,b1,b2,b3) : false; } +bool Uniform::get( unsigned long long& ull ) const +{ + return isScalar() ? getElement(0,ull) : false; +} +bool Uniform::get( long long& ll ) const +{ + return isScalar() ? getElement(0,ll) : false; +} /////////////////////////////////////////////////////////////////////////// // Value assignment for array uniforms. @@ -2110,7 +2229,22 @@ bool Uniform::setElement( unsigned int index, bool b0, bool b1, bool b2, bool b3 dirty(); return true; } - +bool Uniform::setElement( unsigned int index, unsigned long long ull ) +{ + if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT64) ) return false; + unsigned int j = index * getTypeNumComponents(getType()); + (*_uint64Array)[j] = ull; + dirty(); + return true; +} +bool Uniform::setElement( unsigned int index, long long ll ) +{ + if( index>=getNumElements() || !isCompatibleType(INT64) ) return false; + unsigned int j = index * getTypeNumComponents(getType()); + (*_int64Array)[j] = ll; + dirty(); + return true; +} /////////////////////////////////////////////////////////////////////////// // Value query for array uniforms. @@ -2422,6 +2556,22 @@ bool Uniform::getElement( unsigned int index, bool& b ) const return true; } +bool Uniform::getElement( unsigned int index, unsigned long long& ull ) const +{ + if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT64) ) return false; + unsigned int j = index * getTypeNumComponents(getType()); + ull = ((*_uint64Array)[j] != 0); + return true; +} + +bool Uniform::getElement( unsigned int index, long long& ll ) const +{ + if( index>=getNumElements() || !isCompatibleType(INT64) ) return false; + unsigned int j = index * getTypeNumComponents(getType()); + ll = ((*_int64Array)[j] != 0); + return true; +} + bool Uniform::getElement( unsigned int index, bool& b0, bool& b1 ) const { if( index>=getNumElements() || !isCompatibleType(BOOL_VEC2) ) return false; @@ -2604,6 +2754,19 @@ void Uniform::apply(const GLExtensions* ext, GLint location) const if( _uintArray.valid() ) ext->glUniform4uiv( location, num, &_uintArray->front() ); break; + case UNSIGNED_INT64: + if( _uint64Array.valid() ){ + if (ext->glUniform1ui64v) + ext->glUniform1ui64v( location, num, &_uint64Array->front() ); + else + OSG_WARN << "how got here? " __FILE__ ":" << __LINE__ << std::endl; + } + break; + + case INT64: + if( _int64Array.valid() ) ext->glUniform1i64v( location, num, &_int64Array->front() ); + break; + default: OSG_FATAL << "how got here? " __FILE__ ":" << __LINE__ << std::endl; break;