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