Commit 4a8329f2 by Olli Etuaho

Refactoring: Split TextureTest to multiple classes

This removes the cube map setup and the draw scale parameter from the tests that don't need them, and reuses the code for setting up the window and the shader program for most of the texture tests. The tests are now structured as follows: TexCoordDrawTest: Test class that sets up a shader program for drawing with texture coordinates. Vertex shader source can be overridden in subclasses, and fragment shader source must be specified in subclasses. Texture2DTest: Inherits TexCoordDrawTest, sets up a 2D texture and a shader for drawing from it. Texture2DTestWithDrawScale: Inherits Texture2DTest, adding a scale parameter that scales the quad that gets drawn. TextureCubeTest: Inherits TexCoordDrawTest, sets up a cube map and a 2D texture and a shader for drawing from them. Texture2DArrayTestES3: Inherits TexCoordDrawTest. Reserves a texture ID and sets up an ESSL3 shader for drawing from a 2D texture array. Also add a few comments about where things being tested are specified. Also, ANGLETest::drawQuad parameter names are renamed to make their meaning clearer. The parameters affect the vertex shader attribute values, which the shader may use for other things besides setting the vertex position. BUG=angleproject:1261 TEST=angle_end2end_tests Change-Id: Id673e36d5883aaaf47f2f830c2a1ad0ca293d578 Reviewed-on: https://chromium-review.googlesource.com/321620Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 74f44506
...@@ -11,10 +11,10 @@ using namespace angle; ...@@ -11,10 +11,10 @@ using namespace angle;
namespace namespace
{ {
class TextureTest : public ANGLETest class TexCoordDrawTest : public ANGLETest
{ {
protected: protected:
TextureTest() TexCoordDrawTest() : ANGLETest(), mProgram(0)
{ {
setWindowWidth(128); setWindowWidth(128);
setWindowHeight(128); setWindowHeight(128);
...@@ -24,88 +24,92 @@ class TextureTest : public ANGLETest ...@@ -24,88 +24,92 @@ class TextureTest : public ANGLETest
setConfigAlphaBits(8); setConfigAlphaBits(8);
} }
void SetUp() override virtual std::string getVertexShaderSource()
{ {
ANGLETest::SetUp(); return std::string(SHADER_SOURCE
glGenTextures(1, &mTexture2D);
glGenTextures(1, &mTextureCube);
glBindTexture(GL_TEXTURE_2D, mTexture2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
EXPECT_GL_NO_ERROR();
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
EXPECT_GL_NO_ERROR();
ASSERT_GL_NO_ERROR();
const std::string vertexShaderSource = SHADER_SOURCE
( (
precision highp float; precision highp float;
attribute vec4 position; attribute vec4 position;
varying vec2 texcoord; varying vec2 texcoord;
uniform vec2 textureScale;
void main() void main()
{ {
gl_Position = vec4(position.xy * textureScale, 0.0, 1.0); gl_Position = vec4(position.xy, 0.0, 1.0);
texcoord = (position.xy * 0.5) + 0.5; texcoord = (position.xy * 0.5) + 0.5;
} }
)
); );
}
const std::string fragmentShaderSource2D = SHADER_SOURCE virtual std::string getFragmentShaderSource() = 0;
(
precision highp float;
uniform sampler2D tex;
varying vec2 texcoord;
void main() void SetUp() override
{ {
gl_FragColor = texture2D(tex, texcoord); ANGLETest::SetUp();
const std::string vertexShaderSource = getVertexShaderSource();
const std::string fragmentShaderSource = getFragmentShaderSource();
mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
ASSERT_NE(0u, mProgram);
ASSERT_GL_NO_ERROR();
}
void TearDown() override
{
glDeleteProgram(mProgram);
ANGLETest::TearDown();
}
// Returns the created texture ID.
GLuint create2DTexture()
{
GLuint texture2D;
glGenTextures(1, &texture2D);
glBindTexture(GL_TEXTURE_2D, texture2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
EXPECT_GL_NO_ERROR();
return texture2D;
} }
);
const std::string fragmentShaderSourceCube = SHADER_SOURCE GLuint mProgram;
};
class Texture2DTest : public TexCoordDrawTest
{
protected:
Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
std::string getFragmentShaderSource() override
{
return std::string(SHADER_SOURCE
( (
precision highp float; precision highp float;
uniform sampler2D tex2D; uniform sampler2D tex;
uniform samplerCube texCube;
varying vec2 texcoord; varying vec2 texcoord;
void main() void main()
{ {
gl_FragColor = texture2D(tex2D, texcoord); gl_FragColor = texture2D(tex, texcoord);
gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
} }
)
); );
}
m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D); void SetUp() override
mCubeProgram = CompileProgram(vertexShaderSource, fragmentShaderSourceCube); {
ASSERT_NE(0u, m2DProgram); TexCoordDrawTest::SetUp();
ASSERT_NE(0u, mCubeProgram); mTexture2D = create2DTexture();
mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
ASSERT_NE(-1, mTexture2DUniformLocation);
mTextureScaleUniformLocation = glGetUniformLocation(m2DProgram, "textureScale");
ASSERT_NE(-1, mTextureScaleUniformLocation);
glUseProgram(m2DProgram);
glUniform2f(mTextureScaleUniformLocation, 1.0f, 1.0f);
glUseProgram(0);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex");
ASSERT_NE(-1, mTexture2DUniformLocation);
} }
void TearDown() override void TearDown() override
{ {
glDeleteTextures(1, &mTexture2D); glDeleteTextures(1, &mTexture2D);
glDeleteTextures(1, &mTextureCube); TexCoordDrawTest::TearDown();
glDeleteProgram(m2DProgram);
glDeleteProgram(mCubeProgram);
ANGLETest::TearDown();
} }
// Tests CopyTexSubImage with floating point textures of various formats. // Tests CopyTexSubImage with floating point textures of various formats.
...@@ -216,7 +220,7 @@ class TextureTest : public ANGLETest ...@@ -216,7 +220,7 @@ class TextureTest : public ANGLETest
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
drawQuad(m2DProgram, "position", 0.5f); drawQuad(mProgram, "position", 0.5f);
int testImageChannels = std::min(sourceImageChannels, destImageChannels); int testImageChannels = std::min(sourceImageChannels, destImageChannels);
...@@ -238,44 +242,128 @@ class TextureTest : public ANGLETest ...@@ -238,44 +242,128 @@ class TextureTest : public ANGLETest
} }
GLuint mTexture2D; GLuint mTexture2D;
GLuint mTextureCube;
GLuint m2DProgram;
GLuint mCubeProgram;
GLint mTexture2DUniformLocation; GLint mTexture2DUniformLocation;
GLint mTextureScaleUniformLocation;
}; };
class TextureTestES3 : public ANGLETest class Texture2DTestWithDrawScale : public Texture2DTest
{ {
protected: protected:
TextureTestES3() Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
: m2DArrayTexture(0),
m2DArrayProgram(0), std::string getVertexShaderSource() override
mTextureArrayLocation(-1)
{ {
setWindowWidth(128); return std::string(SHADER_SOURCE
setWindowHeight(128); (
setConfigRedBits(8); precision highp float;
setConfigGreenBits(8); attribute vec4 position;
setConfigBlueBits(8); varying vec2 texcoord;
setConfigAlphaBits(8);
uniform vec2 drawScale;
void main()
{
gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
texcoord = (position.xy * 0.5) + 0.5;
}
)
);
} }
void SetUp() override void SetUp() override
{ {
ANGLETest::SetUp(); Texture2DTest::SetUp();
mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
ASSERT_NE(-1, mDrawScaleUniformLocation);
glUseProgram(mProgram);
glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
glUseProgram(0);
ASSERT_GL_NO_ERROR();
}
GLint mDrawScaleUniformLocation;
};
class TextureCubeTest : public TexCoordDrawTest
{
protected:
TextureCubeTest()
: TexCoordDrawTest(),
mTexture2D(0),
mTextureCube(0),
mTexture2DUniformLocation(-1),
mTextureCubeUniformLocation(-1)
{
}
std::string getFragmentShaderSource() override
{
return std::string(SHADER_SOURCE
(
precision highp float;
uniform sampler2D tex2D;
uniform samplerCube texCube;
varying vec2 texcoord;
void main()
{
gl_FragColor = texture2D(tex2D, texcoord);
gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
}
)
);
}
void SetUp() override
{
TexCoordDrawTest::SetUp();
glGenTextures(1, &mTextureCube);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
EXPECT_GL_NO_ERROR();
const std::string vertexShaderSource = mTexture2D = create2DTexture();
mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
ASSERT_NE(-1, mTexture2DUniformLocation);
mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
ASSERT_NE(-1, mTextureCubeUniformLocation);
}
void TearDown() override
{
glDeleteTextures(1, &mTextureCube);
TexCoordDrawTest::TearDown();
}
GLuint mTexture2D;
GLuint mTextureCube;
GLint mTexture2DUniformLocation;
GLint mTextureCubeUniformLocation;
};
class Texture2DArrayTestES3 : public TexCoordDrawTest
{
protected:
Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
std::string getVertexShaderSource() override
{
return std::string(
"#version 300 es\n" "#version 300 es\n"
"out vec2 texcoord;\n" "out vec2 texcoord;\n"
"in vec4 position;\n" "in vec4 position;\n"
"void main() {\n" "void main()\n"
"{\n"
" gl_Position = vec4(position.xy, 0.0, 1.0);\n" " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
" texcoord = (position.xy * 0.5) + 0.5;\n" " texcoord = (position.xy * 0.5) + 0.5;\n"
"}"; "}\n");
}
const std::string fragmentShaderSource2DArray = std::string getFragmentShaderSource() override
{
return std::string(
"#version 300 es\n" "#version 300 es\n"
"precision highp float;\n" "precision highp float;\n"
"uniform highp sampler2DArray tex2DArray;\n" "uniform highp sampler2DArray tex2DArray;\n"
...@@ -284,12 +372,14 @@ class TextureTestES3 : public ANGLETest ...@@ -284,12 +372,14 @@ class TextureTestES3 : public ANGLETest
"void main()\n" "void main()\n"
"{\n" "{\n"
" fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n" " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
"}\n"; "}\n");
}
m2DArrayProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2DArray); void SetUp() override
ASSERT_NE(0u, m2DArrayProgram); {
TexCoordDrawTest::SetUp();
mTextureArrayLocation = glGetUniformLocation(m2DArrayProgram, "tex2DArray"); mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
ASSERT_NE(-1, mTextureArrayLocation); ASSERT_NE(-1, mTextureArrayLocation);
glGenTextures(1, &m2DArrayTexture); glGenTextures(1, &m2DArrayTexture);
...@@ -299,15 +389,14 @@ class TextureTestES3 : public ANGLETest ...@@ -299,15 +389,14 @@ class TextureTestES3 : public ANGLETest
void TearDown() override void TearDown() override
{ {
glDeleteTextures(1, &m2DArrayTexture); glDeleteTextures(1, &m2DArrayTexture);
glDeleteProgram(m2DArrayProgram); TexCoordDrawTest::TearDown();
} }
GLuint m2DArrayTexture; GLuint m2DArrayTexture;
GLuint m2DArrayProgram;
GLint mTextureArrayLocation; GLint mTextureArrayLocation;
}; };
TEST_P(TextureTest, NegativeAPISubImage) TEST_P(Texture2DTest, NegativeAPISubImage)
{ {
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
EXPECT_GL_ERROR(GL_NO_ERROR); EXPECT_GL_ERROR(GL_NO_ERROR);
...@@ -317,15 +406,15 @@ TEST_P(TextureTest, NegativeAPISubImage) ...@@ -317,15 +406,15 @@ TEST_P(TextureTest, NegativeAPISubImage)
EXPECT_GL_ERROR(GL_INVALID_VALUE); EXPECT_GL_ERROR(GL_INVALID_VALUE);
} }
TEST_P(TextureTest, ZeroSizedUploads) TEST_P(Texture2DTest, ZeroSizedUploads)
{ {
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
EXPECT_GL_ERROR(GL_NO_ERROR); EXPECT_GL_ERROR(GL_NO_ERROR);
// Use the texture first to make sure it's in video memory // Use the texture first to make sure it's in video memory
glUseProgram(m2DProgram); glUseProgram(mProgram);
glUniform1i(mTexture2DUniformLocation, 0); glUniform1i(mTexture2DUniformLocation, 0);
drawQuad(m2DProgram, "position", 0.5f); drawQuad(mProgram, "position", 0.5f);
const GLubyte *pixel[4] = { 0 }; const GLubyte *pixel[4] = { 0 };
...@@ -340,7 +429,7 @@ TEST_P(TextureTest, ZeroSizedUploads) ...@@ -340,7 +429,7 @@ TEST_P(TextureTest, ZeroSizedUploads)
} }
// Test drawing with two texture types, to trigger an ANGLE bug in validation // Test drawing with two texture types, to trigger an ANGLE bug in validation
TEST_P(TextureTest, CubeMapBug) TEST_P(TextureCubeTest, CubeMapBug)
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
...@@ -348,19 +437,15 @@ TEST_P(TextureTest, CubeMapBug) ...@@ -348,19 +437,15 @@ TEST_P(TextureTest, CubeMapBug)
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
EXPECT_GL_ERROR(GL_NO_ERROR); EXPECT_GL_ERROR(GL_NO_ERROR);
glUseProgram(mCubeProgram); glUseProgram(mProgram);
GLint tex2DUniformLocation = glGetUniformLocation(mCubeProgram, "tex2D"); glUniform1i(mTexture2DUniformLocation, 0);
GLint texCubeUniformLocation = glGetUniformLocation(mCubeProgram, "texCube"); glUniform1i(mTextureCubeUniformLocation, 1);
EXPECT_NE(-1, tex2DUniformLocation); drawQuad(mProgram, "position", 0.5f);
EXPECT_NE(-1, texCubeUniformLocation);
glUniform1i(tex2DUniformLocation, 0);
glUniform1i(texCubeUniformLocation, 1);
drawQuad(mCubeProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps // Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
TEST_P(TextureTest, MipmapsTwice) TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
{ {
int px = getWindowWidth() / 2; int px = getWindowWidth() / 2;
int py = getWindowHeight() / 2; int py = getWindowHeight() / 2;
...@@ -383,10 +468,10 @@ TEST_P(TextureTest, MipmapsTwice) ...@@ -383,10 +468,10 @@ TEST_P(TextureTest, MipmapsTwice)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glUseProgram(m2DProgram); glUseProgram(mProgram);
glUniform1i(mTexture2DUniformLocation, 0); glUniform1i(mTexture2DUniformLocation, 0);
glUniform2f(mTextureScaleUniformLocation, 0.0625f, 0.0625f); glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
drawQuad(m2DProgram, "position", 0.5f); drawQuad(mProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255); EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
...@@ -414,7 +499,7 @@ TEST_P(TextureTest, MipmapsTwice) ...@@ -414,7 +499,7 @@ TEST_P(TextureTest, MipmapsTwice)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
drawQuad(m2DProgram, "position", 0.5f); drawQuad(mProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255); EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
...@@ -422,7 +507,7 @@ TEST_P(TextureTest, MipmapsTwice) ...@@ -422,7 +507,7 @@ TEST_P(TextureTest, MipmapsTwice)
// Test creating a FBO with a cube map render target, to test an ANGLE bug // Test creating a FBO with a cube map render target, to test an ANGLE bug
// https://code.google.com/p/angleproject/issues/detail?id=849 // https://code.google.com/p/angleproject/issues/detail?id=849
TEST_P(TextureTest, CubeMapFBO) TEST_P(TextureCubeTest, CubeMapFBO)
{ {
GLuint fbo; GLuint fbo;
glGenFramebuffers(1, &fbo); glGenFramebuffers(1, &fbo);
...@@ -439,7 +524,7 @@ TEST_P(TextureTest, CubeMapFBO) ...@@ -439,7 +524,7 @@ TEST_P(TextureTest, CubeMapFBO)
} }
// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color. // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
TEST_P(TextureTest, TexStorage) TEST_P(Texture2DTest, TexStorage)
{ {
int width = getWindowWidth(); int width = getWindowWidth();
int height = getWindowHeight(); int height = getWindowHeight();
...@@ -469,10 +554,9 @@ TEST_P(TextureTest, TexStorage) ...@@ -469,10 +554,9 @@ TEST_P(TextureTest, TexStorage)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glUseProgram(m2DProgram); glUseProgram(mProgram);
glUniform1i(mTexture2DUniformLocation, 0); glUniform1i(mTexture2DUniformLocation, 0);
glUniform2f(mTextureScaleUniformLocation, 1.f, 1.f); drawQuad(mProgram, "position", 0.5f);
drawQuad(m2DProgram, "position", 0.5f);
glDeleteTextures(1, &tex2D); glDeleteTextures(1, &tex2D);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255); EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
...@@ -484,7 +568,7 @@ TEST_P(TextureTest, TexStorage) ...@@ -484,7 +568,7 @@ TEST_P(TextureTest, TexStorage)
} }
// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has initialized the image with a default color. // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has initialized the image with a default color.
TEST_P(TextureTest, TexStorageWithPBO) TEST_P(Texture2DTest, TexStorageWithPBO)
{ {
if (extensionEnabled("NV_pixel_buffer_object")) if (extensionEnabled("NV_pixel_buffer_object"))
{ {
...@@ -522,10 +606,9 @@ TEST_P(TextureTest, TexStorageWithPBO) ...@@ -522,10 +606,9 @@ TEST_P(TextureTest, TexStorageWithPBO)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glUseProgram(m2DProgram); glUseProgram(mProgram);
glUniform1i(mTexture2DUniformLocation, 0); glUniform1i(mTexture2DUniformLocation, 0);
glUniform2f(mTextureScaleUniformLocation, 1.f, 1.f); drawQuad(mProgram, "position", 0.5f);
drawQuad(m2DProgram, "position", 0.5f);
glDeleteTextures(1, &tex2D); glDeleteTextures(1, &tex2D);
glDeleteTextures(1, &pbo); glDeleteTextures(1, &pbo);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
...@@ -535,59 +618,59 @@ TEST_P(TextureTest, TexStorageWithPBO) ...@@ -535,59 +618,59 @@ TEST_P(TextureTest, TexStorageWithPBO)
} }
// See description on testFloatCopySubImage // See description on testFloatCopySubImage
TEST_P(TextureTest, CopySubImageFloat_R_R) TEST_P(Texture2DTest, CopySubImageFloat_R_R)
{ {
testFloatCopySubImage(1, 1); testFloatCopySubImage(1, 1);
} }
TEST_P(TextureTest, CopySubImageFloat_RG_R) TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
{ {
testFloatCopySubImage(2, 1); testFloatCopySubImage(2, 1);
} }
TEST_P(TextureTest, CopySubImageFloat_RG_RG) TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
{ {
testFloatCopySubImage(2, 2); testFloatCopySubImage(2, 2);
} }
TEST_P(TextureTest, CopySubImageFloat_RGB_R) TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
{ {
testFloatCopySubImage(3, 1); testFloatCopySubImage(3, 1);
} }
TEST_P(TextureTest, CopySubImageFloat_RGB_RG) TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
{ {
testFloatCopySubImage(3, 2); testFloatCopySubImage(3, 2);
} }
TEST_P(TextureTest, CopySubImageFloat_RGB_RGB) TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
{ {
testFloatCopySubImage(3, 3); testFloatCopySubImage(3, 3);
} }
TEST_P(TextureTest, CopySubImageFloat_RGBA_R) TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
{ {
testFloatCopySubImage(4, 1); testFloatCopySubImage(4, 1);
} }
TEST_P(TextureTest, CopySubImageFloat_RGBA_RG) TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
{ {
testFloatCopySubImage(4, 2); testFloatCopySubImage(4, 2);
} }
TEST_P(TextureTest, CopySubImageFloat_RGBA_RGB) TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
{ {
testFloatCopySubImage(4, 3); testFloatCopySubImage(4, 3);
} }
TEST_P(TextureTest, CopySubImageFloat_RGBA_RGBA) TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
{ {
testFloatCopySubImage(4, 4); testFloatCopySubImage(4, 4);
} }
// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html // Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA // Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA
TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE) TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
{ {
const int npotTexSize = 5; const int npotTexSize = 5;
const int potTexSize = 4; // Should be less than npotTexSize const int potTexSize = 4; // Should be less than npotTexSize
...@@ -632,7 +715,7 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE) ...@@ -632,7 +715,7 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
drawQuad(m2DProgram, "position", 1.0f); drawQuad(mProgram, "position", 1.0f);
EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255); EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
// NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
...@@ -640,13 +723,13 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE) ...@@ -640,13 +723,13 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
drawQuad(m2DProgram, "position", 1.0f); drawQuad(mProgram, "position", 1.0f);
EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255); EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
// NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
drawQuad(m2DProgram, "position", 1.0f); drawQuad(mProgram, "position", 1.0f);
EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64); EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
// Check that glTexImage2D for POT texture succeeds // Check that glTexImage2D for POT texture succeeds
...@@ -663,14 +746,14 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE) ...@@ -663,14 +746,14 @@ TEST_P(TextureTest, TextureNPOT_GL_ALPHA_UBYTE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
drawQuad(m2DProgram, "position", 1.0f); drawQuad(mProgram, "position", 1.0f);
EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64); EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions. // Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect. // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
TEST_P(TextureTest, NPOTSubImageParameters) TEST_P(Texture2DTest, NPOTSubImageParameters)
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
...@@ -691,7 +774,7 @@ TEST_P(TextureTest, NPOTSubImageParameters) ...@@ -691,7 +774,7 @@ TEST_P(TextureTest, NPOTSubImageParameters)
// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0 // In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as // in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
// expected. // expected.
TEST_P(TextureTestES3, RedefineInittableArray) TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
{ {
std::vector<GLubyte> pixelData; std::vector<GLubyte> pixelData;
for (size_t count = 0; count < 5000; count++) for (size_t count = 0; count < 5000; count++)
...@@ -702,7 +785,7 @@ TEST_P(TextureTestES3, RedefineInittableArray) ...@@ -702,7 +785,7 @@ TEST_P(TextureTestES3, RedefineInittableArray)
} }
glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture); glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
glUseProgram(m2DArrayProgram); glUseProgram(mProgram);
glUniform1i(mTextureArrayLocation, 0); glUniform1i(mTextureArrayLocation, 0);
// The first draw worked correctly. // The first draw worked correctly.
...@@ -712,12 +795,12 @@ TEST_P(TextureTestES3, RedefineInittableArray) ...@@ -712,12 +795,12 @@ TEST_P(TextureTestES3, RedefineInittableArray)
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
drawQuad(m2DArrayProgram, "position", 1.0f); drawQuad(mProgram, "position", 1.0f);
EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
// The dimension of the respecification must match the original exactly to trigger the bug. // The dimension of the respecification must match the original exactly to trigger the bug.
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
drawQuad(m2DArrayProgram, "position", 1.0f); drawQuad(mProgram, "position", 1.0f);
EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
...@@ -1044,6 +1127,7 @@ TEST_P(TextureLimitsTest, MaxActiveFragmentTextures) ...@@ -1044,6 +1127,7 @@ TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
} }
// Negative test for pointing two sampler uniforms of different types to the same texture. // Negative test for pointing two sampler uniforms of different types to the same texture.
// GLES 2.0.25 section 2.10.4 page 39.
TEST_P(TextureLimitsTest, TextureTypeConflict) TEST_P(TextureLimitsTest, TextureTypeConflict)
{ {
const std::string &vertexShader = const std::string &vertexShader =
...@@ -1083,7 +1167,9 @@ TEST_P(TextureLimitsTest, TextureTypeConflict) ...@@ -1083,7 +1167,9 @@ TEST_P(TextureLimitsTest, TextureTypeConflict)
} }
// Negative test for rendering with texture outside the valid range. // Negative test for rendering with texture outside the valid range.
// TODO(jmadill): Research if this is correct. // TODO(jmadill): Possibly adjust the test according to the spec:
// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum) TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
{ {
const std::string &vertexShader = const std::string &vertexShader =
...@@ -1116,8 +1202,11 @@ TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum) ...@@ -1116,8 +1202,11 @@ TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
} }
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(TextureTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3()); // TODO(geofflang): Figure out why this test fails on Intel OpenGL // TODO(geofflang): Figure out why tests below fail on Intel OpenGL:
ANGLE_INSTANTIATE_TEST(TextureTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(Texture2DTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
ANGLE_INSTANTIATE_TEST(TextureCubeTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL()); ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL());
} // namespace } // namespace
...@@ -94,21 +94,30 @@ void ANGLETest::swapBuffers() ...@@ -94,21 +94,30 @@ void ANGLETest::swapBuffers()
} }
} }
void ANGLETest::drawQuad(GLuint program, const std::string& positionAttribName, GLfloat quadDepth, GLfloat quadScale) void ANGLETest::drawQuad(GLuint program,
const std::string &positionAttribName,
GLfloat positionAttribZ)
{
drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
}
void ANGLETest::drawQuad(GLuint program,
const std::string &positionAttribName,
GLfloat positionAttribZ,
GLfloat positionAttribXYScale)
{ {
GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str()); GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
glUseProgram(program); glUseProgram(program);
const GLfloat vertices[] = const GLfloat vertices[] = {
{ -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
-1.0f * quadScale, 1.0f * quadScale, quadDepth, -1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
-1.0f * quadScale, -1.0f * quadScale, quadDepth, 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
1.0f * quadScale, -1.0f * quadScale, quadDepth,
-1.0f * quadScale, 1.0f * quadScale, quadDepth, -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
1.0f * quadScale, -1.0f * quadScale, quadDepth, 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
1.0f * quadScale, 1.0f * quadScale, quadDepth, 1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
}; };
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices); glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
......
...@@ -82,7 +82,13 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters> ...@@ -82,7 +82,13 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
virtual void swapBuffers(); virtual void swapBuffers();
static void drawQuad(GLuint program, const std::string& positionAttribName, GLfloat quadDepth, GLfloat quadScale = 1.0f); static void drawQuad(GLuint program,
const std::string &positionAttribName,
GLfloat positionAttribZ);
static void drawQuad(GLuint program,
const std::string &positionAttribName,
GLfloat positionAttribZ,
GLfloat positionAttribXYScale);
static GLuint compileShader(GLenum type, const std::string &source); static GLuint compileShader(GLenum type, const std::string &source);
static bool extensionEnabled(const std::string &extName); static bool extensionEnabled(const std::string &extName);
static bool eglClientExtensionEnabled(const std::string &extName); static bool eglClientExtensionEnabled(const std::string &extName);
......
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