Commit 262e2824 by Anders Leino Committed by Commit Bot

Use D3D11 GetDimensions driver workaround for 3D 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: Ic54328e3d712e28a40efb4e63b8fce0baeb4ef42 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1619785 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 1ad4771e
...@@ -609,17 +609,18 @@ void OutputIntegerTextureSampleFunctionComputations( ...@@ -609,17 +609,18 @@ void OutputIntegerTextureSampleFunctionComputations(
{ {
return; return;
} }
if (IsSamplerCube(textureFunction.sampler))
if (getDimensionsIgnoresBaseLevel)
{ {
if (getDimensionsIgnoresBaseLevel) out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
{ }
out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n"; else
} {
else out << " int baseLevel = 0;\n";
{ }
out << " int baseLevel = 0;\n";
}
if (IsSamplerCube(textureFunction.sampler))
{
out << " float width; float height; float layers; float levels;\n"; out << " float width; float height; float layers; float levels;\n";
out << " uint mip = 0;\n"; out << " uint mip = 0;\n";
...@@ -784,16 +785,7 @@ void OutputIntegerTextureSampleFunctionComputations( ...@@ -784,16 +785,7 @@ void OutputIntegerTextureSampleFunctionComputations(
{ {
if (IsSamplerArray(textureFunction.sampler)) if (IsSamplerArray(textureFunction.sampler))
{ {
if (getDimensionsIgnoresBaseLevel)
{
out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
}
else
{
out << " int baseLevel = 0;\n";
}
out << " float width; float height; float layers; float levels;\n"; out << " float width; float height; float layers; float levels;\n";
if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0) if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
{ {
out << " uint mip = 0;\n"; out << " uint mip = 0;\n";
...@@ -837,15 +829,6 @@ void OutputIntegerTextureSampleFunctionComputations( ...@@ -837,15 +829,6 @@ void OutputIntegerTextureSampleFunctionComputations(
} }
else if (IsSampler2D(textureFunction.sampler)) 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"; out << " float width; float height; float levels;\n";
if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0) if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
...@@ -904,7 +887,7 @@ void OutputIntegerTextureSampleFunctionComputations( ...@@ -904,7 +887,7 @@ void OutputIntegerTextureSampleFunctionComputations(
else else
{ {
out << " " << textureReference out << " " << textureReference
<< ".GetDimensions(0, width, height, depth, levels);\n"; << ".GetDimensions(baseLevel, width, height, depth, levels);\n";
if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT || if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS) textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
...@@ -932,7 +915,7 @@ void OutputIntegerTextureSampleFunctionComputations( ...@@ -932,7 +915,7 @@ void OutputIntegerTextureSampleFunctionComputations(
} }
out << " " << textureReference out << " " << textureReference
<< ".GetDimensions(mip, width, height, depth, levels);\n"; << ".GetDimensions(baseLevel + mip, width, height, depth, levels);\n";
} }
else else
UNREACHABLE(); UNREACHABLE();
......
...@@ -1328,6 +1328,37 @@ class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3 ...@@ -1328,6 +1328,37 @@ class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
} }
}; };
class Texture3DIntegerTestES3 : public Texture3DTestES3
{
protected:
Texture3DIntegerTestES3() : Texture3DTestES3() {}
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 usampler3D tex3D;\n"
"in vec2 texcoord;\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
" fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
"}\n";
}
};
TEST_P(Texture2DTest, NegativeAPISubImage) TEST_P(Texture2DTest, NegativeAPISubImage)
{ {
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
...@@ -4773,6 +4804,31 @@ TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel) ...@@ -4773,6 +4804,31 @@ TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color); EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
} }
// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
// texture is output.
TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, mTexture3D);
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_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
GL_UNSIGNED_BYTE, pixels.data());
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, 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 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_INSTANTIATE_TEST(Texture2DTest,
...@@ -4877,5 +4933,6 @@ ANGLE_INSTANTIATE_TEST(TextureCubeIntegerTestES3, ES3_D3D11(), ES3_OPENGL()); ...@@ -4877,5 +4933,6 @@ ANGLE_INSTANTIATE_TEST(TextureCubeIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(TextureCubeIntegerEdgeTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(TextureCubeIntegerEdgeTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(Texture2DIntegerProjectiveOffsetTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(Texture2DIntegerProjectiveOffsetTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(Texture2DArrayIntegerTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(Texture2DArrayIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(Texture3DIntegerTestES3, ES3_D3D11(), ES3_OPENGL());
} // anonymous namespace } // 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