Commit bce743ab by Olli Etuaho Committed by Commit Bot

Use texture base level to implement textureSize on D3D11 HLSL

HLSL GetDimensions call doesn't take the texture base level into account, so ANGLE needs to use the texture base level passed in uniforms to emulate ESSL textureSize() which does take it into account. After this change the relevant dEQP tests pass on NVIDIA, Intel is still suffering from an issue where a wrong value is returned when the lod is > 0 (tested on Intel HD Graphics 4600). AMD is also suffering from an unknown issue. BUG=angleproject:596 TEST=dEQP-GLES3.functional.shaders.texture_functions.texturesize.* (all pass on NVIDIA now), angle_end2end_tests Change-Id: I13e33d126008ecdf2b89461a3fb5040949cf19e2 Reviewed-on: https://chromium-review.googlesource.com/322123Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 618bebcd
...@@ -858,26 +858,29 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built ...@@ -858,26 +858,29 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
if (textureFunction->method == TextureFunction::SIZE) if (textureFunction->method == TextureFunction::SIZE)
{ {
out << "int baseLevel = samplerMetadata[samplerIndex];\n";
if (IsSampler2D(textureFunction->sampler) || IsSamplerCube(textureFunction->sampler)) if (IsSampler2D(textureFunction->sampler) || IsSamplerCube(textureFunction->sampler))
{ {
if (IsSamplerArray(textureFunction->sampler)) if (IsSamplerArray(textureFunction->sampler) ||
(IsIntegerSampler(textureFunction->sampler) &&
IsSamplerCube(textureFunction->sampler)))
{ {
out << " uint width; uint height; uint layers; uint numberOfLevels;\n" out << " uint width; uint height; uint layers; uint numberOfLevels;\n"
<< " " << textureReference << " " << textureReference << ".GetDimensions(baseLevel + lod, width, "
<< ".GetDimensions(lod, width, height, layers, numberOfLevels);\n"; "height, layers, numberOfLevels);\n";
} }
else else
{ {
out << " uint width; uint height; uint numberOfLevels;\n" out << " uint width; uint height; uint numberOfLevels;\n"
<< " " << textureReference << " " << textureReference
<< ".GetDimensions(lod, width, height, numberOfLevels);\n"; << ".GetDimensions(baseLevel + lod, width, height, numberOfLevels);\n";
} }
} }
else if (IsSampler3D(textureFunction->sampler)) else if (IsSampler3D(textureFunction->sampler))
{ {
out << " uint width; uint height; uint depth; uint numberOfLevels;\n" out << " uint width; uint height; uint depth; uint numberOfLevels;\n"
<< " " << textureReference << " " << textureReference
<< ".GetDimensions(lod, width, height, depth, numberOfLevels);\n"; << ".GetDimensions(baseLevel + lod, width, height, depth, numberOfLevels);\n";
} }
else UNREACHABLE(); else UNREACHABLE();
......
...@@ -598,6 +598,71 @@ class Texture2DArrayTestES3 : public TexCoordDrawTest ...@@ -598,6 +598,71 @@ class Texture2DArrayTestES3 : public TexCoordDrawTest
GLint mTextureArrayLocation; GLint mTextureArrayLocation;
}; };
class TextureSizeTextureArrayTest : public TexCoordDrawTest
{
protected:
TextureSizeTextureArrayTest()
: TexCoordDrawTest(),
mTexture2DA(0),
mTexture2DB(0),
mTexture0Location(-1),
mTexture1Location(-1)
{
}
std::string getVertexShaderSource() override
{
return std::string(
"#version 300 es\n"
"in vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position.xy, 0.0, 1.0);\n"
"}\n");
}
std::string getFragmentShaderSource() override
{
return std::string(
"#version 300 es\n"
"precision highp float;\n"
"uniform highp sampler2D tex2DArray[2];\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
" float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
" float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
" fragColor = vec4(red, green, 0.0, 1.0);\n"
"}\n");
}
void SetUp() override
{
TexCoordDrawTest::SetUp();
mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
ASSERT_NE(-1, mTexture0Location);
mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
ASSERT_NE(-1, mTexture1Location);
mTexture2DA = create2DTexture();
mTexture2DB = create2DTexture();
ASSERT_GL_NO_ERROR();
}
void TearDown() override
{
glDeleteTextures(1, &mTexture2DA);
glDeleteTextures(1, &mTexture2DB);
TexCoordDrawTest::TearDown();
}
GLuint mTexture2DA;
GLuint mTexture2DB;
GLint mTexture0Location;
GLint mTexture1Location;
};
class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
{ {
protected: protected:
...@@ -1420,6 +1485,53 @@ TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw) ...@@ -1420,6 +1485,53 @@ TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2); EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
} }
// Test different base levels on textures accessed through the same sampler array.
// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
{
if ((isAMD() || isIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
return;
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2DA);
GLsizei size = 64;
for (GLint level = 0; level < 7; ++level)
{
ASSERT_LT(0, size);
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr);
size = size / 2;
}
ASSERT_EQ(0, size);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mTexture2DB);
size = 128;
for (GLint level = 0; level < 8; ++level)
{
ASSERT_LT(0, size);
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
nullptr);
size = size / 2;
}
ASSERT_EQ(0, size);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
EXPECT_GL_NO_ERROR();
glUseProgram(mProgram);
glUniform1i(mTexture0Location, 0);
glUniform1i(mTexture1Location, 1);
drawQuad(mProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
// Red channel: width of level 1 of texture A: 32.
// Green channel: width of level 3 of texture B: 16.
EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
}
class TextureLimitsTest : public ANGLETest class TextureLimitsTest : public ANGLETest
{ {
protected: protected:
...@@ -1860,6 +1972,7 @@ ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3, ...@@ -1860,6 +1972,7 @@ ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
ES3_OPENGLES()); ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES()); ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
} // namespace } // 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