summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/SwizzleTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/SwizzleTest.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/SwizzleTest.cpp441
1 files changed, 441 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/SwizzleTest.cpp b/gfx/angle/src/tests/gl_tests/SwizzleTest.cpp
new file mode 100755
index 000000000..b1ad13102
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/SwizzleTest.cpp
@@ -0,0 +1,441 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "test_utils/ANGLETest.h"
+
+#include <vector>
+
+using namespace angle;
+
+namespace
+{
+
+class SwizzleTest : public ANGLETest
+{
+ protected:
+ SwizzleTest()
+ {
+ setWindowWidth(128);
+ setWindowHeight(128);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+
+ GLenum swizzles[] =
+ {
+ GL_RED,
+ GL_GREEN,
+ GL_BLUE,
+ GL_ALPHA,
+ GL_ZERO,
+ GL_ONE,
+ };
+
+ for (int r = 0; r < 6; r++)
+ {
+ for (int g = 0; g < 6; g++)
+ {
+ for (int b = 0; b < 6; b++)
+ {
+ for (int a = 0; a < 6; a++)
+ {
+ swizzlePermutation permutation;
+ permutation.swizzleRed = swizzles[r];
+ permutation.swizzleGreen = swizzles[g];
+ permutation.swizzleBlue = swizzles[b];
+ permutation.swizzleAlpha = swizzles[a];
+ mPermutations.push_back(permutation);
+ }
+ }
+ }
+ }
+ }
+
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+
+ const std::string vertexShaderSource = SHADER_SOURCE
+ (
+ precision highp float;
+ attribute vec4 position;
+ varying vec2 texcoord;
+
+ void main()
+ {
+ gl_Position = position;
+ texcoord = (position.xy * 0.5) + 0.5;
+ }
+ );
+
+ const std::string fragmentShaderSource = SHADER_SOURCE
+ (
+ precision highp float;
+ uniform sampler2D tex;
+ varying vec2 texcoord;
+
+ void main()
+ {
+ gl_FragColor = texture2D(tex, texcoord);
+ }
+ );
+
+ mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
+ ASSERT_NE(0u, mProgram);
+
+ mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
+ ASSERT_NE(-1, mTextureUniformLocation);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ void TearDown() override
+ {
+ glDeleteProgram(mProgram);
+ glDeleteTextures(1, &mTexture);
+
+ ANGLETest::TearDown();
+ }
+
+ template <typename T>
+ void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T* data)
+ {
+ glGenTextures(1, &mTexture);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, dataFormat, dataType, data);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+
+ void init2DCompressedTexture(GLenum internalFormat, GLsizei width, GLsizei height, GLsizei dataSize, const GLubyte* data)
+ {
+ glGenTextures(1, &mTexture);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, dataSize, data);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+
+ GLubyte getExpectedValue(GLenum swizzle, GLubyte unswizzled[4])
+ {
+ switch (swizzle)
+ {
+ case GL_RED: return unswizzled[0];
+ case GL_GREEN: return unswizzled[1];
+ case GL_BLUE: return unswizzled[2];
+ case GL_ALPHA: return unswizzled[3];
+ case GL_ZERO: return 0;
+ case GL_ONE: return 255;
+ default: return 0;
+ }
+ }
+
+ void runTest2D()
+ {
+ // TODO(jmadill): Figure out why this fails on Intel.
+ if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
+ {
+ std::cout << "Test skipped on Intel." << std::endl;
+ return;
+ }
+
+ glUseProgram(mProgram);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ glUniform1i(mTextureUniformLocation, 0);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ drawQuad(mProgram, "position", 0.5f);
+
+ GLubyte unswizzled[4];
+ glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &unswizzled);
+
+ ASSERT_GL_NO_ERROR();
+
+ for (size_t i = 0; i < mPermutations.size(); i++)
+ {
+ const swizzlePermutation& permutation = mPermutations[i];
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, permutation.swizzleRed);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, permutation.swizzleGreen);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, permutation.swizzleBlue);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, permutation.swizzleAlpha);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ drawQuad(mProgram, "position", 0.5f);
+
+ EXPECT_PIXEL_EQ(0, 0,
+ getExpectedValue(permutation.swizzleRed, unswizzled),
+ getExpectedValue(permutation.swizzleGreen, unswizzled),
+ getExpectedValue(permutation.swizzleBlue, unswizzled),
+ getExpectedValue(permutation.swizzleAlpha, unswizzled));
+
+ ASSERT_GL_NO_ERROR();
+ }
+ }
+
+ GLuint mProgram;
+ GLint mTextureUniformLocation;
+
+ GLuint mTexture;
+
+ struct swizzlePermutation
+ {
+ GLenum swizzleRed;
+ GLenum swizzleGreen;
+ GLenum swizzleBlue;
+ GLenum swizzleAlpha;
+ };
+ std::vector<swizzlePermutation> mPermutations;
+};
+
+class SwizzleIntegerTest : public SwizzleTest
+{
+ protected:
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+
+ const std::string vertexShaderSource =
+ "#version 300 es\n"
+ "precision highp float;\n"
+ "in vec4 position;\n"
+ "out vec2 texcoord;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = position;\n"
+ " texcoord = (position.xy * 0.5) + 0.5;\n"
+ "}\n";
+
+ const std::string fragmentShaderSource =
+ "#version 300 es\n"
+ "precision highp float;\n"
+ "precision highp usampler2D;\n"
+ "uniform usampler2D tex;\n"
+ "in vec2 texcoord;\n"
+ "out vec4 my_FragColor;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " uvec4 s = texture(tex, texcoord);\n"
+ " if (s[0] == 1u) s[0] = 255u;\n"
+ " if (s[1] == 1u) s[1] = 255u;\n"
+ " if (s[2] == 1u) s[2] = 255u;\n"
+ " if (s[3] == 1u) s[3] = 255u;\n"
+ " my_FragColor = vec4(s) / 255.0;\n"
+ "}\n";
+
+ mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
+ ASSERT_NE(0u, mProgram);
+
+ mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
+ ASSERT_NE(-1, mTextureUniformLocation);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ ASSERT_GL_NO_ERROR();
+ }
+};
+
+TEST_P(SwizzleTest, RGBA8_2D)
+{
+ GLubyte data[] = { 1, 64, 128, 200 };
+ init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, RGB8_2D)
+{
+ GLubyte data[] = { 77, 66, 55 };
+ init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, RG8_2D)
+{
+ GLubyte data[] = { 11, 99 };
+ init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, R8_2D)
+{
+ GLubyte data[] = { 2 };
+ init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, RGB10_A2_2D)
+{
+ GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
+ init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, RGBA32F_2D)
+{
+ GLfloat data[] = { 0.25f, 0.5f, 0.75f, 0.8f };
+ init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, RGB32F_2D)
+{
+ GLfloat data[] = { 0.1f, 0.2f, 0.3f };
+ init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, RG32F_2D)
+{
+ GLfloat data[] = { 0.9f, 0.1f };
+ init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, R32F_2D)
+{
+ GLfloat data[] = { 0.5f };
+ init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, D32F_2D)
+{
+ GLfloat data[] = { 0.5f };
+ init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, D16_2D)
+{
+ GLushort data[] = { 0xFF };
+ init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, D24_2D)
+{
+ GLuint data[] = { 0xFFFF };
+ init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, L8_2D)
+{
+ GLubyte data[] = {0x77};
+ init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, A8_2D)
+{
+ GLubyte data[] = {0x55};
+ init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, LA8_2D)
+{
+ GLubyte data[] = {0x77, 0x66};
+ init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, L32F_2D)
+{
+ GLfloat data[] = {0.7f};
+ init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, A32F_2D)
+{
+ GLfloat data[] = {
+ 0.4f,
+ };
+ init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data);
+ runTest2D();
+}
+
+TEST_P(SwizzleTest, LA32F_2D)
+{
+ GLfloat data[] = {
+ 0.5f, 0.6f,
+ };
+ init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, data);
+ runTest2D();
+}
+
+#include "media/pixel.inl"
+
+TEST_P(SwizzleTest, CompressedDXT_2D)
+{
+ if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
+ {
+ std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1." << std::endl;
+ return;
+ }
+
+ init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, pixel_0_size, pixel_0_data);
+ runTest2D();
+}
+
+TEST_P(SwizzleIntegerTest, RGB8UI_2D)
+{
+ GLubyte data[] = {77, 66, 55};
+ init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
+ runTest2D();
+}
+
+// Test that updating the texture data still generates the correct swizzles
+TEST_P(SwizzleTest, SubUpdate)
+{
+ GLColor data(1, 64, 128, 200);
+ init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data);
+
+ glUseProgram(mProgram);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ glUniform1i(mTextureUniformLocation, 0);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ drawQuad(mProgram, "position", 0.5f);
+
+ GLColor expectedData(data.R, data.R, data.R, data.R);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, expectedData);
+
+ GLColor updateData(32, 234, 28, 232);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &updateData);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ drawQuad(mProgram, "position", 0.5f);
+
+ GLColor expectedUpdateData(updateData.R, updateData.R, updateData.R, updateData.R);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
+ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGL(3, 3), ES3_OPENGLES());
+ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest,
+ ES3_D3D11(),
+ ES3_OPENGL(),
+ ES3_OPENGL(3, 3),
+ ES3_OPENGLES());
+
+} // namespace