Test D3D11 GetDimensions driver workaround for textureProjOffset
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 texture formats because the dimensions are used for
sample position calculations on integer format textures, which leads to sampling
outside the texture when the base level is non-zero.
Bug: angleproject:3441
Change-Id: I9d2f8fa8e66caca704cbc46d4933d3f97aaf93ea
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1617779
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 4315839..6798dea 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -1263,6 +1263,39 @@
}
};
+class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
+{
+ protected:
+ Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
+
+ 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 = 0.5*position.xy + vec2(0.5, 0.5);\n"
+ "}\n";
+ }
+
+ const char *getFragmentShaderSource() override
+ {
+ return "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp usampler2D;\n"
+ "uniform usampler2D tex;\n"
+ "in vec2 texcoord;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
+ "0.0))/255.0;\n"
+ "}\n";
+ }
+};
+
TEST_P(Texture2DTest, NegativeAPISubImage)
{
glBindTexture(GL_TEXTURE_2D, mTexture2D);
@@ -4653,6 +4686,33 @@
EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
}
+// 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(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, mTexture2D);
+ int width = getWindowWidth();
+ int height = getWindowHeight();
+ GLColor color = GLColor::green;
+ std::vector<GLColor> pixels(width * height, color);
+ GLint baseLevel = 1;
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
+ GL_UNSIGNED_BYTE, pixels.data());
+
+ setUpProgram();
+ glUseProgram(mProgram);
+ glUniform1i(mTexture2DUniformLocation, 0);
+ 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,
@@ -4755,5 +4815,6 @@
ANGLE_INSTANTIATE_TEST(Texture2DIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(TextureCubeIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(TextureCubeIntegerEdgeTestES3, ES3_D3D11(), ES3_OPENGL());
+ANGLE_INSTANTIATE_TEST(Texture2DIntegerProjectiveOffsetTestES3, ES3_D3D11(), ES3_OPENGL());
} // anonymous namespace