xref: /aosp_15_r20/external/angle/src/tests/gl_tests/SwizzleTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include <vector>
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker namespace
14*8975f5c5SAndroid Build Coastguard Worker {
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker class SwizzleTest : public ANGLETest<>
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker   protected:
SwizzleTest()19*8975f5c5SAndroid Build Coastguard Worker     SwizzleTest()
20*8975f5c5SAndroid Build Coastguard Worker     {
21*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(128);
22*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(128);
23*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
24*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
25*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
26*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
27*8975f5c5SAndroid Build Coastguard Worker 
28*8975f5c5SAndroid Build Coastguard Worker         constexpr GLenum swizzles[] = {
29*8975f5c5SAndroid Build Coastguard Worker             GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE,
30*8975f5c5SAndroid Build Coastguard Worker         };
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker         // Only use every 13th swizzle permutation, use a prime number to make sure the permuations
33*8975f5c5SAndroid Build Coastguard Worker         // are somewhat evenly distributed.  Reduces the permuations from 1296 to 100.
34*8975f5c5SAndroid Build Coastguard Worker         constexpr size_t swizzleReductionFactor = 13;
35*8975f5c5SAndroid Build Coastguard Worker 
36*8975f5c5SAndroid Build Coastguard Worker         size_t swizzleCount = 0;
37*8975f5c5SAndroid Build Coastguard Worker         for (GLenum r : swizzles)
38*8975f5c5SAndroid Build Coastguard Worker         {
39*8975f5c5SAndroid Build Coastguard Worker             for (GLenum g : swizzles)
40*8975f5c5SAndroid Build Coastguard Worker             {
41*8975f5c5SAndroid Build Coastguard Worker                 for (GLenum b : swizzles)
42*8975f5c5SAndroid Build Coastguard Worker                 {
43*8975f5c5SAndroid Build Coastguard Worker                     for (GLenum a : swizzles)
44*8975f5c5SAndroid Build Coastguard Worker                     {
45*8975f5c5SAndroid Build Coastguard Worker                         swizzleCount++;
46*8975f5c5SAndroid Build Coastguard Worker                         if (swizzleCount % swizzleReductionFactor != 0)
47*8975f5c5SAndroid Build Coastguard Worker                         {
48*8975f5c5SAndroid Build Coastguard Worker                             continue;
49*8975f5c5SAndroid Build Coastguard Worker                         }
50*8975f5c5SAndroid Build Coastguard Worker 
51*8975f5c5SAndroid Build Coastguard Worker                         swizzlePermutation permutation;
52*8975f5c5SAndroid Build Coastguard Worker                         permutation.swizzleRed   = r;
53*8975f5c5SAndroid Build Coastguard Worker                         permutation.swizzleGreen = g;
54*8975f5c5SAndroid Build Coastguard Worker                         permutation.swizzleBlue  = b;
55*8975f5c5SAndroid Build Coastguard Worker                         permutation.swizzleAlpha = a;
56*8975f5c5SAndroid Build Coastguard Worker                         mPermutations.push_back(permutation);
57*8975f5c5SAndroid Build Coastguard Worker                     }
58*8975f5c5SAndroid Build Coastguard Worker                 }
59*8975f5c5SAndroid Build Coastguard Worker             }
60*8975f5c5SAndroid Build Coastguard Worker         }
61*8975f5c5SAndroid Build Coastguard Worker     }
62*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()63*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
64*8975f5c5SAndroid Build Coastguard Worker     {
65*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] = R"(precision highp float;
66*8975f5c5SAndroid Build Coastguard Worker attribute vec4 position;
67*8975f5c5SAndroid Build Coastguard Worker varying vec2 texcoord;
68*8975f5c5SAndroid Build Coastguard Worker 
69*8975f5c5SAndroid Build Coastguard Worker void main()
70*8975f5c5SAndroid Build Coastguard Worker {
71*8975f5c5SAndroid Build Coastguard Worker     gl_Position = position;
72*8975f5c5SAndroid Build Coastguard Worker     texcoord = (position.xy * 0.5) + 0.5;
73*8975f5c5SAndroid Build Coastguard Worker })";
74*8975f5c5SAndroid Build Coastguard Worker 
75*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] = R"(precision highp float;
76*8975f5c5SAndroid Build Coastguard Worker uniform sampler2D tex;
77*8975f5c5SAndroid Build Coastguard Worker varying vec2 texcoord;
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker void main()
80*8975f5c5SAndroid Build Coastguard Worker {
81*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = texture2D(tex, texcoord);
82*8975f5c5SAndroid Build Coastguard Worker })";
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(kVS, kFS);
85*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, mProgram);
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker         mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
88*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, mTextureUniformLocation);
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
91*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
92*8975f5c5SAndroid Build Coastguard Worker     }
93*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()94*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
95*8975f5c5SAndroid Build Coastguard Worker     {
96*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mProgram);
97*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &mTexture);
98*8975f5c5SAndroid Build Coastguard Worker     }
99*8975f5c5SAndroid Build Coastguard Worker 
isTextureSwizzleAvailable() const100*8975f5c5SAndroid Build Coastguard Worker     bool isTextureSwizzleAvailable() const
101*8975f5c5SAndroid Build Coastguard Worker     {
102*8975f5c5SAndroid Build Coastguard Worker         // On Metal back-end, texture swizzle is not always supported.
103*8975f5c5SAndroid Build Coastguard Worker         return !IsMetal() || IsMetalTextureSwizzleAvailable();
104*8975f5c5SAndroid Build Coastguard Worker     }
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker     template <typename T>
init2DTexture(GLenum internalFormat,GLenum dataFormat,GLenum dataType,const T * data)107*8975f5c5SAndroid Build Coastguard Worker     void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T *data)
108*8975f5c5SAndroid Build Coastguard Worker     {
109*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mTexture);
110*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, mTexture);
111*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, dataFormat, dataType, data);
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
114*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
115*8975f5c5SAndroid Build Coastguard Worker     }
116*8975f5c5SAndroid Build Coastguard Worker 
init2DCompressedTexture(GLenum internalFormat,GLsizei width,GLsizei height,GLsizei dataSize,const GLubyte * data)117*8975f5c5SAndroid Build Coastguard Worker     void init2DCompressedTexture(GLenum internalFormat,
118*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei width,
119*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei height,
120*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei dataSize,
121*8975f5c5SAndroid Build Coastguard Worker                                  const GLubyte *data)
122*8975f5c5SAndroid Build Coastguard Worker     {
123*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mTexture);
124*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, mTexture);
125*8975f5c5SAndroid Build Coastguard Worker         glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataSize, data);
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
128*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
129*8975f5c5SAndroid Build Coastguard Worker     }
130*8975f5c5SAndroid Build Coastguard Worker 
getExpectedValue(GLenum swizzle,GLubyte unswizzled[4])131*8975f5c5SAndroid Build Coastguard Worker     GLubyte getExpectedValue(GLenum swizzle, GLubyte unswizzled[4])
132*8975f5c5SAndroid Build Coastguard Worker     {
133*8975f5c5SAndroid Build Coastguard Worker         switch (swizzle)
134*8975f5c5SAndroid Build Coastguard Worker         {
135*8975f5c5SAndroid Build Coastguard Worker             case GL_RED:
136*8975f5c5SAndroid Build Coastguard Worker                 return unswizzled[0];
137*8975f5c5SAndroid Build Coastguard Worker             case GL_GREEN:
138*8975f5c5SAndroid Build Coastguard Worker                 return unswizzled[1];
139*8975f5c5SAndroid Build Coastguard Worker             case GL_BLUE:
140*8975f5c5SAndroid Build Coastguard Worker                 return unswizzled[2];
141*8975f5c5SAndroid Build Coastguard Worker             case GL_ALPHA:
142*8975f5c5SAndroid Build Coastguard Worker                 return unswizzled[3];
143*8975f5c5SAndroid Build Coastguard Worker             case GL_ZERO:
144*8975f5c5SAndroid Build Coastguard Worker                 return 0;
145*8975f5c5SAndroid Build Coastguard Worker             case GL_ONE:
146*8975f5c5SAndroid Build Coastguard Worker                 return 255;
147*8975f5c5SAndroid Build Coastguard Worker             default:
148*8975f5c5SAndroid Build Coastguard Worker                 return 0;
149*8975f5c5SAndroid Build Coastguard Worker         }
150*8975f5c5SAndroid Build Coastguard Worker     }
151*8975f5c5SAndroid Build Coastguard Worker 
runTest2D()152*8975f5c5SAndroid Build Coastguard Worker     void runTest2D()
153*8975f5c5SAndroid Build Coastguard Worker     {
154*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
155*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, mTexture);
156*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(mTextureUniformLocation, 0);
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
159*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
160*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
161*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
162*8975f5c5SAndroid Build Coastguard Worker 
163*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
164*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, "position", 0.5f);
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker         GLubyte unswizzled[4];
167*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &unswizzled);
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
170*8975f5c5SAndroid Build Coastguard Worker 
171*8975f5c5SAndroid Build Coastguard Worker         for (const auto &permutation : mPermutations)
172*8975f5c5SAndroid Build Coastguard Worker         {
173*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, permutation.swizzleRed);
174*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, permutation.swizzleGreen);
175*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, permutation.swizzleBlue);
176*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, permutation.swizzleAlpha);
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT);
179*8975f5c5SAndroid Build Coastguard Worker             drawQuad(mProgram, "position", 0.5f);
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_EQ(0, 0, getExpectedValue(permutation.swizzleRed, unswizzled),
182*8975f5c5SAndroid Build Coastguard Worker                             getExpectedValue(permutation.swizzleGreen, unswizzled),
183*8975f5c5SAndroid Build Coastguard Worker                             getExpectedValue(permutation.swizzleBlue, unswizzled),
184*8975f5c5SAndroid Build Coastguard Worker                             getExpectedValue(permutation.swizzleAlpha, unswizzled));
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
187*8975f5c5SAndroid Build Coastguard Worker         }
188*8975f5c5SAndroid Build Coastguard Worker     }
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram               = 0;
191*8975f5c5SAndroid Build Coastguard Worker     GLint mTextureUniformLocation = 0;
192*8975f5c5SAndroid Build Coastguard Worker 
193*8975f5c5SAndroid Build Coastguard Worker     GLuint mTexture = 0;
194*8975f5c5SAndroid Build Coastguard Worker 
195*8975f5c5SAndroid Build Coastguard Worker     struct swizzlePermutation
196*8975f5c5SAndroid Build Coastguard Worker     {
197*8975f5c5SAndroid Build Coastguard Worker         GLenum swizzleRed;
198*8975f5c5SAndroid Build Coastguard Worker         GLenum swizzleGreen;
199*8975f5c5SAndroid Build Coastguard Worker         GLenum swizzleBlue;
200*8975f5c5SAndroid Build Coastguard Worker         GLenum swizzleAlpha;
201*8975f5c5SAndroid Build Coastguard Worker     };
202*8975f5c5SAndroid Build Coastguard Worker     std::vector<swizzlePermutation> mPermutations;
203*8975f5c5SAndroid Build Coastguard Worker };
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker class SwizzleIntegerTest : public SwizzleTest
206*8975f5c5SAndroid Build Coastguard Worker {
207*8975f5c5SAndroid Build Coastguard Worker   protected:
testSetUp()208*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
209*8975f5c5SAndroid Build Coastguard Worker     {
210*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] =
211*8975f5c5SAndroid Build Coastguard Worker             "#version 300 es\n"
212*8975f5c5SAndroid Build Coastguard Worker             "precision highp float;\n"
213*8975f5c5SAndroid Build Coastguard Worker             "in vec4 position;\n"
214*8975f5c5SAndroid Build Coastguard Worker             "out vec2 texcoord;\n"
215*8975f5c5SAndroid Build Coastguard Worker             "\n"
216*8975f5c5SAndroid Build Coastguard Worker             "void main()\n"
217*8975f5c5SAndroid Build Coastguard Worker             "{\n"
218*8975f5c5SAndroid Build Coastguard Worker             "    gl_Position = position;\n"
219*8975f5c5SAndroid Build Coastguard Worker             "    texcoord = (position.xy * 0.5) + 0.5;\n"
220*8975f5c5SAndroid Build Coastguard Worker             "}\n";
221*8975f5c5SAndroid Build Coastguard Worker 
222*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] =
223*8975f5c5SAndroid Build Coastguard Worker             "#version 300 es\n"
224*8975f5c5SAndroid Build Coastguard Worker             "precision highp float;\n"
225*8975f5c5SAndroid Build Coastguard Worker             "precision highp usampler2D;\n"
226*8975f5c5SAndroid Build Coastguard Worker             "uniform usampler2D tex;\n"
227*8975f5c5SAndroid Build Coastguard Worker             "in vec2 texcoord;\n"
228*8975f5c5SAndroid Build Coastguard Worker             "out vec4 my_FragColor;\n"
229*8975f5c5SAndroid Build Coastguard Worker             "\n"
230*8975f5c5SAndroid Build Coastguard Worker             "void main()\n"
231*8975f5c5SAndroid Build Coastguard Worker             "{\n"
232*8975f5c5SAndroid Build Coastguard Worker             "    uvec4 s = texture(tex, texcoord);\n"
233*8975f5c5SAndroid Build Coastguard Worker             "    if (s[0] == 1u) s[0] = 255u;\n"
234*8975f5c5SAndroid Build Coastguard Worker             "    if (s[1] == 1u) s[1] = 255u;\n"
235*8975f5c5SAndroid Build Coastguard Worker             "    if (s[2] == 1u) s[2] = 255u;\n"
236*8975f5c5SAndroid Build Coastguard Worker             "    if (s[3] == 1u) s[3] = 255u;\n"
237*8975f5c5SAndroid Build Coastguard Worker             "    my_FragColor = vec4(s) / 255.0;\n"
238*8975f5c5SAndroid Build Coastguard Worker             "}\n";
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(kVS, kFS);
241*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, mProgram);
242*8975f5c5SAndroid Build Coastguard Worker 
243*8975f5c5SAndroid Build Coastguard Worker         mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
244*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, mTextureUniformLocation);
245*8975f5c5SAndroid Build Coastguard Worker 
246*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
247*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
248*8975f5c5SAndroid Build Coastguard Worker     }
249*8975f5c5SAndroid Build Coastguard Worker };
250*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RGBA8_2D)251*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RGBA8_2D)
252*8975f5c5SAndroid Build Coastguard Worker {
253*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
254*8975f5c5SAndroid Build Coastguard Worker 
255*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {1, 64, 128, 200};
256*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
257*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
258*8975f5c5SAndroid Build Coastguard Worker }
259*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RGB8_2D)260*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RGB8_2D)
261*8975f5c5SAndroid Build Coastguard Worker {
262*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
263*8975f5c5SAndroid Build Coastguard Worker 
264*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {77, 66, 55};
265*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
266*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RG8_2D)269*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RG8_2D)
270*8975f5c5SAndroid Build Coastguard Worker {
271*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {11, 99};
274*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
275*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
276*8975f5c5SAndroid Build Coastguard Worker }
277*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,R8_2D)278*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, R8_2D)
279*8975f5c5SAndroid Build Coastguard Worker {
280*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
281*8975f5c5SAndroid Build Coastguard Worker 
282*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {2};
283*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
284*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
285*8975f5c5SAndroid Build Coastguard Worker }
286*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RGB10_A2_2D)287*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RGB10_A2_2D)
288*8975f5c5SAndroid Build Coastguard Worker {
289*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker     GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
292*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data);
293*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
294*8975f5c5SAndroid Build Coastguard Worker }
295*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RGB10_2D)296*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RGB10_2D)
297*8975f5c5SAndroid Build Coastguard Worker {
298*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
299*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_texture_type_2_10_10_10_REV"));
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker     GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
302*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGB, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, data);
303*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RGBA32F_2D)306*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RGBA32F_2D)
307*8975f5c5SAndroid Build Coastguard Worker {
308*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {0.25f, 0.5f, 0.75f, 0.8f};
311*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
312*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
313*8975f5c5SAndroid Build Coastguard Worker }
314*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RGB32F_2D)315*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RGB32F_2D)
316*8975f5c5SAndroid Build Coastguard Worker {
317*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
318*8975f5c5SAndroid Build Coastguard Worker 
319*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {0.1f, 0.2f, 0.3f};
320*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
321*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
322*8975f5c5SAndroid Build Coastguard Worker }
323*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,RG32F_2D)324*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, RG32F_2D)
325*8975f5c5SAndroid Build Coastguard Worker {
326*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {0.9f, 0.1f};
329*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
330*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
331*8975f5c5SAndroid Build Coastguard Worker }
332*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,R32F_2D)333*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, R32F_2D)
334*8975f5c5SAndroid Build Coastguard Worker {
335*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
336*8975f5c5SAndroid Build Coastguard Worker 
337*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {0.5f};
338*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
339*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
340*8975f5c5SAndroid Build Coastguard Worker }
341*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,D32F_2D)342*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, D32F_2D)
343*8975f5c5SAndroid Build Coastguard Worker {
344*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
345*8975f5c5SAndroid Build Coastguard Worker 
346*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {0.5f};
347*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
348*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
349*8975f5c5SAndroid Build Coastguard Worker }
350*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,D16_2D)351*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, D16_2D)
352*8975f5c5SAndroid Build Coastguard Worker {
353*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
354*8975f5c5SAndroid Build Coastguard Worker 
355*8975f5c5SAndroid Build Coastguard Worker     GLushort data[] = {0xFF};
356*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
357*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
358*8975f5c5SAndroid Build Coastguard Worker }
359*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,D24_2D)360*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, D24_2D)
361*8975f5c5SAndroid Build Coastguard Worker {
362*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
363*8975f5c5SAndroid Build Coastguard Worker 
364*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAMD() && IsWindows());  // anglebug.com/42262208
365*8975f5c5SAndroid Build Coastguard Worker     GLuint data[] = {0xFFFF};
366*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
367*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
368*8975f5c5SAndroid Build Coastguard Worker }
369*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,L8_2D)370*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, L8_2D)
371*8975f5c5SAndroid Build Coastguard Worker {
372*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
373*8975f5c5SAndroid Build Coastguard Worker 
374*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {0x77};
375*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
376*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
377*8975f5c5SAndroid Build Coastguard Worker }
378*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,A8_2D)379*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, A8_2D)
380*8975f5c5SAndroid Build Coastguard Worker {
381*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
382*8975f5c5SAndroid Build Coastguard Worker 
383*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {0x55};
384*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data);
385*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
386*8975f5c5SAndroid Build Coastguard Worker }
387*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,LA8_2D)388*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, LA8_2D)
389*8975f5c5SAndroid Build Coastguard Worker {
390*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
391*8975f5c5SAndroid Build Coastguard Worker 
392*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {0x77, 0x66};
393*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
394*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
395*8975f5c5SAndroid Build Coastguard Worker }
396*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,L32F_2D)397*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, L32F_2D)
398*8975f5c5SAndroid Build Coastguard Worker {
399*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
400*8975f5c5SAndroid Build Coastguard Worker 
401*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
402*8975f5c5SAndroid Build Coastguard Worker 
403*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {0.7f};
404*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data);
405*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
406*8975f5c5SAndroid Build Coastguard Worker }
407*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,A32F_2D)408*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, A32F_2D)
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
413*8975f5c5SAndroid Build Coastguard Worker 
414*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {
415*8975f5c5SAndroid Build Coastguard Worker         0.4f,
416*8975f5c5SAndroid Build Coastguard Worker     };
417*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data);
418*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
419*8975f5c5SAndroid Build Coastguard Worker }
420*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,LA32F_2D)421*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, LA32F_2D)
422*8975f5c5SAndroid Build Coastguard Worker {
423*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
424*8975f5c5SAndroid Build Coastguard Worker 
425*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker     GLfloat data[] = {
428*8975f5c5SAndroid Build Coastguard Worker         0.5f,
429*8975f5c5SAndroid Build Coastguard Worker         0.6f,
430*8975f5c5SAndroid Build Coastguard Worker     };
431*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, data);
432*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
433*8975f5c5SAndroid Build Coastguard Worker }
434*8975f5c5SAndroid Build Coastguard Worker 
435*8975f5c5SAndroid Build Coastguard Worker #include "media/pixel.inc"
436*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,CompressedDXT_2D)437*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, CompressedDXT_2D)
438*8975f5c5SAndroid Build Coastguard Worker {
439*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
440*8975f5c5SAndroid Build Coastguard Worker 
441*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
442*8975f5c5SAndroid Build Coastguard Worker 
443*8975f5c5SAndroid Build Coastguard Worker     init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height,
444*8975f5c5SAndroid Build Coastguard Worker                             pixel_0_size, pixel_0_data);
445*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
446*8975f5c5SAndroid Build Coastguard Worker }
447*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleTest,CompressedDXT1_RGB_2D)448*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, CompressedDXT1_RGB_2D)
449*8975f5c5SAndroid Build Coastguard Worker {
450*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
451*8975f5c5SAndroid Build Coastguard Worker 
452*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
453*8975f5c5SAndroid Build Coastguard Worker 
454*8975f5c5SAndroid Build Coastguard Worker     init2DCompressedTexture(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height,
455*8975f5c5SAndroid Build Coastguard Worker                             pixel_0_size, pixel_0_data);
456*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
457*8975f5c5SAndroid Build Coastguard Worker }
458*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(SwizzleIntegerTest,RGB8UI_2D)459*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleIntegerTest, RGB8UI_2D)
460*8975f5c5SAndroid Build Coastguard Worker {
461*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
462*8975f5c5SAndroid Build Coastguard Worker 
463*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan());  // anglebug.com/42261870 - integer textures
464*8975f5c5SAndroid Build Coastguard Worker     GLubyte data[] = {77, 66, 55};
465*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
466*8975f5c5SAndroid Build Coastguard Worker     runTest2D();
467*8975f5c5SAndroid Build Coastguard Worker }
468*8975f5c5SAndroid Build Coastguard Worker 
469*8975f5c5SAndroid Build Coastguard Worker // Test that updating the texture data still generates the correct swizzles
TEST_P(SwizzleTest,SubUpdate)470*8975f5c5SAndroid Build Coastguard Worker TEST_P(SwizzleTest, SubUpdate)
471*8975f5c5SAndroid Build Coastguard Worker {
472*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
473*8975f5c5SAndroid Build Coastguard Worker 
474*8975f5c5SAndroid Build Coastguard Worker     GLColor data(1, 64, 128, 200);
475*8975f5c5SAndroid Build Coastguard Worker     init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data);
476*8975f5c5SAndroid Build Coastguard Worker 
477*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
478*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, mTexture);
479*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureUniformLocation, 0);
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
482*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
483*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
484*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
485*8975f5c5SAndroid Build Coastguard Worker 
486*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
487*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
488*8975f5c5SAndroid Build Coastguard Worker 
489*8975f5c5SAndroid Build Coastguard Worker     GLColor expectedData(data.R, data.R, data.R, data.R);
490*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedData);
491*8975f5c5SAndroid Build Coastguard Worker 
492*8975f5c5SAndroid Build Coastguard Worker     GLColor updateData(32, 234, 28, 232);
493*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &updateData);
494*8975f5c5SAndroid Build Coastguard Worker 
495*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
496*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "position", 0.5f);
497*8975f5c5SAndroid Build Coastguard Worker 
498*8975f5c5SAndroid Build Coastguard Worker     GLColor expectedUpdateData(updateData.R, updateData.R, updateData.R, updateData.R);
499*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
500*8975f5c5SAndroid Build Coastguard Worker }
501*8975f5c5SAndroid Build Coastguard Worker 
502*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SwizzleTest);
503*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND(SwizzleTest);
504*8975f5c5SAndroid Build Coastguard Worker 
505*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SwizzleIntegerTest);
506*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND(SwizzleIntegerTest);
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker }  // namespace
509