Fix texture completeness check when base level > 0 is used
ANGLE would previously treat a texture as incomplete whenever its base
level was above 0. This was because the base level wasn't being taken
into account correctly when determining what size the image at a specific
mip level should be. Fix this by taking the base level into account when
determining the expected size.
BUG=angleproject:596
TEST=angle_end2end_tests
Change-Id: I4b05514aed2858797ea46cf3570c3c40e5efc508
Reviewed-on: https://chromium-review.googlesource.com/322132
Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Texture.cpp b/src/libANGLE/Texture.cpp
index 8d7a5f8..5ef6762 100644
--- a/src/libANGLE/Texture.cpp
+++ b/src/libANGLE/Texture.cpp
@@ -812,19 +812,21 @@
return false;
}
- if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> level))
+ ASSERT(level >= mTextureState.baseLevel);
+ const size_t relativeLevel = level - mTextureState.baseLevel;
+ if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel))
{
return false;
}
- if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> level))
+ if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> relativeLevel))
{
return false;
}
if (mTarget == GL_TEXTURE_3D)
{
- if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> level))
+ if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel))
{
return false;
}
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index 8ae600a..f3d5c5a 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -277,6 +277,39 @@
GLint mTexture2DUniformLocation;
};
+class Texture2DTestES3 : public Texture2DTest
+{
+ protected:
+ Texture2DTestES3() : Texture2DTest() {}
+
+ std::string getVertexShaderSource() override
+ {
+ return std::string(
+ "#version 300 es\n"
+ "out vec2 texcoord;\n"
+ "in vec4 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
+ " texcoord = (position.xy * 0.5) + 0.5;\n"
+ "}\n");
+ }
+
+ std::string getFragmentShaderSource() override
+ {
+ return std::string(
+ "#version 300 es\n"
+ "precision highp float;\n"
+ "uniform highp sampler2D tex;\n"
+ "in vec2 texcoord;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = texture(tex, texcoord);\n"
+ "}\n");
+ }
+};
+
class Texture2DTestWithDrawScale : public Texture2DTest
{
protected:
@@ -1182,6 +1215,42 @@
EXPECT_GL_NO_ERROR();
}
+// Test to check that texture completeness is determined correctly when the texture base level is
+// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
+TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, mTexture2D);
+ GLubyte texDataRed[4u * 4u * 4u];
+ for (size_t i = 0u; i < 4u * 4u; ++i)
+ {
+ texDataRed[i * 4u] = 255u;
+ texDataRed[i * 4u + 1u] = 0u;
+ texDataRed[i * 4u + 2u] = 0u;
+ texDataRed[i * 4u + 3u] = 255u;
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
+ GLubyte texDataGreen[2u * 2u * 4u];
+ for (size_t i = 0u; i < 2u * 2u; ++i)
+ {
+ texDataGreen[i * 4u] = 0u;
+ texDataGreen[i * 4u + 1u] = 255u;
+ texDataGreen[i * 4u + 2u] = 0u;
+ texDataGreen[i * 4u + 3u] = 255u;
+ }
+ glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
+ glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
+
+ EXPECT_GL_NO_ERROR();
+
+ drawQuad(mProgram, "position", 0.5f);
+
+ EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
+}
+
// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
// expected.
@@ -1732,6 +1801,7 @@
ES2_OPENGL());
ANGLE_INSTANTIATE_TEST(SamplerArrayTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL());
ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
+ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL());