From 8573194aa03cc38c7e7034986aac9b317a1585ec Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 28 May 2008 13:01:44 +0000 Subject: [PATCH] From Michael Platings, "Yes it's definitely a driver problem - I submitted a bug report to nvidia 6 months ago and the issue is still "in progress". I've given up waiting for them! Platform - various Intel Windows XP SP2 PCs with various nvidia cards including GeForce 8800 GTS and Quadro FX 4500, and various driver versions including the latest WHQL 175.16. I investigated your concerns about glGenerateMipmapEXT being slower than GL_GENERATE_MIPMAP_SGIS, and for power-of-two textures, to my surprise it is. For a 512*512 texture, glGenerateMipmapEXT takes on average 10ms, while GL_GENERATE_MIPMAP_SGIS takes on average 6ms. Therefore I have modified the code to only use glGenerateMipmapEXT if the texture has a non-power-of-two width or height. I am resubmitting all the files previously submitted (only "Texture.cpp" has significant changes since my previous submission, I've also replaced tabs with spaces in "Texture"). " --- src/osg/Texture.cpp | 47 ++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index f7c33c6ce..d4e2a922d 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -1425,19 +1425,26 @@ Texture::GenerateMipmapMode Texture::mipmapBeforeTexImage(const State& state, bo { if (hardwareMipmapOn) { - //GL_GENERATE_MIPMAP_SGIS with non-power-of-two textures on NVIDIA hardware - //is extremely slow. Use glGenerateMipmapEXT() instead if supported. - if (_internalFormatType != SIGNED_INTEGER && - _internalFormatType != UNSIGNED_INTEGER && - FBOExtensions::instance(state.getContextID(), true)->glGenerateMipmapEXT) + int width = getTextureWidth(); + int height = getTextureHeight(); + + //quick bithack to determine whether width or height are non-power-of-two + if ((width & (width - 1)) || (height & (height - 1))) { - return GENERATE_MIPMAP; - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - return GENERATE_MIPMAP_TEX_PARAMETER; + //GL_GENERATE_MIPMAP_SGIS with non-power-of-two textures on NVIDIA hardware + //is extremely slow. Use glGenerateMipmapEXT() instead if supported. + if (_internalFormatType != SIGNED_INTEGER && + _internalFormatType != UNSIGNED_INTEGER) + { + if (FBOExtensions::instance(state.getContextID(), true)->glGenerateMipmapEXT) + { + return GENERATE_MIPMAP; + } + } } + + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); + return GENERATE_MIPMAP_TEX_PARAMETER; } return GENERATE_MIPMAP_NONE; } @@ -1447,7 +1454,15 @@ void Texture::mipmapAfterTexImage(State& state, GenerateMipmapMode beforeResult) switch (beforeResult) { case GENERATE_MIPMAP: - generateMipmap(state); + { + unsigned int contextID = state.getContextID(); + TextureObject* textureObject = getTextureObject(contextID); + if (textureObject) + { + osg::FBOExtensions* fbo_ext = osg::FBOExtensions::instance(contextID, true); + fbo_ext->glGenerateMipmapEXT(textureObject->_target); + } + } break; case GENERATE_MIPMAP_TEX_PARAMETER: glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE); @@ -1481,9 +1496,6 @@ void Texture::generateMipmap(State& state) const if (fbo_ext->glGenerateMipmapEXT) { textureObject->bind(); - - // osg::notify(osg::NOTICE)<<"Using generate glGenerateMipmap"<glGenerateMipmapEXT(textureObject->_target); // inform state that this texture is the current one bound. @@ -1507,12 +1519,7 @@ void Texture::generateMipmap(State& state) const void Texture::compileGLObjects(State& state) const { - // osg::Timer_t startTick = osg::Timer::instance()->tick(); - apply(state); - - // osg::Timer_t endTick = osg::Timer::instance()->tick(); - // osg::notify(osg::NOTICE)<<"compile time = "<delta_m(startTick, endTick)<