Use D3D11 GetDimensions driver workaround for 2D array textures
Some NVIDIA D3D11 drivers are buggy and interprets the level passed to
GetDimensions as being relative to 0, rather than the SRV's MostDetailedMip.
This affects all integer format textures, because the dimensions are used for
sample position calculations with integer format textures, which leads to
sampling outside texture when the base level is non-zero.
Bug: angleproject:3441
Change-Id: Ic012cac94ce0a627221087ecb2ee6aa3665900d1
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1617780
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Kimmo Kinnunen FI <kkinnunen@nvidia.com>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index 6798dea..b37b155 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -1296,6 +1296,38 @@
}
};
+class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
+{
+ protected:
+ Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
+
+ const char *getVertexShaderSource() override
+ {
+ return "#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";
+ }
+
+ const char *getFragmentShaderSource() override
+ {
+ return "#version 300 es\n"
+ "precision highp float;\n"
+ "uniform highp usampler2DArray tex2DArray;\n"
+ "in vec2 texcoord;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
+ "0.0)))/255.0;\n"
+ "}\n";
+ }
+};
+
TEST_P(Texture2DTest, NegativeAPISubImage)
{
glBindTexture(GL_TEXTURE_2D, mTexture2D);
@@ -4713,6 +4745,31 @@
EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
}
+// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
+// texture is output.
+TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+ int width = getWindowWidth();
+ int height = getWindowHeight();
+ int depth = 2;
+ GLColor color = GLColor::green;
+ std::vector<GLColor> pixels(width * height * depth, color);
+ GLint baseLevel = 1;
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
+ GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ drawQuad(mProgram, "position", 0.5f);
+
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(0, 0, color);
+ EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(Texture2DTest,
@@ -4816,5 +4873,6 @@
ANGLE_INSTANTIATE_TEST(TextureCubeIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(TextureCubeIntegerEdgeTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(Texture2DIntegerProjectiveOffsetTestES3, ES3_D3D11(), ES3_OPENGL());
+ANGLE_INSTANTIATE_TEST(Texture2DArrayIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
} // anonymous namespace