07ea2481b33a1fac2b1eb793bea4bae788877fd1
[WebKit-https.git] / Source / ThirdParty / ANGLE / src / tests / gl_tests / TextureTest.cpp
1 //
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
7 #include "common/mathutil.h"
8 #include "test_utils/ANGLETest.h"
9 #include "test_utils/gl_raii.h"
10
11 using namespace angle;
12
13 namespace
14 {
15
16 constexpr GLuint kPixelTolerance     = 1u;
17 constexpr GLfloat kPixelTolerance32F = 0.01f;
18
19 // Single compressed ETC2 block of source pixels all set red
20 constexpr uint8_t kCompressedImageETC2[] = {0x7E, 0x80, 0x04, 0x7F, 0x00, 0x07, 0xE0, 0x00};
21
22 // Take a pixel, and reset the components not covered by the format to default
23 // values. In particular, the default value for the alpha component is 255
24 // (1.0 as unsigned normalized fixed point value).
25 // For legacy formats, the components may be reordered to match the color that
26 // would be created if a pixel of that format was initialized from the given color
27 GLColor SliceFormatColor(GLenum format, GLColor full)
28 {
29     switch (format)
30     {
31         case GL_RED:
32             return GLColor(full.R, 0, 0, 255u);
33         case GL_RG:
34             return GLColor(full.R, full.G, 0, 255u);
35         case GL_RGB:
36             return GLColor(full.R, full.G, full.B, 255u);
37         case GL_RGBA:
38             return full;
39         case GL_LUMINANCE:
40             return GLColor(full.R, full.R, full.R, 255u);
41         case GL_ALPHA:
42             return GLColor(0, 0, 0, full.R);
43         case GL_LUMINANCE_ALPHA:
44             return GLColor(full.R, full.R, full.R, full.G);
45         default:
46             EXPECT_TRUE(false);
47             return GLColor::white;
48     }
49 }
50
51 GLColor16UI SliceFormatColor16UI(GLenum format, GLColor16UI full)
52 {
53     switch (format)
54     {
55         case GL_RED:
56             return GLColor16UI(full.R, 0, 0, 0xFFFF);
57         case GL_RG:
58             return GLColor16UI(full.R, full.G, 0, 0xFFFF);
59         case GL_RGB:
60             return GLColor16UI(full.R, full.G, full.B, 0xFFFF);
61         case GL_RGBA:
62             return full;
63         case GL_LUMINANCE:
64             return GLColor16UI(full.R, full.R, full.R, 0xFFFF);
65         case GL_ALPHA:
66             return GLColor16UI(0, 0, 0, full.R);
67         case GL_LUMINANCE_ALPHA:
68             return GLColor16UI(full.R, full.R, full.R, full.G);
69         default:
70             EXPECT_TRUE(false);
71             return GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
72     }
73 }
74
75 // As above, for 32F colors
76 GLColor32F SliceFormatColor32F(GLenum format, GLColor32F full)
77 {
78     switch (format)
79     {
80         case GL_RED:
81             return GLColor32F(full.R, 0.0f, 0.0f, 1.0f);
82         case GL_RG:
83             return GLColor32F(full.R, full.G, 0.0f, 1.0f);
84         case GL_RGB:
85             return GLColor32F(full.R, full.G, full.B, 1.0f);
86         case GL_RGBA:
87             return full;
88         case GL_LUMINANCE:
89             return GLColor32F(full.R, full.R, full.R, 1.0f);
90         case GL_ALPHA:
91             return GLColor32F(0.0f, 0.0f, 0.0f, full.R);
92         case GL_LUMINANCE_ALPHA:
93             return GLColor32F(full.R, full.R, full.R, full.G);
94         default:
95             EXPECT_TRUE(false);
96             return GLColor32F(1.0f, 1.0f, 1.0f, 1.0f);
97     }
98 }
99
100 class TexCoordDrawTest : public ANGLETest
101 {
102   protected:
103     TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
104     {
105         setWindowWidth(128);
106         setWindowHeight(128);
107         setConfigRedBits(8);
108         setConfigGreenBits(8);
109         setConfigBlueBits(8);
110         setConfigAlphaBits(8);
111     }
112
113     virtual const char *getVertexShaderSource()
114     {
115         return R"(precision highp float;
116 attribute vec4 position;
117 varying vec2 texcoord;
118
119 void main()
120 {
121     gl_Position = vec4(position.xy, 0.0, 1.0);
122     texcoord = (position.xy * 0.5) + 0.5;
123 })";
124     }
125
126     virtual const char *getFragmentShaderSource() = 0;
127
128     virtual void setUpProgram()
129     {
130         const char *vertexShaderSource   = getVertexShaderSource();
131         const char *fragmentShaderSource = getFragmentShaderSource();
132
133         mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
134         ASSERT_NE(0u, mProgram);
135         ASSERT_GL_NO_ERROR();
136     }
137
138     void testSetUp() override { setUpFramebuffer(); }
139
140     void testTearDown() override
141     {
142         glBindFramebuffer(GL_FRAMEBUFFER, 0);
143         glDeleteFramebuffers(1, &mFramebuffer);
144         glDeleteTextures(1, &mFramebufferColorTexture);
145         glDeleteProgram(mProgram);
146     }
147
148     void setUpFramebuffer()
149     {
150         // We use an FBO to work around an issue where the default framebuffer applies SRGB
151         // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
152         // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
153         // section 4.4 says that the format of the default framebuffer is entirely up to the window
154         // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
155         // SRGB conversion like desktop GL does.
156         // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
157         glGenFramebuffers(1, &mFramebuffer);
158         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
159
160         glGenTextures(1, &mFramebufferColorTexture);
161         glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
162         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
163                      GL_UNSIGNED_BYTE, nullptr);
164         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
165                                mFramebufferColorTexture, 0);
166         ASSERT_GL_NO_ERROR();
167         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
168         glBindTexture(GL_TEXTURE_2D, 0);
169     }
170
171     // Returns the created texture ID.
172     GLuint create2DTexture()
173     {
174         GLuint texture2D;
175         glGenTextures(1, &texture2D);
176         glBindTexture(GL_TEXTURE_2D, texture2D);
177         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
178         EXPECT_GL_NO_ERROR();
179         return texture2D;
180     }
181
182     GLuint mProgram;
183     GLuint mFramebuffer;
184
185   private:
186     GLuint mFramebufferColorTexture;
187 };
188
189 class Texture2DTest : public TexCoordDrawTest
190 {
191   protected:
192     Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
193
194     const char *getFragmentShaderSource() override
195     {
196         return R"(precision highp float;
197 uniform sampler2D tex;
198 varying vec2 texcoord;
199
200 void main()
201 {
202     gl_FragColor = texture2D(tex, texcoord);
203 })";
204     }
205
206     virtual const char *getTextureUniformName() { return "tex"; }
207
208     void setUpProgram() override
209     {
210         TexCoordDrawTest::setUpProgram();
211         mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
212         ASSERT_NE(-1, mTexture2DUniformLocation);
213     }
214
215     void testSetUp() override
216     {
217         TexCoordDrawTest::testSetUp();
218         mTexture2D = create2DTexture();
219
220         ASSERT_GL_NO_ERROR();
221     }
222
223     void testTearDown() override
224     {
225         glDeleteTextures(1, &mTexture2D);
226         TexCoordDrawTest::testTearDown();
227     }
228
229     // Tests CopyTexSubImage with floating point textures of various formats.
230     void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
231     {
232         setUpProgram();
233
234         if (getClientMajorVersion() < 3)
235         {
236             ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
237                                !IsGLExtensionEnabled("GL_OES_texture_float"));
238
239             ANGLE_SKIP_TEST_IF((sourceImageChannels < 3 || destImageChannels < 3) &&
240                                !IsGLExtensionEnabled("GL_EXT_texture_rg"));
241
242             ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
243                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
244
245             ANGLE_SKIP_TEST_IF(destImageChannels == 4 &&
246                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"));
247
248             ANGLE_SKIP_TEST_IF(destImageChannels <= 2);
249         }
250         else
251         {
252             ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_color_buffer_float"));
253
254             ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
255                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
256         }
257
258         // clang-format off
259         GLfloat sourceImageData[4][16] =
260         {
261             { // R
262                 1.0f,
263                 0.0f,
264                 0.0f,
265                 1.0f
266             },
267             { // RG
268                 1.0f, 0.0f,
269                 0.0f, 1.0f,
270                 0.0f, 0.0f,
271                 1.0f, 1.0f
272             },
273             { // RGB
274                 1.0f, 0.0f, 0.0f,
275                 0.0f, 1.0f, 0.0f,
276                 0.0f, 0.0f, 1.0f,
277                 1.0f, 1.0f, 0.0f
278             },
279             { // RGBA
280                 1.0f, 0.0f, 0.0f, 1.0f,
281                 0.0f, 1.0f, 0.0f, 1.0f,
282                 0.0f, 0.0f, 1.0f, 1.0f,
283                 1.0f, 1.0f, 0.0f, 1.0f
284             },
285         };
286         // clang-format on
287
288         GLenum imageFormats[] = {
289             GL_R32F,
290             GL_RG32F,
291             GL_RGB32F,
292             GL_RGBA32F,
293         };
294
295         GLenum sourceUnsizedFormats[] = {
296             GL_RED,
297             GL_RG,
298             GL_RGB,
299             GL_RGBA,
300         };
301
302         GLuint textures[2];
303
304         glGenTextures(2, textures);
305
306         GLfloat *imageData         = sourceImageData[sourceImageChannels - 1];
307         GLenum sourceImageFormat   = imageFormats[sourceImageChannels - 1];
308         GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
309         GLenum destImageFormat     = imageFormats[destImageChannels - 1];
310
311         glBindTexture(GL_TEXTURE_2D, textures[0]);
312         if (getClientMajorVersion() >= 3)
313         {
314             glTexStorage2D(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
315         }
316         else
317         {
318             glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
319         }
320         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
321         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
322         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
323
324         if (sourceImageChannels < 3 && !IsGLExtensionEnabled("GL_EXT_texture_rg"))
325         {
326             // This is not supported
327             ASSERT_GL_ERROR(GL_INVALID_OPERATION);
328         }
329         else
330         {
331             ASSERT_GL_NO_ERROR();
332         }
333
334         GLuint fbo;
335         glGenFramebuffers(1, &fbo);
336         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
337         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
338
339         glBindTexture(GL_TEXTURE_2D, textures[1]);
340         if (getClientMajorVersion() >= 3)
341         {
342             glTexStorage2D(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
343         }
344         else
345         {
346             glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
347         }
348         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350
351         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
352         ASSERT_GL_NO_ERROR();
353
354         glBindFramebuffer(GL_FRAMEBUFFER, 0);
355         drawQuad(mProgram, "position", 0.5f);
356
357         int testImageChannels = std::min(sourceImageChannels, destImageChannels);
358
359         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
360         if (testImageChannels > 1)
361         {
362             EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
363             EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
364             if (testImageChannels > 2)
365             {
366                 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
367             }
368         }
369
370         glDeleteFramebuffers(1, &fbo);
371         glDeleteTextures(2, textures);
372
373         ASSERT_GL_NO_ERROR();
374     }
375
376     GLuint mTexture2D;
377     GLint mTexture2DUniformLocation;
378 };
379
380 class Texture2DTestES3 : public Texture2DTest
381 {
382   protected:
383     Texture2DTestES3() : Texture2DTest() {}
384
385     const char *getVertexShaderSource() override
386     {
387         return "#version 300 es\n"
388                "out vec2 texcoord;\n"
389                "in vec4 position;\n"
390                "void main()\n"
391                "{\n"
392                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
393                "    texcoord = (position.xy * 0.5) + 0.5;\n"
394                "}\n";
395     }
396
397     const char *getFragmentShaderSource() override
398     {
399         return "#version 300 es\n"
400                "precision highp float;\n"
401                "uniform highp sampler2D tex;\n"
402                "in vec2 texcoord;\n"
403                "out vec4 fragColor;\n"
404                "void main()\n"
405                "{\n"
406                "    fragColor = texture(tex, texcoord);\n"
407                "}\n";
408     }
409
410     void testSetUp() override
411     {
412         Texture2DTest::testSetUp();
413         setUpProgram();
414     }
415 };
416
417 class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
418 {
419   protected:
420     Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
421
422     const char *getVertexShaderSource() override
423     {
424         return "#version 300 es\n"
425                "out vec2 texcoord;\n"
426                "in vec4 position;\n"
427                "void main()\n"
428                "{\n"
429                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
430                "    texcoord = (position.xy * 0.5) + 0.5;\n"
431                "}\n";
432     }
433
434     const char *getFragmentShaderSource() override
435     {
436         return "#version 300 es\n"
437                "precision highp float;\n"
438                "uniform highp isampler2D tex;\n"
439                "in vec2 texcoord;\n"
440                "out vec4 fragColor;\n"
441                "void main()\n"
442                "{\n"
443                "    vec4 green = vec4(0, 1, 0, 1);\n"
444                "    vec4 black = vec4(0, 0, 0, 0);\n"
445                "    fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
446                "}\n";
447     }
448
449     void testSetUp() override
450     {
451         Texture2DTest::testSetUp();
452         setUpProgram();
453     }
454 };
455
456 class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
457 {
458   protected:
459     Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
460
461     const char *getVertexShaderSource() override
462     {
463         return "#version 300 es\n"
464                "out vec2 texcoord;\n"
465                "in vec4 position;\n"
466                "void main()\n"
467                "{\n"
468                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
469                "    texcoord = (position.xy * 0.5) + 0.5;\n"
470                "}\n";
471     }
472
473     const char *getFragmentShaderSource() override
474     {
475         return "#version 300 es\n"
476                "precision highp float;\n"
477                "uniform highp usampler2D tex;\n"
478                "in vec2 texcoord;\n"
479                "out vec4 fragColor;\n"
480                "void main()\n"
481                "{\n"
482                "    vec4 green = vec4(0, 1, 0, 1);\n"
483                "    vec4 black = vec4(0, 0, 0, 0);\n"
484                "    fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
485                "}\n";
486     }
487
488     void testSetUp() override
489     {
490         Texture2DTest::testSetUp();
491         setUpProgram();
492     }
493 };
494
495 class Texture2DTestWithDrawScale : public Texture2DTest
496 {
497   protected:
498     Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
499
500     const char *getVertexShaderSource() override
501     {
502         return
503             R"(precision highp float;
504             attribute vec4 position;
505             varying vec2 texcoord;
506
507             uniform vec2 drawScale;
508
509             void main()
510             {
511                 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
512                 texcoord = (position.xy * 0.5) + 0.5;
513             })";
514     }
515
516     void testSetUp() override
517     {
518         Texture2DTest::testSetUp();
519
520         setUpProgram();
521
522         mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
523         ASSERT_NE(-1, mDrawScaleUniformLocation);
524
525         glUseProgram(mProgram);
526         glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
527         glUseProgram(0);
528         ASSERT_GL_NO_ERROR();
529     }
530
531     GLint mDrawScaleUniformLocation;
532 };
533
534 class Sampler2DAsFunctionParameterTest : public Texture2DTest
535 {
536   protected:
537     Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
538
539     const char *getFragmentShaderSource() override
540     {
541         return
542             R"(precision highp float;
543             uniform sampler2D tex;
544             varying vec2 texcoord;
545
546             vec4 computeFragColor(sampler2D aTex)
547             {
548                 return texture2D(aTex, texcoord);
549             }
550
551             void main()
552             {
553                 gl_FragColor = computeFragColor(tex);
554             })";
555     }
556
557     void testSetUp() override
558     {
559         Texture2DTest::testSetUp();
560         setUpProgram();
561     }
562 };
563
564 class TextureCubeTest : public TexCoordDrawTest
565 {
566   protected:
567     TextureCubeTest()
568         : TexCoordDrawTest(),
569           mTexture2D(0),
570           mTextureCube(0),
571           mTexture2DUniformLocation(-1),
572           mTextureCubeUniformLocation(-1)
573     {}
574
575     const char *getFragmentShaderSource() override
576     {
577         return
578             R"(precision highp float;
579             uniform sampler2D tex2D;
580             uniform samplerCube texCube;
581             varying vec2 texcoord;
582
583             void main()
584             {
585                 gl_FragColor = texture2D(tex2D, texcoord);
586                 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
587             })";
588     }
589
590     void testSetUp() override
591     {
592         TexCoordDrawTest::testSetUp();
593
594         glGenTextures(1, &mTextureCube);
595         glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
596         for (GLenum face = 0; face < 6; face++)
597         {
598             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
599                          GL_UNSIGNED_BYTE, nullptr);
600         }
601         EXPECT_GL_NO_ERROR();
602
603         mTexture2D = create2DTexture();
604
605         setUpProgram();
606
607         mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
608         ASSERT_NE(-1, mTexture2DUniformLocation);
609         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
610         ASSERT_NE(-1, mTextureCubeUniformLocation);
611     }
612
613     void testTearDown() override
614     {
615         glDeleteTextures(1, &mTextureCube);
616         TexCoordDrawTest::testTearDown();
617     }
618
619     GLuint mTexture2D;
620     GLuint mTextureCube;
621     GLint mTexture2DUniformLocation;
622     GLint mTextureCubeUniformLocation;
623 };
624
625 class TextureCubeTestES3 : public ANGLETest
626 {
627   protected:
628     TextureCubeTestES3() {}
629 };
630
631 class SamplerArrayTest : public TexCoordDrawTest
632 {
633   protected:
634     SamplerArrayTest()
635         : TexCoordDrawTest(),
636           mTexture2DA(0),
637           mTexture2DB(0),
638           mTexture0UniformLocation(-1),
639           mTexture1UniformLocation(-1)
640     {}
641
642     const char *getFragmentShaderSource() override
643     {
644         return
645             R"(precision mediump float;
646             uniform highp sampler2D tex2DArray[2];
647             varying vec2 texcoord;
648             void main()
649             {
650                 gl_FragColor = texture2D(tex2DArray[0], texcoord);
651                 gl_FragColor += texture2D(tex2DArray[1], texcoord);
652             })";
653     }
654
655     void testSetUp() override
656     {
657         TexCoordDrawTest::testSetUp();
658
659         setUpProgram();
660
661         mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
662         ASSERT_NE(-1, mTexture0UniformLocation);
663         mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
664         ASSERT_NE(-1, mTexture1UniformLocation);
665
666         mTexture2DA = create2DTexture();
667         mTexture2DB = create2DTexture();
668         ASSERT_GL_NO_ERROR();
669     }
670
671     void testTearDown() override
672     {
673         glDeleteTextures(1, &mTexture2DA);
674         glDeleteTextures(1, &mTexture2DB);
675         TexCoordDrawTest::testTearDown();
676     }
677
678     void testSamplerArrayDraw()
679     {
680         GLubyte texData[4];
681         texData[0] = 0;
682         texData[1] = 60;
683         texData[2] = 0;
684         texData[3] = 255;
685
686         glActiveTexture(GL_TEXTURE0);
687         glBindTexture(GL_TEXTURE_2D, mTexture2DA);
688         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
689
690         texData[1] = 120;
691         glActiveTexture(GL_TEXTURE1);
692         glBindTexture(GL_TEXTURE_2D, mTexture2DB);
693         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
694         EXPECT_GL_ERROR(GL_NO_ERROR);
695
696         glUseProgram(mProgram);
697         glUniform1i(mTexture0UniformLocation, 0);
698         glUniform1i(mTexture1UniformLocation, 1);
699         drawQuad(mProgram, "position", 0.5f);
700         EXPECT_GL_NO_ERROR();
701
702         EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
703     }
704
705     GLuint mTexture2DA;
706     GLuint mTexture2DB;
707     GLint mTexture0UniformLocation;
708     GLint mTexture1UniformLocation;
709 };
710
711 class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
712 {
713   protected:
714     SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
715
716     const char *getFragmentShaderSource() override
717     {
718         return
719             R"(precision mediump float;
720             uniform highp sampler2D tex2DArray[2];
721             varying vec2 texcoord;
722
723             vec4 computeFragColor(highp sampler2D aTex2DArray[2])
724             {
725                 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
726             }
727
728             void main()
729             {
730                 gl_FragColor = computeFragColor(tex2DArray);
731             })";
732     }
733 };
734
735 class Texture2DArrayTestES3 : public TexCoordDrawTest
736 {
737   protected:
738     Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
739
740     const char *getVertexShaderSource() override
741     {
742         return "#version 300 es\n"
743                "out vec2 texcoord;\n"
744                "in vec4 position;\n"
745                "void main()\n"
746                "{\n"
747                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
748                "    texcoord = (position.xy * 0.5) + 0.5;\n"
749                "}\n";
750     }
751
752     const char *getFragmentShaderSource() override
753     {
754         return "#version 300 es\n"
755                "precision highp float;\n"
756                "uniform highp sampler2DArray tex2DArray;\n"
757                "in vec2 texcoord;\n"
758                "out vec4 fragColor;\n"
759                "void main()\n"
760                "{\n"
761                "    fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
762                "}\n";
763     }
764
765     void testSetUp() override
766     {
767         TexCoordDrawTest::testSetUp();
768
769         setUpProgram();
770
771         mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
772         ASSERT_NE(-1, mTextureArrayLocation);
773
774         glGenTextures(1, &m2DArrayTexture);
775         ASSERT_GL_NO_ERROR();
776     }
777
778     void testTearDown() override
779     {
780         glDeleteTextures(1, &m2DArrayTexture);
781         TexCoordDrawTest::testTearDown();
782     }
783
784     GLuint m2DArrayTexture;
785     GLint mTextureArrayLocation;
786 };
787
788 class TextureSizeTextureArrayTest : public TexCoordDrawTest
789 {
790   protected:
791     TextureSizeTextureArrayTest()
792         : TexCoordDrawTest(),
793           mTexture2DA(0),
794           mTexture2DB(0),
795           mTexture0Location(-1),
796           mTexture1Location(-1)
797     {}
798
799     const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
800
801     const char *getFragmentShaderSource() override
802     {
803         return "#version 300 es\n"
804                "precision highp float;\n"
805                "uniform highp sampler2D tex2DArray[2];\n"
806                "out vec4 fragColor;\n"
807                "void main()\n"
808                "{\n"
809                "    float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
810                "    float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
811                "    fragColor = vec4(red, green, 0.0, 1.0);\n"
812                "}\n";
813     }
814
815     void testSetUp() override
816     {
817         TexCoordDrawTest::testSetUp();
818
819         setUpProgram();
820
821         mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
822         ASSERT_NE(-1, mTexture0Location);
823         mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
824         ASSERT_NE(-1, mTexture1Location);
825
826         mTexture2DA = create2DTexture();
827         mTexture2DB = create2DTexture();
828         ASSERT_GL_NO_ERROR();
829     }
830
831     void testTearDown() override
832     {
833         glDeleteTextures(1, &mTexture2DA);
834         glDeleteTextures(1, &mTexture2DB);
835         TexCoordDrawTest::testTearDown();
836     }
837
838     GLuint mTexture2DA;
839     GLuint mTexture2DB;
840     GLint mTexture0Location;
841     GLint mTexture1Location;
842 };
843
844 class Texture3DTestES3 : public TexCoordDrawTest
845 {
846   protected:
847     Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
848
849     const char *getVertexShaderSource() override
850     {
851         return "#version 300 es\n"
852                "out vec2 texcoord;\n"
853                "in vec4 position;\n"
854                "void main()\n"
855                "{\n"
856                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
857                "    texcoord = (position.xy * 0.5) + 0.5;\n"
858                "}\n";
859     }
860
861     const char *getFragmentShaderSource() override
862     {
863         return "#version 300 es\n"
864                "precision highp float;\n"
865                "uniform highp sampler3D tex3D;\n"
866                "in vec2 texcoord;\n"
867                "out vec4 fragColor;\n"
868                "void main()\n"
869                "{\n"
870                "    fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
871                "}\n";
872     }
873
874     void testSetUp() override
875     {
876         TexCoordDrawTest::testSetUp();
877
878         glGenTextures(1, &mTexture3D);
879
880         setUpProgram();
881
882         mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
883         ASSERT_NE(-1, mTexture3DUniformLocation);
884     }
885
886     void testTearDown() override
887     {
888         glDeleteTextures(1, &mTexture3D);
889         TexCoordDrawTest::testTearDown();
890     }
891
892     GLuint mTexture3D;
893     GLint mTexture3DUniformLocation;
894 };
895
896 class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
897 {
898   protected:
899     ShadowSamplerPlusSampler3DTestES3()
900         : TexCoordDrawTest(),
901           mTextureShadow(0),
902           mTexture3D(0),
903           mTextureShadowUniformLocation(-1),
904           mTexture3DUniformLocation(-1),
905           mDepthRefUniformLocation(-1)
906     {}
907
908     const char *getVertexShaderSource() override
909     {
910         return "#version 300 es\n"
911                "out vec2 texcoord;\n"
912                "in vec4 position;\n"
913                "void main()\n"
914                "{\n"
915                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
916                "    texcoord = (position.xy * 0.5) + 0.5;\n"
917                "}\n";
918     }
919
920     const char *getFragmentShaderSource() override
921     {
922         return "#version 300 es\n"
923                "precision highp float;\n"
924                "uniform highp sampler2DShadow tex2DShadow;\n"
925                "uniform highp sampler3D tex3D;\n"
926                "in vec2 texcoord;\n"
927                "uniform float depthRef;\n"
928                "out vec4 fragColor;\n"
929                "void main()\n"
930                "{\n"
931                "    fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
932                "    fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
933                "}\n";
934     }
935
936     void testSetUp() override
937     {
938         TexCoordDrawTest::testSetUp();
939
940         glGenTextures(1, &mTexture3D);
941
942         glGenTextures(1, &mTextureShadow);
943         glBindTexture(GL_TEXTURE_2D, mTextureShadow);
944         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
945
946         setUpProgram();
947
948         mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
949         ASSERT_NE(-1, mTextureShadowUniformLocation);
950         mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
951         ASSERT_NE(-1, mTexture3DUniformLocation);
952         mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
953         ASSERT_NE(-1, mDepthRefUniformLocation);
954     }
955
956     void testTearDown() override
957     {
958         glDeleteTextures(1, &mTextureShadow);
959         glDeleteTextures(1, &mTexture3D);
960         TexCoordDrawTest::testTearDown();
961     }
962
963     GLuint mTextureShadow;
964     GLuint mTexture3D;
965     GLint mTextureShadowUniformLocation;
966     GLint mTexture3DUniformLocation;
967     GLint mDepthRefUniformLocation;
968 };
969
970 class SamplerTypeMixTestES3 : public TexCoordDrawTest
971 {
972   protected:
973     SamplerTypeMixTestES3()
974         : TexCoordDrawTest(),
975           mTexture2D(0),
976           mTextureCube(0),
977           mTexture2DShadow(0),
978           mTextureCubeShadow(0),
979           mTexture2DUniformLocation(-1),
980           mTextureCubeUniformLocation(-1),
981           mTexture2DShadowUniformLocation(-1),
982           mTextureCubeShadowUniformLocation(-1),
983           mDepthRefUniformLocation(-1)
984     {}
985
986     const char *getVertexShaderSource() override
987     {
988         return "#version 300 es\n"
989                "out vec2 texcoord;\n"
990                "in vec4 position;\n"
991                "void main()\n"
992                "{\n"
993                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
994                "    texcoord = (position.xy * 0.5) + 0.5;\n"
995                "}\n";
996     }
997
998     const char *getFragmentShaderSource() override
999     {
1000         return "#version 300 es\n"
1001                "precision highp float;\n"
1002                "uniform highp sampler2D tex2D;\n"
1003                "uniform highp samplerCube texCube;\n"
1004                "uniform highp sampler2DShadow tex2DShadow;\n"
1005                "uniform highp samplerCubeShadow texCubeShadow;\n"
1006                "in vec2 texcoord;\n"
1007                "uniform float depthRef;\n"
1008                "out vec4 fragColor;\n"
1009                "void main()\n"
1010                "{\n"
1011                "    fragColor = texture(tex2D, texcoord);\n"
1012                "    fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1013                "    fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1014                "    fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1015                "0.125);\n"
1016                "}\n";
1017     }
1018
1019     void testSetUp() override
1020     {
1021         TexCoordDrawTest::testSetUp();
1022
1023         glGenTextures(1, &mTexture2D);
1024         glGenTextures(1, &mTextureCube);
1025
1026         glGenTextures(1, &mTexture2DShadow);
1027         glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1028         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1029
1030         glGenTextures(1, &mTextureCubeShadow);
1031         glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1032         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1033
1034         setUpProgram();
1035
1036         mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1037         ASSERT_NE(-1, mTexture2DUniformLocation);
1038         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1039         ASSERT_NE(-1, mTextureCubeUniformLocation);
1040         mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1041         ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1042         mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1043         ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1044         mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1045         ASSERT_NE(-1, mDepthRefUniformLocation);
1046
1047         ASSERT_GL_NO_ERROR();
1048     }
1049
1050     void testTearDown() override
1051     {
1052         glDeleteTextures(1, &mTexture2D);
1053         glDeleteTextures(1, &mTextureCube);
1054         glDeleteTextures(1, &mTexture2DShadow);
1055         glDeleteTextures(1, &mTextureCubeShadow);
1056         TexCoordDrawTest::testTearDown();
1057     }
1058
1059     GLuint mTexture2D;
1060     GLuint mTextureCube;
1061     GLuint mTexture2DShadow;
1062     GLuint mTextureCubeShadow;
1063     GLint mTexture2DUniformLocation;
1064     GLint mTextureCubeUniformLocation;
1065     GLint mTexture2DShadowUniformLocation;
1066     GLint mTextureCubeShadowUniformLocation;
1067     GLint mDepthRefUniformLocation;
1068 };
1069
1070 class SamplerInStructTest : public Texture2DTest
1071 {
1072   protected:
1073     SamplerInStructTest() : Texture2DTest() {}
1074
1075     const char *getTextureUniformName() override { return "us.tex"; }
1076
1077     const char *getFragmentShaderSource() override
1078     {
1079         return "precision highp float;\n"
1080                "struct S\n"
1081                "{\n"
1082                "    vec4 a;\n"
1083                "    highp sampler2D tex;\n"
1084                "};\n"
1085                "uniform S us;\n"
1086                "varying vec2 texcoord;\n"
1087                "void main()\n"
1088                "{\n"
1089                "    gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1090                "}\n";
1091     }
1092
1093     void runSamplerInStructTest()
1094     {
1095         setUpProgram();
1096
1097         glActiveTexture(GL_TEXTURE0);
1098         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1099         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1100                      &GLColor::green);
1101         drawQuad(mProgram, "position", 0.5f);
1102         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1103     }
1104 };
1105
1106 class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1107 {
1108   protected:
1109     SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1110
1111     const char *getFragmentShaderSource() override
1112     {
1113         return "precision highp float;\n"
1114                "struct S\n"
1115                "{\n"
1116                "    vec4 a;\n"
1117                "    highp sampler2D tex;\n"
1118                "};\n"
1119                "uniform S us;\n"
1120                "varying vec2 texcoord;\n"
1121                "vec4 sampleFrom(S s) {\n"
1122                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1123                "}\n"
1124                "void main()\n"
1125                "{\n"
1126                "    gl_FragColor = sampleFrom(us);\n"
1127                "}\n";
1128     }
1129 };
1130
1131 class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1132 {
1133   protected:
1134     SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1135
1136     const char *getTextureUniformName() override { return "us[0].tex"; }
1137
1138     const char *getFragmentShaderSource() override
1139     {
1140         return "precision highp float;\n"
1141                "struct S\n"
1142                "{\n"
1143                "    vec4 a;\n"
1144                "    highp sampler2D tex;\n"
1145                "};\n"
1146                "uniform S us[1];\n"
1147                "varying vec2 texcoord;\n"
1148                "vec4 sampleFrom(S s) {\n"
1149                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1150                "}\n"
1151                "void main()\n"
1152                "{\n"
1153                "    gl_FragColor = sampleFrom(us[0]);\n"
1154                "}\n";
1155     }
1156 };
1157
1158 class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1159 {
1160   protected:
1161     SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1162
1163     const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1164
1165     const char *getFragmentShaderSource() override
1166     {
1167         return "precision highp float;\n"
1168                "struct SUB\n"
1169                "{\n"
1170                "    vec4 a;\n"
1171                "    highp sampler2D tex;\n"
1172                "};\n"
1173                "struct S\n"
1174                "{\n"
1175                "    SUB sub;\n"
1176                "};\n"
1177                "uniform S us[1];\n"
1178                "varying vec2 texcoord;\n"
1179                "vec4 sampleFrom(SUB s) {\n"
1180                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1181                "}\n"
1182                "void main()\n"
1183                "{\n"
1184                "    gl_FragColor = sampleFrom(us[0].sub);\n"
1185                "}\n";
1186     }
1187 };
1188
1189 class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1190 {
1191   protected:
1192     SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1193
1194     const char *getFragmentShaderSource() override
1195     {
1196         return "precision highp float;\n"
1197                "struct S\n"
1198                "{\n"
1199                "    vec4 a;\n"
1200                "    highp sampler2D tex;\n"
1201                "};\n"
1202                "uniform S us;\n"
1203                "uniform float us_tex;\n"
1204                "varying vec2 texcoord;\n"
1205                "void main()\n"
1206                "{\n"
1207                "    gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1208                "}\n";
1209     }
1210 };
1211
1212 class Texture2DIntegerTestES3 : public Texture2DTest
1213 {
1214   protected:
1215     Texture2DIntegerTestES3() : Texture2DTest() {}
1216
1217     const char *getVertexShaderSource() override
1218     {
1219         return "#version 300 es\n"
1220                "out vec2 texcoord;\n"
1221                "in vec4 position;\n"
1222                "void main()\n"
1223                "{\n"
1224                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1225                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1226                "}\n";
1227     }
1228
1229     const char *getFragmentShaderSource() override
1230     {
1231         return "#version 300 es\n"
1232                "precision highp float;\n"
1233                "precision highp usampler2D;\n"
1234                "uniform usampler2D tex;\n"
1235                "in vec2 texcoord;\n"
1236                "out vec4 fragColor;\n"
1237                "void main()\n"
1238                "{\n"
1239                "    fragColor = vec4(texture(tex, texcoord))/255.0;\n"
1240                "}\n";
1241     }
1242 };
1243
1244 class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1245 {
1246   protected:
1247     TextureCubeIntegerTestES3()
1248         : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1249     {}
1250
1251     const char *getVertexShaderSource() override
1252     {
1253         return "#version 300 es\n"
1254                "out vec2 texcoord;\n"
1255                "in vec4 position;\n"
1256                "void main()\n"
1257                "{\n"
1258                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1259                "    texcoord = 0.5*position.xy;\n"
1260                "}\n";
1261     }
1262
1263     const char *getFragmentShaderSource() override
1264     {
1265         return "#version 300 es\n"
1266                "precision highp float;\n"
1267                "precision highp usamplerCube;\n"
1268                "uniform usamplerCube texCube;\n"
1269                "in vec2 texcoord;\n"
1270                "out vec4 fragColor;\n"
1271                "void main()\n"
1272                "{\n"
1273                "    fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1274                "}\n";
1275     }
1276
1277     void testSetUp() override
1278     {
1279         TexCoordDrawTest::testSetUp();
1280         glGenTextures(1, &mTextureCube);
1281         setUpProgram();
1282
1283         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1284         ASSERT_NE(-1, mTextureCubeUniformLocation);
1285     }
1286
1287     void testTearDown() override
1288     {
1289         glDeleteTextures(1, &mTextureCube);
1290         TexCoordDrawTest::testTearDown();
1291     }
1292
1293     GLuint mTextureCube;
1294     GLint mTextureCubeUniformLocation;
1295 };
1296
1297 class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1298 {
1299   protected:
1300     TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1301
1302     const char *getVertexShaderSource() override
1303     {
1304         return "#version 300 es\n"
1305                "out vec2 texcoord;\n"
1306                "in vec4 position;\n"
1307                "void main()\n"
1308                "{\n"
1309                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1310                "    texcoord = position.xy;\n"
1311                "}\n";
1312     }
1313
1314     const char *getFragmentShaderSource() override
1315     {
1316         return "#version 300 es\n"
1317                "precision highp float;\n"
1318                "precision highp usamplerCube;\n"
1319                "uniform usamplerCube texCube;\n"
1320                "in vec2 texcoord;\n"
1321                "out vec4 fragColor;\n"
1322                "void main()\n"
1323                "{\n"
1324                "    fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1325                "}\n";
1326     }
1327 };
1328
1329 class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1330 {
1331   protected:
1332     Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1333
1334     const char *getVertexShaderSource() override
1335     {
1336         return "#version 300 es\n"
1337                "out vec2 texcoord;\n"
1338                "in vec4 position;\n"
1339                "void main()\n"
1340                "{\n"
1341                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1342                "    texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1343                "}\n";
1344     }
1345
1346     const char *getFragmentShaderSource() override
1347     {
1348         return "#version 300 es\n"
1349                "precision highp float;\n"
1350                "precision highp usampler2D;\n"
1351                "uniform usampler2D tex;\n"
1352                "in vec2 texcoord;\n"
1353                "out vec4 fragColor;\n"
1354                "void main()\n"
1355                "{\n"
1356                "    fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1357                "0.0))/255.0;\n"
1358                "}\n";
1359     }
1360 };
1361
1362 class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1363 {
1364   protected:
1365     Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1366
1367     const char *getVertexShaderSource() override
1368     {
1369         return "#version 300 es\n"
1370                "out vec2 texcoord;\n"
1371                "in vec4 position;\n"
1372                "void main()\n"
1373                "{\n"
1374                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1375                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1376                "}\n";
1377     }
1378
1379     const char *getFragmentShaderSource() override
1380     {
1381         return "#version 300 es\n"
1382                "precision highp float;\n"
1383                "uniform highp usampler2DArray tex2DArray;\n"
1384                "in vec2 texcoord;\n"
1385                "out vec4 fragColor;\n"
1386                "void main()\n"
1387                "{\n"
1388                "    fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
1389                "0.0)))/255.0;\n"
1390                "}\n";
1391     }
1392 };
1393
1394 class Texture3DIntegerTestES3 : public Texture3DTestES3
1395 {
1396   protected:
1397     Texture3DIntegerTestES3() : Texture3DTestES3() {}
1398
1399     const char *getVertexShaderSource() override
1400     {
1401         return "#version 300 es\n"
1402                "out vec2 texcoord;\n"
1403                "in vec4 position;\n"
1404                "void main()\n"
1405                "{\n"
1406                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1407                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1408                "}\n";
1409     }
1410
1411     const char *getFragmentShaderSource() override
1412     {
1413         return "#version 300 es\n"
1414                "precision highp float;\n"
1415                "uniform highp usampler3D tex3D;\n"
1416                "in vec2 texcoord;\n"
1417                "out vec4 fragColor;\n"
1418                "void main()\n"
1419                "{\n"
1420                "    fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1421                "}\n";
1422     }
1423 };
1424
1425 class PBOCompressedTextureTest : public Texture2DTest
1426 {
1427   protected:
1428     PBOCompressedTextureTest() : Texture2DTest() {}
1429
1430     void testSetUp() override
1431     {
1432         TexCoordDrawTest::testSetUp();
1433         glGenTextures(1, &mTexture2D);
1434         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1435         EXPECT_GL_NO_ERROR();
1436
1437         setUpProgram();
1438
1439         glGenBuffers(1, &mPBO);
1440     }
1441
1442     void testTearDown() override
1443     {
1444         glDeleteBuffers(1, &mPBO);
1445         Texture2DTest::testTearDown();
1446     }
1447
1448     GLuint mPBO;
1449 };
1450
1451 class ETC1CompressedTextureTest : public Texture2DTest
1452 {
1453   protected:
1454     ETC1CompressedTextureTest() : Texture2DTest() {}
1455
1456     void testSetUp() override
1457     {
1458         TexCoordDrawTest::testSetUp();
1459         glGenTextures(1, &mTexture2D);
1460         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1461         EXPECT_GL_NO_ERROR();
1462
1463         setUpProgram();
1464     }
1465
1466     void testTearDown() override { Texture2DTest::testTearDown(); }
1467 };
1468
1469 TEST_P(Texture2DTest, NegativeAPISubImage)
1470 {
1471     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1472     EXPECT_GL_ERROR(GL_NO_ERROR);
1473
1474     setUpProgram();
1475
1476     const GLubyte *pixels[20] = {0};
1477     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1478     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1479
1480     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
1481     {
1482         // Create a 1-level immutable texture.
1483         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1484
1485         // Try calling sub image on the second level.
1486         glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1487         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1488     }
1489 }
1490
1491 // Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
1492 TEST_P(Texture2DTest, QueryBinding)
1493 {
1494     glBindTexture(GL_TEXTURE_2D, 0);
1495     EXPECT_GL_ERROR(GL_NO_ERROR);
1496
1497     GLint textureBinding;
1498     glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1499     EXPECT_GL_NO_ERROR();
1500     EXPECT_EQ(0, textureBinding);
1501
1502     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
1503     if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1504         IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
1505     {
1506         EXPECT_GL_NO_ERROR();
1507         EXPECT_EQ(0, textureBinding);
1508     }
1509     else
1510     {
1511         EXPECT_GL_ERROR(GL_INVALID_ENUM);
1512     }
1513 }
1514
1515 TEST_P(Texture2DTest, ZeroSizedUploads)
1516 {
1517     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1518     EXPECT_GL_ERROR(GL_NO_ERROR);
1519
1520     setUpProgram();
1521
1522     // Use the texture first to make sure it's in video memory
1523     glUseProgram(mProgram);
1524     glUniform1i(mTexture2DUniformLocation, 0);
1525     drawQuad(mProgram, "position", 0.5f);
1526
1527     const GLubyte *pixel[4] = {0};
1528
1529     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1530     EXPECT_GL_NO_ERROR();
1531
1532     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1533     EXPECT_GL_NO_ERROR();
1534
1535     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1536     EXPECT_GL_NO_ERROR();
1537 }
1538
1539 // Test drawing with two texture types, to trigger an ANGLE bug in validation
1540 TEST_P(TextureCubeTest, CubeMapBug)
1541 {
1542     glActiveTexture(GL_TEXTURE0);
1543     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1544     glActiveTexture(GL_TEXTURE1);
1545     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1546     EXPECT_GL_ERROR(GL_NO_ERROR);
1547
1548     glUseProgram(mProgram);
1549     glUniform1i(mTexture2DUniformLocation, 0);
1550     glUniform1i(mTextureCubeUniformLocation, 1);
1551     drawQuad(mProgram, "position", 0.5f);
1552     EXPECT_GL_NO_ERROR();
1553 }
1554
1555 // Test drawing with two texture types accessed from the same shader and check that the result of
1556 // drawing is correct.
1557 TEST_P(TextureCubeTest, CubeMapDraw)
1558 {
1559     GLubyte texData[4];
1560     texData[0] = 0;
1561     texData[1] = 60;
1562     texData[2] = 0;
1563     texData[3] = 255;
1564
1565     glActiveTexture(GL_TEXTURE0);
1566     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1567     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1568
1569     glActiveTexture(GL_TEXTURE1);
1570     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1571     texData[1] = 120;
1572     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1573                     texData);
1574     EXPECT_GL_ERROR(GL_NO_ERROR);
1575
1576     glUseProgram(mProgram);
1577     glUniform1i(mTexture2DUniformLocation, 0);
1578     glUniform1i(mTextureCubeUniformLocation, 1);
1579     drawQuad(mProgram, "position", 0.5f);
1580     EXPECT_GL_NO_ERROR();
1581
1582     int px = getWindowWidth() - 1;
1583     int py = 0;
1584     EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1585 }
1586
1587 TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1588 {
1589     glActiveTexture(GL_TEXTURE0);
1590     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1591     GLubyte texData[4];
1592     texData[0] = 0;
1593     texData[1] = 128;
1594     texData[2] = 0;
1595     texData[3] = 255;
1596     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1597     glUseProgram(mProgram);
1598     glUniform1i(mTexture2DUniformLocation, 0);
1599     drawQuad(mProgram, "position", 0.5f);
1600     EXPECT_GL_NO_ERROR();
1601
1602     EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1603 }
1604
1605 // Test drawing with two textures passed to the shader in a sampler array.
1606 TEST_P(SamplerArrayTest, SamplerArrayDraw)
1607 {
1608     testSamplerArrayDraw();
1609 }
1610
1611 // Test drawing with two textures passed to the shader in a sampler array which is passed to a
1612 // user-defined function in the shader.
1613 TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1614 {
1615     // TODO: Diagnose and fix. http://anglebug.com/2955
1616     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1617
1618     testSamplerArrayDraw();
1619 }
1620
1621 // Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
1622 TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
1623 {
1624     int px = getWindowWidth() / 2;
1625     int py = getWindowHeight() / 2;
1626
1627     glActiveTexture(GL_TEXTURE0);
1628     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1629
1630     std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
1631
1632     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
1633     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1634     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1635     glGenerateMipmap(GL_TEXTURE_2D);
1636
1637     glUseProgram(mProgram);
1638     glUniform1i(mTexture2DUniformLocation, 0);
1639     glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1640     drawQuad(mProgram, "position", 0.5f);
1641     EXPECT_GL_NO_ERROR();
1642     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1643
1644     std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
1645
1646     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1647                  pixelsBlue.data());
1648     glGenerateMipmap(GL_TEXTURE_2D);
1649
1650     std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
1651
1652     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1653                  pixelsGreen.data());
1654     glGenerateMipmap(GL_TEXTURE_2D);
1655
1656     drawQuad(mProgram, "position", 0.5f);
1657
1658     EXPECT_GL_NO_ERROR();
1659     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1660 }
1661
1662 // Test creating a FBO with a cube map render target, to test an ANGLE bug
1663 // https://code.google.com/p/angleproject/issues/detail?id=849
1664 TEST_P(TextureCubeTest, CubeMapFBO)
1665 {
1666     // http://anglebug.com/3145
1667     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1668
1669     // http://anglebug.com/2822
1670     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1671
1672     GLFramebuffer fbo;
1673     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1674
1675     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1676     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1677                            mTextureCube, 0);
1678
1679     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1680     EXPECT_GL_NO_ERROR();
1681
1682     // Test clearing the six mip faces individually.
1683     std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
1684                                           GLColor::yellow, GLColor::cyan, GLColor::magenta}};
1685
1686     for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1687     {
1688         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1689                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1690
1691         Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
1692         glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
1693         glClear(GL_COLOR_BUFFER_BIT);
1694
1695         EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
1696     }
1697
1698     // Iterate the faces again to make sure the colors haven't changed.
1699     for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1700     {
1701         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1702                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1703         EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
1704             << "face color " << faceIndex << " shouldn't change";
1705     }
1706 }
1707
1708 // Tests clearing a cube map with a scissor enabled.
1709 TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
1710 {
1711     // TODO(jie.a.chen): Diagnose and fix. http://anglebug.com/2822
1712     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
1713
1714     // http://anglebug.com/3145
1715     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1716
1717     constexpr size_t kSize = 16;
1718
1719     GLFramebuffer fbo;
1720     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1721     glViewport(0, 0, kSize, kSize);
1722
1723     GLTexture texcube;
1724     glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
1725     for (GLenum face = 0; face < 6; face++)
1726     {
1727         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
1728                      GL_UNSIGNED_BYTE, nullptr);
1729     }
1730     ASSERT_GL_NO_ERROR();
1731
1732     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1733                            texcube, 0);
1734
1735     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1736     ASSERT_GL_NO_ERROR();
1737
1738     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1739     glClear(GL_COLOR_BUFFER_BIT);
1740     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1741
1742     glEnable(GL_SCISSOR_TEST);
1743     glScissor(kSize / 2, 0, kSize / 2, kSize);
1744     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1745     glClear(GL_COLOR_BUFFER_BIT);
1746
1747     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1748     EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
1749
1750     ASSERT_GL_NO_ERROR();
1751 }
1752
1753 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
1754 // default color.
1755 TEST_P(Texture2DTest, TexStorage)
1756 {
1757     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1758                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
1759
1760     int width  = getWindowWidth();
1761     int height = getWindowHeight();
1762
1763     GLuint tex2D;
1764     glGenTextures(1, &tex2D);
1765     glActiveTexture(GL_TEXTURE0);
1766     glBindTexture(GL_TEXTURE_2D, tex2D);
1767
1768     // Fill with red
1769     std::vector<GLubyte> pixels(3 * 16 * 16);
1770     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1771     {
1772         pixels[pixelId * 3 + 0] = 255;
1773         pixels[pixelId * 3 + 1] = 0;
1774         pixels[pixelId * 3 + 2] = 0;
1775     }
1776
1777     // ANGLE internally uses RGBA as the DirectX format for RGB images
1778     // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1779     // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
1780     if (getClientMajorVersion() >= 3)
1781     {
1782         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1783     }
1784     else
1785     {
1786         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1787     }
1788
1789     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1790     // glTexSubImage2D should take into account that the image is dirty.
1791     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1792     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1793     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1794
1795     setUpProgram();
1796
1797     glUseProgram(mProgram);
1798     glUniform1i(mTexture2DUniformLocation, 0);
1799     drawQuad(mProgram, "position", 0.5f);
1800     glDeleteTextures(1, &tex2D);
1801     EXPECT_GL_NO_ERROR();
1802     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1803
1804     // Validate that the region of the texture without data has an alpha of 1.0
1805     angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
1806     EXPECT_EQ(255, pixel.A);
1807 }
1808
1809 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
1810 // initialized the image with a default color.
1811 TEST_P(Texture2DTest, TexStorageWithPBO)
1812 {
1813     // http://anglebug.com/4126
1814     ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
1815
1816     if (getClientMajorVersion() < 3)
1817     {
1818         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1819         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
1820     }
1821
1822     const int width          = getWindowWidth();
1823     const int height         = getWindowHeight();
1824     const size_t pixelCount  = width * height;
1825     const int componentCount = 3;
1826
1827     GLuint tex2D;
1828     glGenTextures(1, &tex2D);
1829     glActiveTexture(GL_TEXTURE0);
1830     glBindTexture(GL_TEXTURE_2D, tex2D);
1831
1832     // Fill with red
1833     std::vector<GLubyte> pixels(componentCount * pixelCount);
1834     for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
1835     {
1836         pixels[pixelId * componentCount + 0] = 255;
1837         pixels[pixelId * componentCount + 1] = 0;
1838         pixels[pixelId * componentCount + 2] = 0;
1839     }
1840
1841     // Read 16x16 region from red backbuffer to PBO
1842     GLuint pbo;
1843     glGenBuffers(1, &pbo);
1844     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1845     glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
1846                  GL_STATIC_DRAW);
1847
1848     // ANGLE internally uses RGBA as the DirectX format for RGB images
1849     // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1850     // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
1851     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
1852
1853     // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
1854     // untouched. glTexSubImage2D should take into account that the image is dirty.
1855     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
1856                     nullptr);
1857     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1858     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1859
1860     setUpProgram();
1861
1862     glUseProgram(mProgram);
1863     glUniform1i(mTexture2DUniformLocation, 0);
1864     drawQuad(mProgram, "position", 0.5f);
1865     glDeleteTextures(1, &tex2D);
1866     glDeleteBuffers(1, &pbo);
1867     EXPECT_GL_NO_ERROR();
1868     EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1869     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1870 }
1871
1872 // Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
1873 // and drawing with the texture
1874 // Pseudo code for the follow test:
1875 // 1. Upload PBO to mTexture2D
1876 // 2. Delete PBO
1877 // 3. Draw with otherTexture (x5)
1878 // 4. Draw with mTexture2D
1879 // 5. Validate color output
1880 TEST_P(Texture2DTest, PBOWithMultipleDraws)
1881 {
1882     if (getClientMajorVersion() < 3)
1883     {
1884         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1885         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
1886     }
1887
1888     const GLuint width            = getWindowWidth();
1889     const GLuint height           = getWindowHeight();
1890     const GLuint windowPixelCount = width * height;
1891     std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
1892     std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
1893
1894     // Create secondary draw that does not use mTexture
1895     const char *vertexShaderSource   = getVertexShaderSource();
1896     const char *fragmentShaderSource = getFragmentShaderSource();
1897     ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
1898
1899     GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
1900     ASSERT_NE(-1, uniformLoc);
1901     glUseProgram(0);
1902
1903     // Create secondary Texture to draw with
1904     GLTexture otherTexture;
1905     glActiveTexture(GL_TEXTURE0);
1906     glBindTexture(GL_TEXTURE_2D, otherTexture);
1907     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1908     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1909                     pixelsRed.data());
1910     ASSERT_GL_NO_ERROR();
1911
1912     // Setup primary Texture
1913     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1914     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1915     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1916     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1917     ASSERT_GL_NO_ERROR();
1918
1919     // Setup PBO
1920     GLuint pbo = 0;
1921     glGenBuffers(1, &pbo);
1922     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1923     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
1924                  GL_STATIC_DRAW);
1925     ASSERT_GL_NO_ERROR();
1926
1927     // Write PBO to mTexture
1928     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1929     ASSERT_GL_NO_ERROR();
1930     // Delete PBO as ANGLE should be properly handling refcount of this buffer
1931     glDeleteBuffers(1, &pbo);
1932     pixelsGreen.clear();
1933
1934     // Do 5 draws not involving primary texture that the PBO updated
1935     glUseProgram(otherProgram);
1936     glUniform1i(uniformLoc, 0);
1937     glBindTexture(GL_TEXTURE_2D, otherTexture);
1938     drawQuad(otherProgram, "position", 0.5f);
1939     glBindTexture(GL_TEXTURE_2D, 0);
1940     glUseProgram(0);
1941
1942     glUseProgram(otherProgram);
1943     glUniform1i(uniformLoc, 0);
1944     glBindTexture(GL_TEXTURE_2D, otherTexture);
1945     drawQuad(otherProgram, "position", 0.5f);
1946     glBindTexture(GL_TEXTURE_2D, 0);
1947     glUseProgram(0);
1948
1949     glUseProgram(otherProgram);
1950     glUniform1i(uniformLoc, 0);
1951     glBindTexture(GL_TEXTURE_2D, otherTexture);
1952     drawQuad(otherProgram, "position", 0.5f);
1953     glBindTexture(GL_TEXTURE_2D, 0);
1954     glUseProgram(0);
1955
1956     glUseProgram(otherProgram);
1957     glUniform1i(uniformLoc, 0);
1958     glBindTexture(GL_TEXTURE_2D, otherTexture);
1959     drawQuad(otherProgram, "position", 0.5f);
1960     glBindTexture(GL_TEXTURE_2D, 0);
1961     glUseProgram(0);
1962     ASSERT_GL_NO_ERROR();
1963
1964     std::vector<GLColor> output(windowPixelCount, GLColor::black);
1965     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1966                  output.data());
1967     EXPECT_EQ(pixelsRed, output);
1968
1969     setUpProgram();
1970     // Draw using PBO updated texture
1971     glUseProgram(mProgram);
1972     glUniform1i(mTexture2DUniformLocation, 0);
1973     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1974     drawQuad(mProgram, "position", 0.5f);
1975     ASSERT_GL_NO_ERROR();
1976
1977     std::vector<GLColor> actual(windowPixelCount, GLColor::black);
1978     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1979                  actual.data());
1980     // Value should be green as it was updated during PBO transfer to mTexture
1981     std::vector<GLColor> expected(windowPixelCount, GLColor::green);
1982     EXPECT_EQ(expected, actual);
1983 }
1984
1985 // Tests CopySubImage for float formats
1986 TEST_P(Texture2DTest, CopySubImageFloat_R_R)
1987 {
1988     testFloatCopySubImage(1, 1);
1989 }
1990
1991 TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
1992 {
1993     testFloatCopySubImage(2, 1);
1994 }
1995
1996 TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
1997 {
1998     testFloatCopySubImage(2, 2);
1999 }
2000
2001 TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
2002 {
2003     testFloatCopySubImage(3, 1);
2004 }
2005
2006 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
2007 {
2008     testFloatCopySubImage(3, 2);
2009 }
2010
2011 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
2012 {
2013     // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2014     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2015
2016     // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2017     ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
2018
2019     testFloatCopySubImage(3, 3);
2020 }
2021
2022 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
2023 {
2024     testFloatCopySubImage(4, 1);
2025 }
2026
2027 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
2028 {
2029     testFloatCopySubImage(4, 2);
2030 }
2031
2032 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
2033 {
2034     // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2035     ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
2036
2037     testFloatCopySubImage(4, 3);
2038 }
2039
2040 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
2041 {
2042     // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2043     ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
2044
2045     testFloatCopySubImage(4, 4);
2046 }
2047
2048 // Port of
2049 // https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
2050 // Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
2051 // handles GL_ALPHA
2052 TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
2053 {
2054     const int npotTexSize = 5;
2055     const int potTexSize  = 4;  // Should be less than npotTexSize
2056     GLuint tex2D;
2057
2058     if (IsGLExtensionEnabled("GL_OES_texture_npot"))
2059     {
2060         // This test isn't applicable if texture_npot is enabled
2061         return;
2062     }
2063
2064     setUpProgram();
2065
2066     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2067
2068     // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
2069     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2070
2071     glActiveTexture(GL_TEXTURE0);
2072     glGenTextures(1, &tex2D);
2073     glBindTexture(GL_TEXTURE_2D, tex2D);
2074
2075     const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
2076
2077     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2078     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2079
2080     // Check that an NPOT texture not on level 0 generates INVALID_VALUE
2081     glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2082                  GL_UNSIGNED_BYTE, pixels.data());
2083     EXPECT_GL_ERROR(GL_INVALID_VALUE);
2084
2085     // Check that an NPOT texture on level 0 succeeds
2086     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2087                  GL_UNSIGNED_BYTE, pixels.data());
2088     EXPECT_GL_NO_ERROR();
2089
2090     // Check that generateMipmap fails on NPOT
2091     glGenerateMipmap(GL_TEXTURE_2D);
2092     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2093
2094     // Check that nothing is drawn if filtering is not correct for NPOT
2095     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2096     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2097     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2098     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2099     glClear(GL_COLOR_BUFFER_BIT);
2100     drawQuad(mProgram, "position", 1.0f);
2101     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2102
2103     // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
2104     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2105     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2106     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
2107     glClear(GL_COLOR_BUFFER_BIT);
2108     drawQuad(mProgram, "position", 1.0f);
2109     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2110
2111     // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
2112     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2113     glClear(GL_COLOR_BUFFER_BIT);
2114     drawQuad(mProgram, "position", 1.0f);
2115     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2116
2117     // Check that glTexImage2D for POT texture succeeds
2118     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
2119                  pixels.data());
2120     EXPECT_GL_NO_ERROR();
2121
2122     // Check that generateMipmap for an POT texture succeeds
2123     glGenerateMipmap(GL_TEXTURE_2D);
2124     EXPECT_GL_NO_ERROR();
2125
2126     // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
2127     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2128     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2129     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2130     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2131     glClear(GL_COLOR_BUFFER_BIT);
2132     drawQuad(mProgram, "position", 1.0f);
2133     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2134     EXPECT_GL_NO_ERROR();
2135 }
2136
2137 // Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
2138 // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
2139 TEST_P(Texture2DTest, NPOTSubImageParameters)
2140 {
2141     glActiveTexture(GL_TEXTURE0);
2142     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2143
2144     // Create an 8x8 (i.e. power-of-two) texture.
2145     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2146     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2147     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2148     glGenerateMipmap(GL_TEXTURE_2D);
2149
2150     // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
2151     // This should always work, even if GL_OES_texture_npot isn't active.
2152     std::array<GLColor, 3 * 3> data;
2153     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
2154
2155     EXPECT_GL_NO_ERROR();
2156 }
2157
2158 // Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
2159 // TextureImpl and the texture is synced before being used in a draw call.
2160 TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
2161 {
2162     ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
2163     // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
2164     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
2165     // D3D Debug device reports an error. http://anglebug.com/3501
2166     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
2167     // TODO(cnorthrop): Needs triage on Vulkan backend. http://anglebug.com/3950
2168     ANGLE_SKIP_TEST_IF(IsVulkan());
2169
2170     // The workaround in the GL backend required to trigger this bug generates driver warning
2171     // messages.
2172     ScopedIgnorePlatformMessages ignoreMessages;
2173
2174     setUpProgram();
2175     glUseProgram(mProgram);
2176     glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
2177
2178     GLTexture dest;
2179     glBindTexture(GL_TEXTURE_2D, dest);
2180
2181     GLTexture source;
2182     glBindTexture(GL_TEXTURE_2D, source);
2183
2184     // Put data in mip 0 and 1
2185     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2186                  GLColor::red.data());
2187     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2188                  GLColor::green.data());
2189
2190     // Disable mipmapping so source is complete
2191     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2192     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2193
2194     // Force the dirty bits to be synchronized in source
2195     drawQuad(mProgram, "position", 1.0f);
2196
2197     // Copy from mip 1 of the source.  In the GL backend this internally sets the base level to mip
2198     // 1 and sets a dirty bit.
2199     glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
2200                           GL_FALSE, GL_FALSE);
2201
2202     // Draw again, assertions are generated if the texture has internal dirty bits at draw time
2203     drawQuad(mProgram, "position", 1.0f);
2204 }
2205
2206 // This test case changes the base level of a texture that's attached to a framebuffer, clears every
2207 // level to green, and then samples the texture when rendering. Test is taken from
2208 // https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
2209 TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
2210 {
2211     // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
2212     ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
2213
2214     setUpProgram();
2215
2216     constexpr GLint width  = 8;
2217     constexpr GLint height = 4;
2218
2219     GLTexture texture;
2220     glBindTexture(GL_TEXTURE_2D, texture);
2221     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2222     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2223     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2224     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2225
2226     // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
2227     GLint level  = 0;
2228     GLint levelW = width;
2229     GLint levelH = height;
2230     glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2231                  nullptr);
2232     while (levelW > 1 || levelH > 1)
2233     {
2234         ++level;
2235         levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
2236         levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
2237         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2238                      nullptr);
2239     }
2240
2241     // Clear each level of the texture using an FBO. Change the base level to match the level used
2242     // for the FBO on each iteration.
2243     GLFramebuffer fbo;
2244     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2245     level  = 0;
2246     levelW = width;
2247     levelH = height;
2248     while (levelW > 1 || levelH > 1)
2249     {
2250         levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
2251         levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
2252
2253         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
2254         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
2255
2256         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2257         EXPECT_GL_NO_ERROR();
2258
2259         glClearColor(0, 1, 0, 1);
2260         glClear(GL_COLOR_BUFFER_BIT);
2261
2262         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2263
2264         ++level;
2265     }
2266
2267     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2268     glViewport(0, 0, 16, 16);
2269     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2270
2271     drawQuad(mProgram, "position", 0.5f);
2272
2273     EXPECT_GL_NO_ERROR();
2274     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2275 }
2276
2277 // Test to check that texture completeness is determined correctly when the texture base level is
2278 // greater than 0, and also that level 0 is not sampled when base level is greater than 0.
2279 TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
2280 {
2281     glActiveTexture(GL_TEXTURE0);
2282     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2283
2284     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
2285     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2286     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2287     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2288                  texDataGreen.data());
2289     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2290                  texDataGreen.data());
2291     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2292     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2293     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2294
2295     EXPECT_GL_NO_ERROR();
2296
2297     drawQuad(mProgram, "position", 0.5f);
2298
2299     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2300 }
2301
2302 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2303 // have images defined.
2304 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
2305 {
2306     // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2307     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2308
2309     glActiveTexture(GL_TEXTURE0);
2310     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2311     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2312     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2313                  texDataGreen.data());
2314     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2315     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2316     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2317     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2318
2319     EXPECT_GL_NO_ERROR();
2320
2321     drawQuad(mProgram, "position", 0.5f);
2322
2323     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2324 }
2325
2326 // Test that drawing works correctly when level 0 is undefined and base level is 1.
2327 TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
2328 {
2329     // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2330     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2331
2332     glActiveTexture(GL_TEXTURE0);
2333     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2334     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2335     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2336                  texDataGreen.data());
2337     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2338     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2339     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2340     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2341
2342     EXPECT_GL_NO_ERROR();
2343
2344     // Texture is incomplete.
2345     drawQuad(mProgram, "position", 0.5f);
2346     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2347
2348     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2349                  texDataGreen.data());
2350
2351     // Texture is now complete.
2352     drawQuad(mProgram, "position", 0.5f);
2353     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2354 }
2355
2356 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2357 // dimensions that don't fit the images inside the range.
2358 // GLES 3.0.4 section 3.8.13 Texture completeness
2359 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2360 {
2361     glActiveTexture(GL_TEXTURE0);
2362     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2363     std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
2364     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2365     std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
2366
2367     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2368     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2369
2370     // Two levels that are initially unused.
2371     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2372     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2373                  texDataCyan.data());
2374
2375     // One level that is used - only this level should affect completeness.
2376     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2377                  texDataGreen.data());
2378
2379     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2380     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2381
2382     EXPECT_GL_NO_ERROR();
2383
2384     drawQuad(mProgram, "position", 0.5f);
2385
2386     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2387
2388     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2389
2390     // Switch the level that is being used to the cyan level 2.
2391     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2392     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2393
2394     EXPECT_GL_NO_ERROR();
2395
2396     drawQuad(mProgram, "position", 0.5f);
2397
2398     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2399 }
2400
2401 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2402 // have images defined.
2403 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
2404 {
2405     glActiveTexture(GL_TEXTURE0);
2406     glBindTexture(GL_TEXTURE_3D, mTexture3D);
2407     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2408     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2409                  texDataGreen.data());
2410     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2411     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2412     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2413     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2414
2415     EXPECT_GL_NO_ERROR();
2416
2417     drawQuad(mProgram, "position", 0.5f);
2418
2419     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2420 }
2421
2422 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2423 // dimensions that don't fit the images inside the range.
2424 // GLES 3.0.4 section 3.8.13 Texture completeness
2425 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2426 {
2427     // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
2428     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
2429
2430     glActiveTexture(GL_TEXTURE0);
2431     glBindTexture(GL_TEXTURE_3D, mTexture3D);
2432     std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2433     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2434     std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2435
2436     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2437     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2438
2439     // Two levels that are initially unused.
2440     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2441                  texDataRed.data());
2442     glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2443                  texDataCyan.data());
2444
2445     // One level that is used - only this level should affect completeness.
2446     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2447                  texDataGreen.data());
2448
2449     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2450     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2451
2452     EXPECT_GL_NO_ERROR();
2453
2454     drawQuad(mProgram, "position", 0.5f);
2455
2456     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2457
2458     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2459
2460     // Switch the level that is being used to the cyan level 2.
2461     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
2462     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
2463
2464     EXPECT_GL_NO_ERROR();
2465
2466     drawQuad(mProgram, "position", 0.5f);
2467
2468     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2469 }
2470
2471 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2472 // have images defined.
2473 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
2474 {
2475     glActiveTexture(GL_TEXTURE0);
2476     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2477     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2478     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2479                  texDataGreen.data());
2480     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2481     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2482     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2483     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2484
2485     EXPECT_GL_NO_ERROR();
2486
2487     drawQuad(mProgram, "position", 0.5f);
2488
2489     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2490 }
2491
2492 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2493 // dimensions that don't fit the images inside the range.
2494 // GLES 3.0.4 section 3.8.13 Texture completeness
2495 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2496 {
2497     // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2498     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2499
2500     glActiveTexture(GL_TEXTURE0);
2501     glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
2502     std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2503     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2504     std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2505
2506     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2507     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2508
2509     // Two levels that are initially unused.
2510     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2511                  texDataRed.data());
2512     glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2513                  texDataCyan.data());
2514
2515     // One level that is used - only this level should affect completeness.
2516     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2517                  texDataGreen.data());
2518
2519     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2520     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2521
2522     EXPECT_GL_NO_ERROR();
2523
2524     drawQuad(mProgram, "position", 0.5f);
2525
2526     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2527
2528     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2529
2530     // Switch the level that is being used to the cyan level 2.
2531     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
2532     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
2533
2534     EXPECT_GL_NO_ERROR();
2535
2536     drawQuad(mProgram, "position", 0.5f);
2537
2538     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2539 }
2540
2541 // Test that texture completeness is updated if texture max level changes.
2542 // GLES 3.0.4 section 3.8.13 Texture completeness
2543 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2544 {
2545     glActiveTexture(GL_TEXTURE0);
2546     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2547     std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2548
2549     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2550     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2551
2552     // A level that is initially unused.
2553     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2554                  texDataGreen.data());
2555
2556     // One level that is initially used - only this level should affect completeness.
2557     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2558                  texDataGreen.data());
2559
2560     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2561     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2562
2563     EXPECT_GL_NO_ERROR();
2564
2565     drawQuad(mProgram, "position", 0.5f);
2566
2567     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2568
2569     // Switch the max level to level 1. The levels within the used range now have inconsistent
2570     // dimensions and the texture should be incomplete.
2571     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2572
2573     EXPECT_GL_NO_ERROR();
2574
2575     drawQuad(mProgram, "position", 0.5f);
2576
2577     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2578 }
2579
2580 // Test that 3D texture completeness is updated if texture max level changes.
2581 // GLES 3.0.4 section 3.8.13 Texture completeness
2582 TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2583 {
2584     glActiveTexture(GL_TEXTURE0);
2585     glBindTexture(GL_TEXTURE_3D, mTexture3D);
2586     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2587
2588     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2589     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2590
2591     // A level that is initially unused.
2592     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2593                  texDataGreen.data());
2594
2595     // One level that is initially used - only this level should affect completeness.
2596     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2597                  texDataGreen.data());
2598
2599     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2600     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2601
2602     EXPECT_GL_NO_ERROR();
2603
2604     drawQuad(mProgram, "position", 0.5f);
2605
2606     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2607
2608     // Switch the max level to level 1. The levels within the used range now have inconsistent
2609     // dimensions and the texture should be incomplete.
2610     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2611
2612     EXPECT_GL_NO_ERROR();
2613
2614     drawQuad(mProgram, "position", 0.5f);
2615
2616     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2617 }
2618
2619 // Test that texture completeness is updated if texture base level changes.
2620 // GLES 3.0.4 section 3.8.13 Texture completeness
2621 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2622 {
2623     glActiveTexture(GL_TEXTURE0);
2624     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2625     std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2626
2627     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2628     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2629
2630     // Two levels that are initially unused.
2631     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2632                  texDataGreen.data());
2633     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2634                  texDataGreen.data());
2635
2636     // One level that is initially used - only this level should affect completeness.
2637     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2638                  texDataGreen.data());
2639
2640     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2641     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2642
2643     EXPECT_GL_NO_ERROR();
2644
2645     drawQuad(mProgram, "position", 0.5f);
2646
2647     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2648
2649     // Switch the base level to level 1. The levels within the used range now have inconsistent
2650     // dimensions and the texture should be incomplete.
2651     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2652
2653     EXPECT_GL_NO_ERROR();
2654
2655     drawQuad(mProgram, "position", 0.5f);
2656
2657     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2658 }
2659
2660 // Test that texture is not complete if base level is greater than max level.
2661 // GLES 3.0.4 section 3.8.13 Texture completeness
2662 TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2663 {
2664     glActiveTexture(GL_TEXTURE0);
2665     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2666
2667     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2668     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2669
2670     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2671
2672     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2673     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2674
2675     EXPECT_GL_NO_ERROR();
2676
2677     drawQuad(mProgram, "position", 0.5f);
2678
2679     // Texture should be incomplete.
2680     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2681 }
2682
2683 // Test that immutable texture base level and max level are clamped.
2684 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2685 TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2686 {
2687     glActiveTexture(GL_TEXTURE0);
2688     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2689
2690     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2691     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2692
2693     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2694
2695     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2696
2697     // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2698     // should be clamped to [base_level, levels - 1].
2699     // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2700     // In the case of this test, those rules make the effective base level and max level 0.
2701     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2702     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2703
2704     EXPECT_GL_NO_ERROR();
2705
2706     drawQuad(mProgram, "position", 0.5f);
2707
2708     // Texture should be complete.
2709     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2710 }
2711
2712 // Test that changing base level works when it affects the format of the texture.
2713 TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2714 {
2715     // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2716     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2717
2718     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
2719
2720     // Observed incorrect rendering on AMD OpenGL.
2721     ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
2722
2723     glActiveTexture(GL_TEXTURE0);
2724     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2725     std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2726     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2727
2728     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2729     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2730
2731     // RGBA8 level that's initially unused.
2732     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2733                  texDataCyan.data());
2734
2735     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2736     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2737
2738     // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2739     // format. It reads green channel data from the green and alpha channels of texDataGreen
2740     // (this is a bit hacky but works).
2741     glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2742
2743     EXPECT_GL_NO_ERROR();
2744
2745     drawQuad(mProgram, "position", 0.5f);
2746
2747     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2748
2749     // Switch the texture to use the cyan level 0 with the RGBA format.
2750     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2751     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2752
2753     EXPECT_GL_NO_ERROR();
2754
2755     drawQuad(mProgram, "position", 0.5f);
2756
2757     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2758 }
2759
2760 // Test that setting a texture image works when base level is out of range.
2761 TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2762 {
2763     glActiveTexture(GL_TEXTURE0);
2764     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2765
2766     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2767     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2768
2769     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2770     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2771
2772     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2773
2774     EXPECT_GL_NO_ERROR();
2775
2776     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2777
2778     drawQuad(mProgram, "position", 0.5f);
2779
2780     // Texture should be complete.
2781     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2782 }
2783
2784 // In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
2785 // RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
2786 // with these formats does not work as expected.
2787 TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
2788 {
2789     std::vector<GLubyte> pixelData;
2790     for (size_t count = 0; count < 5000; count++)
2791     {
2792         pixelData.push_back(0u);
2793         pixelData.push_back(255u);
2794         pixelData.push_back(0u);
2795     }
2796
2797     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2798     glUseProgram(mProgram);
2799     glUniform1i(mTextureArrayLocation, 0);
2800
2801     // The first draw worked correctly.
2802     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2803                  &pixelData[0]);
2804
2805     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2806     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2807     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2808     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
2809     drawQuad(mProgram, "position", 1.0f);
2810     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2811
2812     // The dimension of the respecification must match the original exactly to trigger the bug.
2813     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2814                  &pixelData[0]);
2815     drawQuad(mProgram, "position", 1.0f);
2816     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2817
2818     ASSERT_GL_NO_ERROR();
2819 }
2820
2821 // Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2822 // This test is needed especially to confirm that sampler registers get assigned correctly on
2823 // the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2824 TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2825 {
2826     glActiveTexture(GL_TEXTURE0);
2827     glBindTexture(GL_TEXTURE_3D, mTexture3D);
2828     GLubyte texData[4];
2829     texData[0] = 0;
2830     texData[1] = 60;
2831     texData[2] = 0;
2832     texData[3] = 255;
2833     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2834
2835     glActiveTexture(GL_TEXTURE1);
2836     glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2837     GLfloat depthTexData[1];
2838     depthTexData[0] = 0.5f;
2839     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2840                  depthTexData);
2841
2842     glUseProgram(mProgram);
2843     glUniform1f(mDepthRefUniformLocation, 0.3f);
2844     glUniform1i(mTexture3DUniformLocation, 0);
2845     glUniform1i(mTextureShadowUniformLocation, 1);
2846
2847     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2848     drawQuad(mProgram, "position", 0.5f);
2849     EXPECT_GL_NO_ERROR();
2850     // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2851     EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2852
2853     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2854     drawQuad(mProgram, "position", 0.5f);
2855     EXPECT_GL_NO_ERROR();
2856     // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2857     EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2858 }
2859
2860 // Test multiple different sampler types in the same shader.
2861 // This test makes sure that even if sampler / texture registers get grouped together based on type
2862 // or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2863 // still has the right register index information for each ESSL sampler.
2864 // The tested ESSL samplers have the following types in D3D11 HLSL:
2865 // sampler2D:         Texture2D   + SamplerState
2866 // samplerCube:       TextureCube + SamplerState
2867 // sampler2DShadow:   Texture2D   + SamplerComparisonState
2868 // samplerCubeShadow: TextureCube + SamplerComparisonState
2869 TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2870 {
2871     glActiveTexture(GL_TEXTURE0);
2872     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2873     GLubyte texData[4];
2874     texData[0] = 0;
2875     texData[1] = 0;
2876     texData[2] = 120;
2877     texData[3] = 255;
2878     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2879
2880     glActiveTexture(GL_TEXTURE1);
2881     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2882     texData[0] = 0;
2883     texData[1] = 90;
2884     texData[2] = 0;
2885     texData[3] = 255;
2886     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2887     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2888                     texData);
2889
2890     glActiveTexture(GL_TEXTURE2);
2891     glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2892     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2893     GLfloat depthTexData[1];
2894     depthTexData[0] = 0.5f;
2895     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2896                  depthTexData);
2897
2898     glActiveTexture(GL_TEXTURE3);
2899     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2900     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2901     depthTexData[0] = 0.2f;
2902     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2903     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2904                     depthTexData);
2905
2906     // http://anglebug.com/3949: TODO: Add a DS texture case
2907
2908     EXPECT_GL_NO_ERROR();
2909
2910     glUseProgram(mProgram);
2911     glUniform1f(mDepthRefUniformLocation, 0.3f);
2912     glUniform1i(mTexture2DUniformLocation, 0);
2913     glUniform1i(mTextureCubeUniformLocation, 1);
2914     glUniform1i(mTexture2DShadowUniformLocation, 2);
2915     glUniform1i(mTextureCubeShadowUniformLocation, 3);
2916
2917     drawQuad(mProgram, "position", 0.5f);
2918     EXPECT_GL_NO_ERROR();
2919     // The shader writes:
2920     // <texture 2d color> +
2921     // <cube map color> +
2922     // 0.25 * <comparison result (1.0)> +
2923     // 0.125 * <comparison result (0.0)>
2924     EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2925 }
2926
2927 // Test different base levels on textures accessed through the same sampler array.
2928 // Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2929 TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2930 {
2931     ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
2932
2933     // http://anglebug.com/4391
2934     ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
2935
2936     glActiveTexture(GL_TEXTURE0);
2937     glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2938     GLsizei size = 64;
2939     for (GLint level = 0; level < 7; ++level)
2940     {
2941         ASSERT_LT(0, size);
2942         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2943                      nullptr);
2944         size = size / 2;
2945     }
2946     ASSERT_EQ(0, size);
2947     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2948
2949     glActiveTexture(GL_TEXTURE1);
2950     glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2951     size = 128;
2952     for (GLint level = 0; level < 8; ++level)
2953     {
2954         ASSERT_LT(0, size);
2955         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2956                      nullptr);
2957         size = size / 2;
2958     }
2959     ASSERT_EQ(0, size);
2960     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2961     EXPECT_GL_NO_ERROR();
2962
2963     glUseProgram(mProgram);
2964     glUniform1i(mTexture0Location, 0);
2965     glUniform1i(mTexture1Location, 1);
2966
2967     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
2968     EXPECT_GL_NO_ERROR();
2969     // Red channel: width of level 1 of texture A: 32.
2970     // Green channel: width of level 3 of texture B: 16.
2971     EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2972 }
2973
2974 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2975 // ES 3.0.4 table 3.24
2976 TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2977 {
2978     glActiveTexture(GL_TEXTURE0);
2979     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2980     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2981     EXPECT_GL_NO_ERROR();
2982
2983     drawQuad(mProgram, "position", 0.5f);
2984
2985     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2986 }
2987
2988 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2989 // ES 3.0.4 table 3.24
2990 TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
2991 {
2992     setUpProgram();
2993
2994     glActiveTexture(GL_TEXTURE0);
2995     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2996     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2997     EXPECT_GL_NO_ERROR();
2998
2999     drawQuad(mProgram, "position", 0.5f);
3000
3001     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3002 }
3003
3004 // Validate that every component of the pixel will be equal to the luminance value we've set
3005 // and that the alpha channel will be 1 (or 255 to be exact).
3006 TEST_P(Texture2DTest, TextureLuminanceRGBSame)
3007 {
3008     setUpProgram();
3009
3010     glActiveTexture(GL_TEXTURE0);
3011     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3012     uint8_t pixel = 50;
3013     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
3014     EXPECT_GL_NO_ERROR();
3015
3016     drawQuad(mProgram, "position", 0.5f);
3017
3018     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
3019 }
3020
3021 // Validate that every component of the pixel will be equal to the luminance value we've set
3022 // and that the alpha channel will be the second component.
3023 TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
3024 {
3025     setUpProgram();
3026
3027     glActiveTexture(GL_TEXTURE0);
3028     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3029     uint8_t pixel[] = {50, 25};
3030     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
3031                  GL_UNSIGNED_BYTE, pixel);
3032     EXPECT_GL_NO_ERROR();
3033
3034     drawQuad(mProgram, "position", 0.5f);
3035
3036     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
3037 }
3038
3039 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3040 // ES 3.0.4 table 3.24
3041 TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
3042 {
3043     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
3044     ANGLE_SKIP_TEST_IF(IsD3D9());
3045     ANGLE_SKIP_TEST_IF(IsVulkan());
3046
3047     setUpProgram();
3048
3049     glActiveTexture(GL_TEXTURE0);
3050     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3051     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
3052     EXPECT_GL_NO_ERROR();
3053
3054     drawQuad(mProgram, "position", 0.5f);
3055
3056     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3057 }
3058
3059 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3060 // ES 3.0.4 table 3.24
3061 TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
3062 {
3063     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
3064     ANGLE_SKIP_TEST_IF(IsD3D9());
3065     ANGLE_SKIP_TEST_IF(IsVulkan());
3066     // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
3067     ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
3068
3069     setUpProgram();
3070
3071     glActiveTexture(GL_TEXTURE0);
3072     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3073     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
3074     EXPECT_GL_NO_ERROR();
3075
3076     drawQuad(mProgram, "position", 0.5f);
3077
3078     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3079 }
3080
3081 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3082 // ES 3.0.4 table 3.24
3083 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
3084 {
3085     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3086
3087     glActiveTexture(GL_TEXTURE0);
3088     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3089     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
3090     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3091     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3092     EXPECT_GL_NO_ERROR();
3093
3094     drawQuad(mProgram, "position", 0.5f);
3095
3096     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3097 }
3098
3099 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3100 // ES 3.0.4 table 3.24
3101 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
3102 {
3103     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3104
3105     glActiveTexture(GL_TEXTURE0);
3106     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3107
3108     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
3109     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3110     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3111     EXPECT_GL_NO_ERROR();
3112
3113     drawQuad(mProgram, "position", 0.5f);
3114
3115     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3116 }
3117
3118 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3119 // ES 3.0.4 table 3.24
3120 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
3121 {
3122     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3123
3124     glActiveTexture(GL_TEXTURE0);
3125     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3126     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
3127     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3128     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3129     EXPECT_GL_NO_ERROR();
3130
3131     drawQuad(mProgram, "position", 0.5f);
3132
3133     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3134 }
3135
3136 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3137 // ES 3.0.4 table 3.24
3138 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
3139 {
3140     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3141
3142     glActiveTexture(GL_TEXTURE0);
3143     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3144     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
3145     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3146     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3147     EXPECT_GL_NO_ERROR();
3148
3149     drawQuad(mProgram, "position", 0.5f);
3150
3151     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3152 }
3153
3154 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3155 // ES 3.0.4 table 3.24
3156 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
3157 {
3158     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3159
3160     glActiveTexture(GL_TEXTURE0);
3161     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3162     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
3163     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3164     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3165     EXPECT_GL_NO_ERROR();
3166
3167     drawQuad(mProgram, "position", 0.5f);
3168
3169     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3170 }
3171
3172 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3173 // ES 3.0.4 table 3.24
3174 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
3175 {
3176     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3177
3178     glActiveTexture(GL_TEXTURE0);
3179     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3180     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
3181     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3182     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3183     EXPECT_GL_NO_ERROR();
3184
3185     drawQuad(mProgram, "position", 0.5f);
3186
3187     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3188 }
3189
3190 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3191 // ES 3.0.4 table 3.24
3192 TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
3193 {
3194     glActiveTexture(GL_TEXTURE0);
3195     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3196     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
3197     EXPECT_GL_NO_ERROR();
3198
3199     drawQuad(mProgram, "position", 0.5f);
3200
3201     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3202 }
3203
3204 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3205 // ES 3.0.4 table 3.24
3206 TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
3207 {
3208     glActiveTexture(GL_TEXTURE0);
3209     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3210     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
3211                  nullptr);
3212     EXPECT_GL_NO_ERROR();
3213
3214     drawQuad(mProgram, "position", 0.5f);
3215
3216     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3217 }
3218
3219 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3220 // ES 3.0.4 table 3.24
3221 TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
3222 {
3223     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3224     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
3225
3226     glActiveTexture(GL_TEXTURE0);
3227     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3228     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
3229     EXPECT_GL_NO_ERROR();
3230
3231     drawQuad(mProgram, "position", 0.5f);
3232
3233     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3234 }
3235
3236 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3237 // ES 3.0.4 table 3.24
3238 TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
3239 {
3240     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3241     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
3242
3243     glActiveTexture(GL_TEXTURE0);
3244     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3245     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
3246     EXPECT_GL_NO_ERROR();
3247
3248     drawQuad(mProgram, "position", 0.5f);
3249
3250     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3251 }
3252
3253 // Use a sampler in a uniform struct.
3254 TEST_P(SamplerInStructTest, SamplerInStruct)
3255 {
3256     runSamplerInStructTest();
3257 }
3258
3259 // Use a sampler in a uniform struct that's passed as a function parameter.
3260 TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
3261 {
3262     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3263     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
3264
3265     runSamplerInStructTest();
3266 }
3267
3268 // Use a sampler in a uniform struct array with a struct from the array passed as a function
3269 // parameter.
3270 TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
3271 {
3272     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3273     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
3274
3275     runSamplerInStructTest();
3276 }
3277
3278 // Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
3279 // parameter.
3280 TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
3281 {
3282     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3283     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
3284
3285     runSamplerInStructTest();
3286 }
3287
3288 // Make sure that there isn't a name conflict between sampler extracted from a struct and a
3289 // similarly named uniform.
3290 TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
3291 {
3292     runSamplerInStructTest();
3293 }
3294
3295 // GL_EXT_texture_filter_anisotropic
3296 class TextureAnisotropyTest : public Texture2DTest
3297 {
3298   protected:
3299     void uploadTexture()
3300     {
3301         glActiveTexture(GL_TEXTURE0);
3302         glBindTexture(GL_TEXTURE_2D, mTexture2D);
3303         GLColor texDataRed[1] = {GLColor::red};
3304         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
3305         EXPECT_GL_NO_ERROR();
3306     }
3307 };
3308
3309 // Tests that setting anisotropic filtering doesn't cause failures at draw time.
3310 TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
3311 {
3312     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
3313
3314     setUpProgram();
3315
3316     uploadTexture();
3317
3318     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3319     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3320     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
3321     EXPECT_GL_NO_ERROR();
3322
3323     drawQuad(mProgram, "position", 0.5f);
3324
3325     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3326     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3327     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
3328 }
3329
3330 // GL_OES_texture_border_clamp
3331 class TextureBorderClampTest : public Texture2DTest
3332 {
3333   protected:
3334     TextureBorderClampTest() : Texture2DTest() {}
3335
3336     const char *getVertexShaderSource() override
3337     {
3338         return
3339             R"(precision highp float;
3340             attribute vec4 position;
3341             varying vec2 texcoord;
3342
3343             void main()
3344             {
3345                 gl_Position = vec4(position.xy, 0.0, 1.0);
3346                 // texcoords in [-0.5, 1.5]
3347                 texcoord = (position.xy) + 0.5;
3348             })";
3349     }
3350
3351     void uploadTexture()
3352     {
3353         glActiveTexture(GL_TEXTURE0);
3354         glBindTexture(GL_TEXTURE_2D, mTexture2D);
3355         std::vector<GLColor> texDataRed(1, GLColor::red);
3356         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3357                      texDataRed.data());
3358         EXPECT_GL_NO_ERROR();
3359     }
3360 };
3361
3362 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3363 // GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
3364 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
3365 {
3366     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3367
3368     setUpProgram();
3369
3370     uploadTexture();
3371
3372     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3373     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3374     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3375     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3376     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3377     EXPECT_GL_NO_ERROR();
3378
3379     drawQuad(mProgram, "position", 0.5f);
3380
3381     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3382     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3383     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3384 }
3385
3386 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
3387 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
3388 {
3389     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3390
3391     glActiveTexture(GL_TEXTURE0);
3392     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3393
3394     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3395
3396     GLint colorFixedPoint[4] = {0};
3397     glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3398     constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3399                                                std::numeric_limits<GLint>::max()};
3400     EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3401     EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3402     EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3403     EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3404
3405     constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3406                                               std::numeric_limits<GLint>::max()};
3407     glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3408
3409     GLfloat color[4] = {0.0f};
3410     glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
3411     EXPECT_EQ(color[0], kFloatBlue.R);
3412     EXPECT_EQ(color[1], kFloatBlue.G);
3413     EXPECT_EQ(color[2], kFloatBlue.B);
3414     EXPECT_EQ(color[3], kFloatBlue.A);
3415 }
3416
3417 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
3418 TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
3419 {
3420     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3421
3422     glActiveTexture(GL_TEXTURE0);
3423     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3424
3425     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
3426     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3427
3428     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3429     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3430
3431     glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3432     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3433
3434     GLint colorInt[4] = {0};
3435     glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
3436     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3437
3438     if (getClientMajorVersion() < 3)
3439     {
3440         glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3441         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3442         glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3443         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3444
3445         GLuint colorUInt[4] = {0};
3446         glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3447         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3448         glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3449         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3450
3451         GLSampler sampler;
3452         glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3453         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3454         glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3455         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3456
3457         glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3458         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3459         glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3460         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3461     }
3462 }
3463
3464 class TextureBorderClampTestES3 : public TextureBorderClampTest
3465 {
3466   protected:
3467     TextureBorderClampTestES3() : TextureBorderClampTest() {}
3468 };
3469
3470 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3471 // GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
3472 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
3473 {
3474     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3475
3476     setUpProgram();
3477
3478     uploadTexture();
3479
3480     GLSampler sampler;
3481     glBindSampler(0, sampler);
3482     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3483     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3484     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3485     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3486     glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3487     EXPECT_GL_NO_ERROR();
3488
3489     drawQuad(mProgram, "position", 0.5f);
3490
3491     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3492     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3493     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3494 }
3495
3496 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
3497 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
3498 {
3499     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3500
3501     glActiveTexture(GL_TEXTURE0);
3502
3503     GLSampler sampler;
3504     glBindSampler(0, sampler);
3505
3506     glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3507
3508     GLint colorFixedPoint[4] = {0};
3509     glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3510     constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3511                                                std::numeric_limits<GLint>::max()};
3512     EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3513     EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3514     EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3515     EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3516
3517     constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3518                                               std::numeric_limits<GLint>::max()};
3519     glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3520
3521     GLfloat color[4] = {0.0f};
3522     glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
3523     EXPECT_EQ(color[0], kFloatBlue.R);
3524     EXPECT_EQ(color[1], kFloatBlue.G);
3525     EXPECT_EQ(color[2], kFloatBlue.B);
3526     EXPECT_EQ(color[3], kFloatBlue.A);
3527
3528     constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
3529     glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
3530     GLint colorInt[4] = {0};
3531     glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3532     EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
3533     EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
3534     EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
3535     EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
3536
3537     constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
3538     glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
3539     GLuint colorUInt[4] = {0};
3540     glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3541     EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
3542     EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
3543     EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
3544     EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
3545
3546     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3547
3548     constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
3549     glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
3550     glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3551     EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
3552     EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
3553     EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
3554     EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
3555
3556     constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
3557     glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
3558     glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3559     EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
3560     EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
3561     EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
3562     EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
3563 }
3564
3565 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
3566 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
3567 {
3568     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3569
3570     glActiveTexture(GL_TEXTURE0);
3571
3572     GLSampler sampler;
3573     glBindSampler(0, sampler);
3574
3575     glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
3576     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3577
3578     glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3579     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3580 }
3581
3582 class TextureBorderClampIntegerTestES3 : public Texture2DTest
3583 {
3584   protected:
3585     TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
3586
3587     const char *getVertexShaderSource() override
3588     {
3589         return
3590             R"(#version 300 es
3591             out vec2 texcoord;
3592             in vec4 position;
3593
3594             void main()
3595             {
3596                 gl_Position = vec4(position.xy, 0.0, 1.0);
3597                 // texcoords in [-0.5, 1.5]
3598                 texcoord = (position.xy) + 0.5;
3599             })";
3600     }
3601
3602     const char *getFragmentShaderSource() override
3603     {
3604         if (isUnsignedIntTest)
3605         {
3606             return "#version 300 es\n"
3607                    "precision highp float;\n"
3608                    "uniform highp usampler2D tex;\n"
3609                    "in vec2 texcoord;\n"
3610                    "out vec4 fragColor;\n"
3611
3612                    "void main()\n"
3613                    "{\n"
3614                    "vec4 red   = vec4(1.0, 0.0, 0.0, 1.0);\n"
3615                    "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3616                    "fragColor = (texture(tex, texcoord).r == 150u)"
3617                    "            ? green : red;\n"
3618                    "}\n";
3619         }
3620         else
3621         {
3622             return "#version 300 es\n"
3623                    "precision highp float;\n"
3624                    "uniform highp isampler2D tex;\n"
3625                    "in vec2 texcoord;\n"
3626                    "out vec4 fragColor;\n"
3627
3628                    "void main()\n"
3629                    "{\n"
3630                    "vec4 red   = vec4(1.0, 0.0, 0.0, 1.0);\n"
3631                    "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3632                    "fragColor = (texture(tex, texcoord).r == -50)"
3633                    "            ? green : red;\n"
3634                    "}\n";
3635         }
3636     }
3637
3638     void uploadTexture()
3639     {
3640         glActiveTexture(GL_TEXTURE0);
3641         glBindTexture(GL_TEXTURE_2D, mTexture2D);
3642         if (isUnsignedIntTest)
3643         {
3644             std::vector<GLubyte> texData(4, 100);
3645             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
3646                          texData.data());
3647         }
3648         else
3649         {
3650             std::vector<GLbyte> texData(4, 100);
3651             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
3652                          texData.data());
3653         }
3654         EXPECT_GL_NO_ERROR();
3655     }
3656
3657     bool isUnsignedIntTest;
3658 };
3659
3660 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3661 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3662 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
3663 {
3664     // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3665     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3666
3667     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3668
3669     setUpProgram();
3670
3671     uploadTexture();
3672
3673     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3674     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3675     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3676     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3677
3678     constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3679     glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3680
3681     EXPECT_GL_NO_ERROR();
3682
3683     drawQuad(mProgram, "position", 0.5f);
3684
3685     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3686     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3687     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3688 }
3689
3690 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3691 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3692 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
3693 {
3694     // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3695     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3696
3697     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3698
3699     setUpProgram();
3700
3701     uploadTexture();
3702
3703     GLSampler sampler;
3704     glBindSampler(0, sampler);
3705     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3706     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3707     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3708     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3709
3710     constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3711     glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3712
3713     EXPECT_GL_NO_ERROR();
3714
3715     drawQuad(mProgram, "position", 0.5f);
3716
3717     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3718     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3719     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3720 }
3721
3722 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3723 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
3724 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
3725 {
3726     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3727
3728     isUnsignedIntTest = true;
3729
3730     setUpProgram();
3731
3732     uploadTexture();
3733
3734     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3735     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3736     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3737     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3738
3739     constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3740     glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3741
3742     EXPECT_GL_NO_ERROR();
3743
3744     drawQuad(mProgram, "position", 0.5f);
3745
3746     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3747     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3748     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3749 }
3750
3751 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3752 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
3753 // glSamplerParameterIuivOES).
3754 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
3755 {
3756     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
3757
3758     isUnsignedIntTest = true;
3759
3760     setUpProgram();
3761
3762     uploadTexture();
3763
3764     GLSampler sampler;
3765     glBindSampler(0, sampler);
3766     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3767     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3768     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3769     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3770
3771     constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3772     glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3773
3774     EXPECT_GL_NO_ERROR();
3775
3776     drawQuad(mProgram, "position", 0.5f);
3777
3778     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3779     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3780     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3781 }
3782
3783 // ~GL_OES_texture_border_clamp
3784
3785 class TextureLimitsTest : public