blob: 3e533819c58d9f512444d8d4ab16e22f0a1c526e [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Geoff Lang2c254d82014-01-15 14:51:23 -05008
9#include <vector>
10
Jamie Madillfa05f602015-05-07 13:47:11 -040011using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070012
Jamie Madillfa05f602015-05-07 13:47:11 -040013namespace
14{
15
Geoff Lang2c254d82014-01-15 14:51:23 -050016class SwizzleTest : public ANGLETest
17{
Jamie Madillfa05f602015-05-07 13:47:11 -040018 protected:
19 SwizzleTest()
Geoff Lang2c254d82014-01-15 14:51:23 -050020 {
21 setWindowWidth(128);
22 setWindowHeight(128);
23 setConfigRedBits(8);
24 setConfigGreenBits(8);
25 setConfigBlueBits(8);
26 setConfigAlphaBits(8);
Geoff Lang2c254d82014-01-15 14:51:23 -050027
Geoff Langd61396b2017-03-06 14:49:46 -080028 constexpr GLenum swizzles[] = {
29 GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE,
Geoff Lang2c254d82014-01-15 14:51:23 -050030 };
31
Geoff Langd61396b2017-03-06 14:49:46 -080032 // Only use every 13th swizzle permutation, use a prime number to make sure the permuations
33 // are somewhat evenly distributed. Reduces the permuations from 1296 to 100.
34 constexpr size_t swizzleReductionFactor = 13;
35
36 size_t swizzleCount = 0;
37 for (GLenum r : swizzles)
Geoff Lang2c254d82014-01-15 14:51:23 -050038 {
Geoff Langd61396b2017-03-06 14:49:46 -080039 for (GLenum g : swizzles)
Geoff Lang2c254d82014-01-15 14:51:23 -050040 {
Geoff Langd61396b2017-03-06 14:49:46 -080041 for (GLenum b : swizzles)
Geoff Lang2c254d82014-01-15 14:51:23 -050042 {
Geoff Langd61396b2017-03-06 14:49:46 -080043 for (GLenum a : swizzles)
Geoff Lang2c254d82014-01-15 14:51:23 -050044 {
Geoff Langd61396b2017-03-06 14:49:46 -080045 swizzleCount++;
46 if (swizzleCount % swizzleReductionFactor != 0)
47 {
48 continue;
49 }
50
Geoff Lang2c254d82014-01-15 14:51:23 -050051 swizzlePermutation permutation;
Geoff Langd61396b2017-03-06 14:49:46 -080052 permutation.swizzleRed = r;
53 permutation.swizzleGreen = g;
54 permutation.swizzleBlue = b;
55 permutation.swizzleAlpha = a;
Geoff Lang2c254d82014-01-15 14:51:23 -050056 mPermutations.push_back(permutation);
57 }
58 }
59 }
60 }
61 }
62
Jamie Madillfa05f602015-05-07 13:47:11 -040063 void SetUp() override
Geoff Lang2c254d82014-01-15 14:51:23 -050064 {
65 ANGLETest::SetUp();
66
67 const std::string vertexShaderSource = SHADER_SOURCE
68 (
69 precision highp float;
70 attribute vec4 position;
71 varying vec2 texcoord;
72
73 void main()
74 {
75 gl_Position = position;
76 texcoord = (position.xy * 0.5) + 0.5;
77 }
78 );
79
80 const std::string fragmentShaderSource = SHADER_SOURCE
81 (
82 precision highp float;
83 uniform sampler2D tex;
84 varying vec2 texcoord;
85
86 void main()
87 {
88 gl_FragColor = texture2D(tex, texcoord);
89 }
90 );
91
Jamie Madill5599c8f2014-08-26 13:16:39 -040092 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
Olli Etuaho7b591902016-02-26 14:37:57 +020093 ASSERT_NE(0u, mProgram);
Geoff Lang2c254d82014-01-15 14:51:23 -050094
95 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
Olli Etuaho7b591902016-02-26 14:37:57 +020096 ASSERT_NE(-1, mTextureUniformLocation);
Geoff Lang2c254d82014-01-15 14:51:23 -050097
98 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Jamie Madill1ea9aaa2015-10-07 11:13:55 -040099 ASSERT_GL_NO_ERROR();
Geoff Lang2c254d82014-01-15 14:51:23 -0500100 }
101
Jamie Madillfa05f602015-05-07 13:47:11 -0400102 void TearDown() override
Geoff Lang2c254d82014-01-15 14:51:23 -0500103 {
104 glDeleteProgram(mProgram);
105 glDeleteTextures(1, &mTexture);
106
107 ANGLETest::TearDown();
108 }
109
110 template <typename T>
111 void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T* data)
112 {
113 glGenTextures(1, &mTexture);
114 glBindTexture(GL_TEXTURE_2D, mTexture);
Geoff Lang53b8aec2015-08-24 10:33:25 -0400115 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, dataFormat, dataType, data);
Geoff Lang2c254d82014-01-15 14:51:23 -0500116
117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
119 }
120
121 void init2DCompressedTexture(GLenum internalFormat, GLsizei width, GLsizei height, GLsizei dataSize, const GLubyte* data)
122 {
123 glGenTextures(1, &mTexture);
124 glBindTexture(GL_TEXTURE_2D, mTexture);
125 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, dataSize, data);
126
127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
129 }
130
131 GLubyte getExpectedValue(GLenum swizzle, GLubyte unswizzled[4])
132 {
133 switch (swizzle)
134 {
135 case GL_RED: return unswizzled[0];
136 case GL_GREEN: return unswizzled[1];
137 case GL_BLUE: return unswizzled[2];
138 case GL_ALPHA: return unswizzled[3];
139 case GL_ZERO: return 0;
140 case GL_ONE: return 255;
141 default: return 0;
142 }
143 }
144
145 void runTest2D()
146 {
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400147 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -0500148 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400149 {
150 std::cout << "Test skipped on Intel." << std::endl;
151 return;
152 }
153
Geoff Lang2c254d82014-01-15 14:51:23 -0500154 glUseProgram(mProgram);
155 glBindTexture(GL_TEXTURE_2D, mTexture);
156 glUniform1i(mTextureUniformLocation, 0);
157
158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
161 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
162
163 glClear(GL_COLOR_BUFFER_BIT);
164 drawQuad(mProgram, "position", 0.5f);
165
166 GLubyte unswizzled[4];
167 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &unswizzled);
168
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400169 ASSERT_GL_NO_ERROR();
170
Geoff Langd61396b2017-03-06 14:49:46 -0800171 for (const auto &permutation : mPermutations)
Geoff Lang2c254d82014-01-15 14:51:23 -0500172 {
Geoff Lang2c254d82014-01-15 14:51:23 -0500173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, permutation.swizzleRed);
174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, permutation.swizzleGreen);
175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, permutation.swizzleBlue);
176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, permutation.swizzleAlpha);
177
178 glClear(GL_COLOR_BUFFER_BIT);
179 drawQuad(mProgram, "position", 0.5f);
180
181 EXPECT_PIXEL_EQ(0, 0,
182 getExpectedValue(permutation.swizzleRed, unswizzled),
183 getExpectedValue(permutation.swizzleGreen, unswizzled),
184 getExpectedValue(permutation.swizzleBlue, unswizzled),
185 getExpectedValue(permutation.swizzleAlpha, unswizzled));
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400186
187 ASSERT_GL_NO_ERROR();
Geoff Lang2c254d82014-01-15 14:51:23 -0500188 }
189 }
190
191 GLuint mProgram;
192 GLint mTextureUniformLocation;
193
194 GLuint mTexture;
195
196 struct swizzlePermutation
197 {
198 GLenum swizzleRed;
199 GLenum swizzleGreen;
200 GLenum swizzleBlue;
201 GLenum swizzleAlpha;
202 };
203 std::vector<swizzlePermutation> mPermutations;
204};
205
Olli Etuaho7b591902016-02-26 14:37:57 +0200206class SwizzleIntegerTest : public SwizzleTest
207{
208 protected:
209 void SetUp() override
210 {
211 ANGLETest::SetUp();
212
213 const std::string vertexShaderSource =
214 "#version 300 es\n"
215 "precision highp float;\n"
216 "in vec4 position;\n"
217 "out vec2 texcoord;\n"
218 "\n"
219 "void main()\n"
220 "{\n"
221 " gl_Position = position;\n"
222 " texcoord = (position.xy * 0.5) + 0.5;\n"
223 "}\n";
224
225 const std::string fragmentShaderSource =
226 "#version 300 es\n"
227 "precision highp float;\n"
228 "precision highp usampler2D;\n"
229 "uniform usampler2D tex;\n"
230 "in vec2 texcoord;\n"
231 "out vec4 my_FragColor;\n"
232 "\n"
233 "void main()\n"
234 "{\n"
235 " uvec4 s = texture(tex, texcoord);\n"
236 " if (s[0] == 1u) s[0] = 255u;\n"
237 " if (s[1] == 1u) s[1] = 255u;\n"
238 " if (s[2] == 1u) s[2] = 255u;\n"
239 " if (s[3] == 1u) s[3] = 255u;\n"
240 " my_FragColor = vec4(s) / 255.0;\n"
241 "}\n";
242
243 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
244 ASSERT_NE(0u, mProgram);
245
246 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
247 ASSERT_NE(-1, mTextureUniformLocation);
248
249 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
250 ASSERT_GL_NO_ERROR();
251 }
252};
253
Jamie Madillfa05f602015-05-07 13:47:11 -0400254TEST_P(SwizzleTest, RGBA8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500255{
256 GLubyte data[] = { 1, 64, 128, 200 };
257 init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
258 runTest2D();
259}
260
Jamie Madillfa05f602015-05-07 13:47:11 -0400261TEST_P(SwizzleTest, RGB8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500262{
263 GLubyte data[] = { 77, 66, 55 };
264 init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
265 runTest2D();
266}
267
Jamie Madillfa05f602015-05-07 13:47:11 -0400268TEST_P(SwizzleTest, RG8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500269{
270 GLubyte data[] = { 11, 99 };
271 init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
272 runTest2D();
273}
274
Jamie Madillfa05f602015-05-07 13:47:11 -0400275TEST_P(SwizzleTest, R8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500276{
277 GLubyte data[] = { 2 };
Nico Weberce8bb2f2014-12-30 13:32:25 -0800278 init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
Geoff Lang2c254d82014-01-15 14:51:23 -0500279 runTest2D();
280}
281
Olli Etuahobc497582016-02-23 14:43:19 +0200282TEST_P(SwizzleTest, RGB10_A2_2D)
283{
284 GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
285 init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data);
286 runTest2D();
287}
288
Jamie Madillfa05f602015-05-07 13:47:11 -0400289TEST_P(SwizzleTest, RGBA32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500290{
291 GLfloat data[] = { 0.25f, 0.5f, 0.75f, 0.8f };
292 init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
293 runTest2D();
294}
295
Jamie Madillfa05f602015-05-07 13:47:11 -0400296TEST_P(SwizzleTest, RGB32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500297{
298 GLfloat data[] = { 0.1f, 0.2f, 0.3f };
299 init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
300 runTest2D();
301}
302
Jamie Madillfa05f602015-05-07 13:47:11 -0400303TEST_P(SwizzleTest, RG32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500304{
305 GLfloat data[] = { 0.9f, 0.1f };
306 init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
307 runTest2D();
308}
309
Jamie Madillfa05f602015-05-07 13:47:11 -0400310TEST_P(SwizzleTest, R32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500311{
312 GLfloat data[] = { 0.5f };
313 init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
314 runTest2D();
315}
316
Jamie Madillfa05f602015-05-07 13:47:11 -0400317TEST_P(SwizzleTest, D32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500318{
319 GLfloat data[] = { 0.5f };
320 init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
321 runTest2D();
322}
323
Jamie Madillfa05f602015-05-07 13:47:11 -0400324TEST_P(SwizzleTest, D16_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500325{
326 GLushort data[] = { 0xFF };
327 init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
328 runTest2D();
329}
330
Jamie Madillfa05f602015-05-07 13:47:11 -0400331TEST_P(SwizzleTest, D24_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500332{
333 GLuint data[] = { 0xFFFF };
334 init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
335 runTest2D();
336}
337
Geoff Lang53b8aec2015-08-24 10:33:25 -0400338TEST_P(SwizzleTest, L8_2D)
339{
340 GLubyte data[] = {0x77};
341 init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
342 runTest2D();
343}
344
345TEST_P(SwizzleTest, A8_2D)
346{
347 GLubyte data[] = {0x55};
348 init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data);
349 runTest2D();
350}
351
352TEST_P(SwizzleTest, LA8_2D)
353{
354 GLubyte data[] = {0x77, 0x66};
355 init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
356 runTest2D();
357}
358
359TEST_P(SwizzleTest, L32F_2D)
360{
361 GLfloat data[] = {0.7f};
362 init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data);
363 runTest2D();
364}
365
366TEST_P(SwizzleTest, A32F_2D)
367{
368 GLfloat data[] = {
369 0.4f,
370 };
371 init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data);
372 runTest2D();
373}
374
375TEST_P(SwizzleTest, LA32F_2D)
376{
377 GLfloat data[] = {
378 0.5f, 0.6f,
379 };
380 init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, data);
381 runTest2D();
382}
383
Geoff Lang2c254d82014-01-15 14:51:23 -0500384#include "media/pixel.inl"
385
Jamie Madillfa05f602015-05-07 13:47:11 -0400386TEST_P(SwizzleTest, CompressedDXT_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500387{
Geoff Lang167dceb2015-03-31 12:49:57 -0400388 if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
389 {
Geoff Langf34d1db2015-05-20 14:10:46 -0400390 std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1." << std::endl;
Geoff Lang167dceb2015-03-31 12:49:57 -0400391 return;
392 }
393
Geoff Lang2c254d82014-01-15 14:51:23 -0500394 init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, pixel_0_size, pixel_0_data);
395 runTest2D();
396}
Jamie Madillfa05f602015-05-07 13:47:11 -0400397
Olli Etuaho7b591902016-02-26 14:37:57 +0200398TEST_P(SwizzleIntegerTest, RGB8UI_2D)
399{
400 GLubyte data[] = {77, 66, 55};
401 init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
402 runTest2D();
403}
404
Geoff Lang5b46a682016-09-01 15:22:06 -0400405// Test that updating the texture data still generates the correct swizzles
406TEST_P(SwizzleTest, SubUpdate)
407{
408 GLColor data(1, 64, 128, 200);
409 init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data);
410
411 glUseProgram(mProgram);
412 glBindTexture(GL_TEXTURE_2D, mTexture);
413 glUniform1i(mTextureUniformLocation, 0);
414
415 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
416 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
417 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
418 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
419
420 glClear(GL_COLOR_BUFFER_BIT);
421 drawQuad(mProgram, "position", 0.5f);
422
423 GLColor expectedData(data.R, data.R, data.R, data.R);
424 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedData);
425
426 GLColor updateData(32, 234, 28, 232);
427 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &updateData);
428
429 glClear(GL_COLOR_BUFFER_BIT);
430 drawQuad(mProgram, "position", 0.5f);
431
432 GLColor expectedUpdateData(updateData.R, updateData.R, updateData.R, updateData.R);
433 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
434}
435
Jamie Madillfa05f602015-05-07 13:47:11 -0400436// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500437ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGL(3, 3), ES3_OPENGLES());
Olli Etuaho7b591902016-02-26 14:37:57 +0200438ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest,
439 ES3_D3D11(),
440 ES3_OPENGL(),
441 ES3_OPENGL(3, 3),
442 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -0400443
444} // namespace