blob: e82f11da4a4cb973f8ad00089dc4ad4f9b39423b [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
Olli Etuahoa20af6d2017-09-18 13:32:29 +030067 const std::string vertexShaderSource =
68 R"(precision highp float;
Geoff Lang2c254d82014-01-15 14:51:23 -050069 attribute vec4 position;
70 varying vec2 texcoord;
71
72 void main()
73 {
74 gl_Position = position;
75 texcoord = (position.xy * 0.5) + 0.5;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030076 })";
Geoff Lang2c254d82014-01-15 14:51:23 -050077
Olli Etuahoa20af6d2017-09-18 13:32:29 +030078 const std::string fragmentShaderSource =
79 R"(precision highp float;
Geoff Lang2c254d82014-01-15 14:51:23 -050080 uniform sampler2D tex;
81 varying vec2 texcoord;
82
83 void main()
84 {
85 gl_FragColor = texture2D(tex, texcoord);
Olli Etuahoa20af6d2017-09-18 13:32:29 +030086 })";
Geoff Lang2c254d82014-01-15 14:51:23 -050087
Jamie Madill5599c8f2014-08-26 13:16:39 -040088 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
Olli Etuaho7b591902016-02-26 14:37:57 +020089 ASSERT_NE(0u, mProgram);
Geoff Lang2c254d82014-01-15 14:51:23 -050090
91 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
Olli Etuaho7b591902016-02-26 14:37:57 +020092 ASSERT_NE(-1, mTextureUniformLocation);
Geoff Lang2c254d82014-01-15 14:51:23 -050093
94 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Jamie Madill1ea9aaa2015-10-07 11:13:55 -040095 ASSERT_GL_NO_ERROR();
Geoff Lang2c254d82014-01-15 14:51:23 -050096 }
97
Jamie Madillfa05f602015-05-07 13:47:11 -040098 void TearDown() override
Geoff Lang2c254d82014-01-15 14:51:23 -050099 {
100 glDeleteProgram(mProgram);
101 glDeleteTextures(1, &mTexture);
102
103 ANGLETest::TearDown();
104 }
105
106 template <typename T>
107 void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T* data)
108 {
109 glGenTextures(1, &mTexture);
110 glBindTexture(GL_TEXTURE_2D, mTexture);
Geoff Lang53b8aec2015-08-24 10:33:25 -0400111 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, dataFormat, dataType, data);
Geoff Lang2c254d82014-01-15 14:51:23 -0500112
113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
115 }
116
117 void init2DCompressedTexture(GLenum internalFormat, GLsizei width, GLsizei height, GLsizei dataSize, const GLubyte* data)
118 {
119 glGenTextures(1, &mTexture);
120 glBindTexture(GL_TEXTURE_2D, mTexture);
121 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, dataSize, data);
122
123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
125 }
126
127 GLubyte getExpectedValue(GLenum swizzle, GLubyte unswizzled[4])
128 {
129 switch (swizzle)
130 {
131 case GL_RED: return unswizzled[0];
132 case GL_GREEN: return unswizzled[1];
133 case GL_BLUE: return unswizzled[2];
134 case GL_ALPHA: return unswizzled[3];
135 case GL_ZERO: return 0;
136 case GL_ONE: return 255;
137 default: return 0;
138 }
139 }
140
141 void runTest2D()
142 {
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400143 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -0500144 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400145 {
146 std::cout << "Test skipped on Intel." << std::endl;
147 return;
148 }
149
Geoff Lang2c254d82014-01-15 14:51:23 -0500150 glUseProgram(mProgram);
151 glBindTexture(GL_TEXTURE_2D, mTexture);
152 glUniform1i(mTextureUniformLocation, 0);
153
154 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
155 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
156 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
158
159 glClear(GL_COLOR_BUFFER_BIT);
160 drawQuad(mProgram, "position", 0.5f);
161
162 GLubyte unswizzled[4];
163 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &unswizzled);
164
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400165 ASSERT_GL_NO_ERROR();
166
Geoff Langd61396b2017-03-06 14:49:46 -0800167 for (const auto &permutation : mPermutations)
Geoff Lang2c254d82014-01-15 14:51:23 -0500168 {
Geoff Lang2c254d82014-01-15 14:51:23 -0500169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, permutation.swizzleRed);
170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, permutation.swizzleGreen);
171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, permutation.swizzleBlue);
172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, permutation.swizzleAlpha);
173
174 glClear(GL_COLOR_BUFFER_BIT);
175 drawQuad(mProgram, "position", 0.5f);
176
177 EXPECT_PIXEL_EQ(0, 0,
178 getExpectedValue(permutation.swizzleRed, unswizzled),
179 getExpectedValue(permutation.swizzleGreen, unswizzled),
180 getExpectedValue(permutation.swizzleBlue, unswizzled),
181 getExpectedValue(permutation.swizzleAlpha, unswizzled));
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400182
183 ASSERT_GL_NO_ERROR();
Geoff Lang2c254d82014-01-15 14:51:23 -0500184 }
185 }
186
187 GLuint mProgram;
188 GLint mTextureUniformLocation;
189
190 GLuint mTexture;
191
192 struct swizzlePermutation
193 {
194 GLenum swizzleRed;
195 GLenum swizzleGreen;
196 GLenum swizzleBlue;
197 GLenum swizzleAlpha;
198 };
199 std::vector<swizzlePermutation> mPermutations;
200};
201
Olli Etuaho7b591902016-02-26 14:37:57 +0200202class SwizzleIntegerTest : public SwizzleTest
203{
204 protected:
205 void SetUp() override
206 {
207 ANGLETest::SetUp();
208
209 const std::string vertexShaderSource =
210 "#version 300 es\n"
211 "precision highp float;\n"
212 "in vec4 position;\n"
213 "out vec2 texcoord;\n"
214 "\n"
215 "void main()\n"
216 "{\n"
217 " gl_Position = position;\n"
218 " texcoord = (position.xy * 0.5) + 0.5;\n"
219 "}\n";
220
221 const std::string fragmentShaderSource =
222 "#version 300 es\n"
223 "precision highp float;\n"
224 "precision highp usampler2D;\n"
225 "uniform usampler2D tex;\n"
226 "in vec2 texcoord;\n"
227 "out vec4 my_FragColor;\n"
228 "\n"
229 "void main()\n"
230 "{\n"
231 " uvec4 s = texture(tex, texcoord);\n"
232 " if (s[0] == 1u) s[0] = 255u;\n"
233 " if (s[1] == 1u) s[1] = 255u;\n"
234 " if (s[2] == 1u) s[2] = 255u;\n"
235 " if (s[3] == 1u) s[3] = 255u;\n"
236 " my_FragColor = vec4(s) / 255.0;\n"
237 "}\n";
238
239 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
240 ASSERT_NE(0u, mProgram);
241
242 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
243 ASSERT_NE(-1, mTextureUniformLocation);
244
245 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
246 ASSERT_GL_NO_ERROR();
247 }
248};
249
Jamie Madillfa05f602015-05-07 13:47:11 -0400250TEST_P(SwizzleTest, RGBA8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500251{
252 GLubyte data[] = { 1, 64, 128, 200 };
253 init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
254 runTest2D();
255}
256
Jamie Madillfa05f602015-05-07 13:47:11 -0400257TEST_P(SwizzleTest, RGB8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500258{
259 GLubyte data[] = { 77, 66, 55 };
260 init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
261 runTest2D();
262}
263
Jamie Madillfa05f602015-05-07 13:47:11 -0400264TEST_P(SwizzleTest, RG8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500265{
266 GLubyte data[] = { 11, 99 };
267 init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
268 runTest2D();
269}
270
Jamie Madillfa05f602015-05-07 13:47:11 -0400271TEST_P(SwizzleTest, R8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500272{
273 GLubyte data[] = { 2 };
Nico Weberce8bb2f2014-12-30 13:32:25 -0800274 init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
Geoff Lang2c254d82014-01-15 14:51:23 -0500275 runTest2D();
276}
277
Olli Etuahobc497582016-02-23 14:43:19 +0200278TEST_P(SwizzleTest, RGB10_A2_2D)
279{
280 GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
281 init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data);
282 runTest2D();
283}
284
Jamie Madillfa05f602015-05-07 13:47:11 -0400285TEST_P(SwizzleTest, RGBA32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500286{
287 GLfloat data[] = { 0.25f, 0.5f, 0.75f, 0.8f };
288 init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
289 runTest2D();
290}
291
Jamie Madillfa05f602015-05-07 13:47:11 -0400292TEST_P(SwizzleTest, RGB32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500293{
294 GLfloat data[] = { 0.1f, 0.2f, 0.3f };
295 init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
296 runTest2D();
297}
298
Jamie Madillfa05f602015-05-07 13:47:11 -0400299TEST_P(SwizzleTest, RG32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500300{
301 GLfloat data[] = { 0.9f, 0.1f };
302 init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
303 runTest2D();
304}
305
Jamie Madillfa05f602015-05-07 13:47:11 -0400306TEST_P(SwizzleTest, R32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500307{
308 GLfloat data[] = { 0.5f };
309 init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
310 runTest2D();
311}
312
Jamie Madillfa05f602015-05-07 13:47:11 -0400313TEST_P(SwizzleTest, D32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500314{
315 GLfloat data[] = { 0.5f };
316 init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
317 runTest2D();
318}
319
Jamie Madillfa05f602015-05-07 13:47:11 -0400320TEST_P(SwizzleTest, D16_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500321{
322 GLushort data[] = { 0xFF };
323 init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
324 runTest2D();
325}
326
Jamie Madillfa05f602015-05-07 13:47:11 -0400327TEST_P(SwizzleTest, D24_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500328{
329 GLuint data[] = { 0xFFFF };
330 init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
331 runTest2D();
332}
333
Geoff Lang53b8aec2015-08-24 10:33:25 -0400334TEST_P(SwizzleTest, L8_2D)
335{
336 GLubyte data[] = {0x77};
337 init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
338 runTest2D();
339}
340
341TEST_P(SwizzleTest, A8_2D)
342{
343 GLubyte data[] = {0x55};
344 init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data);
345 runTest2D();
346}
347
348TEST_P(SwizzleTest, LA8_2D)
349{
350 GLubyte data[] = {0x77, 0x66};
351 init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
352 runTest2D();
353}
354
355TEST_P(SwizzleTest, L32F_2D)
356{
Geoff Langca271392017-04-05 12:30:00 -0400357 if (!extensionEnabled("GL_OES_texture_float"))
358 {
359 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
360 return;
361 }
362
Geoff Lang53b8aec2015-08-24 10:33:25 -0400363 GLfloat data[] = {0.7f};
364 init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data);
365 runTest2D();
366}
367
368TEST_P(SwizzleTest, A32F_2D)
369{
Geoff Langca271392017-04-05 12:30:00 -0400370 if (!extensionEnabled("GL_OES_texture_float"))
371 {
372 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
373 return;
374 }
375
Geoff Lang53b8aec2015-08-24 10:33:25 -0400376 GLfloat data[] = {
377 0.4f,
378 };
379 init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data);
380 runTest2D();
381}
382
383TEST_P(SwizzleTest, LA32F_2D)
384{
Geoff Langca271392017-04-05 12:30:00 -0400385 if (!extensionEnabled("GL_OES_texture_float"))
386 {
387 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
388 return;
389 }
390
Geoff Lang53b8aec2015-08-24 10:33:25 -0400391 GLfloat data[] = {
392 0.5f, 0.6f,
393 };
394 init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, data);
395 runTest2D();
396}
397
Geoff Lang2c254d82014-01-15 14:51:23 -0500398#include "media/pixel.inl"
399
Jamie Madillfa05f602015-05-07 13:47:11 -0400400TEST_P(SwizzleTest, CompressedDXT_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500401{
Geoff Lang167dceb2015-03-31 12:49:57 -0400402 if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
403 {
Geoff Langf34d1db2015-05-20 14:10:46 -0400404 std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1." << std::endl;
Geoff Lang167dceb2015-03-31 12:49:57 -0400405 return;
406 }
407
Geoff Lang2c254d82014-01-15 14:51:23 -0500408 init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, pixel_0_size, pixel_0_data);
409 runTest2D();
410}
Jamie Madillfa05f602015-05-07 13:47:11 -0400411
Olli Etuaho7b591902016-02-26 14:37:57 +0200412TEST_P(SwizzleIntegerTest, RGB8UI_2D)
413{
414 GLubyte data[] = {77, 66, 55};
415 init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
416 runTest2D();
417}
418
Geoff Lang5b46a682016-09-01 15:22:06 -0400419// Test that updating the texture data still generates the correct swizzles
420TEST_P(SwizzleTest, SubUpdate)
421{
422 GLColor data(1, 64, 128, 200);
423 init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data);
424
425 glUseProgram(mProgram);
426 glBindTexture(GL_TEXTURE_2D, mTexture);
427 glUniform1i(mTextureUniformLocation, 0);
428
429 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
430 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
431 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
432 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
433
434 glClear(GL_COLOR_BUFFER_BIT);
435 drawQuad(mProgram, "position", 0.5f);
436
437 GLColor expectedData(data.R, data.R, data.R, data.R);
438 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedData);
439
440 GLColor updateData(32, 234, 28, 232);
441 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &updateData);
442
443 glClear(GL_COLOR_BUFFER_BIT);
444 drawQuad(mProgram, "position", 0.5f);
445
446 GLColor expectedUpdateData(updateData.R, updateData.R, updateData.R, updateData.R);
447 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
448}
449
Jamie Madillfa05f602015-05-07 13:47:11 -0400450// 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 -0500451ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGL(3, 3), ES3_OPENGLES());
Olli Etuaho7b591902016-02-26 14:37:57 +0200452ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest,
453 ES3_D3D11(),
454 ES3_OPENGL(),
455 ES3_OPENGL(3, 3),
456 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -0400457
458} // namespace