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