1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "common/mathutil.h"
8 #include "test_utils/ANGLETest.h"
9 #include "test_utils/gl_raii.h"
10 
11 using namespace angle;
12 
13 namespace
14 {
15 
16 constexpr GLuint kPixelTolerance     = 1u;
17 constexpr GLfloat kPixelTolerance32F = 0.01f;
18 
19 // Single compressed ETC2 block of source pixels all set red
20 constexpr uint8_t kCompressedImageETC2[] = {0x7E, 0x80, 0x04, 0x7F, 0x00, 0x07, 0xE0, 0x00};
21 
22 // Take a pixel, and reset the components not covered by the format to default
23 // values. In particular, the default value for the alpha component is 255
24 // (1.0 as unsigned normalized fixed point value).
25 // For legacy formats, the components may be reordered to match the color that
26 // would be created if a pixel of that format was initialized from the given color
SliceFormatColor(GLenum format,GLColor full)27 GLColor SliceFormatColor(GLenum format, GLColor full)
28 {
29     switch (format)
30     {
31         case GL_RED:
32             return GLColor(full.R, 0, 0, 255u);
33         case GL_RG:
34             return GLColor(full.R, full.G, 0, 255u);
35         case GL_RGB:
36             return GLColor(full.R, full.G, full.B, 255u);
37         case GL_RGBA:
38             return full;
39         case GL_LUMINANCE:
40             return GLColor(full.R, full.R, full.R, 255u);
41         case GL_ALPHA:
42             return GLColor(0, 0, 0, full.R);
43         case GL_LUMINANCE_ALPHA:
44             return GLColor(full.R, full.R, full.R, full.G);
45         default:
46             EXPECT_TRUE(false);
47             return GLColor::white;
48     }
49 }
50 
SliceFormatColor16UI(GLenum format,GLColor16UI full)51 GLColor16UI SliceFormatColor16UI(GLenum format, GLColor16UI full)
52 {
53     switch (format)
54     {
55         case GL_RED:
56             return GLColor16UI(full.R, 0, 0, 0xFFFF);
57         case GL_RG:
58             return GLColor16UI(full.R, full.G, 0, 0xFFFF);
59         case GL_RGB:
60             return GLColor16UI(full.R, full.G, full.B, 0xFFFF);
61         case GL_RGBA:
62             return full;
63         case GL_LUMINANCE:
64             return GLColor16UI(full.R, full.R, full.R, 0xFFFF);
65         case GL_ALPHA:
66             return GLColor16UI(0, 0, 0, full.R);
67         case GL_LUMINANCE_ALPHA:
68             return GLColor16UI(full.R, full.R, full.R, full.G);
69         default:
70             EXPECT_TRUE(false);
71             return GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
72     }
73 }
74 
75 // As above, for 32F colors
SliceFormatColor32F(GLenum format,GLColor32F full)76 GLColor32F SliceFormatColor32F(GLenum format, GLColor32F full)
77 {
78     switch (format)
79     {
80         case GL_RED:
81             return GLColor32F(full.R, 0.0f, 0.0f, 1.0f);
82         case GL_RG:
83             return GLColor32F(full.R, full.G, 0.0f, 1.0f);
84         case GL_RGB:
85             return GLColor32F(full.R, full.G, full.B, 1.0f);
86         case GL_RGBA:
87             return full;
88         case GL_LUMINANCE:
89             return GLColor32F(full.R, full.R, full.R, 1.0f);
90         case GL_ALPHA:
91             return GLColor32F(0.0f, 0.0f, 0.0f, full.R);
92         case GL_LUMINANCE_ALPHA:
93             return GLColor32F(full.R, full.R, full.R, full.G);
94         default:
95             EXPECT_TRUE(false);
96             return GLColor32F(1.0f, 1.0f, 1.0f, 1.0f);
97     }
98 }
99 
100 class TexCoordDrawTest : public ANGLETest
101 {
102   protected:
TexCoordDrawTest()103     TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
104     {
105         setWindowWidth(128);
106         setWindowHeight(128);
107         setConfigRedBits(8);
108         setConfigGreenBits(8);
109         setConfigBlueBits(8);
110         setConfigAlphaBits(8);
111     }
112 
getVertexShaderSource()113     virtual const char *getVertexShaderSource()
114     {
115         return R"(precision highp float;
116 attribute vec4 position;
117 varying vec2 texcoord;
118 
119 void main()
120 {
121     gl_Position = vec4(position.xy, 0.0, 1.0);
122     texcoord = (position.xy * 0.5) + 0.5;
123 })";
124     }
125 
126     virtual const char *getFragmentShaderSource() = 0;
127 
setUpProgram()128     virtual void setUpProgram()
129     {
130         const char *vertexShaderSource   = getVertexShaderSource();
131         const char *fragmentShaderSource = getFragmentShaderSource();
132 
133         mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
134         ASSERT_NE(0u, mProgram);
135         ASSERT_GL_NO_ERROR();
136     }
137 
testSetUp()138     void testSetUp() override { setUpFramebuffer(); }
139 
testTearDown()140     void testTearDown() override
141     {
142         glBindFramebuffer(GL_FRAMEBUFFER, 0);
143         glDeleteFramebuffers(1, &mFramebuffer);
144         glDeleteTextures(1, &mFramebufferColorTexture);
145         glDeleteProgram(mProgram);
146     }
147 
setUpFramebuffer()148     void setUpFramebuffer()
149     {
150         // We use an FBO to work around an issue where the default framebuffer applies SRGB
151         // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
152         // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
153         // section 4.4 says that the format of the default framebuffer is entirely up to the window
154         // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
155         // SRGB conversion like desktop GL does.
156         // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
157         glGenFramebuffers(1, &mFramebuffer);
158         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
159 
160         glGenTextures(1, &mFramebufferColorTexture);
161         glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
162         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
163                      GL_UNSIGNED_BYTE, nullptr);
164         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
165                                mFramebufferColorTexture, 0);
166         ASSERT_GL_NO_ERROR();
167         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
168         glBindTexture(GL_TEXTURE_2D, 0);
169     }
170 
171     // Returns the created texture ID.
create2DTexture()172     GLuint create2DTexture()
173     {
174         GLuint texture2D;
175         glGenTextures(1, &texture2D);
176         glBindTexture(GL_TEXTURE_2D, texture2D);
177         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
178         EXPECT_GL_NO_ERROR();
179         return texture2D;
180     }
181 
182     GLuint mProgram;
183     GLuint mFramebuffer;
184 
185   private:
186     GLuint mFramebufferColorTexture;
187 };
188 
189 class Texture2DTest : public TexCoordDrawTest
190 {
191   protected:
Texture2DTest()192     Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
193 
getFragmentShaderSource()194     const char *getFragmentShaderSource() override
195     {
196         return R"(precision highp float;
197 uniform sampler2D tex;
198 varying vec2 texcoord;
199 
200 void main()
201 {
202     gl_FragColor = texture2D(tex, texcoord);
203 })";
204     }
205 
getTextureUniformName()206     virtual const char *getTextureUniformName() { return "tex"; }
207 
setUpProgram()208     void setUpProgram() override
209     {
210         TexCoordDrawTest::setUpProgram();
211         mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
212         ASSERT_NE(-1, mTexture2DUniformLocation);
213     }
214 
testSetUp()215     void testSetUp() override
216     {
217         TexCoordDrawTest::testSetUp();
218         mTexture2D = create2DTexture();
219 
220         ASSERT_GL_NO_ERROR();
221     }
222 
testTearDown()223     void testTearDown() override
224     {
225         glDeleteTextures(1, &mTexture2D);
226         TexCoordDrawTest::testTearDown();
227     }
228 
229     // Tests CopyTexSubImage with floating point textures of various formats.
testFloatCopySubImage(int sourceImageChannels,int destImageChannels)230     void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
231     {
232         setUpProgram();
233 
234         if (getClientMajorVersion() < 3)
235         {
236             ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
237                                !IsGLExtensionEnabled("GL_OES_texture_float"));
238 
239             ANGLE_SKIP_TEST_IF((sourceImageChannels < 3 || destImageChannels < 3) &&
240                                !IsGLExtensionEnabled("GL_EXT_texture_rg"));
241 
242             ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
243                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
244 
245             ANGLE_SKIP_TEST_IF(destImageChannels == 4 &&
246                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"));
247 
248             ANGLE_SKIP_TEST_IF(destImageChannels <= 2);
249         }
250         else
251         {
252             ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_color_buffer_float"));
253 
254             ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
255                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
256         }
257 
258         // clang-format off
259         GLfloat sourceImageData[4][16] =
260         {
261             { // R
262                 1.0f,
263                 0.0f,
264                 0.0f,
265                 1.0f
266             },
267             { // RG
268                 1.0f, 0.0f,
269                 0.0f, 1.0f,
270                 0.0f, 0.0f,
271                 1.0f, 1.0f
272             },
273             { // RGB
274                 1.0f, 0.0f, 0.0f,
275                 0.0f, 1.0f, 0.0f,
276                 0.0f, 0.0f, 1.0f,
277                 1.0f, 1.0f, 0.0f
278             },
279             { // RGBA
280                 1.0f, 0.0f, 0.0f, 1.0f,
281                 0.0f, 1.0f, 0.0f, 1.0f,
282                 0.0f, 0.0f, 1.0f, 1.0f,
283                 1.0f, 1.0f, 0.0f, 1.0f
284             },
285         };
286         // clang-format on
287 
288         GLenum imageFormats[] = {
289             GL_R32F,
290             GL_RG32F,
291             GL_RGB32F,
292             GL_RGBA32F,
293         };
294 
295         GLenum sourceUnsizedFormats[] = {
296             GL_RED,
297             GL_RG,
298             GL_RGB,
299             GL_RGBA,
300         };
301 
302         GLuint textures[2];
303 
304         glGenTextures(2, textures);
305 
306         GLfloat *imageData         = sourceImageData[sourceImageChannels - 1];
307         GLenum sourceImageFormat   = imageFormats[sourceImageChannels - 1];
308         GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
309         GLenum destImageFormat     = imageFormats[destImageChannels - 1];
310 
311         glBindTexture(GL_TEXTURE_2D, textures[0]);
312         if (getClientMajorVersion() >= 3)
313         {
314             glTexStorage2D(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
315         }
316         else
317         {
318             glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
319         }
320         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
321         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
322         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
323 
324         if (sourceImageChannels < 3 && !IsGLExtensionEnabled("GL_EXT_texture_rg"))
325         {
326             // This is not supported
327             ASSERT_GL_ERROR(GL_INVALID_OPERATION);
328         }
329         else
330         {
331             ASSERT_GL_NO_ERROR();
332         }
333 
334         GLuint fbo;
335         glGenFramebuffers(1, &fbo);
336         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
337         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
338 
339         glBindTexture(GL_TEXTURE_2D, textures[1]);
340         if (getClientMajorVersion() >= 3)
341         {
342             glTexStorage2D(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
343         }
344         else
345         {
346             glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
347         }
348         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350 
351         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
352         ASSERT_GL_NO_ERROR();
353 
354         glBindFramebuffer(GL_FRAMEBUFFER, 0);
355         drawQuad(mProgram, "position", 0.5f);
356 
357         int testImageChannels = std::min(sourceImageChannels, destImageChannels);
358 
359         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
360         if (testImageChannels > 1)
361         {
362             EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
363             EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
364             if (testImageChannels > 2)
365             {
366                 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
367             }
368         }
369 
370         glDeleteFramebuffers(1, &fbo);
371         glDeleteTextures(2, textures);
372 
373         ASSERT_GL_NO_ERROR();
374     }
375 
376     GLuint mTexture2D;
377     GLint mTexture2DUniformLocation;
378 };
379 
380 class Texture2DTestES3 : public Texture2DTest
381 {
382   protected:
Texture2DTestES3()383     Texture2DTestES3() : Texture2DTest() {}
384 
getVertexShaderSource()385     const char *getVertexShaderSource() override
386     {
387         return "#version 300 es\n"
388                "out vec2 texcoord;\n"
389                "in vec4 position;\n"
390                "void main()\n"
391                "{\n"
392                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
393                "    texcoord = (position.xy * 0.5) + 0.5;\n"
394                "}\n";
395     }
396 
getFragmentShaderSource()397     const char *getFragmentShaderSource() override
398     {
399         return "#version 300 es\n"
400                "precision highp float;\n"
401                "uniform highp sampler2D tex;\n"
402                "in vec2 texcoord;\n"
403                "out vec4 fragColor;\n"
404                "void main()\n"
405                "{\n"
406                "    fragColor = texture(tex, texcoord);\n"
407                "}\n";
408     }
409 
testSetUp()410     void testSetUp() override
411     {
412         Texture2DTest::testSetUp();
413         setUpProgram();
414     }
415 };
416 
417 class Texture2DBaseMaxTestES3 : public ANGLETest
418 {
419   protected:
420     static constexpr size_t kMip0Size   = 13;
421     static constexpr uint32_t kMipCount = 4;
422 
Texture2DBaseMaxTestES3()423     Texture2DBaseMaxTestES3() : ANGLETest(), mTextureLocation(0), mLodLocation(0)
424     {
425         setWindowWidth(128);
426         setWindowHeight(128);
427         setConfigRedBits(8);
428         setConfigGreenBits(8);
429         setConfigBlueBits(8);
430         setConfigAlphaBits(8);
431     }
432 
getMipDataSize(size_t mip0Size,size_t mip)433     static constexpr size_t getMipDataSize(size_t mip0Size, size_t mip)
434     {
435         size_t mipSize = std::max<size_t>(1u, mip0Size >> mip);
436         return mipSize * mipSize;
437     }
438 
getTotalMipDataSize(size_t mip0Size)439     static constexpr size_t getTotalMipDataSize(size_t mip0Size)
440     {
441         size_t totalCount = 0;
442         for (size_t mip = 0; mip < kMipCount; ++mip)
443         {
444             totalCount += getMipDataSize(mip0Size, mip);
445         }
446         return totalCount;
447     }
448 
getMipDataOffset(size_t mip0Size,size_t mip)449     static constexpr size_t getMipDataOffset(size_t mip0Size, size_t mip)
450     {
451         // This calculates:
452         //
453         //     mip == 0: 0
454         //     o.w.:     sum(0, mip-1) getMipDataSize(i)
455         //
456         // The above can be calculated simply as:
457         //
458         //     (mip0 >> (kMipCount-1))^2 * (0x55555555 & ((1 << (2*mip)) - 1))
459         //     \__________  ___________/   \_______________  ________________/
460         //                \/                               \/
461         //          last mip size                 sum(0, mip-1) (4^i)
462         //
463         // But let's loop explicitly for clarity.
464         size_t offset = 0;
465         for (size_t m = 0; m < mip; ++m)
466         {
467             offset += getMipDataSize(mip0Size, m);
468         }
469         return offset;
470     }
471 
472     template <typename colorType = GLColor>
fillMipData(colorType * data,size_t mip0Size,const colorType mipColors[kMipCount])473     void fillMipData(colorType *data, size_t mip0Size, const colorType mipColors[kMipCount])
474     {
475         for (size_t mip = 0; mip < kMipCount; ++mip)
476         {
477             size_t offset = getMipDataOffset(mip0Size, mip);
478             size_t size   = getMipDataSize(mip0Size, mip);
479             std::fill(data + offset, data + offset + size, mipColors[mip]);
480         }
481     }
482 
initTest()483     void initTest()
484     {
485         // Set up program to sample from specific lod level.
486         mProgram.makeRaster(essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
487         ASSERT(mProgram.valid());
488 
489         glUseProgram(mProgram);
490 
491         mTextureLocation = glGetUniformLocation(mProgram, essl3_shaders::Texture2DUniform());
492         ASSERT_NE(-1, mTextureLocation);
493 
494         mLodLocation = glGetUniformLocation(mProgram, essl3_shaders::LodUniform());
495         ASSERT_NE(-1, mLodLocation);
496 
497         // Set up texture with a handful of lods.
498         glActiveTexture(GL_TEXTURE0);
499         glBindTexture(GL_TEXTURE_2D, mTexture);
500 
501         std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
502         fillMipData(mipData.data(), kMip0Size, kMipColors);
503 
504         for (size_t mip = 0; mip < kMipCount; ++mip)
505         {
506             glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0,
507                          GL_RGBA, GL_UNSIGNED_BYTE,
508                          mipData.data() + getMipDataOffset(kMip0Size, mip));
509         }
510 
511         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
512         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
513 
514         EXPECT_GL_NO_ERROR();
515     }
516 
setLodUniform(uint32_t lod)517     void setLodUniform(uint32_t lod) { glUniform1f(mLodLocation, lod); }
518 
519     GLProgram mProgram;
520     GLTexture mTexture;
521     GLint mTextureLocation;
522     GLint mLodLocation;
523 
524     const GLColor kMipColors[kMipCount] = {
525         GLColor::red,
526         GLColor::green,
527         GLColor::blue,
528         GLColor::magenta,
529     };
530 };
531 
532 class TextureES31PPO
533 {
534   protected:
TextureES31PPO()535     TextureES31PPO() : mVertProg(0), mFragProg(0), mPipeline(0) {}
536 
get2DTexturedVertexShaderSource()537     const char *get2DTexturedVertexShaderSource()
538     {
539         return "#version 310 es\n"
540                "precision mediump float;\n"
541                "in vec2 position;\n"
542                "out vec2 texCoord;\n"
543                "void main()\n"
544                "{\n"
545                "    gl_Position = vec4(position, 0, 1);\n"
546                "    texCoord = position * 0.5 + vec2(0.5);\n"
547                "}";
548     }
549 
get2DTexturedFragmentShaderSource()550     const char *get2DTexturedFragmentShaderSource()
551     {
552         return "#version 310 es\n"
553                "precision mediump float;\n"
554                "in vec2 texCoord;\n"
555                "uniform sampler2D tex1;\n"
556                "uniform sampler2D tex2;\n"
557                "uniform sampler2D tex3;\n"
558                "uniform sampler2D tex4;\n"
559                "out vec4 color;\n"
560                "void main()\n"
561                "{\n"
562                "    color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
563                "          +  texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
564                "}";
565     }
566 
bindProgramPipeline(const GLchar * vertString,const GLchar * fragString)567     void bindProgramPipeline(const GLchar *vertString, const GLchar *fragString)
568     {
569         mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
570         ASSERT_NE(mVertProg, 0u);
571         mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
572         ASSERT_NE(mFragProg, 0u);
573 
574         // Generate a program pipeline and attach the programs to their respective stages
575         glGenProgramPipelines(1, &mPipeline);
576         EXPECT_GL_NO_ERROR();
577         glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
578         EXPECT_GL_NO_ERROR();
579         glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
580         EXPECT_GL_NO_ERROR();
581         glBindProgramPipeline(mPipeline);
582         EXPECT_GL_NO_ERROR();
583     }
584 
bind2DTexturedQuadProgramPipeline()585     void bind2DTexturedQuadProgramPipeline()
586     {
587         const char *vertexShaderSource   = get2DTexturedVertexShaderSource();
588         const char *fragmentShaderSource = get2DTexturedFragmentShaderSource();
589 
590         m2DTexturedQuadVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertexShaderSource);
591         ASSERT_NE(m2DTexturedQuadVertProg, 0u);
592         m2DTexturedQuadFragProg =
593             glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentShaderSource);
594         ASSERT_NE(m2DTexturedQuadFragProg, 0u);
595 
596         // Generate a program pipeline and attach the programs to their respective stages
597         glGenProgramPipelines(1, &m2DTexturedQuadPipeline);
598         EXPECT_GL_NO_ERROR();
599         glUseProgramStages(m2DTexturedQuadPipeline, GL_VERTEX_SHADER_BIT, m2DTexturedQuadVertProg);
600         EXPECT_GL_NO_ERROR();
601         glUseProgramStages(m2DTexturedQuadPipeline, GL_FRAGMENT_SHADER_BIT,
602                            m2DTexturedQuadFragProg);
603         EXPECT_GL_NO_ERROR();
604         glBindProgramPipeline(m2DTexturedQuadPipeline);
605         EXPECT_GL_NO_ERROR();
606     }
607 
ppoDrawQuad(std::array<Vector3,6> & quadVertices,const std::string & positionAttribName,const GLfloat positionAttribZ,const GLfloat positionAttribXYScale)608     void ppoDrawQuad(std::array<Vector3, 6> &quadVertices,
609                      const std::string &positionAttribName,
610                      const GLfloat positionAttribZ,
611                      const GLfloat positionAttribXYScale)
612     {
613         glUseProgram(0);
614 
615         for (Vector3 &vertex : quadVertices)
616         {
617             vertex.x() *= positionAttribXYScale;
618             vertex.y() *= positionAttribXYScale;
619             vertex.z() = positionAttribZ;
620         }
621 
622         GLint positionLocation = glGetAttribLocation(mVertProg, positionAttribName.c_str());
623 
624         glBindBuffer(GL_ARRAY_BUFFER, 0);
625         glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
626         glEnableVertexAttribArray(positionLocation);
627 
628         glDrawArrays(GL_TRIANGLES, 0, 6);
629 
630         glDisableVertexAttribArray(positionLocation);
631         glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
632     }
633 
634     GLuint mVertProg;
635     GLuint mFragProg;
636     GLuint mPipeline;
637     GLuint m2DTexturedQuadVertProg;
638     GLuint m2DTexturedQuadFragProg;
639     GLuint m2DTexturedQuadPipeline;
640 };
641 
642 class Texture2DTestES31PPO : public TextureES31PPO, public Texture2DTest
643 {
644   protected:
Texture2DTestES31PPO()645     Texture2DTestES31PPO() : TextureES31PPO(), Texture2DTest() {}
646 
testSetUp()647     void testSetUp() override { Texture2DTest::testSetUp(); }
648 };
649 
650 class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
651 {
652   protected:
Texture2DIntegerAlpha1TestES3()653     Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
654 
getVertexShaderSource()655     const char *getVertexShaderSource() override
656     {
657         return "#version 300 es\n"
658                "out vec2 texcoord;\n"
659                "in vec4 position;\n"
660                "void main()\n"
661                "{\n"
662                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
663                "    texcoord = (position.xy * 0.5) + 0.5;\n"
664                "}\n";
665     }
666 
getFragmentShaderSource()667     const char *getFragmentShaderSource() override
668     {
669         return "#version 300 es\n"
670                "precision highp float;\n"
671                "uniform highp isampler2D tex;\n"
672                "in vec2 texcoord;\n"
673                "out vec4 fragColor;\n"
674                "void main()\n"
675                "{\n"
676                "    vec4 green = vec4(0, 1, 0, 1);\n"
677                "    vec4 black = vec4(0, 0, 0, 0);\n"
678                "    fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
679                "}\n";
680     }
681 
testSetUp()682     void testSetUp() override
683     {
684         Texture2DTest::testSetUp();
685         setUpProgram();
686     }
687 };
688 
689 class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
690 {
691   protected:
Texture2DUnsignedIntegerAlpha1TestES3()692     Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
693 
getVertexShaderSource()694     const char *getVertexShaderSource() override
695     {
696         return "#version 300 es\n"
697                "out vec2 texcoord;\n"
698                "in vec4 position;\n"
699                "void main()\n"
700                "{\n"
701                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
702                "    texcoord = (position.xy * 0.5) + 0.5;\n"
703                "}\n";
704     }
705 
getFragmentShaderSource()706     const char *getFragmentShaderSource() override
707     {
708         return "#version 300 es\n"
709                "precision highp float;\n"
710                "uniform highp usampler2D tex;\n"
711                "in vec2 texcoord;\n"
712                "out vec4 fragColor;\n"
713                "void main()\n"
714                "{\n"
715                "    vec4 green = vec4(0, 1, 0, 1);\n"
716                "    vec4 black = vec4(0, 0, 0, 0);\n"
717                "    fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
718                "}\n";
719     }
720 
testSetUp()721     void testSetUp() override
722     {
723         Texture2DTest::testSetUp();
724         setUpProgram();
725     }
726 };
727 
728 class Texture2DTestWithDrawScale : public Texture2DTest
729 {
730   protected:
Texture2DTestWithDrawScale()731     Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
732 
getVertexShaderSource()733     const char *getVertexShaderSource() override
734     {
735         return
736             R"(precision highp float;
737             attribute vec4 position;
738             varying vec2 texcoord;
739 
740             uniform vec2 drawScale;
741 
742             void main()
743             {
744                 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
745                 texcoord = (position.xy * 0.5) + 0.5;
746             })";
747     }
748 
testSetUp()749     void testSetUp() override
750     {
751         Texture2DTest::testSetUp();
752 
753         setUpProgram();
754 
755         mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
756         ASSERT_NE(-1, mDrawScaleUniformLocation);
757 
758         glUseProgram(mProgram);
759         glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
760         glUseProgram(0);
761         ASSERT_GL_NO_ERROR();
762     }
763 
764     GLint mDrawScaleUniformLocation;
765 };
766 
767 class Sampler2DAsFunctionParameterTest : public Texture2DTest
768 {
769   protected:
Sampler2DAsFunctionParameterTest()770     Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
771 
getFragmentShaderSource()772     const char *getFragmentShaderSource() override
773     {
774         return
775             R"(precision highp float;
776             uniform sampler2D tex;
777             varying vec2 texcoord;
778 
779             vec4 computeFragColor(sampler2D aTex)
780             {
781                 return texture2D(aTex, texcoord);
782             }
783 
784             void main()
785             {
786                 gl_FragColor = computeFragColor(tex);
787             })";
788     }
789 
testSetUp()790     void testSetUp() override
791     {
792         Texture2DTest::testSetUp();
793         setUpProgram();
794     }
795 };
796 
797 class TextureCubeTest : public TexCoordDrawTest
798 {
799   protected:
TextureCubeTest()800     TextureCubeTest()
801         : TexCoordDrawTest(),
802           mTexture2D(0),
803           mTextureCube(0),
804           mTexture2DUniformLocation(-1),
805           mTextureCubeUniformLocation(-1)
806     {}
807 
getFragmentShaderSource()808     const char *getFragmentShaderSource() override
809     {
810         return
811             R"(precision highp float;
812             uniform sampler2D tex2D;
813             uniform samplerCube texCube;
814             varying vec2 texcoord;
815 
816             void main()
817             {
818                 gl_FragColor = texture2D(tex2D, texcoord);
819                 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
820             })";
821     }
822 
testSetUp()823     void testSetUp() override
824     {
825         TexCoordDrawTest::testSetUp();
826 
827         glGenTextures(1, &mTextureCube);
828         glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
829         for (GLenum face = 0; face < 6; face++)
830         {
831             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
832                          GL_UNSIGNED_BYTE, nullptr);
833         }
834         EXPECT_GL_NO_ERROR();
835 
836         mTexture2D = create2DTexture();
837 
838         setUpProgram();
839 
840         mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
841         ASSERT_NE(-1, mTexture2DUniformLocation);
842         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
843         ASSERT_NE(-1, mTextureCubeUniformLocation);
844     }
845 
testTearDown()846     void testTearDown() override
847     {
848         glDeleteTextures(1, &mTextureCube);
849         TexCoordDrawTest::testTearDown();
850     }
851 
852     GLuint mTexture2D;
853     GLuint mTextureCube;
854     GLint mTexture2DUniformLocation;
855     GLint mTextureCubeUniformLocation;
856 };
857 
858 class TextureCubeTestES3 : public ANGLETest
859 {
860   protected:
TextureCubeTestES3()861     TextureCubeTestES3() {}
862 };
863 
864 class SamplerArrayTest : public TexCoordDrawTest
865 {
866   protected:
SamplerArrayTest()867     SamplerArrayTest()
868         : TexCoordDrawTest(),
869           mTexture2DA(0),
870           mTexture2DB(0),
871           mTexture0UniformLocation(-1),
872           mTexture1UniformLocation(-1)
873     {}
874 
getFragmentShaderSource()875     const char *getFragmentShaderSource() override
876     {
877         return
878             R"(precision mediump float;
879             uniform highp sampler2D tex2DArray[2];
880             varying vec2 texcoord;
881             void main()
882             {
883                 gl_FragColor = texture2D(tex2DArray[0], texcoord);
884                 gl_FragColor += texture2D(tex2DArray[1], texcoord);
885             })";
886     }
887 
testSetUp()888     void testSetUp() override
889     {
890         TexCoordDrawTest::testSetUp();
891 
892         setUpProgram();
893 
894         mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
895         ASSERT_NE(-1, mTexture0UniformLocation);
896         mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
897         ASSERT_NE(-1, mTexture1UniformLocation);
898 
899         mTexture2DA = create2DTexture();
900         mTexture2DB = create2DTexture();
901         ASSERT_GL_NO_ERROR();
902     }
903 
testTearDown()904     void testTearDown() override
905     {
906         glDeleteTextures(1, &mTexture2DA);
907         glDeleteTextures(1, &mTexture2DB);
908         TexCoordDrawTest::testTearDown();
909     }
910 
testSamplerArrayDraw()911     void testSamplerArrayDraw()
912     {
913         GLubyte texData[4];
914         texData[0] = 0;
915         texData[1] = 60;
916         texData[2] = 0;
917         texData[3] = 255;
918 
919         glActiveTexture(GL_TEXTURE0);
920         glBindTexture(GL_TEXTURE_2D, mTexture2DA);
921         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
922 
923         texData[1] = 120;
924         glActiveTexture(GL_TEXTURE1);
925         glBindTexture(GL_TEXTURE_2D, mTexture2DB);
926         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
927         EXPECT_GL_ERROR(GL_NO_ERROR);
928 
929         glUseProgram(mProgram);
930         glUniform1i(mTexture0UniformLocation, 0);
931         glUniform1i(mTexture1UniformLocation, 1);
932         drawQuad(mProgram, "position", 0.5f);
933         EXPECT_GL_NO_ERROR();
934 
935         EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
936     }
937 
938     GLuint mTexture2DA;
939     GLuint mTexture2DB;
940     GLint mTexture0UniformLocation;
941     GLint mTexture1UniformLocation;
942 };
943 
944 class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
945 {
946   protected:
SamplerArrayAsFunctionParameterTest()947     SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
948 
getFragmentShaderSource()949     const char *getFragmentShaderSource() override
950     {
951         return
952             R"(precision mediump float;
953             uniform highp sampler2D tex2DArray[2];
954             varying vec2 texcoord;
955 
956             vec4 computeFragColor(highp sampler2D aTex2DArray[2])
957             {
958                 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
959             }
960 
961             void main()
962             {
963                 gl_FragColor = computeFragColor(tex2DArray);
964             })";
965     }
966 };
967 
968 class Texture2DArrayTestES3 : public TexCoordDrawTest
969 {
970   protected:
Texture2DArrayTestES3()971     Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
972 
getVertexShaderSource()973     const char *getVertexShaderSource() override
974     {
975         return "#version 300 es\n"
976                "out vec2 texcoord;\n"
977                "in vec4 position;\n"
978                "void main()\n"
979                "{\n"
980                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
981                "    texcoord = (position.xy * 0.5) + 0.5;\n"
982                "}\n";
983     }
984 
getFragmentShaderSource()985     const char *getFragmentShaderSource() override
986     {
987         return "#version 300 es\n"
988                "precision highp float;\n"
989                "uniform highp sampler2DArray tex2DArray;\n"
990                "in vec2 texcoord;\n"
991                "out vec4 fragColor;\n"
992                "void main()\n"
993                "{\n"
994                "    fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
995                "}\n";
996     }
997 
testSetUp()998     void testSetUp() override
999     {
1000         TexCoordDrawTest::testSetUp();
1001 
1002         setUpProgram();
1003 
1004         mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
1005         ASSERT_NE(-1, mTextureArrayLocation);
1006 
1007         glGenTextures(1, &m2DArrayTexture);
1008         ASSERT_GL_NO_ERROR();
1009     }
1010 
testTearDown()1011     void testTearDown() override
1012     {
1013         glDeleteTextures(1, &m2DArrayTexture);
1014         TexCoordDrawTest::testTearDown();
1015     }
1016 
1017     GLuint m2DArrayTexture;
1018     GLint mTextureArrayLocation;
1019 };
1020 
1021 class TextureSizeTextureArrayTest : public TexCoordDrawTest
1022 {
1023   protected:
TextureSizeTextureArrayTest()1024     TextureSizeTextureArrayTest()
1025         : TexCoordDrawTest(),
1026           mTexture2DA(0),
1027           mTexture2DB(0),
1028           mTexture0Location(-1),
1029           mTexture1Location(-1)
1030     {}
1031 
getVertexShaderSource()1032     const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
1033 
getFragmentShaderSource()1034     const char *getFragmentShaderSource() override
1035     {
1036         return "#version 300 es\n"
1037                "precision highp float;\n"
1038                "uniform highp sampler2D tex2DArray[2];\n"
1039                "out vec4 fragColor;\n"
1040                "void main()\n"
1041                "{\n"
1042                "    float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
1043                "    float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
1044                "    fragColor = vec4(red, green, 0.0, 1.0);\n"
1045                "}\n";
1046     }
1047 
testSetUp()1048     void testSetUp() override
1049     {
1050         TexCoordDrawTest::testSetUp();
1051 
1052         setUpProgram();
1053 
1054         mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
1055         ASSERT_NE(-1, mTexture0Location);
1056         mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
1057         ASSERT_NE(-1, mTexture1Location);
1058 
1059         mTexture2DA = create2DTexture();
1060         mTexture2DB = create2DTexture();
1061         ASSERT_GL_NO_ERROR();
1062     }
1063 
testTearDown()1064     void testTearDown() override
1065     {
1066         glDeleteTextures(1, &mTexture2DA);
1067         glDeleteTextures(1, &mTexture2DB);
1068         TexCoordDrawTest::testTearDown();
1069     }
1070 
1071     GLuint mTexture2DA;
1072     GLuint mTexture2DB;
1073     GLint mTexture0Location;
1074     GLint mTexture1Location;
1075 };
1076 
1077 // Test for GL_OES_texture_3D extension
1078 class Texture3DTestES2 : public TexCoordDrawTest
1079 {
1080   protected:
Texture3DTestES2()1081     Texture3DTestES2() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
1082 
getVertexShaderSource()1083     const char *getVertexShaderSource() override
1084     {
1085         return "#version 100\n"
1086                "varying vec2 texcoord;\n"
1087                "attribute vec4 position;\n"
1088                "void main()\n"
1089                "{\n"
1090                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1091                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1092                "}\n";
1093     }
1094 
getFragmentShaderSource()1095     const char *getFragmentShaderSource() override
1096     {
1097         if (!hasTexture3DExt())
1098         {
1099             return "#version 100\n"
1100                    "precision highp float;\n"
1101                    "varying vec2 texcoord;\n"
1102                    "void main()\n"
1103                    "{\n"
1104                    "    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1105                    "}\n";
1106         }
1107         return "#version 100\n"
1108                "#extension GL_OES_texture_3D : enable\n"
1109                "precision highp float;\n"
1110                "uniform highp sampler3D tex3D;\n"
1111                "uniform highp float level;\n"
1112                "varying vec2 texcoord;\n"
1113                "void main()\n"
1114                "{\n"
1115                "    gl_FragColor = texture3DLod(tex3D, vec3(texcoord, 0.0), level);\n"
1116                "}\n";
1117     }
1118 
testSetUp()1119     void testSetUp() override
1120     {
1121         TexCoordDrawTest::testSetUp();
1122 
1123         glGenTextures(1, &mTexture3D);
1124 
1125         setUpProgram();
1126 
1127         mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1128         if (hasTexture3DExt())
1129         {
1130             ASSERT_NE(-1, mTexture3DUniformLocation);
1131         }
1132     }
1133 
testTearDown()1134     void testTearDown() override
1135     {
1136         glDeleteTextures(1, &mTexture3D);
1137         TexCoordDrawTest::testTearDown();
1138     }
1139 
hasTexture3DExt() const1140     bool hasTexture3DExt() const
1141     {
1142         // http://anglebug.com/4927
1143         if (IsPixel2() || IsOpenGLES())
1144         {
1145             return false;
1146         }
1147         return IsGLExtensionEnabled("GL_OES_texture_3D");
1148     }
1149 
1150     GLuint mTexture3D;
1151     GLint mTexture3DUniformLocation;
1152 };
1153 
1154 class Texture3DTestES3 : public Texture3DTestES2
1155 {
1156   protected:
Texture3DTestES3()1157     Texture3DTestES3() : Texture3DTestES2() {}
1158 
getVertexShaderSource()1159     const char *getVertexShaderSource() override
1160     {
1161         return "#version 300 es\n"
1162                "out vec2 texcoord;\n"
1163                "in vec4 position;\n"
1164                "void main()\n"
1165                "{\n"
1166                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1167                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1168                "}\n";
1169     }
1170 
getFragmentShaderSource()1171     const char *getFragmentShaderSource() override
1172     {
1173         return "#version 300 es\n"
1174                "precision highp float;\n"
1175                "uniform highp sampler3D tex3D;\n"
1176                "in vec2 texcoord;\n"
1177                "out vec4 fragColor;\n"
1178                "void main()\n"
1179                "{\n"
1180                "    fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
1181                "}\n";
1182     }
1183 };
1184 
1185 class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
1186 {
1187   protected:
ShadowSamplerPlusSampler3DTestES3()1188     ShadowSamplerPlusSampler3DTestES3()
1189         : TexCoordDrawTest(),
1190           mTextureShadow(0),
1191           mTexture3D(0),
1192           mTextureShadowUniformLocation(-1),
1193           mTexture3DUniformLocation(-1),
1194           mDepthRefUniformLocation(-1)
1195     {}
1196 
getVertexShaderSource()1197     const char *getVertexShaderSource() override
1198     {
1199         return "#version 300 es\n"
1200                "out vec2 texcoord;\n"
1201                "in vec4 position;\n"
1202                "void main()\n"
1203                "{\n"
1204                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1205                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1206                "}\n";
1207     }
1208 
getFragmentShaderSource()1209     const char *getFragmentShaderSource() override
1210     {
1211         return "#version 300 es\n"
1212                "precision highp float;\n"
1213                "uniform highp sampler2DShadow tex2DShadow;\n"
1214                "uniform highp sampler3D tex3D;\n"
1215                "in vec2 texcoord;\n"
1216                "uniform float depthRef;\n"
1217                "out vec4 fragColor;\n"
1218                "void main()\n"
1219                "{\n"
1220                "    fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
1221                "    fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
1222                "}\n";
1223     }
1224 
testSetUp()1225     void testSetUp() override
1226     {
1227         TexCoordDrawTest::testSetUp();
1228 
1229         glGenTextures(1, &mTexture3D);
1230 
1231         glGenTextures(1, &mTextureShadow);
1232         glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1233         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1234 
1235         setUpProgram();
1236 
1237         mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1238         ASSERT_NE(-1, mTextureShadowUniformLocation);
1239         mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1240         ASSERT_NE(-1, mTexture3DUniformLocation);
1241         mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1242         ASSERT_NE(-1, mDepthRefUniformLocation);
1243     }
1244 
testTearDown()1245     void testTearDown() override
1246     {
1247         glDeleteTextures(1, &mTextureShadow);
1248         glDeleteTextures(1, &mTexture3D);
1249         TexCoordDrawTest::testTearDown();
1250     }
1251 
1252     GLuint mTextureShadow;
1253     GLuint mTexture3D;
1254     GLint mTextureShadowUniformLocation;
1255     GLint mTexture3DUniformLocation;
1256     GLint mDepthRefUniformLocation;
1257 };
1258 
1259 class SamplerTypeMixTestES3 : public TexCoordDrawTest
1260 {
1261   protected:
SamplerTypeMixTestES3()1262     SamplerTypeMixTestES3()
1263         : TexCoordDrawTest(),
1264           mTexture2D(0),
1265           mTextureCube(0),
1266           mTexture2DShadow(0),
1267           mTextureCubeShadow(0),
1268           mTexture2DUniformLocation(-1),
1269           mTextureCubeUniformLocation(-1),
1270           mTexture2DShadowUniformLocation(-1),
1271           mTextureCubeShadowUniformLocation(-1),
1272           mDepthRefUniformLocation(-1)
1273     {}
1274 
getVertexShaderSource()1275     const char *getVertexShaderSource() override
1276     {
1277         return "#version 300 es\n"
1278                "out vec2 texcoord;\n"
1279                "in vec4 position;\n"
1280                "void main()\n"
1281                "{\n"
1282                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1283                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1284                "}\n";
1285     }
1286 
getFragmentShaderSource()1287     const char *getFragmentShaderSource() override
1288     {
1289         return "#version 300 es\n"
1290                "precision highp float;\n"
1291                "uniform highp sampler2D tex2D;\n"
1292                "uniform highp samplerCube texCube;\n"
1293                "uniform highp sampler2DShadow tex2DShadow;\n"
1294                "uniform highp samplerCubeShadow texCubeShadow;\n"
1295                "in vec2 texcoord;\n"
1296                "uniform float depthRef;\n"
1297                "out vec4 fragColor;\n"
1298                "void main()\n"
1299                "{\n"
1300                "    fragColor = texture(tex2D, texcoord);\n"
1301                "    fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1302                "    fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1303                "    fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1304                "0.125);\n"
1305                "}\n";
1306     }
1307 
testSetUp()1308     void testSetUp() override
1309     {
1310         TexCoordDrawTest::testSetUp();
1311 
1312         glGenTextures(1, &mTexture2D);
1313         glGenTextures(1, &mTextureCube);
1314 
1315         glGenTextures(1, &mTexture2DShadow);
1316         glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1317         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1318 
1319         glGenTextures(1, &mTextureCubeShadow);
1320         glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1321         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1322 
1323         setUpProgram();
1324 
1325         mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1326         ASSERT_NE(-1, mTexture2DUniformLocation);
1327         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1328         ASSERT_NE(-1, mTextureCubeUniformLocation);
1329         mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1330         ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1331         mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1332         ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1333         mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1334         ASSERT_NE(-1, mDepthRefUniformLocation);
1335 
1336         ASSERT_GL_NO_ERROR();
1337     }
1338 
testTearDown()1339     void testTearDown() override
1340     {
1341         glDeleteTextures(1, &mTexture2D);
1342         glDeleteTextures(1, &mTextureCube);
1343         glDeleteTextures(1, &mTexture2DShadow);
1344         glDeleteTextures(1, &mTextureCubeShadow);
1345         TexCoordDrawTest::testTearDown();
1346     }
1347 
1348     GLuint mTexture2D;
1349     GLuint mTextureCube;
1350     GLuint mTexture2DShadow;
1351     GLuint mTextureCubeShadow;
1352     GLint mTexture2DUniformLocation;
1353     GLint mTextureCubeUniformLocation;
1354     GLint mTexture2DShadowUniformLocation;
1355     GLint mTextureCubeShadowUniformLocation;
1356     GLint mDepthRefUniformLocation;
1357 };
1358 
1359 class SamplerInStructTest : public Texture2DTest
1360 {
1361   protected:
SamplerInStructTest()1362     SamplerInStructTest() : Texture2DTest() {}
1363 
getTextureUniformName()1364     const char *getTextureUniformName() override { return "us.tex"; }
1365 
getFragmentShaderSource()1366     const char *getFragmentShaderSource() override
1367     {
1368         return "precision highp float;\n"
1369                "struct S\n"
1370                "{\n"
1371                "    vec4 a;\n"
1372                "    highp sampler2D tex;\n"
1373                "};\n"
1374                "uniform S us;\n"
1375                "varying vec2 texcoord;\n"
1376                "void main()\n"
1377                "{\n"
1378                "    gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1379                "}\n";
1380     }
1381 
runSamplerInStructTest()1382     void runSamplerInStructTest()
1383     {
1384         setUpProgram();
1385 
1386         glActiveTexture(GL_TEXTURE0);
1387         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1388         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1389                      &GLColor::green);
1390         drawQuad(mProgram, "position", 0.5f);
1391         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1392     }
1393 };
1394 
1395 class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1396 {
1397   protected:
SamplerInStructAsFunctionParameterTest()1398     SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1399 
getFragmentShaderSource()1400     const char *getFragmentShaderSource() override
1401     {
1402         return "precision highp float;\n"
1403                "struct S\n"
1404                "{\n"
1405                "    vec4 a;\n"
1406                "    highp sampler2D tex;\n"
1407                "};\n"
1408                "uniform S us;\n"
1409                "varying vec2 texcoord;\n"
1410                "vec4 sampleFrom(S s) {\n"
1411                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1412                "}\n"
1413                "void main()\n"
1414                "{\n"
1415                "    gl_FragColor = sampleFrom(us);\n"
1416                "}\n";
1417     }
1418 };
1419 
1420 class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1421 {
1422   protected:
SamplerInStructArrayAsFunctionParameterTest()1423     SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1424 
getTextureUniformName()1425     const char *getTextureUniformName() override { return "us[0].tex"; }
1426 
getFragmentShaderSource()1427     const char *getFragmentShaderSource() override
1428     {
1429         return "precision highp float;\n"
1430                "struct S\n"
1431                "{\n"
1432                "    vec4 a;\n"
1433                "    highp sampler2D tex;\n"
1434                "};\n"
1435                "uniform S us[1];\n"
1436                "varying vec2 texcoord;\n"
1437                "vec4 sampleFrom(S s) {\n"
1438                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1439                "}\n"
1440                "void main()\n"
1441                "{\n"
1442                "    gl_FragColor = sampleFrom(us[0]);\n"
1443                "}\n";
1444     }
1445 };
1446 
1447 class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1448 {
1449   protected:
SamplerInNestedStructAsFunctionParameterTest()1450     SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1451 
getTextureUniformName()1452     const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1453 
getFragmentShaderSource()1454     const char *getFragmentShaderSource() override
1455     {
1456         return "precision highp float;\n"
1457                "struct SUB\n"
1458                "{\n"
1459                "    vec4 a;\n"
1460                "    highp sampler2D tex;\n"
1461                "};\n"
1462                "struct S\n"
1463                "{\n"
1464                "    SUB sub;\n"
1465                "};\n"
1466                "uniform S us[1];\n"
1467                "varying vec2 texcoord;\n"
1468                "vec4 sampleFrom(SUB s) {\n"
1469                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1470                "}\n"
1471                "void main()\n"
1472                "{\n"
1473                "    gl_FragColor = sampleFrom(us[0].sub);\n"
1474                "}\n";
1475     }
1476 };
1477 
1478 class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1479 {
1480   protected:
SamplerInStructAndOtherVariableTest()1481     SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1482 
getFragmentShaderSource()1483     const char *getFragmentShaderSource() override
1484     {
1485         return "precision highp float;\n"
1486                "struct S\n"
1487                "{\n"
1488                "    vec4 a;\n"
1489                "    highp sampler2D tex;\n"
1490                "};\n"
1491                "uniform S us;\n"
1492                "uniform float us_tex;\n"
1493                "varying vec2 texcoord;\n"
1494                "void main()\n"
1495                "{\n"
1496                "    gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1497                "}\n";
1498     }
1499 };
1500 
1501 class Texture2DIntegerTestES3 : public Texture2DTest
1502 {
1503   protected:
Texture2DIntegerTestES3()1504     Texture2DIntegerTestES3() : Texture2DTest() {}
1505 
getVertexShaderSource()1506     const char *getVertexShaderSource() override
1507     {
1508         return "#version 300 es\n"
1509                "out vec2 texcoord;\n"
1510                "in vec4 position;\n"
1511                "void main()\n"
1512                "{\n"
1513                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1514                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1515                "}\n";
1516     }
1517 
getFragmentShaderSource()1518     const char *getFragmentShaderSource() override
1519     {
1520         return "#version 300 es\n"
1521                "precision highp float;\n"
1522                "precision highp usampler2D;\n"
1523                "uniform usampler2D tex;\n"
1524                "in vec2 texcoord;\n"
1525                "out vec4 fragColor;\n"
1526                "void main()\n"
1527                "{\n"
1528                "    fragColor = vec4(texture(tex, texcoord))/255.0;\n"
1529                "}\n";
1530     }
1531 };
1532 
1533 class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1534 {
1535   protected:
TextureCubeIntegerTestES3()1536     TextureCubeIntegerTestES3()
1537         : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1538     {}
1539 
getVertexShaderSource()1540     const char *getVertexShaderSource() override
1541     {
1542         return "#version 300 es\n"
1543                "out vec2 texcoord;\n"
1544                "in vec4 position;\n"
1545                "void main()\n"
1546                "{\n"
1547                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1548                "    texcoord = 0.5*position.xy;\n"
1549                "}\n";
1550     }
1551 
getFragmentShaderSource()1552     const char *getFragmentShaderSource() override
1553     {
1554         return "#version 300 es\n"
1555                "precision highp float;\n"
1556                "precision highp usamplerCube;\n"
1557                "uniform usamplerCube texCube;\n"
1558                "in vec2 texcoord;\n"
1559                "out vec4 fragColor;\n"
1560                "void main()\n"
1561                "{\n"
1562                "    fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1563                "}\n";
1564     }
1565 
testSetUp()1566     void testSetUp() override
1567     {
1568         TexCoordDrawTest::testSetUp();
1569         glGenTextures(1, &mTextureCube);
1570         setUpProgram();
1571 
1572         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1573         ASSERT_NE(-1, mTextureCubeUniformLocation);
1574     }
1575 
testTearDown()1576     void testTearDown() override
1577     {
1578         glDeleteTextures(1, &mTextureCube);
1579         TexCoordDrawTest::testTearDown();
1580     }
1581 
1582     GLuint mTextureCube;
1583     GLint mTextureCubeUniformLocation;
1584 };
1585 
1586 class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1587 {
1588   protected:
TextureCubeIntegerEdgeTestES3()1589     TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1590 
getVertexShaderSource()1591     const char *getVertexShaderSource() override
1592     {
1593         return "#version 300 es\n"
1594                "out vec2 texcoord;\n"
1595                "in vec4 position;\n"
1596                "void main()\n"
1597                "{\n"
1598                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1599                "    texcoord = position.xy;\n"
1600                "}\n";
1601     }
1602 
getFragmentShaderSource()1603     const char *getFragmentShaderSource() override
1604     {
1605         return "#version 300 es\n"
1606                "precision highp float;\n"
1607                "precision highp usamplerCube;\n"
1608                "uniform usamplerCube texCube;\n"
1609                "in vec2 texcoord;\n"
1610                "out vec4 fragColor;\n"
1611                "void main()\n"
1612                "{\n"
1613                "    fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1614                "}\n";
1615     }
1616 };
1617 
1618 class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1619 {
1620   protected:
Texture2DIntegerProjectiveOffsetTestES3()1621     Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1622 
getVertexShaderSource()1623     const char *getVertexShaderSource() override
1624     {
1625         return "#version 300 es\n"
1626                "out vec2 texcoord;\n"
1627                "in vec4 position;\n"
1628                "void main()\n"
1629                "{\n"
1630                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1631                "    texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1632                "}\n";
1633     }
1634 
getFragmentShaderSource()1635     const char *getFragmentShaderSource() override
1636     {
1637         return "#version 300 es\n"
1638                "precision highp float;\n"
1639                "precision highp usampler2D;\n"
1640                "uniform usampler2D tex;\n"
1641                "in vec2 texcoord;\n"
1642                "out vec4 fragColor;\n"
1643                "void main()\n"
1644                "{\n"
1645                "    fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1646                "0.0))/255.0;\n"
1647                "}\n";
1648     }
1649 };
1650 
1651 class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1652 {
1653   protected:
Texture2DArrayIntegerTestES3()1654     Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1655 
getVertexShaderSource()1656     const char *getVertexShaderSource() override
1657     {
1658         return "#version 300 es\n"
1659                "out vec2 texcoord;\n"
1660                "in vec4 position;\n"
1661                "void main()\n"
1662                "{\n"
1663                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1664                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1665                "}\n";
1666     }
1667 
getFragmentShaderSource()1668     const char *getFragmentShaderSource() override
1669     {
1670         return "#version 300 es\n"
1671                "precision highp float;\n"
1672                "uniform highp usampler2DArray tex2DArray;\n"
1673                "in vec2 texcoord;\n"
1674                "out vec4 fragColor;\n"
1675                "void main()\n"
1676                "{\n"
1677                "    fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
1678                "0.0)))/255.0;\n"
1679                "}\n";
1680     }
1681 };
1682 
1683 class Texture3DIntegerTestES3 : public Texture3DTestES3
1684 {
1685   protected:
Texture3DIntegerTestES3()1686     Texture3DIntegerTestES3() : Texture3DTestES3() {}
1687 
getVertexShaderSource()1688     const char *getVertexShaderSource() override
1689     {
1690         return "#version 300 es\n"
1691                "out vec2 texcoord;\n"
1692                "in vec4 position;\n"
1693                "void main()\n"
1694                "{\n"
1695                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1696                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1697                "}\n";
1698     }
1699 
getFragmentShaderSource()1700     const char *getFragmentShaderSource() override
1701     {
1702         return "#version 300 es\n"
1703                "precision highp float;\n"
1704                "uniform highp usampler3D tex3D;\n"
1705                "in vec2 texcoord;\n"
1706                "out vec4 fragColor;\n"
1707                "void main()\n"
1708                "{\n"
1709                "    fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1710                "}\n";
1711     }
1712 };
1713 
1714 class PBOCompressedTextureTest : public Texture2DTest
1715 {
1716   protected:
PBOCompressedTextureTest()1717     PBOCompressedTextureTest() : Texture2DTest() {}
1718 
testSetUp()1719     void testSetUp() override
1720     {
1721         TexCoordDrawTest::testSetUp();
1722         glGenTextures(1, &mTexture2D);
1723         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1724         EXPECT_GL_NO_ERROR();
1725 
1726         setUpProgram();
1727 
1728         glGenBuffers(1, &mPBO);
1729     }
1730 
testTearDown()1731     void testTearDown() override
1732     {
1733         glDeleteBuffers(1, &mPBO);
1734         Texture2DTest::testTearDown();
1735     }
1736 
1737     GLuint mPBO;
1738 };
1739 
1740 class ETC1CompressedTextureTest : public Texture2DTest
1741 {
1742   protected:
ETC1CompressedTextureTest()1743     ETC1CompressedTextureTest() : Texture2DTest() {}
1744 
testSetUp()1745     void testSetUp() override
1746     {
1747         TexCoordDrawTest::testSetUp();
1748         glGenTextures(1, &mTexture2D);
1749         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1750         EXPECT_GL_NO_ERROR();
1751 
1752         setUpProgram();
1753     }
1754 
testTearDown()1755     void testTearDown() override { Texture2DTest::testTearDown(); }
1756 };
1757 
TEST_P(Texture2DTest,NegativeAPISubImage)1758 TEST_P(Texture2DTest, NegativeAPISubImage)
1759 {
1760     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1761     EXPECT_GL_ERROR(GL_NO_ERROR);
1762 
1763     setUpProgram();
1764 
1765     const GLubyte *pixels[20] = {0};
1766     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1767     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1768 
1769     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
1770     {
1771         // Create a 1-level immutable texture.
1772         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1773 
1774         // Try calling sub image on the second level.
1775         glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1776         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1777     }
1778 }
1779 
1780 // Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
TEST_P(Texture2DTest,QueryBinding)1781 TEST_P(Texture2DTest, QueryBinding)
1782 {
1783     glBindTexture(GL_TEXTURE_2D, 0);
1784     EXPECT_GL_ERROR(GL_NO_ERROR);
1785 
1786     GLint textureBinding;
1787     glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1788     EXPECT_GL_NO_ERROR();
1789     EXPECT_EQ(0, textureBinding);
1790 
1791     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
1792     if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1793         IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
1794     {
1795         EXPECT_GL_NO_ERROR();
1796         EXPECT_EQ(0, textureBinding);
1797     }
1798     else
1799     {
1800         EXPECT_GL_ERROR(GL_INVALID_ENUM);
1801     }
1802 }
1803 
TEST_P(Texture2DTest,ZeroSizedUploads)1804 TEST_P(Texture2DTest, ZeroSizedUploads)
1805 {
1806     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1807     EXPECT_GL_ERROR(GL_NO_ERROR);
1808 
1809     setUpProgram();
1810 
1811     // Use the texture first to make sure it's in video memory
1812     glUseProgram(mProgram);
1813     glUniform1i(mTexture2DUniformLocation, 0);
1814     drawQuad(mProgram, "position", 0.5f);
1815 
1816     const GLubyte *pixel[4] = {0};
1817 
1818     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1819     EXPECT_GL_NO_ERROR();
1820 
1821     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1822     EXPECT_GL_NO_ERROR();
1823 
1824     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1825     EXPECT_GL_NO_ERROR();
1826 }
1827 
TEST_P(Texture2DTest,DefineMultipleLevelsWithoutMipmapping)1828 TEST_P(Texture2DTest, DefineMultipleLevelsWithoutMipmapping)
1829 {
1830     setUpProgram();
1831 
1832     constexpr size_t kImageSize = 256;
1833     std::array<GLColor, kImageSize * kImageSize> kMipColors[2];
1834 
1835     std::fill(kMipColors[0].begin(), kMipColors[0].end(), GLColor::red);
1836     std::fill(kMipColors[1].begin(), kMipColors[1].end(), GLColor::green);
1837 
1838     glActiveTexture(GL_TEXTURE0);
1839     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1840     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1841     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1842 
1843     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1844                  kMipColors[0].data());
1845     EXPECT_GL_NO_ERROR();
1846 
1847     // Draw so the image is created.
1848     glUseProgram(mProgram);
1849     glUniform1i(mTexture2DUniformLocation, 0);
1850     drawQuad(mProgram, "position", 0.5f);
1851 
1852     // Define level 1 of the texture.
1853     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1854                  kMipColors[1].data());
1855     EXPECT_GL_NO_ERROR();
1856 
1857     // Draw again.
1858     drawQuad(mProgram, "position", 0.5f);
1859     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0][0]);
1860 }
1861 
1862 // Test drawing with two texture types, to trigger an ANGLE bug in validation
TEST_P(TextureCubeTest,CubeMapBug)1863 TEST_P(TextureCubeTest, CubeMapBug)
1864 {
1865     glActiveTexture(GL_TEXTURE0);
1866     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1867     glActiveTexture(GL_TEXTURE1);
1868     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1869     EXPECT_GL_ERROR(GL_NO_ERROR);
1870 
1871     glUseProgram(mProgram);
1872     glUniform1i(mTexture2DUniformLocation, 0);
1873     glUniform1i(mTextureCubeUniformLocation, 1);
1874     drawQuad(mProgram, "position", 0.5f);
1875     EXPECT_GL_NO_ERROR();
1876 }
1877 
1878 // Test drawing with two texture types accessed from the same shader and check that the result of
1879 // drawing is correct.
TEST_P(TextureCubeTest,CubeMapDraw)1880 TEST_P(TextureCubeTest, CubeMapDraw)
1881 {
1882     GLubyte texData[4];
1883     texData[0] = 0;
1884     texData[1] = 60;
1885     texData[2] = 0;
1886     texData[3] = 255;
1887 
1888     glActiveTexture(GL_TEXTURE0);
1889     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1890     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1891 
1892     glActiveTexture(GL_TEXTURE1);
1893     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1894     texData[1] = 120;
1895     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1896                     texData);
1897     EXPECT_GL_ERROR(GL_NO_ERROR);
1898 
1899     glUseProgram(mProgram);
1900     glUniform1i(mTexture2DUniformLocation, 0);
1901     glUniform1i(mTextureCubeUniformLocation, 1);
1902     drawQuad(mProgram, "position", 0.5f);
1903     EXPECT_GL_NO_ERROR();
1904 
1905     int px = getWindowWidth() - 1;
1906     int py = 0;
1907     EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1908 }
1909 
TEST_P(Sampler2DAsFunctionParameterTest,Sampler2DAsFunctionParameter)1910 TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1911 {
1912     glActiveTexture(GL_TEXTURE0);
1913     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1914     GLubyte texData[4];
1915     texData[0] = 0;
1916     texData[1] = 128;
1917     texData[2] = 0;
1918     texData[3] = 255;
1919     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1920     glUseProgram(mProgram);
1921     glUniform1i(mTexture2DUniformLocation, 0);
1922     drawQuad(mProgram, "position", 0.5f);
1923     EXPECT_GL_NO_ERROR();
1924 
1925     EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1926 }
1927 
1928 // Test drawing with two textures passed to the shader in a sampler array.
TEST_P(SamplerArrayTest,SamplerArrayDraw)1929 TEST_P(SamplerArrayTest, SamplerArrayDraw)
1930 {
1931     testSamplerArrayDraw();
1932 }
1933 
1934 // Test drawing with two textures passed to the shader in a sampler array which is passed to a
1935 // user-defined function in the shader.
TEST_P(SamplerArrayAsFunctionParameterTest,SamplerArrayAsFunctionParameter)1936 TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1937 {
1938     // TODO: Diagnose and fix. http://anglebug.com/2955
1939     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1940 
1941     testSamplerArrayDraw();
1942 }
1943 
1944 // Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
TEST_P(Texture2DTestWithDrawScale,MipmapsTwice)1945 TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
1946 {
1947     int px = getWindowWidth() / 2;
1948     int py = getWindowHeight() / 2;
1949 
1950     glActiveTexture(GL_TEXTURE0);
1951     glBindTexture(GL_TEXTURE_2D, mTexture2D);
1952 
1953     std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
1954 
1955     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
1956     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1957     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1958     glGenerateMipmap(GL_TEXTURE_2D);
1959 
1960     glUseProgram(mProgram);
1961     glUniform1i(mTexture2DUniformLocation, 0);
1962     glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1963     drawQuad(mProgram, "position", 0.5f);
1964     EXPECT_GL_NO_ERROR();
1965     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
1966 
1967     std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
1968 
1969     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1970                  pixelsBlue.data());
1971     glGenerateMipmap(GL_TEXTURE_2D);
1972 
1973     std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
1974 
1975     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1976                  pixelsGreen.data());
1977     glGenerateMipmap(GL_TEXTURE_2D);
1978 
1979     drawQuad(mProgram, "position", 0.5f);
1980 
1981     EXPECT_GL_NO_ERROR();
1982     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
1983 }
1984 
1985 // Test creating a FBO with a cube map render target, to test an ANGLE bug
1986 // https://code.google.com/p/angleproject/issues/detail?id=849
TEST_P(TextureCubeTest,CubeMapFBO)1987 TEST_P(TextureCubeTest, CubeMapFBO)
1988 {
1989     // http://anglebug.com/3145
1990     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1991 
1992     // http://anglebug.com/2822
1993     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1994 
1995     GLFramebuffer fbo;
1996     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1997 
1998     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1999     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2000                            mTextureCube, 0);
2001 
2002     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2003     EXPECT_GL_NO_ERROR();
2004 
2005     // Test clearing the six mip faces individually.
2006     std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
2007                                           GLColor::yellow, GLColor::cyan, GLColor::magenta}};
2008 
2009     for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2010     {
2011         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2012                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2013 
2014         Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
2015         glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
2016         glClear(GL_COLOR_BUFFER_BIT);
2017 
2018         EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
2019     }
2020 
2021     // Iterate the faces again to make sure the colors haven't changed.
2022     for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2023     {
2024         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2025                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2026         EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
2027             << "face color " << faceIndex << " shouldn't change";
2028     }
2029 }
2030 
2031 // Tests clearing a cube map with a scissor enabled.
TEST_P(TextureCubeTest,CubeMapFBOScissoredClear)2032 TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
2033 {
2034     // TODO(jie.a.chen): Diagnose and fix. http://anglebug.com/2822
2035     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
2036 
2037     // http://anglebug.com/3145
2038     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
2039 
2040     constexpr size_t kSize = 16;
2041 
2042     GLFramebuffer fbo;
2043     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2044     glViewport(0, 0, kSize, kSize);
2045 
2046     GLTexture texcube;
2047     glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
2048     for (GLenum face = 0; face < 6; face++)
2049     {
2050         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
2051                      GL_UNSIGNED_BYTE, nullptr);
2052     }
2053     ASSERT_GL_NO_ERROR();
2054 
2055     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2056                            texcube, 0);
2057 
2058     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2059     ASSERT_GL_NO_ERROR();
2060 
2061     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2062     glClear(GL_COLOR_BUFFER_BIT);
2063     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2064 
2065     glEnable(GL_SCISSOR_TEST);
2066     glScissor(kSize / 2, 0, kSize / 2, kSize);
2067     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2068     glClear(GL_COLOR_BUFFER_BIT);
2069 
2070     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2071     EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
2072 
2073     ASSERT_GL_NO_ERROR();
2074 }
2075 
2076 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
2077 // default color.
TEST_P(Texture2DTest,TexStorage)2078 TEST_P(Texture2DTest, TexStorage)
2079 {
2080     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
2081                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
2082 
2083     int width  = getWindowWidth();
2084     int height = getWindowHeight();
2085 
2086     GLuint tex2D;
2087     glGenTextures(1, &tex2D);
2088     glActiveTexture(GL_TEXTURE0);
2089     glBindTexture(GL_TEXTURE_2D, tex2D);
2090 
2091     // Fill with red
2092     std::vector<GLubyte> pixels(3 * 16 * 16);
2093     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2094     {
2095         pixels[pixelId * 3 + 0] = 255;
2096         pixels[pixelId * 3 + 1] = 0;
2097         pixels[pixelId * 3 + 2] = 0;
2098     }
2099 
2100     // ANGLE internally uses RGBA as the DirectX format for RGB images
2101     // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2102     // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2103     if (getClientMajorVersion() >= 3)
2104     {
2105         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2106     }
2107     else
2108     {
2109         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2110     }
2111 
2112     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2113     // glTexSubImage2D should take into account that the image is dirty.
2114     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2115     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2116     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2117 
2118     setUpProgram();
2119 
2120     glUseProgram(mProgram);
2121     glUniform1i(mTexture2DUniformLocation, 0);
2122     drawQuad(mProgram, "position", 0.5f);
2123     glDeleteTextures(1, &tex2D);
2124     EXPECT_GL_NO_ERROR();
2125     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2126 
2127     // Validate that the region of the texture without data has an alpha of 1.0
2128     angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
2129     EXPECT_EQ(255, pixel.A);
2130 }
2131 
2132 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2133 // initialized the image with a default color.
TEST_P(Texture2DTest,TexStorageWithPBO)2134 TEST_P(Texture2DTest, TexStorageWithPBO)
2135 {
2136     // http://anglebug.com/4126
2137     ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
2138 
2139     // http://anglebug.com/5081
2140     ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsOpenGL());
2141 
2142     // http://anglebug.com/5097
2143     ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsTSan());
2144 
2145     if (getClientMajorVersion() < 3)
2146     {
2147         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2148         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2149     }
2150 
2151     const int width          = getWindowWidth();
2152     const int height         = getWindowHeight();
2153     const size_t pixelCount  = width * height;
2154     const int componentCount = 3;
2155 
2156     GLuint tex2D;
2157     glGenTextures(1, &tex2D);
2158     glActiveTexture(GL_TEXTURE0);
2159     glBindTexture(GL_TEXTURE_2D, tex2D);
2160 
2161     // Fill with red
2162     std::vector<GLubyte> pixels(componentCount * pixelCount);
2163     for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
2164     {
2165         pixels[pixelId * componentCount + 0] = 255;
2166         pixels[pixelId * componentCount + 1] = 0;
2167         pixels[pixelId * componentCount + 2] = 0;
2168     }
2169 
2170     // Read 16x16 region from red backbuffer to PBO
2171     GLuint pbo;
2172     glGenBuffers(1, &pbo);
2173     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2174     glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
2175                  GL_STATIC_DRAW);
2176 
2177     // ANGLE internally uses RGBA as the DirectX format for RGB images
2178     // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2179     // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2180     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
2181 
2182     // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
2183     // untouched. glTexSubImage2D should take into account that the image is dirty.
2184     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
2185                     nullptr);
2186     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2187     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2188 
2189     setUpProgram();
2190 
2191     glUseProgram(mProgram);
2192     glUniform1i(mTexture2DUniformLocation, 0);
2193     drawQuad(mProgram, "position", 0.5f);
2194     glDeleteTextures(1, &tex2D);
2195     glDeleteBuffers(1, &pbo);
2196     EXPECT_GL_NO_ERROR();
2197     EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
2198     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2199 }
2200 
2201 // Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
2202 // and drawing with the texture
2203 // Pseudo code for the follow test:
2204 // 1. Upload PBO to mTexture2D
2205 // 2. Delete PBO
2206 // 3. Draw with otherTexture (x5)
2207 // 4. Draw with mTexture2D
2208 // 5. Validate color output
TEST_P(Texture2DTest,PBOWithMultipleDraws)2209 TEST_P(Texture2DTest, PBOWithMultipleDraws)
2210 {
2211     if (getClientMajorVersion() < 3)
2212     {
2213         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2214         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2215     }
2216 
2217     const GLuint width            = getWindowWidth();
2218     const GLuint height           = getWindowHeight();
2219     const GLuint windowPixelCount = width * height;
2220     std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
2221     std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
2222 
2223     // Create secondary draw that does not use mTexture
2224     const char *vertexShaderSource   = getVertexShaderSource();
2225     const char *fragmentShaderSource = getFragmentShaderSource();
2226     ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
2227 
2228     GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
2229     ASSERT_NE(-1, uniformLoc);
2230     glUseProgram(0);
2231 
2232     // Create secondary Texture to draw with
2233     GLTexture otherTexture;
2234     glActiveTexture(GL_TEXTURE0);
2235     glBindTexture(GL_TEXTURE_2D, otherTexture);
2236     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2237     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
2238                     pixelsRed.data());
2239     ASSERT_GL_NO_ERROR();
2240 
2241     // Setup primary Texture
2242     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2243     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2244     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2245     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2246     ASSERT_GL_NO_ERROR();
2247 
2248     // Setup PBO
2249     GLuint pbo = 0;
2250     glGenBuffers(1, &pbo);
2251     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2252     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
2253                  GL_STATIC_DRAW);
2254     ASSERT_GL_NO_ERROR();
2255 
2256     // Write PBO to mTexture
2257     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2258     ASSERT_GL_NO_ERROR();
2259     // Delete PBO as ANGLE should be properly handling refcount of this buffer
2260     glDeleteBuffers(1, &pbo);
2261     pixelsGreen.clear();
2262 
2263     // Do 5 draws not involving primary texture that the PBO updated
2264     glUseProgram(otherProgram);
2265     glUniform1i(uniformLoc, 0);
2266     glBindTexture(GL_TEXTURE_2D, otherTexture);
2267     drawQuad(otherProgram, "position", 0.5f);
2268     glBindTexture(GL_TEXTURE_2D, 0);
2269     glUseProgram(0);
2270 
2271     glUseProgram(otherProgram);
2272     glUniform1i(uniformLoc, 0);
2273     glBindTexture(GL_TEXTURE_2D, otherTexture);
2274     drawQuad(otherProgram, "position", 0.5f);
2275     glBindTexture(GL_TEXTURE_2D, 0);
2276     glUseProgram(0);
2277 
2278     glUseProgram(otherProgram);
2279     glUniform1i(uniformLoc, 0);
2280     glBindTexture(GL_TEXTURE_2D, otherTexture);
2281     drawQuad(otherProgram, "position", 0.5f);
2282     glBindTexture(GL_TEXTURE_2D, 0);
2283     glUseProgram(0);
2284 
2285     glUseProgram(otherProgram);
2286     glUniform1i(uniformLoc, 0);
2287     glBindTexture(GL_TEXTURE_2D, otherTexture);
2288     drawQuad(otherProgram, "position", 0.5f);
2289     glBindTexture(GL_TEXTURE_2D, 0);
2290     glUseProgram(0);
2291     ASSERT_GL_NO_ERROR();
2292 
2293     std::vector<GLColor> output(windowPixelCount, GLColor::black);
2294     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2295                  output.data());
2296     EXPECT_EQ(pixelsRed, output);
2297 
2298     setUpProgram();
2299     // Draw using PBO updated texture
2300     glUseProgram(mProgram);
2301     glUniform1i(mTexture2DUniformLocation, 0);
2302     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2303     drawQuad(mProgram, "position", 0.5f);
2304     ASSERT_GL_NO_ERROR();
2305 
2306     std::vector<GLColor> actual(windowPixelCount, GLColor::black);
2307     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2308                  actual.data());
2309     // Value should be green as it was updated during PBO transfer to mTexture
2310     std::vector<GLColor> expected(windowPixelCount, GLColor::green);
2311     EXPECT_EQ(expected, actual);
2312 }
2313 
2314 // Test that glTexSubImage2D combined with a PBO works properly. PBO has all pixels as red
2315 // except the middle one being green.
TEST_P(Texture2DTest,TexStorageWithPBOMiddlePixelDifferent)2316 TEST_P(Texture2DTest, TexStorageWithPBOMiddlePixelDifferent)
2317 {
2318     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2319     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2320 
2321     int width  = getWindowWidth();
2322     int height = getWindowHeight();
2323 
2324     GLuint tex2D;
2325     glGenTextures(1, &tex2D);
2326     glActiveTexture(GL_TEXTURE0);
2327     glBindTexture(GL_TEXTURE_2D, tex2D);
2328 
2329     std::vector<GLubyte> pixels(3 * 16 * 16);
2330 
2331     // Initialize texture with default black color.
2332     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2333     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2334 
2335     // Fill PBO's data with red, with middle one as green
2336     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2337     {
2338         if (pixelId == 8 * 7 + 7)
2339         {
2340             pixels[pixelId * 3 + 0] = 0;
2341             pixels[pixelId * 3 + 1] = 255;
2342             pixels[pixelId * 3 + 2] = 0;
2343         }
2344         else
2345         {
2346             pixels[pixelId * 3 + 0] = 255;
2347             pixels[pixelId * 3 + 1] = 0;
2348             pixels[pixelId * 3 + 2] = 0;
2349         }
2350     }
2351 
2352     GLuint pbo;
2353     glGenBuffers(1, &pbo);
2354     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2355     glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2356 
2357     // Update the color of the texture's upper-left 8x8 pixels, leaves the other pixels untouched.
2358     // glTexSubImage2D should take into account that the image is dirty.
2359     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2360     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2361     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2362 
2363     setUpProgram();
2364 
2365     glUseProgram(mProgram);
2366     glUniform1i(mTexture2DUniformLocation, 0);
2367     drawQuad(mProgram, "position", 0.5f);
2368     glDeleteTextures(1, &tex2D);
2369     glDeleteBuffers(1, &pbo);
2370     EXPECT_GL_NO_ERROR();
2371     EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
2372     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2373     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2374 }
2375 
2376 // Test that glTexSubImage2D combined with a PBO works properly when glTexImage2D has
2377 // initialized the image with a luminance color
TEST_P(Texture2DTest,TexImageWithLuminancePBO)2378 TEST_P(Texture2DTest, TexImageWithLuminancePBO)
2379 {
2380     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2381 
2382     int width  = getWindowWidth();
2383     int height = getWindowHeight();
2384 
2385     GLuint tex2D;
2386     glGenTextures(1, &tex2D);
2387     glActiveTexture(GL_TEXTURE0);
2388     glBindTexture(GL_TEXTURE_2D, tex2D);
2389 
2390     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
2391                  nullptr);
2392 
2393     // Fill PBO with white, with middle one as grey
2394     std::vector<GLubyte> pixels(16 * 16);
2395     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2396     {
2397         if (pixelId == 8 * 7 + 7)
2398         {
2399             pixels[pixelId] = 128;
2400         }
2401         else
2402         {
2403             pixels[pixelId] = 255;
2404         }
2405     }
2406 
2407     GLuint pbo;
2408     glGenBuffers(1, &pbo);
2409     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2410     glBufferData(GL_PIXEL_UNPACK_BUFFER, 16 * 16, pixels.data(), GL_STATIC_DRAW);
2411 
2412     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2413     // glTexSubImage2D should take into account that the image is dirty.
2414     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2415     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2416     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2417 
2418     setUpProgram();
2419 
2420     glUseProgram(mProgram);
2421     glUniform1i(mTexture2DUniformLocation, 0);
2422     drawQuad(mProgram, "position", 0.5f);
2423     glDeleteTextures(1, &tex2D);
2424     glDeleteBuffers(1, &pbo);
2425     EXPECT_GL_NO_ERROR();
2426     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 255, 255, 255);
2427     EXPECT_PIXEL_NEAR(width / 2 - 1, height / 2 - 1, 128, 128, 128, 255, 1);
2428 }
2429 
2430 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2431 // initialized the image with a RGB656 color
TEST_P(Texture2DTest,TexImageWithRGB565PBO)2432 TEST_P(Texture2DTest, TexImageWithRGB565PBO)
2433 {
2434     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2435     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2436 
2437     int width  = getWindowWidth();
2438     int height = getWindowHeight();
2439 
2440     GLuint tex2D;
2441     glGenTextures(1, &tex2D);
2442     glActiveTexture(GL_TEXTURE0);
2443     glBindTexture(GL_TEXTURE_2D, tex2D);
2444 
2445     // Fill PBO with red, with middle one as green
2446     std::vector<GLushort> pixels(16 * 16);
2447     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2448     {
2449         if (pixelId == 8 * 7 + 8)
2450         {
2451             pixels[pixelId] = 0x7E0;
2452         }
2453         else
2454         {
2455             pixels[pixelId] = 0xF800;
2456         }
2457     }
2458 
2459     GLuint pbo;
2460     glGenBuffers(1, &pbo);
2461     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2462     glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2463 
2464     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB565, 16, 16);
2465 
2466     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2467     // glTexSubImage2D should take into account that the image is dirty.
2468     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
2469                     reinterpret_cast<void *>(2));
2470     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2471     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2472 
2473     setUpProgram();
2474 
2475     glUseProgram(mProgram);
2476     glUniform1i(mTexture2DUniformLocation, 0);
2477     drawQuad(mProgram, "position", 0.5f);
2478     glDeleteTextures(1, &tex2D);
2479     glDeleteBuffers(1, &pbo);
2480     EXPECT_GL_NO_ERROR();
2481     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2482     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2483 }
2484 
2485 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2486 // initialized the image with a RGBA4444 color
TEST_P(Texture2DTest,TexImageWithRGBA4444PBO)2487 TEST_P(Texture2DTest, TexImageWithRGBA4444PBO)
2488 {
2489     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2490     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2491 
2492     int width  = getWindowWidth();
2493     int height = getWindowHeight();
2494 
2495     GLuint tex2D;
2496     glGenTextures(1, &tex2D);
2497     glActiveTexture(GL_TEXTURE0);
2498     glBindTexture(GL_TEXTURE_2D, tex2D);
2499 
2500     // Fill PBO with red, with middle one as green
2501     std::vector<GLushort> pixels(16 * 16);
2502     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2503     {
2504         if (pixelId == 8 * 7 + 8)
2505         {
2506             pixels[pixelId] = 0xF0F;
2507         }
2508         else
2509         {
2510             pixels[pixelId] = 0xF00F;
2511         }
2512     }
2513 
2514     GLuint pbo;
2515     glGenBuffers(1, &pbo);
2516     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2517     glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2518 
2519     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA4, 16, 16);
2520 
2521     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2522     // glTexSubImage2D should take into account that the image is dirty.
2523     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
2524                     reinterpret_cast<void *>(2));
2525     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2526     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2527 
2528     setUpProgram();
2529 
2530     glUseProgram(mProgram);
2531     glUniform1i(mTexture2DUniformLocation, 0);
2532     drawQuad(mProgram, "position", 0.5f);
2533     glDeleteTextures(1, &tex2D);
2534     glDeleteBuffers(1, &pbo);
2535     EXPECT_GL_NO_ERROR();
2536     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2537     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2538 }
2539 
2540 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2541 // initialized the image with a RGBA5551 color
TEST_P(Texture2DTest,TexImageWithRGBA5551PBO)2542 TEST_P(Texture2DTest, TexImageWithRGBA5551PBO)
2543 {
2544     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2545     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2546 
2547     int width  = getWindowWidth();
2548     int height = getWindowHeight();
2549 
2550     GLuint tex2D;
2551     glGenTextures(1, &tex2D);
2552     glActiveTexture(GL_TEXTURE0);
2553     glBindTexture(GL_TEXTURE_2D, tex2D);
2554 
2555     // Fill PBO with red, with middle one as green
2556     std::vector<GLushort> pixels(16 * 16);
2557     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2558     {
2559         if (pixelId == 8 * 7 + 7)
2560         {
2561             pixels[pixelId] = 0x7C1;
2562         }
2563         else
2564         {
2565             pixels[pixelId] = 0xF801;
2566         }
2567     }
2568 
2569     GLuint pbo;
2570     glGenBuffers(1, &pbo);
2571     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2572     glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2573 
2574     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB5_A1, 16, 16);
2575 
2576     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2577     // glTexSubImage2D should take into account that the image is dirty.
2578     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr);
2579     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2580     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2581 
2582     setUpProgram();
2583 
2584     glUseProgram(mProgram);
2585     glUniform1i(mTexture2DUniformLocation, 0);
2586     drawQuad(mProgram, "position", 0.5f);
2587     glDeleteTextures(1, &tex2D);
2588     glDeleteBuffers(1, &pbo);
2589     EXPECT_GL_NO_ERROR();
2590     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2591     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2592 }
2593 
2594 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
2595 // initialized the image with a depth-only format.
TEST_P(Texture2DTestES3,TexImageWithDepthPBO)2596 TEST_P(Texture2DTestES3, TexImageWithDepthPBO)
2597 {
2598     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2599     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2600 
2601     // http://anglebug.com/5315
2602     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());
2603 
2604     // http://anglebug.com/5316
2605     ANGLE_SKIP_TEST_IF(IsMetal() && IsOSX());
2606 
2607     constexpr GLsizei kSize = 4;
2608 
2609     // Set up the framebuffer.
2610     GLTexture colorTexture;
2611     glBindTexture(GL_TEXTURE_2D, colorTexture);
2612     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2613     ASSERT_GL_NO_ERROR();
2614 
2615     GLTexture depthTexture;
2616     glBindTexture(GL_TEXTURE_2D, depthTexture);
2617     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, kSize, kSize);
2618     ASSERT_GL_NO_ERROR();
2619 
2620     GLFramebuffer fbo;
2621     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2622     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2623     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
2624     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2625     ASSERT_GL_NO_ERROR();
2626 
2627     // Clear depth to 0, ensuring the texture's image is allocated.
2628     glClearDepthf(0);
2629     glClearColor(0, 0, 0, 1);
2630     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2631     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2632 
2633     // Fill depth with 1.0f.
2634     std::vector<GLushort> pixels(kSize * kSize);
2635     for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
2636     {
2637         pixels[pixelId] = 0xFFFF;
2638     }
2639 
2640     GLuint pbo;
2641     glGenBuffers(1, &pbo);
2642     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2643     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
2644                  GL_STATIC_DRAW);
2645     ASSERT_GL_NO_ERROR();
2646 
2647     // Upload PBO data.
2648     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
2649                     nullptr);
2650 
2651     // If depth is not set to 1, rendering would fail.
2652     glEnable(GL_DEPTH_TEST);
2653     glDepthFunc(GL_LESS);
2654 
2655     // Draw red
2656     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2657     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
2658     ASSERT_GL_NO_ERROR();
2659 
2660     EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2661 }
2662 
2663 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
2664 // initialized the image with a stencil-only format.
TEST_P(Texture2DTestES3,TexImageWithStencilPBO)2665 TEST_P(Texture2DTestES3, TexImageWithStencilPBO)
2666 {
2667     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2668     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2669 
2670     // http://anglebug.com/5313
2671     ANGLE_SKIP_TEST_IF(IsVulkan() && (IsAndroid() || (IsWindows() && IsIntel())));
2672 
2673     // http://anglebug.com/5315
2674     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());
2675 
2676     // http://anglebug.com/5316
2677     ANGLE_SKIP_TEST_IF(IsMetal() && IsOSX());
2678 
2679     // http://anglebug.com/5317
2680     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D());
2681 
2682     constexpr GLsizei kSize = 4;
2683 
2684     // Set up the framebuffer.
2685     GLTexture colorTexture;
2686     glBindTexture(GL_TEXTURE_2D, colorTexture);
2687     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2688     ASSERT_GL_NO_ERROR();
2689 
2690     GLTexture stencilTexture;
2691     glBindTexture(GL_TEXTURE_2D, stencilTexture);
2692     glTexStorage2D(GL_TEXTURE_2D, 1, GL_STENCIL_INDEX8, kSize, kSize);
2693     ASSERT_GL_NO_ERROR();
2694 
2695     GLFramebuffer fbo;
2696     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2697     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2698     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 0);
2699     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2700     ASSERT_GL_NO_ERROR();
2701 
2702     // Clear stencil to 0, ensuring the texture's image is allocated.
2703     glClearStencil(0);
2704     glClearColor(0, 0, 0, 1);
2705     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2706     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2707 
2708     // Fill stencil with 0x4E
2709     std::vector<GLubyte> pixels(kSize * kSize);
2710     for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
2711     {
2712         pixels[pixelId] = 0x4E;
2713     }
2714 
2715     GLuint pbo;
2716     glGenBuffers(1, &pbo);
2717     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2718     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
2719                  GL_STATIC_DRAW);
2720     ASSERT_GL_NO_ERROR();
2721 
2722     // Upload PBO data.
2723     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
2724                     nullptr);
2725     ASSERT_GL_NO_ERROR();
2726 
2727     // If stencil is not set to 0x4E, rendering would fail.
2728     glEnable(GL_STENCIL_TEST);
2729     glStencilFunc(GL_EQUAL, 0x4E, 0xFF);
2730     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2731     glStencilMask(0xFF);
2732 
2733     // Draw red
2734     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2735     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
2736     ASSERT_GL_NO_ERROR();
2737 
2738     EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2739 }
2740 
2741 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
2742 // initialized the image with a depth/stencil format.
TEST_P(Texture2DTestES3,TexImageWithDepthStencilPBO)2743 TEST_P(Texture2DTestES3, TexImageWithDepthStencilPBO)
2744 {
2745     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2746     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2747 
2748     // http://anglebug.com/5313
2749     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
2750 
2751     // http://anglebug.com/5315
2752     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());
2753 
2754     // http://anglebug.com/5316
2755     ANGLE_SKIP_TEST_IF(IsMetal() && IsOSX());
2756 
2757     // http://anglebug.com/5317
2758     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D());
2759 
2760     constexpr GLsizei kSize = 4;
2761 
2762     // Set up the framebuffer.
2763     GLTexture colorTexture;
2764     glBindTexture(GL_TEXTURE_2D, colorTexture);
2765     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2766     ASSERT_GL_NO_ERROR();
2767 
2768     GLTexture depthStencilTexture;
2769     glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
2770     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
2771     ASSERT_GL_NO_ERROR();
2772 
2773     GLFramebuffer fbo;
2774     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2775     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2776     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
2777                            depthStencilTexture, 0);
2778     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2779     ASSERT_GL_NO_ERROR();
2780 
2781     // Clear depth and stencil to 0, ensuring the texture's image is allocated.
2782     glClearDepthf(0);
2783     glClearStencil(0);
2784     glClearColor(0, 0, 0, 1);
2785     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2786     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2787 
2788     // Fill depth with 1.0f and stencil with 0xD5
2789     std::vector<GLuint> pixels(kSize * kSize);
2790     for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
2791     {
2792         pixels[pixelId] = 0xFFFFFFD5;
2793     }
2794 
2795     GLuint pbo;
2796     glGenBuffers(1, &pbo);
2797     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2798     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
2799                  GL_STATIC_DRAW);
2800     ASSERT_GL_NO_ERROR();
2801 
2802     // Upload PBO data.
2803     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
2804                     nullptr);
2805 
2806     // If depth is not set to 1, rendering would fail.
2807     glEnable(GL_DEPTH_TEST);
2808     glDepthFunc(GL_LESS);
2809 
2810     // If stencil is not set to 0xD5, rendering would fail.
2811     glEnable(GL_STENCIL_TEST);
2812     glStencilFunc(GL_EQUAL, 0xD5, 0xFF);
2813     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2814     glStencilMask(0xFF);
2815 
2816     // Draw red
2817     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2818     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
2819     ASSERT_GL_NO_ERROR();
2820 
2821     EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2822 }
2823 
2824 // Tests CopySubImage for float formats
TEST_P(Texture2DTest,CopySubImageFloat_R_R)2825 TEST_P(Texture2DTest, CopySubImageFloat_R_R)
2826 {
2827     testFloatCopySubImage(1, 1);
2828 }
2829 
TEST_P(Texture2DTest,CopySubImageFloat_RG_R)2830 TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
2831 {
2832     testFloatCopySubImage(2, 1);
2833 }
2834 
TEST_P(Texture2DTest,CopySubImageFloat_RG_RG)2835 TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
2836 {
2837     testFloatCopySubImage(2, 2);
2838 }
2839 
TEST_P(Texture2DTest,CopySubImageFloat_RGB_R)2840 TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
2841 {
2842     testFloatCopySubImage(3, 1);
2843 }
2844 
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RG)2845 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
2846 {
2847     testFloatCopySubImage(3, 2);
2848 }
2849 
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RGB)2850 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
2851 {
2852     // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2853     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
2854 
2855     // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2856     ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
2857 
2858     testFloatCopySubImage(3, 3);
2859 }
2860 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_R)2861 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
2862 {
2863     testFloatCopySubImage(4, 1);
2864 }
2865 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RG)2866 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
2867 {
2868     testFloatCopySubImage(4, 2);
2869 }
2870 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGB)2871 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
2872 {
2873     // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2874     ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
2875 
2876     testFloatCopySubImage(4, 3);
2877 }
2878 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGBA)2879 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
2880 {
2881     // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2882     ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
2883 
2884     testFloatCopySubImage(4, 4);
2885 }
2886 
2887 // Port of
2888 // https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
2889 // Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
2890 // handles GL_ALPHA
TEST_P(Texture2DTest,TextureNPOT_GL_ALPHA_UBYTE)2891 TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
2892 {
2893     const int npotTexSize = 5;
2894     const int potTexSize  = 4;  // Should be less than npotTexSize
2895     GLuint tex2D;
2896 
2897     if (IsGLExtensionEnabled("GL_OES_texture_npot"))
2898     {
2899         // This test isn't applicable if texture_npot is enabled
2900         return;
2901     }
2902 
2903     setUpProgram();
2904 
2905     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2906 
2907     // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
2908     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2909 
2910     glActiveTexture(GL_TEXTURE0);
2911     glGenTextures(1, &tex2D);
2912     glBindTexture(GL_TEXTURE_2D, tex2D);
2913 
2914     const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
2915 
2916     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2917     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2918 
2919     // Check that an NPOT texture not on level 0 generates INVALID_VALUE
2920     glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2921                  GL_UNSIGNED_BYTE, pixels.data());
2922     EXPECT_GL_ERROR(GL_INVALID_VALUE);
2923 
2924     // Check that an NPOT texture on level 0 succeeds
2925     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2926                  GL_UNSIGNED_BYTE, pixels.data());
2927     EXPECT_GL_NO_ERROR();
2928 
2929     // Check that generateMipmap fails on NPOT
2930     glGenerateMipmap(GL_TEXTURE_2D);
2931     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2932 
2933     // Check that nothing is drawn if filtering is not correct for NPOT
2934     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2935     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2936     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2937     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2938     glClear(GL_COLOR_BUFFER_BIT);
2939     drawQuad(mProgram, "position", 1.0f);
2940     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2941 
2942     // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
2943     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2944     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2945     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
2946     glClear(GL_COLOR_BUFFER_BIT);
2947     drawQuad(mProgram, "position", 1.0f);
2948     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2949 
2950     // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
2951     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2952     glClear(GL_COLOR_BUFFER_BIT);
2953     drawQuad(mProgram, "position", 1.0f);
2954     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2955 
2956     // Check that glTexImage2D for POT texture succeeds
2957     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
2958                  pixels.data());
2959     EXPECT_GL_NO_ERROR();
2960 
2961     // Check that generateMipmap for an POT texture succeeds
2962     glGenerateMipmap(GL_TEXTURE_2D);
2963     EXPECT_GL_NO_ERROR();
2964 
2965     // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
2966     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2967     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2968     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2969     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2970     glClear(GL_COLOR_BUFFER_BIT);
2971     drawQuad(mProgram, "position", 1.0f);
2972     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2973     EXPECT_GL_NO_ERROR();
2974 }
2975 
2976 // Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
2977 // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
TEST_P(Texture2DTest,NPOTSubImageParameters)2978 TEST_P(Texture2DTest, NPOTSubImageParameters)
2979 {
2980     glActiveTexture(GL_TEXTURE0);
2981     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2982 
2983     // Create an 8x8 (i.e. power-of-two) texture.
2984     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2985     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2986     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2987     glGenerateMipmap(GL_TEXTURE_2D);
2988 
2989     // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
2990     // This should always work, even if GL_OES_texture_npot isn't active.
2991     std::array<GLColor, 3 * 3> data;
2992     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
2993 
2994     EXPECT_GL_NO_ERROR();
2995 }
2996 
2997 // Test that drawing works correctly RGBA 3D texture
TEST_P(Texture3DTestES2,RGBA)2998 TEST_P(Texture3DTestES2, RGBA)
2999 {
3000     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3001     glActiveTexture(GL_TEXTURE0);
3002     glBindTexture(GL_TEXTURE_3D, mTexture3D);
3003     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
3004     std::vector<GLColor> texDataRed(1u * 1u * 1u, GLColor::red);
3005     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3006                     texDataGreen.data());
3007     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3008                     texDataRed.data());
3009     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3010     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3011 
3012     EXPECT_GL_NO_ERROR();
3013 
3014     drawQuad(mProgram, "position", 0.5f);
3015 
3016     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3017 }
3018 
3019 // Test that drawing works correctly Luminance 3D texture
TEST_P(Texture3DTestES2,Luminance)3020 TEST_P(Texture3DTestES2, Luminance)
3021 {
3022     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3023     glActiveTexture(GL_TEXTURE0);
3024     glBindTexture(GL_TEXTURE_3D, mTexture3D);
3025     std::vector<GLubyte> texData(2u * 2u * 2u, 125);
3026     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3027     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3028                     texData.data());
3029     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3030     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3031 
3032     EXPECT_GL_NO_ERROR();
3033 
3034     drawQuad(mProgram, "position", 0.5f);
3035 
3036     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(125, 125, 125, 255));
3037 }
3038 
3039 // Test that drawing works correctly with glCopyTexSubImage3D
TEST_P(Texture3DTestES2,CopySubImageRGBA)3040 TEST_P(Texture3DTestES2, CopySubImageRGBA)
3041 {
3042     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3043 
3044     glClearColor(0, 0, 1, 1);
3045     glClear(GL_COLOR_BUFFER_BIT);
3046 
3047     glActiveTexture(GL_TEXTURE0);
3048     glBindTexture(GL_TEXTURE_3D, mTexture3D);
3049     std::vector<GLColor> texDataRed(4u * 4u * 4u, GLColor::red);
3050     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3051                     texDataRed.data());
3052     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3053                     texDataRed.data());
3054     glTexImage3DOES(GL_TEXTURE_3D, 2, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3055                     texDataRed.data());
3056     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
3057     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
3058     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3059     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3060 
3061     EXPECT_GL_NO_ERROR();
3062 
3063     glClearColor(0, 1, 0, 1);
3064     glClear(GL_COLOR_BUFFER_BIT);
3065     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3066 
3067     glUseProgram(mProgram);
3068     glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
3069     drawQuad(mProgram, "position", 0.5f);
3070 
3071     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3072 }
3073 
TEST_P(Texture3DTestES2,CopySubImageLuminance)3074 TEST_P(Texture3DTestES2, CopySubImageLuminance)
3075 {
3076     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3077 
3078     glClearColor(1, 0, 0, 1);
3079     glClear(GL_COLOR_BUFFER_BIT);
3080 
3081     glActiveTexture(GL_TEXTURE0);
3082     glBindTexture(GL_TEXTURE_3D, mTexture3D);
3083     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 4, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3084                     nullptr);
3085     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3086                     nullptr);
3087     glTexImage3DOES(GL_TEXTURE_3D, 2, GL_LUMINANCE, 1, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3088                     nullptr);
3089     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
3090     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
3091     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3092     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3093 
3094     EXPECT_GL_NO_ERROR();
3095 
3096     glClearColor(0, 1, 0, 1);
3097     glClear(GL_COLOR_BUFFER_BIT);
3098     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3099 
3100     glUseProgram(mProgram);
3101     glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
3102     drawQuad(mProgram, "position", 0.5f);
3103 
3104     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
3105 }
3106 
TEST_P(Texture3DTestES2,CopySubImageAlpha)3107 TEST_P(Texture3DTestES2, CopySubImageAlpha)
3108 {
3109     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3110 
3111     glClearColor(1, 0, 0, 0.5);
3112     glClear(GL_COLOR_BUFFER_BIT);
3113 
3114     glActiveTexture(GL_TEXTURE0);
3115     glBindTexture(GL_TEXTURE_3D, mTexture3D);
3116     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_ALPHA, 4, 4, 4, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
3117     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_ALPHA, 2, 2, 2, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
3118     glTexImage3DOES(GL_TEXTURE_3D, 2, GL_ALPHA, 1, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
3119     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
3120     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
3121     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3122     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3123 
3124     EXPECT_GL_NO_ERROR();
3125 
3126     glClearColor(0, 1, 0, 1);
3127     glClear(GL_COLOR_BUFFER_BIT);
3128     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3129 
3130     glUseProgram(mProgram);
3131     glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
3132     drawQuad(mProgram, "position", 0.5f);
3133 
3134     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 128), 1.0);
3135 }
3136 
3137 // Verify shrinking a texture with glTexStorage2D works correctly
TEST_P(Texture2DTestES3,ChangeTexSizeWithTexStorage)3138 TEST_P(Texture2DTestES3, ChangeTexSizeWithTexStorage)
3139 {
3140     // TODO: http://anglebug.com/5256
3141     ANGLE_SKIP_TEST_IF(IsWindows() && IsOpenGL());
3142 
3143     constexpr uint32_t kSizeLarge = 128;
3144     constexpr uint32_t kSizeSmall = 64;
3145 
3146     glActiveTexture(GL_TEXTURE0);
3147     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3148     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3149     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3150 
3151     // Create the texture with 'large' dimensions
3152     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSizeLarge, kSizeLarge, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3153                  nullptr);
3154     ASSERT_GL_NO_ERROR();
3155 
3156     GLFramebuffer destFbo;
3157     glBindFramebuffer(GL_FRAMEBUFFER, destFbo);
3158     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
3159     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3160 
3161     // Draw with the new texture so it's created in the back end
3162     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3163     glUseProgram(blueProgram);
3164     drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3165     ASSERT_GL_NO_ERROR();
3166     EXPECT_PIXEL_RECT_EQ(0, 0, kSizeLarge, kSizeLarge, GLColor::blue);
3167 
3168     // Shrink the texture
3169     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
3170     ASSERT_GL_NO_ERROR();
3171 
3172     // Create a source texture/FBO to blit from
3173     GLTexture sourceTex;
3174     glBindTexture(GL_TEXTURE_2D, sourceTex.get());
3175     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
3176     ASSERT_GL_NO_ERROR();
3177     GLFramebuffer sourceFbo;
3178     glBindFramebuffer(GL_FRAMEBUFFER, sourceFbo);
3179     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTex, 0);
3180     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3181     // Fill the source texture with green
3182     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
3183     glUseProgram(greenProgram);
3184     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3185     ASSERT_GL_NO_ERROR();
3186     EXPECT_PIXEL_RECT_EQ(0, 0, kSizeSmall, kSizeSmall, GLColor::green);
3187 
3188     // Blit the source (green) to the destination
3189     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFbo);
3190     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFbo);
3191     glBlitFramebuffer(0, 0, kSizeSmall, kSizeSmall, 0, 0, kSizeSmall, kSizeSmall,
3192                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3193     ASSERT_GL_NO_ERROR();
3194 
3195     // Render to the default framebuffer sampling from the blited texture and verify it's green
3196     glBindFramebuffer(GL_FRAMEBUFFER, 0);
3197     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3198     ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
3199     glUseProgram(texProgram);
3200     drawQuad(texProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3201     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
3202 }
3203 
3204 // Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
3205 // TextureImpl and the texture is synced before being used in a draw call.
TEST_P(Texture2DTestES3,TextureImplPropogatesDirtyBits)3206 TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
3207 {
3208     ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
3209     // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
3210     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
3211     // D3D Debug device reports an error. http://anglebug.com/3501
3212     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
3213     // Support copy from levels outside the image range. http://anglebug.com/4733
3214     ANGLE_SKIP_TEST_IF(IsVulkan());
3215 
3216     // The workaround in the GL backend required to trigger this bug generates driver warning
3217     // messages.
3218     ScopedIgnorePlatformMessages ignoreMessages;
3219 
3220     setUpProgram();
3221     glUseProgram(mProgram);
3222     glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
3223 
3224     GLTexture dest;
3225     glBindTexture(GL_TEXTURE_2D, dest);
3226 
3227     GLTexture source;
3228     glBindTexture(GL_TEXTURE_2D, source);
3229 
3230     // Put data in mip 0 and 1
3231     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3232                  GLColor::red.data());
3233     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3234                  GLColor::green.data());
3235 
3236     // Disable mipmapping so source is complete
3237     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3238     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3239 
3240     // Force the dirty bits to be synchronized in source
3241     drawQuad(mProgram, "position", 1.0f);
3242 
3243     // Copy from mip 1 of the source.  In the GL backend this internally sets the base level to mip
3244     // 1 and sets a dirty bit.
3245     glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
3246                           GL_FALSE, GL_FALSE);
3247 
3248     // Draw again, assertions are generated if the texture has internal dirty bits at draw time
3249     drawQuad(mProgram, "position", 1.0f);
3250 }
3251 
3252 // This test case changes the base level of a texture that's attached to a framebuffer, clears every
3253 // level to green, and then samples the texture when rendering. Test is taken from
3254 // https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
TEST_P(Texture2DTestES3,FramebufferTextureChangingBaselevel)3255 TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
3256 {
3257     // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
3258     ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
3259 
3260     setUpProgram();
3261 
3262     constexpr GLint width  = 8;
3263     constexpr GLint height = 4;
3264 
3265     GLTexture texture;
3266     glBindTexture(GL_TEXTURE_2D, texture);
3267     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3268     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3269     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3270     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3271 
3272     // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
3273     GLint level  = 0;
3274     GLint levelW = width;
3275     GLint levelH = height;
3276     glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3277                  nullptr);
3278     while (levelW > 1 || levelH > 1)
3279     {
3280         ++level;
3281         levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
3282         levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
3283         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3284                      nullptr);
3285     }
3286 
3287     // Clear each level of the texture using an FBO. Change the base level to match the level used
3288     // for the FBO on each iteration.
3289     GLFramebuffer fbo;
3290     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3291     level  = 0;
3292     levelW = width;
3293     levelH = height;
3294     while (levelW > 1 || levelH > 1)
3295     {
3296         levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
3297         levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
3298 
3299         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
3300         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
3301 
3302         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3303         EXPECT_GL_NO_ERROR();
3304 
3305         glClearColor(0, 1, 0, 1);
3306         glClear(GL_COLOR_BUFFER_BIT);
3307 
3308         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3309 
3310         ++level;
3311     }
3312 
3313     glBindFramebuffer(GL_FRAMEBUFFER, 0);
3314     glViewport(0, 0, 16, 16);
3315     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3316 
3317     drawQuad(mProgram, "position", 0.5f);
3318 
3319     EXPECT_GL_NO_ERROR();
3320     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3321 }
3322 
3323 // Test that changing the base level of a texture after redefining a level outside the mip-chain
3324 // preserves the other mips' data.
TEST_P(Texture2DBaseMaxTestES3,ExtendMipChainAfterRedefine)3325 TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
3326 {
3327     // http://anglebug.com/4699
3328     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
3329 
3330     // http://anglebug.com/5153
3331     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && IsOSX());
3332 
3333     GLFramebuffer framebuffer;
3334     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3335 
3336     GLTexture texture;
3337     glBindTexture(GL_TEXTURE_2D, texture);
3338 
3339     std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
3340     fillMipData(mipData.data(), kMip0Size, kMipColors);
3341 
3342     for (size_t mip = 1; mip < kMipCount; ++mip)
3343     {
3344         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
3345                      GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
3346     }
3347 
3348     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3349     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
3350     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3351 
3352     // Mip 1 is green.  Verify this.
3353     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
3354 
3355     // http://anglebug.com/4709
3356     ANGLE_SKIP_TEST_IF(IsOpenGL() && (IsIntel() || IsAMD()) && IsWindows());
3357 
3358     // Add mip 0 and rebase the mip chain.
3359     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3360                  mipData.data() + getMipDataOffset(kMip0Size, 0));
3361     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3362 
3363     // Mip 1 should still be green.
3364     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
3365 
3366     // Verify the other mips too.
3367     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
3368     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3369     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[2]);
3370 
3371     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
3372     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3373     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[3]);
3374 
3375     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3376     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3377 
3378     // http://anglebug.com/4704
3379     ANGLE_SKIP_TEST_IF(IsVulkan());
3380 
3381     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
3382 }
3383 
3384 // Test that changing the base level of a texture multiple times preserves the data.
TEST_P(Texture2DBaseMaxTestES3,PingPongBaseLevel)3385 TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevel)
3386 {
3387     // http://anglebug.com/4710
3388     ANGLE_SKIP_TEST_IF(IsD3D());
3389 
3390     // http://anglebug.com/4711
3391     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsAMD() && IsWindows());
3392 
3393     // http://anglebug.com/4701
3394     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
3395 
3396     initTest();
3397 
3398     // Ping pong a few times.
3399     for (uint32_t tries = 0; tries < 2; ++tries)
3400     {
3401         // Rebase to different mips and verify mips.
3402         for (uint32_t base = 0; base < kMipCount; ++base)
3403         {
3404             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
3405             for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
3406             {
3407                 setLodUniform(lod);
3408                 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3409                 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
3410             }
3411         }
3412 
3413         // Rebase backwards and verify mips.
3414         for (uint32_t base = kMipCount - 2; base > 0; --base)
3415         {
3416             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
3417             for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
3418             {
3419                 setLodUniform(lod);
3420                 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3421                 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
3422             }
3423         }
3424     }
3425 }
3426 
3427 // Test that glTexSubImage2D after incompatibly redefining a mip level correctly applies the update
3428 // after the redefine data.
TEST_P(Texture2DBaseMaxTestES3,SubImageAfterRedefine)3429 TEST_P(Texture2DBaseMaxTestES3, SubImageAfterRedefine)
3430 {
3431     initTest();
3432 
3433     // Test that all mips have the expected data initially (this makes sure the texture image is
3434     // created already).
3435     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3436     {
3437         setLodUniform(lod);
3438         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3439         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3440     }
3441 
3442     // Redefine every level, followed by a glTexSubImage2D
3443     const GLColor kNewMipColors[kMipCount] = {
3444         GLColor::yellow,
3445         GLColor::cyan,
3446         GLColor(127, 0, 0, 255),
3447         GLColor(0, 127, 0, 255),
3448     };
3449     std::array<GLColor, getTotalMipDataSize(kMip0Size * 2)> newMipData;
3450     fillMipData(newMipData.data(), kMip0Size * 2, kNewMipColors);
3451 
3452     const GLColor kSubImageMipColors[kMipCount] = {
3453         GLColor(0, 0, 127, 255),
3454         GLColor(127, 127, 0, 255),
3455         GLColor(0, 127, 127, 255),
3456         GLColor(127, 0, 127, 255),
3457     };
3458     std::array<GLColor, getTotalMipDataSize(kMip0Size)> subImageMipData;
3459     fillMipData(subImageMipData.data(), kMip0Size, kSubImageMipColors);
3460 
3461     for (size_t mip = 0; mip < kMipCount; ++mip)
3462     {
3463         // Redefine the level.
3464         size_t newMipSize = (kMip0Size * 2) >> mip;
3465         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, newMipSize, newMipSize, 0, GL_RGBA,
3466                      GL_UNSIGNED_BYTE, newMipData.data() + getMipDataOffset(kMip0Size * 2, mip));
3467 
3468         // Immediately follow that with a subimage update.
3469         glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
3470                         GL_UNSIGNED_BYTE,
3471                         subImageMipData.data() + getMipDataOffset(kMip0Size, mip));
3472     }
3473     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
3474 
3475     // Test that the texture looks as expected.
3476     const int w = getWindowWidth() - 1;
3477     const int h = getWindowHeight() - 1;
3478     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3479     {
3480         setLodUniform(lod);
3481         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3482         EXPECT_PIXEL_COLOR_EQ(0, 0, kSubImageMipColors[lod]);
3483         EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColors[lod]);
3484         EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColors[lod]);
3485         EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColors[lod]);
3486     }
3487 }
3488 
3489 // Test that incompatibly redefining a level then redefining it back to its original size works.
TEST_P(Texture2DBaseMaxTestES3,IncompatiblyRedefineLevelThenRevert)3490 TEST_P(Texture2DBaseMaxTestES3, IncompatiblyRedefineLevelThenRevert)
3491 {
3492     initTest();
3493 
3494     // Test that all mips have the expected data initially (this makes sure the texture image is
3495     // created already).
3496     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3497     {
3498         setLodUniform(lod);
3499         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3500         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3501     }
3502 
3503     // Redefine Mip 1 to be larger.
3504     constexpr size_t kLargeMip1Size = getMipDataSize(kMip0Size * 2, 1);
3505     std::array<GLColor, kLargeMip1Size> interimMipData;
3506     std::fill(interimMipData.data(), interimMipData.data() + kLargeMip1Size, GLColor::yellow);
3507 
3508     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3509                  interimMipData.data());
3510 
3511     // Redefine Mip 1 back to its original size.
3512     constexpr size_t kNormalMip1Size = getMipDataSize(kMip0Size, 1);
3513     std::array<GLColor, kLargeMip1Size> newMipData;
3514     std::fill(newMipData.data(), newMipData.data() + kNormalMip1Size, GLColor::cyan);
3515 
3516     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size / 2, kMip0Size / 2, 0, GL_RGBA,
3517                  GL_UNSIGNED_BYTE, newMipData.data());
3518 
3519     // Verify texture colors.
3520     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3521     {
3522         setLodUniform(lod);
3523         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3524         EXPECT_PIXEL_COLOR_EQ(0, 0, lod == 1 ? GLColor::cyan : kMipColors[lod]);
3525     }
3526 }
3527 
3528 // Test that redefining every level of a texture to another format works.  The format uses more
3529 // bits per component, to ensure alignment requirements for the new format are taken into account.
TEST_P(Texture2DBaseMaxTestES3,RedefineEveryLevelToAnotherFormat)3530 TEST_P(Texture2DBaseMaxTestES3, RedefineEveryLevelToAnotherFormat)
3531 {
3532     initTest();
3533 
3534     // Test that all mips have the expected data initially (this makes sure the texture image is
3535     // created already).
3536     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3537     {
3538         setLodUniform(lod);
3539         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3540         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3541     }
3542 
3543     const GLColor32F kNewMipColors[kMipCount] = {
3544         GLColor32F(1.0, 1.0, 0.0, 1.0f),
3545         GLColor32F(1.0, 0.0, 1.0, 1.0f),
3546         GLColor32F(0.0, 1.0, 1.0, 1.0f),
3547         GLColor32F(1.0, 1.0, 1.0, 1.0f),
3548     };
3549 
3550     std::array<GLColor32F, getTotalMipDataSize(kMip0Size)> newMipData;
3551     fillMipData(newMipData.data(), kMip0Size, kNewMipColors);
3552 
3553     // Redefine every level with the new format.
3554     for (size_t mip = 0; mip < kMipCount; ++mip)
3555     {
3556         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA32F, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
3557                      GL_FLOAT, newMipData.data() + getMipDataOffset(kMip0Size, mip));
3558     }
3559 
3560     // Verify texture colors.
3561     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3562     {
3563         setLodUniform(lod);
3564         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3565 
3566         GLColor32F mipColor32F = kNewMipColors[lod];
3567         GLColor mipColor(static_cast<GLubyte>(std::roundf(mipColor32F.R * 255)),
3568                          static_cast<GLubyte>(std::roundf(mipColor32F.G * 255)),
3569                          static_cast<GLubyte>(std::roundf(mipColor32F.B * 255)),
3570                          static_cast<GLubyte>(std::roundf(mipColor32F.A * 255)));
3571 
3572         EXPECT_PIXEL_COLOR_EQ(0, 0, mipColor);
3573     }
3574 }
3575 
3576 // Test that generating mipmaps after incompatibly redefining a level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefine)3577 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefine)
3578 {
3579     initTest();
3580 
3581     // Test that all mips have the expected data initially (this makes sure the texture image is
3582     // created already).
3583     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3584     {
3585         setLodUniform(lod);
3586         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3587         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3588     }
3589 
3590     // Redefine level 1 (any level would do other than 0) to an incompatible size, say the same size
3591     // as level 0.
3592     const GLColor kNewMipColor = GLColor::yellow;
3593     std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
3594     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
3595 
3596     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3597                  newMipData.data());
3598 
3599     // Generate mipmaps.  This should redefine level 1 back to being compatible with level 0.
3600     glGenerateMipmap(GL_TEXTURE_2D);
3601 
3602     // Test that the texture looks as expected.
3603     const int w = getWindowWidth() - 1;
3604     const int h = getWindowHeight() - 1;
3605     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3606     {
3607         setLodUniform(lod);
3608         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3609         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
3610         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]);
3611         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]);
3612         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]);
3613     }
3614 }
3615 
3616 // Test that generating mipmaps after incompatibly redefining a level while simultaneously changing
3617 // the base level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefineAndRebase)3618 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefineAndRebase)
3619 {
3620     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
3621 
3622     // http://crbug.com/1100613
3623     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
3624 
3625     // TODO(crbug.com/1132295): Failing on Apple DTK.
3626     ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsDesktopOpenGL());
3627 
3628     initTest();
3629 
3630     // Test that all mips have the expected data initially (this makes sure the texture image is
3631     // created already).
3632     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3633     {
3634         setLodUniform(lod);
3635         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3636         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3637     }
3638 
3639     // Redefine level 2 to an incompatible size, say the same size as level 0.
3640     const GLColor kNewMipColor = GLColor::yellow;
3641     std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
3642     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
3643 
3644     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3645                  newMipData.data());
3646 
3647     // Set base level of the texture to 1 then generate mipmaps.  Level 2 that's redefined should
3648     // go back to being compatibly defined.
3649     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3650     glGenerateMipmap(GL_TEXTURE_2D);
3651 
3652     // Test that the texture looks as expected.
3653     const int w = getWindowWidth() - 1;
3654     const int h = getWindowHeight() - 1;
3655     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3656     {
3657         setLodUniform(lod);
3658         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3659         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
3660         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[1]);
3661         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[1]);
3662         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[1]);
3663     }
3664 
3665     // Redefine level 1 (current base level) to an incompatible size.
3666     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3667                  newMipData.data());
3668 
3669     // Set base level of the texture back to 0 then generate mipmaps.  Level 1 should go back to
3670     // being compatibly defined.
3671     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3672     glGenerateMipmap(GL_TEXTURE_2D);
3673 
3674     // Test that the texture looks as expected.
3675     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3676     {
3677         setLodUniform(lod);
3678         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3679         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
3680         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]);
3681         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]);
3682         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]);
3683     }
3684 }
3685 
3686 // Test that generating mipmaps after incompatibly redefining the base level of the texture works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBase)3687 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBase)
3688 {
3689     initTest();
3690 
3691     // Test that all mips have the expected data initially (this makes sure the texture image is
3692     // created already).
3693     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3694     {
3695         setLodUniform(lod);
3696         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3697         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3698     }
3699 
3700     // Redefine level 0 to an incompatible size.
3701     const GLColor kNewMipColor = GLColor::yellow;
3702     std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
3703     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
3704 
3705     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
3706                  GL_UNSIGNED_BYTE, newMipData.data());
3707 
3708     // Generate mipmaps.
3709     glGenerateMipmap(GL_TEXTURE_2D);
3710 
3711     // Test that the texture looks as expected.
3712     const int w = getWindowWidth() - 1;
3713     const int h = getWindowHeight() - 1;
3714     for (uint32_t lod = 0; lod < kMipCount + 1; ++lod)
3715     {
3716         setLodUniform(lod);
3717         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3718         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
3719         EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
3720         EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
3721         EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
3722     }
3723 }
3724 
3725 // Test that generating mipmaps after incompatibly redefining the base level while simultaneously
3726 // changing MAX_LEVEL works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBaseAndChangingMax)3727 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBaseAndChangingMax)
3728 {
3729     initTest();
3730 
3731     // Test that all mips have the expected data initially (this makes sure the texture image is
3732     // created already).
3733     for (uint32_t lod = 0; lod < kMipCount; ++lod)
3734     {
3735         setLodUniform(lod);
3736         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3737         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3738     }
3739 
3740     // Redefine level 0 to an incompatible size.
3741     const GLColor kNewMipColor = GLColor::yellow;
3742     std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
3743     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
3744 
3745     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
3746                  GL_UNSIGNED_BYTE, newMipData.data());
3747 
3748     // Set max level of the texture to 2 then generate mipmaps.
3749     constexpr uint32_t kMaxLevel = 2;
3750     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMaxLevel);
3751     glGenerateMipmap(GL_TEXTURE_2D);
3752 
3753     // Test that the texture looks as expected.
3754     const int w = getWindowWidth() - 1;
3755     const int h = getWindowHeight() - 1;
3756     for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
3757     {
3758         setLodUniform(lod);
3759         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3760         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
3761         EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
3762         EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
3763         EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
3764     }
3765 }
3766 
3767 // Test that stage invalid texture levels work.
TEST_P(Texture2DBaseMaxTestES3,StageInvalidLevels)3768 TEST_P(Texture2DBaseMaxTestES3, StageInvalidLevels)
3769 {
3770     constexpr uint32_t kMaxLevel           = 2;
3771     const GLColor kMipColor[kMaxLevel + 1] = {GLColor::red, GLColor::green, GLColor::blue};
3772 
3773     initTest();
3774 
3775     GLTexture texture;
3776     glBindTexture(GL_TEXTURE_2D, texture);
3777 
3778     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3779     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3780     std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
3781     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataCyan.data());
3782     setLodUniform(0);
3783     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3784     EXPECT_GL_NO_ERROR();
3785 
3786     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
3787     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3788                  texDataGreen.data());
3789     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
3790     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3791     EXPECT_GL_NO_ERROR();
3792 
3793     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
3794     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
3795     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3796     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3797 
3798     // Test that the texture looks as expected.
3799     const int w = getWindowWidth() - 1;
3800     const int h = getWindowHeight() - 1;
3801     for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
3802     {
3803         setLodUniform(lod);
3804         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3805         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColor[lod]);
3806         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColor[lod]);
3807         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColor[lod]);
3808         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColor[lod]);
3809     }
3810 }
3811 
3812 // Test to check that texture completeness is determined correctly when the texture base level is
3813 // greater than 0, and also that level 0 is not sampled when base level is greater than 0.
TEST_P(Texture2DTestES3,DrawWithBaseLevel1)3814 TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
3815 {
3816     glActiveTexture(GL_TEXTURE0);
3817     glBindTexture(GL_TEXTURE_2D, mTexture2D);
3818 
3819     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
3820     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
3821     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
3822     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3823                  texDataGreen.data());
3824     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3825                  texDataGreen.data());
3826     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3827     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3828     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3829 
3830     EXPECT_GL_NO_ERROR();
3831 
3832     drawQuad(mProgram, "position", 0.5f);
3833 
3834     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3835 }
3836 
3837 // Test basic GL_EXT_copy_image copy without any bound textures
TEST_P(Texture2DTestES3,CopyImage)3838 TEST_P(Texture2DTestES3, CopyImage)
3839 {
3840     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
3841 
3842     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
3843     GLTexture srcTexture;
3844     GLTexture destTexture;
3845 
3846     glActiveTexture(GL_TEXTURE0);
3847     glBindTexture(GL_TEXTURE_2D, destTexture);
3848     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3849     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3850     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3851     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3852     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
3853 
3854     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
3855     glBindTexture(GL_TEXTURE_2D, srcTexture);
3856     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3857     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3858     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3859     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3860     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3861                  texDataGreen.data());
3862 
3863     glBindTexture(GL_TEXTURE_2D, 0);
3864 
3865     // copy
3866     glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 2, 2, 0, destTexture, GL_TEXTURE_2D, 0, 2,
3867                           2, 0, 2, 2, 1);
3868 
3869     glBindTexture(GL_TEXTURE_2D, destTexture);
3870 
3871     EXPECT_GL_NO_ERROR();
3872 
3873     glViewport(0, 0, 4, 4);
3874     drawQuad(mProgram, "position", 0.5f);
3875     EXPECT_GL_NO_ERROR();
3876 
3877     EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
3878     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
3879     EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
3880 }
3881 
3882 // Test GL_EXT_copy_image copy with a non-zero base level
TEST_P(Texture2DTestES3,CopyImageBaseLevel1)3883 TEST_P(Texture2DTestES3, CopyImageBaseLevel1)
3884 {
3885     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
3886 
3887     std::vector<GLColor> texDataBlack(8u * 8u, GLColor::black);
3888     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
3889     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
3890     std::vector<GLColor> texDataBlue(4u * 4u, GLColor::blue);
3891 
3892     GLTexture srcTexture;
3893     GLTexture destTexture;
3894 
3895     glActiveTexture(GL_TEXTURE0);
3896     glBindTexture(GL_TEXTURE_2D, destTexture);
3897     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3898     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3899     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3900                  texDataBlack.data());
3901     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
3902     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3903                  texDataGreen.data());
3904     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
3905     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3906     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3907 
3908     glBindTexture(GL_TEXTURE_2D, srcTexture);
3909     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3910     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3911     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3912                  texDataBlack.data());
3913     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3914                  texDataGreen.data());
3915     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
3916     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
3917     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3918     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3919 
3920     glBindTexture(GL_TEXTURE_2D, 0);
3921 
3922     // copy
3923     glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 1, 2, 2, 0, destTexture, GL_TEXTURE_2D, 1, 2,
3924                           2, 0, 2, 2, 1);
3925 
3926     glBindTexture(GL_TEXTURE_2D, destTexture);
3927 
3928     EXPECT_GL_NO_ERROR();
3929 
3930     glViewport(0, 0, 4, 4);
3931     drawQuad(mProgram, "position", 0.5f);
3932     EXPECT_GL_NO_ERROR();
3933 
3934     EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
3935     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
3936     EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
3937 }
3938 
3939 // Test basic GL_EXT_copy_image copy without any draw calls by attaching the texture
3940 // to a framebuffer and reads from the framebuffer to validate the copy
TEST_P(Texture2DTestES3,CopyImageFB)3941 TEST_P(Texture2DTestES3, CopyImageFB)
3942 {
3943     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
3944 
3945     glViewport(0, 0, 4, 4);
3946     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
3947     GLTexture srcTexture;
3948     GLTexture destTexture;
3949 
3950     glActiveTexture(GL_TEXTURE0);
3951     glBindTexture(GL_TEXTURE_2D, destTexture);
3952     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3953     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3954     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3955     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3956     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
3957 
3958     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
3959     glBindTexture(GL_TEXTURE_2D, srcTexture);
3960     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3961     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3962     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3963     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3964     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3965                  texDataGreen.data());
3966     glBindTexture(GL_TEXTURE_2D, 0);
3967 
3968     // copy
3969     glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, destTexture, GL_TEXTURE_2D, 0, 0,
3970                           1, 0, 3, 3, 1);
3971 
3972     EXPECT_GL_NO_ERROR();
3973 
3974     GLFramebuffer fb;
3975     glBindFramebuffer(GL_FRAMEBUFFER, fb);
3976     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
3977     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3978 
3979     EXPECT_PIXEL_RECT_EQ(0, 1, 3, 3, GLColor::green);
3980     EXPECT_PIXEL_RECT_EQ(3, 0, 1, 4, GLColor::red);
3981     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 1, GLColor::red);
3982 
3983     glBindFramebuffer(GL_FRAMEBUFFER, 0);
3984 }
3985 
3986 // Test GL_EXT_copy_image copy to a framebuffer attachment after
3987 // invalidation. Then draw with blending onto the framebuffer.
TEST_P(Texture2DTestES3,CopyImageFBInvalidateThenBlend)3988 TEST_P(Texture2DTestES3, CopyImageFBInvalidateThenBlend)
3989 {
3990     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
3991 
3992     ANGLE_GL_PROGRAM(drawBlueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3993     ANGLE_GL_PROGRAM(drawRedProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3994 
3995     glViewport(0, 0, 4, 4);
3996     GLTexture srcTexture;
3997     GLTexture textureAttachment;
3998 
3999     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
4000     glBindTexture(GL_TEXTURE_2D, srcTexture);
4001     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4002     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4003     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4004                  texDataGreen.data());
4005     glBindTexture(GL_TEXTURE_2D, 0);
4006 
4007     glBindTexture(GL_TEXTURE_2D, textureAttachment);
4008     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4009     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4010     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4011     glBindTexture(GL_TEXTURE_2D, 0);
4012 
4013     GLFramebuffer fb;
4014     glBindFramebuffer(GL_FRAMEBUFFER, fb);
4015     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureAttachment,
4016                            0);
4017     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4018 
4019     // Draw something in the texture to make sure it's image is defined.
4020     drawQuad(drawRedProgram, essl1_shaders::PositionAttrib(), 0.0f);
4021 
4022     // Invalidate the framebuffer.
4023     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
4024     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
4025     ASSERT_GL_NO_ERROR();
4026 
4027     // Copy into the framebuffer attachment.
4028     glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, textureAttachment, GL_TEXTURE_2D,
4029                           0, 0, 0, 0, 4, 4, 1);
4030     EXPECT_GL_NO_ERROR();
4031 
4032     // Draw and blend, making sure both the copy and draw happen correctly.
4033     glEnable(GL_BLEND);
4034     glBlendFunc(GL_ONE, GL_ONE);
4035     drawQuad(drawBlueProgram, essl1_shaders::PositionAttrib(), 0.0f);
4036     ASSERT_GL_NO_ERROR();
4037 
4038     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::cyan);
4039 
4040     glBindFramebuffer(GL_FRAMEBUFFER, 0);
4041 }
4042 
4043 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
4044 // have images defined.
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeUndefined)4045 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
4046 {
4047     // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
4048     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
4049 
4050     glActiveTexture(GL_TEXTURE0);
4051     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4052     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4053     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4054                  texDataGreen.data());
4055     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4056     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4057     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4058     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4059 
4060     EXPECT_GL_NO_ERROR();
4061 
4062     drawQuad(mProgram, "position", 0.5f);
4063 
4064     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4065 }
4066 
4067 // Test that drawing works correctly when level 0 is undefined and base level is 1.
TEST_P(Texture2DTestES3,DrawWithLevelZeroUndefined)4068 TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
4069 {
4070     // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
4071     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
4072 
4073     glActiveTexture(GL_TEXTURE0);
4074     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4075     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4076     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4077                  texDataGreen.data());
4078     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4079     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4080     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4081     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
4082 
4083     EXPECT_GL_NO_ERROR();
4084 
4085     // Texture is incomplete.
4086     drawQuad(mProgram, "position", 0.5f);
4087     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4088 
4089     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4090                  texDataGreen.data());
4091 
4092     // Texture is now complete.
4093     drawQuad(mProgram, "position", 0.5f);
4094     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4095 }
4096 
4097 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
4098 // dimensions that don't fit the images inside the range.
4099 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)4100 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
4101 {
4102     glActiveTexture(GL_TEXTURE0);
4103     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4104     std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
4105     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4106     std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
4107 
4108     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4109     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4110 
4111     // Two levels that are initially unused.
4112     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4113     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4114                  texDataCyan.data());
4115 
4116     // One level that is used - only this level should affect completeness.
4117     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4118                  texDataGreen.data());
4119 
4120     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4121     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4122 
4123     EXPECT_GL_NO_ERROR();
4124 
4125     drawQuad(mProgram, "position", 0.5f);
4126 
4127     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4128 
4129     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
4130 
4131     // Switch the level that is being used to the cyan level 2.
4132     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
4133     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
4134 
4135     EXPECT_GL_NO_ERROR();
4136 
4137     drawQuad(mProgram, "position", 0.5f);
4138 
4139     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
4140 }
4141 
4142 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
4143 // have images defined.
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeUndefined)4144 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
4145 {
4146     glActiveTexture(GL_TEXTURE0);
4147     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4148     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
4149     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4150                  texDataGreen.data());
4151     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4152     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4153     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
4154     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
4155 
4156     EXPECT_GL_NO_ERROR();
4157 
4158     drawQuad(mProgram, "position", 0.5f);
4159 
4160     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4161 }
4162 
4163 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
4164 // dimensions that don't fit the images inside the range.
4165 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)4166 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
4167 {
4168     // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
4169     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
4170 
4171     glActiveTexture(GL_TEXTURE0);
4172     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4173     std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
4174     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
4175     std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
4176 
4177     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4178     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4179 
4180     // Two levels that are initially unused.
4181     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4182                  texDataRed.data());
4183     glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4184                  texDataCyan.data());
4185 
4186     // One level that is used - only this level should affect completeness.
4187     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4188                  texDataGreen.data());
4189 
4190     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
4191     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
4192 
4193     EXPECT_GL_NO_ERROR();
4194 
4195     drawQuad(mProgram, "position", 0.5f);
4196 
4197     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4198 
4199     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
4200 
4201     // Switch the level that is being used to the cyan level 2.
4202     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
4203     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
4204 
4205     EXPECT_GL_NO_ERROR();
4206 
4207     drawQuad(mProgram, "position", 0.5f);
4208 
4209     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
4210 }
4211 
4212 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
4213 // have images defined.
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeUndefined)4214 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
4215 {
4216     glActiveTexture(GL_TEXTURE0);
4217     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
4218     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
4219     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4220                  texDataGreen.data());
4221     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4222     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4223     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
4224     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
4225 
4226     EXPECT_GL_NO_ERROR();
4227 
4228     drawQuad(mProgram, "position", 0.5f);
4229 
4230     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4231 }
4232 
4233 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
4234 // dimensions that don't fit the images inside the range.
4235 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)4236 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
4237 {
4238     // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
4239     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
4240 
4241     glActiveTexture(GL_TEXTURE0);
4242     glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
4243     std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
4244     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
4245     std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
4246 
4247     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4248     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4249 
4250     // Two levels that are initially unused.
4251     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4252                  texDataRed.data());
4253     glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4254                  texDataCyan.data());
4255 
4256     // One level that is used - only this level should affect completeness.
4257     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4258                  texDataGreen.data());
4259 
4260     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
4261     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
4262 
4263     EXPECT_GL_NO_ERROR();
4264 
4265     drawQuad(mProgram, "position", 0.5f);
4266 
4267     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4268 
4269     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
4270 
4271     // Switch the level that is being used to the cyan level 2.
4272     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
4273     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
4274 
4275     EXPECT_GL_NO_ERROR();
4276 
4277     drawQuad(mProgram, "position", 0.5f);
4278 
4279     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
4280 }
4281 
4282 // Test that texture completeness is updated if texture max level changes.
4283 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithMaxLevel)4284 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
4285 {
4286     glActiveTexture(GL_TEXTURE0);
4287     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4288     std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
4289 
4290     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4291     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4292 
4293     // A level that is initially unused.
4294     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4295                  texDataGreen.data());
4296 
4297     // One level that is initially used - only this level should affect completeness.
4298     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4299                  texDataGreen.data());
4300 
4301     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4302     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4303 
4304     EXPECT_GL_NO_ERROR();
4305 
4306     drawQuad(mProgram, "position", 0.5f);
4307 
4308     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4309 
4310     // Switch the max level to level 1. The levels within the used range now have inconsistent
4311     // dimensions and the texture should be incomplete.
4312     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4313 
4314     EXPECT_GL_NO_ERROR();
4315 
4316     drawQuad(mProgram, "position", 0.5f);
4317 
4318     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4319 }
4320 
4321 // Test that 3D texture completeness is updated if texture max level changes.
4322 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,Texture3DCompletenessChangesWithMaxLevel)4323 TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
4324 {
4325     glActiveTexture(GL_TEXTURE0);
4326     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4327     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
4328 
4329     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4330     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4331 
4332     // A level that is initially unused.
4333     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4334                  texDataGreen.data());
4335 
4336     // One level that is initially used - only this level should affect completeness.
4337     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4338                  texDataGreen.data());
4339 
4340     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
4341     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
4342 
4343     EXPECT_GL_NO_ERROR();
4344 
4345     drawQuad(mProgram, "position", 0.5f);
4346 
4347     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4348 
4349     // Switch the max level to level 1. The levels within the used range now have inconsistent
4350     // dimensions and the texture should be incomplete.
4351     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
4352 
4353     EXPECT_GL_NO_ERROR();
4354 
4355     drawQuad(mProgram, "position", 0.5f);
4356 
4357     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4358 }
4359 
4360 // Test that texture completeness is updated if texture base level changes.
4361 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithBaseLevel)4362 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
4363 {
4364     glActiveTexture(GL_TEXTURE0);
4365     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4366     std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
4367 
4368     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4369     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4370 
4371     // Two levels that are initially unused.
4372     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4373                  texDataGreen.data());
4374     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4375                  texDataGreen.data());
4376 
4377     // One level that is initially used - only this level should affect completeness.
4378     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4379                  texDataGreen.data());
4380 
4381     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
4382     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
4383 
4384     EXPECT_GL_NO_ERROR();
4385 
4386     drawQuad(mProgram, "position", 0.5f);
4387 
4388     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4389 
4390     // Switch the base level to level 1. The levels within the used range now have inconsistent
4391     // dimensions and the texture should be incomplete.
4392     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4393 
4394     EXPECT_GL_NO_ERROR();
4395 
4396     drawQuad(mProgram, "position", 0.5f);
4397 
4398     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4399 }
4400 
4401 // Test that texture is not complete if base level is greater than max level.
4402 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureBaseLevelGreaterThanMaxLevel)4403 TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
4404 {
4405     glActiveTexture(GL_TEXTURE0);
4406     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4407 
4408     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4409     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4410 
4411     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
4412 
4413     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
4414     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4415 
4416     EXPECT_GL_NO_ERROR();
4417 
4418     drawQuad(mProgram, "position", 0.5f);
4419 
4420     // Texture should be incomplete.
4421     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4422 }
4423 
4424 // Test that immutable texture base level and max level are clamped.
4425 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
TEST_P(Texture2DTestES3,ImmutableTextureBaseLevelOutOfRange)4426 TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
4427 {
4428     glActiveTexture(GL_TEXTURE0);
4429     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4430 
4431     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4432     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4433 
4434     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
4435 
4436     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
4437 
4438     // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
4439     // should be clamped to [base_level, levels - 1].
4440     // GLES 3.0.4 section 3.8.10 subsection Mipmapping
4441     // In the case of this test, those rules make the effective base level and max level 0.
4442     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
4443     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
4444 
4445     EXPECT_GL_NO_ERROR();
4446 
4447     drawQuad(mProgram, "position", 0.5f);
4448 
4449     // Texture should be complete.
4450     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4451 }
4452 
4453 // Test that changing base level works when it affects the format of the texture.
TEST_P(Texture2DTestES3,TextureFormatChangesWithBaseLevel)4454 TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
4455 {
4456     // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
4457     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
4458 
4459     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
4460 
4461     // Observed incorrect rendering on AMD OpenGL.
4462     ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
4463 
4464     glActiveTexture(GL_TEXTURE0);
4465     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4466     std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
4467     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
4468 
4469     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4470     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4471 
4472     // RGBA8 level that's initially unused.
4473     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4474                  texDataCyan.data());
4475 
4476     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4477     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4478 
4479     // RG8 level that's initially used, with consistent dimensions with level 0 but a different
4480     // format. It reads green channel data from the green and alpha channels of texDataGreen
4481     // (this is a bit hacky but works).
4482     glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
4483 
4484     EXPECT_GL_NO_ERROR();
4485 
4486     drawQuad(mProgram, "position", 0.5f);
4487 
4488     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4489 
4490     // Switch the texture to use the cyan level 0 with the RGBA format.
4491     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4492     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4493 
4494     EXPECT_GL_NO_ERROR();
4495 
4496     drawQuad(mProgram, "position", 0.5f);
4497 
4498     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
4499 }
4500 
4501 // Test that setting a texture image works when base level is out of range.
TEST_P(Texture2DTestES3,SetImageWhenBaseLevelOutOfRange)4502 TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
4503 {
4504     glActiveTexture(GL_TEXTURE0);
4505     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4506 
4507     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4508     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4509 
4510     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
4511     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
4512 
4513     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
4514 
4515     EXPECT_GL_NO_ERROR();
4516 
4517     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4518 
4519     drawQuad(mProgram, "position", 0.5f);
4520 
4521     // Texture should be complete.
4522     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4523 }
4524 
4525 // In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
4526 // RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
4527 // with these formats does not work as expected.
TEST_P(Texture2DArrayTestES3,RedefineInittableArray)4528 TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
4529 {
4530     std::vector<GLubyte> pixelData;
4531     for (size_t count = 0; count < 5000; count++)
4532     {
4533         pixelData.push_back(0u);
4534         pixelData.push_back(255u);
4535         pixelData.push_back(0u);
4536     }
4537 
4538     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
4539     glUseProgram(mProgram);
4540     glUniform1i(mTextureArrayLocation, 0);
4541 
4542     // The first draw worked correctly.
4543     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
4544                  &pixelData[0]);
4545 
4546     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4547     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4548     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
4549     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
4550     drawQuad(mProgram, "position", 1.0f);
4551     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4552 
4553     // The dimension of the respecification must match the original exactly to trigger the bug.
4554     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
4555                  &pixelData[0]);
4556     drawQuad(mProgram, "position", 1.0f);
4557     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4558 
4559     ASSERT_GL_NO_ERROR();
4560 }
4561 
4562 // Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
4563 // This test is needed especially to confirm that sampler registers get assigned correctly on
4564 // the HLSL backend even when there's a mix of different HLSL sampler and texture types.
TEST_P(ShadowSamplerPlusSampler3DTestES3,ShadowSamplerPlusSampler3DDraw)4565 TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
4566 {
4567     glActiveTexture(GL_TEXTURE0);
4568     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4569     GLubyte texData[4];
4570     texData[0] = 0;
4571     texData[1] = 60;
4572     texData[2] = 0;
4573     texData[3] = 255;
4574     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
4575 
4576     glActiveTexture(GL_TEXTURE1);
4577     glBindTexture(GL_TEXTURE_2D, mTextureShadow);
4578     GLfloat depthTexData[1];
4579     depthTexData[0] = 0.5f;
4580     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
4581                  depthTexData);
4582 
4583     glUseProgram(mProgram);
4584     glUniform1f(mDepthRefUniformLocation, 0.3f);
4585     glUniform1i(mTexture3DUniformLocation, 0);
4586     glUniform1i(mTextureShadowUniformLocation, 1);
4587 
4588     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
4589     drawQuad(mProgram, "position", 0.5f);
4590     EXPECT_GL_NO_ERROR();
4591     // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
4592     EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
4593 
4594     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
4595     drawQuad(mProgram, "position", 0.5f);
4596     EXPECT_GL_NO_ERROR();
4597     // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
4598     EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
4599 }
4600 
4601 // Test multiple different sampler types in the same shader.
4602 // This test makes sure that even if sampler / texture registers get grouped together based on type
4603 // or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
4604 // still has the right register index information for each ESSL sampler.
4605 // The tested ESSL samplers have the following types in D3D11 HLSL:
4606 // sampler2D:         Texture2D   + SamplerState
4607 // samplerCube:       TextureCube + SamplerState
4608 // sampler2DShadow:   Texture2D   + SamplerComparisonState
4609 // samplerCubeShadow: TextureCube + SamplerComparisonState
TEST_P(SamplerTypeMixTestES3,SamplerTypeMixDraw)4610 TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
4611 {
4612     glActiveTexture(GL_TEXTURE0);
4613     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4614     GLubyte texData[4];
4615     texData[0] = 0;
4616     texData[1] = 0;
4617     texData[2] = 120;
4618     texData[3] = 255;
4619     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
4620 
4621     glActiveTexture(GL_TEXTURE1);
4622     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
4623     texData[0] = 0;
4624     texData[1] = 90;
4625     texData[2] = 0;
4626     texData[3] = 255;
4627     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
4628     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
4629                     texData);
4630 
4631     glActiveTexture(GL_TEXTURE2);
4632     glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
4633     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
4634     GLfloat depthTexData[1];
4635     depthTexData[0] = 0.5f;
4636     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
4637                  depthTexData);
4638 
4639     glActiveTexture(GL_TEXTURE3);
4640     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
4641     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
4642     depthTexData[0] = 0.2f;
4643     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
4644     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
4645                     depthTexData);
4646 
4647     // http://anglebug.com/3949: TODO: Add a DS texture case
4648 
4649     EXPECT_GL_NO_ERROR();
4650 
4651     glUseProgram(mProgram);
4652     glUniform1f(mDepthRefUniformLocation, 0.3f);
4653     glUniform1i(mTexture2DUniformLocation, 0);
4654     glUniform1i(mTextureCubeUniformLocation, 1);
4655     glUniform1i(mTexture2DShadowUniformLocation, 2);
4656     glUniform1i(mTextureCubeShadowUniformLocation, 3);
4657 
4658     drawQuad(mProgram, "position", 0.5f);
4659     EXPECT_GL_NO_ERROR();
4660     // The shader writes:
4661     // <texture 2d color> +
4662     // <cube map color> +
4663     // 0.25 * <comparison result (1.0)> +
4664     // 0.125 * <comparison result (0.0)>
4665     EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
4666 }
4667 
4668 // Test different base levels on textures accessed through the same sampler array.
4669 // Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
TEST_P(TextureSizeTextureArrayTest,BaseLevelVariesInTextureArray)4670 TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
4671 {
4672     ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
4673 
4674     // http://anglebug.com/4391
4675     ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
4676 
4677     glActiveTexture(GL_TEXTURE0);
4678     glBindTexture(GL_TEXTURE_2D, mTexture2DA);
4679     GLsizei size = 64;
4680     for (GLint level = 0; level < 7; ++level)
4681     {
4682         ASSERT_LT(0, size);
4683         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4684                      nullptr);
4685         size = size / 2;
4686     }
4687     ASSERT_EQ(0, size);
4688     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4689 
4690     glActiveTexture(GL_TEXTURE1);
4691     glBindTexture(GL_TEXTURE_2D, mTexture2DB);
4692     size = 128;
4693     for (GLint level = 0; level < 8; ++level)
4694     {
4695         ASSERT_LT(0, size);
4696         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4697                      nullptr);
4698         size = size / 2;
4699     }
4700     ASSERT_EQ(0, size);
4701     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
4702     EXPECT_GL_NO_ERROR();
4703 
4704     glUseProgram(mProgram);
4705     glUniform1i(mTexture0Location, 0);
4706     glUniform1i(mTexture1Location, 1);
4707 
4708     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4709     EXPECT_GL_NO_ERROR();
4710     // Red channel: width of level 1 of texture A: 32.
4711     // Green channel: width of level 3 of texture B: 16.
4712     EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
4713 }
4714 
4715 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4716 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBImplicitAlpha1)4717 TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
4718 {
4719     glActiveTexture(GL_TEXTURE0);
4720     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4721     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
4722     EXPECT_GL_NO_ERROR();
4723 
4724     drawQuad(mProgram, "position", 0.5f);
4725 
4726     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4727 }
4728 
4729 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4730 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminanceImplicitAlpha1)4731 TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
4732 {
4733     setUpProgram();
4734 
4735     glActiveTexture(GL_TEXTURE0);
4736     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4737     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
4738     EXPECT_GL_NO_ERROR();
4739 
4740     drawQuad(mProgram, "position", 0.5f);
4741 
4742     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4743 }
4744 
4745 // Validate that every component of the pixel will be equal to the luminance value we've set
4746 // and that the alpha channel will be 1 (or 255 to be exact).
TEST_P(Texture2DTest,TextureLuminanceRGBSame)4747 TEST_P(Texture2DTest, TextureLuminanceRGBSame)
4748 {
4749     setUpProgram();
4750 
4751     glActiveTexture(GL_TEXTURE0);
4752     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4753     uint8_t pixel = 50;
4754     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
4755     EXPECT_GL_NO_ERROR();
4756 
4757     drawQuad(mProgram, "position", 0.5f);
4758 
4759     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
4760 }
4761 
4762 // Validate that every component of the pixel will be equal to the luminance value we've set
4763 // and that the alpha channel will be the second component.
TEST_P(Texture2DTest,TextureLuminanceAlphaRGBSame)4764 TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
4765 {
4766     setUpProgram();
4767 
4768     glActiveTexture(GL_TEXTURE0);
4769     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4770     uint8_t pixel[] = {50, 25};
4771     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
4772                  GL_UNSIGNED_BYTE, pixel);
4773     EXPECT_GL_NO_ERROR();
4774 
4775     drawQuad(mProgram, "position", 0.5f);
4776 
4777     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
4778 }
4779 
4780 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4781 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance32ImplicitAlpha1)4782 TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
4783 {
4784     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4785     ANGLE_SKIP_TEST_IF(IsD3D9());
4786     ANGLE_SKIP_TEST_IF(IsVulkan());
4787 
4788     setUpProgram();
4789 
4790     glActiveTexture(GL_TEXTURE0);
4791     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4792     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
4793     EXPECT_GL_NO_ERROR();
4794 
4795     drawQuad(mProgram, "position", 0.5f);
4796 
4797     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4798 }
4799 
4800 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4801 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance16ImplicitAlpha1)4802 TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
4803 {
4804     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4805     ANGLE_SKIP_TEST_IF(IsD3D9());
4806     ANGLE_SKIP_TEST_IF(IsVulkan());
4807     // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
4808     ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
4809 
4810     setUpProgram();
4811 
4812     glActiveTexture(GL_TEXTURE0);
4813     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4814     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
4815     EXPECT_GL_NO_ERROR();
4816 
4817     drawQuad(mProgram, "position", 0.5f);
4818 
4819     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4820 }
4821 
4822 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4823 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB8UIImplicitAlpha1)4824 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
4825 {
4826     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
4827 
4828     glActiveTexture(GL_TEXTURE0);
4829     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4830     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
4831     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4832     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4833     EXPECT_GL_NO_ERROR();
4834 
4835     drawQuad(mProgram, "position", 0.5f);
4836 
4837     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4838 }
4839 
4840 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4841 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB8IImplicitAlpha1)4842 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
4843 {
4844     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
4845 
4846     glActiveTexture(GL_TEXTURE0);
4847     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4848 
4849     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
4850     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4851     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4852     EXPECT_GL_NO_ERROR();
4853 
4854     drawQuad(mProgram, "position", 0.5f);
4855 
4856     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4857 }
4858 
4859 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4860 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB16UIImplicitAlpha1)4861 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
4862 {
4863     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
4864 
4865     glActiveTexture(GL_TEXTURE0);
4866     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4867     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
4868     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4869     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4870     EXPECT_GL_NO_ERROR();
4871 
4872     drawQuad(mProgram, "position", 0.5f);
4873 
4874     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4875 }
4876 
4877 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4878 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB16IImplicitAlpha1)4879 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
4880 {
4881     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
4882 
4883     glActiveTexture(GL_TEXTURE0);
4884     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4885     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
4886     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4887     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4888     EXPECT_GL_NO_ERROR();
4889 
4890     drawQuad(mProgram, "position", 0.5f);
4891 
4892     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4893 }
4894 
4895 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4896 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB32UIImplicitAlpha1)4897 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
4898 {
4899     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
4900 
4901     glActiveTexture(GL_TEXTURE0);
4902     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4903     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
4904     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4905     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4906     EXPECT_GL_NO_ERROR();
4907 
4908     drawQuad(mProgram, "position", 0.5f);
4909 
4910     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4911 }
4912 
4913 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4914 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB32IImplicitAlpha1)4915 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
4916 {
4917     ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
4918 
4919     glActiveTexture(GL_TEXTURE0);
4920     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4921     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
4922     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4923     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4924     EXPECT_GL_NO_ERROR();
4925 
4926     drawQuad(mProgram, "position", 0.5f);
4927 
4928     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4929 }
4930 
4931 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4932 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBSNORMImplicitAlpha1)4933 TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
4934 {
4935     glActiveTexture(GL_TEXTURE0);
4936     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4937     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
4938     EXPECT_GL_NO_ERROR();
4939 
4940     drawQuad(mProgram, "position", 0.5f);
4941 
4942     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4943 }
4944 
4945 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4946 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGB9E5ImplicitAlpha1)4947 TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
4948 {
4949     glActiveTexture(GL_TEXTURE0);
4950     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4951     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
4952                  nullptr);
4953     EXPECT_GL_NO_ERROR();
4954 
4955     drawQuad(mProgram, "position", 0.5f);
4956 
4957     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4958 }
4959 
4960 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4961 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)4962 TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
4963 {
4964     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
4965     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
4966 
4967     // http://anglebug.com/5187
4968     ANGLE_SKIP_TEST_IF(IsOSX() && IsMetal());
4969 
4970     glActiveTexture(GL_TEXTURE0);
4971     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4972     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
4973     EXPECT_GL_NO_ERROR();
4974 
4975     drawQuad(mProgram, "position", 0.5f);
4976 
4977     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4978 }
4979 
4980 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
4981 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)4982 TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
4983 {
4984     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
4985     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
4986 
4987     // http://anglebug.com/5187
4988     ANGLE_SKIP_TEST_IF(IsOSX() && IsMetal());
4989 
4990     glActiveTexture(GL_TEXTURE0);
4991     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4992     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
4993     EXPECT_GL_NO_ERROR();
4994 
4995     drawQuad(mProgram, "position", 0.5f);
4996 
4997     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
4998 }
4999 
5000 // Copied from Texture2DTest::TexStorage
5001 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
5002 // default color.
TEST_P(Texture2DTestES31PPO,TexStorage)5003 TEST_P(Texture2DTestES31PPO, TexStorage)
5004 {
5005     ANGLE_SKIP_TEST_IF(!IsVulkan());
5006     ANGLE_SKIP_TEST_IF((getClientMajorVersion() < 3 && getClientMinorVersion() < 1) &&
5007                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
5008 
5009     const char *vertexShaderSource   = getVertexShaderSource();
5010     const char *fragmentShaderSource = getFragmentShaderSource();
5011 
5012     bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
5013     mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
5014 
5015     int width  = getWindowWidth();
5016     int height = getWindowHeight();
5017 
5018     GLuint tex2D;
5019     glGenTextures(1, &tex2D);
5020     glActiveTexture(GL_TEXTURE0);
5021     glBindTexture(GL_TEXTURE_2D, tex2D);
5022 
5023     // Fill with red
5024     std::vector<GLubyte> pixels(3 * 16 * 16);
5025     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
5026     {
5027         pixels[pixelId * 3 + 0] = 255;
5028         pixels[pixelId * 3 + 1] = 0;
5029         pixels[pixelId * 3 + 2] = 0;
5030     }
5031 
5032     // ANGLE internally uses RGBA as the internal format for RGB images, therefore glTexStorage2DEXT
5033     // initializes the image to a default color to get a consistent alpha color. The data is kept in
5034     // a CPU-side image and the image is marked as dirty.
5035     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
5036 
5037     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
5038     // glTexSubImage2D should take into account that the image is dirty.
5039     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
5040     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5041     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5042 
5043     glActiveShaderProgram(mPipeline, mFragProg);
5044     glUniform1i(mTexture2DUniformLocation, 0);
5045 
5046     std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
5047     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
5048 
5049     glDeleteTextures(1, &tex2D);
5050     EXPECT_GL_NO_ERROR();
5051     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
5052 
5053     // Validate that the region of the texture without data has an alpha of 1.0
5054     angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
5055     EXPECT_EQ(255, pixel.A);
5056 }
5057 
5058 // Copied from Texture2DTestES3::SingleTextureMultipleSamplers
5059 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES31PPO,SingleTextureMultipleSamplers)5060 TEST_P(Texture2DTestES31PPO, SingleTextureMultipleSamplers)
5061 {
5062     ANGLE_SKIP_TEST_IF(!IsVulkan());
5063 
5064     const char *vertexShaderSource   = getVertexShaderSource();
5065     const char *fragmentShaderSource = getFragmentShaderSource();
5066 
5067     bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
5068     mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
5069 
5070     GLint maxTextureUnits = 0;
5071     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
5072     ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
5073 
5074     constexpr int kSize                 = 16;
5075     std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
5076 
5077     // Make a single-level texture, fill it with red.
5078     std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
5079     GLTexture tex;
5080     glBindTexture(GL_TEXTURE_2D, tex);
5081     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5082                  redColors.data());
5083     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5084     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5085 
5086     // Simple confidence check.
5087     bind2DTexturedQuadProgramPipeline();
5088     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
5089     ASSERT_GL_NO_ERROR();
5090     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5091 
5092     // Bind texture to unit 1 with a sampler object making it incomplete.
5093     GLSampler sampler;
5094     glBindSampler(0, sampler);
5095     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5096     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5097 
5098     // Make a mipmap texture, fill it with blue.
5099     std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
5100     GLTexture mipmapTex;
5101     glBindTexture(GL_TEXTURE_2D, mipmapTex);
5102     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5103                  blueColors.data());
5104     glGenerateMipmap(GL_TEXTURE_2D);
5105 
5106     // Draw with the sampler, expect blue.
5107     draw2DTexturedQuad(0.5f, 1.0f, true);
5108     ASSERT_GL_NO_ERROR();
5109     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5110 
5111     // Simple multitexturing program.
5112     constexpr char kVS[] =
5113         "#version 310 es\n"
5114         "precision mediump float;\n"
5115         "in vec2 position;\n"
5116         "out vec2 texCoord;\n"
5117         "void main()\n"
5118         "{\n"
5119         "    gl_Position = vec4(position, 0, 1);\n"
5120         "    texCoord = position * 0.5 + vec2(0.5);\n"
5121         "}";
5122 
5123     constexpr char kFS[] =
5124         "#version 310 es\n"
5125         "precision mediump float;\n"
5126         "in vec2 texCoord;\n"
5127         "uniform sampler2D tex1;\n"
5128         "uniform sampler2D tex2;\n"
5129         "uniform sampler2D tex3;\n"
5130         "uniform sampler2D tex4;\n"
5131         "out vec4 color;\n"
5132         "void main()\n"
5133         "{\n"
5134         "    color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
5135         "          +  texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
5136         "}";
5137 
5138     bindProgramPipeline(kVS, kFS);
5139 
5140     std::array<GLint, 4> texLocations = {
5141         {glGetUniformLocation(mFragProg, "tex1"), glGetUniformLocation(mFragProg, "tex2"),
5142          glGetUniformLocation(mFragProg, "tex3"), glGetUniformLocation(mFragProg, "tex4")}};
5143     for (GLint location : texLocations)
5144     {
5145         ASSERT_NE(-1, location);
5146     }
5147 
5148     // Init the uniform data.
5149     glActiveShaderProgram(mPipeline, mFragProg);
5150     for (GLint location = 0; location < 4; ++location)
5151     {
5152         glUniform1i(texLocations[location], location);
5153     }
5154 
5155     // Initialize four samplers
5156     GLSampler samplers[4];
5157 
5158     // 0: non-mipped.
5159     glBindSampler(0, samplers[0]);
5160     glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5161     glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5162 
5163     // 1: mipped.
5164     glBindSampler(1, samplers[1]);
5165     glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5166     glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5167 
5168     // 2: non-mipped.
5169     glBindSampler(2, samplers[2]);
5170     glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5171     glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5172 
5173     // 3: mipped.
5174     glBindSampler(3, samplers[3]);
5175     glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5176     glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5177 
5178     // Bind two blue mipped textures and two single layer textures, should all draw.
5179     glActiveTexture(GL_TEXTURE0);
5180     glBindTexture(GL_TEXTURE_2D, tex);
5181 
5182     glActiveTexture(GL_TEXTURE1);
5183     glBindTexture(GL_TEXTURE_2D, mipmapTex);
5184 
5185     glActiveTexture(GL_TEXTURE2);
5186     glBindTexture(GL_TEXTURE_2D, tex);
5187 
5188     glActiveTexture(GL_TEXTURE3);
5189     glBindTexture(GL_TEXTURE_2D, mipmapTex);
5190 
5191     ASSERT_GL_NO_ERROR();
5192 
5193     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
5194     ASSERT_GL_NO_ERROR();
5195     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
5196 
5197     // Bind four single layer textures, two should be incomplete.
5198     glActiveTexture(GL_TEXTURE1);
5199     glBindTexture(GL_TEXTURE_2D, tex);
5200 
5201     glActiveTexture(GL_TEXTURE3);
5202     glBindTexture(GL_TEXTURE_2D, tex);
5203 
5204     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
5205     ASSERT_GL_NO_ERROR();
5206     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
5207 }
5208 
5209 // Use a sampler in a uniform struct.
TEST_P(SamplerInStructTest,SamplerInStruct)5210 TEST_P(SamplerInStructTest, SamplerInStruct)
5211 {
5212     runSamplerInStructTest();
5213 }
5214 
5215 // Use a sampler in a uniform struct that's passed as a function parameter.
TEST_P(SamplerInStructAsFunctionParameterTest,SamplerInStructAsFunctionParameter)5216 TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
5217 {
5218     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
5219     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
5220 
5221     runSamplerInStructTest();
5222 }
5223 
5224 // Use a sampler in a uniform struct array with a struct from the array passed as a function
5225 // parameter.
TEST_P(SamplerInStructArrayAsFunctionParameterTest,SamplerInStructArrayAsFunctionParameter)5226 TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
5227 {
5228     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
5229     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
5230 
5231     runSamplerInStructTest();
5232 }
5233 
5234 // Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
5235 // parameter.
TEST_P(SamplerInNestedStructAsFunctionParameterTest,SamplerInNestedStructAsFunctionParameter)5236 TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
5237 {
5238     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
5239     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
5240 
5241     runSamplerInStructTest();
5242 }
5243 
5244 // Make sure that there isn't a name conflict between sampler extracted from a struct and a
5245 // similarly named uniform.
TEST_P(SamplerInStructAndOtherVariableTest,SamplerInStructAndOtherVariable)5246 TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
5247 {
5248     runSamplerInStructTest();
5249 }
5250 
5251 // GL_EXT_texture_filter_anisotropic
5252 class TextureAnisotropyTest : public Texture2DTest
5253 {
5254   protected:
uploadTexture()5255     void uploadTexture()
5256     {
5257         glActiveTexture(GL_TEXTURE0);
5258         glBindTexture(GL_TEXTURE_2D, mTexture2D);
5259         GLColor texDataRed[1] = {GLColor::red};
5260         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
5261         EXPECT_GL_NO_ERROR();
5262     }
5263 };
5264 
5265 // Tests that setting anisotropic filtering doesn't cause failures at draw time.
TEST_P(TextureAnisotropyTest,AnisotropyFunctional)5266 TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
5267 {
5268     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
5269 
5270     setUpProgram();
5271 
5272     uploadTexture();
5273 
5274     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5275     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5276     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
5277     EXPECT_GL_NO_ERROR();
5278 
5279     drawQuad(mProgram, "position", 0.5f);
5280 
5281     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5282     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5283     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
5284 }
5285 
5286 // GL_OES_texture_border_clamp
5287 class TextureBorderClampTest : public Texture2DTest
5288 {
5289   protected:
TextureBorderClampTest()5290     TextureBorderClampTest() : Texture2DTest() {}
5291 
getVertexShaderSource()5292     const char *getVertexShaderSource() override
5293     {
5294         return
5295             R"(precision highp float;
5296             attribute vec4 position;
5297             varying vec2 texcoord;
5298 
5299             void main()
5300             {
5301                 gl_Position = vec4(position.xy, 0.0, 1.0);
5302                 // texcoords in [-0.5, 1.5]
5303                 texcoord = (position.xy) + 0.5;
5304             })";
5305     }
5306 
uploadTexture()5307     void uploadTexture()
5308     {
5309         glActiveTexture(GL_TEXTURE0);
5310         glBindTexture(GL_TEXTURE_2D, mTexture2D);
5311         std::vector<GLColor> texDataRed(1, GLColor::red);
5312         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5313                      texDataRed.data());
5314         EXPECT_GL_NO_ERROR();
5315     }
5316 };
5317 
5318 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
5319 // GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional)5320 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
5321 {
5322     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5323 
5324     setUpProgram();
5325 
5326     uploadTexture();
5327 
5328     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
5329     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
5330     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5331     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5332     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
5333     EXPECT_GL_NO_ERROR();
5334 
5335     drawQuad(mProgram, "position", 0.5f);
5336 
5337     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5338     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5339     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
5340 }
5341 
5342 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional2)5343 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
5344 {
5345     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5346 
5347     glActiveTexture(GL_TEXTURE0);
5348     glBindTexture(GL_TEXTURE_2D, mTexture2D);
5349 
5350     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
5351 
5352     GLint colorFixedPoint[4] = {0};
5353     glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
5354     constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
5355                                                std::numeric_limits<GLint>::max()};
5356     EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
5357     EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
5358     EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
5359     EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
5360 
5361     constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
5362                                               std::numeric_limits<GLint>::max()};
5363     glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
5364 
5365     GLfloat color[4] = {0.0f};
5366     glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
5367     EXPECT_EQ(color[0], kFloatBlue.R);
5368     EXPECT_EQ(color[1], kFloatBlue.G);
5369     EXPECT_EQ(color[2], kFloatBlue.B);
5370     EXPECT_EQ(color[3], kFloatBlue.A);
5371 }
5372 
5373 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampValidation)5374 TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
5375 {
5376     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5377 
5378     glActiveTexture(GL_TEXTURE0);
5379     glBindTexture(GL_TEXTURE_2D, mTexture2D);
5380 
5381     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
5382     EXPECT_GL_ERROR(GL_INVALID_ENUM);
5383 
5384     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
5385     EXPECT_GL_ERROR(GL_INVALID_ENUM);
5386 
5387     glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
5388     EXPECT_GL_ERROR(GL_INVALID_ENUM);
5389 
5390     GLint colorInt[4] = {0};
5391     glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
5392     EXPECT_GL_ERROR(GL_INVALID_ENUM);
5393 
5394     if (getClientMajorVersion() < 3)
5395     {
5396         glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
5397         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5398         glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
5399         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5400 
5401         GLuint colorUInt[4] = {0};
5402         glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
5403         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5404         glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
5405         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5406 
5407         GLSampler sampler;
5408         glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
5409         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5410         glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
5411         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5412 
5413         glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
5414         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5415         glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
5416         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5417     }
5418 }
5419 
5420 class TextureBorderClampTestES3 : public TextureBorderClampTest
5421 {
5422   protected:
TextureBorderClampTestES3()5423     TextureBorderClampTestES3() : TextureBorderClampTest() {}
5424 };
5425 
5426 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
5427 // GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional)5428 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
5429 {
5430     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5431 
5432     setUpProgram();
5433 
5434     uploadTexture();
5435 
5436     GLSampler sampler;
5437     glBindSampler(0, sampler);
5438     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
5439     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
5440     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5441     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5442     glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
5443     EXPECT_GL_NO_ERROR();
5444 
5445     drawQuad(mProgram, "position", 0.5f);
5446 
5447     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5448     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5449     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
5450 }
5451 
5452 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional2)5453 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
5454 {
5455     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5456 
5457     glActiveTexture(GL_TEXTURE0);
5458 
5459     GLSampler sampler;
5460     glBindSampler(0, sampler);
5461 
5462     glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
5463 
5464     GLint colorFixedPoint[4] = {0};
5465     glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
5466     constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
5467                                                std::numeric_limits<GLint>::max()};
5468     EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
5469     EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
5470     EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
5471     EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
5472 
5473     constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
5474                                               std::numeric_limits<GLint>::max()};
5475     glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
5476 
5477     GLfloat color[4] = {0.0f};
5478     glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
5479     EXPECT_EQ(color[0], kFloatBlue.R);
5480     EXPECT_EQ(color[1], kFloatBlue.G);
5481     EXPECT_EQ(color[2], kFloatBlue.B);
5482     EXPECT_EQ(color[3], kFloatBlue.A);
5483 
5484     constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
5485     glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
5486     GLint colorInt[4] = {0};
5487     glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
5488     EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
5489     EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
5490     EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
5491     EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
5492 
5493     constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
5494     glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
5495     GLuint colorUInt[4] = {0};
5496     glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
5497     EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
5498     EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
5499     EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
5500     EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
5501 
5502     glBindTexture(GL_TEXTURE_2D, mTexture2D);
5503 
5504     constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
5505     glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
5506     glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
5507     EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
5508     EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
5509     EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
5510     EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
5511 
5512     constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
5513     glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
5514     glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
5515     EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
5516     EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
5517     EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
5518     EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
5519 }
5520 
5521 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Validation)5522 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
5523 {
5524     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5525 
5526     glActiveTexture(GL_TEXTURE0);
5527 
5528     GLSampler sampler;
5529     glBindSampler(0, sampler);
5530 
5531     glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
5532     EXPECT_GL_ERROR(GL_INVALID_ENUM);
5533 
5534     glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
5535     EXPECT_GL_ERROR(GL_INVALID_ENUM);
5536 }
5537 
5538 class TextureBorderClampIntegerTestES3 : public Texture2DTest
5539 {
5540   protected:
TextureBorderClampIntegerTestES3()5541     TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
5542 
getVertexShaderSource()5543     const char *getVertexShaderSource() override
5544     {
5545         return
5546             R"(#version 300 es
5547             out vec2 texcoord;
5548             in vec4 position;
5549 
5550             void main()
5551             {
5552                 gl_Position = vec4(position.xy, 0.0, 1.0);
5553                 // texcoords in [-0.5, 1.5]
5554                 texcoord = (position.xy) + 0.5;
5555             })";
5556     }
5557 
getFragmentShaderSource()5558     const char *getFragmentShaderSource() override
5559     {
5560         if (isUnsignedIntTest)
5561         {
5562             return "#version 300 es\n"
5563                    "precision highp float;\n"
5564                    "uniform highp usampler2D tex;\n"
5565                    "in vec2 texcoord;\n"
5566                    "out vec4 fragColor;\n"
5567 
5568                    "void main()\n"
5569                    "{\n"
5570                    "vec4 red   = vec4(1.0, 0.0, 0.0, 1.0);\n"
5571                    "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
5572                    "fragColor = (texture(tex, texcoord).r == 150u)"
5573                    "            ? green : red;\n"
5574                    "}\n";
5575         }
5576         else
5577         {
5578             return "#version 300 es\n"
5579                    "precision highp float;\n"
5580                    "uniform highp isampler2D tex;\n"
5581                    "in vec2 texcoord;\n"
5582                    "out vec4 fragColor;\n"
5583 
5584                    "void main()\n"
5585                    "{\n"
5586                    "vec4 red   = vec4(1.0, 0.0, 0.0, 1.0);\n"
5587                    "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
5588                    "fragColor = (texture(tex, texcoord).r == -50)"
5589                    "            ? green : red;\n"
5590                    "}\n";
5591         }
5592     }
5593 
uploadTexture()5594     void uploadTexture()
5595     {
5596         glActiveTexture(GL_TEXTURE0);
5597         glBindTexture(GL_TEXTURE_2D, mTexture2D);
5598         if (isUnsignedIntTest)
5599         {
5600             std::vector<GLubyte> texData(4, 100);
5601             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
5602                          texData.data());
5603         }
5604         else
5605         {
5606             std::vector<GLbyte> texData(4, 100);
5607             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
5608                          texData.data());
5609         }
5610         EXPECT_GL_NO_ERROR();
5611     }
5612 
5613     bool isUnsignedIntTest;
5614 };
5615 
5616 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
5617 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger)5618 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
5619 {
5620     // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
5621     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5622 
5623     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5624 
5625     setUpProgram();
5626 
5627     uploadTexture();
5628 
5629     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
5630     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
5631     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5632     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5633 
5634     constexpr GLint borderColor[4] = {-50, -50, -50, -50};
5635     glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
5636 
5637     EXPECT_GL_NO_ERROR();
5638 
5639     drawQuad(mProgram, "position", 0.5f);
5640 
5641     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5642     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5643     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
5644 }
5645 
5646 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
5647 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger2)5648 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
5649 {
5650     // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
5651     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5652 
5653     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5654 
5655     setUpProgram();
5656 
5657     uploadTexture();
5658 
5659     GLSampler sampler;
5660     glBindSampler(0, sampler);
5661     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
5662     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
5663     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5664     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5665 
5666     constexpr GLint borderColor[4] = {-50, -50, -50, -50};
5667     glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
5668 
5669     EXPECT_GL_NO_ERROR();
5670 
5671     drawQuad(mProgram, "position", 0.5f);
5672 
5673     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5674     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5675     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
5676 }
5677 
5678 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
5679 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned)5680 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
5681 {
5682     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5683 
5684     isUnsignedIntTest = true;
5685 
5686     setUpProgram();
5687 
5688     uploadTexture();
5689 
5690     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
5691     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
5692     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5693     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5694 
5695     constexpr GLuint borderColor[4] = {150, 150, 150, 150};
5696     glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
5697 
5698     EXPECT_GL_NO_ERROR();
5699 
5700     drawQuad(mProgram, "position", 0.5f);
5701 
5702     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5703     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5704     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
5705 }
5706 
5707 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
5708 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
5709 // glSamplerParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned2)5710 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
5711 {
5712     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
5713 
5714     isUnsignedIntTest = true;
5715 
5716     setUpProgram();
5717 
5718     uploadTexture();
5719 
5720     GLSampler sampler;
5721     glBindSampler(0, sampler);
5722     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
5723     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
5724     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5725     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5726 
5727     constexpr GLuint borderColor[4] = {150, 150, 150, 150};
5728     glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
5729 
5730     EXPECT_GL_NO_ERROR();
5731 
5732     drawQuad(mProgram, "position", 0.5f);
5733 
5734     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5735     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5736     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
5737 }
5738 
5739 // ~GL_OES_texture_border_clamp
5740 
5741 class TextureLimitsTest : public ANGLETest
5742 {
5743   protected:
5744     struct RGBA8
5745     {
5746         uint8_t R, G, B, A;
5747     };
5748 
TextureLimitsTest()5749     TextureLimitsTest()
5750         : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
5751     {
5752         setWindowWidth(128);
5753         setWindowHeight(128);
5754         setConfigRedBits(8);
5755         setConfigGreenBits(8);
5756         setConfigBlueBits(8);
5757         setConfigAlphaBits(8);
5758     }
5759 
testSetUp()5760     void testSetUp() override
5761     {
5762         glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
5763         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
5764         glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
5765 
5766         ASSERT_GL_NO_ERROR();
5767     }
5768 
testTearDown()5769     void testTearDown() override
5770     {
5771         if (mProgram != 0)
5772         {
5773             glDeleteProgram(mProgram);
5774             mProgram = 0;
5775 
5776             if (!mTextures.empty())
5777             {
5778                 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
5779             }
5780         }
5781     }
5782 
compileProgramWithTextureCounts(const std::string & vertexPrefix,GLint vertexTextureCount,GLint vertexActiveTextureCount,const std::string & fragPrefix,GLint fragmentTextureCount,GLint fragmentActiveTextureCount)5783     void compileProgramWithTextureCounts(const std::string &vertexPrefix,
5784                                          GLint vertexTextureCount,
5785                                          GLint vertexActiveTextureCount,
5786                                          const std::string &fragPrefix,
5787                                          GLint fragmentTextureCount,
5788                                          GLint fragmentActiveTextureCount)
5789     {
5790         std::stringstream vertexShaderStr;
5791         vertexShaderStr << "attribute vec2 position;\n"
5792                         << "varying vec4 color;\n"
5793                         << "varying vec2 texCoord;\n";
5794 
5795         for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
5796         {
5797             vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
5798         }
5799 
5800         vertexShaderStr << "void main() {\n"
5801                         << "  gl_Position = vec4(position, 0, 1);\n"
5802                         << "  texCoord = (position * 0.5) + 0.5;\n"
5803                         << "  color = vec4(0);\n";
5804 
5805         for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
5806         {
5807             vertexShaderStr << "  color += texture2D(" << vertexPrefix << textureIndex
5808                             << ", texCoord);\n";
5809         }
5810 
5811         vertexShaderStr << "}";
5812 
5813         std::stringstream fragmentShaderStr;
5814         fragmentShaderStr << "varying mediump vec4 color;\n"
5815                           << "varying mediump vec2 texCoord;\n";
5816 
5817         for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
5818         {
5819             fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
5820         }
5821 
5822         fragmentShaderStr << "void main() {\n"
5823                           << "  gl_FragColor = color;\n";
5824 
5825         for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
5826         {
5827             fragmentShaderStr << "  gl_FragColor += texture2D(" << fragPrefix << textureIndex
5828                               << ", texCoord);\n";
5829         }
5830 
5831         fragmentShaderStr << "}";
5832 
5833         const std::string &vertexShaderSource   = vertexShaderStr.str();
5834         const std::string &fragmentShaderSource = fragmentShaderStr.str();
5835 
5836         mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
5837     }
5838 
getPixel(GLint texIndex)5839     RGBA8 getPixel(GLint texIndex)
5840     {
5841         RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
5842                        0, 255u};
5843         return pixel;
5844     }
5845 
initTextures(GLint tex2DCount,GLint texCubeCount)5846     void initTextures(GLint tex2DCount, GLint texCubeCount)
5847     {
5848         GLint totalCount = tex2DCount + texCubeCount;
5849         mTextures.assign(totalCount, 0);
5850         glGenTextures(totalCount, &mTextures[0]);
5851         ASSERT_GL_NO_ERROR();
5852 
5853         std::vector<RGBA8> texData(16 * 16);
5854 
5855         GLint texIndex = 0;
5856         for (; texIndex < tex2DCount; ++texIndex)
5857         {
5858             texData.assign(texData.size(), getPixel(texIndex));
5859             glActiveTexture(GL_TEXTURE0 + texIndex);
5860             glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
5861             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5862                          &texData[0]);
5863             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5864             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5865             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5866             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5867         }
5868 
5869         ASSERT_GL_NO_ERROR();
5870 
5871         for (; texIndex < texCubeCount; ++texIndex)
5872         {
5873             texData.assign(texData.size(), getPixel(texIndex));
5874             glActiveTexture(GL_TEXTURE0 + texIndex);
5875             glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
5876             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5877                          GL_UNSIGNED_BYTE, &texData[0]);
5878             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5879                          GL_UNSIGNED_BYTE, &texData[0]);
5880             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5881                          GL_UNSIGNED_BYTE, &texData[0]);
5882             glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5883                          GL_UNSIGNED_BYTE, &texData[0]);
5884             glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5885                          GL_UNSIGNED_BYTE, &texData[0]);
5886             glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5887                          GL_UNSIGNED_BYTE, &texData[0]);
5888             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5889             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5890             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5891             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5892         }
5893 
5894         ASSERT_GL_NO_ERROR();
5895     }
5896 
testWithTextures(GLint vertexTextureCount,const std::string & vertexTexturePrefix,GLint fragmentTextureCount,const std::string & fragmentTexturePrefix)5897     void testWithTextures(GLint vertexTextureCount,
5898                           const std::string &vertexTexturePrefix,
5899                           GLint fragmentTextureCount,
5900                           const std::string &fragmentTexturePrefix)
5901     {
5902         // Generate textures
5903         initTextures(vertexTextureCount + fragmentTextureCount, 0);
5904 
5905         glUseProgram(mProgram);
5906         RGBA8 expectedSum = {0};
5907         for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
5908         {
5909             std::stringstream uniformNameStr;
5910             uniformNameStr << vertexTexturePrefix << texIndex;
5911             const std::string &uniformName = uniformNameStr.str();
5912             GLint location                 = glGetUniformLocation(mProgram, uniformName.c_str());
5913             ASSERT_NE(-1, location);
5914 
5915             glUniform1i(location, texIndex);
5916             RGBA8 contribution = getPixel(texIndex);
5917             expectedSum.R += contribution.R;
5918             expectedSum.G += contribution.G;
5919         }
5920 
5921         for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
5922         {
5923             std::stringstream uniformNameStr;
5924             uniformNameStr << fragmentTexturePrefix << texIndex;
5925             const std::string &uniformName = uniformNameStr.str();
5926             GLint location                 = glGetUniformLocation(mProgram, uniformName.c_str());
5927             ASSERT_NE(-1, location);
5928 
5929             glUniform1i(location, texIndex + vertexTextureCount);
5930             RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
5931             expectedSum.R += contribution.R;
5932             expectedSum.G += contribution.G;
5933         }
5934 
5935         ASSERT_GE(256u, expectedSum.G);
5936 
5937         drawQuad(mProgram, "position", 0.5f);
5938         ASSERT_GL_NO_ERROR();
5939         EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
5940     }
5941 
5942     GLuint mProgram;
5943     std::vector<GLuint> mTextures;
5944     GLint mMaxVertexTextures;
5945     GLint mMaxFragmentTextures;
5946     GLint mMaxCombinedTextures;
5947 };
5948 
5949 // Test rendering with the maximum vertex texture units.
TEST_P(TextureLimitsTest,MaxVertexTextures)5950 TEST_P(TextureLimitsTest, MaxVertexTextures)
5951 {
5952     compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
5953     ASSERT_NE(0u, mProgram);
5954     ASSERT_GL_NO_ERROR();
5955 
5956     testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
5957 }
5958 
5959 // Test rendering with the maximum fragment texture units.
TEST_P(TextureLimitsTest,MaxFragmentTextures)5960 TEST_P(TextureLimitsTest, MaxFragmentTextures)
5961 {
5962     compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
5963     ASSERT_NE(0u, mProgram);
5964     ASSERT_GL_NO_ERROR();
5965 
5966     testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
5967 }
5968 
5969 // Test rendering with maximum combined texture units.
TEST_P(TextureLimitsTest,MaxCombinedTextures)5970 TEST_P(TextureLimitsTest, MaxCombinedTextures)
5971 {
5972     // TODO(timvp): http://anglebug.com/3570
5973     // max per-stage sampled image bindings count (32) exceeds device
5974     // maxPerStageDescriptorSampledImages limit (16)
5975     ANGLE_SKIP_TEST_IF(isSwiftshader());
5976 
5977     GLint vertexTextures = mMaxVertexTextures;
5978 
5979     if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
5980     {
5981         vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
5982     }
5983 
5984     compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
5985                                     mMaxFragmentTextures, mMaxFragmentTextures);
5986     ASSERT_NE(0u, mProgram);
5987     ASSERT_GL_NO_ERROR();
5988 
5989     testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
5990 }
5991 
5992 // Negative test for exceeding the number of vertex textures
TEST_P(TextureLimitsTest,ExcessiveVertexTextures)5993 TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
5994 {
5995     compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
5996                                     0);
5997     ASSERT_EQ(0u, mProgram);
5998 }
5999 
6000 // Negative test for exceeding the number of fragment textures
TEST_P(TextureLimitsTest,ExcessiveFragmentTextures)6001 TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
6002 {
6003     compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
6004                                     mMaxFragmentTextures + 1);
6005     ASSERT_EQ(0u, mProgram);
6006 }
6007 
6008 // Test active vertex textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveVertexTextures)6009 TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
6010 {
6011     compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
6012     ASSERT_NE(0u, mProgram);
6013     ASSERT_GL_NO_ERROR();
6014 
6015     testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
6016 }
6017 
6018 // Test active fragment textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveFragmentTextures)6019 TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
6020 {
6021     compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
6022                                     mMaxFragmentTextures);
6023     ASSERT_NE(0u, mProgram);
6024     ASSERT_GL_NO_ERROR();
6025 
6026     testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
6027 }
6028 
6029 // Negative test for pointing two sampler uniforms of different types to the same texture.
6030 // GLES 2.0.25 section 2.10.4 page 39.
TEST_P(TextureLimitsTest,TextureTypeConflict)6031 TEST_P(TextureLimitsTest, TextureTypeConflict)
6032 {
6033     constexpr char kVS[] =
6034         "attribute vec2 position;\n"
6035         "varying float color;\n"
6036         "uniform sampler2D tex2D;\n"
6037         "uniform samplerCube texCube;\n"
6038         "void main() {\n"
6039         "  gl_Position = vec4(position, 0, 1);\n"
6040         "  vec2 texCoord = (position * 0.5) + 0.5;\n"
6041         "  color = texture2D(tex2D, texCoord).x;\n"
6042         "  color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
6043         "}";
6044     constexpr char kFS[] =
6045         "varying mediump float color;\n"
6046         "void main() {\n"
6047         "  gl_FragColor = vec4(color, 0, 0, 1);\n"
6048         "}";
6049 
6050     mProgram = CompileProgram(kVS, kFS);
6051     ASSERT_NE(0u, mProgram);
6052 
6053     initTextures(1, 0);
6054 
6055     glUseProgram(mProgram);
6056     GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
6057     ASSERT_NE(-1, tex2DLocation);
6058     GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
6059     ASSERT_NE(-1, texCubeLocation);
6060 
6061     glUniform1i(tex2DLocation, 0);
6062     glUniform1i(texCubeLocation, 0);
6063     ASSERT_GL_NO_ERROR();
6064 
6065     drawQuad(mProgram, "position", 0.5f);
6066     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6067 }
6068 
6069 class Texture2DNorm16TestES3 : public Texture2DTestES3
6070 {
6071   protected:
Texture2DNorm16TestES3()6072     Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
6073 
testSetUp()6074     void testSetUp() override
6075     {
6076         Texture2DTestES3::testSetUp();
6077 
6078         glActiveTexture(GL_TEXTURE0);
6079         glGenTextures(3, mTextures);
6080         glGenFramebuffers(1, &mFBO);
6081         glGenRenderbuffers(1, &mRenderbuffer);
6082 
6083         for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
6084         {
6085             glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
6086             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6087             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6088         }
6089 
6090         glBindTexture(GL_TEXTURE_2D, 0);
6091 
6092         ASSERT_GL_NO_ERROR();
6093     }
6094 
testTearDown()6095     void testTearDown() override
6096     {
6097         glDeleteTextures(3, mTextures);
6098         glDeleteFramebuffers(1, &mFBO);
6099         glDeleteRenderbuffers(1, &mRenderbuffer);
6100 
6101         Texture2DTestES3::testTearDown();
6102     }
6103 
testNorm16Texture(GLint internalformat,GLenum format,GLenum type)6104     void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
6105     {
6106         // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
6107         ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
6108         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
6109 
6110         GLushort pixelValue  = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
6111         GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
6112 
6113         setUpProgram();
6114 
6115         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
6116         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
6117                                0);
6118 
6119         glBindTexture(GL_TEXTURE_2D, mTextures[0]);
6120         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
6121 
6122         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
6123         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
6124 
6125         EXPECT_GL_NO_ERROR();
6126 
6127         drawQuad(mProgram, "position", 0.5f);
6128 
6129         GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
6130 
6131         EXPECT_PIXEL_COLOR_EQ(0, 0,
6132                               SliceFormatColor(format, GLColor(expectedValue, expectedValue,
6133                                                                expectedValue, expectedValue)));
6134 
6135         glBindFramebuffer(GL_FRAMEBUFFER, 0);
6136 
6137         ASSERT_GL_NO_ERROR();
6138     }
6139 
testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,GLuint y,GLuint width,GLuint height,GLint packRowLength,GLint packAlignment,GLint packSkipPixels,GLint packSkipRows,GLenum type,GLColor16UI color)6140     void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
6141                                                       GLuint y,
6142                                                       GLuint width,
6143                                                       GLuint height,
6144                                                       GLint packRowLength,
6145                                                       GLint packAlignment,
6146                                                       GLint packSkipPixels,
6147                                                       GLint packSkipRows,
6148                                                       GLenum type,
6149                                                       GLColor16UI color)
6150     {
6151         // PACK modes debugging
6152         GLint s = 2;  // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
6153         GLint n = 4;  // 4 components per pixel, stands for GL_RGBA
6154 
6155         GLuint l       = packRowLength == 0 ? width : packRowLength;
6156         const GLint &a = packAlignment;
6157 
6158         // According to
6159         // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
6160         GLint k                    = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
6161         std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
6162         if (static_cast<GLuint>(packRowLength) < width)
6163         {
6164             componentCount += width * n * s - k;
6165         }
6166 
6167         // Populate the pixels array with random dirty value
6168         constexpr GLushort kDirtyValue = 0x1234;
6169         std::vector<GLushort> pixels(componentCount, kDirtyValue);
6170         glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
6171 
6172         EXPECT_GL_NO_ERROR();
6173 
6174         GLushort *pixelRowStart = pixels.data();
6175         pixelRowStart += n * packSkipPixels + k * packSkipRows;
6176 
6177         std::vector<bool> modifiedPixels(componentCount, false);
6178 
6179         char errorInfo[200];
6180 
6181         for (GLuint y = 0; y < height; ++y)
6182         {
6183             GLushort *curPixel = pixelRowStart;
6184             for (GLuint x = 0, len = (y == height - 1) ? width : std::min(l, width); x < len; ++x)
6185             {
6186                 snprintf(errorInfo, sizeof(errorInfo),
6187                          "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
6188                          "skipPixels: %d, skipRows: %d\n",
6189                          width, height, x, y, packRowLength, packAlignment, packSkipPixels,
6190                          packSkipRows);
6191                 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
6192                 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
6193                 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
6194                 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
6195 
6196                 std::ptrdiff_t diff      = curPixel - pixels.data();
6197                 modifiedPixels[diff + 0] = true;
6198                 modifiedPixels[diff + 1] = true;
6199                 modifiedPixels[diff + 2] = true;
6200                 modifiedPixels[diff + 3] = true;
6201 
6202                 curPixel += n;
6203             }
6204             pixelRowStart += k;
6205         }
6206 
6207         for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
6208         {
6209             if (!modifiedPixels[i])
6210             {
6211                 EXPECT_EQ(pixels[i], kDirtyValue);
6212             }
6213         }
6214     }
6215 
testNorm16RenderAndReadPixels(GLint internalformat,GLenum format,GLenum type)6216     void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
6217     {
6218         // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
6219         ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
6220         // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
6221         ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
6222         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
6223 
6224         GLushort pixelValue  = 0x6A35;
6225         GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
6226         GLColor16UI color    = SliceFormatColor16UI(
6227             format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
6228         // Size of drawing viewport
6229         constexpr GLint width = 8, height = 8;
6230 
6231         setUpProgram();
6232 
6233         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
6234         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
6235 
6236         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
6237         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
6238                                0);
6239 
6240         glBindTexture(GL_TEXTURE_2D, mTextures[2]);
6241         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
6242         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6243         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6244 
6245         EXPECT_GL_NO_ERROR();
6246 
6247         drawQuad(mProgram, "position", 0.5f);
6248 
6249         // ReadPixels against different width, height, pixel pack mode combinations to test
6250         // workaround of pixels rearrangement
6251 
6252         // {x, y, width, height}
6253         std::vector<std::array<GLint, 4>> areas = {
6254             {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
6255             {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
6256 
6257             {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
6258 
6259             {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
6260             {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
6261         };
6262 
6263         // Put default settings at the last
6264         std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
6265         std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
6266         std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1},   {1, 1},
6267                                                                          {3, 1}, {20, 20}, {0, 0}};
6268 
6269         // Restore pixel pack modes later
6270         GLint restorePackAlignment;
6271         glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
6272         GLint restorePackRowLength;
6273         glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
6274         GLint restorePackSkipPixels;
6275         glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
6276         GLint restorePackSkipRows;
6277         glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
6278 
6279         // Variable symbols are based on:
6280         // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
6281         for (const auto &skipped : paramsPackSkipPixelsAndRows)
6282         {
6283             glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
6284             glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
6285             for (GLint a : paramsPackAlignment)
6286             {
6287                 glPixelStorei(GL_PACK_ALIGNMENT, a);
6288                 for (GLint l : paramsPackRowLength)
6289                 {
6290                     glPixelStorei(GL_PACK_ROW_LENGTH, l);
6291 
6292                     for (const auto &area : areas)
6293                     {
6294                         ASSERT(area[0] + area[2] <= width);
6295                         ASSERT(area[1] + area[3] <= height);
6296                         testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
6297                                                                      area[3], l, a, skipped[0],
6298                                                                      skipped[1], type, color);
6299                     }
6300                 }
6301             }
6302         }
6303 
6304         glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
6305         glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
6306         glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
6307         glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
6308 
6309         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
6310         glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
6311         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6312                                   mRenderbuffer);
6313         glBindRenderbuffer(GL_RENDERBUFFER, 0);
6314         EXPECT_GL_NO_ERROR();
6315 
6316         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
6317         glClear(GL_COLOR_BUFFER_BIT);
6318 
6319         EXPECT_PIXEL_16UI_COLOR(
6320             0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
6321 
6322         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
6323         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
6324 
6325         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
6326                                0);
6327         EXPECT_PIXEL_16UI_COLOR(
6328             0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
6329 
6330         ASSERT_GL_NO_ERROR();
6331 
6332         glBindFramebuffer(GL_FRAMEBUFFER, 0);
6333     }
6334 
6335     GLuint mTextures[3];
6336     GLuint mFBO;
6337     GLuint mRenderbuffer;
6338 };
6339 
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16TextureTest)6340 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
6341 {
6342     testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
6343 }
6344 
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16SNORMTextureTest)6345 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
6346 {
6347     testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
6348 }
6349 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16TextureTest)6350 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
6351 {
6352     testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
6353 }
6354 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16SNORMTextureTest)6355 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
6356 {
6357     testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
6358 }
6359 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16TextureTest)6360 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
6361 {
6362     // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
6363     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
6364 
6365     testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
6366 }
6367 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16SNORMTextureTest)6368 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
6369 {
6370     // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
6371     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
6372 
6373     testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
6374 }
6375 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16TextureTest)6376 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
6377 {
6378     testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
6379 }
6380 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16SNORMTextureTest)6381 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
6382 {
6383     testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
6384 }
6385 
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16RenderTest)6386 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
6387 {
6388     // http://anglebug.com/5153
6389     ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL() && IsNVIDIA());
6390 
6391     testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
6392 }
6393 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16RenderTest)6394 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
6395 {
6396     // http://anglebug.com/5153
6397     ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL() && IsNVIDIA());
6398 
6399     testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
6400 }
6401 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16RenderTest)6402 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
6403 {
6404     // http://anglebug.com/5153
6405     ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL() && IsNVIDIA());
6406 
6407     testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
6408 }
6409 
6410 class Texture2DRGTest : public Texture2DTest
6411 {
6412   protected:
Texture2DRGTest()6413     Texture2DRGTest()
6414         : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
6415     {}
6416 
testSetUp()6417     void testSetUp() override
6418     {
6419         Texture2DTest::testSetUp();
6420 
6421         glActiveTexture(GL_TEXTURE0);
6422         glGenTextures(1, &mRenderableTexture);
6423         glGenTextures(1, &mTestTexture);
6424         glGenFramebuffers(1, &mFBO);
6425         glGenRenderbuffers(1, &mRenderbuffer);
6426 
6427         glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
6428         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6429         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6430         glBindTexture(GL_TEXTURE_2D, mTestTexture);
6431         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6432         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6433 
6434         glBindTexture(GL_TEXTURE_2D, 0);
6435 
6436         setUpProgram();
6437         glUseProgram(mProgram);
6438         glUniform1i(mTexture2DUniformLocation, 0);
6439 
6440         ASSERT_GL_NO_ERROR();
6441     }
6442 
testTearDown()6443     void testTearDown() override
6444     {
6445         glDeleteTextures(1, &mRenderableTexture);
6446         glDeleteTextures(1, &mTestTexture);
6447         glDeleteFramebuffers(1, &mFBO);
6448         glDeleteRenderbuffers(1, &mRenderbuffer);
6449 
6450         Texture2DTest::testTearDown();
6451     }
6452 
setupFormatTextures(GLenum internalformat,GLenum format,GLenum type,GLvoid * imageData)6453     void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
6454     {
6455         glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
6456         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6457 
6458         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
6459         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6460                                mRenderableTexture, 0);
6461 
6462         glBindTexture(GL_TEXTURE_2D, mTestTexture);
6463         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
6464 
6465         EXPECT_GL_NO_ERROR();
6466     }
6467 
testRGTexture(GLColor expectedColor)6468     void testRGTexture(GLColor expectedColor)
6469     {
6470         drawQuad(mProgram, "position", 0.5f);
6471 
6472         EXPECT_GL_NO_ERROR();
6473         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
6474     }
6475 
testRGRender(GLenum internalformat,GLenum format)6476     void testRGRender(GLenum internalformat, GLenum format)
6477     {
6478         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
6479         glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
6480         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6481                                   mRenderbuffer);
6482         glBindRenderbuffer(GL_RENDERBUFFER, 0);
6483         EXPECT_GL_NO_ERROR();
6484 
6485         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
6486         glClear(GL_COLOR_BUFFER_BIT);
6487 
6488         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
6489 
6490         ASSERT_GL_NO_ERROR();
6491         EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
6492     }
6493 
6494     GLuint mRenderableTexture;
6495     GLuint mTestTexture;
6496     GLuint mFBO;
6497     GLuint mRenderbuffer;
6498 };
6499 
6500 // Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGUNormTest)6501 TEST_P(Texture2DRGTest, TextureRGUNormTest)
6502 {
6503     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
6504     // This workaround causes a GL error on Windows AMD, which is likely a driver bug.
6505     // The workaround is not intended to be enabled in this configuration so skip it.
6506     ANGLE_SKIP_TEST_IF(GetParam().eglParameters.emulateCopyTexImage2DFromRenderbuffers &&
6507                        IsWindows() && IsAMD());
6508 
6509     GLubyte pixelValue  = 0xab;
6510     GLubyte imageData[] = {pixelValue, pixelValue};
6511 
6512     setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
6513     testRGTexture(
6514         SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
6515     testRGRender(GL_R8_EXT, GL_RED_EXT);
6516 
6517     setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
6518     testRGTexture(
6519         SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
6520     testRGRender(GL_RG8_EXT, GL_RG_EXT);
6521 }
6522 
6523 // Test float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGFloatTest)6524 TEST_P(Texture2DRGTest, TextureRGFloatTest)
6525 {
6526     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
6527     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
6528 
6529     GLfloat pixelValue  = 0.54321;
6530     GLfloat imageData[] = {pixelValue, pixelValue};
6531 
6532     GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
6533     GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
6534 
6535     setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
6536     testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
6537 
6538     setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
6539     testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
6540 }
6541 
6542 // Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGHalfFloatTest)6543 TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
6544 {
6545     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
6546     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
6547 
6548     GLfloat pixelValueFloat = 0.543f;
6549     GLhalf pixelValue       = 0x3858;
6550     GLhalf imageData[]      = {pixelValue, pixelValue};
6551 
6552     GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
6553     GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
6554 
6555     setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
6556     testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
6557 
6558     setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
6559     testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
6560 }
6561 
6562 class Texture2DFloatTest : public Texture2DTest
6563 {
6564   protected:
Texture2DFloatTest()6565     Texture2DFloatTest()
6566         : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
6567     {}
6568 
testSetUp()6569     void testSetUp() override
6570     {
6571         Texture2DTest::testSetUp();
6572 
6573         glActiveTexture(GL_TEXTURE0);
6574         glGenTextures(1, &mRenderableTexture);
6575         glGenTextures(1, &mTestTexture);
6576         glGenFramebuffers(1, &mFBO);
6577         glGenRenderbuffers(1, &mRenderbuffer);
6578 
6579         setUpProgram();
6580         glUseProgram(mProgram);
6581         glUniform1i(mTexture2DUniformLocation, 0);
6582 
6583         glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
6584         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6585 
6586         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
6587         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6588                                mRenderableTexture, 0);
6589 
6590         ASSERT_GL_NO_ERROR();
6591     }
6592 
testTearDown()6593     void testTearDown() override
6594     {
6595         glDeleteTextures(1, &mRenderableTexture);
6596         glDeleteTextures(1, &mTestTexture);
6597         glDeleteFramebuffers(1, &mFBO);
6598         glDeleteRenderbuffers(1, &mRenderbuffer);
6599 
6600         Texture2DTest::testTearDown();
6601     }
6602 
testFloatTextureSample(GLenum internalFormat,GLenum format,GLenum type)6603     void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
6604     {
6605         constexpr GLfloat imageDataFloat[] = {
6606             0.2f,
6607             0.3f,
6608             0.4f,
6609             0.5f,
6610         };
6611         constexpr GLhalf imageDataHalf[] = {
6612             0x3266,
6613             0x34CD,
6614             0x3666,
6615             0x3800,
6616         };
6617         GLColor expectedValue;
6618         for (int i = 0; i < 4; i++)
6619         {
6620             expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
6621         }
6622 
6623         const GLvoid *imageData;
6624         switch (type)
6625         {
6626             case GL_FLOAT:
6627                 imageData = imageDataFloat;
6628                 break;
6629             case GL_HALF_FLOAT:
6630             case GL_HALF_FLOAT_OES:
6631                 imageData = imageDataHalf;
6632                 break;
6633             default:
6634                 imageData = nullptr;
6635         }
6636         ASSERT(imageData != nullptr);
6637 
6638         glBindTexture(GL_TEXTURE_2D, mTestTexture);
6639         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
6640 
6641         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6642         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6643 
6644         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
6645         drawQuad(mProgram, "position", 0.5f);
6646 
6647         EXPECT_GL_NO_ERROR();
6648         EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
6649     }
6650 
testFloatTextureLinear(GLenum internalFormat,GLenum format,GLenum type)6651     void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
6652     {
6653         int numComponents;
6654         switch (format)
6655         {
6656             case GL_RGBA:
6657                 numComponents = 4;
6658                 break;
6659             case GL_RGB:
6660                 numComponents = 3;
6661                 break;
6662             case GL_LUMINANCE_ALPHA:
6663                 numComponents = 2;
6664                 break;
6665             case GL_LUMINANCE:
6666             case GL_ALPHA:
6667                 numComponents = 1;
6668                 break;
6669             default:
6670                 numComponents = 0;
6671         }
6672         ASSERT(numComponents > 0);
6673 
6674         constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
6675         constexpr GLhalf pixelIntensitiesHalf[]   = {0x0000, 0x3C00, 0x0000, 0x3C00};
6676 
6677         GLfloat imageDataFloat[16];
6678         GLhalf imageDataHalf[16];
6679         for (int i = 0; i < 4; i++)
6680         {
6681             for (int c = 0; c < numComponents; c++)
6682             {
6683                 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
6684                 imageDataHalf[i * numComponents + c]  = pixelIntensitiesHalf[i];
6685             }
6686         }
6687 
6688         const GLvoid *imageData;
6689         switch (type)
6690         {
6691             case GL_FLOAT:
6692                 imageData = imageDataFloat;
6693                 break;
6694             case GL_HALF_FLOAT:
6695             case GL_HALF_FLOAT_OES:
6696                 imageData = imageDataHalf;
6697                 break;
6698             default:
6699                 imageData = nullptr;
6700         }
6701         ASSERT(imageData != nullptr);
6702 
6703         glBindTexture(GL_TEXTURE_2D, mTestTexture);
6704         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
6705 
6706         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6707         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6708 
6709         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
6710         drawQuad(mProgram, "position", 0.5f);
6711 
6712         EXPECT_GL_NO_ERROR();
6713         // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
6714         // should expect the final value to be gray (halfway in-between)
6715         EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
6716                                 kPixelTolerance);
6717     }
6718 
performFloatTextureRender(GLenum internalFormat,GLenum renderBufferFormat,GLenum format,GLenum type)6719     bool performFloatTextureRender(GLenum internalFormat,
6720                                    GLenum renderBufferFormat,
6721                                    GLenum format,
6722                                    GLenum type)
6723     {
6724         glBindTexture(GL_TEXTURE_2D, mTestTexture);
6725         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
6726         glBindTexture(GL_TEXTURE_2D, 0);
6727 
6728         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
6729         glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
6730         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6731                                   mRenderbuffer);
6732         glBindRenderbuffer(GL_RENDERBUFFER, 0);
6733         EXPECT_GL_NO_ERROR();
6734 
6735         if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
6736         {
6737             return false;
6738         }
6739 
6740         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
6741 
6742         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
6743         glClear(GL_COLOR_BUFFER_BIT);
6744 
6745         EXPECT_GL_NO_ERROR();
6746         return true;
6747     }
6748 
6749     GLuint mRenderableTexture;
6750     GLuint mTestTexture;
6751     GLuint mFBO;
6752     GLuint mRenderbuffer;
6753 };
6754 
6755 class Texture2DFloatTestES3 : public Texture2DFloatTest
6756 {
6757   protected:
testFloatTextureRender(GLenum internalFormat,GLenum format,GLenum type)6758     void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
6759     {
6760         bool framebufferComplete =
6761             performFloatTextureRender(internalFormat, internalFormat, format, type);
6762         EXPECT_TRUE(framebufferComplete);
6763         EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
6764                                    SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
6765                                    kPixelTolerance32F);
6766     }
6767 };
6768 
6769 class Texture2DFloatTestES2 : public Texture2DFloatTest
6770 {
6771   protected:
checkFloatTextureRender(GLenum renderBufferFormat,GLenum format,GLenum type)6772     bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
6773     {
6774         bool framebufferComplete =
6775             performFloatTextureRender(format, renderBufferFormat, format, type);
6776 
6777         if (!framebufferComplete)
6778         {
6779             return false;
6780         }
6781 
6782         EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
6783                                    SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
6784                                    kPixelTolerance32F);
6785         return true;
6786     }
6787 };
6788 
6789 // Test texture sampling for ES3 float texture formats
TEST_P(Texture2DFloatTestES3,TextureFloatSampleBasicTest)6790 TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
6791 {
6792     testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
6793     testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
6794 }
6795 
6796 // Test texture sampling for ES2 float texture formats
TEST_P(Texture2DFloatTestES2,TextureFloatSampleBasicTest)6797 TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
6798 {
6799     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
6800     testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
6801     testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
6802 }
6803 
6804 // Test texture sampling for ES3 half float texture formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleBasicTest)6805 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
6806 {
6807     testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
6808     testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
6809 }
6810 
6811 // Test texture sampling for ES2 half float texture formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleBasicTest)6812 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
6813 {
6814     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
6815     testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
6816     testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
6817 }
6818 
6819 // Test texture sampling for legacy GLES 2.0 float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatSampleLegacyTest)6820 TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
6821 {
6822     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
6823 
6824     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
6825     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
6826     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
6827 
6828     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
6829     {
6830         testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
6831         testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
6832         testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
6833     }
6834 }
6835 
6836 // Test texture sampling for legacy GLES 2.0 float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatSampleLegacyTest)6837 TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
6838 {
6839     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
6840 
6841     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
6842     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
6843     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
6844 }
6845 
6846 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleLegacyTest)6847 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
6848 {
6849     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
6850 
6851     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
6852     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
6853     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
6854 
6855     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
6856     {
6857         testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
6858         testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
6859         testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
6860     }
6861 }
6862 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleLegacyTest)6863 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
6864 {
6865     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
6866 
6867     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
6868     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
6869     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
6870 }
6871 
6872 // Test linear sampling for ES3 32F formats
TEST_P(Texture2DFloatTestES3,TextureFloatLinearTest)6873 TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
6874 {
6875     // TODO(crbug.com/1132295): Failing on Apple DTK.
6876     ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsDesktopOpenGL());
6877 
6878     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
6879 
6880     testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
6881     testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
6882 }
6883 // Test linear sampling for ES2 32F formats
TEST_P(Texture2DFloatTestES2,TextureFloatLinearTest)6884 TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
6885 {
6886     // TODO(crbug.com/1132295): Failing on Apple DTK.
6887     ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && (IsDesktopOpenGL() || IsMetal()));
6888 
6889     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
6890 
6891     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
6892 
6893     testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
6894 }
6895 
6896 // Test linear sampling for ES3 16F formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearTest)6897 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
6898 {
6899     // Half float formats must be linearly filterable in GLES 3.0 core
6900     testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
6901     testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
6902 }
6903 // Test linear sampling for ES2 16F formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearTest)6904 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
6905 {
6906     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
6907     testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
6908     testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
6909 }
6910 
6911 // Test linear sampling for legacy GLES 2.0 32F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatLinearLegacyTest)6912 TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
6913 {
6914     // TODO(crbug.com/1132295): Failing on Apple DTK.
6915     ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsDesktopOpenGL());
6916 
6917     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
6918     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
6919 
6920     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
6921     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
6922     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
6923 
6924     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
6925     {
6926         testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
6927         testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
6928         testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
6929     }
6930 }
6931 // Test linear sampling for legacy GLES 2.0 32F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatLinearLegacyTest)6932 TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
6933 {
6934     // TODO(crbug.com/1132295): Failing on Apple DTK.
6935     ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && (IsDesktopOpenGL() || IsMetal()));
6936 
6937     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
6938     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
6939 
6940     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
6941     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
6942     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
6943 }
6944 
6945 // Test linear sampling for legacy GLES 2.0 16F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearLegacyTest)6946 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
6947 {
6948     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
6949     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
6950 
6951     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
6952     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
6953     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
6954 
6955     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
6956     {
6957         testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
6958         testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
6959         testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
6960     }
6961 }
6962 // Test linear sampling for legacy GLES 2.0 16F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearLegacyTest)6963 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
6964 {
6965     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
6966     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
6967 
6968     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
6969     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
6970     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
6971 }
6972 
6973 // Test color-renderability for ES3 float and half float textures
TEST_P(Texture2DFloatTestES3,TextureFloatRenderTest)6974 TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
6975 {
6976     // http://anglebug.com/4092
6977     ANGLE_SKIP_TEST_IF(IsD3D9());
6978     // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
6979     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
6980 
6981     testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
6982     testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
6983     testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
6984 
6985     testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
6986     testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
6987     testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
6988 
6989     testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
6990 }
6991 
6992 // Test color-renderability for ES2 half float textures
TEST_P(Texture2DFloatTestES2,TextureFloatRenderTest)6993 TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
6994 {
6995     // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
6996     // require a specific one
6997     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
6998     // https://crbug.com/1003971
6999     ANGLE_SKIP_TEST_IF(IsOzone());
7000     // http://anglebug.com/4092
7001     ANGLE_SKIP_TEST_IF(IsD3D9());
7002 
7003     bool atLeastOneSupported = false;
7004 
7005     if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
7006         IsGLExtensionEnabled("GL_OES_texture_half_float"))
7007     {
7008         atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
7009         atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
7010     }
7011     if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
7012     {
7013         atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
7014 
7015         // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
7016         bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
7017         EXPECT_TRUE(rgbaSupported);
7018         atLeastOneSupported |= rgbaSupported;
7019     }
7020 
7021     EXPECT_TRUE(atLeastOneSupported);
7022 }
7023 
7024 // Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
7025 // GLES 3.0.4 section 3.8.3.
TEST_P(Texture2DTestES3,UnpackSkipImages2D)7026 TEST_P(Texture2DTestES3, UnpackSkipImages2D)
7027 {
7028     // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
7029     ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
7030 
7031     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7032     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7033     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7034     ASSERT_GL_NO_ERROR();
7035 
7036     // SKIP_IMAGES should not have an effect on uploading 2D textures
7037     glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
7038     ASSERT_GL_NO_ERROR();
7039 
7040     std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
7041 
7042     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7043                  pixelsGreen.data());
7044     ASSERT_GL_NO_ERROR();
7045 
7046     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
7047                     pixelsGreen.data());
7048     ASSERT_GL_NO_ERROR();
7049 
7050     glUseProgram(mProgram);
7051     drawQuad(mProgram, "position", 0.5f);
7052     ASSERT_GL_NO_ERROR();
7053 
7054     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7055 }
7056 
7057 // Test that skip defined in unpack parameters is taken into account when determining whether
7058 // unpacking source extends outside unpack buffer bounds.
TEST_P(Texture2DTestES3,UnpackSkipPixelsOutOfBounds)7059 TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
7060 {
7061     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7062     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7063     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7064     ASSERT_GL_NO_ERROR();
7065 
7066     GLBuffer buf;
7067     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
7068     std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
7069     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
7070                  GL_DYNAMIC_COPY);
7071     ASSERT_GL_NO_ERROR();
7072 
7073     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
7074     ASSERT_GL_NO_ERROR();
7075 
7076     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
7077     ASSERT_GL_NO_ERROR();
7078 
7079     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
7080     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7081 
7082     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
7083     glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
7084     ASSERT_GL_NO_ERROR();
7085 
7086     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
7087     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7088 }
7089 
7090 // Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
TEST_P(Texture2DTestES3,UnpackOverlappingRowsFromUnpackBuffer)7091 TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
7092 {
7093     ANGLE_SKIP_TEST_IF(IsD3D11());
7094 
7095     // Incorrect rendering results seen on OSX AMD.
7096     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX() && IsAMD());
7097 
7098     const GLuint width            = 8u;
7099     const GLuint height           = 8u;
7100     const GLuint unpackRowLength  = 5u;
7101     const GLuint unpackSkipPixels = 1u;
7102 
7103     setWindowWidth(width);
7104     setWindowHeight(height);
7105 
7106     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7107     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7108     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7109     ASSERT_GL_NO_ERROR();
7110 
7111     GLBuffer buf;
7112     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
7113     std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
7114                                      GLColor::green);
7115 
7116     for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
7117     {
7118         pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
7119     }
7120 
7121     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
7122                  GL_DYNAMIC_COPY);
7123     ASSERT_GL_NO_ERROR();
7124 
7125     glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
7126     glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
7127     ASSERT_GL_NO_ERROR();
7128 
7129     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
7130     ASSERT_GL_NO_ERROR();
7131 
7132     glUseProgram(mProgram);
7133     drawQuad(mProgram, "position", 0.5f);
7134     ASSERT_GL_NO_ERROR();
7135 
7136     GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
7137     std::vector<GLColor> actual(windowPixelCount, GLColor::black);
7138     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
7139                  actual.data());
7140     std::vector<GLColor> expected(windowPixelCount, GLColor::green);
7141     EXPECT_EQ(expected, actual);
7142 }
7143 
7144 template <typename T>
UNorm(double value)7145 T UNorm(double value)
7146 {
7147     return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
7148 }
7149 
7150 // Test rendering a depth texture with mipmaps.
TEST_P(Texture2DTestES3,DepthTexturesWithMipmaps)7151 TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
7152 {
7153     // TODO(cwallez) this is failing on Intel Win7 OpenGL.
7154     // TODO(zmo) this is faling on Win Intel HD 530 Debug.
7155     // http://anglebug.com/1706
7156     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
7157 
7158     // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
7159     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
7160 
7161     // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
7162     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
7163 
7164     const int size = getWindowWidth();
7165 
7166     auto dim   = [size](int level) { return size >> level; };
7167     int levels = gl::log2(size);
7168 
7169     glActiveTexture(GL_TEXTURE0);
7170     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7171     glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
7172     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
7173     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7174     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7175     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7176     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7177     ASSERT_GL_NO_ERROR();
7178 
7179     glUseProgram(mProgram);
7180     glUniform1i(mTexture2DUniformLocation, 0);
7181 
7182     std::vector<unsigned char> expected;
7183 
7184     for (int level = 0; level < levels; ++level)
7185     {
7186         double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
7187         expected.push_back(UNorm<unsigned char>(value));
7188 
7189         int levelDim = dim(level);
7190 
7191         ASSERT_GT(levelDim, 0);
7192 
7193         std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
7194         glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
7195                         GL_UNSIGNED_INT, initData.data());
7196     }
7197     ASSERT_GL_NO_ERROR();
7198 
7199     for (int level = 0; level < levels; ++level)
7200     {
7201         glViewport(0, 0, dim(level), dim(level));
7202         drawQuad(mProgram, "position", 0.5f);
7203         GLColor actual = ReadColor(0, 0);
7204         EXPECT_NEAR(expected[level], actual.R, 10u);
7205     }
7206 
7207     ASSERT_GL_NO_ERROR();
7208 }
7209 
7210 class Texture2DDepthTest : public Texture2DTest
7211 {
7212   protected:
Texture2DDepthTest()7213     Texture2DDepthTest() : Texture2DTest() {}
7214 
getVertexShaderSource()7215     const char *getVertexShaderSource() override
7216     {
7217         return "attribute vec4 vPosition;\n"
7218                "void main() {\n"
7219                "  gl_Position = vPosition;\n"
7220                "}\n";
7221     }
7222 
getFragmentShaderSource()7223     const char *getFragmentShaderSource() override
7224     {
7225         return "precision mediump float;\n"
7226                "uniform sampler2D ShadowMap;"
7227                "void main() {\n"
7228                "  vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
7229                "  if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
7230                "    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
7231                "  } else {"
7232                "    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
7233                "  }"
7234                "}\n";
7235     }
7236 
checkTexImageFormatSupport(GLenum format,GLenum internalformat,GLenum type)7237     bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
7238     {
7239         EXPECT_GL_NO_ERROR();
7240 
7241         GLTexture tex;
7242         glBindTexture(GL_TEXTURE_2D, tex);
7243         glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
7244 
7245         return (glGetError() == GL_NO_ERROR);
7246     }
7247 
testBehavior(bool useSizedComponent)7248     void testBehavior(bool useSizedComponent)
7249     {
7250         int w                 = getWindowWidth();
7251         int h                 = getWindowHeight();
7252         GLuint format         = GL_DEPTH_COMPONENT;
7253         GLuint internalFormat = GL_DEPTH_COMPONENT;
7254 
7255         if (useSizedComponent)
7256         {
7257             internalFormat = GL_DEPTH_COMPONENT24;
7258         }
7259 
7260         GLFramebuffer fbo;
7261         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7262         ASSERT_GL_NO_ERROR();
7263 
7264         GLTexture depthTexture;
7265         glBindTexture(GL_TEXTURE_2D, depthTexture);
7266         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7267         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7268         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7269         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7270 
7271         TexCoordDrawTest::setUpProgram();
7272         GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
7273         ASSERT_NE(-1, shadowMapLocation);
7274 
7275         GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
7276         ASSERT_NE(-1, positionLocation);
7277 
7278         ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
7279         glBindTexture(GL_TEXTURE_2D, depthTexture);
7280         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
7281         ASSERT_GL_NO_ERROR();
7282 
7283         // try adding a color buffer.
7284         GLuint colorTex = 0;
7285         glGenTextures(1, &colorTex);
7286         glBindTexture(GL_TEXTURE_2D, colorTex);
7287         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7288         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7289         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7290         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7291         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7292         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
7293         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
7294         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
7295         ASSERT_GL_NO_ERROR();
7296 
7297         glViewport(0, 0, w, h);
7298         // Fill depthTexture with 0.75
7299         glClearDepthf(0.75);
7300         glClear(GL_DEPTH_BUFFER_BIT);
7301 
7302         // Revert to normal framebuffer to test depth shader
7303         glBindFramebuffer(GL_FRAMEBUFFER, 0);
7304         glViewport(0, 0, w, h);
7305         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
7306         glClearDepthf(0.0f);
7307         ASSERT_GL_NO_ERROR();
7308 
7309         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
7310         ASSERT_GL_NO_ERROR();
7311 
7312         glActiveTexture(GL_TEXTURE0);
7313         glBindTexture(GL_TEXTURE_2D, depthTexture);
7314 
7315         glUseProgram(mProgram);
7316         ASSERT_GL_NO_ERROR();
7317 
7318         glUniform1i(shadowMapLocation, 0);
7319 
7320         const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
7321 
7322         glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
7323         ASSERT_GL_NO_ERROR();
7324         glEnableVertexAttribArray(positionLocation);
7325         ASSERT_GL_NO_ERROR();
7326         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
7327         ASSERT_GL_NO_ERROR();
7328 
7329         GLuint pixels[1];
7330         glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
7331         ASSERT_GL_NO_ERROR();
7332 
7333         // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
7334         // However, the OES_depth_texture indicates that the depth value is treated as luminance and
7335         // is in all the color components. Multiple implementations implement a workaround that
7336         // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
7337         // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
7338         // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
7339         // depending on if it sees the texture sample in only the RED component.
7340         if (useSizedComponent)
7341         {
7342             ASSERT_NE(pixels[0], 0xff0000ff);
7343         }
7344         else
7345         {
7346             ASSERT_EQ(pixels[0], 0xff0000ff);
7347         }
7348 
7349         glBindFramebuffer(GL_FRAMEBUFFER, 0);
7350         glDeleteProgram(mProgram);
7351     }
7352 };
7353 
7354 // Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
TEST_P(Texture2DDepthTest,DepthTextureES2Compatibility)7355 TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
7356 {
7357     ANGLE_SKIP_TEST_IF(IsD3D11());
7358     ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
7359     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
7360                        !IsGLExtensionEnabled("GL_OES_depth_texture"));
7361     // http://anglebug.com/4092
7362     ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
7363     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
7364 
7365     // http://anglebug.com/4908
7366     ANGLE_SKIP_TEST_IF(IsIntel() && IsMetal());
7367 
7368     // When the depth texture is specified with unsized internalformat implementations follow
7369     // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
7370     testBehavior(false);
7371 }
7372 
7373 // Test depth texture compatibility with GLES3 using sized internalformat.
TEST_P(Texture2DDepthTest,DepthTextureES3Compatibility)7374 TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
7375 {
7376     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
7377 
7378     // http://anglebug.com/5243
7379     ANGLE_SKIP_TEST_IF(IsMetal() && !IsMetalTextureSwizzleAvailable());
7380 
7381     testBehavior(true);
7382 }
7383 
7384 // Tests unpacking into the unsized GL_ALPHA format.
TEST_P(Texture2DTestES3,UnsizedAlphaUnpackBuffer)7385 TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
7386 {
7387     // Initialize the texure.
7388     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7389     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
7390                  GL_UNSIGNED_BYTE, nullptr);
7391     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7392     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7393 
7394     std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
7395 
7396     // Pull in the color data from the unpack buffer.
7397     GLBuffer unpackBuffer;
7398     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7399     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
7400     glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
7401                  GL_STATIC_DRAW);
7402 
7403     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
7404                     GL_UNSIGNED_BYTE, nullptr);
7405 
7406     // Clear to a weird color to make sure we're drawing something.
7407     glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
7408     glClear(GL_COLOR_BUFFER_BIT);
7409 
7410     // Draw with the alpha texture and verify.
7411     drawQuad(mProgram, "position", 0.5f);
7412 
7413     ASSERT_GL_NO_ERROR();
7414     EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
7415 }
7416 
7417 // Ensure stale unpack data doesn't propagate in D3D11.
TEST_P(Texture2DTestES3,StaleUnpackData)7418 TEST_P(Texture2DTestES3, StaleUnpackData)
7419 {
7420     // Init unpack buffer.
7421     GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
7422     std::vector<GLColor> pixels(pixelCount, GLColor::red);
7423 
7424     GLBuffer unpackBuffer;
7425     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7426     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
7427     GLsizei bufferSize = pixelCount * sizeof(GLColor);
7428     glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
7429 
7430     // Create from unpack buffer.
7431     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7432     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
7433                  GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7434     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7435     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7436 
7437     drawQuad(mProgram, "position", 0.5f);
7438 
7439     ASSERT_GL_NO_ERROR();
7440     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7441 
7442     // Fill unpack with green, recreating buffer.
7443     pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
7444     GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
7445     glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
7446 
7447     // Reinit texture with green.
7448     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
7449                     GL_UNSIGNED_BYTE, nullptr);
7450 
7451     drawQuad(mProgram, "position", 0.5f);
7452 
7453     ASSERT_GL_NO_ERROR();
7454     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7455 }
7456 
7457 // Ensure that texture parameters passed as floats that are converted to ints are rounded before
7458 // validating they are less than 0.
TEST_P(Texture2DTestES3,TextureBaseMaxLevelRoundingValidation)7459 TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
7460 {
7461     GLTexture texture;
7462     glBindTexture(GL_TEXTURE_2D, texture);
7463 
7464     // Use a negative number that will round to zero when converted to an integer
7465     // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
7466     // "Validation of values performed by state-setting commands is performed after conversion,
7467     // unless specified otherwise for a specific command."
7468     GLfloat param = -7.30157126e-07f;
7469     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
7470     EXPECT_GL_NO_ERROR();
7471 
7472     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
7473     EXPECT_GL_NO_ERROR();
7474 }
7475 
7476 // This test covers a D3D format redefinition bug for 3D textures. The base level format was not
7477 // being properly checked, and the texture storage of the previous texture format was persisting.
7478 // This would result in an ASSERT in debug and incorrect rendering in release.
7479 // See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
TEST_P(Texture3DTestES3,FormatRedefinitionBug)7480 TEST_P(Texture3DTestES3, FormatRedefinitionBug)
7481 {
7482     GLTexture tex;
7483     glBindTexture(GL_TEXTURE_3D, tex.get());
7484     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7485 
7486     GLFramebuffer framebuffer;
7487     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
7488     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
7489 
7490     glCheckFramebufferStatus(GL_FRAMEBUFFER);
7491 
7492     std::vector<uint8_t> pixelData(100, 0);
7493 
7494     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
7495     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
7496                     pixelData.data());
7497 
7498     ASSERT_GL_NO_ERROR();
7499 }
7500 
7501 // Test glTexSubImage using PBO to 3D texture that expose the regression bug
7502 // https://issuetracker.google.com/170657065
TEST_P(Texture3DTestES3,TexSubImageWithPBO)7503 TEST_P(Texture3DTestES3, TexSubImageWithPBO)
7504 {
7505     GLTexture tex;
7506 
7507     GLuint pbo;
7508     glGenBuffers(1, &pbo);
7509     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
7510     std::vector<uint8_t> pixelData(128 * 128 * 8 * 4, 0x1f);
7511     glBufferData(GL_PIXEL_UNPACK_BUFFER, 128 * 128 * 8 * 4, pixelData.data(), GL_STATIC_DRAW);
7512 
7513     glBindTexture(GL_TEXTURE_3D, tex.get());
7514     glTexStorage3D(GL_TEXTURE_3D, 8, GL_RGBA8, 128, 128, 8);
7515     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
7516     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7517     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7518     glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7519     glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7520     glTexSubImage3D(GL_TEXTURE_3D, 3, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7521     glTexSubImage3D(GL_TEXTURE_3D, 4, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7522     glTexSubImage3D(GL_TEXTURE_3D, 5, 0, 0, 0, 4, 4, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7523     glTexSubImage3D(GL_TEXTURE_3D, 6, 0, 0, 0, 2, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7524     glTexSubImage3D(GL_TEXTURE_3D, 7, 0, 0, 0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7525 
7526     drawQuad(mProgram, "position", 0.5f);
7527     ASSERT_GL_NO_ERROR();
7528 
7529     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7530     glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7531     glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7532     ASSERT_GL_NO_ERROR();
7533 
7534     drawQuad(mProgram, "position", 0.5f);
7535     ASSERT_GL_NO_ERROR();
7536 }
7537 
7538 // Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
TEST_P(Texture3DTestES3,BasicUnpackBufferOOB)7539 TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
7540 {
7541     // 2D tests
7542     {
7543         GLTexture tex;
7544         glBindTexture(GL_TEXTURE_2D, tex.get());
7545 
7546         GLBuffer pbo;
7547         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
7548 
7549         // Test OOB
7550         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
7551         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7552         ASSERT_GL_ERROR(GL_INVALID_OPERATION);
7553 
7554         // Test OOB
7555         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
7556         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7557         ASSERT_GL_NO_ERROR();
7558     }
7559 
7560     // 3D tests
7561     {
7562         GLTexture tex;
7563         glBindTexture(GL_TEXTURE_3D, tex.get());
7564 
7565         GLBuffer pbo;
7566         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
7567 
7568         // Test OOB
7569         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
7570                      GL_STATIC_DRAW);
7571         glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7572         ASSERT_GL_ERROR(GL_INVALID_OPERATION);
7573 
7574         // Test OOB
7575         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
7576         glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7577         ASSERT_GL_NO_ERROR();
7578     }
7579 }
7580 
7581 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES3,SingleTextureMultipleSamplers)7582 TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
7583 {
7584     GLint maxTextureUnits = 0;
7585     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
7586     ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
7587 
7588     constexpr int kSize = 16;
7589 
7590     // Make a single-level texture, fill it with red.
7591     std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
7592     GLTexture tex;
7593     glBindTexture(GL_TEXTURE_2D, tex);
7594     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7595                  redColors.data());
7596     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7597     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7598 
7599     // Simple confidence check.
7600     draw2DTexturedQuad(0.5f, 1.0f, true);
7601     ASSERT_GL_NO_ERROR();
7602     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7603 
7604     // Bind texture to unit 1 with a sampler object making it incomplete.
7605     GLSampler sampler;
7606     glBindSampler(0, sampler);
7607     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
7608     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7609 
7610     // Make a mipmap texture, fill it with blue.
7611     std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
7612     GLTexture mipmapTex;
7613     glBindTexture(GL_TEXTURE_2D, mipmapTex);
7614     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7615                  blueColors.data());
7616     glGenerateMipmap(GL_TEXTURE_2D);
7617 
7618     // Draw with the sampler, expect blue.
7619     draw2DTexturedQuad(0.5f, 1.0f, true);
7620     ASSERT_GL_NO_ERROR();
7621     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
7622 
7623     // Simple multitexturing program.
7624     constexpr char kVS[] =
7625         "#version 300 es\n"
7626         "in vec2 position;\n"
7627         "out vec2 texCoord;\n"
7628         "void main()\n"
7629         "{\n"
7630         "    gl_Position = vec4(position, 0, 1);\n"
7631         "    texCoord = position * 0.5 + vec2(0.5);\n"
7632         "}";
7633 
7634     constexpr char kFS[] =
7635         "#version 300 es\n"
7636         "precision mediump float;\n"
7637         "in vec2 texCoord;\n"
7638         "uniform sampler2D tex1;\n"
7639         "uniform sampler2D tex2;\n"
7640         "uniform sampler2D tex3;\n"
7641         "uniform sampler2D tex4;\n"
7642         "out vec4 color;\n"
7643         "void main()\n"
7644         "{\n"
7645         "    color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
7646         "          +  texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
7647         "}";
7648 
7649     ANGLE_GL_PROGRAM(program, kVS, kFS);
7650 
7651     std::array<GLint, 4> texLocations = {
7652         {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
7653          glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
7654     for (GLint location : texLocations)
7655     {
7656         ASSERT_NE(-1, location);
7657     }
7658 
7659     // Init the uniform data.
7660     glUseProgram(program);
7661     for (GLint location = 0; location < 4; ++location)
7662     {
7663         glUniform1i(texLocations[location], location);
7664     }
7665 
7666     // Initialize four samplers
7667     GLSampler samplers[4];
7668 
7669     // 0: non-mipped.
7670     glBindSampler(0, samplers[0]);
7671     glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7672     glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7673 
7674     // 1: mipped.
7675     glBindSampler(1, samplers[1]);
7676     glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
7677     glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7678 
7679     // 2: non-mipped.
7680     glBindSampler(2, samplers[2]);
7681     glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7682     glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7683 
7684     // 3: mipped.
7685     glBindSampler(3, samplers[3]);
7686     glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
7687     glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7688 
7689     // Bind two blue mipped textures and two single layer textures, should all draw.
7690     glActiveTexture(GL_TEXTURE0);
7691     glBindTexture(GL_TEXTURE_2D, tex);
7692 
7693     glActiveTexture(GL_TEXTURE1);
7694     glBindTexture(GL_TEXTURE_2D, mipmapTex);
7695 
7696     glActiveTexture(GL_TEXTURE2);
7697     glBindTexture(GL_TEXTURE_2D, tex);
7698 
7699     glActiveTexture(GL_TEXTURE3);
7700     glBindTexture(GL_TEXTURE_2D, mipmapTex);
7701 
7702     ASSERT_GL_NO_ERROR();
7703 
7704     drawQuad(program, "position", 0.5f);
7705     ASSERT_GL_NO_ERROR();
7706     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
7707 
7708     // Bind four single layer textures, two should be incomplete.
7709     glActiveTexture(GL_TEXTURE1);
7710     glBindTexture(GL_TEXTURE_2D, tex);
7711 
7712     glActiveTexture(GL_TEXTURE3);
7713     glBindTexture(GL_TEXTURE_2D, tex);
7714 
7715     drawQuad(program, "position", 0.5f);
7716     ASSERT_GL_NO_ERROR();
7717     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
7718 }
7719 
7720 // The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
7721 // always at level 0 instead of the base level resulting in an incomplete texture if the faces at
7722 // level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
7723 // level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
7724 // samples the cubemap using a direction vector (1,1,1).
TEST_P(TextureCubeTestES3,SpecifyAndSampleFromBaseLevel1)7725 TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
7726 {
7727     // Check http://anglebug.com/2155.
7728     ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
7729 
7730     constexpr char kVS[] =
7731         R"(#version 300 es
7732         precision mediump float;
7733         in vec3 pos;
7734         void main() {
7735             gl_Position = vec4(pos, 1.0);
7736         })";
7737 
7738     constexpr char kFS[] =
7739         R"(#version 300 es
7740         precision mediump float;
7741         out vec4 color;
7742         uniform samplerCube uTex;
7743         void main(){
7744             color = texture(uTex, vec3(1.0));
7745         })";
7746 
7747     ANGLE_GL_PROGRAM(program, kVS, kFS);
7748     glUseProgram(program);
7749 
7750     glUniform1i(glGetUniformLocation(program, "uTex"), 0);
7751     glActiveTexture(GL_TEXTURE0);
7752 
7753     GLTexture cubeTex;
7754     glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
7755 
7756     const int kFaceWidth  = 1;
7757     const int kFaceHeight = 1;
7758     std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
7759     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
7760                  GL_UNSIGNED_BYTE, texData.data());
7761     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
7762                  GL_UNSIGNED_BYTE, texData.data());
7763     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
7764                  GL_UNSIGNED_BYTE, texData.data());
7765     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
7766                  GL_UNSIGNED_BYTE, texData.data());
7767     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
7768                  GL_UNSIGNED_BYTE, texData.data());
7769     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
7770                  GL_UNSIGNED_BYTE, texData.data());
7771     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7772     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7773     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
7774     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
7775     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
7776     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
7777 
7778     drawQuad(program, "pos", 0.5f, 1.0f, true);
7779     ASSERT_GL_NO_ERROR();
7780 
7781     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
7782 }
7783 
7784 // Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
TEST_P(Texture2DTestES3,NegativeTextureBaseLevelAndMaxLevel)7785 TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
7786 {
7787     GLuint texture = create2DTexture();
7788 
7789     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
7790     EXPECT_GL_ERROR(GL_INVALID_VALUE);
7791 
7792     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
7793     EXPECT_GL_ERROR(GL_INVALID_VALUE);
7794 
7795     glDeleteTextures(1, &texture);
7796     EXPECT_GL_NO_ERROR();
7797 }
7798 
7799 // Test setting base level after calling generateMipmap on a LUMA texture.
7800 // Covers http://anglebug.com/2498
TEST_P(Texture2DTestES3,GenerateMipmapAndBaseLevelLUMA)7801 TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
7802 {
7803     glActiveTexture(GL_TEXTURE0);
7804     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7805 
7806     constexpr const GLsizei kWidth  = 8;
7807     constexpr const GLsizei kHeight = 8;
7808     std::array<GLubyte, kWidth * kHeight * 2> whiteData;
7809     whiteData.fill(255u);
7810 
7811     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
7812                  GL_UNSIGNED_BYTE, whiteData.data());
7813     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
7814     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7815     glGenerateMipmap(GL_TEXTURE_2D);
7816     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7817     EXPECT_GL_NO_ERROR();
7818 
7819     drawQuad(mProgram, "position", 0.5f);
7820     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
7821 }
7822 
7823 // Incompatible levels with non-mipmap filtering should work.
TEST_P(Texture2DTestES3,IncompatibleMipsButNoMipmapFiltering)7824 TEST_P(Texture2DTestES3, IncompatibleMipsButNoMipmapFiltering)
7825 {
7826     // http://anglebug.com/4780
7827     ANGLE_SKIP_TEST_IF(IsVulkan());
7828 
7829     // http://anglebug.com/4782
7830     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsWindows() && (IsAMD() || IsIntel()));
7831 
7832     // http://anglebug.com/4786
7833     ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsNVIDIAShield());
7834 
7835     glActiveTexture(GL_TEXTURE0);
7836     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7837 
7838     constexpr const GLsizei kSize = 8;
7839     const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
7840     const std::vector<GLColor> kLevel1Data(kSize * kSize, GLColor::red);
7841 
7842     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7843                  kLevel0Data.data());
7844     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7845                  kLevel1Data.data());
7846     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7847     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7848     EXPECT_GL_NO_ERROR();
7849 
7850     // Draw with base level 0.  The GL_LINEAR filtering ensures the texture's image is not created
7851     // with mipmap.
7852     drawQuad(mProgram, "position", 0.5f);
7853     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
7854 
7855     // Verify draw with level 1.
7856     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7857     drawQuad(mProgram, "position", 0.5f);
7858     EXPECT_GL_NO_ERROR();
7859     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel1Data[0]);
7860 
7861     // Verify draw with level 0 again
7862     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7863     drawQuad(mProgram, "position", 0.5f);
7864     EXPECT_GL_NO_ERROR();
7865     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
7866 }
7867 
7868 // Enabling mipmap filtering after previously having used the texture without it should work.
TEST_P(Texture2DTestES3,NoMipmapDrawThenMipmapDraw)7869 TEST_P(Texture2DTestES3, NoMipmapDrawThenMipmapDraw)
7870 {
7871     glActiveTexture(GL_TEXTURE0);
7872     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7873 
7874     constexpr const GLsizei kSize = 8;
7875     const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
7876     const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
7877 
7878     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7879                  kLevel0Data.data());
7880     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7881     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7882     EXPECT_GL_NO_ERROR();
7883 
7884     // Draw so the texture's image is allocated.
7885     drawQuad(mProgram, "position", 0.5f);
7886     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
7887 
7888     // Specify the rest of the image
7889     for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
7890     {
7891         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
7892                      GL_UNSIGNED_BYTE, kLevelOtherData.data());
7893     }
7894     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
7895 
7896     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
7897     glUseProgram(program);
7898     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
7899     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
7900     ASSERT_NE(-1, textureLoc);
7901     ASSERT_NE(-1, lodLoc);
7902     glUniform1i(textureLoc, 0);
7903 
7904     // Verify the mips
7905     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
7906     {
7907         glUniform1f(lodLoc, mip);
7908         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
7909         EXPECT_GL_NO_ERROR();
7910         EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
7911     }
7912 }
7913 
7914 // Disabling mipmap filtering after previously having used the texture with it should work.
TEST_P(Texture2DTestES3,MipmapDrawThenNoMipmapDraw)7915 TEST_P(Texture2DTestES3, MipmapDrawThenNoMipmapDraw)
7916 {
7917     glActiveTexture(GL_TEXTURE0);
7918     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7919 
7920     constexpr const GLsizei kSize = 8;
7921     const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
7922     const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
7923 
7924     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7925                  kLevel0Data.data());
7926     for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
7927     {
7928         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
7929                      GL_UNSIGNED_BYTE, kLevelOtherData.data());
7930     }
7931     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
7932     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7933     EXPECT_GL_NO_ERROR();
7934 
7935     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
7936     glUseProgram(program);
7937     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
7938     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
7939     ASSERT_NE(-1, textureLoc);
7940     ASSERT_NE(-1, lodLoc);
7941     glUniform1i(textureLoc, 0);
7942 
7943     // Verify the mips.
7944     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
7945     {
7946         glUniform1f(lodLoc, mip);
7947         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
7948         EXPECT_GL_NO_ERROR();
7949         EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
7950     }
7951 
7952     // Disable mipmapping and verify mips again.
7953     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7954 
7955     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
7956     {
7957         glUniform1f(lodLoc, mip);
7958         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
7959         EXPECT_GL_NO_ERROR();
7960         EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
7961     }
7962 }
7963 
7964 // Respecify texture with more mips.
TEST_P(Texture2DTestES3,RespecifyWithMoreMips)7965 TEST_P(Texture2DTestES3, RespecifyWithMoreMips)
7966 {
7967     glActiveTexture(GL_TEXTURE0);
7968     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7969 
7970     constexpr const GLsizei kSize = 8;
7971     const std::vector<GLColor> kLevelEvenData(kSize * kSize, GLColor::blue);
7972     const std::vector<GLColor> kLevelOddData(kSize * kSize * 4, GLColor::red);
7973 
7974     auto getLevelData = [&](GLint mip) {
7975         return mip % 2 == 0 ? kLevelEvenData.data() : kLevelOddData.data();
7976     };
7977 
7978     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
7979     {
7980         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
7981                      GL_UNSIGNED_BYTE, getLevelData(mip));
7982     }
7983     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
7984     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7985     EXPECT_GL_NO_ERROR();
7986 
7987     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
7988     glUseProgram(program);
7989     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
7990     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
7991     ASSERT_NE(-1, textureLoc);
7992     ASSERT_NE(-1, lodLoc);
7993     glUniform1i(textureLoc, 0);
7994 
7995     // Verify the mips.
7996     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
7997     {
7998         glUniform1f(lodLoc, mip);
7999         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
8000         EXPECT_GL_NO_ERROR();
8001         EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip)[0]);
8002     }
8003 
8004     // Respecify the texture with more mips, without changing any parameters.
8005     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8006                  kLevelOddData.data());
8007     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
8008     {
8009         glTexImage2D(GL_TEXTURE_2D, mip + 1, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
8010                      GL_UNSIGNED_BYTE, getLevelData(mip));
8011     }
8012 
8013     // Verify the mips.
8014     for (GLint mip = 0; ((kSize * 2) >> mip) >= 1; ++mip)
8015     {
8016         glUniform1f(lodLoc, mip);
8017         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
8018         EXPECT_GL_NO_ERROR();
8019         EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip - 1)[0]);
8020     }
8021 }
8022 
8023 // Covers a bug in the D3D11 backend: http://anglebug.com/2772
8024 // When using a sampler the texture was created as if it has mipmaps,
8025 // regardless what you specified in GL_TEXTURE_MIN_FILTER via
8026 // glSamplerParameteri() -- mistakenly the default value
8027 // GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
8028 // evaluated.
8029 // If you didn't provide mipmaps and didn't let the driver generate them
8030 // this led to not sampling your texture data when minification occurred.
TEST_P(Texture2DTestES3,MinificationWithSamplerNoMipmapping)8031 TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
8032 {
8033     constexpr char kVS[] =
8034         "#version 300 es\n"
8035         "out vec2 texcoord;\n"
8036         "in vec4 position;\n"
8037         "void main()\n"
8038         "{\n"
8039         "    gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
8040         "    texcoord = (position.xy * 0.5) + 0.5;\n"
8041         "}\n";
8042 
8043     constexpr char kFS[] =
8044         "#version 300 es\n"
8045         "precision highp float;\n"
8046         "uniform highp sampler2D tex;\n"
8047         "in vec2 texcoord;\n"
8048         "out vec4 fragColor;\n"
8049         "void main()\n"
8050         "{\n"
8051         "    fragColor = texture(tex, texcoord);\n"
8052         "}\n";
8053 
8054     ANGLE_GL_PROGRAM(program, kVS, kFS);
8055 
8056     GLSampler sampler;
8057     glBindSampler(0, sampler);
8058     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8059     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8060 
8061     glActiveTexture(GL_TEXTURE0);
8062     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8063 
8064     const GLsizei texWidth  = getWindowWidth();
8065     const GLsizei texHeight = getWindowHeight();
8066     const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
8067 
8068     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8069                  whiteData.data());
8070     EXPECT_GL_NO_ERROR();
8071 
8072     drawQuad(program, "position", 0.5f);
8073     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
8074 }
8075 
8076 // Test that clears due to emulated formats are to the correct level given non-zero base level.
TEST_P(Texture2DTestES3,NonZeroBaseEmulatedClear)8077 TEST_P(Texture2DTestES3, NonZeroBaseEmulatedClear)
8078 {
8079     // Tests behavior of the Vulkan backend with emulated formats.
8080     ANGLE_SKIP_TEST_IF(!IsVulkan());
8081 
8082     setUpProgram();
8083 
8084     glActiveTexture(GL_TEXTURE0);
8085     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8086     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
8087     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
8088     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
8089     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
8090     glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
8091     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
8092     EXPECT_GL_NO_ERROR();
8093 
8094     drawQuad(mProgram, "position", 0.5f);
8095 
8096     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
8097 }
8098 
8099 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
8100 // texture is output.
TEST_P(Texture2DIntegerTestES3,IntegerTextureNonZeroBaseLevel)8101 TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
8102 {
8103     // http://anglebug.com/3478
8104     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
8105 
8106     glActiveTexture(GL_TEXTURE0);
8107     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8108     int width     = getWindowWidth();
8109     int height    = getWindowHeight();
8110     GLColor color = GLColor::green;
8111     std::vector<GLColor> pixels(width * height, color);
8112     GLint baseLevel = 1;
8113     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
8114     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8115     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8116     glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
8117                  GL_UNSIGNED_BYTE, pixels.data());
8118 
8119     setUpProgram();
8120     glUseProgram(mProgram);
8121     glUniform1i(mTexture2DUniformLocation, 0);
8122     drawQuad(mProgram, "position", 0.5f);
8123 
8124     EXPECT_GL_NO_ERROR();
8125     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
8126     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
8127 }
8128 
8129 // Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
8130 // the texture is output.
TEST_P(TextureCubeIntegerTestES3,IntegerCubeTextureNonZeroBaseLevel)8131 TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
8132 {
8133     // All output checks returned black, rather than the texture color.
8134     ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
8135 
8136     glActiveTexture(GL_TEXTURE0);
8137 
8138     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
8139     GLint baseLevel = 1;
8140     int width       = getWindowWidth();
8141     int height      = getWindowHeight();
8142     GLColor color   = GLColor::green;
8143     std::vector<GLColor> pixels(width * height, color);
8144     for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
8145     {
8146         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
8147                      height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
8148         EXPECT_GL_NO_ERROR();
8149     }
8150     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
8151     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8152     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8153 
8154     glUseProgram(mProgram);
8155     glUniform1i(mTextureCubeUniformLocation, 0);
8156     drawQuad(mProgram, "position", 0.5f);
8157 
8158     EXPECT_GL_NO_ERROR();
8159     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
8160     EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
8161     EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
8162     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
8163 }
8164 
8165 // This test sets up a cube map with four distincly colored MIP levels.
8166 // The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
8167 // the corners of the screen.
TEST_P(TextureCubeIntegerEdgeTestES3,IntegerCubeTextureCorner)8168 TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
8169 {
8170     glActiveTexture(GL_TEXTURE0);
8171 
8172     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
8173     int width  = getWindowWidth();
8174     int height = getWindowHeight();
8175     ASSERT_EQ(width, height);
8176     GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
8177     for (GLint level = 0; level < 4; level++)
8178     {
8179         for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
8180         {
8181             int levelWidth  = (2 * width) >> level;
8182             int levelHeight = (2 * height) >> level;
8183             std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
8184             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
8185                          levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
8186             EXPECT_GL_NO_ERROR();
8187         }
8188     }
8189     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8190     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8191     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
8192 
8193     glUseProgram(mProgram);
8194     glUniform1i(mTextureCubeUniformLocation, 0);
8195     drawQuad(mProgram, "position", 0.5f);
8196 
8197     ASSERT_GL_NO_ERROR();
8198     // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
8199     EXPECT_EQ(ReadColor(0, 0).R, 0);
8200     EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
8201     EXPECT_EQ(ReadColor(0, height - 1).R, 0);
8202     EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
8203 }
8204 
8205 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
8206 // texture is output.
TEST_P(Texture2DIntegerProjectiveOffsetTestES3,NonZeroBaseLevel)8207 TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
8208 {
8209     // Fails on AMD: http://crbug.com/967796
8210     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
8211 
8212     glActiveTexture(GL_TEXTURE0);
8213     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8214     int width     = getWindowWidth();
8215     int height    = getWindowHeight();
8216     GLColor color = GLColor::green;
8217     std::vector<GLColor> pixels(width * height, color);
8218     GLint baseLevel = 1;
8219     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
8220     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8221     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8222     glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
8223                  GL_UNSIGNED_BYTE, pixels.data());
8224 
8225     setUpProgram();
8226     glUseProgram(mProgram);
8227     glUniform1i(mTexture2DUniformLocation, 0);
8228     drawQuad(mProgram, "position", 0.5f);
8229 
8230     EXPECT_GL_NO_ERROR();
8231     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
8232     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
8233 }
8234 
8235 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
8236 // texture is output.
TEST_P(Texture2DArrayIntegerTestES3,NonZeroBaseLevel)8237 TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
8238 {
8239     glActiveTexture(GL_TEXTURE0);
8240     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
8241     int width     = getWindowWidth();
8242     int height    = getWindowHeight();
8243     int depth     = 2;
8244     GLColor color = GLColor::green;
8245     std::vector<GLColor> pixels(width * height * depth, color);
8246     GLint baseLevel = 1;
8247     glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
8248                  GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
8249     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
8250     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8251     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8252 
8253     drawQuad(mProgram, "position", 0.5f);
8254 
8255     EXPECT_GL_NO_ERROR();
8256     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
8257     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
8258 }
8259 
8260 // Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
8261 // texture is output.
TEST_P(Texture3DIntegerTestES3,NonZeroBaseLevel)8262 TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
8263 {
8264     glActiveTexture(GL_TEXTURE0);
8265     glBindTexture(GL_TEXTURE_3D, mTexture3D);
8266     int width     = getWindowWidth();
8267     int height    = getWindowHeight();
8268     int depth     = 2;
8269     GLColor color = GLColor::green;
8270     std::vector<GLColor> pixels(width * height * depth, color);
8271     GLint baseLevel = 1;
8272     glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
8273                  GL_UNSIGNED_BYTE, pixels.data());
8274     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
8275     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8276     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8277 
8278     drawQuad(mProgram, "position", 0.5f);
8279 
8280     EXPECT_GL_NO_ERROR();
8281     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
8282     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
8283 }
8284 
8285 // Test that uses glCompressedTexSubImage2D combined with a PBO
TEST_P(PBOCompressedTextureTest,PBOCompressedSubImage)8286 TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
8287 {
8288     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
8289     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
8290     // http://anglebug.com/4115
8291     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
8292     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
8293 
8294     if (getClientMajorVersion() < 3)
8295     {
8296         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
8297         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
8298         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
8299     }
8300 
8301     const GLuint width  = 4u;
8302     const GLuint height = 4u;
8303 
8304     setWindowWidth(width);
8305     setWindowHeight(height);
8306 
8307     // Setup primary Texture
8308     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8309     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8310     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8311 
8312     if (getClientMajorVersion() < 3)
8313     {
8314         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
8315     }
8316     else
8317     {
8318         glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
8319     }
8320     ASSERT_GL_NO_ERROR();
8321 
8322     // Setup PBO and fill it with a red
8323     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
8324     glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
8325     ASSERT_GL_NO_ERROR();
8326 
8327     // Write PBO to mTexture
8328     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
8329                               width * height / 2u, nullptr);
8330     ASSERT_GL_NO_ERROR();
8331 
8332     setUpProgram();
8333     // Draw using PBO updated texture
8334     glUseProgram(mProgram);
8335     glUniform1i(mTexture2DUniformLocation, 0);
8336     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8337     drawQuad(mProgram, "position", 0.5f);
8338     ASSERT_GL_NO_ERROR();
8339 
8340     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8341     ASSERT_GL_NO_ERROR();
8342 }
8343 
8344 // Test using ETC1_RGB8 with subimage updates
TEST_P(ETC1CompressedTextureTest,ETC1CompressedSubImage)8345 TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
8346 {
8347     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
8348     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
8349 
8350     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
8351                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
8352     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
8353 
8354     const GLuint width  = 4u;
8355     const GLuint height = 4u;
8356 
8357     setWindowWidth(width);
8358     setWindowHeight(height);
8359 
8360     // Setup primary Texture
8361     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8362     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8363 
8364     if (getClientMajorVersion() < 3)
8365     {
8366         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
8367     }
8368     else
8369     {
8370         glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
8371     }
8372     ASSERT_GL_NO_ERROR();
8373 
8374     // Populate a subimage of the texture
8375     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
8376                               width * height / 2u, kCompressedImageETC2);
8377     ASSERT_GL_NO_ERROR();
8378 
8379     // Render and ensure we get red
8380     glUseProgram(mProgram);
8381     drawQuad(mProgram, "position", 0.5f);
8382     ASSERT_GL_NO_ERROR();
8383 
8384     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8385     ASSERT_GL_NO_ERROR();
8386 }
8387 
8388 // Fully-define a NPOT compressed texture and draw; set MAX_LEVEL and draw; then increase
8389 // MAX_LEVEL and draw.  This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageNPOT)8390 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageNPOT)
8391 {
8392     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
8393     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
8394 
8395     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
8396     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
8397 
8398     const GLuint width  = 5u;
8399     const GLuint height = 5u;
8400     // round up to the nearest block size
8401     const GLsizei imageSize = 8 * 8 / 2;
8402     // smallest block size
8403     const GLsizei minImageSize = 4 * 4 / 2;
8404 
8405     uint8_t data[imageSize] = {0};
8406 
8407     setWindowWidth(width);
8408     setWindowHeight(height);
8409 
8410     // Setup primary Texture
8411     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8412     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8413     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8414     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8415 
8416     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
8417     ASSERT_GL_NO_ERROR();
8418 
8419     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width / 2, height / 2, 0,
8420                            minImageSize, data);
8421     ASSERT_GL_NO_ERROR();
8422 
8423     glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_ETC1_RGB8_OES, width / 4, height / 4, 0,
8424                            minImageSize, data);
8425     ASSERT_GL_NO_ERROR();
8426 
8427     glUseProgram(mProgram);
8428     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
8429     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8430     drawQuad(mProgram, "position", 0.5f);
8431     ASSERT_GL_NO_ERROR();
8432 
8433     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
8434     drawQuad(mProgram, "position", 0.5f);
8435     ASSERT_GL_NO_ERROR();
8436 }
8437 
8438 // Define two NPOT compressed textures, set MAX_LEVEL, draw, and swap buffers
8439 // with the two textures. This used to cause release of staging buffers
8440 // that have not been flushed.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageDraws)8441 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageDraws)
8442 {
8443     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
8444     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
8445 
8446     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
8447     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
8448 
8449     const GLuint width  = 384u;
8450     const GLuint height = 384u;
8451     // round up to the nearest block size
8452     const GLsizei imageSize = width * height / 2;
8453 
8454     uint8_t data[imageSize] = {0};
8455 
8456     setWindowWidth(width);
8457     setWindowHeight(height);
8458 
8459     const GLuint smallerWidth  = 384u;
8460     const GLuint smallerHeight = 320u;
8461     // round up to the nearest block size
8462     const GLsizei smallerImageSize = smallerWidth * smallerHeight / 2;
8463 
8464     // Setup primary Texture
8465     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8466     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8467     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8468     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8469 
8470     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, smallerWidth, smallerHeight, 0,
8471                            smallerImageSize, data);
8472     ASSERT_GL_NO_ERROR();
8473 
8474     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 160, 0, 15360, data);
8475     ASSERT_GL_NO_ERROR();
8476 
8477     GLTexture largerTexture;
8478     glBindTexture(GL_TEXTURE_2D, largerTexture);
8479 
8480     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
8481     ASSERT_GL_NO_ERROR();
8482 
8483     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 192, 0, 18432, data);
8484     ASSERT_GL_NO_ERROR();
8485 
8486     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8487 
8488     glUseProgram(mProgram);
8489     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
8490     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8491     drawQuad(mProgram, "position", 0.5f);
8492     ASSERT_GL_NO_ERROR();
8493     swapBuffers();
8494     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
8495     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
8496     drawQuad(mProgram, "position", 0.5f);
8497     ASSERT_GL_NO_ERROR();
8498     swapBuffers();
8499 
8500     glBindTexture(GL_TEXTURE_2D, largerTexture);
8501 
8502     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
8503     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8504     drawQuad(mProgram, "position", 0.5f);
8505     ASSERT_GL_NO_ERROR();
8506     swapBuffers();
8507 
8508     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
8509     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
8510     drawQuad(mProgram, "position", 0.5f);
8511     ASSERT_GL_NO_ERROR();
8512     swapBuffers();
8513 
8514     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8515 
8516     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
8517     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8518     drawQuad(mProgram, "position", 0.5f);
8519     swapBuffers();
8520     ASSERT_GL_NO_ERROR();
8521 }
8522 
8523 // Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
8524 // MAX_LEVEL and draw.  This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1ShrinkThenGrowMaxLevels)8525 TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
8526 {
8527     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
8528     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
8529 
8530     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
8531     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
8532 
8533     const GLuint width  = 4u;
8534     const GLuint height = 4u;
8535 
8536     setWindowWidth(width);
8537     setWindowHeight(height);
8538 
8539     // Setup primary Texture
8540     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8541     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8542 
8543     if (getClientMajorVersion() < 3)
8544     {
8545         glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
8546     }
8547     else
8548     {
8549         glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
8550     }
8551     ASSERT_GL_NO_ERROR();
8552 
8553     // Populate a subimage of the texture
8554     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
8555                               width * height / 2u, kCompressedImageETC2);
8556     glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
8557                               width * height / 2u, kCompressedImageETC2);
8558     glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
8559                               width * height / 2u, kCompressedImageETC2);
8560     ASSERT_GL_NO_ERROR();
8561 
8562     // Set MAX_LEVEL to 2 (the highest level)
8563     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
8564 
8565     // Render and ensure we get red
8566     glUseProgram(mProgram);
8567     drawQuad(mProgram, "position", 0.5f);
8568     ASSERT_GL_NO_ERROR();
8569     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8570     ASSERT_GL_NO_ERROR();
8571 
8572     // Decrease MAX_LEVEL to 0, render, and ensure we still get red
8573     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8574     drawQuad(mProgram, "position", 0.5f);
8575     ASSERT_GL_NO_ERROR();
8576     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8577     ASSERT_GL_NO_ERROR();
8578 
8579     // Increase MAX_LEVEL back to 2, render, and ensure we still get red
8580     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
8581     drawQuad(mProgram, "position", 0.5f);
8582     ASSERT_GL_NO_ERROR();
8583     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8584     ASSERT_GL_NO_ERROR();
8585 }
8586 
8587 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
8588 // tests should be run against.
8589 #define ES2_EMULATE_COPY_TEX_IMAGE()                          \
8590     WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGL()), \
8591         WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGLES())
8592 #define ES3_EMULATE_COPY_TEX_IMAGE()                          \
8593     WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()), \
8594         WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES())
8595 ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ES2_EMULATE_COPY_TEX_IMAGE());
8596 ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
8597 ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
8598 ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
8599 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
8600 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
8601 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DTestES3, WithAllocateNonZeroMemory(ES3_VULKAN()));
8602 ANGLE_INSTANTIATE_TEST_ES31(Texture2DTestES31PPO);
8603 ANGLE_INSTANTIATE_TEST_ES3(Texture2DBaseMaxTestES3);
8604 ANGLE_INSTANTIATE_TEST_ES2(Texture3DTestES2);
8605 ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
8606 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
8607 ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
8608 ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
8609 ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
8610 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
8611 ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
8612 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
8613 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
8614 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
8615 ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
8616 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
8617 ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
8618 ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
8619 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
8620 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
8621 ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
8622 ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
8623 ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
8624                        ANGLE_ALL_TEST_PLATFORMS_ES2,
8625                        ANGLE_ALL_TEST_PLATFORMS_ES3,
8626                        ES2_EMULATE_COPY_TEX_IMAGE(),
8627                        ES3_EMULATE_COPY_TEX_IMAGE());
8628 ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
8629 ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
8630 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
8631 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
8632 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
8633 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
8634 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
8635 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
8636 ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
8637 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
8638 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
8639 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
8640 
8641 }  // anonymous namespace
8642