blob: 2c83f5cdbf4b1196acee10348e6e6b58f91bc27a [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 {
143 glUseProgram(mProgram);
144 glBindTexture(GL_TEXTURE_2D, mTexture);
145 glUniform1i(mTextureUniformLocation, 0);
146
147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
151
152 glClear(GL_COLOR_BUFFER_BIT);
153 drawQuad(mProgram, "position", 0.5f);
154
155 GLubyte unswizzled[4];
156 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &unswizzled);
157
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400158 ASSERT_GL_NO_ERROR();
159
Geoff Langd61396b2017-03-06 14:49:46 -0800160 for (const auto &permutation : mPermutations)
Geoff Lang2c254d82014-01-15 14:51:23 -0500161 {
Geoff Lang2c254d82014-01-15 14:51:23 -0500162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, permutation.swizzleRed);
163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, permutation.swizzleGreen);
164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, permutation.swizzleBlue);
165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, permutation.swizzleAlpha);
166
167 glClear(GL_COLOR_BUFFER_BIT);
168 drawQuad(mProgram, "position", 0.5f);
169
170 EXPECT_PIXEL_EQ(0, 0,
171 getExpectedValue(permutation.swizzleRed, unswizzled),
172 getExpectedValue(permutation.swizzleGreen, unswizzled),
173 getExpectedValue(permutation.swizzleBlue, unswizzled),
174 getExpectedValue(permutation.swizzleAlpha, unswizzled));
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400175
176 ASSERT_GL_NO_ERROR();
Geoff Lang2c254d82014-01-15 14:51:23 -0500177 }
178 }
179
180 GLuint mProgram;
181 GLint mTextureUniformLocation;
182
183 GLuint mTexture;
184
185 struct swizzlePermutation
186 {
187 GLenum swizzleRed;
188 GLenum swizzleGreen;
189 GLenum swizzleBlue;
190 GLenum swizzleAlpha;
191 };
192 std::vector<swizzlePermutation> mPermutations;
193};
194
Olli Etuaho7b591902016-02-26 14:37:57 +0200195class SwizzleIntegerTest : public SwizzleTest
196{
197 protected:
198 void SetUp() override
199 {
200 ANGLETest::SetUp();
201
202 const std::string vertexShaderSource =
203 "#version 300 es\n"
204 "precision highp float;\n"
205 "in vec4 position;\n"
206 "out vec2 texcoord;\n"
207 "\n"
208 "void main()\n"
209 "{\n"
210 " gl_Position = position;\n"
211 " texcoord = (position.xy * 0.5) + 0.5;\n"
212 "}\n";
213
214 const std::string fragmentShaderSource =
215 "#version 300 es\n"
216 "precision highp float;\n"
217 "precision highp usampler2D;\n"
218 "uniform usampler2D tex;\n"
219 "in vec2 texcoord;\n"
220 "out vec4 my_FragColor;\n"
221 "\n"
222 "void main()\n"
223 "{\n"
224 " uvec4 s = texture(tex, texcoord);\n"
225 " if (s[0] == 1u) s[0] = 255u;\n"
226 " if (s[1] == 1u) s[1] = 255u;\n"
227 " if (s[2] == 1u) s[2] = 255u;\n"
228 " if (s[3] == 1u) s[3] = 255u;\n"
229 " my_FragColor = vec4(s) / 255.0;\n"
230 "}\n";
231
232 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
233 ASSERT_NE(0u, mProgram);
234
235 mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
236 ASSERT_NE(-1, mTextureUniformLocation);
237
238 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
239 ASSERT_GL_NO_ERROR();
240 }
241};
242
Jamie Madillfa05f602015-05-07 13:47:11 -0400243TEST_P(SwizzleTest, RGBA8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500244{
245 GLubyte data[] = { 1, 64, 128, 200 };
246 init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
247 runTest2D();
248}
249
Jamie Madillfa05f602015-05-07 13:47:11 -0400250TEST_P(SwizzleTest, RGB8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500251{
252 GLubyte data[] = { 77, 66, 55 };
253 init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
254 runTest2D();
255}
256
Jamie Madillfa05f602015-05-07 13:47:11 -0400257TEST_P(SwizzleTest, RG8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500258{
259 GLubyte data[] = { 11, 99 };
260 init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
261 runTest2D();
262}
263
Jamie Madillfa05f602015-05-07 13:47:11 -0400264TEST_P(SwizzleTest, R8_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500265{
266 GLubyte data[] = { 2 };
Nico Weberce8bb2f2014-12-30 13:32:25 -0800267 init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
Geoff Lang2c254d82014-01-15 14:51:23 -0500268 runTest2D();
269}
270
Olli Etuahobc497582016-02-23 14:43:19 +0200271TEST_P(SwizzleTest, RGB10_A2_2D)
272{
273 GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
274 init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data);
275 runTest2D();
276}
277
Jamie Madillfa05f602015-05-07 13:47:11 -0400278TEST_P(SwizzleTest, RGBA32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500279{
280 GLfloat data[] = { 0.25f, 0.5f, 0.75f, 0.8f };
281 init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
282 runTest2D();
283}
284
Jamie Madillfa05f602015-05-07 13:47:11 -0400285TEST_P(SwizzleTest, RGB32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500286{
287 GLfloat data[] = { 0.1f, 0.2f, 0.3f };
288 init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
289 runTest2D();
290}
291
Jamie Madillfa05f602015-05-07 13:47:11 -0400292TEST_P(SwizzleTest, RG32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500293{
294 GLfloat data[] = { 0.9f, 0.1f };
295 init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
296 runTest2D();
297}
298
Jamie Madillfa05f602015-05-07 13:47:11 -0400299TEST_P(SwizzleTest, R32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500300{
301 GLfloat data[] = { 0.5f };
302 init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
303 runTest2D();
304}
305
Jamie Madillfa05f602015-05-07 13:47:11 -0400306TEST_P(SwizzleTest, D32F_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500307{
308 GLfloat data[] = { 0.5f };
309 init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
310 runTest2D();
311}
312
Jamie Madillfa05f602015-05-07 13:47:11 -0400313TEST_P(SwizzleTest, D16_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500314{
315 GLushort data[] = { 0xFF };
316 init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
317 runTest2D();
318}
319
Jamie Madillfa05f602015-05-07 13:47:11 -0400320TEST_P(SwizzleTest, D24_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500321{
322 GLuint data[] = { 0xFFFF };
323 init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
324 runTest2D();
325}
326
Geoff Lang53b8aec2015-08-24 10:33:25 -0400327TEST_P(SwizzleTest, L8_2D)
328{
329 GLubyte data[] = {0x77};
330 init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
331 runTest2D();
332}
333
334TEST_P(SwizzleTest, A8_2D)
335{
336 GLubyte data[] = {0x55};
337 init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data);
338 runTest2D();
339}
340
341TEST_P(SwizzleTest, LA8_2D)
342{
343 GLubyte data[] = {0x77, 0x66};
344 init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
345 runTest2D();
346}
347
348TEST_P(SwizzleTest, L32F_2D)
349{
Geoff Langca271392017-04-05 12:30:00 -0400350 if (!extensionEnabled("GL_OES_texture_float"))
351 {
352 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
353 return;
354 }
355
Geoff Lang53b8aec2015-08-24 10:33:25 -0400356 GLfloat data[] = {0.7f};
357 init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data);
358 runTest2D();
359}
360
361TEST_P(SwizzleTest, A32F_2D)
362{
Geoff Langca271392017-04-05 12:30:00 -0400363 if (!extensionEnabled("GL_OES_texture_float"))
364 {
365 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
366 return;
367 }
368
Geoff Lang53b8aec2015-08-24 10:33:25 -0400369 GLfloat data[] = {
370 0.4f,
371 };
372 init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data);
373 runTest2D();
374}
375
376TEST_P(SwizzleTest, LA32F_2D)
377{
Geoff Langca271392017-04-05 12:30:00 -0400378 if (!extensionEnabled("GL_OES_texture_float"))
379 {
380 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
381 return;
382 }
383
Geoff Lang53b8aec2015-08-24 10:33:25 -0400384 GLfloat data[] = {
385 0.5f, 0.6f,
386 };
387 init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, data);
388 runTest2D();
389}
390
Geoff Lang2c254d82014-01-15 14:51:23 -0500391#include "media/pixel.inl"
392
Jamie Madillfa05f602015-05-07 13:47:11 -0400393TEST_P(SwizzleTest, CompressedDXT_2D)
Geoff Lang2c254d82014-01-15 14:51:23 -0500394{
Geoff Lang167dceb2015-03-31 12:49:57 -0400395 if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
396 {
Geoff Langf34d1db2015-05-20 14:10:46 -0400397 std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1." << std::endl;
Geoff Lang167dceb2015-03-31 12:49:57 -0400398 return;
399 }
400
Geoff Lang2c254d82014-01-15 14:51:23 -0500401 init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, pixel_0_size, pixel_0_data);
402 runTest2D();
403}
Jamie Madillfa05f602015-05-07 13:47:11 -0400404
Olli Etuaho7b591902016-02-26 14:37:57 +0200405TEST_P(SwizzleIntegerTest, RGB8UI_2D)
406{
407 GLubyte data[] = {77, 66, 55};
408 init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
409 runTest2D();
410}
411
Geoff Lang5b46a682016-09-01 15:22:06 -0400412// Test that updating the texture data still generates the correct swizzles
413TEST_P(SwizzleTest, SubUpdate)
414{
415 GLColor data(1, 64, 128, 200);
416 init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data);
417
418 glUseProgram(mProgram);
419 glBindTexture(GL_TEXTURE_2D, mTexture);
420 glUniform1i(mTextureUniformLocation, 0);
421
422 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
425 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
426
427 glClear(GL_COLOR_BUFFER_BIT);
428 drawQuad(mProgram, "position", 0.5f);
429
430 GLColor expectedData(data.R, data.R, data.R, data.R);
431 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedData);
432
433 GLColor updateData(32, 234, 28, 232);
434 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &updateData);
435
436 glClear(GL_COLOR_BUFFER_BIT);
437 drawQuad(mProgram, "position", 0.5f);
438
439 GLColor expectedUpdateData(updateData.R, updateData.R, updateData.R, updateData.R);
440 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
441}
442
Jamie Madillfa05f602015-05-07 13:47:11 -0400443// 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 -0500444ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGL(3, 3), ES3_OPENGLES());
Olli Etuaho7b591902016-02-26 14:37:57 +0200445ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest,
446 ES3_D3D11(),
447 ES3_OPENGL(),
448 ES3_OPENGL(3, 3),
449 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -0400450
451} // namespace