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