Commit be815a4f by Olli Etuaho Committed by Commit Bot

Apply effective base and max level on GL backend

This works around GL drivers that neglect to clamp the base level or max level of immutable textures. BUG=angleproject:596 BUG=610800 TEST=angle_end2end_tests Change-Id: Ie4e04aaa9253f2befd73bccefa7759486b3ef487 Reviewed-on: https://chromium-review.googlesource.com/344590Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 53ea9cc6
......@@ -80,6 +80,7 @@ GLuint TextureState::getEffectiveBaseLevel() const
{
if (immutableFormat)
{
// GLES 3.0.4 section 3.8.10
return std::min(baseLevel, immutableLevels - 1);
}
// Some classes use the effective base level to index arrays with level data. By clamping the
......@@ -89,6 +90,18 @@ GLuint TextureState::getEffectiveBaseLevel() const
return std::min(baseLevel, static_cast<GLuint>(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
}
GLuint TextureState::getEffectiveMaxLevel() const
{
if (immutableFormat)
{
// GLES 3.0.4 section 3.8.10
GLuint clampedMaxLevel = std::max(maxLevel, getEffectiveBaseLevel());
clampedMaxLevel = std::min(clampedMaxLevel, immutableLevels - 1);
return clampedMaxLevel;
}
return maxLevel;
}
Texture::Texture(rx::GLImplFactory *factory, GLuint id, GLenum target)
: egl::ImageSibling(id),
mState(target),
......
......@@ -49,6 +49,7 @@ struct TextureState final : public angle::NonCopyable
bool swizzleRequired() const;
GLuint getEffectiveBaseLevel() const;
GLuint getEffectiveMaxLevel() const;
// TODO(jmadill): Make the data members here private.
......
......@@ -726,12 +726,25 @@ void TextureGL::syncState(size_t textureUnit) const
}
};
// clang-format off
// Sync texture state
SyncTextureStateMember(mFunctions, applyTextureFunc, mState, mAppliedTextureState, mState.target, GL_TEXTURE_BASE_LEVEL, &gl::TextureState::baseLevel);
SyncTextureStateMember(mFunctions, applyTextureFunc, mState, mAppliedTextureState, mState.target, GL_TEXTURE_MAX_LEVEL, &gl::TextureState::maxLevel);
// Apply the effective base level and max level instead of the base level and max level set from
// the API. This can help with buggy drivers.
if (mAppliedTextureState.getEffectiveBaseLevel() != mState.getEffectiveBaseLevel())
{
applyTextureFunc();
mFunctions->texParameteri(mState.target, GL_TEXTURE_BASE_LEVEL,
mState.getEffectiveBaseLevel());
}
mAppliedTextureState.baseLevel = mState.baseLevel;
if (mAppliedTextureState.getEffectiveMaxLevel() != mState.getEffectiveMaxLevel())
{
applyTextureFunc();
mFunctions->texParameteri(mState.target, GL_TEXTURE_MAX_LEVEL,
mState.getEffectiveMaxLevel());
}
mAppliedTextureState.maxLevel = mState.maxLevel;
// clang-format off
const LevelInfoGL &levelInfo = mLevelInfo[mState.getEffectiveBaseLevel()];
SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_R, &gl::TextureState::swizzleRed);
SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_G, &gl::TextureState::swizzleGreen);
......
......@@ -2126,26 +2126,6 @@ TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
// GLES 3.0.4 section 3.8.10 subsection Mipmapping
TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
{
if (IsOSX())
{
// Observed incorrect rendering on OSX.
std::cout << "Test skipped on OSX." << std::endl;
return;
}
if (IsAMD() && isOpenGL())
{
// Observed incorrect rendering on AMD OpenGL.
std::cout << "Test skipped on AMD OpenGL." << std::endl;
return;
}
if (IsLinux() && IsIntel() && isOpenGL())
{
// The Mesa Intel driver doesn't clamp the base level
std::cout << "Test skipped on Intel Linux OpenGL." << std::endl;
return;
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment