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"). "
This commit is contained in:
@@ -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"<<std::endl;
|
||||
|
||||
fbo_ext->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 = "<<osg::Timer::instance()->delta_m(startTick, endTick)<<std::endl;;
|
||||
}
|
||||
|
||||
void Texture::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
|
||||
Reference in New Issue
Block a user