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 ...@@ -80,6 +80,7 @@ GLuint TextureState::getEffectiveBaseLevel() const
{ {
if (immutableFormat) if (immutableFormat)
{ {
// GLES 3.0.4 section 3.8.10
return std::min(baseLevel, immutableLevels - 1); return std::min(baseLevel, immutableLevels - 1);
} }
// Some classes use the effective base level to index arrays with level data. By clamping the // Some classes use the effective base level to index arrays with level data. By clamping the
...@@ -89,6 +90,18 @@ GLuint TextureState::getEffectiveBaseLevel() const ...@@ -89,6 +90,18 @@ GLuint TextureState::getEffectiveBaseLevel() const
return std::min(baseLevel, static_cast<GLuint>(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); 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) Texture::Texture(rx::GLImplFactory *factory, GLuint id, GLenum target)
: egl::ImageSibling(id), : egl::ImageSibling(id),
mState(target), mState(target),
......
...@@ -49,6 +49,7 @@ struct TextureState final : public angle::NonCopyable ...@@ -49,6 +49,7 @@ struct TextureState final : public angle::NonCopyable
bool swizzleRequired() const; bool swizzleRequired() const;
GLuint getEffectiveBaseLevel() const; GLuint getEffectiveBaseLevel() const;
GLuint getEffectiveMaxLevel() const;
// TODO(jmadill): Make the data members here private. // TODO(jmadill): Make the data members here private.
......
...@@ -726,12 +726,25 @@ void TextureGL::syncState(size_t textureUnit) const ...@@ -726,12 +726,25 @@ void TextureGL::syncState(size_t textureUnit) const
} }
}; };
// clang-format off
// Sync texture state // Sync texture state
SyncTextureStateMember(mFunctions, applyTextureFunc, mState, mAppliedTextureState, mState.target, GL_TEXTURE_BASE_LEVEL, &gl::TextureState::baseLevel); // Apply the effective base level and max level instead of the base level and max level set from
SyncTextureStateMember(mFunctions, applyTextureFunc, mState, mAppliedTextureState, mState.target, GL_TEXTURE_MAX_LEVEL, &gl::TextureState::maxLevel); // 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()]; 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_R, &gl::TextureState::swizzleRed);
SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_G, &gl::TextureState::swizzleGreen); SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, mState, mAppliedTextureState, mState.target, GL_TEXTURE_SWIZZLE_G, &gl::TextureState::swizzleGreen);
......
...@@ -2126,26 +2126,6 @@ TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel) ...@@ -2126,26 +2126,6 @@ TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
// GLES 3.0.4 section 3.8.10 subsection Mipmapping // GLES 3.0.4 section 3.8.10 subsection Mipmapping
TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange) 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); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D); 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