Commit f6cbe44a by Anders Leino Committed by Commit Bot

Use D3D11 GetDimensions driver workaround for 2D integer 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. A test is added which reads from non-zero base level integer texture. When the workaround is not being used, reads outside the first quadrant return black. Bug: chromium:679639 Change-Id: I5282a1ba207b2d553d1836f9460ec09cb5590ea6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1591594 Commit-Queue: Kimmo Kinnunen FI <kkinnunen@nvidia.com> Reviewed-by: 's avatarKimmo Kinnunen FI <kkinnunen@nvidia.com>
parent e211740e
......@@ -127,6 +127,7 @@ NVIDIA Corporation
Martin Radev
Joonatan Saarhelo
Markus Tavenrath
Anders Leino
Opera Software ASA
Daniel Bratell
......@@ -144,4 +145,3 @@ IBM Inc.
AdaptVis GmbH
Sascha Kolodzey
......@@ -602,7 +602,8 @@ void OutputIntegerTextureSampleFunctionComputations(
const ImmutableString &textureReference,
ImmutableString *texCoordX,
ImmutableString *texCoordY,
ImmutableString *texCoordZ)
ImmutableString *texCoordZ,
bool getDimensionsIgnoresBaseLevel)
{
if (!IsIntegerSampler(textureFunction.sampler))
{
......@@ -752,6 +753,15 @@ void OutputIntegerTextureSampleFunctionComputations(
}
else if (IsSampler2D(textureFunction.sampler))
{
if (getDimensionsIgnoresBaseLevel)
{
out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
}
else
{
out << " int baseLevel = 0;\n";
}
out << " float width; float height; float levels;\n";
if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
......@@ -764,7 +774,8 @@ void OutputIntegerTextureSampleFunctionComputations(
}
else
{
out << " " << textureReference << ".GetDimensions(0, width, height, levels);\n";
out << " " << textureReference
<< ".GetDimensions(baseLevel, width, height, levels);\n";
if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
......@@ -791,7 +802,8 @@ void OutputIntegerTextureSampleFunctionComputations(
out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
}
out << " " << textureReference << ".GetDimensions(mip, width, height, levels);\n";
out << " " << textureReference
<< ".GetDimensions(baseLevel + mip, width, height, levels);\n";
}
else if (IsSampler3D(textureFunction.sampler))
{
......@@ -1458,9 +1470,9 @@ void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out,
else
{
ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ);
OutputIntegerTextureSampleFunctionComputations(out, textureFunction, outputType,
textureReference, &texCoordX,
&texCoordY, &texCoordZ);
OutputIntegerTextureSampleFunctionComputations(
out, textureFunction, outputType, textureReference, &texCoordX, &texCoordY,
&texCoordZ, getDimensionsIgnoresBaseLevel);
OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType,
textureReference, samplerReference,
texCoordX, texCoordY, texCoordZ);
......
......@@ -1152,6 +1152,38 @@ class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
}
};
class Texture2DIntegerTestES3 : public Texture2DTest
{
protected:
Texture2DIntegerTestES3() : 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 = (position.xy * 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(texture(tex, texcoord));\n"
"}\n";
}
};
TEST_P(Texture2DTest, NegativeAPISubImage)
{
glBindTexture(GL_TEXTURE_2D, mTexture2D);
......@@ -4440,6 +4472,33 @@ TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
}
// 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(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
{
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,
......@@ -4539,5 +4598,6 @@ ANGLE_INSTANTIATE_TEST(TextureBorderClampIntegerTestES3, ES3_D3D11(), ES3_OPENGL
ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES(), ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(Texture2DNorm16TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(TextureCubeTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(Texture2DIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
} // anonymous namespace
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