• 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 #include <limits>
12 
13 using namespace angle;
14 
15 namespace
16 {
17 
18 constexpr GLuint kPixelTolerance     = 1u;
19 constexpr GLfloat kPixelTolerance32F = 0.01f;
20 
21 // Single compressed ETC2 block of source pixels all set red
22 constexpr uint8_t kCompressedImageETC2[] = {0x7E, 0x80, 0x04, 0x7F, 0x00, 0x07, 0xE0, 0x00};
23 
24 // Take a pixel, and reset the components not covered by the format to default
25 // values. In particular, the default value for the alpha component is 255
26 // (1.0 as unsigned normalized fixed point value).
27 // For legacy formats, the components may be reordered to match the color that
28 // would be created if a pixel of that format was initialized from the given color
SliceFormatColor(GLenum format,GLColor full)29 GLColor SliceFormatColor(GLenum format, GLColor full)
30 {
31     switch (format)
32     {
33         case GL_RED:
34             return GLColor(full.R, 0, 0, 255u);
35         case GL_RG:
36             return GLColor(full.R, full.G, 0, 255u);
37         case GL_RGB:
38             return GLColor(full.R, full.G, full.B, 255u);
39         case GL_RGBA:
40             return full;
41         case GL_LUMINANCE:
42             return GLColor(full.R, full.R, full.R, 255u);
43         case GL_ALPHA:
44             return GLColor(0, 0, 0, full.R);
45         case GL_LUMINANCE_ALPHA:
46             return GLColor(full.R, full.R, full.R, full.G);
47         default:
48             EXPECT_TRUE(false);
49             return GLColor::white;
50     }
51 }
52 
SliceFormatColor16(GLenum format,GLColor16 full)53 GLColor16 SliceFormatColor16(GLenum format, GLColor16 full)
54 {
55     switch (format)
56     {
57         case GL_RED:
58             return GLColor16(full.R, 0, 0, 0xFFFF);
59         case GL_RG:
60             return GLColor16(full.R, full.G, 0, 0xFFFF);
61         case GL_RGB:
62             return GLColor16(full.R, full.G, full.B, 0xFFFF);
63         case GL_RGBA:
64             return full;
65         case GL_LUMINANCE:
66             return GLColor16(full.R, full.R, full.R, 0xFFFF);
67         case GL_ALPHA:
68             return GLColor16(0, 0, 0, full.R);
69         case GL_LUMINANCE_ALPHA:
70             return GLColor16(full.R, full.R, full.R, full.G);
71         default:
72             EXPECT_TRUE(false);
73             return GLColor16(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
74     }
75 }
76 
77 // As above, for 32F colors
SliceFormatColor32F(GLenum format,GLColor32F full)78 GLColor32F SliceFormatColor32F(GLenum format, GLColor32F full)
79 {
80     switch (format)
81     {
82         case GL_RED:
83             return GLColor32F(full.R, 0.0f, 0.0f, 1.0f);
84         case GL_RG:
85             return GLColor32F(full.R, full.G, 0.0f, 1.0f);
86         case GL_RGB:
87             return GLColor32F(full.R, full.G, full.B, 1.0f);
88         case GL_RGBA:
89             return full;
90         case GL_LUMINANCE:
91             return GLColor32F(full.R, full.R, full.R, 1.0f);
92         case GL_ALPHA:
93             return GLColor32F(0.0f, 0.0f, 0.0f, full.R);
94         case GL_LUMINANCE_ALPHA:
95             return GLColor32F(full.R, full.R, full.R, full.G);
96         default:
97             EXPECT_TRUE(false);
98             return GLColor32F(1.0f, 1.0f, 1.0f, 1.0f);
99     }
100 }
101 
102 class TexCoordDrawTest : public ANGLETest<>
103 {
104   protected:
TexCoordDrawTest()105     TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
106     {
107         setWindowWidth(128);
108         setWindowHeight(128);
109         setConfigRedBits(8);
110         setConfigGreenBits(8);
111         setConfigBlueBits(8);
112         setConfigAlphaBits(8);
113     }
114 
getVertexShaderSource()115     virtual const char *getVertexShaderSource()
116     {
117         return R"(precision highp float;
118 attribute vec4 position;
119 varying vec2 texcoord;
120 
121 void main()
122 {
123     gl_Position = vec4(position.xy, 0.0, 1.0);
124     texcoord = (position.xy * 0.5) + 0.5;
125 })";
126     }
127 
128     virtual const char *getFragmentShaderSource() = 0;
129 
setUpProgram()130     virtual void setUpProgram()
131     {
132         const char *vertexShaderSource   = getVertexShaderSource();
133         const char *fragmentShaderSource = getFragmentShaderSource();
134 
135         mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
136         ASSERT_NE(0u, mProgram);
137         ASSERT_GL_NO_ERROR();
138     }
139 
testSetUp()140     void testSetUp() override { setUpFramebuffer(); }
141 
testTearDown()142     void testTearDown() override
143     {
144         glBindFramebuffer(GL_FRAMEBUFFER, 0);
145         glDeleteFramebuffers(1, &mFramebuffer);
146         glDeleteTextures(1, &mFramebufferColorTexture);
147         glDeleteProgram(mProgram);
148     }
149 
setUpFramebuffer()150     void setUpFramebuffer()
151     {
152         // We use an FBO to work around an issue where the default framebuffer applies SRGB
153         // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
154         // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
155         // section 4.4 says that the format of the default framebuffer is entirely up to the window
156         // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
157         // SRGB conversion like desktop GL does.
158         // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
159         glGenFramebuffers(1, &mFramebuffer);
160         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
161 
162         glGenTextures(1, &mFramebufferColorTexture);
163         glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
164         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
165                      GL_UNSIGNED_BYTE, nullptr);
166         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
167                                mFramebufferColorTexture, 0);
168         ASSERT_GL_NO_ERROR();
169         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
170         glBindTexture(GL_TEXTURE_2D, 0);
171     }
172 
173     // Returns the created texture ID.
create2DTexture()174     GLuint create2DTexture()
175     {
176         GLuint texture2D;
177         glGenTextures(1, &texture2D);
178         glBindTexture(GL_TEXTURE_2D, texture2D);
179         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
180         EXPECT_GL_NO_ERROR();
181         return texture2D;
182     }
183 
184     GLuint mProgram;
185     GLuint mFramebuffer;
186 
187   protected:
188     GLuint mFramebufferColorTexture;
189 };
190 
191 class Texture2DTest : public TexCoordDrawTest
192 {
193   protected:
Texture2DTest()194     Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
195 
getFragmentShaderSource()196     const char *getFragmentShaderSource() override
197     {
198         return R"(precision highp float;
199 uniform sampler2D tex;
200 varying vec2 texcoord;
201 
202 void main()
203 {
204     gl_FragColor = texture2D(tex, texcoord);
205 })";
206     }
207 
getTextureUniformName()208     virtual const char *getTextureUniformName() { return "tex"; }
209 
setUpProgram()210     void setUpProgram() override
211     {
212         TexCoordDrawTest::setUpProgram();
213         mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
214         ASSERT_NE(-1, mTexture2DUniformLocation);
215     }
216 
testSetUp()217     void testSetUp() override
218     {
219         TexCoordDrawTest::testSetUp();
220         mTexture2D = create2DTexture();
221 
222         ASSERT_GL_NO_ERROR();
223     }
224 
testTearDown()225     void testTearDown() override
226     {
227         glDeleteTextures(1, &mTexture2D);
228         TexCoordDrawTest::testTearDown();
229     }
230 
231     // Tests CopyTexSubImage with floating point textures of various formats.
testFloatCopySubImage(int sourceImageChannels,int destImageChannels)232     void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
233     {
234         setUpProgram();
235 
236         if (getClientMajorVersion() < 3)
237         {
238             ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
239                                !IsGLExtensionEnabled("GL_OES_texture_float"));
240 
241             ANGLE_SKIP_TEST_IF((sourceImageChannels < 3 || destImageChannels < 3) &&
242                                !IsGLExtensionEnabled("GL_EXT_texture_rg"));
243 
244             ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
245                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
246 
247             ANGLE_SKIP_TEST_IF(destImageChannels == 4 &&
248                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"));
249 
250             ANGLE_SKIP_TEST_IF(destImageChannels <= 2);
251         }
252         else
253         {
254             ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_color_buffer_float"));
255 
256             ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
257                                !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
258         }
259 
260         // clang-format off
261         GLfloat sourceImageData[4][16] =
262         {
263             { // R
264                 1.0f,
265                 0.0f,
266                 0.0f,
267                 1.0f
268             },
269             { // RG
270                 1.0f, 0.0f,
271                 0.0f, 1.0f,
272                 0.0f, 0.0f,
273                 1.0f, 1.0f
274             },
275             { // RGB
276                 1.0f, 0.0f, 0.0f,
277                 0.0f, 1.0f, 0.0f,
278                 0.0f, 0.0f, 1.0f,
279                 1.0f, 1.0f, 0.0f
280             },
281             { // RGBA
282                 1.0f, 0.0f, 0.0f, 1.0f,
283                 0.0f, 1.0f, 0.0f, 1.0f,
284                 0.0f, 0.0f, 1.0f, 1.0f,
285                 1.0f, 1.0f, 0.0f, 1.0f
286             },
287         };
288         // clang-format on
289 
290         GLenum imageFormats[] = {
291             GL_R32F,
292             GL_RG32F,
293             GL_RGB32F,
294             GL_RGBA32F,
295         };
296 
297         GLenum sourceUnsizedFormats[] = {
298             GL_RED,
299             GL_RG,
300             GL_RGB,
301             GL_RGBA,
302         };
303 
304         GLTexture textures[2];
305 
306         GLfloat *imageData         = sourceImageData[sourceImageChannels - 1];
307         GLenum sourceImageFormat   = imageFormats[sourceImageChannels - 1];
308         GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
309         GLenum destImageFormat     = imageFormats[destImageChannels - 1];
310 
311         glBindTexture(GL_TEXTURE_2D, textures[0]);
312         if (getClientMajorVersion() >= 3)
313         {
314             glTexStorage2D(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
315         }
316         else
317         {
318             glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
319         }
320         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
321         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
322         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
323 
324         if (sourceImageChannels < 3 && !IsGLExtensionEnabled("GL_EXT_texture_rg"))
325         {
326             // This is not supported
327             ASSERT_GL_ERROR(GL_INVALID_OPERATION);
328         }
329         else
330         {
331             ASSERT_GL_NO_ERROR();
332         }
333 
334         GLuint fbo;
335         glGenFramebuffers(1, &fbo);
336         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
337         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
338 
339         glBindTexture(GL_TEXTURE_2D, textures[1]);
340         if (getClientMajorVersion() >= 3)
341         {
342             glTexStorage2D(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
343         }
344         else
345         {
346             glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
347         }
348         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350 
351         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
352         ASSERT_GL_NO_ERROR();
353 
354         glBindFramebuffer(GL_FRAMEBUFFER, 0);
355         drawQuad(mProgram, "position", 0.5f);
356 
357         int testImageChannels = std::min(sourceImageChannels, destImageChannels);
358 
359         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
360         if (testImageChannels > 1)
361         {
362             EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
363             EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
364             if (testImageChannels > 2)
365             {
366                 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
367             }
368         }
369 
370         glDeleteFramebuffers(1, &fbo);
371 
372         ASSERT_GL_NO_ERROR();
373     }
374 
375     void testTextureSize(int testCaseIndex);
376     void testTextureSizeError();
377 
378     struct UploadThenUseStageParam
379     {
380         GLenum useStage;
381         bool closeRenderPassAfterUse;
382     };
383 
384     void testUploadThenUseInDifferentStages(const std::vector<UploadThenUseStageParam> &uses);
385 
386     GLuint mTexture2D;
387     GLint mTexture2DUniformLocation;
388 };
389 
390 class Texture2DTestES3 : public Texture2DTest
391 {
392   protected:
Texture2DTestES3()393     Texture2DTestES3() : Texture2DTest() {}
394 
getVertexShaderSource()395     const char *getVertexShaderSource() override
396     {
397         return "#version 300 es\n"
398                "out vec2 texcoord;\n"
399                "in vec4 position;\n"
400                "void main()\n"
401                "{\n"
402                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
403                "    texcoord = (position.xy * 0.5) + 0.5;\n"
404                "}\n";
405     }
406 
getFragmentShaderSource()407     const char *getFragmentShaderSource() override
408     {
409         return "#version 300 es\n"
410                "precision highp float;\n"
411                "uniform highp sampler2D tex;\n"
412                "in vec2 texcoord;\n"
413                "out vec4 fragColor;\n"
414                "void main()\n"
415                "{\n"
416                "    fragColor = texture(tex, texcoord);\n"
417                "}\n";
418     }
419 
testSetUp()420     void testSetUp() override
421     {
422         Texture2DTest::testSetUp();
423         setUpProgram();
424     }
425 
createImmutableTexture2D(GLuint texture,size_t width,size_t height,GLenum format,GLenum internalFormat,GLenum type,GLsizei levels,GLubyte data[4])426     void createImmutableTexture2D(GLuint texture,
427                                   size_t width,
428                                   size_t height,
429                                   GLenum format,
430                                   GLenum internalFormat,
431                                   GLenum type,
432                                   GLsizei levels,
433                                   GLubyte data[4])
434     {
435         // Support only 1 level for now
436         ASSERT(levels == 1);
437 
438         glBindTexture(GL_TEXTURE_2D, texture);
439 
440         glTexStorage2D(GL_TEXTURE_2D, levels, internalFormat, width, height);
441         ASSERT_GL_NO_ERROR();
442 
443         if (data != nullptr)
444         {
445             glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data);
446             ASSERT_GL_NO_ERROR();
447         }
448 
449         // Disable mipmapping
450         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
451         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
452         ASSERT_GL_NO_ERROR();
453     }
454 
verifyResults2D(GLuint texture,GLubyte referenceColor[4])455     void verifyResults2D(GLuint texture, GLubyte referenceColor[4])
456     {
457         // Draw a quad with the target texture
458         glUseProgram(mProgram);
459         glBindTexture(GL_TEXTURE_2D, texture);
460         glUniform1i(mTexture2DUniformLocation, 0);
461 
462         drawQuad(mProgram, "position", 0.5f);
463 
464         // Expect that the rendered quad's color is the same as the reference color with a tolerance
465         // of 1
466         EXPECT_PIXEL_NEAR(0, 0, referenceColor[0], referenceColor[1], referenceColor[2],
467                           referenceColor[3], 1);
468     }
469 
470     void testCopyImage(const APIExtensionVersion usedExtension);
471     void testCopyImageDepthStencil(const APIExtensionVersion usedExtension);
472 };
473 
474 class MultisampleTexture2DTestES31 : public Texture2DTest
475 {
476   protected:
MultisampleTexture2DTestES31()477     MultisampleTexture2DTestES31() : Texture2DTest() {}
478 
479     void testCopyMultisampleImage(const APIExtensionVersion usedExtension,
480                                   const GLenum internalFormat);
481     void testCopyMultisampleArrayImage(const APIExtensionVersion usedExtension,
482                                        const GLenum internalFormat);
483 };
484 
485 class Texture2DMemoryTestES3 : public Texture2DTestES3
486 {
487   protected:
getPerfCounters()488     angle::VulkanPerfCounters getPerfCounters()
489     {
490         if (mIndexMap.empty())
491         {
492             mIndexMap = BuildCounterNameToIndexMap();
493         }
494 
495         return GetPerfCounters(mIndexMap);
496     }
497 
498     CounterNameToIndexMap mIndexMap;
499 };
500 
501 class Texture2DTestES3YUV : public Texture2DTestES3
502 {};
503 
504 class Texture2DTestES3RobustInit : public Texture2DTestES3
505 {
506   protected:
Texture2DTestES3RobustInit()507     Texture2DTestES3RobustInit() : Texture2DTestES3() { setRobustResourceInit(true); }
508 };
509 
510 class Texture2DTestES3Foveation : public Texture2DTestES3
511 {
512   protected:
Texture2DTestES3Foveation()513     Texture2DTestES3Foveation() : Texture2DTestES3()
514     {
515         setWindowWidth(256);
516         setWindowHeight(256);
517     }
518 };
519 
520 class Texture2DTestES31Foveation : public Texture2DTestES3Foveation
521 {};
522 
523 class Texture2DBaseMaxTestES3 : public ANGLETest<>
524 {
525   protected:
526     static constexpr size_t kMip0Size   = 13;
527     static constexpr uint32_t kMipCount = 4;
528 
Texture2DBaseMaxTestES3()529     Texture2DBaseMaxTestES3() : ANGLETest(), mTextureLocation(0), mLodLocation(0)
530     {
531         setWindowWidth(128);
532         setWindowHeight(128);
533         setConfigRedBits(8);
534         setConfigGreenBits(8);
535         setConfigBlueBits(8);
536         setConfigAlphaBits(8);
537     }
538 
getMipDataSize(size_t mip0Size,size_t mip)539     static constexpr size_t getMipDataSize(size_t mip0Size, size_t mip)
540     {
541         size_t mipSize = std::max<size_t>(1u, mip0Size >> mip);
542         return mipSize * mipSize;
543     }
544 
getTotalMipDataSize(size_t mip0Size)545     static constexpr size_t getTotalMipDataSize(size_t mip0Size)
546     {
547         size_t totalCount = 0;
548         for (size_t mip = 0; mip < kMipCount; ++mip)
549         {
550             totalCount += getMipDataSize(mip0Size, mip);
551         }
552         return totalCount;
553     }
554 
getMipDataOffset(size_t mip0Size,size_t mip)555     static constexpr size_t getMipDataOffset(size_t mip0Size, size_t mip)
556     {
557         // This calculates:
558         //
559         //     mip == 0: 0
560         //     o.w.:     sum(0, mip-1) getMipDataSize(i)
561         //
562         // The above can be calculated simply as:
563         //
564         //     (mip0 >> (kMipCount-1))^2 * (0x55555555 & ((1 << (2*mip)) - 1))
565         //     \__________  ___________/   \_______________  ________________/
566         //                \/                               \/
567         //          last mip size                 sum(0, mip-1) (4^i)
568         //
569         // But let's loop explicitly for clarity.
570         size_t offset = 0;
571         for (size_t m = 0; m < mip; ++m)
572         {
573             offset += getMipDataSize(mip0Size, m);
574         }
575         return offset;
576     }
577 
578     template <typename colorType = GLColor>
fillMipData(colorType * data,size_t mip0Size,const colorType mipColors[kMipCount])579     void fillMipData(colorType *data, size_t mip0Size, const colorType mipColors[kMipCount])
580     {
581         for (size_t mip = 0; mip < kMipCount; ++mip)
582         {
583             size_t offset = getMipDataOffset(mip0Size, mip);
584             size_t size   = getMipDataSize(mip0Size, mip);
585             std::fill(data + offset, data + offset + size, mipColors[mip]);
586         }
587     }
588 
initTest(bool immutable)589     void initTest(bool immutable)
590     {
591         // Set up program to sample from specific lod level.
592         mProgram.makeRaster(essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
593         ASSERT(mProgram.valid());
594 
595         glUseProgram(mProgram);
596 
597         mTextureLocation = glGetUniformLocation(mProgram, essl3_shaders::Texture2DUniform());
598         ASSERT_NE(-1, mTextureLocation);
599 
600         mLodLocation = glGetUniformLocation(mProgram, essl3_shaders::LodUniform());
601         ASSERT_NE(-1, mLodLocation);
602 
603         // Set up texture with a handful of lods.
604         glActiveTexture(GL_TEXTURE0);
605         glBindTexture(GL_TEXTURE_2D, mTexture);
606 
607         std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
608         fillMipData(mipData.data(), kMip0Size, kMipColors);
609 
610         if (immutable)
611         {
612             glTexStorage2D(GL_TEXTURE_2D, kMipCount, GL_RGBA8, kMip0Size, kMip0Size);
613             for (size_t mip = 0; mip < kMipCount; ++mip)
614             {
615                 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip,
616                                 GL_RGBA, GL_UNSIGNED_BYTE,
617                                 mipData.data() + getMipDataOffset(kMip0Size, mip));
618             }
619         }
620         else
621         {
622             for (size_t mip = 0; mip < kMipCount; ++mip)
623             {
624                 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0,
625                              GL_RGBA, GL_UNSIGNED_BYTE,
626                              mipData.data() + getMipDataOffset(kMip0Size, mip));
627             }
628         }
629 
630         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
631         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
632 
633         EXPECT_GL_NO_ERROR();
634     }
635 
setLodUniform(uint32_t lod)636     void setLodUniform(uint32_t lod) { glUniform1f(mLodLocation, lod); }
637 
638     void testPingPongBaseLevel(bool immutable);
639     void testGenerateMipmapAfterRebase(bool immutable);
640 
641     GLProgram mProgram;
642     GLTexture mTexture;
643     GLint mTextureLocation;
644     GLint mLodLocation;
645 
646     const GLColor kMipColors[kMipCount] = {
647         GLColor::red,
648         GLColor::green,
649         GLColor::blue,
650         GLColor::magenta,
651     };
652 };
653 
654 class TextureES31PPO
655 {
656   protected:
TextureES31PPO()657     TextureES31PPO() : mVertProg(0), mFragProg(0), mPipeline(0) {}
658 
get2DTexturedVertexShaderSource()659     const char *get2DTexturedVertexShaderSource()
660     {
661         return "#version 310 es\n"
662                "precision mediump float;\n"
663                "in vec2 position;\n"
664                "out vec2 texCoord;\n"
665                "void main()\n"
666                "{\n"
667                "    gl_Position = vec4(position, 0, 1);\n"
668                "    texCoord = position * 0.5 + vec2(0.5);\n"
669                "}";
670     }
671 
get2DTexturedFragmentShaderSource()672     const char *get2DTexturedFragmentShaderSource()
673     {
674         return "#version 310 es\n"
675                "precision mediump float;\n"
676                "in vec2 texCoord;\n"
677                "uniform sampler2D tex1;\n"
678                "uniform sampler2D tex2;\n"
679                "uniform sampler2D tex3;\n"
680                "uniform sampler2D tex4;\n"
681                "out vec4 color;\n"
682                "void main()\n"
683                "{\n"
684                "    color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
685                "          +  texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
686                "}";
687     }
688 
bindProgramPipeline(const GLchar * vertString,const GLchar * fragString)689     void bindProgramPipeline(const GLchar *vertString, const GLchar *fragString)
690     {
691         mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
692         ASSERT_NE(mVertProg, 0u);
693         mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
694         ASSERT_NE(mFragProg, 0u);
695 
696         // Generate a program pipeline and attach the programs to their respective stages
697         glGenProgramPipelines(1, &mPipeline);
698         EXPECT_GL_NO_ERROR();
699         glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
700         EXPECT_GL_NO_ERROR();
701         glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
702         EXPECT_GL_NO_ERROR();
703         glBindProgramPipeline(mPipeline);
704         EXPECT_GL_NO_ERROR();
705     }
706 
bind2DTexturedQuadProgramPipeline()707     void bind2DTexturedQuadProgramPipeline()
708     {
709         const char *vertexShaderSource   = get2DTexturedVertexShaderSource();
710         const char *fragmentShaderSource = get2DTexturedFragmentShaderSource();
711 
712         m2DTexturedQuadVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertexShaderSource);
713         ASSERT_NE(m2DTexturedQuadVertProg, 0u);
714         m2DTexturedQuadFragProg =
715             glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentShaderSource);
716         ASSERT_NE(m2DTexturedQuadFragProg, 0u);
717 
718         // Generate a program pipeline and attach the programs to their respective stages
719         glGenProgramPipelines(1, &m2DTexturedQuadPipeline);
720         EXPECT_GL_NO_ERROR();
721         glUseProgramStages(m2DTexturedQuadPipeline, GL_VERTEX_SHADER_BIT, m2DTexturedQuadVertProg);
722         EXPECT_GL_NO_ERROR();
723         glUseProgramStages(m2DTexturedQuadPipeline, GL_FRAGMENT_SHADER_BIT,
724                            m2DTexturedQuadFragProg);
725         EXPECT_GL_NO_ERROR();
726         glBindProgramPipeline(m2DTexturedQuadPipeline);
727         EXPECT_GL_NO_ERROR();
728     }
729 
ppoDrawQuad(std::array<Vector3,6> & quadVertices,const std::string & positionAttribName,const GLfloat positionAttribZ,const GLfloat positionAttribXYScale)730     void ppoDrawQuad(std::array<Vector3, 6> &quadVertices,
731                      const std::string &positionAttribName,
732                      const GLfloat positionAttribZ,
733                      const GLfloat positionAttribXYScale)
734     {
735         glUseProgram(0);
736 
737         for (Vector3 &vertex : quadVertices)
738         {
739             vertex.x() *= positionAttribXYScale;
740             vertex.y() *= positionAttribXYScale;
741             vertex.z() = positionAttribZ;
742         }
743 
744         GLint positionLocation = glGetAttribLocation(mVertProg, positionAttribName.c_str());
745 
746         glBindBuffer(GL_ARRAY_BUFFER, 0);
747         glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
748         glEnableVertexAttribArray(positionLocation);
749 
750         glDrawArrays(GL_TRIANGLES, 0, 6);
751 
752         glDisableVertexAttribArray(positionLocation);
753         glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
754     }
755 
756     GLuint mVertProg;
757     GLuint mFragProg;
758     GLuint mPipeline;
759     GLuint m2DTexturedQuadVertProg;
760     GLuint m2DTexturedQuadFragProg;
761     GLuint m2DTexturedQuadPipeline;
762 };
763 
764 class Texture2DTestES31PPO : public TextureES31PPO, public Texture2DTest
765 {
766   protected:
Texture2DTestES31PPO()767     Texture2DTestES31PPO() : TextureES31PPO(), Texture2DTest() {}
768 
testSetUp()769     void testSetUp() override { Texture2DTest::testSetUp(); }
770 };
771 
772 class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
773 {
774   protected:
Texture2DIntegerAlpha1TestES3()775     Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
776 
getVertexShaderSource()777     const char *getVertexShaderSource() override
778     {
779         return "#version 300 es\n"
780                "out vec2 texcoord;\n"
781                "in vec4 position;\n"
782                "void main()\n"
783                "{\n"
784                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
785                "    texcoord = (position.xy * 0.5) + 0.5;\n"
786                "}\n";
787     }
788 
getFragmentShaderSource()789     const char *getFragmentShaderSource() override
790     {
791         return "#version 300 es\n"
792                "precision highp float;\n"
793                "uniform highp isampler2D tex;\n"
794                "in vec2 texcoord;\n"
795                "out vec4 fragColor;\n"
796                "void main()\n"
797                "{\n"
798                "    vec4 green = vec4(0, 1, 0, 1);\n"
799                "    vec4 black = vec4(0, 0, 0, 0);\n"
800                "    fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
801                "}\n";
802     }
803 
testSetUp()804     void testSetUp() override
805     {
806         Texture2DTest::testSetUp();
807         setUpProgram();
808     }
809 };
810 
811 class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
812 {
813   protected:
Texture2DUnsignedIntegerAlpha1TestES3()814     Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
815 
getVertexShaderSource()816     const char *getVertexShaderSource() override
817     {
818         return "#version 300 es\n"
819                "out vec2 texcoord;\n"
820                "in vec4 position;\n"
821                "void main()\n"
822                "{\n"
823                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
824                "    texcoord = (position.xy * 0.5) + 0.5;\n"
825                "}\n";
826     }
827 
getFragmentShaderSource()828     const char *getFragmentShaderSource() override
829     {
830         return "#version 300 es\n"
831                "precision highp float;\n"
832                "uniform highp usampler2D tex;\n"
833                "in vec2 texcoord;\n"
834                "out vec4 fragColor;\n"
835                "void main()\n"
836                "{\n"
837                "    vec4 green = vec4(0, 1, 0, 1);\n"
838                "    vec4 black = vec4(0, 0, 0, 0);\n"
839                "    fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
840                "}\n";
841     }
842 
testSetUp()843     void testSetUp() override
844     {
845         Texture2DTest::testSetUp();
846         setUpProgram();
847     }
848 };
849 
850 class Texture2DTestWithDrawScale : public Texture2DTest
851 {
852   protected:
Texture2DTestWithDrawScale()853     Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
854 
getVertexShaderSource()855     const char *getVertexShaderSource() override
856     {
857         return
858             R"(precision highp float;
859             attribute vec4 position;
860             varying vec2 texcoord;
861 
862             uniform vec2 drawScale;
863 
864             void main()
865             {
866                 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
867                 texcoord = (position.xy * 0.5) + 0.5;
868             })";
869     }
870 
testSetUp()871     void testSetUp() override
872     {
873         Texture2DTest::testSetUp();
874 
875         setUpProgram();
876 
877         mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
878         ASSERT_NE(-1, mDrawScaleUniformLocation);
879 
880         glUseProgram(mProgram);
881         glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
882         glUseProgram(0);
883         ASSERT_GL_NO_ERROR();
884     }
885 
886     GLint mDrawScaleUniformLocation;
887 };
888 
889 class Sampler2DAsFunctionParameterTest : public Texture2DTest
890 {
891   protected:
Sampler2DAsFunctionParameterTest()892     Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
893 
getFragmentShaderSource()894     const char *getFragmentShaderSource() override
895     {
896         return
897             R"(precision highp float;
898             uniform sampler2D tex;
899             varying vec2 texcoord;
900 
901             vec4 computeFragColor(sampler2D aTex)
902             {
903                 return texture2D(aTex, texcoord);
904             }
905 
906             void main()
907             {
908                 gl_FragColor = computeFragColor(tex);
909             })";
910     }
911 
testSetUp()912     void testSetUp() override
913     {
914         Texture2DTest::testSetUp();
915         setUpProgram();
916     }
917 };
918 
919 class TextureCubeTest : public TexCoordDrawTest
920 {
921   protected:
TextureCubeTest()922     TextureCubeTest()
923         : TexCoordDrawTest(),
924           mTexture2D(0),
925           mTextureCube(0),
926           mTexture2DUniformLocation(-1),
927           mTextureCubeUniformLocation(-1)
928     {}
929 
getFragmentShaderSource()930     const char *getFragmentShaderSource() override
931     {
932         return
933             R"(precision highp float;
934             uniform sampler2D tex2D;
935             uniform samplerCube texCube;
936             uniform int cubeFace;
937             varying vec2 texcoord;
938 
939             void main()
940             {
941                 gl_FragColor = texture2D(tex2D, texcoord);
942 
943                 vec2 scaled = vec2(1) - vec2(2) * texcoord.xy;
944                 vec3 cubecoord = vec3(1, scaled.xy);
945                 if (cubeFace == 1)
946                     cubecoord = vec3(-1, scaled.xy);
947                 else if (cubeFace == 2)
948                     cubecoord = vec3(scaled.x, 1, scaled.y);
949                 else if (cubeFace == 3)
950                     cubecoord = vec3(scaled.x, -1, scaled.y);
951                 else if (cubeFace == 4)
952                     cubecoord = vec3(scaled.xy, 1);
953                 else if (cubeFace == 5)
954                     cubecoord = vec3(scaled.xy, -1);
955 
956                 gl_FragColor += textureCube(texCube, cubecoord);
957             })";
958     }
959 
testSetUp()960     void testSetUp() override
961     {
962         TexCoordDrawTest::testSetUp();
963 
964         glGenTextures(1, &mTextureCube);
965         glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
966         for (GLenum face = 0; face < 6; face++)
967         {
968             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
969                          GL_UNSIGNED_BYTE, nullptr);
970         }
971         EXPECT_GL_NO_ERROR();
972 
973         mTexture2D = create2DTexture();
974 
975         setUpProgram();
976 
977         mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
978         ASSERT_NE(-1, mTexture2DUniformLocation);
979         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
980         ASSERT_NE(-1, mTextureCubeUniformLocation);
981         mTextureCubeFaceUniformLocation = glGetUniformLocation(mProgram, "cubeFace");
982         ASSERT_NE(-1, mTextureCubeFaceUniformLocation);
983     }
984 
testTearDown()985     void testTearDown() override
986     {
987         glDeleteTextures(1, &mTextureCube);
988         TexCoordDrawTest::testTearDown();
989     }
990 
991     GLuint mTexture2D;
992     GLuint mTextureCube;
993     GLint mTexture2DUniformLocation;
994     GLint mTextureCubeUniformLocation;
995     GLint mTextureCubeFaceUniformLocation;
996 };
997 
998 class TextureCubeTestES3 : public TextureCubeTest
999 {
1000   protected:
TextureCubeTestES3()1001     TextureCubeTestES3() {}
1002 };
1003 
1004 class TextureCubeTestES32 : public TextureCubeTest
1005 {
1006   protected:
TextureCubeTestES32()1007     TextureCubeTestES32() {}
1008 };
1009 
1010 class SamplerArrayTest : public TexCoordDrawTest
1011 {
1012   protected:
SamplerArrayTest()1013     SamplerArrayTest()
1014         : TexCoordDrawTest(),
1015           mTexture2DA(0),
1016           mTexture2DB(0),
1017           mTexture0UniformLocation(-1),
1018           mTexture1UniformLocation(-1)
1019     {}
1020 
getFragmentShaderSource()1021     const char *getFragmentShaderSource() override
1022     {
1023         return
1024             R"(precision mediump float;
1025             uniform highp sampler2D tex2DArray[2];
1026             varying vec2 texcoord;
1027             void main()
1028             {
1029                 gl_FragColor = texture2D(tex2DArray[0], texcoord);
1030                 gl_FragColor += texture2D(tex2DArray[1], texcoord);
1031             })";
1032     }
1033 
testSetUp()1034     void testSetUp() override
1035     {
1036         TexCoordDrawTest::testSetUp();
1037 
1038         setUpProgram();
1039 
1040         mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
1041         ASSERT_NE(-1, mTexture0UniformLocation);
1042         mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
1043         ASSERT_NE(-1, mTexture1UniformLocation);
1044 
1045         mTexture2DA = create2DTexture();
1046         mTexture2DB = create2DTexture();
1047         ASSERT_GL_NO_ERROR();
1048     }
1049 
testTearDown()1050     void testTearDown() override
1051     {
1052         glDeleteTextures(1, &mTexture2DA);
1053         glDeleteTextures(1, &mTexture2DB);
1054         TexCoordDrawTest::testTearDown();
1055     }
1056 
testSamplerArrayDraw()1057     void testSamplerArrayDraw()
1058     {
1059         GLubyte texData[4];
1060         texData[0] = 0;
1061         texData[1] = 60;
1062         texData[2] = 0;
1063         texData[3] = 255;
1064 
1065         glActiveTexture(GL_TEXTURE0);
1066         glBindTexture(GL_TEXTURE_2D, mTexture2DA);
1067         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1068 
1069         texData[1] = 120;
1070         glActiveTexture(GL_TEXTURE1);
1071         glBindTexture(GL_TEXTURE_2D, mTexture2DB);
1072         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1073         EXPECT_GL_ERROR(GL_NO_ERROR);
1074 
1075         glUseProgram(mProgram);
1076         glUniform1i(mTexture0UniformLocation, 0);
1077         glUniform1i(mTexture1UniformLocation, 1);
1078         drawQuad(mProgram, "position", 0.5f);
1079         EXPECT_GL_NO_ERROR();
1080 
1081         EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
1082     }
1083 
1084     GLuint mTexture2DA;
1085     GLuint mTexture2DB;
1086     GLint mTexture0UniformLocation;
1087     GLint mTexture1UniformLocation;
1088 };
1089 
1090 class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
1091 {
1092   protected:
SamplerArrayAsFunctionParameterTest()1093     SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
1094 
getFragmentShaderSource()1095     const char *getFragmentShaderSource() override
1096     {
1097         return
1098             R"(precision mediump float;
1099             uniform highp sampler2D tex2DArray[2];
1100             varying vec2 texcoord;
1101 
1102             vec4 computeFragColor(highp sampler2D aTex2DArray[2])
1103             {
1104                 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
1105             }
1106 
1107             void main()
1108             {
1109                 gl_FragColor = computeFragColor(tex2DArray);
1110             })";
1111     }
1112 };
1113 
1114 class Texture2DArrayTestES3 : public TexCoordDrawTest
1115 {
1116   protected:
Texture2DArrayTestES3()1117     Texture2DArrayTestES3()
1118         : TexCoordDrawTest(),
1119           m2DArrayTexture(0),
1120           mTextureArrayLocation(-1),
1121           mTextureArraySliceUniformLocation(-1)
1122     {}
1123 
getVertexShaderSource()1124     const char *getVertexShaderSource() override
1125     {
1126         return R"(#version 300 es
1127 out vec2 texcoord;
1128 in vec4 position;
1129 void main()
1130 {
1131     gl_Position = vec4(position.xy, 0.0, 1.0);
1132     texcoord = (position.xy * 0.5) + 0.5;
1133 })";
1134     }
1135 
getFragmentShaderSource()1136     const char *getFragmentShaderSource() override
1137     {
1138         return R"(#version 300 es
1139 precision highp float;
1140 uniform highp sampler2DArray tex2DArray;
1141 uniform int slice;
1142 in vec2 texcoord;
1143 out vec4 fragColor;
1144 void main()
1145 {
1146     fragColor = texture(tex2DArray, vec3(texcoord, float(slice)));
1147 })";
1148     }
1149 
testSetUp()1150     void testSetUp() override
1151     {
1152         TexCoordDrawTest::testSetUp();
1153 
1154         setUpProgram();
1155 
1156         mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
1157         ASSERT_NE(-1, mTextureArrayLocation);
1158 
1159         mTextureArraySliceUniformLocation = glGetUniformLocation(mProgram, "slice");
1160         ASSERT_NE(-1, mTextureArraySliceUniformLocation);
1161 
1162         glGenTextures(1, &m2DArrayTexture);
1163         ASSERT_GL_NO_ERROR();
1164     }
1165 
testTearDown()1166     void testTearDown() override
1167     {
1168         glDeleteTextures(1, &m2DArrayTexture);
1169         TexCoordDrawTest::testTearDown();
1170     }
1171 
1172     GLuint m2DArrayTexture;
1173     GLint mTextureArrayLocation;
1174     GLint mTextureArraySliceUniformLocation;
1175 };
1176 
1177 class TextureSizeTextureArrayTest : public TexCoordDrawTest
1178 {
1179   protected:
TextureSizeTextureArrayTest()1180     TextureSizeTextureArrayTest()
1181         : TexCoordDrawTest(),
1182           mTexture2DA(0),
1183           mTexture2DB(0),
1184           mTexture0Location(-1),
1185           mTexture1Location(-1)
1186     {}
1187 
getVertexShaderSource()1188     const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
1189 
getFragmentShaderSource()1190     const char *getFragmentShaderSource() override
1191     {
1192         return "#version 300 es\n"
1193                "precision highp float;\n"
1194                "uniform highp sampler2D tex2DArray[2];\n"
1195                "out vec4 fragColor;\n"
1196                "void main()\n"
1197                "{\n"
1198                "    float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
1199                "    float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
1200                "    fragColor = vec4(red, green, 0.0, 1.0);\n"
1201                "}\n";
1202     }
1203 
testSetUp()1204     void testSetUp() override
1205     {
1206         TexCoordDrawTest::testSetUp();
1207 
1208         setUpProgram();
1209 
1210         mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
1211         ASSERT_NE(-1, mTexture0Location);
1212         mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
1213         ASSERT_NE(-1, mTexture1Location);
1214 
1215         mTexture2DA = create2DTexture();
1216         mTexture2DB = create2DTexture();
1217         ASSERT_GL_NO_ERROR();
1218     }
1219 
testTearDown()1220     void testTearDown() override
1221     {
1222         glDeleteTextures(1, &mTexture2DA);
1223         glDeleteTextures(1, &mTexture2DB);
1224         TexCoordDrawTest::testTearDown();
1225     }
1226 
1227     GLuint mTexture2DA;
1228     GLuint mTexture2DB;
1229     GLint mTexture0Location;
1230     GLint mTexture1Location;
1231 };
1232 
1233 // Test for GL_OES_texture_3D extension
1234 class Texture3DTestES2 : public TexCoordDrawTest
1235 {
1236   protected:
Texture3DTestES2()1237     Texture3DTestES2() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
1238 
getVertexShaderSource()1239     const char *getVertexShaderSource() override
1240     {
1241         return "#version 100\n"
1242                "varying vec2 texcoord;\n"
1243                "attribute vec4 position;\n"
1244                "void main()\n"
1245                "{\n"
1246                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1247                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1248                "}\n";
1249     }
1250 
getFragmentShaderSource()1251     const char *getFragmentShaderSource() override
1252     {
1253         if (!hasTexture3DExt())
1254         {
1255             return "#version 100\n"
1256                    "precision highp float;\n"
1257                    "varying vec2 texcoord;\n"
1258                    "void main()\n"
1259                    "{\n"
1260                    "    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1261                    "}\n";
1262         }
1263         return "#version 100\n"
1264                "#extension GL_OES_texture_3D : enable\n"
1265                "precision highp float;\n"
1266                "uniform highp sampler3D tex3D;\n"
1267                "uniform highp float level;\n"
1268                "varying vec2 texcoord;\n"
1269                "void main()\n"
1270                "{\n"
1271                "    gl_FragColor = texture3DLod(tex3D, vec3(texcoord, 0.0), level);\n"
1272                "}\n";
1273     }
1274 
testSetUp()1275     void testSetUp() override
1276     {
1277         // http://anglebug.com/42264265
1278         ANGLE_SKIP_TEST_IF(IsOzone());
1279 
1280         TexCoordDrawTest::testSetUp();
1281 
1282         glGenTextures(1, &mTexture3D);
1283 
1284         setUpProgram();
1285 
1286         mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1287         if (hasTexture3DExt())
1288         {
1289             ASSERT_NE(-1, mTexture3DUniformLocation);
1290         }
1291     }
1292 
testTearDown()1293     void testTearDown() override
1294     {
1295         glDeleteTextures(1, &mTexture3D);
1296         TexCoordDrawTest::testTearDown();
1297     }
1298 
hasTexture3DExt() const1299     bool hasTexture3DExt() const
1300     {
1301         // http://anglebug.com/42263501
1302         if ((IsPixel2() || IsNexus5X()) && IsOpenGLES())
1303         {
1304             return false;
1305         }
1306         return IsGLExtensionEnabled("GL_OES_texture_3D");
1307     }
1308 
1309     GLuint mTexture3D;
1310     GLint mTexture3DUniformLocation;
1311 };
1312 
1313 class Texture3DTestES3 : public Texture3DTestES2
1314 {
1315   protected:
Texture3DTestES3()1316     Texture3DTestES3() : Texture3DTestES2() {}
1317 
getVertexShaderSource()1318     const char *getVertexShaderSource() override
1319     {
1320         return "#version 300 es\n"
1321                "out vec2 texcoord;\n"
1322                "in vec4 position;\n"
1323                "void main()\n"
1324                "{\n"
1325                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1326                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1327                "}\n";
1328     }
1329 
getFragmentShaderSource()1330     const char *getFragmentShaderSource() override
1331     {
1332         return "#version 300 es\n"
1333                "precision highp float;\n"
1334                "uniform highp sampler3D tex3D;\n"
1335                "in vec2 texcoord;\n"
1336                "out vec4 fragColor;\n"
1337                "void main()\n"
1338                "{\n"
1339                "    fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
1340                "}\n";
1341     }
1342 };
1343 
1344 class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
1345 {
1346   protected:
ShadowSamplerPlusSampler3DTestES3()1347     ShadowSamplerPlusSampler3DTestES3()
1348         : TexCoordDrawTest(),
1349           mTextureShadow(0),
1350           mTexture3D(0),
1351           mTextureShadowUniformLocation(-1),
1352           mTexture3DUniformLocation(-1),
1353           mDepthRefUniformLocation(-1)
1354     {}
1355 
getVertexShaderSource()1356     const char *getVertexShaderSource() override
1357     {
1358         return "#version 300 es\n"
1359                "out vec2 texcoord;\n"
1360                "in vec4 position;\n"
1361                "void main()\n"
1362                "{\n"
1363                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1364                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1365                "}\n";
1366     }
1367 
getFragmentShaderSource()1368     const char *getFragmentShaderSource() override
1369     {
1370         return "#version 300 es\n"
1371                "precision highp float;\n"
1372                "uniform highp sampler2DShadow tex2DShadow;\n"
1373                "uniform highp sampler3D tex3D;\n"
1374                "in vec2 texcoord;\n"
1375                "uniform float depthRef;\n"
1376                "out vec4 fragColor;\n"
1377                "void main()\n"
1378                "{\n"
1379                "    fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
1380                "    fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
1381                "}\n";
1382     }
1383 
testSetUp()1384     void testSetUp() override
1385     {
1386         TexCoordDrawTest::testSetUp();
1387 
1388         glGenTextures(1, &mTexture3D);
1389 
1390         glGenTextures(1, &mTextureShadow);
1391         glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1392         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1393 
1394         setUpProgram();
1395 
1396         mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1397         ASSERT_NE(-1, mTextureShadowUniformLocation);
1398         mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1399         ASSERT_NE(-1, mTexture3DUniformLocation);
1400         mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1401         ASSERT_NE(-1, mDepthRefUniformLocation);
1402     }
1403 
testTearDown()1404     void testTearDown() override
1405     {
1406         glDeleteTextures(1, &mTextureShadow);
1407         glDeleteTextures(1, &mTexture3D);
1408         TexCoordDrawTest::testTearDown();
1409     }
1410 
1411     GLuint mTextureShadow;
1412     GLuint mTexture3D;
1413     GLint mTextureShadowUniformLocation;
1414     GLint mTexture3DUniformLocation;
1415     GLint mDepthRefUniformLocation;
1416 };
1417 
1418 class SamplerTypeMixTestES3 : public TexCoordDrawTest
1419 {
1420   protected:
SamplerTypeMixTestES3()1421     SamplerTypeMixTestES3()
1422         : TexCoordDrawTest(),
1423           mTexture2D(0),
1424           mTextureCube(0),
1425           mTexture2DShadow(0),
1426           mTextureCubeShadow(0),
1427           mTexture2DUniformLocation(-1),
1428           mTextureCubeUniformLocation(-1),
1429           mTexture2DShadowUniformLocation(-1),
1430           mTextureCubeShadowUniformLocation(-1),
1431           mDepthRefUniformLocation(-1)
1432     {}
1433 
getVertexShaderSource()1434     const char *getVertexShaderSource() override
1435     {
1436         return "#version 300 es\n"
1437                "out vec2 texcoord;\n"
1438                "in vec4 position;\n"
1439                "void main()\n"
1440                "{\n"
1441                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1442                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1443                "}\n";
1444     }
1445 
getFragmentShaderSource()1446     const char *getFragmentShaderSource() override
1447     {
1448         return "#version 300 es\n"
1449                "precision highp float;\n"
1450                "uniform highp sampler2D tex2D;\n"
1451                "uniform highp samplerCube texCube;\n"
1452                "uniform highp sampler2DShadow tex2DShadow;\n"
1453                "uniform highp samplerCubeShadow texCubeShadow;\n"
1454                "in vec2 texcoord;\n"
1455                "uniform float depthRef;\n"
1456                "out vec4 fragColor;\n"
1457                "void main()\n"
1458                "{\n"
1459                "    fragColor = texture(tex2D, texcoord);\n"
1460                "    fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1461                "    fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1462                "    fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1463                "0.125);\n"
1464                "}\n";
1465     }
1466 
testSetUp()1467     void testSetUp() override
1468     {
1469         TexCoordDrawTest::testSetUp();
1470 
1471         glGenTextures(1, &mTexture2D);
1472         glGenTextures(1, &mTextureCube);
1473 
1474         glGenTextures(1, &mTexture2DShadow);
1475         glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1476         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1477 
1478         glGenTextures(1, &mTextureCubeShadow);
1479         glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1480         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1481 
1482         setUpProgram();
1483 
1484         mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1485         ASSERT_NE(-1, mTexture2DUniformLocation);
1486         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1487         ASSERT_NE(-1, mTextureCubeUniformLocation);
1488         mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1489         ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1490         mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1491         ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1492         mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1493         ASSERT_NE(-1, mDepthRefUniformLocation);
1494 
1495         ASSERT_GL_NO_ERROR();
1496     }
1497 
testTearDown()1498     void testTearDown() override
1499     {
1500         glDeleteTextures(1, &mTexture2D);
1501         glDeleteTextures(1, &mTextureCube);
1502         glDeleteTextures(1, &mTexture2DShadow);
1503         glDeleteTextures(1, &mTextureCubeShadow);
1504         TexCoordDrawTest::testTearDown();
1505     }
1506 
1507     GLuint mTexture2D;
1508     GLuint mTextureCube;
1509     GLuint mTexture2DShadow;
1510     GLuint mTextureCubeShadow;
1511     GLint mTexture2DUniformLocation;
1512     GLint mTextureCubeUniformLocation;
1513     GLint mTexture2DShadowUniformLocation;
1514     GLint mTextureCubeShadowUniformLocation;
1515     GLint mDepthRefUniformLocation;
1516 };
1517 
1518 class SamplerInStructTest : public Texture2DTest
1519 {
1520   protected:
SamplerInStructTest()1521     SamplerInStructTest() : Texture2DTest() {}
1522 
getTextureUniformName()1523     const char *getTextureUniformName() override { return "us.tex"; }
1524 
getFragmentShaderSource()1525     const char *getFragmentShaderSource() override
1526     {
1527         return "precision highp float;\n"
1528                "struct S\n"
1529                "{\n"
1530                "    vec4 a;\n"
1531                "    highp sampler2D tex;\n"
1532                "};\n"
1533                "uniform S us;\n"
1534                "varying vec2 texcoord;\n"
1535                "void main()\n"
1536                "{\n"
1537                "    gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1538                "}\n";
1539     }
1540 
runSamplerInStructTest()1541     void runSamplerInStructTest()
1542     {
1543         setUpProgram();
1544 
1545         glActiveTexture(GL_TEXTURE0);
1546         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1547         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1548                      &GLColor::green);
1549         drawQuad(mProgram, "position", 0.5f);
1550         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1551     }
1552 };
1553 
1554 class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1555 {
1556   protected:
SamplerInStructAsFunctionParameterTest()1557     SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1558 
getFragmentShaderSource()1559     const char *getFragmentShaderSource() override
1560     {
1561         return "precision highp float;\n"
1562                "struct S\n"
1563                "{\n"
1564                "    vec4 a;\n"
1565                "    highp sampler2D tex;\n"
1566                "};\n"
1567                "uniform S us;\n"
1568                "varying vec2 texcoord;\n"
1569                "vec4 sampleFrom(S s) {\n"
1570                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1571                "}\n"
1572                "void main()\n"
1573                "{\n"
1574                "    gl_FragColor = sampleFrom(us);\n"
1575                "}\n";
1576     }
1577 };
1578 
1579 class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1580 {
1581   protected:
SamplerInStructArrayAsFunctionParameterTest()1582     SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1583 
getTextureUniformName()1584     const char *getTextureUniformName() override { return "us[0].tex"; }
1585 
getFragmentShaderSource()1586     const char *getFragmentShaderSource() override
1587     {
1588         return "precision highp float;\n"
1589                "struct S\n"
1590                "{\n"
1591                "    vec4 a;\n"
1592                "    highp sampler2D tex;\n"
1593                "};\n"
1594                "uniform S us[1];\n"
1595                "varying vec2 texcoord;\n"
1596                "vec4 sampleFrom(S s) {\n"
1597                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1598                "}\n"
1599                "void main()\n"
1600                "{\n"
1601                "    gl_FragColor = sampleFrom(us[0]);\n"
1602                "}\n";
1603     }
1604 };
1605 
1606 class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1607 {
1608   protected:
SamplerInNestedStructAsFunctionParameterTest()1609     SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1610 
getTextureUniformName()1611     const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1612 
getFragmentShaderSource()1613     const char *getFragmentShaderSource() override
1614     {
1615         return "precision highp float;\n"
1616                "struct SUB\n"
1617                "{\n"
1618                "    vec4 a;\n"
1619                "    highp sampler2D tex;\n"
1620                "};\n"
1621                "struct S\n"
1622                "{\n"
1623                "    SUB sub;\n"
1624                "};\n"
1625                "uniform S us[1];\n"
1626                "varying vec2 texcoord;\n"
1627                "vec4 sampleFrom(SUB s) {\n"
1628                "    return texture2D(s.tex, texcoord + s.a.x);\n"
1629                "}\n"
1630                "void main()\n"
1631                "{\n"
1632                "    gl_FragColor = sampleFrom(us[0].sub);\n"
1633                "}\n";
1634     }
1635 };
1636 
1637 class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1638 {
1639   protected:
SamplerInStructAndOtherVariableTest()1640     SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1641 
getFragmentShaderSource()1642     const char *getFragmentShaderSource() override
1643     {
1644         return "precision highp float;\n"
1645                "struct S\n"
1646                "{\n"
1647                "    vec4 a;\n"
1648                "    highp sampler2D tex;\n"
1649                "};\n"
1650                "uniform S us;\n"
1651                "uniform float us_tex;\n"
1652                "varying vec2 texcoord;\n"
1653                "void main()\n"
1654                "{\n"
1655                "    gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1656                "}\n";
1657     }
1658 };
1659 
1660 class Texture2DIntegerTestES3 : public Texture2DTest
1661 {
1662   protected:
Texture2DIntegerTestES3()1663     Texture2DIntegerTestES3() : Texture2DTest() {}
1664 
getVertexShaderSource()1665     const char *getVertexShaderSource() override
1666     {
1667         return "#version 300 es\n"
1668                "out vec2 texcoord;\n"
1669                "in vec4 position;\n"
1670                "void main()\n"
1671                "{\n"
1672                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1673                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1674                "}\n";
1675     }
1676 
getFragmentShaderSource()1677     const char *getFragmentShaderSource() override
1678     {
1679         return "#version 300 es\n"
1680                "precision highp float;\n"
1681                "precision highp usampler2D;\n"
1682                "uniform usampler2D tex;\n"
1683                "in vec2 texcoord;\n"
1684                "out vec4 fragColor;\n"
1685                "void main()\n"
1686                "{\n"
1687                "    fragColor = vec4(texture(tex, texcoord))/255.0;\n"
1688                "}\n";
1689     }
1690 };
1691 
1692 class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1693 {
1694   protected:
TextureCubeIntegerTestES3()1695     TextureCubeIntegerTestES3()
1696         : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1697     {}
1698 
getVertexShaderSource()1699     const char *getVertexShaderSource() override
1700     {
1701         return "#version 300 es\n"
1702                "out vec2 texcoord;\n"
1703                "in vec4 position;\n"
1704                "void main()\n"
1705                "{\n"
1706                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1707                "    texcoord = 0.5*position.xy;\n"
1708                "}\n";
1709     }
1710 
getFragmentShaderSource()1711     const char *getFragmentShaderSource() override
1712     {
1713         return "#version 300 es\n"
1714                "precision highp float;\n"
1715                "precision highp usamplerCube;\n"
1716                "uniform usamplerCube texCube;\n"
1717                "in vec2 texcoord;\n"
1718                "out vec4 fragColor;\n"
1719                "void main()\n"
1720                "{\n"
1721                "    fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1722                "}\n";
1723     }
1724 
testSetUp()1725     void testSetUp() override
1726     {
1727         TexCoordDrawTest::testSetUp();
1728         glGenTextures(1, &mTextureCube);
1729         setUpProgram();
1730 
1731         mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1732         ASSERT_NE(-1, mTextureCubeUniformLocation);
1733     }
1734 
testTearDown()1735     void testTearDown() override
1736     {
1737         glDeleteTextures(1, &mTextureCube);
1738         TexCoordDrawTest::testTearDown();
1739     }
1740 
1741     GLuint mTextureCube;
1742     GLint mTextureCubeUniformLocation;
1743 };
1744 
1745 class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1746 {
1747   protected:
TextureCubeIntegerEdgeTestES3()1748     TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1749 
getVertexShaderSource()1750     const char *getVertexShaderSource() override
1751     {
1752         return "#version 300 es\n"
1753                "out vec2 texcoord;\n"
1754                "in vec4 position;\n"
1755                "void main()\n"
1756                "{\n"
1757                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1758                "    texcoord = position.xy;\n"
1759                "}\n";
1760     }
1761 
getFragmentShaderSource()1762     const char *getFragmentShaderSource() override
1763     {
1764         return "#version 300 es\n"
1765                "precision highp float;\n"
1766                "precision highp usamplerCube;\n"
1767                "uniform usamplerCube texCube;\n"
1768                "in vec2 texcoord;\n"
1769                "out vec4 fragColor;\n"
1770                "void main()\n"
1771                "{\n"
1772                "    fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1773                "}\n";
1774     }
1775 };
1776 
1777 class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1778 {
1779   protected:
Texture2DIntegerProjectiveOffsetTestES3()1780     Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1781 
getVertexShaderSource()1782     const char *getVertexShaderSource() override
1783     {
1784         return "#version 300 es\n"
1785                "out vec2 texcoord;\n"
1786                "in vec4 position;\n"
1787                "void main()\n"
1788                "{\n"
1789                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1790                "    texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1791                "}\n";
1792     }
1793 
getFragmentShaderSource()1794     const char *getFragmentShaderSource() override
1795     {
1796         return "#version 300 es\n"
1797                "precision highp float;\n"
1798                "precision highp usampler2D;\n"
1799                "uniform usampler2D tex;\n"
1800                "in vec2 texcoord;\n"
1801                "out vec4 fragColor;\n"
1802                "void main()\n"
1803                "{\n"
1804                "    fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1805                "0.0))/255.0;\n"
1806                "}\n";
1807     }
1808 };
1809 
1810 class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1811 {
1812   protected:
Texture2DArrayIntegerTestES3()1813     Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1814 
getVertexShaderSource()1815     const char *getVertexShaderSource() override
1816     {
1817         return R"(#version 300 es
1818 out vec2 texcoord;
1819 in vec4 position;
1820 void main()
1821 {
1822     gl_Position = vec4(position.xy, 0.0, 1.0);
1823     texcoord = (position.xy * 0.5) + 0.5;
1824 })";
1825     }
1826 
getFragmentShaderSource()1827     const char *getFragmentShaderSource() override
1828     {
1829         return R"(#version 300 es
1830 precision highp float;
1831 uniform highp usampler2DArray tex2DArray;
1832 uniform int slice;
1833 in vec2 texcoord;
1834 out vec4 fragColor;
1835 void main()
1836 {
1837     fragColor = vec4(texture(tex2DArray, vec3(texcoord, slice)))/255.0;
1838 })";
1839     }
1840 };
1841 
1842 class Texture3DIntegerTestES3 : public Texture3DTestES3
1843 {
1844   protected:
Texture3DIntegerTestES3()1845     Texture3DIntegerTestES3() : Texture3DTestES3() {}
1846 
getVertexShaderSource()1847     const char *getVertexShaderSource() override
1848     {
1849         return "#version 300 es\n"
1850                "out vec2 texcoord;\n"
1851                "in vec4 position;\n"
1852                "void main()\n"
1853                "{\n"
1854                "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1855                "    texcoord = (position.xy * 0.5) + 0.5;\n"
1856                "}\n";
1857     }
1858 
getFragmentShaderSource()1859     const char *getFragmentShaderSource() override
1860     {
1861         return "#version 300 es\n"
1862                "precision highp float;\n"
1863                "uniform highp usampler3D tex3D;\n"
1864                "in vec2 texcoord;\n"
1865                "out vec4 fragColor;\n"
1866                "void main()\n"
1867                "{\n"
1868                "    fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1869                "}\n";
1870     }
1871 };
1872 
1873 class PBOCompressedTextureTest : public Texture2DTest
1874 {
1875   protected:
PBOCompressedTextureTest()1876     PBOCompressedTextureTest() : Texture2DTest() {}
1877 
testSetUp()1878     void testSetUp() override
1879     {
1880         TexCoordDrawTest::testSetUp();
1881         glGenTextures(1, &mTexture2D);
1882         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1883         EXPECT_GL_NO_ERROR();
1884 
1885         setUpProgram();
1886 
1887         glGenBuffers(1, &mPBO);
1888     }
1889 
testTearDown()1890     void testTearDown() override
1891     {
1892         glDeleteBuffers(1, &mPBO);
1893         Texture2DTest::testTearDown();
1894     }
1895 
1896     void runCompressedSubImage();
1897 
1898     GLuint mPBO;
1899 };
1900 
1901 class ETC1CompressedTextureTest : public Texture2DTest
1902 {
1903   protected:
ETC1CompressedTextureTest()1904     ETC1CompressedTextureTest() : Texture2DTest() {}
1905 
testSetUp()1906     void testSetUp() override
1907     {
1908         TexCoordDrawTest::testSetUp();
1909         glGenTextures(1, &mTexture2D);
1910         glBindTexture(GL_TEXTURE_2D, mTexture2D);
1911         EXPECT_GL_NO_ERROR();
1912 
1913         setUpProgram();
1914     }
1915 
testTearDown()1916     void testTearDown() override { Texture2DTest::testTearDown(); }
1917 };
1918 
1919 class Texture2DDepthStencilTestES3 : public Texture2DTest
1920 {
1921   protected:
Texture2DDepthStencilTestES3()1922     Texture2DDepthStencilTestES3() : Texture2DTest() {}
1923 
1924     void TestSampleWithDepthStencilMode(GLenum format, GLenum mode, bool swizzle);
1925 };
1926 
TestSampleWithDepthStencilMode(GLenum format,GLenum mode,bool swizzle)1927 void Texture2DDepthStencilTestES3::TestSampleWithDepthStencilMode(GLenum format,
1928                                                                   GLenum mode,
1929                                                                   bool swizzle)
1930 {
1931     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_stencil_texturing"));
1932 
1933     constexpr GLsizei kSize = 4;
1934 
1935     ASSERT(mode == GL_STENCIL_INDEX || mode == GL_DEPTH_COMPONENT);
1936 
1937     bool isStencilMode;
1938     GLenum attachment;
1939     switch (format)
1940     {
1941         case GL_DEPTH_COMPONENT16:
1942         case GL_DEPTH_COMPONENT24:
1943         case GL_DEPTH_COMPONENT32F:
1944             attachment    = GL_DEPTH_ATTACHMENT;
1945             isStencilMode = false;
1946             break;
1947         case GL_DEPTH24_STENCIL8:
1948         case GL_DEPTH32F_STENCIL8:
1949             attachment    = GL_DEPTH_STENCIL_ATTACHMENT;
1950             isStencilMode = mode == GL_STENCIL_INDEX;
1951             break;
1952         case GL_STENCIL_INDEX8:
1953             attachment    = GL_STENCIL_ATTACHMENT;
1954             isStencilMode = true;
1955             break;
1956         default:
1957             UNREACHABLE();
1958     }
1959 
1960     // Set up a color texture.
1961     GLTexture colorTexture;
1962     glBindTexture(GL_TEXTURE_2D, colorTexture);
1963     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
1964     ASSERT_GL_NO_ERROR();
1965 
1966     // Set up a depth/stencil texture to be sampled as mode.
1967     GLTexture depthStencilTexture;
1968     glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
1969     glTexStorage2D(GL_TEXTURE_2D, 1, format, kSize, kSize);
1970     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1971     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1972     glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE_ANGLE, mode);
1973     if (swizzle)
1974     {
1975         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
1976         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
1977         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_GREEN);
1978         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
1979     }
1980     ASSERT_GL_NO_ERROR();
1981 
1982     constexpr char kStencilFS[] =
1983         R"(#version 300 es
1984 precision mediump float;
1985 uniform highp usampler2D tex;
1986 out vec4 color;
1987 void main()
1988 {
1989     color = vec4(texelFetch(tex, ivec2(0, 0), 0)) / 255.0f;
1990 })";
1991 
1992     constexpr char kDepthFS[] =
1993         R"(#version 300 es
1994 precision mediump float;
1995 uniform highp sampler2D tex;
1996 out vec4 color;
1997 void main()
1998 {
1999     color = texture(tex, vec2(0, 0));
2000 })";
2001 
2002     // Clear stencil to 42.
2003     GLFramebuffer clearFBO;
2004     glBindFramebuffer(GL_FRAMEBUFFER, clearFBO);
2005     glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, depthStencilTexture, 0);
2006     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2007     glClearDepthf(0.5);
2008     glClearStencil(42);
2009     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2010     ASSERT_GL_NO_ERROR();
2011 
2012     glActiveTexture(GL_TEXTURE0);
2013     glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
2014     EXPECT_GL_ERROR(GL_NO_ERROR);
2015 
2016     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), isStencilMode ? kStencilFS : kDepthFS);
2017     GLint texLocation = glGetUniformLocation(program, "tex");
2018     ASSERT_NE(-1, texLocation);
2019     ASSERT_GL_NO_ERROR();
2020 
2021     glUseProgram(program);
2022     glUniform1i(texLocation, 0);
2023 
2024     GLFramebuffer drawFBO;
2025     glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
2026     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2027     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2028     ASSERT_GL_NO_ERROR();
2029 
2030     drawQuad(program, essl3_shaders::PositionAttrib(), 0.95f);
2031     ASSERT_GL_NO_ERROR();
2032 
2033     if (isStencilMode)
2034     {
2035         GLColor expected = swizzle ? GLColor(1, 0, 0, 42) : GLColor(42, 0, 0, 1);
2036         EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, expected);
2037     }
2038     else
2039     {
2040         GLColor expected = swizzle ? GLColor(255, 0, 0, 127) : GLColor(127, 0, 0, 255);
2041         EXPECT_PIXEL_COLOR_NEAR(0, 0, expected, 1);
2042     }
2043 }
2044 
TEST_P(Texture2DTest,NegativeAPISubImage)2045 TEST_P(Texture2DTest, NegativeAPISubImage)
2046 {
2047     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2048     EXPECT_GL_ERROR(GL_NO_ERROR);
2049 
2050     setUpProgram();
2051 
2052     const GLubyte *pixels[20] = {0};
2053     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2054     EXPECT_GL_ERROR(GL_INVALID_VALUE);
2055 
2056     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
2057     {
2058         // Create a 1-level immutable texture.
2059         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
2060 
2061         // Try calling sub image on the second level.
2062         glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2063         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2064     }
2065 }
2066 
2067 // Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
TEST_P(Texture2DTest,QueryBinding)2068 TEST_P(Texture2DTest, QueryBinding)
2069 {
2070     glBindTexture(GL_TEXTURE_2D, 0);
2071     EXPECT_GL_ERROR(GL_NO_ERROR);
2072 
2073     GLint textureBinding;
2074     glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
2075     EXPECT_GL_NO_ERROR();
2076     EXPECT_EQ(0, textureBinding);
2077 
2078     glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
2079     if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
2080         IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
2081     {
2082         EXPECT_GL_NO_ERROR();
2083         EXPECT_EQ(0, textureBinding);
2084     }
2085     else
2086     {
2087         EXPECT_GL_ERROR(GL_INVALID_ENUM);
2088     }
2089 }
2090 
TEST_P(Texture2DTest,ZeroSizedUploads)2091 TEST_P(Texture2DTest, ZeroSizedUploads)
2092 {
2093     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2094     EXPECT_GL_ERROR(GL_NO_ERROR);
2095 
2096     setUpProgram();
2097 
2098     // Use the texture first to make sure it's in video memory
2099     glUseProgram(mProgram);
2100     glUniform1i(mTexture2DUniformLocation, 0);
2101     drawQuad(mProgram, "position", 0.5f);
2102 
2103     const GLubyte *pixel[4] = {0};
2104 
2105     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
2106     EXPECT_GL_NO_ERROR();
2107 
2108     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
2109     EXPECT_GL_NO_ERROR();
2110 
2111     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
2112     EXPECT_GL_NO_ERROR();
2113 }
2114 
2115 // Tests uploading a red texture and immediately reading from it.
TEST_P(Texture2DTest,SimpleUpload)2116 TEST_P(Texture2DTest, SimpleUpload)
2117 {
2118     const GLuint width            = getWindowWidth();
2119     const GLuint height           = getWindowHeight();
2120     const GLuint windowPixelCount = width * height;
2121     std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
2122     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2123     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2124                  pixelsRed.data());
2125     EXPECT_GL_ERROR(GL_NO_ERROR);
2126 
2127     GLFramebuffer fbo;
2128     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2129 
2130     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
2131 
2132     EXPECT_GL_ERROR(GL_NO_ERROR);
2133     std::vector<GLColor> output(windowPixelCount, GLColor::green);
2134     glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, output.data());
2135     EXPECT_EQ(pixelsRed, output);
2136 }
2137 
2138 // Test that interleaved superseded updates work as expected
TEST_P(Texture2DTest,InterleavedSupersedingTextureUpdates)2139 TEST_P(Texture2DTest, InterleavedSupersedingTextureUpdates)
2140 {
2141     constexpr uint32_t kTexWidth  = 3840;
2142     constexpr uint32_t kTexHeight = 2160;
2143     constexpr uint32_t kBpp       = 4;
2144 
2145     // Create the texture
2146     glActiveTexture(GL_TEXTURE0);
2147     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2148     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2149     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2150     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2151                  nullptr);
2152     EXPECT_GL_ERROR(GL_NO_ERROR);
2153 
2154     // 1. One big upload followed by many small identical uploads
2155     // Update the entire texture
2156     std::vector<GLubyte> fullTextureData(kTexWidth * kTexHeight * kBpp, 128);
2157     constexpr GLColor kFullTextureColor = GLColor(128u, 128u, 128u, 128u);
2158     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2159                     fullTextureData.data());
2160 
2161     // Make a number of identical updates to the right half of the texture
2162     std::vector<GLubyte> rightHalfData(kTexWidth * kTexHeight * kBpp, 201);
2163     constexpr GLColor kRightHalfColor = GLColor(201u, 201u, 201u, 201u);
2164     for (uint32_t iteration = 0; iteration < 10; iteration++)
2165     {
2166         glTexSubImage2D(GL_TEXTURE_2D, 0, kTexWidth / 2, 0, kTexWidth / 2, kTexHeight, GL_RGBA,
2167                         GL_UNSIGNED_BYTE, rightHalfData.data());
2168     }
2169 
2170     setUpProgram();
2171     glUseProgram(mProgram);
2172     glUniform1i(mTexture2DUniformLocation, 0);
2173     drawQuad(mProgram, "position", 0.5f);
2174     EXPECT_GL_NO_ERROR();
2175     EXPECT_PIXEL_COLOR_EQ(1 * getWindowWidth() / 4, getWindowHeight() / 2, kFullTextureColor);
2176     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 2, kRightHalfColor);
2177 
2178     // 2. Some small uploads followed by one big upload followed by many identical uploads
2179     // Clear the entire texture
2180     std::vector<GLubyte> zeroTextureData(kTexWidth * kTexHeight * kBpp, 255);
2181     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2182                     zeroTextureData.data());
2183 
2184     // Update the top left quadrant of the texture
2185     std::vector<GLubyte> topLeftQuadrantData(kTexWidth * kTexHeight * kBpp, 128);
2186     constexpr GLColor kTopLeftQuandrantTextureColor = GLColor(128u, 128u, 128u, 128u);
2187     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, kTexHeight / 2, kTexWidth / 2, kTexHeight / 2, GL_RGBA,
2188                     GL_UNSIGNED_BYTE, topLeftQuadrantData.data());
2189 
2190     // Update the top right quadrant of the texture
2191     std::vector<GLubyte> topRightQuadrantData(kTexWidth * kTexHeight * kBpp, 156);
2192     constexpr GLColor kTopRightQuadrantTextureColor = GLColor(156u, 156u, 156u, 156u);
2193     glTexSubImage2D(GL_TEXTURE_2D, 0, kTexWidth / 2, kTexHeight / 2, kTexWidth / 2, kTexHeight / 2,
2194                     GL_RGBA, GL_UNSIGNED_BYTE, topRightQuadrantData.data());
2195 
2196     // Update the bottom half of the texture
2197     std::vector<GLubyte> bottomHalfTextureData(kTexWidth * kTexHeight * kBpp, 187);
2198     constexpr GLColor kBottomHalfTextureColor = GLColor(187u, 187u, 187u, 187u);
2199     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight / 2, GL_RGBA, GL_UNSIGNED_BYTE,
2200                     bottomHalfTextureData.data());
2201 
2202     // Make a number of identical updates to the bottom right quadrant of the texture
2203     std::vector<GLubyte> bottomRightQuadrantData(kTexWidth * kTexHeight * kBpp, 201);
2204     constexpr GLColor kBottomRightQuadrantColor = GLColor(201u, 201u, 201u, 201u);
2205     for (uint32_t iteration = 0; iteration < 10; iteration++)
2206     {
2207         glTexSubImage2D(GL_TEXTURE_2D, 0, kTexWidth / 2, 0, kTexWidth / 2, kTexHeight / 2, GL_RGBA,
2208                         GL_UNSIGNED_BYTE, bottomRightQuadrantData.data());
2209     }
2210 
2211     setUpProgram();
2212     glUseProgram(mProgram);
2213     glUniform1i(mTexture2DUniformLocation, 0);
2214     drawQuad(mProgram, "position", 0.5f);
2215     EXPECT_GL_NO_ERROR();
2216     EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, kTopLeftQuandrantTextureColor);
2217     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1,
2218                           kTopRightQuadrantTextureColor);
2219     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, kBottomHalfTextureColor);
2220     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4,
2221                           kBottomRightQuadrantColor);
2222 
2223     // 3. Many small uploads folloed by one big upload
2224     // Clear the entire texture
2225     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2226                     zeroTextureData.data());
2227 
2228     // Make a number of small updates to different parts of the texture
2229     std::vector<std::pair<GLint, GLint>> xyOffsets = {
2230         {1, 4}, {128, 34}, {1208, 1090}, {2560, 2022}};
2231     constexpr GLColor kRandomColor = GLColor(55u, 128u, 201u, 255u);
2232     for (const std::pair<GLint, GLint> &xyOffset : xyOffsets)
2233     {
2234         glTexSubImage2D(GL_TEXTURE_2D, 0, xyOffset.first, xyOffset.second, 1, 1, GL_RGBA,
2235                         GL_UNSIGNED_BYTE, kRandomColor.data());
2236     }
2237 
2238     // Update the entire texture
2239     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2240                     fullTextureData.data());
2241 
2242     setUpProgram();
2243     glUseProgram(mProgram);
2244     glUniform1i(mTexture2DUniformLocation, 0);
2245     drawQuad(mProgram, "position", 0.5f);
2246     EXPECT_GL_NO_ERROR();
2247     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() - 1, getWindowHeight() - 1, kFullTextureColor);
2248 }
2249 
2250 // Test that repeated calls to glTexSubImage2D with superseding updates works
TEST_P(Texture2DTest,ManySupersedingTextureUpdates)2251 TEST_P(Texture2DTest, ManySupersedingTextureUpdates)
2252 {
2253     constexpr uint32_t kTexWidth  = 3840;
2254     constexpr uint32_t kTexHeight = 2160;
2255     constexpr uint32_t kBpp       = 4;
2256     std::vector<GLubyte> data(kTexWidth * kTexHeight * kBpp, 0);
2257 
2258     // Create the texture
2259     glActiveTexture(GL_TEXTURE0);
2260     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2261     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2262     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2263     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2264                  nullptr);
2265     EXPECT_GL_ERROR(GL_NO_ERROR);
2266 
2267     // Make a large number of superseding updates
2268     for (uint32_t width = kTexWidth / 2, height = kTexHeight / 2;
2269          width < kTexWidth && height < kTexHeight; width++, height++)
2270     {
2271         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
2272                         data.data());
2273     }
2274 
2275     // Upload different color to the whole texture thus superseding all prior updates.
2276     std::vector<GLubyte> supersedingData(kTexWidth * kTexHeight * kBpp, 128);
2277     constexpr GLColor kGray = GLColor(128u, 128u, 128u, 128u);
2278     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2279                     supersedingData.data());
2280 
2281     setUpProgram();
2282     glUseProgram(mProgram);
2283     glUniform1i(mTexture2DUniformLocation, 0);
2284     drawQuad(mProgram, "position", 0.5f);
2285     EXPECT_GL_NO_ERROR();
2286     EXPECT_PIXEL_COLOR_EQ(0, 0, kGray);
2287 }
2288 
TEST_P(Texture2DTest,DefineMultipleLevelsWithoutMipmapping)2289 TEST_P(Texture2DTest, DefineMultipleLevelsWithoutMipmapping)
2290 {
2291     setUpProgram();
2292 
2293     constexpr size_t kImageSize = 256;
2294     std::array<GLColor, kImageSize * kImageSize> kMipColors[2];
2295 
2296     std::fill(kMipColors[0].begin(), kMipColors[0].end(), GLColor::red);
2297     std::fill(kMipColors[1].begin(), kMipColors[1].end(), GLColor::green);
2298 
2299     glActiveTexture(GL_TEXTURE0);
2300     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2301     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2302     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2303 
2304     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2305                  kMipColors[0].data());
2306     EXPECT_GL_NO_ERROR();
2307 
2308     // Draw so the image is created.
2309     glUseProgram(mProgram);
2310     glUniform1i(mTexture2DUniformLocation, 0);
2311     drawQuad(mProgram, "position", 0.5f);
2312 
2313     // Define level 1 of the texture.
2314     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2315                  kMipColors[1].data());
2316     EXPECT_GL_NO_ERROR();
2317 
2318     // Draw again.
2319     drawQuad(mProgram, "position", 0.5f);
2320     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0][0]);
2321 }
2322 
2323 // Test drawing with two texture types, to trigger an ANGLE bug in validation
TEST_P(TextureCubeTest,CubeMapBug)2324 TEST_P(TextureCubeTest, CubeMapBug)
2325 {
2326     glActiveTexture(GL_TEXTURE0);
2327     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2328     glActiveTexture(GL_TEXTURE1);
2329     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2330     EXPECT_GL_ERROR(GL_NO_ERROR);
2331 
2332     glUseProgram(mProgram);
2333     glUniform1i(mTexture2DUniformLocation, 0);
2334     glUniform1i(mTextureCubeUniformLocation, 1);
2335     drawQuad(mProgram, "position", 0.5f);
2336     EXPECT_GL_NO_ERROR();
2337 }
2338 
2339 // Test drawing with two texture types accessed from the same shader and check that the result of
2340 // drawing is correct.
TEST_P(TextureCubeTest,CubeMapDraw)2341 TEST_P(TextureCubeTest, CubeMapDraw)
2342 {
2343     GLubyte texData[4];
2344     texData[0] = 0;
2345     texData[1] = 60;
2346     texData[2] = 0;
2347     texData[3] = 255;
2348 
2349     glActiveTexture(GL_TEXTURE0);
2350     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2351     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2352 
2353     glActiveTexture(GL_TEXTURE1);
2354     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2355     texData[1] = 120;
2356     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2357                     texData);
2358     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2359                     texData);
2360     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2361                     texData);
2362     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2363                     texData);
2364     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2365                     texData);
2366     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2367                     texData);
2368     EXPECT_GL_ERROR(GL_NO_ERROR);
2369 
2370     glUseProgram(mProgram);
2371     glUniform1i(mTexture2DUniformLocation, 0);
2372     glUniform1i(mTextureCubeUniformLocation, 1);
2373     drawQuad(mProgram, "position", 0.5f);
2374     EXPECT_GL_NO_ERROR();
2375 
2376     int px = getWindowWidth() - 1;
2377     int py = 0;
2378     EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
2379 }
2380 
TEST_P(Sampler2DAsFunctionParameterTest,Sampler2DAsFunctionParameter)2381 TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
2382 {
2383     glActiveTexture(GL_TEXTURE0);
2384     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2385     GLubyte texData[4];
2386     texData[0] = 0;
2387     texData[1] = 128;
2388     texData[2] = 0;
2389     texData[3] = 255;
2390     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2391     glUseProgram(mProgram);
2392     glUniform1i(mTexture2DUniformLocation, 0);
2393     drawQuad(mProgram, "position", 0.5f);
2394     EXPECT_GL_NO_ERROR();
2395 
2396     EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
2397 }
2398 
2399 // Test drawing with two textures passed to the shader in a sampler array.
TEST_P(SamplerArrayTest,SamplerArrayDraw)2400 TEST_P(SamplerArrayTest, SamplerArrayDraw)
2401 {
2402     testSamplerArrayDraw();
2403 }
2404 
2405 // Test drawing with two textures passed to the shader in a sampler array which is passed to a
2406 // user-defined function in the shader.
TEST_P(SamplerArrayAsFunctionParameterTest,SamplerArrayAsFunctionParameter)2407 TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
2408 {
2409     // TODO: Diagnose and fix. http://anglebug.com/42261649
2410     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
2411 
2412     testSamplerArrayDraw();
2413 }
2414 
2415 // Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
TEST_P(Texture2DTestWithDrawScale,MipmapsTwice)2416 TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
2417 {
2418     int px = getWindowWidth() / 2;
2419     int py = getWindowHeight() / 2;
2420 
2421     glActiveTexture(GL_TEXTURE0);
2422     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2423 
2424     std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
2425 
2426     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
2427     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2428     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2429     glGenerateMipmap(GL_TEXTURE_2D);
2430 
2431     glUseProgram(mProgram);
2432     glUniform1i(mTexture2DUniformLocation, 0);
2433     glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
2434     drawQuad(mProgram, "position", 0.5f);
2435     EXPECT_GL_NO_ERROR();
2436     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
2437 
2438     std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
2439 
2440     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2441                  pixelsBlue.data());
2442     glGenerateMipmap(GL_TEXTURE_2D);
2443 
2444     drawQuad(mProgram, "position", 0.5f);
2445 
2446     EXPECT_GL_NO_ERROR();
2447     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::blue);
2448 
2449     std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
2450 
2451     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2452                  pixelsGreen.data());
2453     glGenerateMipmap(GL_TEXTURE_2D);
2454 
2455     drawQuad(mProgram, "position", 0.5f);
2456 
2457     EXPECT_GL_NO_ERROR();
2458     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
2459 }
2460 
2461 // Test creating a FBO with a cube map render target, to test an ANGLE bug
2462 // https://code.google.com/p/angleproject/issues/detail?id=849
TEST_P(TextureCubeTest,CubeMapFBO)2463 TEST_P(TextureCubeTest, CubeMapFBO)
2464 {
2465     // http://anglebug.com/42261821
2466     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
2467 
2468     GLFramebuffer fbo;
2469     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2470 
2471     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2472     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2473                            mTextureCube, 0);
2474 
2475     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2476     EXPECT_GL_NO_ERROR();
2477 
2478     // Test clearing the six mip faces individually.
2479     std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
2480                                           GLColor::yellow, GLColor::cyan, GLColor::magenta}};
2481 
2482     for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2483     {
2484         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2485                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2486 
2487         Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
2488         glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
2489         glClear(GL_COLOR_BUFFER_BIT);
2490 
2491         EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
2492     }
2493 
2494     // Iterate the faces again to make sure the colors haven't changed.
2495     for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2496     {
2497         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2498                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2499         EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
2500             << "face color " << faceIndex << " shouldn't change";
2501     }
2502 }
2503 
2504 // Tests clearing a cube map with a scissor enabled.
TEST_P(TextureCubeTest,CubeMapFBOScissoredClear)2505 TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
2506 {
2507     // http://anglebug.com/42261821
2508     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
2509 
2510     constexpr size_t kSize = 16;
2511 
2512     GLFramebuffer fbo;
2513     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2514     glViewport(0, 0, kSize, kSize);
2515 
2516     GLTexture texcube;
2517     glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
2518     for (GLenum face = 0; face < 6; face++)
2519     {
2520         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
2521                      GL_UNSIGNED_BYTE, nullptr);
2522     }
2523     ASSERT_GL_NO_ERROR();
2524 
2525     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2526                            texcube, 0);
2527 
2528     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2529     ASSERT_GL_NO_ERROR();
2530 
2531     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2532     glClear(GL_COLOR_BUFFER_BIT);
2533     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2534 
2535     glEnable(GL_SCISSOR_TEST);
2536     glScissor(kSize / 2, 0, kSize / 2, kSize);
2537     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2538     glClear(GL_COLOR_BUFFER_BIT);
2539 
2540     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2541     EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
2542 
2543     ASSERT_GL_NO_ERROR();
2544 }
2545 
2546 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
2547 // default color.
TEST_P(Texture2DTest,TexStorage)2548 TEST_P(Texture2DTest, TexStorage)
2549 {
2550     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
2551                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
2552 
2553     int width  = getWindowWidth();
2554     int height = getWindowHeight();
2555 
2556     GLTexture tex2D;
2557     glActiveTexture(GL_TEXTURE0);
2558     glBindTexture(GL_TEXTURE_2D, tex2D);
2559 
2560     // Fill with red
2561     std::vector<GLubyte> pixels(3 * 16 * 16);
2562     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2563     {
2564         pixels[pixelId * 3 + 0] = 255;
2565         pixels[pixelId * 3 + 1] = 0;
2566         pixels[pixelId * 3 + 2] = 0;
2567     }
2568 
2569     // ANGLE internally uses RGBA as the DirectX format for RGB images
2570     // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2571     // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2572     if (getClientMajorVersion() >= 3)
2573     {
2574         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2575     }
2576     else
2577     {
2578         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2579     }
2580 
2581     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2582     // glTexSubImage2D should take into account that the image is dirty.
2583     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2584     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2585     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2586 
2587     setUpProgram();
2588 
2589     glUseProgram(mProgram);
2590     glUniform1i(mTexture2DUniformLocation, 0);
2591     drawQuad(mProgram, "position", 0.5f);
2592     EXPECT_GL_NO_ERROR();
2593     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2594 
2595     // Validate that the region of the texture without data has an alpha of 1.0
2596     angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
2597     EXPECT_EQ(255, pixel.A);
2598 }
2599 
2600 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2601 // initialized the image with a default color.
TEST_P(Texture2DTest,TexStorageWithPBO)2602 TEST_P(Texture2DTest, TexStorageWithPBO)
2603 {
2604     if (getClientMajorVersion() < 3)
2605     {
2606         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2607         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2608     }
2609 
2610     const int width          = getWindowWidth();
2611     const int height         = getWindowHeight();
2612     const size_t pixelCount  = width * height;
2613     const int componentCount = 3;
2614 
2615     GLTexture tex2D;
2616     glActiveTexture(GL_TEXTURE0);
2617     glBindTexture(GL_TEXTURE_2D, tex2D);
2618 
2619     // Fill with red
2620     std::vector<GLubyte> pixels(componentCount * pixelCount);
2621     for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
2622     {
2623         pixels[pixelId * componentCount + 0] = 255;
2624         pixels[pixelId * componentCount + 1] = 0;
2625         pixels[pixelId * componentCount + 2] = 0;
2626     }
2627 
2628     // Read 16x16 region from red backbuffer to PBO
2629     GLuint pbo;
2630     glGenBuffers(1, &pbo);
2631     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2632     glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
2633                  GL_STATIC_DRAW);
2634 
2635     // ANGLE internally uses RGBA as the DirectX format for RGB images
2636     // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2637     // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2638     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
2639 
2640     // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
2641     // untouched. glTexSubImage2D should take into account that the image is dirty.
2642     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
2643                     nullptr);
2644     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2645     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2646 
2647     setUpProgram();
2648 
2649     glUseProgram(mProgram);
2650     glUniform1i(mTexture2DUniformLocation, 0);
2651     drawQuad(mProgram, "position", 0.5f);
2652     glDeleteBuffers(1, &pbo);
2653     EXPECT_GL_NO_ERROR();
2654     EXPECT_PIXEL_RECT_EQ(0, 0, width / 2, height / 2, GLColor(255, 0, 0, 255));
2655 }
2656 
2657 // Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
2658 // and drawing with the texture
2659 // Pseudo code for the follow test:
2660 // 1. Upload PBO to mTexture2D
2661 // 2. Delete PBO
2662 // 3. Draw with otherTexture (x5)
2663 // 4. Draw with mTexture2D
2664 // 5. Validate color output
TEST_P(Texture2DTest,PBOWithMultipleDraws)2665 TEST_P(Texture2DTest, PBOWithMultipleDraws)
2666 {
2667     if (getClientMajorVersion() < 3)
2668     {
2669         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2670         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2671     }
2672 
2673     const GLuint width            = getWindowWidth();
2674     const GLuint height           = getWindowHeight();
2675     const GLuint windowPixelCount = width * height;
2676     std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
2677     std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
2678 
2679     // Create secondary draw that does not use mTexture
2680     const char *vertexShaderSource   = getVertexShaderSource();
2681     const char *fragmentShaderSource = getFragmentShaderSource();
2682     ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
2683 
2684     GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
2685     ASSERT_NE(-1, uniformLoc);
2686     glUseProgram(0);
2687 
2688     // Create secondary Texture to draw with
2689     GLTexture otherTexture;
2690     glActiveTexture(GL_TEXTURE0);
2691     glBindTexture(GL_TEXTURE_2D, otherTexture);
2692     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2693     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
2694                     pixelsRed.data());
2695     ASSERT_GL_NO_ERROR();
2696 
2697     // Setup primary Texture
2698     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2699     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2700     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2701     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2702     ASSERT_GL_NO_ERROR();
2703 
2704     // Setup PBO
2705     GLuint pbo = 0;
2706     glGenBuffers(1, &pbo);
2707     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2708     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
2709                  GL_STATIC_DRAW);
2710     ASSERT_GL_NO_ERROR();
2711 
2712     // Write PBO to mTexture
2713     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2714     ASSERT_GL_NO_ERROR();
2715     // Delete PBO as ANGLE should be properly handling refcount of this buffer
2716     glDeleteBuffers(1, &pbo);
2717     pixelsGreen.clear();
2718 
2719     // Do 5 draws not involving primary texture that the PBO updated
2720     glUseProgram(otherProgram);
2721     glUniform1i(uniformLoc, 0);
2722     glBindTexture(GL_TEXTURE_2D, otherTexture);
2723     drawQuad(otherProgram, "position", 0.5f);
2724     glBindTexture(GL_TEXTURE_2D, 0);
2725     glUseProgram(0);
2726 
2727     glUseProgram(otherProgram);
2728     glUniform1i(uniformLoc, 0);
2729     glBindTexture(GL_TEXTURE_2D, otherTexture);
2730     drawQuad(otherProgram, "position", 0.5f);
2731     glBindTexture(GL_TEXTURE_2D, 0);
2732     glUseProgram(0);
2733 
2734     glUseProgram(otherProgram);
2735     glUniform1i(uniformLoc, 0);
2736     glBindTexture(GL_TEXTURE_2D, otherTexture);
2737     drawQuad(otherProgram, "position", 0.5f);
2738     glBindTexture(GL_TEXTURE_2D, 0);
2739     glUseProgram(0);
2740 
2741     glUseProgram(otherProgram);
2742     glUniform1i(uniformLoc, 0);
2743     glBindTexture(GL_TEXTURE_2D, otherTexture);
2744     drawQuad(otherProgram, "position", 0.5f);
2745     glBindTexture(GL_TEXTURE_2D, 0);
2746     glUseProgram(0);
2747     ASSERT_GL_NO_ERROR();
2748 
2749     std::vector<GLColor> output(windowPixelCount, GLColor::black);
2750     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2751                  output.data());
2752     EXPECT_EQ(pixelsRed, output);
2753 
2754     setUpProgram();
2755     // Draw using PBO updated texture
2756     glUseProgram(mProgram);
2757     glUniform1i(mTexture2DUniformLocation, 0);
2758     glBindTexture(GL_TEXTURE_2D, mTexture2D);
2759     drawQuad(mProgram, "position", 0.5f);
2760     ASSERT_GL_NO_ERROR();
2761 
2762     std::vector<GLColor> actual(windowPixelCount, GLColor::black);
2763     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2764                  actual.data());
2765     // Value should be green as it was updated during PBO transfer to mTexture
2766     std::vector<GLColor> expected(windowPixelCount, GLColor::green);
2767     EXPECT_EQ(expected, actual);
2768 }
2769 
2770 // Almost mirrors UnitTest_DMSAA_dst_read test from Android skqp test suite
TEST_P(Texture2DTestES3,UnitTest_DMSAA_dst_read)2771 TEST_P(Texture2DTestES3, UnitTest_DMSAA_dst_read)
2772 {
2773     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB_write_control"));
2774 
2775     GLTexture texture;
2776     glActiveTexture(GL_TEXTURE31);
2777     glBindTexture(GL_TEXTURE_2D, texture);
2778     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2779     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2780     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2781     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2782     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 16, 16);
2783     glBindTexture(GL_TEXTURE_2D, 0);
2784 
2785     GLFramebuffer fboTexture;
2786     glBindFramebuffer(GL_FRAMEBUFFER, fboTexture);
2787     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2788     glCheckFramebufferStatus(GL_FRAMEBUFFER);
2789 
2790     GLFramebuffer fboRenderbuffer;
2791     GLRenderbuffer renderbuffer;
2792     glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2793     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
2794     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 16, 16);
2795     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
2796     glCheckFramebufferStatus(GL_FRAMEBUFFER);
2797 
2798     glActiveTexture(GL_TEXTURE0);
2799     glBindTexture(GL_TEXTURE_2D, texture);
2800     GLSampler sampler;
2801     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2802     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2803     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2804     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2805     glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.000000);
2806     glBindSampler(0, sampler);
2807     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2808 
2809     glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2810     glViewport(0, 0, 16, 16);
2811     glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2812 
2813     // Create texture program
2814     ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
2815     ASSERT_GL_NO_ERROR();
2816     GLint texLocation = glGetUniformLocation(drawTexture, essl1_shaders::Texture2DUniform());
2817     ASSERT_NE(-1, texLocation);
2818     glUseProgram(drawTexture);
2819     glUniform1i(texLocation, 0);
2820 
2821     glDisable(GL_BLEND);
2822     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2823     glDisable(GL_SCISSOR_TEST);
2824     glDisable(GL_STENCIL_TEST);
2825 
2826     glEnable(GL_FRAMEBUFFER_SRGB_EXT);
2827     drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2828 
2829     glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2830     glEnable(GL_SCISSOR_TEST);
2831     glScissor(0, 6, 10, 10);
2832 
2833     drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2834 
2835     // Blit fboRenderbuffer onto fboTexture
2836     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
2837     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboTexture);
2838     glDisable(GL_SCISSOR_TEST);
2839     glBlitFramebuffer(0, 6, 10, 16, 0, 6, 10, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2840     GLenum attachment = GL_COLOR_ATTACHMENT0;
2841     glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, &attachment);
2842 
2843     glBindFramebuffer(GL_FRAMEBUFFER, fboTexture);
2844     std::array<GLubyte, 10 * 10 * 4> pixelData;
2845     glReadPixels(0, 6, 10, 10, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
2846     glFinish();
2847 
2848     glClearColor(1.000000, 1.000000, 1.000000, 1.000000);
2849     glClear(GL_COLOR_BUFFER_BIT);
2850 
2851     glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2852     glEnable(GL_FRAMEBUFFER_SRGB_EXT);
2853     drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2854 
2855     glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2856     glEnable(GL_SCISSOR_TEST);
2857     drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2858 
2859     // Blit fboRenderbuffer onto fboTexture
2860     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
2861     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboTexture);
2862     glDisable(GL_SCISSOR_TEST);
2863     glBlitFramebuffer(0, 6, 10, 16, 0, 6, 10, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2864     attachment = GL_COLOR_ATTACHMENT0;
2865     glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, &attachment);
2866     glFinish();
2867 
2868     glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2869     glEnable(GL_FRAMEBUFFER_SRGB_EXT);
2870     drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2871 
2872     glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2873     glEnable(GL_SCISSOR_TEST);
2874     drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2875 
2876     // Blit fboRenderbuffer onto fboTexture
2877     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
2878     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboTexture);
2879     glDisable(GL_SCISSOR_TEST);
2880     glBlitFramebuffer(0, 6, 10, 16, 0, 6, 10, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2881     attachment = GL_COLOR_ATTACHMENT0;
2882     glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, &attachment);
2883     glFinish();
2884 
2885     glBindFramebuffer(GL_FRAMEBUFFER, fboTexture);
2886     glReadPixels(0, 6, 10, 10, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
2887     glFinish();
2888 }
2889 
2890 // Test that stencil texture uploads work.
TEST_P(Texture2DTestES3,TexImageWithStencilData)2891 TEST_P(Texture2DTestES3, TexImageWithStencilData)
2892 {
2893     constexpr GLsizei kSize = 4;
2894 
2895     const std::array<std::tuple<GLenum, GLenum, int, int>, 3> testConfigs = {
2896         std::make_tuple(GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, 4),
2897         std::make_tuple(GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, 4, 0),
2898         std::make_tuple(GL_STENCIL_INDEX8, GL_UNSIGNED_BYTE, 1, 0)};
2899 
2900     for (auto testConfig : testConfigs)
2901     {
2902         const GLenum format     = std::get<0>(testConfig);
2903         const GLenum type       = std::get<1>(testConfig);
2904         const GLenum typeLength = std::get<2>(testConfig);
2905         const GLenum typeOffset = std::get<3>(testConfig);
2906 
2907         ANGLE_SKIP_TEST_IF(format == GL_STENCIL_INDEX8 &&
2908                            !IsGLExtensionEnabled("GL_OES_texture_stencil8"));
2909 
2910         // Set up the framebuffer
2911         GLTexture colorTexture;
2912         glBindTexture(GL_TEXTURE_2D, colorTexture);
2913         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2914                      nullptr);
2915         ASSERT_GL_NO_ERROR();
2916 
2917         GLTexture depthStencilTexture;
2918         glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
2919 
2920         GLubyte pixels[kSize * kSize * 8] = {};
2921         for (size_t pixelId = 0; pixelId < kSize * kSize; ++pixelId)
2922         {
2923             pixels[pixelId * typeLength + typeOffset] = 0xD5;
2924         }
2925         glTexImage2D(GL_TEXTURE_2D, 0, format, kSize, kSize, 0,
2926                      format == GL_STENCIL_INDEX8 ? GL_STENCIL_INDEX : GL_DEPTH_STENCIL, type,
2927                      pixels);
2928         ASSERT_GL_NO_ERROR();
2929 
2930         GLFramebuffer fbo;
2931         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2932         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture,
2933                                0);
2934         glFramebufferTexture2D(
2935             GL_FRAMEBUFFER,
2936             format == GL_STENCIL_INDEX8 ? GL_STENCIL_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT,
2937             GL_TEXTURE_2D, depthStencilTexture, 0);
2938         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2939         ASSERT_GL_NO_ERROR();
2940 
2941         // Clear only color.
2942         glClearColor(0, 0, 0, 1);
2943         glClear(GL_COLOR_BUFFER_BIT);
2944         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2945 
2946         // If stencil is not set to 0xD5, rendering would fail.
2947         glEnable(GL_STENCIL_TEST);
2948         glStencilFunc(GL_EQUAL, 0xD5, 0xFF);
2949         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2950         glStencilMask(0xFF);
2951 
2952         // Draw red
2953         ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2954         drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
2955         ASSERT_GL_NO_ERROR();
2956 
2957         EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2958     }
2959 }
2960 
2961 // Test that glTexSubImage2D combined with a PBO works properly. PBO has all pixels as red
2962 // except the middle one being green.
TEST_P(Texture2DTest,TexStorageWithPBOMiddlePixelDifferent)2963 TEST_P(Texture2DTest, TexStorageWithPBOMiddlePixelDifferent)
2964 {
2965     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2966     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2967 
2968     int width  = getWindowWidth();
2969     int height = getWindowHeight();
2970 
2971     GLTexture tex2D;
2972     glActiveTexture(GL_TEXTURE0);
2973     glBindTexture(GL_TEXTURE_2D, tex2D);
2974 
2975     std::vector<GLubyte> pixels(3 * 16 * 16);
2976 
2977     // Initialize texture with default black color.
2978     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2979     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2980 
2981     // Fill PBO's data with red, with middle one as green
2982     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2983     {
2984         if (pixelId == 8 * 7 + 7)
2985         {
2986             pixels[pixelId * 3 + 0] = 0;
2987             pixels[pixelId * 3 + 1] = 255;
2988             pixels[pixelId * 3 + 2] = 0;
2989         }
2990         else
2991         {
2992             pixels[pixelId * 3 + 0] = 255;
2993             pixels[pixelId * 3 + 1] = 0;
2994             pixels[pixelId * 3 + 2] = 0;
2995         }
2996     }
2997 
2998     GLuint pbo;
2999     glGenBuffers(1, &pbo);
3000     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3001     glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3002 
3003     // Update the color of the texture's upper-left 8x8 pixels, leaves the other pixels untouched.
3004     // glTexSubImage2D should take into account that the image is dirty.
3005     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
3006     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3007     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3008 
3009     setUpProgram();
3010 
3011     glUseProgram(mProgram);
3012     glUniform1i(mTexture2DUniformLocation, 0);
3013     drawQuad(mProgram, "position", 0.5f);
3014     glDeleteBuffers(1, &pbo);
3015     EXPECT_GL_NO_ERROR();
3016     EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
3017     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3018     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3019 }
3020 
3021 // Test that glTexSubImage2D combined with a PBO works properly when glTexImage2D has
3022 // initialized the image with a luminance color
TEST_P(Texture2DTest,TexImageWithLuminancePBO)3023 TEST_P(Texture2DTest, TexImageWithLuminancePBO)
3024 {
3025     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3026 
3027     int width  = getWindowWidth();
3028     int height = getWindowHeight();
3029 
3030     GLTexture tex2D;
3031     glActiveTexture(GL_TEXTURE0);
3032     glBindTexture(GL_TEXTURE_2D, tex2D);
3033 
3034     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3035                  nullptr);
3036 
3037     // Fill PBO with white, with middle one as grey
3038     std::vector<GLubyte> pixels(16 * 16);
3039     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3040     {
3041         if (pixelId == 8 * 7 + 7)
3042         {
3043             pixels[pixelId] = 128;
3044         }
3045         else
3046         {
3047             pixels[pixelId] = 255;
3048         }
3049     }
3050 
3051     GLuint pbo;
3052     glGenBuffers(1, &pbo);
3053     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3054     glBufferData(GL_PIXEL_UNPACK_BUFFER, 16 * 16, pixels.data(), GL_STATIC_DRAW);
3055 
3056     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3057     // glTexSubImage2D should take into account that the image is dirty.
3058     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
3059     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3060     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3061 
3062     setUpProgram();
3063 
3064     glUseProgram(mProgram);
3065     glUniform1i(mTexture2DUniformLocation, 0);
3066     drawQuad(mProgram, "position", 0.5f);
3067     glDeleteBuffers(1, &pbo);
3068     EXPECT_GL_NO_ERROR();
3069     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 255, 255, 255);
3070     EXPECT_PIXEL_NEAR(width / 2 - 1, height / 2 - 1, 128, 128, 128, 255, 1);
3071 }
3072 
3073 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
3074 // initialized the image with a RGB656 color
TEST_P(Texture2DTest,TexImageWithRGB565PBO)3075 TEST_P(Texture2DTest, TexImageWithRGB565PBO)
3076 {
3077     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3078     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3079 
3080     int width  = getWindowWidth();
3081     int height = getWindowHeight();
3082 
3083     GLTexture tex2D;
3084     glActiveTexture(GL_TEXTURE0);
3085     glBindTexture(GL_TEXTURE_2D, tex2D);
3086 
3087     // Fill PBO with red, with middle one as green
3088     std::vector<GLushort> pixels(16 * 16);
3089     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3090     {
3091         if (pixelId == 8 * 7 + 8)
3092         {
3093             pixels[pixelId] = 0x7E0;
3094         }
3095         else
3096         {
3097             pixels[pixelId] = 0xF800;
3098         }
3099     }
3100 
3101     GLuint pbo;
3102     glGenBuffers(1, &pbo);
3103     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3104     glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3105 
3106     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB565, 16, 16);
3107 
3108     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3109     // glTexSubImage2D should take into account that the image is dirty.
3110     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
3111                     reinterpret_cast<void *>(2));
3112     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3113     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3114 
3115     setUpProgram();
3116 
3117     glUseProgram(mProgram);
3118     glUniform1i(mTexture2DUniformLocation, 0);
3119     drawQuad(mProgram, "position", 0.5f);
3120     glDeleteBuffers(1, &pbo);
3121     EXPECT_GL_NO_ERROR();
3122     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3123     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3124 }
3125 
3126 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
3127 // initialized the image with a RGBA4444 color
TEST_P(Texture2DTest,TexImageWithRGBA4444PBO)3128 TEST_P(Texture2DTest, TexImageWithRGBA4444PBO)
3129 {
3130     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3131     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3132 
3133     int width  = getWindowWidth();
3134     int height = getWindowHeight();
3135 
3136     GLTexture tex2D;
3137     glActiveTexture(GL_TEXTURE0);
3138     glBindTexture(GL_TEXTURE_2D, tex2D);
3139 
3140     // Fill PBO with red, with middle one as green
3141     std::vector<GLushort> pixels(16 * 16);
3142     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3143     {
3144         if (pixelId == 8 * 7 + 8)
3145         {
3146             pixels[pixelId] = 0xF0F;
3147         }
3148         else
3149         {
3150             pixels[pixelId] = 0xF00F;
3151         }
3152     }
3153 
3154     GLuint pbo;
3155     glGenBuffers(1, &pbo);
3156     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3157     glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3158 
3159     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA4, 16, 16);
3160 
3161     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3162     // glTexSubImage2D should take into account that the image is dirty.
3163     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
3164                     reinterpret_cast<void *>(2));
3165     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3166     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3167 
3168     setUpProgram();
3169 
3170     glUseProgram(mProgram);
3171     glUniform1i(mTexture2DUniformLocation, 0);
3172     drawQuad(mProgram, "position", 0.5f);
3173     glDeleteBuffers(1, &pbo);
3174     EXPECT_GL_NO_ERROR();
3175     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3176     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3177 }
3178 
3179 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
3180 // initialized the image with a RGBA5551 color
TEST_P(Texture2DTest,TexImageWithRGBA5551PBO)3181 TEST_P(Texture2DTest, TexImageWithRGBA5551PBO)
3182 {
3183     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3184     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3185 
3186     int width  = getWindowWidth();
3187     int height = getWindowHeight();
3188 
3189     GLTexture tex2D;
3190     glActiveTexture(GL_TEXTURE0);
3191     glBindTexture(GL_TEXTURE_2D, tex2D);
3192 
3193     // Fill PBO with red, with middle one as green
3194     std::vector<GLushort> pixels(16 * 16);
3195     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3196     {
3197         if (pixelId == 8 * 7 + 7)
3198         {
3199             pixels[pixelId] = 0x7C1;
3200         }
3201         else
3202         {
3203             pixels[pixelId] = 0xF801;
3204         }
3205     }
3206 
3207     GLuint pbo;
3208     glGenBuffers(1, &pbo);
3209     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3210     glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3211 
3212     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB5_A1, 16, 16);
3213 
3214     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3215     // glTexSubImage2D should take into account that the image is dirty.
3216     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr);
3217     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3218     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3219 
3220     setUpProgram();
3221 
3222     glUseProgram(mProgram);
3223     glUniform1i(mTexture2DUniformLocation, 0);
3224     drawQuad(mProgram, "position", 0.5f);
3225     glDeleteBuffers(1, &pbo);
3226     EXPECT_GL_NO_ERROR();
3227     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3228     EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3229 }
3230 
3231 // Test that glTexSubImage2D from a PBO respects GL_UNPACK_ROW_LENGTH.
TEST_P(Texture2DTest,TexImageUnpackRowLengthPBO)3232 TEST_P(Texture2DTest, TexImageUnpackRowLengthPBO)
3233 {
3234     if (getClientMajorVersion() < 3)
3235     {
3236         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3237         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3238         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_unpack_subimage"));
3239     }
3240 
3241     const int width      = getWindowWidth() / 2;
3242     const int height     = getWindowHeight();
3243     const int rowLength  = getWindowWidth();
3244     const int bufferSize = rowLength * height;
3245 
3246     GLTexture tex2D;
3247     glActiveTexture(GL_TEXTURE0);
3248     glBindTexture(GL_TEXTURE_2D, tex2D);
3249 
3250     std::vector<GLColor> pixels(bufferSize);
3251     for (int y = 0; y < rowLength; ++y)
3252     {
3253         for (int x = 0; x < width; ++x)
3254         {
3255             pixels[y * rowLength + x] =
3256                 x < width ? (y < height / 2 ? GLColor::green : GLColor::blue) : GLColor::red;
3257         }
3258     }
3259 
3260     GLuint pbo;
3261     glGenBuffers(1, &pbo);
3262     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3263     glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize * sizeof(GLColor), pixels.data(),
3264                  GL_STATIC_DRAW);
3265 
3266     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
3267 
3268     // Initializes the texture from width x height of the PBO.
3269     glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength);
3270     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3271     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3272     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3273 
3274     setUpProgram();
3275 
3276     glUseProgram(mProgram);
3277     glUniform1i(mTexture2DUniformLocation, 0);
3278     drawQuad(mProgram, "position", 0.5f);
3279     glDeleteBuffers(1, &pbo);
3280     EXPECT_GL_NO_ERROR();
3281     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3282     EXPECT_PIXEL_COLOR_EQ(0, height - 1, GLColor::blue);
3283 }
3284 
3285 // Test if the KHR debug label is set and passed to D3D correctly using glCopyTexImage2D.
TEST_P(Texture2DTest,TextureKHRDebugLabelWithCopyTexImage2D)3286 TEST_P(Texture2DTest, TextureKHRDebugLabelWithCopyTexImage2D)
3287 {
3288     GLTexture texture2D;
3289     glBindTexture(GL_TEXTURE_2D, texture2D);
3290 
3291     // Create a texture and copy into, to initialize storage object.
3292     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 32, 32, 0);
3293 
3294     // Set KHR Debug Label.
3295     std::string label = "TestKHR.DebugLabel";
3296     glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3297 
3298     std::vector<char> labelBuf(label.length() + 1);
3299     GLsizei labelLengthBuf = 0;
3300 
3301     glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3302                         &labelLengthBuf, labelBuf.data());
3303 
3304     EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
3305     EXPECT_STREQ(label.c_str(), labelBuf.data());
3306 
3307     // Delete the texture.
3308     texture2D.reset();
3309     EXPECT_GL_NO_ERROR();
3310 
3311     glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3312     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3313 
3314     glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3315                         &labelLengthBuf, labelBuf.data());
3316     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3317 }
3318 
3319 // Test to call labeling API before the storage texture is created.
TEST_P(Texture2DTest,CallKHRDebugLabelBeforeTexStorageCreation)3320 TEST_P(Texture2DTest, CallKHRDebugLabelBeforeTexStorageCreation)
3321 {
3322     GLTexture texture2D;
3323     glBindTexture(GL_TEXTURE_2D, texture2D);
3324 
3325     // Set label before texture storage creation.
3326     std::string label = "TestKHR.DebugLabel";
3327     glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3328 
3329     // Create a texture and copy into, to initialize storage object.
3330     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 32, 32, 0);
3331 
3332     std::vector<char> labelBuf(label.length() + 1);
3333     GLsizei labelLengthBuf = 0;
3334 
3335     glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3336                         &labelLengthBuf, labelBuf.data());
3337 
3338     EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
3339     EXPECT_STREQ(label.c_str(), labelBuf.data());
3340 
3341     // Delete the texture.
3342     texture2D.reset();
3343     EXPECT_GL_NO_ERROR();
3344 
3345     glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3346     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3347 
3348     glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3349                         &labelLengthBuf, labelBuf.data());
3350     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3351 }
3352 
3353 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
3354 // initialized the image with a depth-only format.
TEST_P(Texture2DTestES3,TexImageWithDepthPBO)3355 TEST_P(Texture2DTestES3, TexImageWithDepthPBO)
3356 {
3357     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3358     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3359 
3360     // http://anglebug.com/42263861
3361     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
3362 
3363     constexpr GLsizei kSize = 4;
3364 
3365     // Set up the framebuffer.
3366     GLTexture colorTexture;
3367     glBindTexture(GL_TEXTURE_2D, colorTexture);
3368     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3369     ASSERT_GL_NO_ERROR();
3370 
3371     GLTexture depthTexture;
3372     glBindTexture(GL_TEXTURE_2D, depthTexture);
3373     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, kSize, kSize);
3374     ASSERT_GL_NO_ERROR();
3375 
3376     GLFramebuffer fbo;
3377     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3378     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3379     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3380     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3381     ASSERT_GL_NO_ERROR();
3382 
3383     // Clear depth to 0, ensuring the texture's image is allocated.
3384     glClearDepthf(0);
3385     glClearColor(0, 0, 0, 1);
3386     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3387     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3388 
3389     // Fill depth with 1.0f.
3390     std::vector<GLushort> pixels(kSize * kSize);
3391     for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
3392     {
3393         pixels[pixelId] = 0xFFFF;
3394     }
3395 
3396     GLuint pbo;
3397     glGenBuffers(1, &pbo);
3398     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3399     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
3400                  GL_STATIC_DRAW);
3401     ASSERT_GL_NO_ERROR();
3402 
3403     // Upload PBO data.
3404     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
3405                     nullptr);
3406 
3407     // If depth is not set to 1, rendering would fail.
3408     glEnable(GL_DEPTH_TEST);
3409     glDepthFunc(GL_LESS);
3410 
3411     // Draw red
3412     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3413     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
3414     ASSERT_GL_NO_ERROR();
3415 
3416     EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
3417 }
3418 
3419 // Test sampling modes with a DEPTH_COMPONENT16 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth16)3420 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth16)
3421 {
3422     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, false);
3423     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX, false);
3424 }
3425 
3426 // Test sampling modes with a swizzled DEPTH_COMPONENT16 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth16Swizzled)3427 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth16Swizzled)
3428 {
3429     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, true);
3430     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX, true);
3431 }
3432 
3433 // Test sampling modes with a DEPTH_COMPONENT24 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24)3434 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24)
3435 {
3436     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, false);
3437     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_STENCIL_INDEX, false);
3438 }
3439 
3440 // Test sampling modes with a swizzled DEPTH_COMPONENT24 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24Swizzled)3441 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24Swizzled)
3442 {
3443     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, true);
3444     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_STENCIL_INDEX, true);
3445 }
3446 
3447 // Test depth sampling with a DEPTH_COMPONENT32F texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32f)3448 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32f)
3449 {
3450     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, false);
3451     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_STENCIL_INDEX, false);
3452 }
3453 
3454 // Test depth sampling with a swizzled DEPTH_COMPONENT32F texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32fSwizzled)3455 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32fSwizzled)
3456 {
3457     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, true);
3458     TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_STENCIL_INDEX, true);
3459 }
3460 
3461 // Test sampling modes with a DEPTH24_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24Stencil8)3462 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24Stencil8)
3463 {
3464     TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_DEPTH_COMPONENT, false);
3465     TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_STENCIL_INDEX, false);
3466 }
3467 
3468 // Test sampling modes with a swizzled DEPTH24_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24Stencil8Swizzled)3469 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24Stencil8Swizzled)
3470 {
3471     TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_DEPTH_COMPONENT, true);
3472     TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_STENCIL_INDEX, true);
3473 }
3474 
3475 // Test sampling modes with a DEPTH32F_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32fStencil8)3476 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32fStencil8)
3477 {
3478     TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT, false);
3479     TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_STENCIL_INDEX, false);
3480 }
3481 
3482 // Test sampling modes with a swizzled DEPTH32F_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32fStencil8Swizzled)3483 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32fStencil8Swizzled)
3484 {
3485     TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT, true);
3486     TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_STENCIL_INDEX, true);
3487 }
3488 
3489 // Test sampling modes with a STENCIL_INDEX8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithStencil8)3490 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithStencil8)
3491 {
3492     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_stencil8"));
3493     TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_DEPTH_COMPONENT, false);
3494     TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, false);
3495 }
3496 
3497 // Test sampling modes with a swizzled STENCIL_INDEX8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithStencil8Swizzled)3498 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithStencil8Swizzled)
3499 {
3500     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_stencil8"));
3501     TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_DEPTH_COMPONENT, true);
3502     TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, true);
3503 }
3504 
3505 // Test that updating a texture format triggers depth/stencil mode resync.
TEST_P(Texture2DDepthStencilTestES3,Redefinition)3506 TEST_P(Texture2DDepthStencilTestES3, Redefinition)
3507 {
3508     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_stencil_texturing"));
3509 
3510     constexpr char kDepthFS[] =
3511         R"(#version 300 es
3512 precision mediump float;
3513 uniform highp sampler2D tex;
3514 out vec4 color;
3515 void main()
3516 {
3517     color = texture(tex, vec2(0, 0));
3518 })";
3519     ANGLE_GL_PROGRAM(programDepth, essl3_shaders::vs::Simple(), kDepthFS);
3520 
3521     constexpr char kStencilFS[] =
3522         R"(#version 300 es
3523 precision mediump float;
3524 uniform highp usampler2D tex;
3525 out vec4 color;
3526 void main()
3527 {
3528     color = vec4(texelFetch(tex, ivec2(0, 0), 0)) / 255.0;
3529 })";
3530     ANGLE_GL_PROGRAM(programStencil, essl3_shaders::vs::Simple(), kStencilFS);
3531 
3532     // Set up a D32F with stencil mode.
3533     GLTexture texture;
3534     glBindTexture(GL_TEXTURE_2D, texture);
3535     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3536     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3537     glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE_ANGLE, GL_STENCIL_INDEX);
3538 
3539     const GLfloat d32f = 0.5f;
3540     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
3541                  &d32f);
3542     ASSERT_GL_NO_ERROR();
3543 
3544     drawQuad(programDepth, essl3_shaders::PositionAttrib(), 0.5f);
3545     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
3546 
3547     // Redefine the same texture as D24S8
3548     const GLuint d24s8 = 0xC0;
3549     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL,
3550                  GL_UNSIGNED_INT_24_8, &d24s8);
3551     ASSERT_GL_NO_ERROR();
3552 
3553     drawQuad(programStencil, essl3_shaders::PositionAttrib(), 0.5f);
3554     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(192, 0, 0, 1), 1);
3555 
3556     // Redefine the same texture as D16
3557     const GLushort d16 = 0x4000;
3558     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 1, 1, 0, GL_DEPTH_COMPONENT,
3559                  GL_UNSIGNED_SHORT, &d16);
3560     ASSERT_GL_NO_ERROR();
3561 
3562     drawQuad(programDepth, essl3_shaders::PositionAttrib(), 0.5f);
3563     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(64, 0, 0, 255), 1);
3564 }
3565 
3566 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
3567 // initialized the image with a stencil-only format.
TEST_P(Texture2DTestES3,TexImageWithStencilPBO)3568 TEST_P(Texture2DTestES3, TexImageWithStencilPBO)
3569 {
3570     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3571     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3572 
3573     // http://anglebug.com/42263861
3574     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
3575 
3576     constexpr GLsizei kSize = 4;
3577 
3578     // Set up the framebuffer.
3579     GLTexture colorTexture;
3580     glBindTexture(GL_TEXTURE_2D, colorTexture);
3581     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3582     ASSERT_GL_NO_ERROR();
3583 
3584     GLTexture stencilTexture;
3585     glBindTexture(GL_TEXTURE_2D, stencilTexture);
3586     glTexStorage2D(GL_TEXTURE_2D, 1, GL_STENCIL_INDEX8, kSize, kSize);
3587     ASSERT_GL_NO_ERROR();
3588 
3589     GLFramebuffer fbo;
3590     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3591     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3592     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 0);
3593     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3594     ASSERT_GL_NO_ERROR();
3595 
3596     // Clear stencil to 0, ensuring the texture's image is allocated.
3597     glClearStencil(0);
3598     glClearColor(0, 0, 0, 1);
3599     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3600     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3601 
3602     // Fill stencil with 0x4E
3603     std::vector<GLubyte> pixels(kSize * kSize);
3604     for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
3605     {
3606         pixels[pixelId] = 0x4E;
3607     }
3608 
3609     GLuint pbo;
3610     glGenBuffers(1, &pbo);
3611     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3612     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
3613                  GL_STATIC_DRAW);
3614     ASSERT_GL_NO_ERROR();
3615 
3616     // Upload PBO data.
3617     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
3618                     nullptr);
3619     ASSERT_GL_NO_ERROR();
3620 
3621     // If stencil is not set to 0x4E, rendering would fail.
3622     glEnable(GL_STENCIL_TEST);
3623     glStencilFunc(GL_EQUAL, 0x4E, 0xFF);
3624     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3625     glStencilMask(0xFF);
3626 
3627     // Draw red
3628     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3629     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
3630     ASSERT_GL_NO_ERROR();
3631 
3632     EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
3633 }
3634 
3635 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
3636 // initialized the image with a depth/stencil format.
TEST_P(Texture2DTestES3,TexImageWithDepthStencilPBO)3637 TEST_P(Texture2DTestES3, TexImageWithDepthStencilPBO)
3638 {
3639     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3640     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3641 
3642     // http://anglebug.com/42263861
3643     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
3644 
3645     constexpr GLsizei kSize = 4;
3646 
3647     // Set up the framebuffer.
3648     GLTexture colorTexture;
3649     glBindTexture(GL_TEXTURE_2D, colorTexture);
3650     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3651     ASSERT_GL_NO_ERROR();
3652 
3653     GLTexture depthStencilTexture;
3654     glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
3655     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
3656     ASSERT_GL_NO_ERROR();
3657 
3658     GLFramebuffer fbo;
3659     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3660     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3661     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
3662                            depthStencilTexture, 0);
3663     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3664     ASSERT_GL_NO_ERROR();
3665 
3666     // Clear depth and stencil to 0, ensuring the texture's image is allocated.
3667     glClearDepthf(0);
3668     glClearStencil(0);
3669     glClearColor(0, 0, 0, 1);
3670     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3671     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3672 
3673     // Fill depth with 1.0f and stencil with 0xD5
3674     std::vector<GLuint> pixels(kSize * kSize);
3675     for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
3676     {
3677         pixels[pixelId] = 0xFFFFFFD5;
3678     }
3679 
3680     GLuint pbo;
3681     glGenBuffers(1, &pbo);
3682     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3683     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
3684                  GL_STATIC_DRAW);
3685     ASSERT_GL_NO_ERROR();
3686 
3687     // Upload PBO data.
3688     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
3689                     nullptr);
3690 
3691     // If depth is not set to 1, rendering would fail.
3692     glEnable(GL_DEPTH_TEST);
3693     glDepthFunc(GL_LESS);
3694 
3695     // If stencil is not set to 0xD5, rendering would fail.
3696     glEnable(GL_STENCIL_TEST);
3697     glStencilFunc(GL_EQUAL, 0xD5, 0xFF);
3698     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3699     glStencilMask(0xFF);
3700 
3701     // Draw red
3702     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3703     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
3704     ASSERT_GL_NO_ERROR();
3705 
3706     EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
3707 }
3708 
3709 // Test that it is possible to upload to a texture, upload a second texture and delete the first.
TEST_P(Texture2DTestES3,Texture1UploadThenTexture2UploadThenTexture1Delete)3710 TEST_P(Texture2DTestES3, Texture1UploadThenTexture2UploadThenTexture1Delete)
3711 {
3712     constexpr size_t kMaxBufferToImageCopySize = 64 * 1024 * 1024;
3713     constexpr size_t kTexSize                  = 4096;
3714     constexpr uint32_t kPixelSizeRGBA          = 4;
3715     static_assert(kTexSize * kTexSize * kPixelSizeRGBA == kMaxBufferToImageCopySize);
3716 
3717     std::vector<GLColor> textureColors(kTexSize * kTexSize, GLColor::red);
3718 
3719     // A mutable texture is defined here. The second texture is used to flush the first one when the
3720     // relevant feature (mutableMipmapTextureUpload) is enabled. If flushed, the update on level 0
3721     // is large enough to trigger one submission using Vulkan, but the rest of its updates will not
3722     // trigger a second one. In that case, the texture should not be deleted until all updates are
3723     // processed.
3724     GLuint texture1;
3725     glGenTextures(1, &texture1);
3726     glBindTexture(GL_TEXTURE_2D, texture1);
3727     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3728                  textureColors.data());
3729     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
3730                  GL_UNSIGNED_BYTE, textureColors.data());
3731     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3732     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3733     ASSERT_GL_NO_ERROR();
3734 
3735     GLTexture texture2;
3736     glBindTexture(GL_TEXTURE_2D, texture2);
3737     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3738                  textureColors.data());
3739     ASSERT_GL_NO_ERROR();
3740 
3741     glDeleteTextures(1, &texture1);
3742     ASSERT_GL_NO_ERROR();
3743 }
3744 
3745 // Test that the driver performs a flush when there is a large amount of image updates.
TEST_P(Texture2DMemoryTestES3,TextureDataInLoopUntilFlush)3746 TEST_P(Texture2DMemoryTestES3, TextureDataInLoopUntilFlush)
3747 {
3748     // Run this test for Vulkan only.
3749     ANGLE_SKIP_TEST_IF(!IsVulkan());
3750 
3751     // If VK_EXT_host_image_copy is used, uploads will all be done on the CPU and there would be no
3752     // submissions.
3753     ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::SupportsHostImageCopy));
3754 
3755     GLPerfMonitor monitor;
3756     glBeginPerfMonitorAMD(monitor);
3757 
3758     uint64_t expectedSubmitCalls = getPerfCounters().commandQueueSubmitCallsTotal + 1;
3759 
3760     // Set up program
3761     const char *kFS = R"(#version 300 es
3762 precision highp float;
3763 uniform uni { vec4 color; };
3764 out vec4 fragColor;
3765 void main()
3766 {
3767     fragColor = color;
3768 })";
3769     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
3770     ASSERT_NE(program, 0u);
3771 
3772     // Set up the uniform buffer and framebuffer
3773     GLint uniformBufferIndex;
3774     uniformBufferIndex = glGetUniformBlockIndex(program, "uni");
3775     ASSERT_NE(uniformBufferIndex, -1);
3776 
3777     glClear(GL_COLOR_BUFFER_BIT);
3778     constexpr size_t kBufferSize = 4 * 1024 * 1024;
3779     std::vector<float> floatData;
3780     floatData.resize(kBufferSize / (sizeof(float)), 0.0f);
3781     floatData[0] = 0.5f;
3782     floatData[1] = 0.75f;
3783     floatData[2] = 0.25f;
3784     floatData[3] = 1.0f;
3785 
3786     GLBuffer uniformBuffer;
3787     glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer);
3788     glBufferData(GL_UNIFORM_BUFFER, kBufferSize, floatData.data(), GL_STATIC_DRAW);
3789     glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniformBuffer);
3790     glUniformBlockBinding(program, uniformBufferIndex, 0);
3791 
3792     GLFramebuffer fbo;
3793     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3794 
3795     // Create textures and draw
3796     constexpr uint32_t kTextureWidth  = 512;
3797     constexpr uint32_t kTextureHeight = 512;
3798     std::vector<GLColor> textureColor(kTextureWidth * kTextureHeight, GLColor::red);
3799     constexpr uint32_t kIterationCount = 4096;
3800     GLTexture textures[kIterationCount];
3801 
3802     for (auto &texture : textures)
3803     {
3804         glBindTexture(GL_TEXTURE_2D, texture);
3805         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
3806         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RGBA,
3807                         GL_UNSIGNED_BYTE, textureColor.data());
3808 
3809         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3810         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3811         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3812 
3813         if (getPerfCounters().commandQueueSubmitCallsTotal == expectedSubmitCalls)
3814         {
3815             break;
3816         }
3817     }
3818     glEndPerfMonitorAMD(monitor);
3819 
3820     EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedSubmitCalls);
3821     ASSERT_GL_NO_ERROR();
3822     EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1);
3823 }
3824 
3825 // Creating a texture and drawing with it in a loop without glFlush() should still work. Driver is
3826 // supposedly to issue flush if needed. There should be no fallbacks to allocate outside the device
3827 // memory.
TEST_P(Texture2DMemoryTestES3,TextureDataInLoopManyTimes)3828 TEST_P(Texture2DMemoryTestES3, TextureDataInLoopManyTimes)
3829 {
3830     // Run this test for Vulkan only.
3831     ANGLE_SKIP_TEST_IF(!IsVulkan());
3832 
3833     GLPerfMonitor monitor;
3834     glBeginPerfMonitorAMD(monitor);
3835 
3836     uint64_t expectedSubmitCalls           = getPerfCounters().commandQueueSubmitCallsTotal + 1;
3837     uint64_t expectedDeviceMemoryFallbacks = getPerfCounters().deviceMemoryImageAllocationFallbacks;
3838 
3839     // Set up program
3840     const char *kFS = R"(#version 300 es
3841 precision highp float;
3842 uniform uni { vec4 color; };
3843 out vec4 fragColor;
3844 void main()
3845 {
3846     fragColor = color;
3847 })";
3848     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
3849     ASSERT_NE(program, 0u);
3850 
3851     // Set up the uniform buffer and framebuffer
3852     GLint uniformBufferIndex;
3853     uniformBufferIndex = glGetUniformBlockIndex(program, "uni");
3854     ASSERT_NE(uniformBufferIndex, -1);
3855 
3856     glClear(GL_COLOR_BUFFER_BIT);
3857     constexpr size_t kBufferSize = 4 * 1024 * 1024;
3858     std::vector<float> floatData;
3859     floatData.resize(kBufferSize / (sizeof(float)), 0.0f);
3860     floatData[0] = 0.5f;
3861     floatData[1] = 0.75f;
3862     floatData[2] = 0.25f;
3863     floatData[3] = 1.0f;
3864 
3865     GLBuffer uniformBuffer;
3866     glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer);
3867     glBufferData(GL_UNIFORM_BUFFER, kBufferSize, floatData.data(), GL_STATIC_DRAW);
3868     glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniformBuffer);
3869     glUniformBlockBinding(program, uniformBufferIndex, 0);
3870 
3871     GLFramebuffer fbo;
3872     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3873 
3874     // Create textures and draw. We will use very small image updates to prevent flush before the
3875     // device runs out of memory.
3876     constexpr uint32_t kTextureWidth  = 4096;
3877     constexpr uint32_t kTextureHeight = 4096;
3878     std::vector<GLColor> textureColor(kTextureWidth * kTextureHeight, GLColor::red);
3879     constexpr uint32_t kIterationCount = 4096;
3880 
3881     uint32_t iteration = 0;
3882     for (; iteration < kIterationCount; iteration++)
3883     {
3884         GLTexture texture;
3885         glBindTexture(GL_TEXTURE_2D, texture);
3886         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureWidth, kTextureHeight, 0, GL_RGBA,
3887                      GL_UNSIGNED_BYTE, nullptr);
3888         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
3889                         textureColor.data());
3890 
3891         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3892         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3893         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3894 
3895         if (getPerfCounters().commandQueueSubmitCallsTotal >= expectedSubmitCalls)
3896         {
3897             break;
3898         }
3899     }
3900 
3901     glEndPerfMonitorAMD(monitor);
3902     EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedSubmitCalls)
3903         << "iteration " << iteration;
3904     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks,
3905               expectedDeviceMemoryFallbacks);
3906     ASSERT_GL_NO_ERROR();
3907 }
3908 
3909 // Test functionality of GL_ANGLE_yuv_internal_format with min/mag filters
3910 // set to nearest and linear modes.
TEST_P(Texture2DTestES3YUV,TexStorage2DYuvFilterModes)3911 TEST_P(Texture2DTestES3YUV, TexStorage2DYuvFilterModes)
3912 {
3913     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3914 
3915     // Create YUV texture
3916     GLTexture yuvTexture;
3917     GLubyte yuvColor[]         = {40, 40, 40, 40, 40, 40, 40, 40, 240, 109, 240, 109};
3918     GLubyte expectedRgbColor[] = {0, 0, 255, 255};
3919     createImmutableTexture2D(yuvTexture, 2, 4, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3920                              GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
3921 
3922     // Default is nearest filter mode
3923     verifyResults2D(yuvTexture, expectedRgbColor);
3924     ASSERT_GL_NO_ERROR();
3925 
3926     // Enable linear filter mode
3927     glBindTexture(GL_TEXTURE_2D, yuvTexture);
3928     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3929     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3930     verifyResults2D(yuvTexture, expectedRgbColor);
3931     ASSERT_GL_NO_ERROR();
3932 
3933     const int windowHeight = getWindowHeight();
3934     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::blue, 1);
3935     EXPECT_PIXEL_COLOR_NEAR(0, windowHeight - 1, GLColor::blue, 1);
3936     EXPECT_PIXEL_COLOR_NEAR(0, windowHeight / 2, GLColor::blue, 1);
3937 }
3938 
3939 // Test functionality of GL_ANGLE_yuv_internal_format while cycling through RGB and YUV sources
TEST_P(Texture2DTestES3,TexStorage2DCycleThroughYuvAndRgbSources)3940 TEST_P(Texture2DTestES3, TexStorage2DCycleThroughYuvAndRgbSources)
3941 {
3942     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3943 
3944     // Create YUV texture
3945     GLTexture yuvTexture;
3946     GLubyte yuvColor[6]         = {40, 40, 40, 40, 240, 109};
3947     GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
3948     createImmutableTexture2D(yuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3949                              GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
3950 
3951     // Create RGBA texture
3952     GLTexture rgbaTexture;
3953     GLubyte rgbaColor[4] = {0, 0, 255, 255};
3954     createImmutableTexture2D(rgbaTexture, 1, 1, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, 1, rgbaColor);
3955 
3956     // Cycle through source textures
3957     // RGBA source
3958     verifyResults2D(rgbaTexture, rgbaColor);
3959     ASSERT_GL_NO_ERROR();
3960 
3961     // YUV source
3962     verifyResults2D(yuvTexture, expectedRgbColor);
3963     ASSERT_GL_NO_ERROR();
3964 
3965     // RGBA source
3966     verifyResults2D(rgbaTexture, rgbaColor);
3967     ASSERT_GL_NO_ERROR();
3968 }
3969 
3970 // Test functionality of GL_ANGLE_yuv_internal_format with large number of YUV sources
TEST_P(Texture2DTestES3,TexStorage2DLargeYuvTextureCount)3971 TEST_P(Texture2DTestES3, TexStorage2DLargeYuvTextureCount)
3972 {
3973     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3974 
3975     constexpr uint32_t kTextureCount = 16;
3976 
3977     // Create YUV texture
3978     GLTexture yuvTexture[kTextureCount];
3979     for (uint32_t i = 0; i < kTextureCount; i++)
3980     {
3981         // Create 2 plane YCbCr 420 texture
3982         createImmutableTexture2D(yuvTexture[i], 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3983                                  GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
3984     }
3985 
3986     // Cycle through YUV source textures
3987     glUseProgram(mProgram);
3988     glUniform1i(mTexture2DUniformLocation, 0);
3989 
3990     for (uint32_t i = 0; i < kTextureCount; i++)
3991     {
3992         glBindTexture(GL_TEXTURE_2D, yuvTexture[i]);
3993         drawQuad(mProgram, "position", 0.5f);
3994         ASSERT_GL_NO_ERROR();
3995     }
3996 }
3997 
3998 // Test functionality of GL_ANGLE_yuv_internal_format with simultaneous use of multiple YUV sources
TEST_P(Texture2DTestES3,TexStorage2DSimultaneousUseOfMultipleYuvSourcesNoData)3999 TEST_P(Texture2DTestES3, TexStorage2DSimultaneousUseOfMultipleYuvSourcesNoData)
4000 {
4001     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4002 
4003     // Create YUV texture
4004     // Create 2 plane YCbCr 420 texture
4005     GLTexture twoPlaneYuvTexture;
4006     createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4007                              GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4008 
4009     // Create 3 plane YCbCr 420 texture
4010     GLTexture threePlaneYuvTexture;
4011     createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4012                              GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4013 
4014     // Cycle through YUV source textures
4015     // Create program with 2 samplers
4016     const char *vertexShaderSource   = getVertexShaderSource();
4017     const char *fragmentShaderSource = R"(#version 300 es
4018 precision highp float;
4019 uniform sampler2D tex0;
4020 uniform sampler2D tex1;
4021 in vec2 texcoord;
4022 out vec4 fragColor;
4023 
4024 void main()
4025 {
4026     vec4 color0 = texture(tex0, texcoord);
4027     vec4 color1 = texture(tex1, texcoord);
4028     fragColor = color0 + color1;
4029 })";
4030 
4031     ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
4032     glUseProgram(twoSamplersProgram);
4033     GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
4034     ASSERT_NE(-1, tex0Location);
4035     GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
4036     ASSERT_NE(-1, tex1Location);
4037 
4038     glUniform1i(tex0Location, 0);
4039     glUniform1i(tex1Location, 1);
4040 
4041     // Bind 2 plane YUV source
4042     glActiveTexture(GL_TEXTURE0);
4043     glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4044     ASSERT_GL_NO_ERROR();
4045 
4046     // Bind 3 plane YUV source
4047     glActiveTexture(GL_TEXTURE1);
4048     glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4049     ASSERT_GL_NO_ERROR();
4050 
4051     drawQuad(twoSamplersProgram, "position", 0.5f);
4052     ASSERT_GL_NO_ERROR();
4053 
4054     // Switch active texture index and draw again
4055     // Bind 2 plane YUV source
4056     glActiveTexture(GL_TEXTURE1);
4057     glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4058     ASSERT_GL_NO_ERROR();
4059 
4060     // Bind 3 plane YUV source
4061     glActiveTexture(GL_TEXTURE0);
4062     glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4063     ASSERT_GL_NO_ERROR();
4064 
4065     drawQuad(twoSamplersProgram, "position", 0.5f);
4066     ASSERT_GL_NO_ERROR();
4067 }
4068 
4069 // Test functional of GL_ANGLE_yuv_internal_format while cycling through YUV sources
TEST_P(Texture2DTestES3,TexStorage2DCycleThroughYuvSourcesNoData)4070 TEST_P(Texture2DTestES3, TexStorage2DCycleThroughYuvSourcesNoData)
4071 {
4072     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4073 
4074     // Create YUV texture
4075     // Create 2 plane YCbCr 420 texture
4076     GLTexture twoPlaneYuvTexture;
4077     createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4078                              GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4079 
4080     // Create 3 plane YCbCr 420 texture
4081     GLTexture threePlaneYuvTexture;
4082     createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4083                              GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4084 
4085     // Cycle through YUV source textures
4086     glUseProgram(mProgram);
4087     glUniform1i(mTexture2DUniformLocation, 0);
4088 
4089     // 2 plane YUV source
4090     glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4091     drawQuad(mProgram, "position", 0.5f);
4092     ASSERT_GL_NO_ERROR();
4093 
4094     // 3 plane YUV source
4095     glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4096     drawQuad(mProgram, "position", 0.5f);
4097     ASSERT_GL_NO_ERROR();
4098 
4099     // 2 plane YUV source
4100     glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4101     drawQuad(mProgram, "position", 0.5f);
4102     ASSERT_GL_NO_ERROR();
4103 }
4104 
4105 // Test functionality of GL_ANGLE_yuv_internal_format with multiple YUV samplers while
4106 // switching sampler uniform values.
TEST_P(Texture2DTestES3,TexStorage2DMultipleYuvSamplersSwitchSamplerUniformValues)4107 TEST_P(Texture2DTestES3, TexStorage2DMultipleYuvSamplersSwitchSamplerUniformValues)
4108 {
4109     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4110 
4111     // Create YUV texture
4112     GLTexture yuvTexture;
4113     GLubyte yuvColor[6]         = {40, 40, 40, 40, 240, 109};
4114     GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
4115 
4116     // Create YUV texture
4117     // Create 2 plane YCbCr 420 texture
4118     GLTexture twoPlaneYuvTexture;
4119     createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4120                              GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
4121     // Create 3 plane YCbCr 420 texture
4122     GLTexture threePlaneYuvTexture;
4123     createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4124                              GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4125     // Create program with 2 samplers
4126     const char *vertexShaderSource   = getVertexShaderSource();
4127     const char *fragmentShaderSource = R"(#version 300 es
4128 precision highp float;
4129 uniform sampler2D tex0;
4130 uniform sampler2D tex1;
4131 uniform int texIndex;
4132 in vec2 texcoord;
4133 out vec4 fragColor;
4134 void main()
4135 {
4136     vec4 color0 = texture(tex0, texcoord);
4137     vec4 color1 = texture(tex1, texcoord);
4138     if (texIndex == 0)
4139     {
4140         fragColor = color0;
4141     }
4142     else
4143     {
4144         fragColor = color1;
4145     }
4146 })";
4147     ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
4148     glUseProgram(twoSamplersProgram);
4149     GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
4150     ASSERT_NE(-1, tex0Location);
4151     GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
4152     ASSERT_NE(-1, tex1Location);
4153     GLint texIndexLocation = glGetUniformLocation(twoSamplersProgram, "texIndex");
4154     ASSERT_NE(-1, texIndexLocation);
4155     // Bind 2 plane YUV source
4156     glActiveTexture(GL_TEXTURE0);
4157     glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4158     ASSERT_GL_NO_ERROR();
4159     // Bind 3 plane YUV source
4160     glActiveTexture(GL_TEXTURE1);
4161     glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4162     ASSERT_GL_NO_ERROR();
4163 
4164     // Set sampler uniform values and draw
4165     glUniform1i(tex0Location, 0);
4166     glUniform1i(tex1Location, 1);
4167     // Set texture index selector to the 2 plane texture unit
4168     glUniform1i(texIndexLocation, 0);
4169     drawQuad(twoSamplersProgram, "position", 0.5f);
4170     ASSERT_GL_NO_ERROR();
4171     EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4172                       expectedRgbColor[3], 1);
4173     ASSERT_GL_NO_ERROR();
4174 
4175     // Switch sampler uniform values and draw
4176     glUniform1i(tex0Location, 1);
4177     glUniform1i(tex1Location, 0);
4178     // Set texture index selector to the 2 plane texture unit
4179     glUniform1i(texIndexLocation, 1);
4180     drawQuad(twoSamplersProgram, "position", 0.5f);
4181     ASSERT_GL_NO_ERROR();
4182     EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4183                       expectedRgbColor[3], 1);
4184     ASSERT_GL_NO_ERROR();
4185 
4186     // Switch back sampler uniform values and draw
4187     glUniform1i(tex0Location, 0);
4188     glUniform1i(tex1Location, 1);
4189     // Set texture index selector to the 2 plane texture unit
4190     glUniform1i(texIndexLocation, 0);
4191     drawQuad(twoSamplersProgram, "position", 0.5f);
4192     ASSERT_GL_NO_ERROR();
4193     EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4194                       expectedRgbColor[3], 1);
4195     ASSERT_GL_NO_ERROR();
4196 }
4197 
4198 // Test functionality of GL_ANGLE_yuv_internal_format with multiple YUV samplers while
4199 // switching bound textures.
TEST_P(Texture2DTestES3,TexStorage2DMultipleYuvSamplersSwitchBoundTextures)4200 TEST_P(Texture2DTestES3, TexStorage2DMultipleYuvSamplersSwitchBoundTextures)
4201 {
4202     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4203 
4204     // Create YUV texture
4205     GLTexture yuvTexture;
4206     GLubyte yuvColor[6]         = {40, 40, 40, 40, 240, 109};
4207     GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
4208 
4209     // Create YUV texture
4210     // Create 2 plane YCbCr 420 texture
4211     GLTexture twoPlaneYuvTexture;
4212     createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4213                              GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
4214     // Create 3 plane YCbCr 420 texture
4215     GLTexture threePlaneYuvTexture;
4216     createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4217                              GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4218     // Create program with 2 samplers
4219     const char *vertexShaderSource   = getVertexShaderSource();
4220     const char *fragmentShaderSource = R"(#version 300 es
4221 precision highp float;
4222 uniform sampler2D tex0;
4223 uniform sampler2D tex1;
4224 uniform int texIndex;
4225 in vec2 texcoord;
4226 out vec4 fragColor;
4227 void main()
4228 {
4229     vec4 color0 = texture(tex0, texcoord);
4230     vec4 color1 = texture(tex1, texcoord);
4231     if (texIndex == 0)
4232     {
4233         fragColor = color0;
4234     }
4235     else
4236     {
4237         fragColor = color1;
4238     }
4239 })";
4240     ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
4241     glUseProgram(twoSamplersProgram);
4242     GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
4243     ASSERT_NE(-1, tex0Location);
4244     GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
4245     ASSERT_NE(-1, tex1Location);
4246     GLint texIndexLocation = glGetUniformLocation(twoSamplersProgram, "texIndex");
4247     ASSERT_NE(-1, texIndexLocation);
4248     // Set sampler uniform values
4249     glUniform1i(tex0Location, 0);
4250     glUniform1i(tex1Location, 1);
4251 
4252     // Bind 2 plane YUV source
4253     glActiveTexture(GL_TEXTURE0);
4254     glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4255     ASSERT_GL_NO_ERROR();
4256     // Bind 3 plane YUV source
4257     glActiveTexture(GL_TEXTURE1);
4258     glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4259     ASSERT_GL_NO_ERROR();
4260     // Set texture index selector to the 2 plane texture unit
4261     glUniform1i(texIndexLocation, 0);
4262     // Draw
4263     drawQuad(twoSamplersProgram, "position", 0.5f);
4264     ASSERT_GL_NO_ERROR();
4265     EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4266                       expectedRgbColor[3], 1);
4267     ASSERT_GL_NO_ERROR();
4268 
4269     // Bind 3 plane YUV source
4270     glActiveTexture(GL_TEXTURE0);
4271     glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4272     ASSERT_GL_NO_ERROR();
4273     // Bind 2 plane YUV source
4274     glActiveTexture(GL_TEXTURE1);
4275     glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4276     ASSERT_GL_NO_ERROR();
4277     // Set texture index selector to the 2 plane texture unit
4278     glUniform1i(texIndexLocation, 1);
4279     // Draw
4280     drawQuad(twoSamplersProgram, "position", 0.5f);
4281     ASSERT_GL_NO_ERROR();
4282     EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4283                       expectedRgbColor[3], 1);
4284     ASSERT_GL_NO_ERROR();
4285 }
4286 
4287 // Tests CopySubImage for float formats
TEST_P(Texture2DTest,CopySubImageFloat_R_R)4288 TEST_P(Texture2DTest, CopySubImageFloat_R_R)
4289 {
4290     testFloatCopySubImage(1, 1);
4291 }
4292 
TEST_P(Texture2DTest,CopySubImageFloat_RG_R)4293 TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
4294 {
4295     testFloatCopySubImage(2, 1);
4296 }
4297 
TEST_P(Texture2DTest,CopySubImageFloat_RG_RG)4298 TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
4299 {
4300     testFloatCopySubImage(2, 2);
4301 }
4302 
TEST_P(Texture2DTest,CopySubImageFloat_RGB_R)4303 TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
4304 {
4305     testFloatCopySubImage(3, 1);
4306 }
4307 
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RG)4308 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
4309 {
4310     testFloatCopySubImage(3, 2);
4311 }
4312 
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RGB)4313 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
4314 {
4315     // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/40096350)
4316     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
4317 
4318     testFloatCopySubImage(3, 3);
4319 }
4320 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_R)4321 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
4322 {
4323     testFloatCopySubImage(4, 1);
4324 }
4325 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RG)4326 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
4327 {
4328     testFloatCopySubImage(4, 2);
4329 }
4330 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGB)4331 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
4332 {
4333     testFloatCopySubImage(4, 3);
4334 }
4335 
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGBA)4336 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
4337 {
4338     testFloatCopySubImage(4, 4);
4339 }
4340 
4341 // Port of
4342 // https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
4343 // Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
4344 // handles GL_ALPHA
TEST_P(Texture2DTest,TextureNPOT_GL_ALPHA_UBYTE)4345 TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
4346 {
4347     const int npotTexSize = 5;
4348     const int potTexSize  = 4;  // Should be less than npotTexSize
4349     GLTexture tex2D;
4350 
4351     if (IsGLExtensionEnabled("GL_OES_texture_npot"))
4352     {
4353         // This test isn't applicable if texture_npot is enabled
4354         return;
4355     }
4356 
4357     setUpProgram();
4358 
4359     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
4360 
4361     // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
4362     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4363 
4364     glActiveTexture(GL_TEXTURE0);
4365     glBindTexture(GL_TEXTURE_2D, tex2D);
4366 
4367     const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
4368 
4369     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4370     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4371 
4372     // Check that an NPOT texture not on level 0 generates INVALID_VALUE
4373     glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
4374                  GL_UNSIGNED_BYTE, pixels.data());
4375     EXPECT_GL_ERROR(GL_INVALID_VALUE);
4376 
4377     // Check that an NPOT texture on level 0 succeeds
4378     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
4379                  GL_UNSIGNED_BYTE, pixels.data());
4380     EXPECT_GL_NO_ERROR();
4381 
4382     // Check that generateMipmap fails on NPOT
4383     glGenerateMipmap(GL_TEXTURE_2D);
4384     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4385 
4386     // Check that nothing is drawn if filtering is not correct for NPOT
4387     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4388     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4389     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
4390     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
4391     glClear(GL_COLOR_BUFFER_BIT);
4392     drawQuad(mProgram, "position", 1.0f);
4393     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
4394 
4395     // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
4396     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4397     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4398     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
4399     glClear(GL_COLOR_BUFFER_BIT);
4400     drawQuad(mProgram, "position", 1.0f);
4401     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
4402 
4403     // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
4404     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4405     glClear(GL_COLOR_BUFFER_BIT);
4406     drawQuad(mProgram, "position", 1.0f);
4407     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
4408 
4409     // Check that glTexImage2D for POT texture succeeds
4410     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
4411                  pixels.data());
4412     EXPECT_GL_NO_ERROR();
4413 
4414     // Check that generateMipmap for an POT texture succeeds
4415     glGenerateMipmap(GL_TEXTURE_2D);
4416     EXPECT_GL_NO_ERROR();
4417 
4418     // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
4419     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4420     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4421     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
4422     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
4423     glClear(GL_COLOR_BUFFER_BIT);
4424     drawQuad(mProgram, "position", 1.0f);
4425     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
4426     EXPECT_GL_NO_ERROR();
4427 }
4428 
4429 // Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
4430 // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
TEST_P(Texture2DTest,NPOTSubImageParameters)4431 TEST_P(Texture2DTest, NPOTSubImageParameters)
4432 {
4433     glActiveTexture(GL_TEXTURE0);
4434     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4435 
4436     // Create an 8x8 (i.e. power-of-two) texture.
4437     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4438     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4439     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4440     glGenerateMipmap(GL_TEXTURE_2D);
4441 
4442     // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
4443     // This should always work, even if GL_OES_texture_npot isn't active.
4444     std::array<GLColor, 3 * 3> data;
4445     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
4446 
4447     EXPECT_GL_NO_ERROR();
4448 }
4449 
4450 // Regression test for https://crbug.com/1222516 to prevent integer overflow during validation.
TEST_P(Texture2DTest,SubImageValidationOverflow)4451 TEST_P(Texture2DTest, SubImageValidationOverflow)
4452 {
4453     glActiveTexture(GL_TEXTURE0);
4454     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4455 
4456     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4457     EXPECT_GL_NO_ERROR();
4458 
4459     glTexSubImage2D(GL_TEXTURE_2D, 0, -4, 0, 2147483647, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4460     EXPECT_GL_ERROR(GL_INVALID_VALUE);
4461 
4462     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, -4, 1, 2147483647, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4463     EXPECT_GL_ERROR(GL_INVALID_VALUE);
4464 }
4465 
4466 // Test that when a mutable texture is deleted, its corresponding pointer in the Vulkan backend,
4467 // which is used for mutable texture flushing, is also deleted, and is not accessed by the new
4468 // mutable texture after it.
TEST_P(Texture2DTest,MutableUploadThenDeleteThenMutableUpload)4469 TEST_P(Texture2DTest, MutableUploadThenDeleteThenMutableUpload)
4470 {
4471     GLTexture texture1;
4472     glBindTexture(GL_TEXTURE_2D, texture1);
4473     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4474                  GLColor::red.data());
4475     texture1.reset();
4476     EXPECT_GL_NO_ERROR();
4477 
4478     GLTexture texture2;
4479     glBindTexture(GL_TEXTURE_2D, texture2);
4480     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4481                  GLColor::green.data());
4482     texture2.reset();
4483     EXPECT_GL_NO_ERROR();
4484 }
4485 
4486 // Test to ensure that glTexStorage3D accepts ASTC sliced 3D. https://crbug.com/1060012
TEST_P(Texture3DTestES3,ImmutableASTCSliced3D)4487 TEST_P(Texture3DTestES3, ImmutableASTCSliced3D)
4488 {
4489     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_texture_compression_astc_sliced_3d"));
4490 
4491     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4492     glTexStorage3D(GL_TEXTURE_3D, 1, GL_COMPRESSED_RGBA_ASTC_4x4, 4, 4, 1);
4493     EXPECT_GL_NO_ERROR();
4494 }
4495 
FillLevel(GLint level,GLuint width,GLuint height,const GLColor & color,bool cubemap,bool subTex)4496 void FillLevel(GLint level,
4497                GLuint width,
4498                GLuint height,
4499                const GLColor &color,
4500                bool cubemap,
4501                bool subTex)
4502 {
4503     std::vector<GLColor> pixels(width * height, color);
4504     std::vector<GLenum> targets;
4505     if (cubemap)
4506     {
4507         targets = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
4508                    GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
4509                    GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
4510     }
4511     else
4512     {
4513         targets = {GL_TEXTURE_2D};
4514     }
4515 
4516     for (GLenum target : targets)
4517     {
4518         if (subTex)
4519         {
4520             glTexSubImage2D(target, level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
4521                             pixels.data());
4522         }
4523         else
4524         {
4525             glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4526                          pixels.data());
4527         }
4528     }
4529 }
4530 
4531 // This is part of tests that webgl_conformance_vulkan_passthrough_tests
4532 // conformance/textures/misc/texture-size.html does
testTextureSize(int testCaseIndex)4533 void Texture2DTest::testTextureSize(int testCaseIndex)
4534 {
4535     std::array<GLColor, 6> kNewMipColors = {
4536         GLColor::green,  GLColor::red,     GLColor::blue,
4537         GLColor::yellow, GLColor::magenta, GLColor::cyan,
4538     };
4539     GLuint colorCount = 0;
4540 
4541     setUpProgram();
4542 
4543     constexpr char kVS[] =
4544         R"(precision highp float;
4545 attribute vec4 position;
4546 varying vec3 texcoord;
4547 void main()
4548 {
4549     gl_Position = position;
4550     texcoord = (position.xyz * 0.5) + 0.5;
4551 }
4552 )";
4553     constexpr char kFS[] =
4554         R"(precision mediump float;
4555 uniform samplerCube tex;
4556 varying vec3 texcoord;
4557 void main()
4558 {
4559     gl_FragColor = textureCube(tex, texcoord);
4560 })";
4561     ANGLE_GL_PROGRAM(programCubeMap, kVS, kFS);
4562     GLint textureCubeUniformLocation = glGetUniformLocation(programCubeMap, "tex");
4563     ASSERT_NE(-1, textureCubeUniformLocation);
4564     ASSERT_GL_NO_ERROR();
4565 
4566     GLint max2DSize = 0;
4567     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
4568     GLint maxCubeMapSize = 0;
4569     glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapSize);
4570     // Assuming 2048x2048xRGBA (22 mb with mips) will run on all WebGL platforms
4571     GLint max2DSquareSize = std::min(max2DSize, 2048);
4572     // I'd prefer this to be 2048 but that's 16 mb x 6 faces or 128 mb (with mips)
4573     // 1024 is 33.5 mb (with mips)
4574     maxCubeMapSize = std::min(maxCubeMapSize, 1024);
4575     ASSERT_GL_NO_ERROR();
4576 
4577     for (GLint size = 1; size <= max2DSize; size *= 2)
4578     {
4579         bool cubeMap     = testCaseIndex == 3;
4580         GLenum texTarget = cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
4581         GLuint program   = cubeMap ? programCubeMap : mProgram;
4582         GLint texWidth = 0, texHeight = 0;
4583 
4584         switch (testCaseIndex)
4585         {
4586             case 0:
4587                 texWidth  = size;
4588                 texHeight = 1;
4589                 break;
4590             case 1:
4591                 texWidth  = 1;
4592                 texHeight = size;
4593                 break;
4594             case 2:
4595             case 3:
4596                 texWidth  = size;
4597                 texHeight = size;
4598                 break;
4599         }
4600 
4601         if (texWidth == texHeight && size > max2DSquareSize)
4602         {
4603             return;
4604         }
4605 
4606         if (cubeMap && size > maxCubeMapSize)
4607         {
4608             return;
4609         }
4610 
4611         GLTexture texture;
4612         glActiveTexture(GL_TEXTURE0);
4613         glBindTexture(texTarget, texture);
4614         FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
4615         glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4616         glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4617         glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4618         glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4619         ASSERT_GL_NO_ERROR();
4620 
4621         glClear(GL_COLOR_BUFFER_BIT);
4622         ASSERT_GL_NO_ERROR();
4623 
4624         glUseProgram(program);
4625         if (cubeMap)
4626         {
4627             glUniform1i(textureCubeUniformLocation, 0);
4628         }
4629         else
4630         {
4631             glUniform1i(mTexture2DUniformLocation, 0);
4632         }
4633 
4634         drawQuad(program, "position", 1.0f);
4635         ASSERT_GL_NO_ERROR();
4636         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
4637 
4638         colorCount = (colorCount + 1) % kNewMipColors.size();
4639         FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
4640         glGenerateMipmap(texTarget);
4641         ASSERT_GL_NO_ERROR();
4642 
4643         glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4644         glClear(GL_COLOR_BUFFER_BIT);
4645         drawQuad(program, "position", 1.0f);
4646         ASSERT_GL_NO_ERROR();
4647         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
4648 
4649         colorCount = (colorCount + 1) % kNewMipColors.size();
4650         FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, true);
4651         glGenerateMipmap(texTarget);
4652 
4653         glClear(GL_COLOR_BUFFER_BIT);
4654         drawQuad(program, "position", 1.0f);
4655         ASSERT_GL_NO_ERROR();
4656         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
4657     }
4658 }
4659 
testTextureSizeError()4660 void Texture2DTest::testTextureSizeError()
4661 {
4662     GLint max2DSize = 0;
4663     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
4664     glActiveTexture(GL_TEXTURE0);
4665     GLTexture texture;
4666     glBindTexture(GL_TEXTURE_2D, texture);
4667     FillLevel(0, max2DSize, max2DSize, GLColor::red, false, false);
4668     GLenum err  = glGetError();
4669     bool passed = (err == GL_NO_ERROR || err == GL_OUT_OF_MEMORY);
4670     ASSERT_TRUE(passed);
4671 }
4672 
4673 // Permutation 0 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase0)4674 TEST_P(Texture2DTest, TextureSizeCase0)
4675 {
4676     testTextureSize(0);
4677 }
4678 
4679 // Permutation 1 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase1)4680 TEST_P(Texture2DTest, TextureSizeCase1)
4681 {
4682     testTextureSize(1);
4683 }
4684 
4685 // Permutation 2 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase2)4686 TEST_P(Texture2DTest, TextureSizeCase2)
4687 {
4688     testTextureSize(2);
4689 }
4690 
4691 // Permutation 3 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase3)4692 TEST_P(Texture2DTest, TextureSizeCase3)
4693 {
4694     testTextureSize(3);
4695 }
4696 
4697 // Test allocating a very large texture
TEST_P(Texture2DTest,TextureMaxSize)4698 TEST_P(Texture2DTest, TextureMaxSize)
4699 {
4700     testTextureSizeError();
4701 }
4702 
4703 // Test that drawing works correctly RGBA 3D texture
TEST_P(Texture3DTestES2,RGBA)4704 TEST_P(Texture3DTestES2, RGBA)
4705 {
4706     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4707 
4708     // http://anglebug.com/42264265
4709     ANGLE_SKIP_TEST_IF(IsOzone());
4710 
4711     glActiveTexture(GL_TEXTURE0);
4712     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4713     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
4714     std::vector<GLColor> texDataRed(1u * 1u * 1u, GLColor::red);
4715     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4716                     texDataGreen.data());
4717     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4718                     texDataRed.data());
4719     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4720     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4721 
4722     EXPECT_GL_NO_ERROR();
4723 
4724     drawQuad(mProgram, "position", 0.5f);
4725 
4726     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4727 }
4728 
4729 // Test that drawing works correctly Luminance 3D texture
TEST_P(Texture3DTestES2,Luminance)4730 TEST_P(Texture3DTestES2, Luminance)
4731 {
4732     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4733 
4734     // http://anglebug.com/42264265
4735     ANGLE_SKIP_TEST_IF(IsOzone());
4736 
4737     glActiveTexture(GL_TEXTURE0);
4738     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4739     std::vector<GLubyte> texData(2u * 2u * 2u, 125);
4740     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4741     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4742                     texData.data());
4743     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4744     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4745 
4746     EXPECT_GL_NO_ERROR();
4747 
4748     drawQuad(mProgram, "position", 0.5f);
4749 
4750     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(125, 125, 125, 255));
4751 }
4752 
4753 // Test that drawing works correctly with glCopyTexSubImage3D
TEST_P(Texture3DTestES2,CopySubImageRGBA)4754 TEST_P(Texture3DTestES2, CopySubImageRGBA)
4755 {
4756     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4757 
4758     // http://anglebug.com/42264265
4759     ANGLE_SKIP_TEST_IF(IsOzone());
4760 
4761     glClearColor(0, 0, 1, 1);
4762     glClear(GL_COLOR_BUFFER_BIT);
4763 
4764     glActiveTexture(GL_TEXTURE0);
4765     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4766     std::vector<GLColor> texDataRed(4u * 4u * 4u, GLColor::red);
4767     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4768                     texDataRed.data());
4769     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4770                     texDataRed.data());
4771     glTexImage3DOES(GL_TEXTURE_3D, 2, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4772                     texDataRed.data());
4773     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
4774     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
4775     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4776     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4777 
4778     EXPECT_GL_NO_ERROR();
4779 
4780     glClearColor(0, 1, 0, 1);
4781     glClear(GL_COLOR_BUFFER_BIT);
4782     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4783 
4784     glUseProgram(mProgram);
4785     glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
4786     drawQuad(mProgram, "position", 0.5f);
4787 
4788     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
4789 }
4790 
TEST_P(Texture3DTestES2,CopySubImageLuminance)4791 TEST_P(Texture3DTestES2, CopySubImageLuminance)
4792 {
4793     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4794 
4795     // http://anglebug.com/42264265
4796     ANGLE_SKIP_TEST_IF(IsOzone());
4797 
4798     glClearColor(1, 0, 0, 1);
4799     glClear(GL_COLOR_BUFFER_BIT);
4800 
4801     glActiveTexture(GL_TEXTURE0);
4802     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4803     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 4, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4804                     nullptr);
4805     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4806                     nullptr);
4807     glTexImage3DOES(GL_TEXTURE_3D, 2, GL_LUMINANCE, 1, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4808                     nullptr);
4809     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
4810     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
4811     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4812     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4813 
4814     EXPECT_GL_NO_ERROR();
4815 
4816     glClearColor(0, 1, 0, 1);
4817     glClear(GL_COLOR_BUFFER_BIT);
4818     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4819 
4820     glUseProgram(mProgram);
4821     glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
4822     drawQuad(mProgram, "position", 0.5f);
4823 
4824     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
4825 }
4826 
TEST_P(Texture3DTestES2,CopySubImageAlpha)4827 TEST_P(Texture3DTestES2, CopySubImageAlpha)
4828 {
4829     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4830 
4831     // http://anglebug.com/42264265
4832     ANGLE_SKIP_TEST_IF(IsOzone());
4833 
4834     glClearColor(1, 0, 0, 0.5);
4835     glClear(GL_COLOR_BUFFER_BIT);
4836 
4837     glActiveTexture(GL_TEXTURE0);
4838     glBindTexture(GL_TEXTURE_3D, mTexture3D);
4839     glTexImage3DOES(GL_TEXTURE_3D, 0, GL_ALPHA, 4, 4, 4, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
4840     glTexImage3DOES(GL_TEXTURE_3D, 1, GL_ALPHA, 2, 2, 2, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
4841     glTexImage3DOES(GL_TEXTURE_3D, 2, GL_ALPHA, 1, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
4842     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
4843     glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
4844     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4845     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4846 
4847     EXPECT_GL_NO_ERROR();
4848 
4849     glClearColor(0, 1, 0, 1);
4850     glClear(GL_COLOR_BUFFER_BIT);
4851     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4852 
4853     glUseProgram(mProgram);
4854     glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
4855     drawQuad(mProgram, "position", 0.5f);
4856 
4857     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 128), 1.0);
4858 }
4859 
4860 // Test that defining a 2D texture array fails with Texture3DOES on ES2.
TEST_P(Texture3DTestES2,DefineTexture2DArrayShouldFail)4861 TEST_P(Texture3DTestES2, DefineTexture2DArrayShouldFail)
4862 {
4863     ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4864 
4865     // http://anglebug.com/42264265
4866     ANGLE_SKIP_TEST_IF(IsOzone());
4867 
4868     glClearColor(1, 0, 0, 1);
4869     glClear(GL_COLOR_BUFFER_BIT);
4870 
4871     glActiveTexture(GL_TEXTURE0);
4872     glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
4873     EXPECT_GL_ERROR(GL_INVALID_ENUM);
4874 
4875     glTexImage3DOES(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4876                     nullptr);
4877     glTexImage3DOES(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4878                     nullptr);
4879     glTexImage3DOES(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4880                     nullptr);
4881     EXPECT_GL_ERROR(GL_INVALID_ENUM);
4882 }
4883 
4884 // Verify shrinking a texture with glTexStorage2D works correctly
TEST_P(Texture2DTestES3,ChangeTexSizeWithTexStorage)4885 TEST_P(Texture2DTestES3, ChangeTexSizeWithTexStorage)
4886 {
4887     // TODO: http://anglebug.com/42263810
4888     ANGLE_SKIP_TEST_IF(IsWindows() && IsOpenGL());
4889 
4890     constexpr uint32_t kSizeLarge = 128;
4891     constexpr uint32_t kSizeSmall = 64;
4892 
4893     glActiveTexture(GL_TEXTURE0);
4894     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4895     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4896     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4897 
4898     // Create the texture with 'large' dimensions
4899     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSizeLarge, kSizeLarge, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4900                  nullptr);
4901     ASSERT_GL_NO_ERROR();
4902 
4903     GLFramebuffer destFbo;
4904     glBindFramebuffer(GL_FRAMEBUFFER, destFbo);
4905     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
4906     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4907 
4908     // Draw with the new texture so it's created in the back end
4909     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
4910     glUseProgram(blueProgram);
4911     drawQuad(blueProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
4912     ASSERT_GL_NO_ERROR();
4913     EXPECT_PIXEL_RECT_EQ(0, 0, kSizeLarge, kSizeLarge, GLColor::blue);
4914 
4915     // Shrink the texture
4916     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
4917     ASSERT_GL_NO_ERROR();
4918 
4919     // Create a source texture/FBO to blit from
4920     GLTexture sourceTex;
4921     glBindTexture(GL_TEXTURE_2D, sourceTex);
4922     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
4923     ASSERT_GL_NO_ERROR();
4924     GLFramebuffer sourceFbo;
4925     glBindFramebuffer(GL_FRAMEBUFFER, sourceFbo);
4926     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTex, 0);
4927     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4928     // Fill the source texture with green
4929     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
4930     glUseProgram(greenProgram);
4931     drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
4932     ASSERT_GL_NO_ERROR();
4933     EXPECT_PIXEL_RECT_EQ(0, 0, kSizeSmall, kSizeSmall, GLColor::green);
4934 
4935     // Blit the source (green) to the destination
4936     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFbo);
4937     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFbo);
4938     glBlitFramebuffer(0, 0, kSizeSmall, kSizeSmall, 0, 0, kSizeSmall, kSizeSmall,
4939                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
4940     ASSERT_GL_NO_ERROR();
4941 
4942     // Render to the default framebuffer sampling from the blited texture and verify it's green
4943     glBindFramebuffer(GL_FRAMEBUFFER, 0);
4944     glBindTexture(GL_TEXTURE_2D, mTexture2D);
4945     ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4946     glUseProgram(texProgram);
4947     drawQuad(texProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
4948     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
4949 }
4950 
4951 // Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
4952 // TextureImpl and the texture is synced before being used in a draw call.
TEST_P(Texture2DTestES3,TextureImplPropogatesDirtyBits)4953 TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
4954 {
4955     ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4956     // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/42262039
4957     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
4958     // D3D Debug device reports an error. http://anglebug.com/40096590
4959     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
4960     // Support copy from levels outside the image range. http://anglebug.com/42263331
4961     ANGLE_SKIP_TEST_IF(IsVulkan());
4962 
4963     // The workaround in the GL backend required to trigger this bug generates driver warning
4964     // messages.
4965     ScopedIgnorePlatformMessages ignoreMessages;
4966 
4967     setUpProgram();
4968     glUseProgram(mProgram);
4969     glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
4970 
4971     GLTexture dest;
4972     glBindTexture(GL_TEXTURE_2D, dest);
4973 
4974     GLTexture source;
4975     glBindTexture(GL_TEXTURE_2D, source);
4976 
4977     // Put data in mip 0 and 1
4978     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4979                  GLColor::red.data());
4980     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4981                  GLColor::green.data());
4982 
4983     // Disable mipmapping so source is complete
4984     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4985     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4986 
4987     // Force the dirty bits to be synchronized in source
4988     drawQuad(mProgram, "position", 1.0f);
4989 
4990     // Copy from mip 1 of the source.  In the GL backend this internally sets the base level to mip
4991     // 1 and sets a dirty bit.
4992     glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
4993                           GL_FALSE, GL_FALSE);
4994 
4995     // Draw again, assertions are generated if the texture has internal dirty bits at draw time
4996     drawQuad(mProgram, "position", 1.0f);
4997 }
4998 
4999 // This test case changes the base level of a texture that's attached to a framebuffer, clears every
5000 // level to green, and then samples the texture when rendering. Test is taken from
5001 // https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
TEST_P(Texture2DTestES3,FramebufferTextureChangingBaselevel)5002 TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
5003 {
5004     // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/42262633
5005     ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
5006 
5007     setUpProgram();
5008 
5009     constexpr GLint width  = 8;
5010     constexpr GLint height = 4;
5011 
5012     GLTexture texture;
5013     glBindTexture(GL_TEXTURE_2D, texture);
5014     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5015     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5016     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5017     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5018 
5019     // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
5020     GLint level  = 0;
5021     GLint levelW = width;
5022     GLint levelH = height;
5023     glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5024                  nullptr);
5025     while (levelW > 1 || levelH > 1)
5026     {
5027         ++level;
5028         levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
5029         levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
5030         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5031                      nullptr);
5032     }
5033 
5034     // Clear each level of the texture using an FBO. Change the base level to match the level used
5035     // for the FBO on each iteration.
5036     GLFramebuffer fbo;
5037     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5038     level  = 0;
5039     levelW = width;
5040     levelH = height;
5041     while (levelW > 1 || levelH > 1)
5042     {
5043         levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
5044         levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
5045 
5046         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
5047         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
5048 
5049         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5050         EXPECT_GL_NO_ERROR();
5051 
5052         glClearColor(0, 1, 0, 1);
5053         glClear(GL_COLOR_BUFFER_BIT);
5054 
5055         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5056 
5057         ++level;
5058     }
5059 
5060     glBindFramebuffer(GL_FRAMEBUFFER, 0);
5061     glViewport(0, 0, 16, 16);
5062     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5063 
5064     drawQuad(mProgram, "position", 0.5f);
5065 
5066     EXPECT_GL_NO_ERROR();
5067     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5068 }
5069 
5070 // Test that changing the base level of a texture after redefining a level outside the mip-chain
5071 // preserves the other mips' data.
TEST_P(Texture2DBaseMaxTestES3,ExtendMipChainAfterRedefine)5072 TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
5073 {
5074     // http://anglebug.com/42263298
5075     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
5076 
5077     // http://anglebug.com/42263714
5078     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && IsMac());
5079 
5080     GLFramebuffer framebuffer;
5081     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
5082 
5083     GLTexture texture;
5084     glBindTexture(GL_TEXTURE_2D, texture);
5085 
5086     std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
5087     fillMipData(mipData.data(), kMip0Size, kMipColors);
5088 
5089     for (size_t mip = 1; mip < kMipCount; ++mip)
5090     {
5091         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
5092                      GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
5093     }
5094 
5095     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5096     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
5097     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5098 
5099     // Mip 1 is green.  Verify this.
5100     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
5101 
5102     // http://anglebug.com/42263308
5103     ANGLE_SKIP_TEST_IF(IsOpenGL() && (IsIntel() || IsAMD()) && IsWindows());
5104 
5105     // Add mip 0 and rebase the mip chain.
5106     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5107                  mipData.data() + getMipDataOffset(kMip0Size, 0));
5108     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5109 
5110     // Mip 1 should still be green.
5111     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
5112 
5113     // Verify the other mips too.
5114     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
5115     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5116     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[2]);
5117 
5118     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
5119     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5120     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[3]);
5121 
5122     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
5123     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5124 
5125     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
5126 }
5127 
5128 // Test that changing the base level of a texture multiple times preserves the data.
TEST_P(Texture2DBaseMaxTestES3,PingPongBaseLevel)5129 TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevel)
5130 {
5131     testPingPongBaseLevel(false);
5132 }
TEST_P(Texture2DBaseMaxTestES3,PingPongBaseLevelImmutable)5133 TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevelImmutable)
5134 {
5135     testPingPongBaseLevel(true);
5136 }
testPingPongBaseLevel(bool immutable)5137 void Texture2DBaseMaxTestES3::testPingPongBaseLevel(bool immutable)
5138 {
5139     // http://anglebug.com/42263310
5140     ANGLE_SKIP_TEST_IF(IsD3D());
5141 
5142     // http://anglebug.com/42263311
5143     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsAMD() && IsWindows());
5144 
5145     // http://anglebug.com/42263301
5146     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
5147 
5148     initTest(immutable);
5149 
5150     // Ping pong a few times.
5151     for (uint32_t tries = 0; tries < 2; ++tries)
5152     {
5153         // Rebase to different mips and verify mips.
5154         for (uint32_t base = 0; base < kMipCount; ++base)
5155         {
5156             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
5157             for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
5158             {
5159                 setLodUniform(lod);
5160                 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5161                 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
5162             }
5163         }
5164 
5165         // Rebase backwards and verify mips.
5166         for (uint32_t base = kMipCount - 2; base > 0; --base)
5167         {
5168             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
5169             for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
5170             {
5171                 setLodUniform(lod);
5172                 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5173                 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
5174             }
5175         }
5176     }
5177 }
5178 
5179 // Test that glTexSubImage2D after incompatibly redefining a mip level correctly applies the update
5180 // after the redefine data.
TEST_P(Texture2DBaseMaxTestES3,SubImageAfterRedefine)5181 TEST_P(Texture2DBaseMaxTestES3, SubImageAfterRedefine)
5182 {
5183     initTest(false);
5184 
5185     // Test that all mips have the expected data initially (this makes sure the texture image is
5186     // created already).
5187     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5188     {
5189         setLodUniform(lod);
5190         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5191         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5192     }
5193 
5194     // Redefine every level, followed by a glTexSubImage2D
5195     const GLColor kNewMipColors[kMipCount] = {
5196         GLColor::yellow,
5197         GLColor::cyan,
5198         GLColor(127, 0, 0, 255),
5199         GLColor(0, 127, 0, 255),
5200     };
5201     std::array<GLColor, getTotalMipDataSize(kMip0Size * 2)> newMipData;
5202     fillMipData(newMipData.data(), kMip0Size * 2, kNewMipColors);
5203 
5204     const GLColor kSubImageMipColors[kMipCount] = {
5205         GLColor(0, 0, 127, 255),
5206         GLColor(127, 127, 0, 255),
5207         GLColor(0, 127, 127, 255),
5208         GLColor(127, 0, 127, 255),
5209     };
5210     std::array<GLColor, getTotalMipDataSize(kMip0Size)> subImageMipData;
5211     fillMipData(subImageMipData.data(), kMip0Size, kSubImageMipColors);
5212 
5213     for (size_t mip = 0; mip < kMipCount; ++mip)
5214     {
5215         // Redefine the level.
5216         size_t newMipSize = (kMip0Size * 2) >> mip;
5217         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, newMipSize, newMipSize, 0, GL_RGBA,
5218                      GL_UNSIGNED_BYTE, newMipData.data() + getMipDataOffset(kMip0Size * 2, mip));
5219 
5220         // Immediately follow that with a subimage update.
5221         glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
5222                         GL_UNSIGNED_BYTE,
5223                         subImageMipData.data() + getMipDataOffset(kMip0Size, mip));
5224     }
5225     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
5226 
5227     // Test that the texture looks as expected.
5228     const int w = getWindowWidth() - 1;
5229     const int h = getWindowHeight() - 1;
5230     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5231     {
5232         setLodUniform(lod);
5233         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5234         EXPECT_PIXEL_COLOR_EQ(0, 0, kSubImageMipColors[lod]);
5235         EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColors[lod]);
5236         EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColors[lod]);
5237         EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColors[lod]);
5238     }
5239 }
5240 
5241 // Test that incompatibly redefining a level then redefining it back to its original size works.
TEST_P(Texture2DBaseMaxTestES3,IncompatiblyRedefineLevelThenRevert)5242 TEST_P(Texture2DBaseMaxTestES3, IncompatiblyRedefineLevelThenRevert)
5243 {
5244     initTest(false);
5245 
5246     // Test that all mips have the expected data initially (this makes sure the texture image is
5247     // created already).
5248     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5249     {
5250         setLodUniform(lod);
5251         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5252         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5253     }
5254 
5255     // Redefine Mip 1 to be larger.
5256     constexpr size_t kLargeMip1Size = getMipDataSize(kMip0Size * 2, 1);
5257     std::array<GLColor, kLargeMip1Size> interimMipData;
5258     std::fill(interimMipData.data(), interimMipData.data() + kLargeMip1Size, GLColor::yellow);
5259 
5260     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5261                  interimMipData.data());
5262 
5263     // Redefine Mip 1 back to its original size.
5264     constexpr size_t kNormalMip1Size = getMipDataSize(kMip0Size, 1);
5265     std::array<GLColor, kLargeMip1Size> newMipData;
5266     std::fill(newMipData.data(), newMipData.data() + kNormalMip1Size, GLColor::cyan);
5267 
5268     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size / 2, kMip0Size / 2, 0, GL_RGBA,
5269                  GL_UNSIGNED_BYTE, newMipData.data());
5270 
5271     // Verify texture colors.
5272     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5273     {
5274         setLodUniform(lod);
5275         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5276         EXPECT_PIXEL_COLOR_EQ(0, 0, lod == 1 ? GLColor::cyan : kMipColors[lod]);
5277     }
5278 }
5279 
5280 // Test that redefining every level of a texture to another format works.  The format uses more
5281 // bits per component, to ensure alignment requirements for the new format are taken into account.
TEST_P(Texture2DBaseMaxTestES3,RedefineEveryLevelToAnotherFormat)5282 TEST_P(Texture2DBaseMaxTestES3, RedefineEveryLevelToAnotherFormat)
5283 {
5284     initTest(false);
5285 
5286     // Test that all mips have the expected data initially (this makes sure the texture image is
5287     // created already).
5288     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5289     {
5290         setLodUniform(lod);
5291         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5292         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5293     }
5294 
5295     const GLColor32F kNewMipColors[kMipCount] = {
5296         GLColor32F(1.0, 1.0, 0.0, 1.0f),
5297         GLColor32F(1.0, 0.0, 1.0, 1.0f),
5298         GLColor32F(0.0, 1.0, 1.0, 1.0f),
5299         GLColor32F(1.0, 1.0, 1.0, 1.0f),
5300     };
5301 
5302     std::array<GLColor32F, getTotalMipDataSize(kMip0Size)> newMipData;
5303     fillMipData(newMipData.data(), kMip0Size, kNewMipColors);
5304 
5305     // Redefine every level with the new format.
5306     for (size_t mip = 0; mip < kMipCount; ++mip)
5307     {
5308         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA32F, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
5309                      GL_FLOAT, newMipData.data() + getMipDataOffset(kMip0Size, mip));
5310     }
5311 
5312     // Verify texture colors.
5313     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5314     {
5315         setLodUniform(lod);
5316         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5317 
5318         GLColor32F mipColor32F = kNewMipColors[lod];
5319         GLColor mipColor(static_cast<GLubyte>(std::roundf(mipColor32F.R * 255)),
5320                          static_cast<GLubyte>(std::roundf(mipColor32F.G * 255)),
5321                          static_cast<GLubyte>(std::roundf(mipColor32F.B * 255)),
5322                          static_cast<GLubyte>(std::roundf(mipColor32F.A * 255)));
5323 
5324         EXPECT_PIXEL_COLOR_EQ(0, 0, mipColor);
5325     }
5326 }
5327 
5328 // Test that generating mipmaps after change base level.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRebase)5329 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRebase)
5330 {
5331     // http://anglebug.com/42264421
5332     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
5333 
5334     testGenerateMipmapAfterRebase(false);
5335 }
5336 
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRebaseImmutable)5337 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRebaseImmutable)
5338 {
5339     // http://anglebug.com/42263310
5340     ANGLE_SKIP_TEST_IF(IsD3D());
5341     // http://anglebug.com/42264332
5342     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA());
5343     // http://anglebug.com/42264421
5344     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
5345 
5346     testGenerateMipmapAfterRebase(true);
5347 }
5348 
testGenerateMipmapAfterRebase(bool immutable)5349 void Texture2DBaseMaxTestES3::testGenerateMipmapAfterRebase(bool immutable)
5350 {
5351     initTest(immutable);
5352 
5353     // Test that all mips have the expected data initially (this makes sure the texture image is
5354     // created already).
5355     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5356     {
5357         setLodUniform(lod);
5358         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5359         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5360     }
5361 
5362     // Update level 1 (any level would do other than 0) with new data
5363     const GLColor kNewMipColor = GLColor::yellow;
5364     std::array<GLColor, getMipDataSize(kMip0Size >> 1, 0)> newMipData;
5365     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5366 
5367     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kMip0Size >> 1, kMip0Size >> 1, GL_RGBA,
5368                     GL_UNSIGNED_BYTE, newMipData.data());
5369 
5370     // Change base level and max level and then generate mipmaps. This should redefine level 1 and 2
5371     // with kNewMipColor and leave levels 0 and 3 unchanged.
5372     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5373     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 2);
5374     glGenerateMipmap(GL_TEXTURE_2D);
5375     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5376     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
5377 
5378     // Test that the texture looks as expected.
5379     const int w = getWindowWidth() - 1;
5380     const int h = getWindowHeight() - 1;
5381     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5382     {
5383         setLodUniform(lod);
5384         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5385         if (lod == 0)
5386         {
5387             EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]) << "lod " << lod;
5388             EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]) << "lod " << lod;
5389             EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]) << "lod " << lod;
5390             EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]) << "lod " << lod;
5391         }
5392         else if (lod == kMipCount - 1)
5393         {
5394             EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]) << "lod " << lod;
5395             EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]) << "lod " << lod;
5396             EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]) << "lod " << lod;
5397             EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]) << "lod " << lod;
5398         }
5399         else
5400         {
5401             EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor) << "lod " << lod;
5402             EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor) << "lod " << lod;
5403             EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor) << "lod " << lod;
5404             EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor) << "lod " << lod;
5405         }
5406     }
5407 }
5408 
5409 // Test that generating mipmaps after incompatibly redefining a level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefine)5410 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefine)
5411 {
5412     initTest(false);
5413 
5414     // Test that all mips have the expected data initially (this makes sure the texture image is
5415     // created already).
5416     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5417     {
5418         setLodUniform(lod);
5419         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5420         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5421     }
5422 
5423     // Redefine level 1 (any level would do other than 0) to an incompatible size, say the same size
5424     // as level 0.
5425     const GLColor kNewMipColor = GLColor::yellow;
5426     std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
5427     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5428 
5429     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5430                  newMipData.data());
5431 
5432     // Generate mipmaps.  This should redefine level 1 back to being compatible with level 0.
5433     glGenerateMipmap(GL_TEXTURE_2D);
5434 
5435     // Test that the texture looks as expected.
5436     const int w = getWindowWidth() - 1;
5437     const int h = getWindowHeight() - 1;
5438     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5439     {
5440         setLodUniform(lod);
5441         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5442         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
5443         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]);
5444         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]);
5445         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]);
5446     }
5447 }
5448 
5449 // Test that generating mipmaps after incompatibly redefining a level while simultaneously changing
5450 // the base level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefineAndRebase)5451 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefineAndRebase)
5452 {
5453     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
5454 
5455     // http://crbug.com/1100613
5456     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
5457 
5458     // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
5459     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
5460 
5461     initTest(false);
5462 
5463     // Test that all mips have the expected data initially (this makes sure the texture image is
5464     // created already).
5465     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5466     {
5467         setLodUniform(lod);
5468         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5469         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]) << lod;
5470     }
5471 
5472     // Redefine level 2 to an incompatible size, say the same size as level 0.
5473     const GLColor kNewMipColor = GLColor::yellow;
5474     std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
5475     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5476 
5477     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5478                  newMipData.data());
5479 
5480     // Set base level of the texture to 1 then generate mipmaps.  Level 2 that's redefined should
5481     // go back to being compatibly defined.
5482     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5483     glGenerateMipmap(GL_TEXTURE_2D);
5484 
5485     // Test that the texture looks as expected.
5486     const int w = getWindowWidth() - 1;
5487     const int h = getWindowHeight() - 1;
5488     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5489     {
5490         setLodUniform(lod);
5491         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5492         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]) << lod;
5493         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[1]) << lod;
5494         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[1]) << lod;
5495         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[1]) << lod;
5496     }
5497 
5498     // Redefine level 1 (current base level) to an incompatible size.
5499     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5500                  newMipData.data());
5501 
5502     // Set base level of the texture back to 0 then generate mipmaps.  Level 1 should go back to
5503     // being compatibly defined.
5504     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5505     glGenerateMipmap(GL_TEXTURE_2D);
5506 
5507     // Test that the texture looks as expected.
5508     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5509     {
5510         setLodUniform(lod);
5511         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5512         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]) << lod;
5513         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]) << lod;
5514         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]) << lod;
5515         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]) << lod;
5516     }
5517 }
5518 
5519 // Test that generating mipmaps after incompatibly redefining the base level of the texture works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBase)5520 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBase)
5521 {
5522     initTest(false);
5523 
5524     // Test that all mips have the expected data initially (this makes sure the texture image is
5525     // created already).
5526     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5527     {
5528         setLodUniform(lod);
5529         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5530         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5531     }
5532 
5533     // Redefine level 0 to an incompatible size.
5534     const GLColor kNewMipColor = GLColor::yellow;
5535     std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
5536     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5537 
5538     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
5539                  GL_UNSIGNED_BYTE, newMipData.data());
5540 
5541     // Generate mipmaps.
5542     glGenerateMipmap(GL_TEXTURE_2D);
5543 
5544     // Test that the texture looks as expected.
5545     const int w = getWindowWidth() - 1;
5546     const int h = getWindowHeight() - 1;
5547     for (uint32_t lod = 0; lod < kMipCount + 1; ++lod)
5548     {
5549         setLodUniform(lod);
5550         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5551         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
5552         EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
5553         EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
5554         EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
5555     }
5556 }
5557 
5558 // Test that generating mipmaps after incompatibly redefining the base level while simultaneously
5559 // changing MAX_LEVEL works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBaseAndChangingMax)5560 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBaseAndChangingMax)
5561 {
5562     initTest(false);
5563 
5564     // Test that all mips have the expected data initially (this makes sure the texture image is
5565     // created already).
5566     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5567     {
5568         setLodUniform(lod);
5569         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5570         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5571     }
5572 
5573     // Redefine level 0 to an incompatible size.
5574     const GLColor kNewMipColor = GLColor::yellow;
5575     std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
5576     std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5577 
5578     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
5579                  GL_UNSIGNED_BYTE, newMipData.data());
5580 
5581     // Set max level of the texture to 2 then generate mipmaps.
5582     constexpr uint32_t kMaxLevel = 2;
5583     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMaxLevel);
5584     glGenerateMipmap(GL_TEXTURE_2D);
5585 
5586     // Test that the texture looks as expected.
5587     const int w = getWindowWidth() - 1;
5588     const int h = getWindowHeight() - 1;
5589     for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
5590     {
5591         setLodUniform(lod);
5592         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5593         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
5594         EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
5595         EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
5596         EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
5597     }
5598 }
5599 
5600 // Test that stage invalid texture levels work.
TEST_P(Texture2DBaseMaxTestES3,StageInvalidLevels)5601 TEST_P(Texture2DBaseMaxTestES3, StageInvalidLevels)
5602 {
5603     constexpr uint32_t kMaxLevel           = 2;
5604     const GLColor kMipColor[kMaxLevel + 1] = {GLColor::red, GLColor::green, GLColor::blue};
5605 
5606     initTest(false);
5607 
5608     GLTexture texture;
5609     glBindTexture(GL_TEXTURE_2D, texture);
5610 
5611     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5612     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5613     std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
5614     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataCyan.data());
5615     setLodUniform(0);
5616     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5617     EXPECT_GL_NO_ERROR();
5618 
5619     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
5620     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5621                  texDataGreen.data());
5622     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
5623     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5624     EXPECT_GL_NO_ERROR();
5625 
5626     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
5627     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
5628     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5629     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5630 
5631     // Test that the texture looks as expected.
5632     const int w = getWindowWidth() - 1;
5633     const int h = getWindowHeight() - 1;
5634     for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
5635     {
5636         setLodUniform(lod);
5637         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5638         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColor[lod]);
5639         EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColor[lod]);
5640         EXPECT_PIXEL_COLOR_EQ(0, h, kMipColor[lod]);
5641         EXPECT_PIXEL_COLOR_EQ(w, h, kMipColor[lod]);
5642     }
5643 }
5644 
5645 // Test redefine a mutable texture into an immutable texture.
TEST_P(Texture2DBaseMaxTestES3,RedefineMutableToImmutable)5646 TEST_P(Texture2DBaseMaxTestES3, RedefineMutableToImmutable)
5647 {
5648     // http://anglebug.com/42263310
5649     ANGLE_SKIP_TEST_IF(IsD3D());
5650 
5651     // http://anglebug.com/42263301
5652     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
5653 
5654     constexpr uint32_t kBaseLevel          = 1;
5655     const GLColor kNewMipColors[kMipCount] = {
5656         GLColor::yellow,
5657         GLColor::cyan,
5658         GLColor::white,
5659         GLColor(127u, 127u, 127u, 255u),
5660     };
5661 
5662     initTest(false);
5663 
5664     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, kBaseLevel);
5665 
5666     // Test that all mips have the expected data
5667     for (uint32_t lod = kBaseLevel; lod < kMipCount; ++lod)
5668     {
5669         setLodUniform(lod - kBaseLevel);
5670         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5671         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5672     }
5673 
5674     glTexStorage2D(GL_TEXTURE_2D, kMipCount, GL_RGBA8, kMip0Size, kMip0Size);
5675     std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
5676     fillMipData(mipData.data(), kMip0Size, kNewMipColors);
5677     for (size_t mip = 0; mip < kMipCount; ++mip)
5678     {
5679         glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
5680                         GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
5681     }
5682 
5683     // Test that all enabled mips have the expected data
5684     for (uint32_t lod = kBaseLevel; lod < kMipCount; ++lod)
5685     {
5686         setLodUniform(lod - kBaseLevel);
5687         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5688         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[lod]);
5689     }
5690 
5691     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5692     for (uint32_t lod = 0; lod < kBaseLevel; ++lod)
5693     {
5694         setLodUniform(lod);
5695         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5696         EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[lod]);
5697     }
5698 }
5699 
5700 // Test that redefine a level with incompatible size beyond the max level.
TEST_P(Texture2DBaseMaxTestES3,RedefineIncompatibleLevelBeyondMaxLevel)5701 TEST_P(Texture2DBaseMaxTestES3, RedefineIncompatibleLevelBeyondMaxLevel)
5702 {
5703     initTest(false);
5704 
5705     // Test that all mips have the expected data initially (this makes sure the texture image is
5706     // created already).
5707     for (uint32_t lod = 0; lod < kMipCount; ++lod)
5708     {
5709         setLodUniform(lod);
5710         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5711         EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5712     }
5713 
5714     uint32_t maxLevel = 1;
5715     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel);
5716 
5717     // Update level 0
5718     const GLColor kNewMipLevle0Color = GLColor::yellow;
5719     std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
5720     std::fill(newMipData.begin(), newMipData.end(), kNewMipLevle0Color);
5721     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kMip0Size, kMip0Size, GL_RGBA, GL_UNSIGNED_BYTE,
5722                     newMipData.data());
5723 
5724     // Update level 2 with incompatible data
5725     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5726                  newMipData.data());
5727     EXPECT_GL_NO_ERROR();
5728 
5729     // Test that the texture looks as expected.
5730     const int w = getWindowWidth() - 1;
5731     const int h = getWindowHeight() - 1;
5732     for (uint32_t lod = 0; lod < maxLevel; ++lod)
5733     {
5734         setLodUniform(lod);
5735         drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5736         if (lod == 0)
5737         {
5738             EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipLevle0Color);
5739             EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipLevle0Color);
5740             EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipLevle0Color);
5741             EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipLevle0Color);
5742         }
5743         else
5744         {
5745             EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5746             EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]);
5747             EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]);
5748             EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]);
5749         }
5750     }
5751 }
5752 
5753 // Port test from web_gl/conformance2/textures/misc/fuzz-545-immutable-tex-render-feedback.html.
5754 // What this tries to do is create a render feedback loop and ensure it is not crashing.
TEST_P(Texture2DBaseMaxTestES3,Fuzz545ImmutableTexRenderFeedback)5755 TEST_P(Texture2DBaseMaxTestES3, Fuzz545ImmutableTexRenderFeedback)
5756 {
5757     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5758 
5759     constexpr uint32_t MIPS = 2;
5760     constexpr uint32_t SIZE = 10;
5761 
5762     GLTexture immutTex;
5763     glBindTexture(GL_TEXTURE_2D, immutTex);
5764     glTexStorage2D(GL_TEXTURE_2D, MIPS, GL_RGBA8, SIZE, SIZE);
5765 
5766     GLTexture mutTex;
5767     glBindTexture(GL_TEXTURE_2D, mutTex);
5768     for (uint32_t mip = 0; mip < MIPS; mip++)
5769     {
5770         const uint32_t size = SIZE >> mip;
5771         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5772                      nullptr);
5773     }
5774 
5775     constexpr GLenum MAG_FILTERS[] = {GL_LINEAR, GL_NEAREST};
5776     constexpr GLenum MIN_FILTERS[] = {
5777         GL_LINEAR,  GL_LINEAR_MIPMAP_LINEAR,  GL_LINEAR_MIPMAP_NEAREST,
5778         GL_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_NEAREST};
5779 
5780     GLFramebuffer fbo;
5781     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5782 
5783     const GLuint texs[] = {immutTex, mutTex};
5784     for (const GLuint tex : texs)
5785     {
5786         glBindTexture(GL_TEXTURE_2D, tex);
5787 
5788         for (GLuint level_prime_base = 0; level_prime_base < (MIPS + 1); level_prime_base++)
5789         {  // `level_base` in GLES
5790             // ES 3.0.6 p150
5791             GLuint _level_base = level_prime_base;
5792             if (tex == immutTex)
5793             {
5794                 _level_base = std::min(_level_base, MIPS - 1);
5795             }
5796             const GLuint level_base = _level_base;
5797 
5798             for (GLuint _level_prime_max = (level_prime_base - 1); _level_prime_max < (MIPS + 2);
5799                  _level_prime_max++)
5800             {  // `q` in GLES
5801                 if (_level_prime_max < 0)
5802                     continue;
5803                 if (_level_prime_max == (MIPS + 1))
5804                 {
5805                     _level_prime_max = 10000;  // This is the default, after all!
5806                 }
5807                 const GLuint level_prime_max = _level_prime_max;
5808 
5809                 // ES 3.0.6 p150
5810                 GLuint _level_max = level_prime_max;
5811                 if (tex == immutTex)
5812                 {
5813                     _level_max = std::min(std::max(level_base, level_prime_max), MIPS - 1);
5814                 }
5815                 const GLuint level_max = _level_max;
5816 
5817                 const GLuint p = std::floor((float)std::log2(SIZE)) + level_base;
5818                 const GLuint q = std::min(p, level_max);
5819 
5820                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level_prime_base);
5821                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level_prime_max);
5822 
5823                 const bool mipComplete = (q <= MIPS - 1);
5824 
5825                 for (const GLenum minFilter : MIN_FILTERS)
5826                 {
5827                     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
5828 
5829                     for (const GLenum magFilter : MAG_FILTERS)
5830                     {
5831                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
5832 
5833                         for (GLuint dstMip = 0; dstMip < (MIPS + 1); dstMip++)
5834                         {
5835                             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5836                                                    GL_TEXTURE_2D, tex, dstMip);
5837 
5838                             // ES3.0 p213-214
5839                             bool fbComplete = true;
5840 
5841                             // * "The width and height of `image` are non-zero"
5842                             fbComplete &= (0 <= dstMip && dstMip <= MIPS - 1);
5843 
5844                             if (tex != immutTex)
5845                             {  // "...does not name an immutable-format texture..."
5846                                 // * "...the value of [level] must be in the range `[level_base,
5847                                 // q]`"
5848                                 fbComplete &= (level_base <= dstMip && dstMip <= q);
5849 
5850                                 // * "...the value of [level] is not `level_base`, then the texture
5851                                 // must be mipmap complete"
5852                                 if (dstMip != level_base)
5853                                 {
5854                                     fbComplete &= mipComplete;
5855                                 }
5856                             }
5857 
5858                             // -
5859                             GLenum expectError  = 0;
5860                             GLenum expectStatus = GL_FRAMEBUFFER_COMPLETE;
5861                             if (!fbComplete)
5862                             {
5863                                 expectStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
5864                                 expectError  = GL_INVALID_FRAMEBUFFER_OPERATION;
5865                             }
5866 
5867                             // -
5868                             EXPECT_GLENUM_EQ(expectStatus,
5869                                              glCheckFramebufferStatus(GL_FRAMEBUFFER));
5870 
5871                             drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
5872                             EXPECT_EQ(expectError, glGetError());
5873                         }
5874                     }
5875                 }
5876             }
5877         }
5878     }
5879 }
5880 
5881 // Test sampling from a texture of a (usually) not color-renderable
5882 // base format with a color-renderable level beyond the max level.
TEST_P(Texture2DBaseMaxTestES3,NotColorRenderableWithColorRenderableBeyondMaxLevel)5883 TEST_P(Texture2DBaseMaxTestES3, NotColorRenderableWithColorRenderableBeyondMaxLevel)
5884 {
5885     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5886 
5887     GLTexture texture;
5888     glBindTexture(GL_TEXTURE_2D, texture);
5889     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5890     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5891 
5892     const GLuint data[4] = {0xC0040200, 0xC0040200, 0xC0040200, 0xC0040200};
5893     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 2, 2, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, data);
5894     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5895     ASSERT_GL_NO_ERROR();
5896 
5897     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5898     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5899     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5900 }
5901 
5902 // Test sampling from a texture of a depth-renderable base format
5903 // with a color-renderable level beyond the max level.
TEST_P(Texture2DBaseMaxTestES3,DepthRenderableWithColorRenderableBeyondMaxLevel)5904 TEST_P(Texture2DBaseMaxTestES3, DepthRenderableWithColorRenderableBeyondMaxLevel)
5905 {
5906     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5907 
5908     GLTexture texture;
5909     glBindTexture(GL_TEXTURE_2D, texture);
5910     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5911     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5912 
5913     const GLfloat data[4] = {1.0f, 1.0f, 1.0f, 1.0f};
5914     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 2, 2, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
5915                  data);
5916     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5917     ASSERT_GL_NO_ERROR();
5918 
5919     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5920     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5921     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5922 }
5923 
5924 // Test texture sampling while changing the base format from color-renderable
5925 // to (usually) not color-renderable by manipulating base and max levels.
TEST_P(Texture2DBaseMaxTestES3,NotColorRenderableAfterColorRenderableBelowBaseLevel)5926 TEST_P(Texture2DBaseMaxTestES3, NotColorRenderableAfterColorRenderableBelowBaseLevel)
5927 {
5928     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5929 
5930     GLTexture texture;
5931     glBindTexture(GL_TEXTURE_2D, texture);
5932     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5933     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5934 
5935     std::array<GLColor, 4> data0;
5936     data0.fill(GLColor::green);
5937     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data0.data());
5938 
5939     const GLuint data1[1] = {0xC0040200};
5940     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, data1);
5941     ASSERT_GL_NO_ERROR();
5942 
5943     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5944     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5945     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5946 
5947     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5948     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
5949     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5950     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5951 }
5952 
5953 // Test texture sampling while changing the base format from color-renderable
5954 // to depth-renderable by manipulating base and max levels.
TEST_P(Texture2DBaseMaxTestES3,DepthRenderableAfterColorRenderableBelowBaseLevel)5955 TEST_P(Texture2DBaseMaxTestES3, DepthRenderableAfterColorRenderableBelowBaseLevel)
5956 {
5957     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5958 
5959     GLTexture texture;
5960     glBindTexture(GL_TEXTURE_2D, texture);
5961     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5962     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5963 
5964     std::array<GLColor, 4> data0;
5965     data0.fill(GLColor::green);
5966     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data0.data());
5967 
5968     const GLfloat data1[1] = {1.0f};
5969     glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
5970                  data1);
5971     ASSERT_GL_NO_ERROR();
5972 
5973     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5974     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5975     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5976 
5977     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5978     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
5979     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5980     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5981 }
5982 
5983 // Test that the following scenario works:
5984 // - change a texture's max level to 0.
5985 // - clear the texture with glClear.
5986 // - sample the texture and draw to another FBO.
5987 // - draw to the texture again.
5988 // - The texture's final color should be clear color in 1st pass + draw color.
TEST_P(Texture2DBaseMaxTestES3,SetMaxLevelToZeroThenClearThenSampleThenDraw)5989 TEST_P(Texture2DBaseMaxTestES3, SetMaxLevelToZeroThenClearThenSampleThenDraw)
5990 {
5991     ANGLE_GL_PROGRAM(textureProgram, angle::essl3_shaders::vs::Texture2DLod(),
5992                      angle::essl3_shaders::fs::Texture2DLod());
5993     ANGLE_GL_PROGRAM(blueProgram, angle::essl1_shaders::vs::Simple(),
5994                      angle::essl1_shaders::fs::Blue());
5995 
5996     GLTexture texture;
5997     glBindTexture(GL_TEXTURE_2D, texture);
5998     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5999     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6000     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6001 
6002     // 1. Change the texture's max level to 0.
6003     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6004     EXPECT_GL_NO_ERROR();
6005 
6006     // 2. Attach the texture to a FBO and clear it.
6007     GLFramebuffer fbo;
6008     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6009     EXPECT_GL_NO_ERROR();
6010     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
6011     glEnable(GL_BLEND);
6012     glBlendFunc(GL_ONE, GL_ONE);
6013     glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);
6014     glClear(GL_COLOR_BUFFER_BIT);
6015 
6016     // 3. Draw the bound texture to default FBO.
6017     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6018     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6019     glClear(GL_COLOR_BUFFER_BIT);
6020     glUseProgram(textureProgram);
6021     drawQuad(textureProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6022 
6023     // 4. Draw to the texture again
6024     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6025     glUseProgram(blueProgram);
6026     drawQuad(blueProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6027 
6028     // Expect the final color to be accumulated color
6029     EXPECT_GL_NO_ERROR();
6030     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(1, 2, 255, 255));
6031 }
6032 
6033 // Test that the following scenario works:
6034 // - change a texture's max level to 1.
6035 // - clear the texture with glClear.
6036 // - change the texture's max level to 0.
6037 // - sample the texture and draw to another FBO.
6038 // - draw to the texture again.
6039 // - The texture's final color should be clear color in 1st pass + draw color.
TEST_P(Texture2DBaseMaxTestES3,SetMaxLevelToOneThenClearThenSetMaxLevelToZeroThenSampleThenDraw)6040 TEST_P(Texture2DBaseMaxTestES3, SetMaxLevelToOneThenClearThenSetMaxLevelToZeroThenSampleThenDraw)
6041 {
6042     ANGLE_GL_PROGRAM(textureProgram, angle::essl3_shaders::vs::Texture2DLod(),
6043                      angle::essl3_shaders::fs::Texture2DLod());
6044     ANGLE_GL_PROGRAM(blueProgram, angle::essl1_shaders::vs::Simple(),
6045                      angle::essl1_shaders::fs::Blue());
6046 
6047     GLTexture texture;
6048     glBindTexture(GL_TEXTURE_2D, texture);
6049     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6050     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6051     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6052     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6053 
6054     // 1. Change the texture's max level to 1.
6055     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6056     EXPECT_GL_NO_ERROR();
6057 
6058     // 2. Attach the texture to a FBO and clear it.
6059     GLFramebuffer fbo;
6060     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6061     EXPECT_GL_NO_ERROR();
6062     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
6063     glEnable(GL_BLEND);
6064     glBlendFunc(GL_ONE, GL_ONE);
6065     glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);
6066     glClear(GL_COLOR_BUFFER_BIT);
6067 
6068     // 3. Change the texture's max level to 0.
6069     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6070 
6071     // 4. Draw the bound texture to default FBO.
6072     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6073     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6074     glClear(GL_COLOR_BUFFER_BIT);
6075     glUseProgram(textureProgram);
6076     drawQuad(textureProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6077 
6078     // 5. Draw to the texture again
6079     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6080     glUseProgram(blueProgram);
6081     drawQuad(blueProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6082 
6083     // Expect the final color to be accumulated color
6084     EXPECT_GL_NO_ERROR();
6085     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(1, 2, 255, 255));
6086 }
6087 
6088 // Test to check that texture completeness is determined correctly when the texture base level is
6089 // greater than 0, and also that level 0 is not sampled when base level is greater than 0.
TEST_P(Texture2DTestES3,DrawWithBaseLevel1)6090 TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
6091 {
6092     glActiveTexture(GL_TEXTURE0);
6093     glBindTexture(GL_TEXTURE_2D, mTexture2D);
6094 
6095     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6096     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6097     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6098     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6099                  texDataGreen.data());
6100     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6101                  texDataGreen.data());
6102     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6103     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6104     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6105 
6106     EXPECT_GL_NO_ERROR();
6107 
6108     drawQuad(mProgram, "position", 0.5f);
6109 
6110     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6111 }
6112 
testCopyImage(const APIExtensionVersion usedExtension)6113 void Texture2DTestES3::testCopyImage(const APIExtensionVersion usedExtension)
6114 {
6115     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6116 
6117     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6118     GLTexture srcTexture;
6119     GLTexture destTexture;
6120 
6121     glActiveTexture(GL_TEXTURE0);
6122     glBindTexture(GL_TEXTURE_2D, destTexture);
6123     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6124     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6125     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6126     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6127     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6128 
6129     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6130     glBindTexture(GL_TEXTURE_2D, srcTexture);
6131     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6132     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6133     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6134     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6135     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6136                  texDataGreen.data());
6137 
6138     glBindTexture(GL_TEXTURE_2D, 0);
6139 
6140     // copy
6141     if (usedExtension == APIExtensionVersion::OES)
6142     {
6143         glCopyImageSubDataOES(srcTexture, GL_TEXTURE_2D, 0, 2, 2, 0, destTexture, GL_TEXTURE_2D, 0,
6144                               2, 2, 0, 2, 2, 1);
6145     }
6146     else
6147     {
6148         glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 2, 2, 0, destTexture, GL_TEXTURE_2D, 0,
6149                               2, 2, 0, 2, 2, 1);
6150     }
6151     glBindTexture(GL_TEXTURE_2D, destTexture);
6152     EXPECT_GL_NO_ERROR();
6153 
6154     glViewport(0, 0, 4, 4);
6155     drawQuad(mProgram, "position", 0.5f);
6156     EXPECT_GL_NO_ERROR();
6157 
6158     EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
6159     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
6160     EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
6161 }
6162 
testCopyMultisampleImage(const APIExtensionVersion usedExtension,const GLenum internalFormat)6163 void MultisampleTexture2DTestES31::testCopyMultisampleImage(const APIExtensionVersion usedExtension,
6164                                                             const GLenum internalFormat)
6165 {
6166     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6167 
6168     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
6169 
6170     GLTexture srcTexture;
6171     GLTexture destTexture;
6172     const GLenum target = GL_TEXTURE_2D_MULTISAMPLE;
6173 
6174     GLint maxSamples = 0;
6175     glGetInternalformativ(target, internalFormat, GL_SAMPLES, 1, &maxSamples);
6176     EXPECT_GL_NO_ERROR();
6177 
6178     glActiveTexture(GL_TEXTURE0);
6179     glBindTexture(target, destTexture);
6180     glTexStorage2DMultisample(target, maxSamples, internalFormat, 4, 4, false);
6181     EXPECT_GL_NO_ERROR();
6182 
6183     glBindTexture(target, srcTexture);
6184     glTexStorage2DMultisample(target, maxSamples, internalFormat, 4, 4, false);
6185     EXPECT_GL_NO_ERROR();
6186 
6187     GLFramebuffer fbo;
6188     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6189     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, srcTexture, 0);
6190     EXPECT_GL_NO_ERROR();
6191 
6192     // Draw red into the source texture
6193     glViewport(0, 0, 4, 4);
6194     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6195 
6196     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
6197     ASSERT_GL_NO_ERROR();
6198 
6199     glBindTexture(target, 0);
6200 
6201     // Copy
6202     if (usedExtension == APIExtensionVersion::OES)
6203     {
6204         glCopyImageSubDataOES(srcTexture, target, 0, 0, 0, 0, destTexture, target, 0, 0, 0, 0, 4, 4,
6205                               1);
6206     }
6207     else
6208     {
6209         glCopyImageSubDataEXT(srcTexture, target, 0, 0, 0, 0, destTexture, target, 0, 0, 0, 0, 4, 4,
6210                               1);
6211     }
6212     EXPECT_GL_NO_ERROR();
6213 
6214     // Resolve the target texture
6215     GLTexture resolveTexture;
6216     glBindTexture(GL_TEXTURE_2D, resolveTexture);
6217     glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 4, 4);
6218 
6219     GLFramebuffer resolveFbo;
6220     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
6221     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
6222                            0);
6223 
6224     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
6225     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, destTexture, 0);
6226     ASSERT_GL_NO_ERROR();
6227     glCheckFramebufferStatus(GL_FRAMEBUFFER);
6228     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6229 
6230     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6231     glBlitFramebuffer(0, 0, 4, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT, GL_LINEAR);
6232     ASSERT_GL_NO_ERROR();
6233 
6234     glBindFramebuffer(GL_FRAMEBUFFER, resolveFbo);
6235     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
6236 }
6237 
testCopyMultisampleArrayImage(const APIExtensionVersion usedExtension,const GLenum internalFormat)6238 void MultisampleTexture2DTestES31::testCopyMultisampleArrayImage(
6239     const APIExtensionVersion usedExtension,
6240     const GLenum internalFormat)
6241 {
6242     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_storage_multisample_2d_array"));
6243 
6244     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6245 
6246     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
6247 
6248     GLTexture srcTexture;
6249     GLTexture destTexture;
6250 
6251     GLint maxSamples = 0;
6252     glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalFormat, GL_SAMPLES, 1, &maxSamples);
6253     EXPECT_GL_NO_ERROR();
6254 
6255     glActiveTexture(GL_TEXTURE0);
6256     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, destTexture);
6257     glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamples, internalFormat, 4,
6258                                  4, 3, false);
6259     EXPECT_GL_NO_ERROR();
6260 
6261     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, srcTexture);
6262     glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamples, internalFormat, 4,
6263                                  4, 3, false);
6264     EXPECT_GL_NO_ERROR();
6265 
6266     GLFramebuffer fbo;
6267     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6268     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTexture, 0, 1);
6269     EXPECT_GL_NO_ERROR();
6270 
6271     // Draw red into the source texture layer 1
6272     glViewport(0, 0, 4, 4);
6273     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6274 
6275     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
6276     ASSERT_GL_NO_ERROR();
6277 
6278     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0);
6279 
6280     // Copy
6281     if (usedExtension == APIExtensionVersion::OES)
6282     {
6283         glCopyImageSubDataOES(srcTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 1,
6284                               destTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 2, 4, 4,
6285                               1);
6286     }
6287     else
6288     {
6289         glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 1,
6290                               destTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 2, 4, 4,
6291                               1);
6292     }
6293     EXPECT_GL_NO_ERROR();
6294 
6295     // Resolve the target texture
6296     GLTexture resolveTexture;
6297     glBindTexture(GL_TEXTURE_2D, resolveTexture);
6298     glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 4, 4);
6299 
6300     GLFramebuffer resolveFbo;
6301     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
6302     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
6303                            0);
6304 
6305     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
6306     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, 2);
6307     ASSERT_GL_NO_ERROR();
6308     glCheckFramebufferStatus(GL_FRAMEBUFFER);
6309     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6310 
6311     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6312     glBlitFramebuffer(0, 0, 4, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT, GL_LINEAR);
6313     ASSERT_GL_NO_ERROR();
6314 
6315     glBindFramebuffer(GL_FRAMEBUFFER, resolveFbo);
6316     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
6317 }
6318 
6319 // Test basic GL_EXT_copy_image copy without any bound textures
TEST_P(Texture2DTestES3,CopyImageEXT)6320 TEST_P(Texture2DTestES3, CopyImageEXT)
6321 {
6322     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6323     testCopyImage(APIExtensionVersion::EXT);
6324 }
6325 
6326 // Test basic GL_OES_copy_image copy without any bound textures
TEST_P(Texture2DTestES3,CopyImageOES)6327 TEST_P(Texture2DTestES3, CopyImageOES)
6328 {
6329     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6330     testCopyImage(APIExtensionVersion::OES);
6331 }
6332 
testCopyImageDepthStencil(const APIExtensionVersion usedExtension)6333 void Texture2DTestES3::testCopyImageDepthStencil(const APIExtensionVersion usedExtension)
6334 {
6335     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6336 
6337     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6338     GLTexture srcTexture;
6339     GLTexture destTexture;
6340 
6341     constexpr GLsizei kSize = 4;
6342 
6343     GLTexture src;
6344     glBindTexture(GL_TEXTURE_2D, src);
6345     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
6346 
6347     GLTexture dst;
6348     glBindTexture(GL_TEXTURE_2D, dst);
6349     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
6350 
6351     // A color image for testing depth/stencil
6352     GLTexture color;
6353     glBindTexture(GL_TEXTURE_2D, color);
6354     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
6355 
6356     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
6357     glUseProgram(program);
6358     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
6359     ASSERT_NE(colorLoc, -1);
6360 
6361     // Initialize the src depth image
6362     GLFramebuffer fbo;
6363     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6364     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
6365     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, src, 0);
6366     glClearDepthf(0.3f);
6367     glClearStencil(0x57);
6368     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6369 
6370     glEnable(GL_DEPTH_TEST);
6371     glDepthMask(GL_FALSE);
6372     glEnable(GL_STENCIL_TEST);
6373     glStencilFunc(GL_EQUAL, 0x57, 0xFF);
6374     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
6375     glStencilMask(0xFF);
6376 
6377     glDepthFunc(GL_LESS);
6378     glUniform4f(colorLoc, 1, 0, 0, 1);
6379     drawQuad(program, essl1_shaders::PositionAttrib(), -0.41f);
6380     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6381 
6382     glDepthFunc(GL_GREATER);
6383     glUniform4f(colorLoc, 0, 1, 0, 1);
6384     drawQuad(program, essl1_shaders::PositionAttrib(), -0.39f);
6385     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6386     ASSERT_GL_NO_ERROR();
6387 
6388     // Now that the depth stencil image is definitely initialized, copy it into the destination
6389     if (usedExtension == APIExtensionVersion::OES)
6390     {
6391         glCopyImageSubDataOES(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
6392                               kSize, 1);
6393     }
6394     else
6395     {
6396         glCopyImageSubDataEXT(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
6397                               kSize, 1);
6398     }
6399     ASSERT_GL_NO_ERROR();
6400 
6401     // Verify the dst texture has the right depth/stencil values
6402     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst, 0);
6403 
6404     glDepthFunc(GL_LESS);
6405     glUniform4f(colorLoc, 0, 0, 1, 1);
6406     drawQuad(program, essl1_shaders::PositionAttrib(), -0.41f);
6407     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
6408 
6409     glDepthFunc(GL_GREATER);
6410     glUniform4f(colorLoc, 1, 1, 0, 1);
6411     drawQuad(program, essl1_shaders::PositionAttrib(), -0.39f);
6412     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
6413     ASSERT_GL_NO_ERROR();
6414 }
6415 
6416 // Test basic GL_EXT_copy_image copy with a depth/stencil texture
TEST_P(Texture2DTestES3,CopyImageEXTDepthStencil)6417 TEST_P(Texture2DTestES3, CopyImageEXTDepthStencil)
6418 {
6419     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6420     testCopyImageDepthStencil(APIExtensionVersion::EXT);
6421 }
6422 
6423 // Test basic GL_OES_copy_image copy with a depth/stencil texture
TEST_P(Texture2DTestES3,CopyImageOESDepthStencil)6424 TEST_P(Texture2DTestES3, CopyImageOESDepthStencil)
6425 {
6426     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6427     testCopyImageDepthStencil(APIExtensionVersion::OES);
6428 }
6429 
6430 // Test GL_EXT_copy_image compressed texture copy with mipmaps smaller than the block size
TEST_P(Texture2DTestES3,CopyCompressedImageMipMaps)6431 TEST_P(Texture2DTestES3, CopyCompressedImageMipMaps)
6432 {
6433     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6434     // TODO(http://anglebug.com/42264170): Fix calls to vkCmdCopyBufferToImage() with images smaller
6435     // than the compressed format block size.
6436     ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::AllocateNonZeroMemory));
6437 
6438     constexpr uint32_t kSize             = 4;
6439     constexpr size_t kNumLevels          = 3;
6440     const uint8_t CompressedImageETC1[8] = {0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0};
6441 
6442     GLTexture srcTexture;
6443     glBindTexture(GL_TEXTURE_2D, srcTexture);
6444     for (size_t level = 0; level < kNumLevels; ++level)
6445     {
6446         glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
6447                                kSize >> level, 0, 8, CompressedImageETC1);
6448         EXPECT_GL_NO_ERROR();
6449     }
6450 
6451     GLTexture destTexture;
6452     glBindTexture(GL_TEXTURE_2D, destTexture);
6453     for (size_t level = 0; level < kNumLevels; ++level)
6454     {
6455         glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
6456                                kSize >> level, 0, 8, nullptr);
6457         EXPECT_GL_NO_ERROR();
6458     }
6459 
6460     glBindTexture(GL_TEXTURE_2D, 0);
6461 
6462     // copy
6463     for (size_t level = 0; level < kNumLevels; ++level)
6464     {
6465         glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, level, 0, 0, 0, destTexture, GL_TEXTURE_2D,
6466                               level, 0, 0, 0, kSize >> level, kSize >> level, 1);
6467         EXPECT_GL_NO_ERROR();
6468     }
6469 }
6470 
6471 // Test GL_EXT_copy_image copy with a non-zero base level
TEST_P(Texture2DTestES3,CopyImageBaseLevel1)6472 TEST_P(Texture2DTestES3, CopyImageBaseLevel1)
6473 {
6474     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6475 
6476     std::vector<GLColor> texDataBlack(8u * 8u, GLColor::black);
6477     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6478     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6479     std::vector<GLColor> texDataBlue(4u * 4u, GLColor::blue);
6480 
6481     GLTexture srcTexture;
6482     GLTexture destTexture;
6483 
6484     glActiveTexture(GL_TEXTURE0);
6485     glBindTexture(GL_TEXTURE_2D, destTexture);
6486     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6487     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6488     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6489                  texDataBlack.data());
6490     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6491     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6492                  texDataGreen.data());
6493     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
6494     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6495     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6496 
6497     glBindTexture(GL_TEXTURE_2D, srcTexture);
6498     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6499     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6500     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6501                  texDataBlack.data());
6502     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6503                  texDataGreen.data());
6504     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
6505     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6506     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6507     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6508 
6509     glBindTexture(GL_TEXTURE_2D, 0);
6510 
6511     // copy
6512     glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 1, 2, 2, 0, destTexture, GL_TEXTURE_2D, 1, 2,
6513                           2, 0, 2, 2, 1);
6514 
6515     glBindTexture(GL_TEXTURE_2D, destTexture);
6516 
6517     EXPECT_GL_NO_ERROR();
6518 
6519     glViewport(0, 0, 4, 4);
6520     drawQuad(mProgram, "position", 0.5f);
6521     EXPECT_GL_NO_ERROR();
6522 
6523     EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
6524     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
6525     EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
6526 }
6527 
6528 // Test basic GL_EXT_copy_image copy without any draw calls by attaching the texture
6529 // to a framebuffer and reads from the framebuffer to validate the copy
TEST_P(Texture2DTestES3,CopyImageFB)6530 TEST_P(Texture2DTestES3, CopyImageFB)
6531 {
6532     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6533 
6534     glViewport(0, 0, 4, 4);
6535     std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6536     GLTexture srcTexture;
6537     GLTexture destTexture;
6538 
6539     glActiveTexture(GL_TEXTURE0);
6540     glBindTexture(GL_TEXTURE_2D, destTexture);
6541     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6542     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6543     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6544     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6545     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6546 
6547     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6548     glBindTexture(GL_TEXTURE_2D, srcTexture);
6549     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6550     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6551     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6552     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6553     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6554                  texDataGreen.data());
6555     glBindTexture(GL_TEXTURE_2D, 0);
6556 
6557     // copy
6558     glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, destTexture, GL_TEXTURE_2D, 0, 0,
6559                           1, 0, 3, 3, 1);
6560 
6561     EXPECT_GL_NO_ERROR();
6562 
6563     GLFramebuffer fb;
6564     glBindFramebuffer(GL_FRAMEBUFFER, fb);
6565     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
6566     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6567 
6568     EXPECT_PIXEL_RECT_EQ(0, 1, 3, 3, GLColor::green);
6569     EXPECT_PIXEL_RECT_EQ(3, 0, 1, 4, GLColor::red);
6570     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 1, GLColor::red);
6571 
6572     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6573 }
6574 
6575 // Test GL_EXT_copy_image copy to a framebuffer attachment after
6576 // invalidation. Then draw with blending onto the framebuffer.
TEST_P(Texture2DTestES3,CopyImageFBInvalidateThenBlend)6577 TEST_P(Texture2DTestES3, CopyImageFBInvalidateThenBlend)
6578 {
6579     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6580 
6581     ANGLE_GL_PROGRAM(drawBlueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
6582     ANGLE_GL_PROGRAM(drawRedProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
6583 
6584     glViewport(0, 0, 4, 4);
6585     GLTexture srcTexture;
6586     GLTexture textureAttachment;
6587 
6588     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6589     glBindTexture(GL_TEXTURE_2D, srcTexture);
6590     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
6591     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6592     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6593                  texDataGreen.data());
6594     glBindTexture(GL_TEXTURE_2D, 0);
6595 
6596     glBindTexture(GL_TEXTURE_2D, textureAttachment);
6597     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6598     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
6599     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6600     glBindTexture(GL_TEXTURE_2D, 0);
6601 
6602     GLFramebuffer fb;
6603     glBindFramebuffer(GL_FRAMEBUFFER, fb);
6604     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureAttachment,
6605                            0);
6606     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6607 
6608     // Draw something in the texture to make sure it's image is defined.
6609     drawQuad(drawRedProgram, essl1_shaders::PositionAttrib(), 0.0f);
6610 
6611     // Invalidate the framebuffer.
6612     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
6613     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
6614     ASSERT_GL_NO_ERROR();
6615 
6616     // Copy into the framebuffer attachment.
6617     glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, textureAttachment, GL_TEXTURE_2D,
6618                           0, 0, 0, 0, 4, 4, 1);
6619     EXPECT_GL_NO_ERROR();
6620 
6621     // Draw and blend, making sure both the copy and draw happen correctly.
6622     glEnable(GL_BLEND);
6623     glBlendFunc(GL_ONE, GL_ONE);
6624     drawQuad(drawBlueProgram, essl1_shaders::PositionAttrib(), 0.0f);
6625     ASSERT_GL_NO_ERROR();
6626 
6627     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::cyan);
6628 
6629     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6630 }
6631 
6632 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
6633 // have images defined.
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeUndefined)6634 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
6635 {
6636     // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
6637     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
6638 
6639     glActiveTexture(GL_TEXTURE0);
6640     glBindTexture(GL_TEXTURE_2D, mTexture2D);
6641     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6642     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6643                  texDataGreen.data());
6644     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6645     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6646     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6647     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6648 
6649     EXPECT_GL_NO_ERROR();
6650 
6651     drawQuad(mProgram, "position", 0.5f);
6652 
6653     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6654 }
6655 
6656 // Test that drawing works correctly when level 0 is undefined and base level is 1.
TEST_P(Texture2DTestES3,DrawWithLevelZeroUndefined)6657 TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
6658 {
6659     // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
6660     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
6661 
6662     glActiveTexture(GL_TEXTURE0);
6663     glBindTexture(GL_TEXTURE_2D, mTexture2D);
6664     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6665     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6666                  texDataGreen.data());
6667     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6668     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6669     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6670     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6671 
6672     EXPECT_GL_NO_ERROR();
6673 
6674     // Texture is incomplete.
6675     drawQuad(mProgram, "position", 0.5f);
6676     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
6677 
6678     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6679                  texDataGreen.data());
6680 
6681     // Texture is now complete.
6682     drawQuad(mProgram, "position", 0.5f);
6683     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6684 }
6685 
6686 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
6687 // dimensions that don't fit the images inside the range.
6688 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)6689 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
6690 {
6691     glActiveTexture(GL_TEXTURE0);
6692     glBindTexture(GL_TEXTURE_2D, mTexture2D);
6693     std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
6694     std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6695     std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
6696 
6697     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6698     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6699 
6700     // Two levels that are initially unused.
6701     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6702     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6703                  texDataCyan.data());
6704 
6705     // One level that is used - only this level should affect completeness.
6706     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6707                  texDataGreen.data());
6708 
6709     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6710     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6711 
6712     EXPECT_GL_NO_ERROR();
6713 
6714     drawQuad(mProgram, "position", 0.5f);
6715 
6716     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6717 
6718     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
6719 
6720     // Switch the level that is being used to the cyan level 2.
6721     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
6722     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6723 
6724     EXPECT_GL_NO_ERROR();
6725 
6726     drawQuad(mProgram, "position", 0.5f);
6727 
6728     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
6729 }
6730 
6731 // Test glCopyImageSubDataEXT with GL_TEXTURE_2D_MULTISAMPLE,
6732 // RGBA8->RGBA8 copy
6733 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleImageEXT)6734 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleImageEXT)
6735 {
6736     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6737     testCopyMultisampleImage(APIExtensionVersion::EXT, GL_RGBA8);
6738     testCopyMultisampleImage(APIExtensionVersion::EXT, GL_RGB8);
6739 }
6740 
6741 // Test glCopyImageSubDataOES with GL_TEXTURE_2D_MULTISAMPLE,
6742 // RGBA8->RGBA8 copy
6743 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleImageOES)6744 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleImageOES)
6745 {
6746     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6747     testCopyMultisampleImage(APIExtensionVersion::OES, GL_RGBA8);
6748     testCopyMultisampleImage(APIExtensionVersion::OES, GL_RGB8);
6749 }
6750 
6751 // Test glCopyImageSubDataEXT with GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
6752 // RGBA8->RGBA8 copy
6753 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleArrayImageEXT)6754 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleArrayImageEXT)
6755 {
6756     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6757     testCopyMultisampleArrayImage(APIExtensionVersion::EXT, GL_RGBA8);
6758     testCopyMultisampleArrayImage(APIExtensionVersion::EXT, GL_RGB8);
6759 }
6760 
6761 // Test glCopyImageSubDataOES with GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
6762 // RGBA8->RGBA8 copy
6763 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleArrayImageOES)6764 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleArrayImageOES)
6765 {
6766     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6767     testCopyMultisampleArrayImage(APIExtensionVersion::OES, GL_RGBA8);
6768     testCopyMultisampleArrayImage(APIExtensionVersion::OES, GL_RGB8);
6769 }
6770 
6771 // Depth/Stencil textures cannot be 3D.
TEST_P(Texture3DTestES3,DepthStencil3DDisallowed)6772 TEST_P(Texture3DTestES3, DepthStencil3DDisallowed)
6773 {
6774     const std::array<std::tuple<GLenum, GLenum, GLenum>, 6> testConfigs = {
6775         std::make_tuple(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT),
6776         std::make_tuple(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT),
6777         std::make_tuple(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT),
6778         std::make_tuple(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV),
6779         std::make_tuple(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8),
6780         std::make_tuple(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE)};
6781 
6782     for (auto testConfig : testConfigs)
6783     {
6784         const GLenum internalformat = std::get<0>(testConfig);
6785         const GLenum format         = std::get<1>(testConfig);
6786         const GLenum type           = std::get<2>(testConfig);
6787 
6788         if (internalformat == GL_STENCIL_INDEX8 && !IsGLExtensionEnabled("GL_OES_texture_stencil8"))
6789         {
6790             continue;
6791         }
6792 
6793         GLTexture depthTexture;
6794         glBindTexture(GL_TEXTURE_3D, depthTexture);
6795         glTexImage3D(GL_TEXTURE_3D, 0, internalformat, 16, 16, 16, 0, format, type, nullptr);
6796         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6797 
6798         glTexStorage3D(GL_TEXTURE_3D, 2, internalformat, 16, 16, 16);
6799         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6800     }
6801 }
6802 
6803 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
6804 // have images defined.
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeUndefined)6805 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
6806 {
6807     glActiveTexture(GL_TEXTURE0);
6808     glBindTexture(GL_TEXTURE_3D, mTexture3D);
6809     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6810     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6811                  texDataGreen.data());
6812     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6813     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6814     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
6815     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
6816 
6817     EXPECT_GL_NO_ERROR();
6818 
6819     drawQuad(mProgram, "position", 0.5f);
6820 
6821     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6822 }
6823 
6824 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
6825 // dimensions that don't fit the images inside the range.
6826 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)6827 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
6828 {
6829     glActiveTexture(GL_TEXTURE0);
6830     glBindTexture(GL_TEXTURE_3D, mTexture3D);
6831     std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
6832     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6833     std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
6834 
6835     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6836     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6837 
6838     // Two levels that are initially unused.
6839     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6840                  texDataRed.data());
6841     glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6842                  texDataCyan.data());
6843 
6844     // One level that is used - only this level should affect completeness.
6845     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6846                  texDataGreen.data());
6847 
6848     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
6849     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
6850 
6851     EXPECT_GL_NO_ERROR();
6852 
6853     drawQuad(mProgram, "position", 0.5f);
6854 
6855     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6856 
6857     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
6858 
6859     // Switch the level that is being used to the cyan level 2.
6860     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
6861     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
6862 
6863     EXPECT_GL_NO_ERROR();
6864 
6865     drawQuad(mProgram, "position", 0.5f);
6866 
6867     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
6868 }
6869 
6870 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
6871 // have images defined.
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeUndefined)6872 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
6873 {
6874     glActiveTexture(GL_TEXTURE0);
6875     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6876     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6877     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6878                  texDataGreen.data());
6879     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6880     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6881     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
6882     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
6883 
6884     EXPECT_GL_NO_ERROR();
6885 
6886     drawQuad(mProgram, "position", 0.5f);
6887 
6888     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6889 }
6890 
6891 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
6892 // dimensions that don't fit the images inside the range.
6893 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)6894 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
6895 {
6896     // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
6897     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
6898 
6899     glActiveTexture(GL_TEXTURE0);
6900     glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
6901     std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
6902     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6903     std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
6904 
6905     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6906     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6907 
6908     // Two levels that are initially unused.
6909     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6910                  texDataRed.data());
6911     glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6912                  texDataCyan.data());
6913 
6914     // One level that is used - only this level should affect completeness.
6915     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6916                  texDataGreen.data());
6917 
6918     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
6919     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
6920 
6921     EXPECT_GL_NO_ERROR();
6922 
6923     drawQuad(mProgram, "position", 0.5f);
6924 
6925     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6926 
6927     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
6928 
6929     // Switch the level that is being used to the cyan level 2.
6930     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
6931     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
6932 
6933     EXPECT_GL_NO_ERROR();
6934 
6935     drawQuad(mProgram, "position", 0.5f);
6936 
6937     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
6938 }
6939 
6940 // Create a 2D array, then immediately redefine it to have fewer layers.  Regression test for a bug
6941 // in the Vulkan backend where the old higher-layer-count data upload was not removed.
TEST_P(Texture2DArrayTestES3,TextureArrayRedefineThenUse)6942 TEST_P(Texture2DArrayTestES3, TextureArrayRedefineThenUse)
6943 {
6944     int px = getWindowWidth() / 2;
6945     int py = getWindowHeight() / 2;
6946 
6947     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6948 
6949     // Fill the whole texture with red, then redefine it and fill with green
6950     std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
6951     std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
6952     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6953                  pixelsRed.data());
6954     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6955                  pixelsGreen.data());
6956 
6957     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6958     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6959     EXPECT_GL_NO_ERROR();
6960 
6961     glUseProgram(mProgram);
6962     EXPECT_GL_NO_ERROR();
6963 
6964     // Draw the first slice
6965     glUniform1i(mTextureArraySliceUniformLocation, 0);
6966     drawQuad(mProgram, "position", 0.5f);
6967     EXPECT_GL_NO_ERROR();
6968     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
6969 
6970     // Draw the second slice
6971     glUniform1i(mTextureArraySliceUniformLocation, 1);
6972     drawQuad(mProgram, "position", 0.5f);
6973     EXPECT_GL_NO_ERROR();
6974     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
6975 }
6976 
6977 // Create a 2D array texture and update layers with data and test that pruning
6978 // of superseded updates works as expected.
TEST_P(Texture2DArrayTestES3,TextureArrayPruneSupersededUpdates)6979 TEST_P(Texture2DArrayTestES3, TextureArrayPruneSupersededUpdates)
6980 {
6981     constexpr uint32_t kTexWidth  = 256;
6982     constexpr uint32_t kTexHeight = 256;
6983     constexpr uint32_t kTexLayers = 3;
6984 
6985     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6986     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6987     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6988     EXPECT_GL_NO_ERROR();
6989 
6990     // Initialize entire texture.
6991     constexpr GLColor kInitialExpectedColor = GLColor(201u, 201u, 201u, 201u);
6992     std::vector<GLColor> initialData(kTexWidth * kTexHeight * kTexLayers, kInitialExpectedColor);
6993     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kTexWidth, kTexHeight, kTexLayers, 0, GL_RGBA,
6994                  GL_UNSIGNED_BYTE, initialData.data());
6995 
6996     // Upate different layers with different colors, these together should supersed
6997     // the entire init update
6998     constexpr GLColor kExpectedColor[] = {GLColor(32u, 32u, 32u, 32u), GLColor(64u, 64u, 64u, 64u),
6999                                           GLColor(128u, 128u, 128u, 128u)};
7000     std::vector<GLColor> supersedingData[] = {
7001         std::vector<GLColor>(kTexWidth * kTexHeight, kExpectedColor[0]),
7002         std::vector<GLColor>(kTexWidth * kTexHeight, kExpectedColor[1]),
7003         std::vector<GLColor>(kTexWidth * kTexHeight, kExpectedColor[2])};
7004 
7005     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kTexWidth, kTexHeight, 1, GL_RGBA,
7006                     GL_UNSIGNED_BYTE, supersedingData[0].data());
7007     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, kTexWidth, kTexHeight, 1, GL_RGBA,
7008                     GL_UNSIGNED_BYTE, supersedingData[1].data());
7009     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, kTexWidth, kTexHeight, 1, GL_RGBA,
7010                     GL_UNSIGNED_BYTE, supersedingData[2].data());
7011 
7012     glUseProgram(mProgram);
7013     EXPECT_GL_NO_ERROR();
7014 
7015     // Draw layer 0
7016     glUniform1i(mTextureArraySliceUniformLocation, 0);
7017     drawQuad(mProgram, "position", 0.5f);
7018     EXPECT_GL_NO_ERROR();
7019     EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor[0]);
7020 
7021     // Draw layer 1
7022     glUniform1i(mTextureArraySliceUniformLocation, 1);
7023     drawQuad(mProgram, "position", 0.5f);
7024     EXPECT_GL_NO_ERROR();
7025     EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor[1]);
7026 
7027     // Draw layer 2
7028     glUniform1i(mTextureArraySliceUniformLocation, 2);
7029     drawQuad(mProgram, "position", 0.5f);
7030     EXPECT_GL_NO_ERROR();
7031     EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor[2]);
7032 }
7033 
7034 // Create a 2D array, use it, then redefine it to have fewer layers.  Regression test for a bug in
7035 // the Vulkan backend where the old higher-layer-count data upload was not removed.
TEST_P(Texture2DArrayTestES3,TextureArrayUseThenRedefineThenUse)7036 TEST_P(Texture2DArrayTestES3, TextureArrayUseThenRedefineThenUse)
7037 {
7038     int px = getWindowWidth() / 2;
7039     int py = getWindowHeight() / 2;
7040 
7041     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
7042 
7043     // Fill the whole texture with red.
7044     std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
7045     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7046                  pixelsRed.data());
7047 
7048     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7049     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7050     EXPECT_GL_NO_ERROR();
7051 
7052     glUseProgram(mProgram);
7053     EXPECT_GL_NO_ERROR();
7054 
7055     // Draw the first slice
7056     glUniform1i(mTextureArraySliceUniformLocation, 0);
7057     drawQuad(mProgram, "position", 0.5f);
7058     EXPECT_GL_NO_ERROR();
7059     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
7060 
7061     // Draw the fourth slice
7062     glUniform1i(mTextureArraySliceUniformLocation, 3);
7063     drawQuad(mProgram, "position", 0.5f);
7064     EXPECT_GL_NO_ERROR();
7065     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
7066 
7067     // Redefine the image and fill with green
7068     std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
7069     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7070                  pixelsGreen.data());
7071 
7072     // Draw the first slice
7073     glUniform1i(mTextureArraySliceUniformLocation, 0);
7074     drawQuad(mProgram, "position", 0.5f);
7075     EXPECT_GL_NO_ERROR();
7076     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
7077 
7078     // Draw the second slice
7079     glUniform1i(mTextureArraySliceUniformLocation, 1);
7080     drawQuad(mProgram, "position", 0.5f);
7081     EXPECT_GL_NO_ERROR();
7082     EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
7083 }
7084 
7085 // Create a 2D array texture, use it, then redefine one level without changing dimensions.
TEST_P(Texture2DArrayTestES3,RedefineLevelData)7086 TEST_P(Texture2DArrayTestES3, RedefineLevelData)
7087 {
7088     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
7089 
7090     // Fill both levels with red
7091     std::vector<GLColor> pixelsRed(2 * 2 * 1, GLColor::red);
7092     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7093                  pixelsRed.data());
7094     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7095                  pixelsRed.data());
7096     ASSERT_GL_NO_ERROR();
7097 
7098     // Check that both levels are red
7099     GLFramebuffer fbo;
7100     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7101     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
7102     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7103     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 1, 0);
7104     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7105 
7106     // Redefine level 1 with green
7107     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7108                  &GLColor::green);
7109     ASSERT_GL_NO_ERROR();
7110 
7111     // Check that level 0 is red and level 1 is green
7112     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
7113     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7114     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 1, 0);
7115     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7116 }
7117 
7118 // Create a 3D texture, use it, then redefine one level without changing dimensions.
TEST_P(Texture3DTestES3,RedefineLevelData)7119 TEST_P(Texture3DTestES3, RedefineLevelData)
7120 {
7121     glBindTexture(GL_TEXTURE_3D, mTexture3D);
7122 
7123     // Fill both levels with red
7124     std::vector<GLColor> pixelsRed(2 * 2 * 1, GLColor::red);
7125     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7126                  pixelsRed.data());
7127     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7128                  pixelsRed.data());
7129     ASSERT_GL_NO_ERROR();
7130 
7131     // Check that both levels are red
7132     GLFramebuffer fbo;
7133     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7134     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 0, 0);
7135     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7136     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 1, 0);
7137     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7138 
7139     // Redefine level 1 with green
7140     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7141                  &GLColor::green);
7142     ASSERT_GL_NO_ERROR();
7143 
7144     // Check that level 0 is red and level 1 is green
7145     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 0, 0);
7146     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7147     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 1, 0);
7148     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7149 }
7150 
7151 // Test that texture completeness is updated if texture max level changes.
7152 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithMaxLevel)7153 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
7154 {
7155     glActiveTexture(GL_TEXTURE0);
7156     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7157     std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
7158 
7159     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7160     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7161 
7162     // A level that is initially unused.
7163     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7164                  texDataGreen.data());
7165 
7166     // One level that is initially used - only this level should affect completeness.
7167     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7168                  texDataGreen.data());
7169 
7170     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7171     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7172 
7173     EXPECT_GL_NO_ERROR();
7174 
7175     drawQuad(mProgram, "position", 0.5f);
7176 
7177     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7178 
7179     // Switch the max level to level 1. The levels within the used range now have inconsistent
7180     // dimensions and the texture should be incomplete.
7181     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
7182 
7183     EXPECT_GL_NO_ERROR();
7184 
7185     drawQuad(mProgram, "position", 0.5f);
7186 
7187     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7188 }
7189 
7190 // Test a bug that staged clear overlaps with glTexSubImage with multiple layers may incorrectly
7191 // keep the staged clear. http://anglebug.com/345532371
TEST_P(Texture2DArrayTestES3,ClearThenTexSubImageWithOverlappingLayersThenRead)7192 TEST_P(Texture2DArrayTestES3, ClearThenTexSubImageWithOverlappingLayersThenRead)
7193 {
7194     constexpr GLsizei kTexWidth  = 128;
7195     constexpr GLsizei kTexHeight = 128;
7196     constexpr GLsizei kTexDepth  = 6;
7197     // Create a single leveled texture with 6 layers
7198     GLTexture tex;
7199     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
7200     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth);
7201 
7202     // Stage clear to red on all layers
7203     GLFramebuffer drawFBO;
7204     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
7205     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
7206     for (GLsizei layer = 0; layer < kTexDepth; layer++)
7207     {
7208         glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7209         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
7210         glClear(GL_COLOR_BUFFER_BIT);
7211     }
7212 
7213     // TexSubImage with green color on half of the image of layer 2,3,4
7214     std::vector<GLColor> updateData((kTexWidth / 2) * kTexHeight * 3, GLColor::green);
7215     GLsizei layerStart = 2;
7216     GLsizei layerCount = 3;
7217     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerStart, kTexWidth / 2, kTexHeight, layerCount,
7218                     GL_RGBA, GL_UNSIGNED_BYTE, updateData.data());
7219 
7220     // Now read out layer 2/3/4
7221     GLFramebuffer readFBO;
7222     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
7223     for (GLsizei layer = layerStart; layer < layerStart + layerCount; layer++)
7224     {
7225         glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7226         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
7227         EXPECT_PIXEL_EQ(kTexWidth / 4, kTexHeight / 2, GLColor::green.R, GLColor::green.G,
7228                         GLColor::green.B, GLColor::green.A);
7229         EXPECT_PIXEL_EQ(3 * kTexWidth / 4, kTexHeight / 2, GLColor::red.R, GLColor::red.G,
7230                         GLColor::red.B, GLColor::red.A);
7231     }
7232     ASSERT_GL_NO_ERROR();
7233 }
7234 
7235 // Test a bug that staged clear overlaps with glTexSubImage with multiple layers may incorrectly
7236 // keep the staged clear. http://anglebug.com/345532371
TEST_P(Texture2DArrayTestES3,ClearThenTexSubImageWithOverlappingLayersThenDrawAndRead)7237 TEST_P(Texture2DArrayTestES3, ClearThenTexSubImageWithOverlappingLayersThenDrawAndRead)
7238 {
7239     constexpr GLsizei kTexWidth  = 128;
7240     constexpr GLsizei kTexHeight = 128;
7241     constexpr GLsizei kTexDepth  = 6;
7242     // Create a single leveled texture with 6 layers
7243     GLTexture tex;
7244     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
7245     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth);
7246 
7247     // Stage clear to red on all layers
7248     GLFramebuffer drawFBO;
7249     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
7250     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
7251     for (GLsizei layer = 0; layer < kTexDepth; layer++)
7252     {
7253         glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7254         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
7255         glClear(GL_COLOR_BUFFER_BIT);
7256     }
7257 
7258     // TexSubImage with green color on half of the image of layer 2,3,4
7259     std::vector<GLColor> updateData((kTexWidth / 2) * kTexHeight * 3, GLColor::green);
7260     GLsizei layerStart = 2;
7261     GLsizei layerCount = 3;
7262     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerStart, kTexWidth / 2, kTexHeight, layerCount,
7263                     GL_RGBA, GL_UNSIGNED_BYTE, updateData.data());
7264 
7265     // Now Draw to fbo on layerStart with blue color
7266     GLsizei blueQuadLayer = 2;
7267     glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, blueQuadLayer);
7268     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
7269     glEnable(GL_BLEND);
7270     glBlendFunc(GL_ONE, GL_ONE);
7271     ANGLE_GL_PROGRAM(blueProgram, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
7272     glUseProgram(blueProgram);
7273     drawQuad(blueProgram, essl3_shaders::PositionAttrib(), 0.5f);
7274 
7275     // Now read out layer 2/3/4
7276     GLFramebuffer readFBO;
7277     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
7278     for (GLsizei layer = layerStart; layer < layerStart + layerCount; layer++)
7279     {
7280         glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7281         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
7282         if (layer == blueQuadLayer)
7283         {
7284             // green + blue = cyan
7285             EXPECT_PIXEL_EQ(kTexWidth / 4, kTexHeight / 2, GLColor::cyan.R, GLColor::cyan.G,
7286                             GLColor::cyan.B, GLColor::cyan.A);
7287             // red + blue = magenta
7288             EXPECT_PIXEL_EQ(3 * kTexWidth / 4, kTexHeight / 2, GLColor::magenta.R,
7289                             GLColor::magenta.G, GLColor::magenta.B, GLColor::magenta.A);
7290         }
7291         else
7292         {
7293             EXPECT_PIXEL_EQ(kTexWidth / 4, kTexHeight / 2, GLColor::green.R, GLColor::green.G,
7294                             GLColor::green.B, GLColor::green.A);
7295             EXPECT_PIXEL_EQ(3 * kTexWidth / 4, kTexHeight / 2, GLColor::red.R, GLColor::red.G,
7296                             GLColor::red.B, GLColor::red.A);
7297         }
7298     }
7299     ASSERT_GL_NO_ERROR();
7300 }
7301 
7302 // Test that compressed textures ignore the pixel unpack state.
7303 // (https://crbug.org/1267496)
TEST_P(Texture3DTestES3,PixelUnpackStateTexImage)7304 TEST_P(Texture3DTestES3, PixelUnpackStateTexImage)
7305 {
7306     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
7307                        !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
7308 
7309     glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 5);
7310     glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
7311 
7312     uint8_t data[64] = {0};
7313     glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 4, 4, 4, 0, 64,
7314                            data);
7315     EXPECT_GL_NO_ERROR();
7316 }
7317 
7318 // Test that compressed textures ignore the pixel unpack state.
7319 // (https://crbug.org/1267496)
TEST_P(Texture3DTestES3,PixelUnpackStateTexSubImage)7320 TEST_P(Texture3DTestES3, PixelUnpackStateTexSubImage)
7321 {
7322     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
7323                        !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
7324 
7325     glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
7326 
7327     uint8_t data[64] = {0};
7328     glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 4, 4, 4, 0, 64,
7329                            data);
7330     EXPECT_GL_NO_ERROR();
7331 
7332     glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 5);
7333 
7334     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 4, 4, 4,
7335                               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 64, data);
7336     EXPECT_GL_NO_ERROR();
7337 }
7338 
7339 // Test that 3D texture completeness is updated if texture max level changes.
7340 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,Texture3DCompletenessChangesWithMaxLevel)7341 TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
7342 {
7343     glActiveTexture(GL_TEXTURE0);
7344     glBindTexture(GL_TEXTURE_3D, mTexture3D);
7345     std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
7346 
7347     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7348     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7349 
7350     // A level that is initially unused.
7351     glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7352                  texDataGreen.data());
7353 
7354     // One level that is initially used - only this level should affect completeness.
7355     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7356                  texDataGreen.data());
7357 
7358     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
7359     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
7360 
7361     EXPECT_GL_NO_ERROR();
7362 
7363     drawQuad(mProgram, "position", 0.5f);
7364 
7365     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7366 
7367     // Switch the max level to level 1. The levels within the used range now have inconsistent
7368     // dimensions and the texture should be incomplete.
7369     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
7370 
7371     EXPECT_GL_NO_ERROR();
7372 
7373     drawQuad(mProgram, "position", 0.5f);
7374 
7375     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7376 }
7377 
7378 // Test that texture completeness is updated if texture base level changes.
7379 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithBaseLevel)7380 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
7381 {
7382     glActiveTexture(GL_TEXTURE0);
7383     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7384     std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
7385 
7386     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7387     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7388 
7389     // Two levels that are initially unused.
7390     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7391                  texDataGreen.data());
7392     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7393                  texDataGreen.data());
7394 
7395     // One level that is initially used - only this level should affect completeness.
7396     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7397                  texDataGreen.data());
7398 
7399     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
7400     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
7401 
7402     EXPECT_GL_NO_ERROR();
7403 
7404     drawQuad(mProgram, "position", 0.5f);
7405 
7406     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7407 
7408     // Switch the base level to level 1. The levels within the used range now have inconsistent
7409     // dimensions and the texture should be incomplete.
7410     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7411 
7412     EXPECT_GL_NO_ERROR();
7413 
7414     drawQuad(mProgram, "position", 0.5f);
7415 
7416     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7417 }
7418 
7419 // Test that texture is not complete if base level is greater than max level.
7420 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureBaseLevelGreaterThanMaxLevel)7421 TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
7422 {
7423     glActiveTexture(GL_TEXTURE0);
7424     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7425 
7426     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7427     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7428 
7429     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
7430 
7431     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
7432     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7433 
7434     EXPECT_GL_NO_ERROR();
7435 
7436     drawQuad(mProgram, "position", 0.5f);
7437 
7438     // Texture should be incomplete.
7439     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7440 }
7441 
7442 // Test that immutable texture base level and max level are clamped.
7443 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
TEST_P(Texture2DTestES3,ImmutableTextureBaseLevelOutOfRange)7444 TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
7445 {
7446     glActiveTexture(GL_TEXTURE0);
7447     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7448 
7449     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7450     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7451 
7452     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
7453 
7454     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
7455 
7456     // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
7457     // should be clamped to [base_level, levels - 1].
7458     // GLES 3.0.4 section 3.8.10 subsection Mipmapping
7459     // In the case of this test, those rules make the effective base level and max level 0.
7460     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
7461     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
7462 
7463     EXPECT_GL_NO_ERROR();
7464 
7465     drawQuad(mProgram, "position", 0.5f);
7466 
7467     // Texture should be complete.
7468     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7469 }
7470 
7471 // Test that changing base level works when it affects the format of the texture.
TEST_P(Texture2DTestES3,TextureFormatChangesWithBaseLevel)7472 TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
7473 {
7474     // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
7475     ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
7476 
7477     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
7478 
7479     // Observed incorrect rendering on AMD OpenGL.
7480     ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
7481 
7482     glActiveTexture(GL_TEXTURE0);
7483     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7484     std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
7485     std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
7486 
7487     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7488     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7489 
7490     // RGBA8 level that's initially unused.
7491     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7492                  texDataCyan.data());
7493 
7494     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7495     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
7496 
7497     // RG8 level that's initially used, with consistent dimensions with level 0 but a different
7498     // format. It reads green channel data from the green and alpha channels of texDataGreen
7499     // (this is a bit hacky but works).
7500     glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
7501 
7502     EXPECT_GL_NO_ERROR();
7503 
7504     drawQuad(mProgram, "position", 0.5f);
7505 
7506     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7507 
7508     // Switch the texture to use the cyan level 0 with the RGBA format.
7509     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7510     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7511 
7512     EXPECT_GL_NO_ERROR();
7513 
7514     drawQuad(mProgram, "position", 0.5f);
7515 
7516     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
7517 }
7518 
7519 // Test that setting a texture image works when base level is out of range.
TEST_P(Texture2DTestES3,SetImageWhenBaseLevelOutOfRange)7520 TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
7521 {
7522     glActiveTexture(GL_TEXTURE0);
7523     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7524 
7525     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7526     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7527 
7528     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
7529     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
7530 
7531     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
7532 
7533     EXPECT_GL_NO_ERROR();
7534 
7535     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7536 
7537     drawQuad(mProgram, "position", 0.5f);
7538 
7539     // Texture should be complete.
7540     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7541 }
7542 
7543 // In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
7544 // RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
7545 // with these formats does not work as expected.
TEST_P(Texture2DArrayTestES3,RedefineInittableArray)7546 TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
7547 {
7548     std::vector<GLubyte> pixelData;
7549     for (size_t count = 0; count < 5000; count++)
7550     {
7551         pixelData.push_back(0u);
7552         pixelData.push_back(255u);
7553         pixelData.push_back(0u);
7554     }
7555 
7556     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
7557     glUseProgram(mProgram);
7558     glUniform1i(mTextureArrayLocation, 0);
7559 
7560     // The first draw worked correctly.
7561     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
7562                  &pixelData[0]);
7563 
7564     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7565     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7566     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
7567     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
7568     drawQuad(mProgram, "position", 1.0f);
7569     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7570 
7571     // The dimension of the respecification must match the original exactly to trigger the bug.
7572     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
7573                  &pixelData[0]);
7574     drawQuad(mProgram, "position", 1.0f);
7575     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7576 
7577     ASSERT_GL_NO_ERROR();
7578 }
7579 
7580 // Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
7581 // This test is needed especially to confirm that sampler registers get assigned correctly on
7582 // the HLSL backend even when there's a mix of different HLSL sampler and texture types.
TEST_P(ShadowSamplerPlusSampler3DTestES3,ShadowSamplerPlusSampler3DDraw)7583 TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
7584 {
7585     glActiveTexture(GL_TEXTURE0);
7586     glBindTexture(GL_TEXTURE_3D, mTexture3D);
7587     GLubyte texData[4];
7588     texData[0] = 0;
7589     texData[1] = 60;
7590     texData[2] = 0;
7591     texData[3] = 255;
7592     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
7593 
7594     glActiveTexture(GL_TEXTURE1);
7595     glBindTexture(GL_TEXTURE_2D, mTextureShadow);
7596     GLfloat depthTexData[1];
7597     depthTexData[0] = 0.5f;
7598     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
7599                  depthTexData);
7600 
7601     glUseProgram(mProgram);
7602     glUniform1f(mDepthRefUniformLocation, 0.3f);
7603     glUniform1i(mTexture3DUniformLocation, 0);
7604     glUniform1i(mTextureShadowUniformLocation, 1);
7605 
7606     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
7607     drawQuad(mProgram, "position", 0.5f);
7608     EXPECT_GL_NO_ERROR();
7609     // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
7610     EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
7611 
7612     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
7613     drawQuad(mProgram, "position", 0.5f);
7614     EXPECT_GL_NO_ERROR();
7615     // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
7616     EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
7617 }
7618 
7619 // Test multiple different sampler types in the same shader.
7620 // This test makes sure that even if sampler / texture registers get grouped together based on type
7621 // or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
7622 // still has the right register index information for each ESSL sampler.
7623 // The tested ESSL samplers have the following types in D3D11 HLSL:
7624 // sampler2D:         Texture2D   + SamplerState
7625 // samplerCube:       TextureCube + SamplerState
7626 // sampler2DShadow:   Texture2D   + SamplerComparisonState
7627 // samplerCubeShadow: TextureCube + SamplerComparisonState
TEST_P(SamplerTypeMixTestES3,SamplerTypeMixDraw)7628 TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
7629 {
7630     glActiveTexture(GL_TEXTURE0);
7631     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7632     GLubyte texData[4];
7633     texData[0] = 0;
7634     texData[1] = 0;
7635     texData[2] = 120;
7636     texData[3] = 255;
7637     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
7638 
7639     glActiveTexture(GL_TEXTURE1);
7640     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
7641     texData[0] = 0;
7642     texData[1] = 90;
7643     texData[2] = 0;
7644     texData[3] = 255;
7645     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
7646     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
7647                     texData);
7648 
7649     glActiveTexture(GL_TEXTURE2);
7650     glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
7651     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
7652     GLfloat depthTexData[1];
7653     depthTexData[0] = 0.5f;
7654     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
7655                  depthTexData);
7656 
7657     glActiveTexture(GL_TEXTURE3);
7658     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
7659     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
7660     depthTexData[0] = 0.2f;
7661     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
7662     glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
7663                     depthTexData);
7664 
7665     // http://anglebug.com/42262588: TODO: Add a DS texture case
7666 
7667     EXPECT_GL_NO_ERROR();
7668 
7669     glUseProgram(mProgram);
7670     glUniform1f(mDepthRefUniformLocation, 0.3f);
7671     glUniform1i(mTexture2DUniformLocation, 0);
7672     glUniform1i(mTextureCubeUniformLocation, 1);
7673     glUniform1i(mTexture2DShadowUniformLocation, 2);
7674     glUniform1i(mTextureCubeShadowUniformLocation, 3);
7675 
7676     drawQuad(mProgram, "position", 0.5f);
7677     EXPECT_GL_NO_ERROR();
7678     // The shader writes:
7679     // <texture 2d color> +
7680     // <cube map color> +
7681     // 0.25 * <comparison result (1.0)> +
7682     // 0.125 * <comparison result (0.0)>
7683     EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
7684 }
7685 
7686 // Test different base levels on textures accessed through the same sampler array.
7687 // Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
TEST_P(TextureSizeTextureArrayTest,BaseLevelVariesInTextureArray)7688 TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
7689 {
7690     ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
7691 
7692     // http://anglebug.com/42263017
7693     ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
7694 
7695     glActiveTexture(GL_TEXTURE0);
7696     glBindTexture(GL_TEXTURE_2D, mTexture2DA);
7697     GLsizei size = 64;
7698     for (GLint level = 0; level < 7; ++level)
7699     {
7700         ASSERT_LT(0, size);
7701         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7702                      nullptr);
7703         size = size / 2;
7704     }
7705     ASSERT_EQ(0, size);
7706     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7707 
7708     glActiveTexture(GL_TEXTURE1);
7709     glBindTexture(GL_TEXTURE_2D, mTexture2DB);
7710     size = 128;
7711     for (GLint level = 0; level < 8; ++level)
7712     {
7713         ASSERT_LT(0, size);
7714         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7715                      nullptr);
7716         size = size / 2;
7717     }
7718     ASSERT_EQ(0, size);
7719     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
7720     EXPECT_GL_NO_ERROR();
7721 
7722     glUseProgram(mProgram);
7723     glUniform1i(mTexture0Location, 0);
7724     glUniform1i(mTexture1Location, 1);
7725 
7726     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
7727     EXPECT_GL_NO_ERROR();
7728     // Red channel: width of level 1 of texture A: 32.
7729     // Green channel: width of level 3 of texture B: 16.
7730     EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
7731 }
7732 
7733 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7734 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBImplicitAlpha1)7735 TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
7736 {
7737     glActiveTexture(GL_TEXTURE0);
7738     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7739     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
7740     EXPECT_GL_NO_ERROR();
7741 
7742     drawQuad(mProgram, "position", 0.5f);
7743 
7744     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7745 }
7746 
7747 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7748 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBXImplicitAlpha1)7749 TEST_P(Texture2DTestES3, TextureRGBXImplicitAlpha1)
7750 {
7751     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
7752 
7753     GLTexture texture2D;
7754     glBindTexture(GL_TEXTURE_2D, texture2D);
7755     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBX8_ANGLE, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
7756     glActiveTexture(GL_TEXTURE0);
7757     EXPECT_GL_NO_ERROR();
7758 
7759     drawQuad(mProgram, "position", 0.5f);
7760 
7761     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7762 }
7763 
7764 // Test that data upload to RGBX works.
TEST_P(Texture2DTestES3,TextureRGBXUpload)7765 TEST_P(Texture2DTestES3, TextureRGBXUpload)
7766 {
7767     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
7768 
7769     const size_t kWidth  = 32;
7770     const size_t kHeight = 32;
7771 
7772     GLTexture color;
7773     glBindTexture(GL_TEXTURE_2D, color);
7774     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
7775 
7776     GLFramebuffer fbo;
7777     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7778     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
7779     ASSERT_GL_NO_ERROR();
7780     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
7781 
7782     // Upload data to an RGBX texture
7783     const GLColorRGB kColor(100, 200, 55);
7784     std::vector<GLColorRGB> data(kWidth * kHeight, kColor);
7785 
7786     GLTexture texture;
7787     glBindTexture(GL_TEXTURE_2D, texture);
7788     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBX8_ANGLE, kWidth, kHeight);
7789     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7790     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7791     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, data.data());
7792     ASSERT_GL_NO_ERROR();
7793 
7794     // Sample from the texture
7795     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
7796     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
7797 
7798     const GLColor kExpect(kColor.R, kColor.G, kColor.B, 255);
7799     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpect, 1);
7800     EXPECT_PIXEL_COLOR_NEAR(0, 1, kExpect, 1);
7801     EXPECT_PIXEL_COLOR_NEAR(1, 0, kExpect, 1);
7802     EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, 0, kExpect, 1);
7803     EXPECT_PIXEL_COLOR_NEAR(0, kHeight - 1, kExpect, 1);
7804     EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, kHeight - 1, kExpect, 1);
7805     EXPECT_PIXEL_COLOR_NEAR(kWidth / 2, kHeight / 2, kExpect, 1);
7806     ASSERT_GL_NO_ERROR();
7807 }
7808 
7809 // Test that data download from RGBX works.
TEST_P(Texture2DTestES3,TextureRGBXDownload)7810 TEST_P(Texture2DTestES3, TextureRGBXDownload)
7811 {
7812     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
7813 
7814     const size_t kWidth  = 32;
7815     const size_t kHeight = 32;
7816 
7817     GLTexture color;
7818     glBindTexture(GL_TEXTURE_2D, color);
7819     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBX8_ANGLE, kWidth, kHeight);
7820 
7821     GLFramebuffer fbo;
7822     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7823     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
7824     ASSERT_GL_NO_ERROR();
7825     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
7826 
7827     // Render to the RGBX texture
7828     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
7829     glUseProgram(program);
7830     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
7831     ASSERT_NE(colorLoc, -1);
7832 
7833     glUniform4f(colorLoc, 0.3f, 0.6f, 0.8f, 0.2f);
7834     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
7835     ASSERT_GL_NO_ERROR();
7836 
7837     // Readback as RGBX.
7838     std::vector<GLColor> readback(kWidth * kHeight);
7839     glReadPixels(0, 0, kWidth, kHeight, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, readback.data());
7840     ASSERT_GL_NO_ERROR();
7841 
7842     const GLColor kExpect(76,   // 0.3f * 255
7843                           153,  // 0.6f * 255
7844                           204,  // 0.8f * 255
7845                           255);
7846 
7847     for (size_t y = 0; y < kHeight; y++)
7848     {
7849         for (size_t x = 0; x < kWidth; x++)
7850         {
7851             const GLColor actualColor = readback[y * kWidth + x];
7852 
7853             EXPECT_NEAR(actualColor.R, kExpect.R, 1) << x << "x" << y;
7854             EXPECT_NEAR(actualColor.G, kExpect.G, 1) << x << "x" << y;
7855             EXPECT_NEAR(actualColor.B, kExpect.B, 1) << x << "x" << y;
7856             EXPECT_EQ(actualColor.A, kExpect.A) << x << "x" << y;
7857         }
7858     }
7859     ASSERT_GL_NO_ERROR();
7860 }
7861 
7862 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7863 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminanceImplicitAlpha1)7864 TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
7865 {
7866     setUpProgram();
7867 
7868     glActiveTexture(GL_TEXTURE0);
7869     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7870     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
7871     EXPECT_GL_NO_ERROR();
7872 
7873     drawQuad(mProgram, "position", 0.5f);
7874 
7875     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7876 }
7877 
7878 // Validate that every component of the pixel will be equal to the luminance value we've set
7879 // and that the alpha channel will be 1 (or 255 to be exact).
TEST_P(Texture2DTest,TextureLuminanceRGBSame)7880 TEST_P(Texture2DTest, TextureLuminanceRGBSame)
7881 {
7882     setUpProgram();
7883 
7884     glActiveTexture(GL_TEXTURE0);
7885     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7886     uint8_t pixel = 50;
7887     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
7888     EXPECT_GL_NO_ERROR();
7889 
7890     drawQuad(mProgram, "position", 0.5f);
7891 
7892     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
7893 }
7894 
7895 // Validate that every component of the pixel will be equal to the luminance value we've set
7896 // and that the alpha channel will be the second component.
TEST_P(Texture2DTest,TextureLuminanceAlphaRGBSame)7897 TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
7898 {
7899     setUpProgram();
7900 
7901     glActiveTexture(GL_TEXTURE0);
7902     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7903     uint8_t pixel[] = {50, 25};
7904     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
7905                  GL_UNSIGNED_BYTE, pixel);
7906     EXPECT_GL_NO_ERROR();
7907 
7908     drawQuad(mProgram, "position", 0.5f);
7909 
7910     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
7911 }
7912 
7913 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7914 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance32ImplicitAlpha1)7915 TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
7916 {
7917     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7918     ANGLE_SKIP_TEST_IF(IsD3D9());
7919     ANGLE_SKIP_TEST_IF(IsVulkan());
7920 
7921     setUpProgram();
7922 
7923     glActiveTexture(GL_TEXTURE0);
7924     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7925     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
7926     EXPECT_GL_NO_ERROR();
7927 
7928     drawQuad(mProgram, "position", 0.5f);
7929 
7930     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7931 }
7932 
7933 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7934 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance16ImplicitAlpha1)7935 TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
7936 {
7937     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7938     ANGLE_SKIP_TEST_IF(IsD3D9());
7939     ANGLE_SKIP_TEST_IF(IsVulkan());
7940     // TODO(ynovikov): re-enable once root cause of http://anglebug.com/42260416 is fixed
7941     ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
7942 
7943     setUpProgram();
7944 
7945     glActiveTexture(GL_TEXTURE0);
7946     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7947     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
7948     EXPECT_GL_NO_ERROR();
7949 
7950     drawQuad(mProgram, "position", 0.5f);
7951 
7952     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7953 }
7954 
7955 // Test that CopyTexImage2D does not trigger assertion after CompressedTexImage2D.
7956 // https://crbug.com/1216276
TEST_P(Texture2DTest,CopyAfterCompressed)7957 TEST_P(Texture2DTest, CopyAfterCompressed)
7958 {
7959     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
7960 
7961     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7962     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 0, 8, nullptr);
7963     EXPECT_GL_NO_ERROR();
7964 
7965     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 0, 0, 4, 4, 0);
7966     EXPECT_GL_NO_ERROR();
7967 }
7968 
7969 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7970 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB8UIImplicitAlpha1)7971 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
7972 {
7973     ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
7974 
7975     glActiveTexture(GL_TEXTURE0);
7976     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7977     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
7978     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7979     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7980     EXPECT_GL_NO_ERROR();
7981 
7982     drawQuad(mProgram, "position", 0.5f);
7983 
7984     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7985 }
7986 
7987 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7988 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB8IImplicitAlpha1)7989 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
7990 {
7991     ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
7992 
7993     glActiveTexture(GL_TEXTURE0);
7994     glBindTexture(GL_TEXTURE_2D, mTexture2D);
7995 
7996     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
7997     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7998     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7999     EXPECT_GL_NO_ERROR();
8000 
8001     drawQuad(mProgram, "position", 0.5f);
8002 
8003     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8004 }
8005 
8006 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8007 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB16UIImplicitAlpha1)8008 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
8009 {
8010     ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8011 
8012     glActiveTexture(GL_TEXTURE0);
8013     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8014     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
8015     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8016     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8017     EXPECT_GL_NO_ERROR();
8018 
8019     drawQuad(mProgram, "position", 0.5f);
8020 
8021     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8022 }
8023 
8024 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8025 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB16IImplicitAlpha1)8026 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
8027 {
8028     ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8029 
8030     glActiveTexture(GL_TEXTURE0);
8031     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8032     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
8033     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8034     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8035     EXPECT_GL_NO_ERROR();
8036 
8037     drawQuad(mProgram, "position", 0.5f);
8038 
8039     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8040 }
8041 
8042 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8043 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB32UIImplicitAlpha1)8044 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
8045 {
8046     ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8047 
8048     glActiveTexture(GL_TEXTURE0);
8049     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8050     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
8051     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8052     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8053     EXPECT_GL_NO_ERROR();
8054 
8055     drawQuad(mProgram, "position", 0.5f);
8056 
8057     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8058 }
8059 
8060 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8061 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB32IImplicitAlpha1)8062 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
8063 {
8064     ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8065 
8066     glActiveTexture(GL_TEXTURE0);
8067     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8068     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
8069     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8070     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8071     EXPECT_GL_NO_ERROR();
8072 
8073     drawQuad(mProgram, "position", 0.5f);
8074 
8075     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8076 }
8077 
8078 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8079 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBSNORMImplicitAlpha1)8080 TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
8081 {
8082     glActiveTexture(GL_TEXTURE0);
8083     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8084     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
8085     EXPECT_GL_NO_ERROR();
8086 
8087     drawQuad(mProgram, "position", 0.5f);
8088 
8089     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8090 }
8091 
8092 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8093 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGB9E5ImplicitAlpha1)8094 TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
8095 {
8096     glActiveTexture(GL_TEXTURE0);
8097     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8098     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
8099                  nullptr);
8100     EXPECT_GL_NO_ERROR();
8101 
8102     drawQuad(mProgram, "position", 0.5f);
8103 
8104     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8105 }
8106 
8107 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8108 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)8109 TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
8110 {
8111     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
8112     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
8113 
8114     glActiveTexture(GL_TEXTURE0);
8115     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8116     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
8117     EXPECT_GL_NO_ERROR();
8118 
8119     drawQuad(mProgram, "position", 0.5f);
8120 
8121     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8122 }
8123 
8124 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8125 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)8126 TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
8127 {
8128     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
8129     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
8130 
8131     glActiveTexture(GL_TEXTURE0);
8132     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8133     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
8134     EXPECT_GL_NO_ERROR();
8135 
8136     drawQuad(mProgram, "position", 0.5f);
8137 
8138     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8139 }
8140 
8141 // ETC2 punchthrough alpha formats must be initialized to opaque black when emulated
8142 // http://anglebug.com/42265413
TEST_P(Texture2DTestES3RobustInit,TextureCOMPRESSEDRGB8A1ETC2)8143 TEST_P(Texture2DTestES3RobustInit, TextureCOMPRESSEDRGB8A1ETC2)
8144 {
8145     glActiveTexture(GL_TEXTURE0);
8146     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8147     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 1, 1, 0,
8148                            8, nullptr);
8149     EXPECT_GL_NO_ERROR();
8150 
8151     drawQuad(mProgram, "position", 0.5f);
8152 
8153     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8154 }
8155 
8156 // ETC2 punchthrough alpha formats must be initialized to opaque black when emulated
8157 // http://anglebug.com/42265413
TEST_P(Texture2DTestES3RobustInit,TextureCOMPRESSEDSRGB8A1ETC2)8158 TEST_P(Texture2DTestES3RobustInit, TextureCOMPRESSEDSRGB8A1ETC2)
8159 {
8160     glActiveTexture(GL_TEXTURE0);
8161     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8162     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 1, 1, 0,
8163                            8, nullptr);
8164     EXPECT_GL_NO_ERROR();
8165 
8166     drawQuad(mProgram, "position", 0.5f);
8167 
8168     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8169 }
8170 
8171 // Test that compressed textures ignore the pixel unpack state.
8172 // (https://crbug.org/1267496)
TEST_P(Texture2DTestES3,PixelUnpackStateTexImage)8173 TEST_P(Texture2DTestES3, PixelUnpackStateTexImage)
8174 {
8175     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
8176                        !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
8177 
8178     glPixelStorei(GL_UNPACK_ROW_LENGTH, 9);
8179     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8180 
8181     uint8_t data[64] = {0};
8182     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 8, 8, 0, 64, data);
8183     EXPECT_GL_NO_ERROR();
8184 }
8185 
8186 // Test that compressed textures ignore the pixel unpack state.
8187 // (https://crbug.org/1267496)
TEST_P(Texture2DTestES3,PixelUnpackStateTexSubImage)8188 TEST_P(Texture2DTestES3, PixelUnpackStateTexSubImage)
8189 {
8190     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
8191                        !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
8192 
8193     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8194 
8195     uint8_t data[64] = {0};
8196     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 8, 8, 0, 64, data);
8197     EXPECT_GL_NO_ERROR();
8198 
8199     glPixelStorei(GL_UNPACK_ROW_LENGTH, 9);
8200 
8201     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 64,
8202                               data);
8203     EXPECT_GL_NO_ERROR();
8204 }
8205 
8206 // Test for http://anglebug.com/42265405.
TEST_P(Texture2DTestES3,TextureRGBUpdateWithPBO)8207 TEST_P(Texture2DTestES3, TextureRGBUpdateWithPBO)
8208 {
8209     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
8210 
8211     glViewport(0, 0, 16, 16);
8212 
8213     GLTexture tex1;
8214     std::vector<GLColor> texDataRed(16u * 16u, GLColor::red);
8215     std::vector<GLColor> texDataGreen(16u * 16u, GLColor::green);
8216 
8217     glBindTexture(GL_TEXTURE_2D, tex1);
8218     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
8219     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, texDataRed.data());
8220     ASSERT_GL_NO_ERROR();
8221 
8222     GLBuffer pbo;
8223     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
8224     glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, texDataGreen.data(), GL_STATIC_DRAW);
8225     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
8226     ASSERT_GL_NO_ERROR();
8227 
8228     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8229     ASSERT_GL_NO_ERROR();
8230 
8231     glBindTexture(GL_TEXTURE_2D, 0);
8232     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
8233     EXPECT_PIXEL_COLOR_EQ(4, 4, GLColor::green);
8234 }
8235 
8236 // Copied from Texture2DTest::TexStorage
8237 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
8238 // default color.
TEST_P(Texture2DTestES31PPO,TexStorage)8239 TEST_P(Texture2DTestES31PPO, TexStorage)
8240 {
8241     ANGLE_SKIP_TEST_IF(!IsVulkan());
8242     ANGLE_SKIP_TEST_IF((getClientMajorVersion() < 3 && getClientMinorVersion() < 1) &&
8243                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
8244 
8245     const char *vertexShaderSource   = getVertexShaderSource();
8246     const char *fragmentShaderSource = getFragmentShaderSource();
8247 
8248     bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
8249     mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
8250 
8251     int width  = getWindowWidth();
8252     int height = getWindowHeight();
8253 
8254     GLTexture tex2D;
8255     glActiveTexture(GL_TEXTURE0);
8256     glBindTexture(GL_TEXTURE_2D, tex2D);
8257 
8258     // Fill with red
8259     std::vector<GLubyte> pixels(3 * 16 * 16);
8260     for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
8261     {
8262         pixels[pixelId * 3 + 0] = 255;
8263         pixels[pixelId * 3 + 1] = 0;
8264         pixels[pixelId * 3 + 2] = 0;
8265     }
8266 
8267     // ANGLE internally uses RGBA as the internal format for RGB images, therefore glTexStorage2DEXT
8268     // initializes the image to a default color to get a consistent alpha color. The data is kept in
8269     // a CPU-side image and the image is marked as dirty.
8270     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
8271 
8272     // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
8273     // glTexSubImage2D should take into account that the image is dirty.
8274     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
8275     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8276     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8277 
8278     glActiveShaderProgram(mPipeline, mFragProg);
8279     glUniform1i(mTexture2DUniformLocation, 0);
8280 
8281     std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
8282     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8283 
8284     EXPECT_GL_NO_ERROR();
8285     EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
8286 
8287     // Validate that the region of the texture without data has an alpha of 1.0
8288     angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
8289     EXPECT_EQ(255, pixel.A);
8290 }
8291 
8292 // Copied from Texture2DTestES3::SingleTextureMultipleSamplers
8293 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES31PPO,SingleTextureMultipleSamplers)8294 TEST_P(Texture2DTestES31PPO, SingleTextureMultipleSamplers)
8295 {
8296     ANGLE_SKIP_TEST_IF(!IsVulkan());
8297 
8298     const char *vertexShaderSource   = getVertexShaderSource();
8299     const char *fragmentShaderSource = getFragmentShaderSource();
8300 
8301     bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
8302     mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
8303 
8304     GLint maxTextureUnits = 0;
8305     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
8306     ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
8307 
8308     constexpr int kSize                 = 16;
8309     std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
8310 
8311     // Make a single-level texture, fill it with red.
8312     std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
8313     GLTexture tex;
8314     glBindTexture(GL_TEXTURE_2D, tex);
8315     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8316                  redColors.data());
8317     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8318     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8319 
8320     // Simple confidence check.
8321     bind2DTexturedQuadProgramPipeline();
8322     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8323     ASSERT_GL_NO_ERROR();
8324     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
8325 
8326     // Bind texture to unit 1 with a sampler object making it incomplete.
8327     GLSampler sampler;
8328     glBindSampler(0, sampler);
8329     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8330     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8331 
8332     // Make a mipmap texture, fill it with blue.
8333     std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
8334     GLTexture mipmapTex;
8335     glBindTexture(GL_TEXTURE_2D, mipmapTex);
8336     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8337                  blueColors.data());
8338     glGenerateMipmap(GL_TEXTURE_2D);
8339 
8340     // Draw with the sampler, expect blue.
8341     draw2DTexturedQuad(0.5f, 1.0f, true);
8342     ASSERT_GL_NO_ERROR();
8343     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
8344 
8345     // Simple multitexturing program.
8346     constexpr char kVS[] =
8347         "#version 310 es\n"
8348         "precision mediump float;\n"
8349         "in vec2 position;\n"
8350         "out vec2 texCoord;\n"
8351         "void main()\n"
8352         "{\n"
8353         "    gl_Position = vec4(position, 0, 1);\n"
8354         "    texCoord = position * 0.5 + vec2(0.5);\n"
8355         "}";
8356 
8357     constexpr char kFS[] =
8358         "#version 310 es\n"
8359         "precision mediump float;\n"
8360         "in vec2 texCoord;\n"
8361         "uniform sampler2D tex1;\n"
8362         "uniform sampler2D tex2;\n"
8363         "uniform sampler2D tex3;\n"
8364         "uniform sampler2D tex4;\n"
8365         "out vec4 color;\n"
8366         "void main()\n"
8367         "{\n"
8368         "    color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
8369         "          +  texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
8370         "}";
8371 
8372     bindProgramPipeline(kVS, kFS);
8373 
8374     std::array<GLint, 4> texLocations = {
8375         {glGetUniformLocation(mFragProg, "tex1"), glGetUniformLocation(mFragProg, "tex2"),
8376          glGetUniformLocation(mFragProg, "tex3"), glGetUniformLocation(mFragProg, "tex4")}};
8377     for (GLint location : texLocations)
8378     {
8379         ASSERT_NE(-1, location);
8380     }
8381 
8382     // Init the uniform data.
8383     glActiveShaderProgram(mPipeline, mFragProg);
8384     for (GLint location = 0; location < 4; ++location)
8385     {
8386         glUniform1i(texLocations[location], location);
8387     }
8388 
8389     // Initialize four samplers
8390     GLSampler samplers[4];
8391 
8392     // 0: non-mipped.
8393     glBindSampler(0, samplers[0]);
8394     glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8395     glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8396 
8397     // 1: mipped.
8398     glBindSampler(1, samplers[1]);
8399     glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8400     glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8401 
8402     // 2: non-mipped.
8403     glBindSampler(2, samplers[2]);
8404     glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8405     glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8406 
8407     // 3: mipped.
8408     glBindSampler(3, samplers[3]);
8409     glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8410     glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8411 
8412     // Bind two blue mipped textures and two single layer textures, should all draw.
8413     glActiveTexture(GL_TEXTURE0);
8414     glBindTexture(GL_TEXTURE_2D, tex);
8415 
8416     glActiveTexture(GL_TEXTURE1);
8417     glBindTexture(GL_TEXTURE_2D, mipmapTex);
8418 
8419     glActiveTexture(GL_TEXTURE2);
8420     glBindTexture(GL_TEXTURE_2D, tex);
8421 
8422     glActiveTexture(GL_TEXTURE3);
8423     glBindTexture(GL_TEXTURE_2D, mipmapTex);
8424 
8425     ASSERT_GL_NO_ERROR();
8426 
8427     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8428     ASSERT_GL_NO_ERROR();
8429     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
8430 
8431     // Bind four single layer textures, two should be incomplete.
8432     glActiveTexture(GL_TEXTURE1);
8433     glBindTexture(GL_TEXTURE_2D, tex);
8434 
8435     glActiveTexture(GL_TEXTURE3);
8436     glBindTexture(GL_TEXTURE_2D, tex);
8437 
8438     ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8439     ASSERT_GL_NO_ERROR();
8440     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
8441 }
8442 
8443 // Use a sampler in a uniform struct.
TEST_P(SamplerInStructTest,SamplerInStruct)8444 TEST_P(SamplerInStructTest, SamplerInStruct)
8445 {
8446     runSamplerInStructTest();
8447 }
8448 
8449 // Use a sampler in a uniform struct that's passed as a function parameter.
TEST_P(SamplerInStructAsFunctionParameterTest,SamplerInStructAsFunctionParameter)8450 TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
8451 {
8452     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/42260422
8453     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
8454 
8455     runSamplerInStructTest();
8456 }
8457 
8458 // Use a sampler in a uniform struct array with a struct from the array passed as a function
8459 // parameter.
TEST_P(SamplerInStructArrayAsFunctionParameterTest,SamplerInStructArrayAsFunctionParameter)8460 TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
8461 {
8462     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/42260422
8463     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
8464 
8465     runSamplerInStructTest();
8466 }
8467 
8468 // Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
8469 // parameter.
TEST_P(SamplerInNestedStructAsFunctionParameterTest,SamplerInNestedStructAsFunctionParameter)8470 TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
8471 {
8472     // Fails on Nexus 5X due to a driver bug. http://anglebug.com/42260422
8473     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
8474 
8475     runSamplerInStructTest();
8476 }
8477 
8478 // Make sure that there isn't a name conflict between sampler extracted from a struct and a
8479 // similarly named uniform.
TEST_P(SamplerInStructAndOtherVariableTest,SamplerInStructAndOtherVariable)8480 TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
8481 {
8482     runSamplerInStructTest();
8483 }
8484 
8485 // GL_EXT_texture_filter_anisotropic
8486 class TextureAnisotropyTest : public Texture2DTest
8487 {
8488   protected:
uploadTexture()8489     void uploadTexture()
8490     {
8491         glActiveTexture(GL_TEXTURE0);
8492         glBindTexture(GL_TEXTURE_2D, mTexture2D);
8493         GLColor texDataRed[1] = {GLColor::red};
8494         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
8495         EXPECT_GL_NO_ERROR();
8496     }
8497 };
8498 
8499 // Tests that setting anisotropic filtering doesn't cause failures at draw time.
TEST_P(TextureAnisotropyTest,AnisotropyFunctional)8500 TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
8501 {
8502     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
8503 
8504     setUpProgram();
8505 
8506     uploadTexture();
8507 
8508     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8509     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8510     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
8511     EXPECT_GL_NO_ERROR();
8512 
8513     drawQuad(mProgram, "position", 0.5f);
8514 
8515     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8516     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
8517     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
8518 }
8519 
8520 // GL_OES_texture_border_clamp
8521 class TextureBorderClampTest : public Texture2DTest
8522 {
8523   protected:
TextureBorderClampTest()8524     TextureBorderClampTest() : Texture2DTest() {}
8525 
getVertexShaderSource()8526     const char *getVertexShaderSource() override
8527     {
8528         return
8529             R"(precision highp float;
8530             attribute vec4 position;
8531             varying vec2 texcoord;
8532 
8533             void main()
8534             {
8535                 gl_Position = vec4(position.xy, 0.0, 1.0);
8536                 // texcoords in [-0.5, 1.5]
8537                 texcoord = (position.xy) + 0.5;
8538             })";
8539     }
8540 
uploadTexture()8541     void uploadTexture()
8542     {
8543         glActiveTexture(GL_TEXTURE0);
8544         glBindTexture(GL_TEXTURE_2D, mTexture2D);
8545         std::vector<GLColor> texDataRed(1, GLColor::red);
8546         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8547                      texDataRed.data());
8548         EXPECT_GL_NO_ERROR();
8549     }
8550 
testFormat(GLenum format,GLenum type,GLColor32F borderColor)8551     void testFormat(GLenum format, GLenum type, GLColor32F borderColor)
8552     {
8553         glBindTexture(GL_TEXTURE_2D, mTexture2D);
8554         glActiveTexture(GL_TEXTURE0);
8555         glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor.R);
8556         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8557         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8558         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8559         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8560         glTexImage2D(GL_TEXTURE_2D, 0, format, 2, 2, 0, format, type, nullptr);
8561         drawQuad(mProgram, "position", 0.5f);
8562     }
8563 
testCompressedFormat(GLenum format,GLsizei size,GLColor32F borderColor)8564     void testCompressedFormat(GLenum format, GLsizei size, GLColor32F borderColor)
8565     {
8566         setUpProgram();
8567         glBindTexture(GL_TEXTURE_2D, mTexture2D);
8568         glActiveTexture(GL_TEXTURE0);
8569         glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor.R);
8570         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8571         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8572         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8573         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8574         glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, 4, 4, 0, size, nullptr);
8575         drawQuad(mProgram, "position", 0.5f);
8576     }
8577 };
8578 
8579 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
8580 // GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional)8581 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
8582 {
8583     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8584 
8585     setUpProgram();
8586 
8587     uploadTexture();
8588 
8589     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8590     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8591     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8592     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8593     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8594     EXPECT_GL_NO_ERROR();
8595 
8596     drawQuad(mProgram, "position", 0.5f);
8597 
8598     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8599     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8600     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
8601 }
8602 
8603 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional2)8604 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
8605 {
8606     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8607 
8608     glActiveTexture(GL_TEXTURE0);
8609     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8610 
8611     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8612 
8613     GLint colorFixedPoint[4] = {0};
8614     glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
8615     constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
8616                                                std::numeric_limits<GLint>::max()};
8617     EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
8618     EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
8619     EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
8620     EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
8621 
8622     constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
8623                                               std::numeric_limits<GLint>::max()};
8624     glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
8625 
8626     GLfloat color[4] = {0.0f};
8627     glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
8628     EXPECT_EQ(color[0], kFloatBlue.R);
8629     EXPECT_EQ(color[1], kFloatBlue.G);
8630     EXPECT_EQ(color[2], kFloatBlue.B);
8631     EXPECT_EQ(color[3], kFloatBlue.A);
8632 }
8633 
8634 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampValidation)8635 TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
8636 {
8637     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8638 
8639     glActiveTexture(GL_TEXTURE0);
8640     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8641 
8642     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
8643     EXPECT_GL_ERROR(GL_INVALID_ENUM);
8644 
8645     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
8646     EXPECT_GL_ERROR(GL_INVALID_ENUM);
8647 
8648     glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8649     EXPECT_GL_ERROR(GL_INVALID_ENUM);
8650 
8651     GLint colorInt[4] = {0};
8652     glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
8653     EXPECT_GL_ERROR(GL_INVALID_ENUM);
8654 
8655     if (getClientMajorVersion() < 3)
8656     {
8657         glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
8658         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8659         glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
8660         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8661 
8662         GLuint colorUInt[4] = {0};
8663         glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
8664         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8665         glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
8666         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8667 
8668         GLSampler sampler;
8669         glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
8670         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8671         glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
8672         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8673 
8674         glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
8675         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8676         glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
8677         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8678     }
8679 }
8680 
8681 // Test GL_TEXTURE_BORDER_COLOR parameter with unorm formats.
TEST_P(TextureBorderClampTest,TextureBorderClampUnorm8)8682 TEST_P(TextureBorderClampTest, TextureBorderClampUnorm8)
8683 {
8684     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8685 
8686     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8687 
8688     setUpProgram();
8689 
8690     testFormat(GL_ALPHA, GL_UNSIGNED_BYTE, kBorder);
8691     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8692 
8693     testFormat(GL_RGB, GL_UNSIGNED_BYTE, kBorder);
8694     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8695 
8696     testFormat(GL_RGBA, GL_UNSIGNED_BYTE, kBorder);
8697     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8698 
8699     testFormat(GL_LUMINANCE, GL_UNSIGNED_BYTE, kBorder);
8700     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 255), 1);
8701 
8702     testFormat(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, kBorder);
8703     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8704 }
8705 
8706 // Test GL_TEXTURE_BORDER_COLOR parameter with sRGB formats.
TEST_P(TextureBorderClampTest,TextureBorderClampSrgb)8707 TEST_P(TextureBorderClampTest, TextureBorderClampSrgb)
8708 {
8709     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8710     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB"));
8711 
8712     // AMD D3D9 drivers always sample sRGB formats with (0, 0, 0, 0) border color, won't fix.
8713     ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
8714 
8715     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8716 
8717     setUpProgram();
8718 
8719     testFormat(GL_SRGB_EXT, GL_UNSIGNED_BYTE, kBorder);
8720     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8721 
8722     testFormat(GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, kBorder);
8723     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8724 }
8725 
8726 // Test GL_TEXTURE_BORDER_COLOR parameter with half-float formats.
TEST_P(TextureBorderClampTest,TextureBorderClampFloat16)8727 TEST_P(TextureBorderClampTest, TextureBorderClampFloat16)
8728 {
8729     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8730     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
8731 
8732     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8733 
8734     setUpProgram();
8735 
8736     testFormat(GL_ALPHA, GL_HALF_FLOAT_OES, kBorder);
8737     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8738 
8739     testFormat(GL_RGB, GL_HALF_FLOAT_OES, kBorder);
8740     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8741 
8742     testFormat(GL_RGBA, GL_HALF_FLOAT_OES, kBorder);
8743     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8744 
8745     testFormat(GL_LUMINANCE, GL_HALF_FLOAT_OES, kBorder);
8746     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 255), 1);
8747 
8748     testFormat(GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, kBorder);
8749     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8750 }
8751 
8752 // Test GL_TEXTURE_BORDER_COLOR parameter with float formats.
TEST_P(TextureBorderClampTest,TextureBorderClampFloat32)8753 TEST_P(TextureBorderClampTest, TextureBorderClampFloat32)
8754 {
8755     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8756     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
8757 
8758     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8759 
8760     setUpProgram();
8761 
8762     testFormat(GL_ALPHA, GL_FLOAT, kBorder);
8763     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8764 
8765     testFormat(GL_RGB, GL_FLOAT, kBorder);
8766     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8767 
8768     testFormat(GL_RGBA, GL_FLOAT, kBorder);
8769     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8770 
8771     testFormat(GL_LUMINANCE, GL_FLOAT, kBorder);
8772     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 255), 1);
8773 
8774     testFormat(GL_LUMINANCE_ALPHA, GL_FLOAT, kBorder);
8775     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8776 }
8777 
8778 // Test GL_TEXTURE_BORDER_COLOR parameter with red and red-green formats.
TEST_P(TextureBorderClampTest,TextureBorderClampRG)8779 TEST_P(TextureBorderClampTest, TextureBorderClampRG)
8780 {
8781     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8782     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
8783 
8784     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8785 
8786     setUpProgram();
8787 
8788     testFormat(GL_RED_EXT, GL_UNSIGNED_BYTE, kBorder);
8789     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
8790 
8791     testFormat(GL_RG_EXT, GL_UNSIGNED_BYTE, kBorder);
8792     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 0, 255), 1);
8793 
8794     if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
8795     {
8796         testFormat(GL_RED_EXT, GL_HALF_FLOAT_OES, kBorder);
8797         EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
8798 
8799         testFormat(GL_RG_EXT, GL_HALF_FLOAT_OES, kBorder);
8800         EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 0, 255), 1);
8801     }
8802 
8803     if (IsGLExtensionEnabled("GL_OES_texture_float"))
8804     {
8805         testFormat(GL_RED_EXT, GL_FLOAT, kBorder);
8806         EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
8807 
8808         testFormat(GL_RG_EXT, GL_FLOAT, kBorder);
8809         EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 0, 255), 1);
8810     }
8811 }
8812 
8813 // Test GL_TEXTURE_BORDER_COLOR parameter with DXT1 formats.
TEST_P(TextureBorderClampTest,TextureBorderClampDXT1)8814 TEST_P(TextureBorderClampTest, TextureBorderClampDXT1)
8815 {
8816     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8817     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
8818 
8819     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8820 
8821     setUpProgram();
8822 
8823     testCompressedFormat(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, kBorder);
8824     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8825 
8826     testCompressedFormat(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, kBorder);
8827     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8828 }
8829 
8830 // Test GL_TEXTURE_BORDER_COLOR parameter with DXT1 sRGB formats.
TEST_P(TextureBorderClampTest,TextureBorderClampDXT1Srgb)8831 TEST_P(TextureBorderClampTest, TextureBorderClampDXT1Srgb)
8832 {
8833     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8834     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc_srgb"));
8835 
8836     // AMD D3D9 drivers always sample sRGB formats with (0, 0, 0, 0) border color, won't fix.
8837     ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
8838 
8839     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8840 
8841     setUpProgram();
8842 
8843     testCompressedFormat(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 8, kBorder);
8844     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8845 
8846     testCompressedFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 8, kBorder);
8847     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8848 }
8849 
8850 // Test GL_TEXTURE_BORDER_COLOR parameter with texture redefinition.
TEST_P(TextureBorderClampTest,Redefinition)8851 TEST_P(TextureBorderClampTest, Redefinition)
8852 {
8853     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8854 
8855     GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8856 
8857     setUpProgram();
8858 
8859     testFormat(GL_ALPHA, GL_UNSIGNED_BYTE, kBorder);
8860     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8861 
8862     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 2, 2, 0, GL_LUMINANCE_ALPHA,
8863                  GL_UNSIGNED_BYTE, nullptr);
8864     drawQuad(mProgram, "position", 0.5f);
8865     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8866 
8867     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8868     drawQuad(mProgram, "position", 0.5f);
8869     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8870 }
8871 
8872 class TextureBorderClampTestES3 : public TextureBorderClampTest
8873 {
8874   protected:
TextureBorderClampTestES3()8875     TextureBorderClampTestES3() : TextureBorderClampTest() {}
8876 };
8877 
8878 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
8879 // GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional)8880 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
8881 {
8882     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8883 
8884     setUpProgram();
8885 
8886     uploadTexture();
8887 
8888     GLSampler sampler;
8889     glBindSampler(0, sampler);
8890     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8891     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8892     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8893     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8894     glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8895     EXPECT_GL_NO_ERROR();
8896 
8897     drawQuad(mProgram, "position", 0.5f);
8898 
8899     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8900     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8901     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
8902 }
8903 
8904 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional2)8905 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
8906 {
8907     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8908 
8909     glActiveTexture(GL_TEXTURE0);
8910 
8911     GLSampler sampler;
8912     glBindSampler(0, sampler);
8913 
8914     glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8915 
8916     GLint colorFixedPoint[4] = {0};
8917     glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
8918     constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
8919                                                std::numeric_limits<GLint>::max()};
8920     EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
8921     EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
8922     EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
8923     EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
8924 
8925     constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
8926                                               std::numeric_limits<GLint>::max()};
8927     glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
8928 
8929     GLfloat color[4] = {0.0f};
8930     glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
8931     EXPECT_EQ(color[0], kFloatBlue.R);
8932     EXPECT_EQ(color[1], kFloatBlue.G);
8933     EXPECT_EQ(color[2], kFloatBlue.B);
8934     EXPECT_EQ(color[3], kFloatBlue.A);
8935 
8936     constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
8937     glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
8938     GLint colorInt[4] = {0};
8939     glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
8940     EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
8941     EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
8942     EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
8943     EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
8944 
8945     constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
8946     glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
8947     GLuint colorUInt[4] = {0};
8948     glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
8949     EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
8950     EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
8951     EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
8952     EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
8953 
8954     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8955 
8956     constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
8957     glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
8958     glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
8959     EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
8960     EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
8961     EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
8962     EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
8963 
8964     constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
8965     glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
8966     glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
8967     EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
8968     EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
8969     EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
8970     EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
8971 }
8972 
8973 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Validation)8974 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
8975 {
8976     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8977 
8978     glActiveTexture(GL_TEXTURE0);
8979 
8980     GLSampler sampler;
8981     glBindSampler(0, sampler);
8982 
8983     glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
8984     EXPECT_GL_ERROR(GL_INVALID_ENUM);
8985 
8986     glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
8987     EXPECT_GL_ERROR(GL_INVALID_ENUM);
8988 }
8989 
8990 // Test that format-specific adjustments are applied
8991 // when the border color type does not match the texture type.
TEST_P(TextureBorderClampTestES3,TextureBorderTypeMismatch)8992 TEST_P(TextureBorderClampTestES3, TextureBorderTypeMismatch)
8993 {
8994     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8995 
8996     glBindTexture(GL_TEXTURE_2D, mTexture2D);
8997     glActiveTexture(GL_TEXTURE0);
8998     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8999     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9000     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9001     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9002 
9003     GLColor32UI kBorder = {1, 2, 3, 0};
9004     glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kBorder.R);
9005     ASSERT_GL_NO_ERROR();
9006 
9007     setUpProgram();
9008 
9009     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
9010     drawQuad(mProgram, "position", 0.5f);
9011     EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
9012 }
9013 
9014 class TextureBorderClampIntegerTestES3 : public Texture2DTest
9015 {
9016   protected:
TextureBorderClampIntegerTestES3()9017     TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
9018 
getVertexShaderSource()9019     const char *getVertexShaderSource() override
9020     {
9021         return
9022             R"(#version 300 es
9023             out vec2 texcoord;
9024             in vec4 position;
9025 
9026             void main()
9027             {
9028                 gl_Position = vec4(position.xy, 0.0, 1.0);
9029                 // texcoords in [-0.5, 1.5]
9030                 texcoord = (position.xy) + 0.5;
9031             })";
9032     }
9033 
getFragmentShaderSource()9034     const char *getFragmentShaderSource() override
9035     {
9036         if (isUnsignedIntTest)
9037         {
9038             return "#version 300 es\n"
9039                    "precision highp float;\n"
9040                    "uniform highp usampler2D tex;\n"
9041                    "in vec2 texcoord;\n"
9042                    "out vec4 fragColor;\n"
9043 
9044                    "void main()\n"
9045                    "{\n"
9046                    "vec4 red   = vec4(1.0, 0.0, 0.0, 1.0);\n"
9047                    "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
9048                    "fragColor = (texture(tex, texcoord).r == 150u)"
9049                    "            ? green : red;\n"
9050                    "}\n";
9051         }
9052         else
9053         {
9054             return "#version 300 es\n"
9055                    "precision highp float;\n"
9056                    "uniform highp isampler2D tex;\n"
9057                    "in vec2 texcoord;\n"
9058                    "out vec4 fragColor;\n"
9059 
9060                    "void main()\n"
9061                    "{\n"
9062                    "vec4 red   = vec4(1.0, 0.0, 0.0, 1.0);\n"
9063                    "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
9064                    "fragColor = (texture(tex, texcoord).r == -50)"
9065                    "            ? green : red;\n"
9066                    "}\n";
9067         }
9068     }
9069 
uploadTexture()9070     void uploadTexture()
9071     {
9072         glActiveTexture(GL_TEXTURE0);
9073         glBindTexture(GL_TEXTURE_2D, mTexture2D);
9074         if (isUnsignedIntTest)
9075         {
9076             std::vector<GLubyte> texData(4, 100);
9077             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
9078                          texData.data());
9079         }
9080         else
9081         {
9082             std::vector<GLbyte> texData(4, 100);
9083             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
9084                          texData.data());
9085         }
9086         EXPECT_GL_NO_ERROR();
9087     }
9088 
9089     bool isUnsignedIntTest;
9090 };
9091 
9092 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
9093 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger)9094 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
9095 {
9096     // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/40096617
9097     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
9098 
9099     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9100 
9101     setUpProgram();
9102 
9103     uploadTexture();
9104 
9105     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9106     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9107     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9108     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9109 
9110     constexpr GLint borderColor[4] = {-50, -50, -50, -50};
9111     glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
9112 
9113     EXPECT_GL_NO_ERROR();
9114 
9115     drawQuad(mProgram, "position", 0.5f);
9116 
9117     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9118     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9119     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9120 }
9121 
9122 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
9123 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger2)9124 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
9125 {
9126     // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/40096617
9127     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
9128 
9129     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9130 
9131     setUpProgram();
9132 
9133     uploadTexture();
9134 
9135     GLSampler sampler;
9136     glBindSampler(0, sampler);
9137     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9138     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9139     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9140     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9141 
9142     constexpr GLint borderColor[4] = {-50, -50, -50, -50};
9143     glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
9144 
9145     EXPECT_GL_NO_ERROR();
9146 
9147     drawQuad(mProgram, "position", 0.5f);
9148 
9149     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9150     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9151     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9152 }
9153 
9154 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
9155 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned)9156 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
9157 {
9158     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9159 
9160     isUnsignedIntTest = true;
9161 
9162     setUpProgram();
9163 
9164     uploadTexture();
9165 
9166     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9167     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9168     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9169     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9170 
9171     constexpr GLuint borderColor[4] = {150, 150, 150, 150};
9172     glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
9173 
9174     EXPECT_GL_NO_ERROR();
9175 
9176     drawQuad(mProgram, "position", 0.5f);
9177 
9178     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9179     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9180     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9181 }
9182 
9183 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
9184 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
9185 // glSamplerParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned2)9186 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
9187 {
9188     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9189 
9190     isUnsignedIntTest = true;
9191 
9192     setUpProgram();
9193 
9194     uploadTexture();
9195 
9196     GLSampler sampler;
9197     glBindSampler(0, sampler);
9198     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9199     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9200     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9201     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9202 
9203     constexpr GLuint borderColor[4] = {150, 150, 150, 150};
9204     glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
9205 
9206     EXPECT_GL_NO_ERROR();
9207 
9208     drawQuad(mProgram, "position", 0.5f);
9209 
9210     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9211     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9212     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9213 }
9214 
9215 // ~GL_OES_texture_border_clamp
9216 
9217 // GL_EXT_texture_mirror_clamp_to_edge
9218 class TextureMirrorClampToEdgeTest : public Texture2DTest
9219 {
9220   protected:
TextureMirrorClampToEdgeTest()9221     TextureMirrorClampToEdgeTest() : Texture2DTest() {}
9222 
getVertexShaderSource()9223     const char *getVertexShaderSource() override
9224     {
9225         return R"(precision highp float;
9226 attribute vec4 position;
9227 varying vec2 texcoord;
9228 
9229 void main()
9230 {
9231     gl_Position = vec4(position.xy, 0.0, 1.0);
9232     texcoord = position.xy * 2.0;
9233 })";
9234     }
9235 
uploadTexture(bool isInteger,bool isSigned,GLuint sampler)9236     void uploadTexture(bool isInteger, bool isSigned, GLuint sampler)
9237     {
9238         glActiveTexture(GL_TEXTURE0);
9239         glBindTexture(GL_TEXTURE_2D, mTexture2D);
9240         if (isInteger && isSigned)
9241         {
9242             const int8_t data[] = {0, 0, 0, -1, -1, 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, -1};
9243             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 2, 2, 0, GL_RGBA_INTEGER, GL_BYTE, data);
9244         }
9245         else if (isInteger)
9246         {
9247             const uint8_t data[] = {0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1};
9248             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 2, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
9249                          data);
9250         }
9251         else
9252         {
9253             const uint8_t data[] = {0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255};
9254             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
9255         }
9256 
9257         if (sampler != 0)
9258         {
9259             glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9260             glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9261             glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9262             glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9263         }
9264         else
9265         {
9266             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9267             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9268             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9269             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9270         }
9271         ASSERT_GL_NO_ERROR();
9272     }
9273 
checkTextureSampling()9274     void checkTextureSampling()
9275     {
9276         auto screenX = [&](float x) { return getWindowWidth() * (x * 0.25 + 0.5); };
9277         auto screenY = [&](float y) { return getWindowHeight() * (y * 0.25 + 0.5); };
9278 
9279         // +S, +T
9280         EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(0.25), GLColor::black);
9281         EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(0.25), GLColor::red);
9282         EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(0.25), GLColor::red);
9283         EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(0.75), GLColor::green);
9284         EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(1.50), GLColor::green);
9285         EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(0.75), GLColor::blue);
9286         EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(0.75), GLColor::blue);
9287         EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(1.50), GLColor::blue);
9288         EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(1.50), GLColor::blue);
9289 
9290         // -S, +T
9291         EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(0.25), GLColor::black);
9292         EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(0.25), GLColor::red);
9293         EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(0.25), GLColor::red);
9294         EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(0.75), GLColor::green);
9295         EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(1.50), GLColor::green);
9296         EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(0.75), GLColor::blue);
9297         EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(0.75), GLColor::blue);
9298         EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(1.50), GLColor::blue);
9299         EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(1.50), GLColor::blue);
9300 
9301         // +S, -T
9302         EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(-0.25), GLColor::black);
9303         EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(-0.25), GLColor::red);
9304         EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(-0.25), GLColor::red);
9305         EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(-0.75), GLColor::green);
9306         EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(-1.50), GLColor::green);
9307         EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(-0.75), GLColor::blue);
9308         EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(-0.75), GLColor::blue);
9309         EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(-1.50), GLColor::blue);
9310         EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(-1.50), GLColor::blue);
9311 
9312         // -S, -T
9313         EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(-0.25), GLColor::black);
9314         EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(-0.25), GLColor::red);
9315         EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(-0.25), GLColor::red);
9316         EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(-0.75), GLColor::green);
9317         EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(-1.50), GLColor::green);
9318         EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(-0.75), GLColor::blue);
9319         EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(-0.75), GLColor::blue);
9320         EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(-1.50), GLColor::blue);
9321         EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(-1.50), GLColor::blue);
9322     }
9323 };
9324 
9325 // Test that the texture is correctly mirrored in negative directions
9326 // and clamped to edge pixels outside of the normalized range.
TEST_P(TextureMirrorClampToEdgeTest,TexParameter)9327 TEST_P(TextureMirrorClampToEdgeTest, TexParameter)
9328 {
9329     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9330 
9331     setUpProgram();
9332     uploadTexture(false, false, 0);
9333     drawQuad(mProgram, "position", 0.5f);
9334     ASSERT_GL_NO_ERROR();
9335 
9336     checkTextureSampling();
9337 }
9338 
9339 class TextureMirrorClampToEdgeTestES3 : public TextureMirrorClampToEdgeTest
9340 {
9341   protected:
TextureMirrorClampToEdgeTestES3()9342     TextureMirrorClampToEdgeTestES3() : TextureMirrorClampToEdgeTest() {}
9343 };
9344 
9345 // Test that the texture is correctly mirrored in negative directions and clamped
9346 // to edge pixels outside of the normalized range with mode set via glSamplerParameter.
TEST_P(TextureMirrorClampToEdgeTestES3,SamplerParameter)9347 TEST_P(TextureMirrorClampToEdgeTestES3, SamplerParameter)
9348 {
9349     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9350 
9351     GLSampler sampler;
9352     glBindSampler(0, sampler);
9353 
9354     setUpProgram();
9355     uploadTexture(false, false, sampler);
9356     drawQuad(mProgram, "position", 0.5f);
9357     ASSERT_GL_NO_ERROR();
9358 
9359     checkTextureSampling();
9360 }
9361 
9362 class TextureMirrorClampToEdgeIntegerTestES3 : public TextureMirrorClampToEdgeTestES3
9363 {
9364   protected:
TextureMirrorClampToEdgeIntegerTestES3()9365     TextureMirrorClampToEdgeIntegerTestES3() : TextureMirrorClampToEdgeTestES3() {}
9366 
getVertexShaderSource()9367     const char *getVertexShaderSource() override
9368     {
9369         return R"(#version 300 es
9370 precision highp float;
9371 in vec4 position;
9372 out vec2 texcoord;
9373 
9374 void main()
9375 {
9376     gl_Position = vec4(position.xy, 0.0, 1.0);
9377     texcoord = position.xy * 2.0;
9378 })";
9379     }
9380 
getFragmentShaderSource()9381     const char *getFragmentShaderSource() override
9382     {
9383         if (mIsSigned)
9384         {
9385             return R"(#version 300 es
9386 precision highp float;
9387 uniform highp isampler2D tex;
9388 in vec2 texcoord;
9389 out vec4 fragColor;
9390 void main() { fragColor = vec4(-texture(tex, texcoord)); })";
9391         }
9392         else
9393         {
9394             return R"(#version 300 es
9395 precision highp float;
9396 uniform highp usampler2D tex;
9397 in vec2 texcoord;
9398 out vec4 fragColor;
9399 void main() { fragColor = vec4(texture(tex, texcoord)); })";
9400         }
9401     }
9402 
9403     bool mIsSigned = false;
9404 };
9405 
9406 // Test that the texture is correctly mirrored in negative directions and clamped
9407 // to edge pixels outside of the normalized range with mode set with glTexParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,TexParameterSigned)9408 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, TexParameterSigned)
9409 {
9410     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9411 
9412     mIsSigned = true;
9413     setUpProgram();
9414     uploadTexture(true, true, 0);
9415     drawQuad(mProgram, "position", 0.5f);
9416     ASSERT_GL_NO_ERROR();
9417 
9418     checkTextureSampling();
9419 }
9420 
9421 // Test that the texture is correctly mirrored in negative directions and clamped
9422 // to edge pixels outside of the normalized range with mode set with glSamplerParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,SamplerParameterSigned)9423 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, SamplerParameterSigned)
9424 {
9425     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9426 
9427     GLSampler sampler;
9428     glBindSampler(0, sampler);
9429 
9430     mIsSigned = true;
9431     setUpProgram();
9432     uploadTexture(true, true, sampler);
9433     drawQuad(mProgram, "position", 0.5f);
9434     ASSERT_GL_NO_ERROR();
9435 
9436     checkTextureSampling();
9437 }
9438 
9439 // Test that the unsigned integer texture is correctly mirrored in negative directions and clamped
9440 // to edge pixels outside of the normalized range with mode set with glTexParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,TexParameterUnsigned)9441 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, TexParameterUnsigned)
9442 {
9443     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9444 
9445     setUpProgram();
9446     uploadTexture(true, false, 0);
9447     drawQuad(mProgram, "position", 0.5f);
9448     ASSERT_GL_NO_ERROR();
9449 
9450     checkTextureSampling();
9451 }
9452 
9453 // Test that the unsigned integer texture is correctly mirrored in negative directions and clamped
9454 // to edge pixels outside of the normalized range with mode set with glSamplerParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,SamplerParameterUnsigned)9455 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, SamplerParameterUnsigned)
9456 {
9457     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9458 
9459     GLSampler sampler;
9460     glBindSampler(0, sampler);
9461 
9462     setUpProgram();
9463     uploadTexture(true, false, sampler);
9464     drawQuad(mProgram, "position", 0.5f);
9465     ASSERT_GL_NO_ERROR();
9466 
9467     checkTextureSampling();
9468 }
9469 // ~GL_EXT_texture_mirror_clamp_to_edge
9470 
9471 class TextureLimitsTest : public ANGLETest<>
9472 {
9473   protected:
9474     struct RGBA8
9475     {
9476         uint8_t R, G, B, A;
9477     };
9478 
TextureLimitsTest()9479     TextureLimitsTest()
9480         : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
9481     {
9482         setWindowWidth(128);
9483         setWindowHeight(128);
9484         setConfigRedBits(8);
9485         setConfigGreenBits(8);
9486         setConfigBlueBits(8);
9487         setConfigAlphaBits(8);
9488     }
9489 
testSetUp()9490     void testSetUp() override
9491     {
9492         glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
9493         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
9494         glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
9495 
9496         ASSERT_GL_NO_ERROR();
9497     }
9498 
testTearDown()9499     void testTearDown() override
9500     {
9501         if (mProgram != 0)
9502         {
9503             glDeleteProgram(mProgram);
9504             mProgram = 0;
9505 
9506             if (!mTextures.empty())
9507             {
9508                 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
9509             }
9510         }
9511     }
9512 
compileProgramWithTextureCounts(const std::string & vertexPrefix,GLint vertexTextureCount,GLint vertexActiveTextureCount,const std::string & fragPrefix,GLint fragmentTextureCount,GLint fragmentActiveTextureCount)9513     void compileProgramWithTextureCounts(const std::string &vertexPrefix,
9514                                          GLint vertexTextureCount,
9515                                          GLint vertexActiveTextureCount,
9516                                          const std::string &fragPrefix,
9517                                          GLint fragmentTextureCount,
9518                                          GLint fragmentActiveTextureCount)
9519     {
9520         std::stringstream vertexShaderStr;
9521         vertexShaderStr << "attribute vec2 position;\n"
9522                         << "varying vec4 color;\n"
9523                         << "varying vec2 texCoord;\n";
9524 
9525         for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
9526         {
9527             vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
9528         }
9529 
9530         vertexShaderStr << "void main() {\n"
9531                         << "  gl_Position = vec4(position, 0, 1);\n"
9532                         << "  texCoord = (position * 0.5) + 0.5;\n"
9533                         << "  color = vec4(0);\n";
9534 
9535         for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
9536         {
9537             vertexShaderStr << "  color += texture2D(" << vertexPrefix << textureIndex
9538                             << ", texCoord);\n";
9539         }
9540 
9541         vertexShaderStr << "}";
9542 
9543         std::stringstream fragmentShaderStr;
9544         fragmentShaderStr << "varying mediump vec4 color;\n" << "varying mediump vec2 texCoord;\n";
9545 
9546         for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
9547         {
9548             fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
9549         }
9550 
9551         fragmentShaderStr << "void main() {\n" << "  gl_FragColor = color;\n";
9552 
9553         for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
9554         {
9555             fragmentShaderStr << "  gl_FragColor += texture2D(" << fragPrefix << textureIndex
9556                               << ", texCoord);\n";
9557         }
9558 
9559         fragmentShaderStr << "}";
9560 
9561         const std::string &vertexShaderSource   = vertexShaderStr.str();
9562         const std::string &fragmentShaderSource = fragmentShaderStr.str();
9563 
9564         mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
9565     }
9566 
getPixel(GLint texIndex)9567     RGBA8 getPixel(GLint texIndex)
9568     {
9569         RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
9570                        0, 255u};
9571         return pixel;
9572     }
9573 
initTextures(GLint tex2DCount,GLint texCubeCount)9574     void initTextures(GLint tex2DCount, GLint texCubeCount)
9575     {
9576         GLint totalCount = tex2DCount + texCubeCount;
9577         mTextures.assign(totalCount, 0);
9578         glGenTextures(totalCount, &mTextures[0]);
9579         ASSERT_GL_NO_ERROR();
9580 
9581         std::vector<RGBA8> texData(16 * 16);
9582 
9583         GLint texIndex = 0;
9584         for (; texIndex < tex2DCount; ++texIndex)
9585         {
9586             texData.assign(texData.size(), getPixel(texIndex));
9587             glActiveTexture(GL_TEXTURE0 + texIndex);
9588             glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
9589             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
9590                          &texData[0]);
9591             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9592             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9593             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9594             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9595         }
9596 
9597         ASSERT_GL_NO_ERROR();
9598 
9599         for (; texIndex < texCubeCount; ++texIndex)
9600         {
9601             texData.assign(texData.size(), getPixel(texIndex));
9602             glActiveTexture(GL_TEXTURE0 + texIndex);
9603             glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
9604             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9605                          GL_UNSIGNED_BYTE, &texData[0]);
9606             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9607                          GL_UNSIGNED_BYTE, &texData[0]);
9608             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9609                          GL_UNSIGNED_BYTE, &texData[0]);
9610             glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9611                          GL_UNSIGNED_BYTE, &texData[0]);
9612             glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9613                          GL_UNSIGNED_BYTE, &texData[0]);
9614             glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9615                          GL_UNSIGNED_BYTE, &texData[0]);
9616             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9617             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9618             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9619             glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9620         }
9621 
9622         ASSERT_GL_NO_ERROR();
9623     }
9624 
testWithTextures(GLint vertexTextureCount,const std::string & vertexTexturePrefix,GLint fragmentTextureCount,const std::string & fragmentTexturePrefix)9625     void testWithTextures(GLint vertexTextureCount,
9626                           const std::string &vertexTexturePrefix,
9627                           GLint fragmentTextureCount,
9628                           const std::string &fragmentTexturePrefix)
9629     {
9630         // Generate textures
9631         initTextures(vertexTextureCount + fragmentTextureCount, 0);
9632 
9633         glUseProgram(mProgram);
9634         RGBA8 expectedSum = {0};
9635         for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
9636         {
9637             std::stringstream uniformNameStr;
9638             uniformNameStr << vertexTexturePrefix << texIndex;
9639             const std::string &uniformName = uniformNameStr.str();
9640             GLint location                 = glGetUniformLocation(mProgram, uniformName.c_str());
9641             ASSERT_NE(-1, location);
9642 
9643             glUniform1i(location, texIndex);
9644             RGBA8 contribution = getPixel(texIndex);
9645             expectedSum.R += contribution.R;
9646             expectedSum.G += contribution.G;
9647         }
9648 
9649         for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
9650         {
9651             std::stringstream uniformNameStr;
9652             uniformNameStr << fragmentTexturePrefix << texIndex;
9653             const std::string &uniformName = uniformNameStr.str();
9654             GLint location                 = glGetUniformLocation(mProgram, uniformName.c_str());
9655             ASSERT_NE(-1, location);
9656 
9657             glUniform1i(location, texIndex + vertexTextureCount);
9658             RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
9659             expectedSum.R += contribution.R;
9660             expectedSum.G += contribution.G;
9661         }
9662 
9663         ASSERT_GE(256u, expectedSum.G);
9664 
9665         drawQuad(mProgram, "position", 0.5f);
9666         ASSERT_GL_NO_ERROR();
9667         EXPECT_PIXEL_NEAR(0, 0, expectedSum.R, expectedSum.G, 0, 255, 1);
9668     }
9669 
9670     GLuint mProgram;
9671     std::vector<GLuint> mTextures;
9672     GLint mMaxVertexTextures;
9673     GLint mMaxFragmentTextures;
9674     GLint mMaxCombinedTextures;
9675 };
9676 
9677 // Test rendering with the maximum vertex texture units.
TEST_P(TextureLimitsTest,MaxVertexTextures)9678 TEST_P(TextureLimitsTest, MaxVertexTextures)
9679 {
9680     compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
9681     ASSERT_NE(0u, mProgram);
9682     ASSERT_GL_NO_ERROR();
9683 
9684     testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
9685 }
9686 
9687 // Test rendering with the maximum fragment texture units.
TEST_P(TextureLimitsTest,MaxFragmentTextures)9688 TEST_P(TextureLimitsTest, MaxFragmentTextures)
9689 {
9690     compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
9691     ASSERT_NE(0u, mProgram);
9692     ASSERT_GL_NO_ERROR();
9693 
9694     testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
9695 }
9696 
9697 // Test rendering with maximum combined texture units.
TEST_P(TextureLimitsTest,MaxCombinedTextures)9698 TEST_P(TextureLimitsTest, MaxCombinedTextures)
9699 {
9700     GLint vertexTextures = mMaxVertexTextures;
9701 
9702     if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
9703     {
9704         vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
9705     }
9706 
9707     compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
9708                                     mMaxFragmentTextures, mMaxFragmentTextures);
9709     ASSERT_NE(0u, mProgram);
9710     ASSERT_GL_NO_ERROR();
9711 
9712     testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
9713 }
9714 
9715 // Negative test for exceeding the number of vertex textures
TEST_P(TextureLimitsTest,ExcessiveVertexTextures)9716 TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
9717 {
9718     compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
9719                                     0);
9720     ASSERT_EQ(0u, mProgram);
9721 }
9722 
9723 // Negative test for exceeding the number of fragment textures
TEST_P(TextureLimitsTest,ExcessiveFragmentTextures)9724 TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
9725 {
9726     compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
9727                                     mMaxFragmentTextures + 1);
9728     ASSERT_EQ(0u, mProgram);
9729 }
9730 
9731 // Test active vertex textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveVertexTextures)9732 TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
9733 {
9734     compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
9735     ASSERT_NE(0u, mProgram);
9736     ASSERT_GL_NO_ERROR();
9737 
9738     testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
9739 }
9740 
9741 // Test active fragment textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveFragmentTextures)9742 TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
9743 {
9744     compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
9745                                     mMaxFragmentTextures);
9746     ASSERT_NE(0u, mProgram);
9747     ASSERT_GL_NO_ERROR();
9748 
9749     testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
9750 }
9751 
9752 // Negative test for pointing two sampler uniforms of different types to the same texture.
9753 // GLES 2.0.25 section 2.10.4 page 39.
TEST_P(TextureLimitsTest,TextureTypeConflict)9754 TEST_P(TextureLimitsTest, TextureTypeConflict)
9755 {
9756     constexpr char kVS[] =
9757         "attribute vec2 position;\n"
9758         "varying float color;\n"
9759         "uniform sampler2D tex2D;\n"
9760         "uniform samplerCube texCube;\n"
9761         "void main() {\n"
9762         "  gl_Position = vec4(position, 0, 1);\n"
9763         "  vec2 texCoord = (position * 0.5) + 0.5;\n"
9764         "  color = texture2D(tex2D, texCoord).x;\n"
9765         "  color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
9766         "}";
9767     constexpr char kFS[] =
9768         "varying mediump float color;\n"
9769         "void main() {\n"
9770         "  gl_FragColor = vec4(color, 0, 0, 1);\n"
9771         "}";
9772 
9773     mProgram = CompileProgram(kVS, kFS);
9774     ASSERT_NE(0u, mProgram);
9775 
9776     initTextures(1, 0);
9777 
9778     glUseProgram(mProgram);
9779     GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
9780     ASSERT_NE(-1, tex2DLocation);
9781     GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
9782     ASSERT_NE(-1, texCubeLocation);
9783 
9784     glUniform1i(tex2DLocation, 0);
9785     glUniform1i(texCubeLocation, 0);
9786     ASSERT_GL_NO_ERROR();
9787 
9788     drawQuad(mProgram, "position", 0.5f);
9789     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
9790 }
9791 
9792 class Texture2DNorm16TestES3 : public Texture2DTestES3
9793 {
9794   protected:
Texture2DNorm16TestES3()9795     Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
9796 
testSetUp()9797     void testSetUp() override
9798     {
9799         Texture2DTestES3::testSetUp();
9800 
9801         glActiveTexture(GL_TEXTURE0);
9802         glGenTextures(3, mTextures);
9803         glGenFramebuffers(1, &mFBO);
9804         glGenRenderbuffers(1, &mRenderbuffer);
9805 
9806         for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
9807         {
9808             glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
9809             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9810             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9811         }
9812 
9813         glBindTexture(GL_TEXTURE_2D, 0);
9814 
9815         ASSERT_GL_NO_ERROR();
9816     }
9817 
testTearDown()9818     void testTearDown() override
9819     {
9820         glDeleteTextures(3, mTextures);
9821         glDeleteFramebuffers(1, &mFBO);
9822         glDeleteRenderbuffers(1, &mRenderbuffer);
9823 
9824         Texture2DTestES3::testTearDown();
9825     }
9826 
testNorm16Texture(GLint internalformat,GLenum format,GLenum type)9827     void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
9828     {
9829         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
9830 
9831         GLushort pixelValue  = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
9832         GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
9833 
9834         setUpProgram();
9835 
9836         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
9837         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
9838                                0);
9839 
9840         for (int i = 0; i < 2; ++i)
9841         {
9842             bool isSubImage = i == 1;
9843             SCOPED_TRACE("is subimage:" + std::to_string(isSubImage));
9844             glBindTexture(GL_TEXTURE_2D, mTextures[0]);
9845             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
9846 
9847             glBindTexture(GL_TEXTURE_2D, mTextures[1]);
9848             if (isSubImage)
9849             {
9850                 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, nullptr);
9851                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, format, type, imageData);
9852             }
9853             else
9854             {
9855                 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
9856             }
9857             EXPECT_GL_NO_ERROR();
9858 
9859             drawQuad(mProgram, "position", 0.5f);
9860 
9861             GLubyte expectedValue =
9862                 (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
9863 
9864             EXPECT_PIXEL_COLOR_EQ(0, 0,
9865                                   SliceFormatColor(format, GLColor(expectedValue, expectedValue,
9866                                                                    expectedValue, expectedValue)));
9867         }
9868         glBindFramebuffer(GL_FRAMEBUFFER, 0);
9869 
9870         ASSERT_GL_NO_ERROR();
9871     }
9872 
testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,GLuint y,GLuint width,GLuint height,GLint packRowLength,GLint packAlignment,GLint packSkipPixels,GLint packSkipRows,GLenum type,GLColor16 color)9873     void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
9874                                                       GLuint y,
9875                                                       GLuint width,
9876                                                       GLuint height,
9877                                                       GLint packRowLength,
9878                                                       GLint packAlignment,
9879                                                       GLint packSkipPixels,
9880                                                       GLint packSkipRows,
9881                                                       GLenum type,
9882                                                       GLColor16 color)
9883     {
9884         // PACK modes debugging
9885         GLint s = 2;  // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
9886         GLint n = 4;  // 4 components per pixel, stands for GL_RGBA
9887 
9888         GLuint l       = packRowLength == 0 ? width : packRowLength;
9889         const GLint &a = packAlignment;
9890 
9891         // According to
9892         // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
9893         GLint k                    = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
9894         std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
9895         if (static_cast<GLuint>(packRowLength) < width)
9896         {
9897             componentCount += width * n * s - k;
9898         }
9899 
9900         // Populate the pixels array with random dirty value
9901         constexpr GLushort kDirtyValue = 0x1234;
9902         std::vector<GLushort> pixels(componentCount, kDirtyValue);
9903         glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
9904 
9905         EXPECT_GL_NO_ERROR();
9906 
9907         GLushort *pixelRowStart = pixels.data();
9908         pixelRowStart += n * packSkipPixels + k * packSkipRows;
9909 
9910         std::vector<bool> modifiedPixels(componentCount, false);
9911 
9912         char errorInfo[200];
9913 
9914         for (GLuint row = 0; row < height; ++row)
9915         {
9916             GLushort *curPixel = pixelRowStart;
9917             for (GLuint col = 0, len = (row == height - 1) ? width : std::min(l, width); col < len;
9918                  ++col)
9919             {
9920                 snprintf(errorInfo, sizeof(errorInfo),
9921                          "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
9922                          "skipPixels: %d, skipRows: %d\n",
9923                          width, height, col, row, packRowLength, packAlignment, packSkipPixels,
9924                          packSkipRows);
9925                 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
9926                 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
9927                 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
9928                 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
9929 
9930                 std::ptrdiff_t diff      = curPixel - pixels.data();
9931                 modifiedPixels[diff + 0] = true;
9932                 modifiedPixels[diff + 1] = true;
9933                 modifiedPixels[diff + 2] = true;
9934                 modifiedPixels[diff + 3] = true;
9935 
9936                 curPixel += n;
9937             }
9938             pixelRowStart += k;
9939         }
9940 
9941         for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
9942         {
9943             if (!modifiedPixels[i])
9944             {
9945                 EXPECT_EQ(pixels[i], kDirtyValue);
9946             }
9947         }
9948     }
9949 
testNorm16RenderAndReadPixels(GLint internalformat,GLenum format,GLenum type)9950     void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
9951     {
9952         // TODO(http://anglebug.com/40096653) Fails on Win Intel OpenGL driver
9953         ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
9954         // TODO(http://anglebug.com/42262873) Fails on Win AMD OpenGL driver
9955         ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
9956         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
9957 
9958         GLushort pixelValue  = 0x6A35;
9959         GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
9960         GLColor16 color =
9961             SliceFormatColor16(format, GLColor16(pixelValue, pixelValue, pixelValue, pixelValue));
9962         // Size of drawing viewport
9963         constexpr GLint width = 8, height = 8;
9964 
9965         setUpProgram();
9966 
9967         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
9968         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
9969 
9970         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
9971         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
9972                                0);
9973 
9974         glBindTexture(GL_TEXTURE_2D, mTextures[2]);
9975         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
9976         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9977         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9978 
9979         EXPECT_GL_NO_ERROR();
9980 
9981         drawQuad(mProgram, "position", 0.5f);
9982 
9983         // ReadPixels against different width, height, pixel pack mode combinations to test
9984         // workaround of pixels rearrangement
9985 
9986         // {x, y, width, height}
9987         std::vector<std::array<GLint, 4>> areas = {
9988             {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
9989             {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
9990 
9991             {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
9992 
9993             {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
9994             {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
9995         };
9996 
9997         // Put default settings at the last
9998         std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
9999         std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
10000         std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1},   {1, 1},
10001                                                                          {3, 1}, {20, 20}, {0, 0}};
10002 
10003         // Restore pixel pack modes later
10004         GLint restorePackAlignment;
10005         glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
10006         GLint restorePackRowLength;
10007         glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
10008         GLint restorePackSkipPixels;
10009         glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
10010         GLint restorePackSkipRows;
10011         glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
10012 
10013         // Variable symbols are based on:
10014         // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
10015         for (const auto &skipped : paramsPackSkipPixelsAndRows)
10016         {
10017             glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
10018             glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
10019             for (GLint a : paramsPackAlignment)
10020             {
10021                 glPixelStorei(GL_PACK_ALIGNMENT, a);
10022                 for (GLint l : paramsPackRowLength)
10023                 {
10024                     glPixelStorei(GL_PACK_ROW_LENGTH, l);
10025 
10026                     for (const auto &area : areas)
10027                     {
10028                         ASSERT(area[0] + area[2] <= width);
10029                         ASSERT(area[1] + area[3] <= height);
10030                         testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
10031                                                                      area[3], l, a, skipped[0],
10032                                                                      skipped[1], type, color);
10033                     }
10034                 }
10035             }
10036         }
10037 
10038         glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
10039         glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
10040         glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
10041         glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
10042 
10043         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
10044         glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
10045         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10046                                   mRenderbuffer);
10047         glBindRenderbuffer(GL_RENDERBUFFER, 0);
10048         EXPECT_GL_NO_ERROR();
10049 
10050         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
10051         glClear(GL_COLOR_BUFFER_BIT);
10052 
10053         EXPECT_PIXEL_COLOR16_NEAR(
10054             0, 0, SliceFormatColor16(format, GLColor16(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)), 0);
10055 
10056         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
10057         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
10058 
10059         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
10060                                0);
10061         EXPECT_PIXEL_COLOR16_NEAR(
10062             0, 0, SliceFormatColor16(format, GLColor16(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)), 0);
10063 
10064         ASSERT_GL_NO_ERROR();
10065 
10066         glBindFramebuffer(GL_FRAMEBUFFER, 0);
10067     }
10068 
10069     GLuint mTextures[3];
10070     GLuint mFBO;
10071     GLuint mRenderbuffer;
10072 };
10073 
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16TextureTest)10074 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
10075 {
10076     testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
10077 }
10078 
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16SNORMTextureTest)10079 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
10080 {
10081     testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
10082 }
10083 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16TextureTest)10084 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
10085 {
10086     testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
10087 }
10088 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16SNORMTextureTest)10089 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
10090 {
10091     testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
10092 }
10093 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16TextureTest)10094 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
10095 {
10096     // (http://anglebug.com/40096662) Driver bug on some Qualcomm Adreno gpu
10097     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
10098 
10099     testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
10100 }
10101 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16SNORMTextureTest)10102 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
10103 {
10104     // (http://anglebug.com/40096662) Driver bug on some Qualcomm Adreno gpu
10105     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
10106 
10107     testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
10108 }
10109 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16TextureTest)10110 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
10111 {
10112     testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
10113 }
10114 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16SNORMTextureTest)10115 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
10116 {
10117     testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
10118 }
10119 
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16RenderTest)10120 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
10121 {
10122     // http://anglebug.com/42263714
10123     ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL() && IsNVIDIA());
10124 
10125     testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
10126 }
10127 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16RenderTest)10128 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
10129 {
10130     // http://anglebug.com/42263714
10131     ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL() && IsNVIDIA());
10132 
10133     testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
10134 }
10135 
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16RenderTest)10136 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
10137 {
10138     // http://anglebug.com/42263714
10139     ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL() && IsNVIDIA());
10140 
10141     testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
10142 }
10143 
10144 class Texture2DRGTest : public Texture2DTest
10145 {
10146   protected:
Texture2DRGTest()10147     Texture2DRGTest()
10148         : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
10149     {}
10150 
testSetUp()10151     void testSetUp() override
10152     {
10153         Texture2DTest::testSetUp();
10154 
10155         glActiveTexture(GL_TEXTURE0);
10156         glGenTextures(1, &mRenderableTexture);
10157         glGenTextures(1, &mTestTexture);
10158         glGenFramebuffers(1, &mFBO);
10159         glGenRenderbuffers(1, &mRenderbuffer);
10160 
10161         glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
10162         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10163         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10164         glBindTexture(GL_TEXTURE_2D, mTestTexture);
10165         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10166         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10167 
10168         glBindTexture(GL_TEXTURE_2D, 0);
10169 
10170         setUpProgram();
10171         glUseProgram(mProgram);
10172         glUniform1i(mTexture2DUniformLocation, 0);
10173 
10174         ASSERT_GL_NO_ERROR();
10175     }
10176 
testTearDown()10177     void testTearDown() override
10178     {
10179         glDeleteTextures(1, &mRenderableTexture);
10180         glDeleteTextures(1, &mTestTexture);
10181         glDeleteFramebuffers(1, &mFBO);
10182         glDeleteRenderbuffers(1, &mRenderbuffer);
10183 
10184         Texture2DTest::testTearDown();
10185     }
10186 
setupFormatTextures(GLenum internalformat,GLenum format,GLenum type,GLvoid * imageData)10187     void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
10188     {
10189         glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
10190         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
10191 
10192         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10193         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
10194                                mRenderableTexture, 0);
10195 
10196         glBindTexture(GL_TEXTURE_2D, mTestTexture);
10197         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
10198 
10199         EXPECT_GL_NO_ERROR();
10200     }
10201 
testRGTexture(GLColor expectedColor)10202     void testRGTexture(GLColor expectedColor)
10203     {
10204         drawQuad(mProgram, "position", 0.5f);
10205 
10206         EXPECT_GL_NO_ERROR();
10207         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
10208     }
10209 
testRGRender(GLenum internalformat,GLenum format)10210     void testRGRender(GLenum internalformat, GLenum format)
10211     {
10212         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
10213         glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
10214         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10215                                   mRenderbuffer);
10216         glBindRenderbuffer(GL_RENDERBUFFER, 0);
10217         EXPECT_GL_NO_ERROR();
10218 
10219         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
10220         glClear(GL_COLOR_BUFFER_BIT);
10221 
10222         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
10223 
10224         ASSERT_GL_NO_ERROR();
10225         EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
10226     }
10227 
10228     GLuint mRenderableTexture;
10229     GLuint mTestTexture;
10230     GLuint mFBO;
10231     GLuint mRenderbuffer;
10232 };
10233 
10234 // Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGUNormTest)10235 TEST_P(Texture2DRGTest, TextureRGUNormTest)
10236 {
10237     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
10238     // This workaround causes a GL error on Windows AMD, which is likely a driver bug.
10239     // The workaround is not intended to be enabled in this configuration so skip it.
10240     ANGLE_SKIP_TEST_IF(
10241         getEGLWindow()->isFeatureEnabled(Feature::EmulateCopyTexImage2DFromRenderbuffers) &&
10242         IsWindows() && IsAMD());
10243 
10244     GLubyte pixelValue  = 0xab;
10245     GLubyte imageData[] = {pixelValue, pixelValue};
10246 
10247     setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
10248     testRGTexture(
10249         SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
10250     testRGRender(GL_R8_EXT, GL_RED_EXT);
10251 
10252     setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
10253     testRGTexture(
10254         SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
10255     testRGRender(GL_RG8_EXT, GL_RG_EXT);
10256 }
10257 
10258 // Test float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGFloatTest)10259 TEST_P(Texture2DRGTest, TextureRGFloatTest)
10260 {
10261     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
10262     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10263 
10264     GLfloat pixelValue  = 0.54321;
10265     GLfloat imageData[] = {pixelValue, pixelValue};
10266 
10267     GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
10268     GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
10269 
10270     setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
10271     testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
10272 
10273     setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
10274     testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
10275 }
10276 
10277 // Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGHalfFloatTest)10278 TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
10279 {
10280     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
10281     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10282 
10283     GLfloat pixelValueFloat = 0.543f;
10284     GLhalf pixelValue       = 0x3858;
10285     GLhalf imageData[]      = {pixelValue, pixelValue};
10286 
10287     GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
10288     GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
10289 
10290     setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
10291     testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
10292 
10293     setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
10294     testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
10295 }
10296 
10297 class Texture2DFloatTest : public Texture2DTest
10298 {
10299   protected:
Texture2DFloatTest()10300     Texture2DFloatTest()
10301         : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
10302     {}
10303 
testSetUp()10304     void testSetUp() override
10305     {
10306         Texture2DTest::testSetUp();
10307 
10308         glActiveTexture(GL_TEXTURE0);
10309         glGenTextures(1, &mRenderableTexture);
10310         glGenTextures(1, &mTestTexture);
10311         glGenFramebuffers(1, &mFBO);
10312         glGenRenderbuffers(1, &mRenderbuffer);
10313 
10314         setUpProgram();
10315         glUseProgram(mProgram);
10316         glUniform1i(mTexture2DUniformLocation, 0);
10317 
10318         glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
10319         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
10320 
10321         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10322         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
10323                                mRenderableTexture, 0);
10324 
10325         ASSERT_GL_NO_ERROR();
10326     }
10327 
testTearDown()10328     void testTearDown() override
10329     {
10330         glDeleteTextures(1, &mRenderableTexture);
10331         glDeleteTextures(1, &mTestTexture);
10332         glDeleteFramebuffers(1, &mFBO);
10333         glDeleteRenderbuffers(1, &mRenderbuffer);
10334 
10335         Texture2DTest::testTearDown();
10336     }
10337 
testFloatTextureSample(GLenum internalFormat,GLenum format,GLenum type)10338     void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
10339     {
10340         constexpr GLfloat imageDataFloat[] = {
10341             0.2f,
10342             0.3f,
10343             0.4f,
10344             0.5f,
10345         };
10346         constexpr GLhalf imageDataHalf[] = {
10347             0x3266,
10348             0x34CD,
10349             0x3666,
10350             0x3800,
10351         };
10352         GLColor expectedValue;
10353         for (int i = 0; i < 4; i++)
10354         {
10355             expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
10356         }
10357 
10358         const GLvoid *imageData;
10359         switch (type)
10360         {
10361             case GL_FLOAT:
10362                 imageData = imageDataFloat;
10363                 break;
10364             case GL_HALF_FLOAT:
10365             case GL_HALF_FLOAT_OES:
10366                 imageData = imageDataHalf;
10367                 break;
10368             default:
10369                 imageData = nullptr;
10370         }
10371         ASSERT(imageData != nullptr);
10372 
10373         glBindTexture(GL_TEXTURE_2D, mTestTexture);
10374         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
10375 
10376         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10377         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10378 
10379         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10380         drawQuad(mProgram, "position", 0.5f);
10381 
10382         EXPECT_GL_NO_ERROR();
10383         EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
10384     }
10385 
testFloatTextureLinear(GLenum internalFormat,GLenum format,GLenum type)10386     void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
10387     {
10388         int numComponents;
10389         switch (format)
10390         {
10391             case GL_RGBA:
10392                 numComponents = 4;
10393                 break;
10394             case GL_RGB:
10395                 numComponents = 3;
10396                 break;
10397             case GL_LUMINANCE_ALPHA:
10398                 numComponents = 2;
10399                 break;
10400             case GL_LUMINANCE:
10401             case GL_ALPHA:
10402                 numComponents = 1;
10403                 break;
10404             default:
10405                 numComponents = 0;
10406         }
10407         ASSERT(numComponents > 0);
10408 
10409         constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
10410         constexpr GLhalf pixelIntensitiesHalf[]   = {0x0000, 0x3C00, 0x0000, 0x3C00};
10411 
10412         GLfloat imageDataFloat[16];
10413         GLhalf imageDataHalf[16];
10414         for (int i = 0; i < 4; i++)
10415         {
10416             for (int c = 0; c < numComponents; c++)
10417             {
10418                 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
10419                 imageDataHalf[i * numComponents + c]  = pixelIntensitiesHalf[i];
10420             }
10421         }
10422 
10423         const GLvoid *imageData;
10424         switch (type)
10425         {
10426             case GL_FLOAT:
10427                 imageData = imageDataFloat;
10428                 break;
10429             case GL_HALF_FLOAT:
10430             case GL_HALF_FLOAT_OES:
10431                 imageData = imageDataHalf;
10432                 break;
10433             default:
10434                 imageData = nullptr;
10435         }
10436         ASSERT(imageData != nullptr);
10437 
10438         glBindTexture(GL_TEXTURE_2D, mTestTexture);
10439         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
10440 
10441         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10442         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10443 
10444         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10445         drawQuad(mProgram, "position", 0.5f);
10446 
10447         EXPECT_GL_NO_ERROR();
10448         // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
10449         // should expect the final value to be gray (halfway in-between)
10450         EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
10451                                 kPixelTolerance);
10452     }
10453 
performFloatTextureRender(GLenum internalFormat,GLenum renderBufferFormat,GLenum format,GLenum type)10454     bool performFloatTextureRender(GLenum internalFormat,
10455                                    GLenum renderBufferFormat,
10456                                    GLenum format,
10457                                    GLenum type)
10458     {
10459         glBindTexture(GL_TEXTURE_2D, mTestTexture);
10460         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
10461         glBindTexture(GL_TEXTURE_2D, 0);
10462 
10463         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
10464         glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
10465         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10466                                   mRenderbuffer);
10467         glBindRenderbuffer(GL_RENDERBUFFER, 0);
10468         EXPECT_GL_NO_ERROR();
10469 
10470         if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
10471         {
10472             return false;
10473         }
10474 
10475         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10476 
10477         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
10478         glClear(GL_COLOR_BUFFER_BIT);
10479 
10480         EXPECT_GL_NO_ERROR();
10481         return true;
10482     }
10483 
10484     GLuint mRenderableTexture;
10485     GLuint mTestTexture;
10486     GLuint mFBO;
10487     GLuint mRenderbuffer;
10488 };
10489 
10490 class Texture2DFloatTestES3 : public Texture2DFloatTest
10491 {
10492   protected:
testFloatTextureRender(GLenum internalFormat,GLenum format,GLenum type)10493     void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
10494     {
10495         bool framebufferComplete =
10496             performFloatTextureRender(internalFormat, internalFormat, format, type);
10497         EXPECT_TRUE(framebufferComplete);
10498         EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
10499                                    SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
10500                                    kPixelTolerance32F);
10501     }
10502 };
10503 
10504 class Texture2DFloatTestES2 : public Texture2DFloatTest
10505 {
10506   protected:
checkFloatTextureRender(GLenum renderBufferFormat,GLenum format,GLenum type)10507     bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
10508     {
10509         bool framebufferComplete =
10510             performFloatTextureRender(format, renderBufferFormat, format, type);
10511 
10512         if (!framebufferComplete)
10513         {
10514             return false;
10515         }
10516 
10517         EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
10518                                    SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
10519                                    kPixelTolerance32F);
10520         return true;
10521     }
10522 };
10523 
10524 // Test texture sampling for ES3 float texture formats
TEST_P(Texture2DFloatTestES3,TextureFloatSampleBasicTest)10525 TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
10526 {
10527     testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
10528     testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
10529 }
10530 
10531 // Test texture sampling for ES2 float texture formats
TEST_P(Texture2DFloatTestES2,TextureFloatSampleBasicTest)10532 TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
10533 {
10534     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10535     testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
10536     testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
10537 }
10538 
10539 // Test texture sampling for ES3 half float texture formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleBasicTest)10540 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
10541 {
10542     testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
10543     testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
10544 }
10545 
10546 // Test texture sampling for ES2 half float texture formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleBasicTest)10547 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
10548 {
10549     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10550     testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
10551     testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
10552 }
10553 
10554 // Test texture sampling for legacy GLES 2.0 float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatSampleLegacyTest)10555 TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
10556 {
10557     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10558 
10559     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10560     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10561     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10562 
10563     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10564     {
10565         testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
10566         testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
10567         testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
10568     }
10569 }
10570 
10571 // Test texture sampling for legacy GLES 2.0 float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatSampleLegacyTest)10572 TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
10573 {
10574     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10575 
10576     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10577     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10578     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10579 }
10580 
10581 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleLegacyTest)10582 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
10583 {
10584     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10585 
10586     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10587     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10588     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10589 
10590     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10591     {
10592         testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
10593         testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
10594         testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
10595     }
10596 }
10597 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleLegacyTest)10598 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
10599 {
10600     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10601 
10602     testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10603     testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10604     testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10605 }
10606 
10607 // Test linear sampling for ES3 32F formats
TEST_P(Texture2DFloatTestES3,TextureFloatLinearTest)10608 TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
10609 {
10610     // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10611     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10612 
10613     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10614 
10615     testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
10616     testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
10617 }
10618 // Test linear sampling for ES2 32F formats
TEST_P(Texture2DFloatTestES2,TextureFloatLinearTest)10619 TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
10620 {
10621     // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10622     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10623 
10624     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10625 
10626     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10627 
10628     testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
10629 }
10630 
10631 // Test linear sampling for ES3 16F formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearTest)10632 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
10633 {
10634     // Half float formats must be linearly filterable in GLES 3.0 core
10635     testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
10636     testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
10637 }
10638 // Test linear sampling for ES2 16F formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearTest)10639 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
10640 {
10641     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
10642     testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
10643     testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
10644 }
10645 
10646 // Test linear sampling for legacy GLES 2.0 32F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatLinearLegacyTest)10647 TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
10648 {
10649     // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10650     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10651 
10652     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10653     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10654 
10655     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10656     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10657     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10658 
10659     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10660     {
10661         testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
10662         testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
10663         testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
10664     }
10665 }
10666 // Test linear sampling for legacy GLES 2.0 32F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatLinearLegacyTest)10667 TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
10668 {
10669     // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10670     ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10671 
10672     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10673     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10674 
10675     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10676     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10677     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10678 }
10679 
10680 // Test linear sampling for legacy GLES 2.0 16F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearLegacyTest)10681 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
10682 {
10683     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10684     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
10685 
10686     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10687     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10688     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10689 
10690     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10691     {
10692         testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
10693         testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
10694         testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
10695     }
10696 }
10697 // Test linear sampling for legacy GLES 2.0 16F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearLegacyTest)10698 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
10699 {
10700     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10701     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
10702 
10703     testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10704     testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10705     testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10706 }
10707 
10708 // Test color-renderability for ES3 float and half float textures
TEST_P(Texture2DFloatTestES3,TextureFloatRenderTest)10709 TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
10710 {
10711     // http://anglebug.com/40096654
10712     ANGLE_SKIP_TEST_IF(IsD3D9());
10713     // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
10714     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
10715 
10716     testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
10717     testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
10718     testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
10719 
10720     testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
10721     testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
10722     testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
10723 
10724     testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
10725 }
10726 
10727 // Test color-renderability for ES2 half float textures
TEST_P(Texture2DFloatTestES2,TextureFloatRenderTest)10728 TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
10729 {
10730     // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
10731     // require a specific one
10732     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
10733     // https://crbug.com/1003971
10734     ANGLE_SKIP_TEST_IF(IsOzone());
10735     // http://anglebug.com/40096654
10736     ANGLE_SKIP_TEST_IF(IsD3D9());
10737 
10738     bool atLeastOneSupported = false;
10739 
10740     if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
10741         IsGLExtensionEnabled("GL_OES_texture_half_float"))
10742     {
10743         atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
10744         atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
10745     }
10746     if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
10747     {
10748         atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
10749 
10750         // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
10751         bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
10752         EXPECT_TRUE(rgbaSupported);
10753         atLeastOneSupported |= rgbaSupported;
10754     }
10755 
10756     EXPECT_TRUE(atLeastOneSupported);
10757 }
10758 
10759 // Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
10760 // GLES 3.0.4 section 3.8.3.
TEST_P(Texture2DTestES3,UnpackSkipImages2D)10761 TEST_P(Texture2DTestES3, UnpackSkipImages2D)
10762 {
10763     // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/42260424
10764     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
10765 
10766     glBindTexture(GL_TEXTURE_2D, mTexture2D);
10767     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10768     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10769     ASSERT_GL_NO_ERROR();
10770 
10771     // SKIP_IMAGES should not have an effect on uploading 2D textures
10772     glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
10773     ASSERT_GL_NO_ERROR();
10774 
10775     std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
10776 
10777     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
10778                  pixelsGreen.data());
10779     ASSERT_GL_NO_ERROR();
10780 
10781     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
10782                     pixelsGreen.data());
10783     ASSERT_GL_NO_ERROR();
10784 
10785     glUseProgram(mProgram);
10786     drawQuad(mProgram, "position", 0.5f);
10787     ASSERT_GL_NO_ERROR();
10788 
10789     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
10790 }
10791 
10792 // Test that skip defined in unpack parameters is taken into account when determining whether
10793 // unpacking source extends outside unpack buffer bounds.
TEST_P(Texture2DTestES3,UnpackSkipPixelsOutOfBounds)10794 TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
10795 {
10796     glBindTexture(GL_TEXTURE_2D, mTexture2D);
10797     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10798     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10799     ASSERT_GL_NO_ERROR();
10800 
10801     GLBuffer buf;
10802     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
10803     std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
10804     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
10805                  GL_DYNAMIC_COPY);
10806     ASSERT_GL_NO_ERROR();
10807 
10808     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10809     ASSERT_GL_NO_ERROR();
10810 
10811     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
10812     ASSERT_GL_NO_ERROR();
10813 
10814     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10815     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
10816 
10817     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
10818     glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
10819     ASSERT_GL_NO_ERROR();
10820 
10821     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10822     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
10823 }
10824 
10825 // Test unpacking to texture from a buffer with a compatible format but different type.
10826 // Compatible formats can be found in "Table 8.2: Valid combinations of format, type, and sized
10827 // internal format." of the OpenGL ES 3.2 spec.
TEST_P(Texture2DTestES3,UnpackCompatibleFormatButDifferentType)10828 TEST_P(Texture2DTestES3, UnpackCompatibleFormatButDifferentType)
10829 {
10830     glBindTexture(GL_TEXTURE_2D, mTexture2D);
10831     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10832     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10833     ASSERT_GL_NO_ERROR();
10834 
10835     // Create texture with GL_RGBA4 format and fill with red
10836     std::vector<GLColor> pixelsRed(128u * 128u, GLColor::red);
10837     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
10838                  pixelsRed.data());
10839     ASSERT_GL_NO_ERROR();
10840 
10841     // Call glTexSubImage2D with incompatible format and expect an error
10842     std::array<GLubyte, 2> rgColor = {255, 255};
10843     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RG, GL_UNSIGNED_BYTE, rgColor.data());
10844     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
10845 
10846     glUseProgram(mProgram);
10847     drawQuad(mProgram, "position", 0.5f);
10848     ASSERT_GL_NO_ERROR();
10849     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
10850 
10851     // Create unpack buffer with GL_RGBA8
10852     GLBuffer buf;
10853     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
10854     std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
10855     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
10856                  GL_DYNAMIC_COPY);
10857     ASSERT_GL_NO_ERROR();
10858 
10859     // Unpack GL_RGBA8 buffer data to GL_RGBA4 texture
10860     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10861     ASSERT_GL_NO_ERROR();
10862 
10863     // Validate that the data was unpacked correctly
10864     glUseProgram(mProgram);
10865     drawQuad(mProgram, "position", 0.5f);
10866     ASSERT_GL_NO_ERROR();
10867 
10868     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
10869 }
10870 
10871 // Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
TEST_P(Texture2DTestES3,UnpackOverlappingRowsFromUnpackBuffer)10872 TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
10873 {
10874     ANGLE_SKIP_TEST_IF(IsD3D11());
10875 
10876     // Incorrect rendering results seen on OSX AMD.
10877     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac() && IsAMD());
10878 
10879     const GLuint width            = 8u;
10880     const GLuint height           = 8u;
10881     const GLuint unpackRowLength  = 5u;
10882     const GLuint unpackSkipPixels = 1u;
10883 
10884     setWindowWidth(width);
10885     setWindowHeight(height);
10886 
10887     glBindTexture(GL_TEXTURE_2D, mTexture2D);
10888     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10889     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10890     ASSERT_GL_NO_ERROR();
10891 
10892     GLBuffer buf;
10893     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
10894     std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
10895                                      GLColor::green);
10896 
10897     for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
10898     {
10899         pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
10900     }
10901 
10902     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
10903                  GL_DYNAMIC_COPY);
10904     ASSERT_GL_NO_ERROR();
10905 
10906     glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
10907     glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
10908     ASSERT_GL_NO_ERROR();
10909 
10910     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10911     ASSERT_GL_NO_ERROR();
10912 
10913     glUseProgram(mProgram);
10914     drawQuad(mProgram, "position", 0.5f);
10915     ASSERT_GL_NO_ERROR();
10916 
10917     GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
10918     std::vector<GLColor> actual(windowPixelCount, GLColor::black);
10919     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
10920                  actual.data());
10921     std::vector<GLColor> expected(windowPixelCount, GLColor::green);
10922     EXPECT_EQ(expected, actual);
10923 }
10924 
10925 template <typename T>
UNorm(double value)10926 T UNorm(double value)
10927 {
10928     return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
10929 }
10930 
10931 // Test rendering a depth texture with mipmaps.
TEST_P(Texture2DTestES3,DepthTexturesWithMipmaps)10932 TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
10933 {
10934     // TODO(cwallez) this is failing on Intel Win7 OpenGL.
10935     // TODO(zmo) this is faling on Win Intel HD 530 Debug.
10936     // http://anglebug.com/42260646
10937     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
10938 
10939     // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/40096577
10940     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
10941 
10942     // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/42262590
10943     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
10944 
10945     const int size = getWindowWidth();
10946 
10947     auto dim   = [size](int level) { return size >> level; };
10948     int levels = gl::log2(size);
10949 
10950     glActiveTexture(GL_TEXTURE0);
10951     glBindTexture(GL_TEXTURE_2D, mTexture2D);
10952     glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
10953     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
10954     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10955     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
10956     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
10957     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
10958     ASSERT_GL_NO_ERROR();
10959 
10960     glUseProgram(mProgram);
10961     glUniform1i(mTexture2DUniformLocation, 0);
10962 
10963     std::vector<unsigned char> expected;
10964 
10965     for (int level = 0; level < levels; ++level)
10966     {
10967         double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
10968         expected.push_back(UNorm<unsigned char>(value));
10969 
10970         int levelDim = dim(level);
10971 
10972         ASSERT_GT(levelDim, 0);
10973 
10974         std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
10975         glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
10976                         GL_UNSIGNED_INT, initData.data());
10977     }
10978     ASSERT_GL_NO_ERROR();
10979 
10980     for (int level = 0; level < levels; ++level)
10981     {
10982         glViewport(0, 0, dim(level), dim(level));
10983         drawQuad(mProgram, "position", 0.5f);
10984         GLColor actual = ReadColor(0, 0);
10985         EXPECT_NEAR(expected[level], actual.R, 10u);
10986     }
10987 
10988     ASSERT_GL_NO_ERROR();
10989 }
10990 
10991 class Texture2DDepthTest : public Texture2DTest
10992 {
10993   protected:
Texture2DDepthTest()10994     Texture2DDepthTest() : Texture2DTest() {}
10995 
getVertexShaderSource()10996     const char *getVertexShaderSource() override
10997     {
10998         return "attribute vec4 vPosition;\n"
10999                "void main() {\n"
11000                "  gl_Position = vPosition;\n"
11001                "}\n";
11002     }
11003 
getFragmentShaderSource()11004     const char *getFragmentShaderSource() override
11005     {
11006         return "precision mediump float;\n"
11007                "uniform sampler2D ShadowMap;"
11008                "void main() {\n"
11009                "  vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
11010                "  if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
11011                "    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
11012                "  } else {"
11013                "    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
11014                "  }"
11015                "}\n";
11016     }
11017 
checkTexImageFormatSupport(GLenum format,GLenum internalformat,GLenum type)11018     bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
11019     {
11020         EXPECT_GL_NO_ERROR();
11021 
11022         GLTexture tex;
11023         glBindTexture(GL_TEXTURE_2D, tex);
11024         glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
11025 
11026         return (glGetError() == GL_NO_ERROR);
11027     }
11028 
testBehavior(bool useSizedComponent)11029     void testBehavior(bool useSizedComponent)
11030     {
11031         int w                 = getWindowWidth();
11032         int h                 = getWindowHeight();
11033         GLuint format         = GL_DEPTH_COMPONENT;
11034         GLuint internalFormat = GL_DEPTH_COMPONENT;
11035 
11036         if (useSizedComponent)
11037         {
11038             internalFormat = GL_DEPTH_COMPONENT24;
11039         }
11040 
11041         GLFramebuffer fbo;
11042         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
11043         ASSERT_GL_NO_ERROR();
11044 
11045         GLTexture depthTexture;
11046         glBindTexture(GL_TEXTURE_2D, depthTexture);
11047         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11048         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11049         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
11050         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
11051 
11052         TexCoordDrawTest::setUpProgram();
11053         GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
11054         ASSERT_NE(-1, shadowMapLocation);
11055 
11056         GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
11057         ASSERT_NE(-1, positionLocation);
11058 
11059         ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
11060         glBindTexture(GL_TEXTURE_2D, depthTexture);
11061         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
11062         ASSERT_GL_NO_ERROR();
11063 
11064         // try adding a color buffer.
11065         GLTexture colorTex;
11066         glBindTexture(GL_TEXTURE_2D, colorTex);
11067         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
11068         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
11069         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
11070         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
11071         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11072         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
11073         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
11074         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
11075         ASSERT_GL_NO_ERROR();
11076 
11077         glViewport(0, 0, w, h);
11078         // Fill depthTexture with 0.75
11079         glClearDepthf(0.75);
11080         glClear(GL_DEPTH_BUFFER_BIT);
11081 
11082         // Revert to normal framebuffer to test depth shader
11083         glBindFramebuffer(GL_FRAMEBUFFER, 0);
11084         glViewport(0, 0, w, h);
11085         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
11086         glClearDepthf(0.0f);
11087         ASSERT_GL_NO_ERROR();
11088 
11089         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
11090         ASSERT_GL_NO_ERROR();
11091 
11092         glActiveTexture(GL_TEXTURE0);
11093         glBindTexture(GL_TEXTURE_2D, depthTexture);
11094 
11095         glUseProgram(mProgram);
11096         ASSERT_GL_NO_ERROR();
11097 
11098         glUniform1i(shadowMapLocation, 0);
11099 
11100         const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
11101 
11102         glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
11103         ASSERT_GL_NO_ERROR();
11104         glEnableVertexAttribArray(positionLocation);
11105         ASSERT_GL_NO_ERROR();
11106         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
11107         ASSERT_GL_NO_ERROR();
11108 
11109         GLuint pixels[1];
11110         glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
11111         ASSERT_GL_NO_ERROR();
11112 
11113         // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
11114         // However, the OES_depth_texture indicates that the depth value is treated as luminance and
11115         // is in all the color components. Multiple implementations implement a workaround that
11116         // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
11117         // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
11118         // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
11119         // depending on if it sees the texture sample in only the RED component.
11120         if (useSizedComponent)
11121         {
11122             ASSERT_NE(pixels[0], 0xff0000ff);
11123         }
11124         else
11125         {
11126             ASSERT_EQ(pixels[0], 0xff0000ff);
11127         }
11128 
11129         glBindFramebuffer(GL_FRAMEBUFFER, 0);
11130         glDeleteProgram(mProgram);
11131     }
11132 };
11133 
11134 // Test depth texture compatibility with OES_depth_texture. Uses unsized internal format.
TEST_P(Texture2DDepthTest,DepthTextureES2Compatibility)11135 TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
11136 {
11137     ANGLE_SKIP_TEST_IF(IsD3D11());
11138     ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
11139     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
11140                        !IsGLExtensionEnabled("GL_OES_depth_texture"));
11141     // http://anglebug.com/40096654
11142     ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
11143     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
11144 
11145     // When the depth texture is specified with unsized internalformat implementations follow
11146     // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
11147     testBehavior(false);
11148 }
11149 
11150 // Test depth texture compatibility with GLES3 using sized internalformat.
TEST_P(Texture2DDepthTest,DepthTextureES3Compatibility)11151 TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
11152 {
11153     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
11154 
11155     // http://anglebug.com/42263796
11156     ANGLE_SKIP_TEST_IF(IsMetal() && !IsMetalTextureSwizzleAvailable());
11157 
11158     testBehavior(true);
11159 }
11160 
11161 // Tests unpacking into the unsized GL_ALPHA format.
TEST_P(Texture2DTestES3,UnsizedAlphaUnpackBuffer)11162 TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
11163 {
11164     // Initialize the texure.
11165     glBindTexture(GL_TEXTURE_2D, mTexture2D);
11166     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
11167                  GL_UNSIGNED_BYTE, nullptr);
11168     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11169     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11170 
11171     std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
11172 
11173     // Pull in the color data from the unpack buffer.
11174     GLBuffer unpackBuffer;
11175     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
11176     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
11177     glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
11178                  GL_STATIC_DRAW);
11179 
11180     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
11181                     GL_UNSIGNED_BYTE, nullptr);
11182 
11183     // Clear to a weird color to make sure we're drawing something.
11184     glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
11185     glClear(GL_COLOR_BUFFER_BIT);
11186 
11187     // Draw with the alpha texture and verify.
11188     drawQuad(mProgram, "position", 0.5f);
11189 
11190     ASSERT_GL_NO_ERROR();
11191     EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
11192 }
11193 
11194 // Ensure stale unpack data doesn't propagate in D3D11.
TEST_P(Texture2DTestES3,StaleUnpackData)11195 TEST_P(Texture2DTestES3, StaleUnpackData)
11196 {
11197     // Init unpack buffer.
11198     GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
11199     std::vector<GLColor> pixels(pixelCount, GLColor::red);
11200 
11201     GLBuffer unpackBuffer;
11202     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
11203     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
11204     GLsizei bufferSize = pixelCount * sizeof(GLColor);
11205     glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
11206 
11207     // Create from unpack buffer.
11208     glBindTexture(GL_TEXTURE_2D, mTexture2D);
11209     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
11210                  GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11211     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11212     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11213 
11214     drawQuad(mProgram, "position", 0.5f);
11215 
11216     ASSERT_GL_NO_ERROR();
11217     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
11218 
11219     // Fill unpack with green, recreating buffer.
11220     pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
11221     GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
11222     glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
11223 
11224     // Reinit texture with green.
11225     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
11226                     GL_UNSIGNED_BYTE, nullptr);
11227 
11228     drawQuad(mProgram, "position", 0.5f);
11229 
11230     ASSERT_GL_NO_ERROR();
11231     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
11232 }
11233 
11234 // Ensure that texture parameters passed as floats that are converted to ints are rounded before
11235 // validating they are less than 0.
TEST_P(Texture2DTestES3,TextureBaseMaxLevelRoundingValidation)11236 TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
11237 {
11238     GLTexture texture;
11239     glBindTexture(GL_TEXTURE_2D, texture);
11240 
11241     // Use a negative number that will round to zero when converted to an integer
11242     // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
11243     // "Validation of values performed by state-setting commands is performed after conversion,
11244     // unless specified otherwise for a specific command."
11245     GLfloat param = -7.30157126e-07f;
11246     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
11247     EXPECT_GL_NO_ERROR();
11248 
11249     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
11250     EXPECT_GL_NO_ERROR();
11251 }
11252 
11253 // This test covers a D3D format redefinition bug for 3D textures. The base level format was not
11254 // being properly checked, and the texture storage of the previous texture format was persisting.
11255 // This would result in an ASSERT in debug and incorrect rendering in release.
11256 // See http://anglebug.com/42260575 and WebGL 2 test conformance2/misc/views-with-offsets.html.
TEST_P(Texture3DTestES3,FormatRedefinitionBug)11257 TEST_P(Texture3DTestES3, FormatRedefinitionBug)
11258 {
11259     GLTexture tex;
11260     glBindTexture(GL_TEXTURE_3D, tex);
11261     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11262 
11263     GLFramebuffer framebuffer;
11264     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
11265     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
11266 
11267     glCheckFramebufferStatus(GL_FRAMEBUFFER);
11268 
11269     std::vector<uint8_t> pixelData(100, 0);
11270 
11271     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
11272     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
11273                     pixelData.data());
11274 
11275     ASSERT_GL_NO_ERROR();
11276 }
11277 
11278 // Test glTexSubImage using PBO to 3D texture that expose the regression bug
11279 // https://issuetracker.google.com/170657065
TEST_P(Texture3DTestES3,TexSubImageWithPBO)11280 TEST_P(Texture3DTestES3, TexSubImageWithPBO)
11281 {
11282     GLTexture tex;
11283 
11284     GLuint pbo;
11285     glGenBuffers(1, &pbo);
11286     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
11287     std::vector<uint8_t> pixelData(128 * 128 * 8 * 4, 0x1f);
11288     glBufferData(GL_PIXEL_UNPACK_BUFFER, 128 * 128 * 8 * 4, pixelData.data(), GL_STATIC_DRAW);
11289 
11290     glBindTexture(GL_TEXTURE_3D, tex);
11291     glTexStorage3D(GL_TEXTURE_3D, 8, GL_RGBA8, 128, 128, 8);
11292     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
11293     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
11294     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11295     glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11296     glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11297     glTexSubImage3D(GL_TEXTURE_3D, 3, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11298     glTexSubImage3D(GL_TEXTURE_3D, 4, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11299     glTexSubImage3D(GL_TEXTURE_3D, 5, 0, 0, 0, 4, 4, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11300     glTexSubImage3D(GL_TEXTURE_3D, 6, 0, 0, 0, 2, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11301     glTexSubImage3D(GL_TEXTURE_3D, 7, 0, 0, 0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11302 
11303     drawQuad(mProgram, "position", 0.5f);
11304     ASSERT_GL_NO_ERROR();
11305 
11306     glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11307     glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11308     glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11309     ASSERT_GL_NO_ERROR();
11310 
11311     drawQuad(mProgram, "position", 0.5f);
11312     ASSERT_GL_NO_ERROR();
11313 }
11314 
11315 // Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
TEST_P(Texture3DTestES3,BasicUnpackBufferOOB)11316 TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
11317 {
11318     // 2D tests
11319     {
11320         GLTexture tex;
11321         glBindTexture(GL_TEXTURE_2D, tex);
11322 
11323         GLBuffer pbo;
11324         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
11325 
11326         // Test OOB
11327         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
11328         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11329         ASSERT_GL_ERROR(GL_INVALID_OPERATION);
11330 
11331         // Test OOB
11332         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
11333         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11334         ASSERT_GL_NO_ERROR();
11335     }
11336 
11337     // 3D tests
11338     {
11339         GLTexture tex;
11340         glBindTexture(GL_TEXTURE_3D, tex);
11341 
11342         GLBuffer pbo;
11343         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
11344 
11345         // Test OOB
11346         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
11347                      GL_STATIC_DRAW);
11348         glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11349         ASSERT_GL_ERROR(GL_INVALID_OPERATION);
11350 
11351         // Test OOB
11352         glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
11353         glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11354         ASSERT_GL_NO_ERROR();
11355     }
11356 }
11357 
11358 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES3,SingleTextureMultipleSamplers)11359 TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
11360 {
11361     GLint maxTextureUnits = 0;
11362     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
11363     ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
11364 
11365     constexpr int kSize = 16;
11366 
11367     // Make a single-level texture, fill it with red.
11368     std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
11369     GLTexture tex;
11370     glBindTexture(GL_TEXTURE_2D, tex);
11371     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11372                  redColors.data());
11373     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11374     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11375 
11376     // Simple confidence check.
11377     draw2DTexturedQuad(0.5f, 1.0f, true);
11378     ASSERT_GL_NO_ERROR();
11379     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
11380 
11381     // Bind texture to unit 1 with a sampler object making it incomplete.
11382     GLSampler sampler;
11383     glBindSampler(0, sampler);
11384     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11385     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11386 
11387     // Make a mipmap texture, fill it with blue.
11388     std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
11389     GLTexture mipmapTex;
11390     glBindTexture(GL_TEXTURE_2D, mipmapTex);
11391     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11392                  blueColors.data());
11393     glGenerateMipmap(GL_TEXTURE_2D);
11394 
11395     // Draw with the sampler, expect blue.
11396     draw2DTexturedQuad(0.5f, 1.0f, true);
11397     ASSERT_GL_NO_ERROR();
11398     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
11399 
11400     // Simple multitexturing program.
11401     constexpr char kVS[] =
11402         "#version 300 es\n"
11403         "in vec2 position;\n"
11404         "out vec2 texCoord;\n"
11405         "void main()\n"
11406         "{\n"
11407         "    gl_Position = vec4(position, 0, 1);\n"
11408         "    texCoord = position * 0.5 + vec2(0.5);\n"
11409         "}";
11410 
11411     constexpr char kFS[] =
11412         "#version 300 es\n"
11413         "precision mediump float;\n"
11414         "in vec2 texCoord;\n"
11415         "uniform sampler2D tex1;\n"
11416         "uniform sampler2D tex2;\n"
11417         "uniform sampler2D tex3;\n"
11418         "uniform sampler2D tex4;\n"
11419         "out vec4 color;\n"
11420         "void main()\n"
11421         "{\n"
11422         "    color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
11423         "          +  texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
11424         "}";
11425 
11426     ANGLE_GL_PROGRAM(program, kVS, kFS);
11427 
11428     std::array<GLint, 4> texLocations = {
11429         {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
11430          glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
11431     for (GLint location : texLocations)
11432     {
11433         ASSERT_NE(-1, location);
11434     }
11435 
11436     // Init the uniform data.
11437     glUseProgram(program);
11438     for (GLint location = 0; location < 4; ++location)
11439     {
11440         glUniform1i(texLocations[location], location);
11441     }
11442 
11443     // Initialize four samplers
11444     GLSampler samplers[4];
11445 
11446     // 0: non-mipped.
11447     glBindSampler(0, samplers[0]);
11448     glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11449     glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11450 
11451     // 1: mipped.
11452     glBindSampler(1, samplers[1]);
11453     glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11454     glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11455 
11456     // 2: non-mipped.
11457     glBindSampler(2, samplers[2]);
11458     glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11459     glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11460 
11461     // 3: mipped.
11462     glBindSampler(3, samplers[3]);
11463     glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11464     glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11465 
11466     // Bind two blue mipped textures and two single layer textures, should all draw.
11467     glActiveTexture(GL_TEXTURE0);
11468     glBindTexture(GL_TEXTURE_2D, tex);
11469 
11470     glActiveTexture(GL_TEXTURE1);
11471     glBindTexture(GL_TEXTURE_2D, mipmapTex);
11472 
11473     glActiveTexture(GL_TEXTURE2);
11474     glBindTexture(GL_TEXTURE_2D, tex);
11475 
11476     glActiveTexture(GL_TEXTURE3);
11477     glBindTexture(GL_TEXTURE_2D, mipmapTex);
11478 
11479     ASSERT_GL_NO_ERROR();
11480 
11481     drawQuad(program, "position", 0.5f);
11482     ASSERT_GL_NO_ERROR();
11483     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
11484 
11485     // Bind four single layer textures, two should be incomplete.
11486     glActiveTexture(GL_TEXTURE1);
11487     glBindTexture(GL_TEXTURE_2D, tex);
11488 
11489     glActiveTexture(GL_TEXTURE3);
11490     glBindTexture(GL_TEXTURE_2D, tex);
11491 
11492     drawQuad(program, "position", 0.5f);
11493     ASSERT_GL_NO_ERROR();
11494     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
11495 }
11496 
11497 // The test is added to cover http://anglebug.com/42260889. Cubemap completeness checks used to
11498 // start always at level 0 instead of the base level resulting in an incomplete texture if the faces
11499 // at level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
11500 // level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
11501 // samples the cubemap using a direction vector (1,1,1).
TEST_P(TextureCubeTestES3,SpecifyAndSampleFromBaseLevel1)11502 TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
11503 {
11504     // Check http://anglebug.com/42260891.
11505     ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA());
11506 
11507     constexpr char kVS[] =
11508         R"(#version 300 es
11509         precision mediump float;
11510         in vec3 pos;
11511         void main() {
11512             gl_Position = vec4(pos, 1.0);
11513         })";
11514 
11515     constexpr char kFS[] =
11516         R"(#version 300 es
11517         precision mediump float;
11518         out vec4 color;
11519         uniform samplerCube uTex;
11520         void main(){
11521             color = texture(uTex, vec3(1.0));
11522         })";
11523 
11524     ANGLE_GL_PROGRAM(program, kVS, kFS);
11525     glUseProgram(program);
11526 
11527     glUniform1i(glGetUniformLocation(program, "uTex"), 0);
11528     glActiveTexture(GL_TEXTURE0);
11529 
11530     GLTexture cubeTex;
11531     glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
11532 
11533     const int kFaceWidth  = 1;
11534     const int kFaceHeight = 1;
11535     std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
11536     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11537                  GL_UNSIGNED_BYTE, texData.data());
11538     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11539                  GL_UNSIGNED_BYTE, texData.data());
11540     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11541                  GL_UNSIGNED_BYTE, texData.data());
11542     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11543                  GL_UNSIGNED_BYTE, texData.data());
11544     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11545                  GL_UNSIGNED_BYTE, texData.data());
11546     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11547                  GL_UNSIGNED_BYTE, texData.data());
11548     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11549     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11550     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
11551     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
11552     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
11553     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
11554 
11555     drawQuad(program, "pos", 0.5f, 1.0f, true);
11556     ASSERT_GL_NO_ERROR();
11557 
11558     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
11559 }
11560 
11561 // Test GL_PIXEL_UNPACK_BUFFER with GL_TEXTURE_CUBE_MAP.
TEST_P(TextureCubeTestES3,CubeMapPixelUnpackBuffer)11562 TEST_P(TextureCubeTestES3, CubeMapPixelUnpackBuffer)
11563 {
11564     // Check http://anglebug.com/42260891.
11565     ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA());
11566 
11567     constexpr char kVS[] =
11568         R"(#version 300 es
11569         precision mediump float;
11570         in vec3 pos;
11571         void main() {
11572             gl_Position = vec4(pos, 1.0);
11573         })";
11574 
11575     constexpr char kFS[] =
11576         R"(#version 300 es
11577         precision mediump float;
11578         out vec4 color;
11579         uniform samplerCube uTex;
11580         void main(){
11581             color = texture(uTex, vec3(1.0));
11582         })";
11583 
11584     ANGLE_GL_PROGRAM(program, kVS, kFS);
11585     glUseProgram(program);
11586 
11587     glUniform1i(glGetUniformLocation(program, "uTex"), 0);
11588     glActiveTexture(GL_TEXTURE0);
11589 
11590     GLTexture cubeTex;
11591     glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
11592 
11593     const int kFaceWidth  = 4;
11594     const int kFaceHeight = 4;
11595 
11596     uint16_t kHalfFloatOne  = 0x3C00;
11597     uint16_t kHalfFloatZero = 0;
11598 
11599     glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA16F, kFaceWidth, kFaceHeight);
11600     struct RGBA16F
11601     {
11602         uint16_t R, G, B, A;
11603     };
11604     RGBA16F redColor = {kHalfFloatOne, kHalfFloatZero, kHalfFloatZero, kHalfFloatOne};
11605 
11606     std::vector<RGBA16F> pixels(kFaceWidth * kFaceHeight, redColor);
11607     GLBuffer buffer;
11608     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
11609     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(RGBA16F), pixels.data(),
11610                  GL_DYNAMIC_DRAW);
11611     EXPECT_GL_NO_ERROR();
11612     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
11613 
11614     for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
11615     {
11616         glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, 0, 0, 0, kFaceWidth,
11617                         kFaceHeight, GL_RGBA, GL_HALF_FLOAT, 0);
11618         EXPECT_GL_NO_ERROR();
11619     }
11620     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
11621 
11622     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
11623     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
11624     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
11625     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
11626     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
11627 
11628     drawQuad(program, "pos", 0.5f, 1.0f, true);
11629     ASSERT_GL_NO_ERROR();
11630 
11631     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::red);
11632 }
11633 
11634 // Test creating a mutable cubemap, committing it, and then incomaptibly redefining one layer, while
11635 // compatibly redefining another layer.
TEST_P(TextureCubeTestES3,IncompatibleLayerAThenCompatibleLayerB)11636 TEST_P(TextureCubeTestES3, IncompatibleLayerAThenCompatibleLayerB)
11637 {
11638     GLTexture tex;
11639     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11640 
11641     std::vector<uint32_t> data(32 * 32 * 4, 0xC00FFC00);
11642 
11643     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11644                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11645     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11646                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11647     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11648                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11649     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11650                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11651     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11652                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11653     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11654                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11655     glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11656     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11657                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11658     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11659                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11660     EXPECT_GL_NO_ERROR();
11661 }
11662 
11663 // Test creating a mutable cubemap, committing it, and then comaptibly redefining one layer, while
11664 // incompatibly redefining another layer.
TEST_P(TextureCubeTestES3,CompatibleLayerAThenIncompatibleLayerB)11665 TEST_P(TextureCubeTestES3, CompatibleLayerAThenIncompatibleLayerB)
11666 {
11667     GLTexture tex;
11668     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11669 
11670     std::vector<uint32_t> data(32 * 32 * 4, 0xC00FFC00);
11671 
11672     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11673                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11674     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11675                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11676     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11677                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11678     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11679                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11680     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11681                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11682     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11683                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11684     glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11685     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11686                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11687     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11688                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11689     EXPECT_GL_NO_ERROR();
11690 }
11691 
11692 // Test creating a mutable cubemap, committing it, and then incomaptibly redefining two layers,
11693 // while compatibly redefining another layer.
TEST_P(TextureCubeTestES3,IncompatibleLayerABThenCompatibleLayerC)11694 TEST_P(TextureCubeTestES3, IncompatibleLayerABThenCompatibleLayerC)
11695 {
11696     GLTexture tex;
11697     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11698 
11699     std::vector<uint32_t> data(32 * 32 * 4, 0xC00FFC00);
11700 
11701     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11702                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11703     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11704                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11705     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11706                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11707     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11708                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11709     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11710                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11711     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11712                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11713     glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11714     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11715                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11716     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11717                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11718     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11719                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11720     EXPECT_GL_NO_ERROR();
11721 }
11722 
11723 // Test creating a mutable cubemap, committing it, and then incomaptibly redefining two layers and
11724 // compatibly redefining them again.
TEST_P(TextureCubeTestES3,IncompatibleLayerABThenCompatibleLayerAB)11725 TEST_P(TextureCubeTestES3, IncompatibleLayerABThenCompatibleLayerAB)
11726 {
11727     GLTexture tex;
11728     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11729 
11730     constexpr uint32_t kSize = 64;
11731 
11732     std::vector<uint32_t> data(kSize * kSize * 4 * 4, 0xC00FFC00);
11733     std::vector<uint32_t> data2(kSize * kSize * 4 * 4, 0xC00003FF);
11734 
11735     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11736                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11737     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11738                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11739     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11740                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11741     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11742                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11743     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11744                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11745     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11746                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11747     glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11748     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11749                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11750     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11751                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11752     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11753                  GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11754     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11755                  GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11756 
11757     glActiveTexture(GL_TEXTURE0);
11758     glBindTexture(GL_TEXTURE_2D, 0);
11759     glActiveTexture(GL_TEXTURE1);
11760     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11761 
11762     glUseProgram(mProgram);
11763     glUniform1i(mTexture2DUniformLocation, 0);
11764     glUniform1i(mTextureCubeUniformLocation, 1);
11765 
11766     const int w = getWindowWidth();
11767     const int h = getWindowHeight();
11768 
11769     for (uint32_t i = 0; i < 6; ++i)
11770     {
11771         glUniform1i(mTextureCubeFaceUniformLocation, i);
11772         glClear(GL_COLOR_BUFFER_BIT);
11773         drawQuad(mProgram, "position", 0.5f);
11774 
11775         const bool expectRed = i == 2 || i == 5;
11776         const GLColor expect = expectRed ? GLColor::red : GLColor::green;
11777         EXPECT_PIXEL_RECT_EQ(2, 2, w - 4, h - 4, expect);
11778         EXPECT_GL_NO_ERROR();
11779     }
11780 }
11781 
11782 // Similar to IncompatibleLayerABThenCompatibleLayerAB, but with a single-level texture
TEST_P(TextureCubeTestES3,IncompatibleLayerABThenCompatibleLayerABSingleLevel)11783 TEST_P(TextureCubeTestES3, IncompatibleLayerABThenCompatibleLayerABSingleLevel)
11784 {
11785     GLTexture tex;
11786     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11787 
11788     constexpr uint32_t kSize = 64;
11789 
11790     std::vector<uint32_t> data(kSize * kSize * 4 * 4, 0xC00FFC00);
11791     std::vector<uint32_t> data2(kSize * kSize * 4 * 4, 0xC00003FF);
11792 
11793     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11794                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11795     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11796                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11797     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11798                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11799     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11800                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11801     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11802                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11803     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11804                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11805 
11806     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11807     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11808 
11809     glActiveTexture(GL_TEXTURE0);
11810     glBindTexture(GL_TEXTURE_2D, 0);
11811     glActiveTexture(GL_TEXTURE1);
11812     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11813 
11814     glUseProgram(mProgram);
11815     glUniform1i(mTexture2DUniformLocation, 0);
11816     glUniform1i(mTextureCubeUniformLocation, 1);
11817 
11818     const int w = getWindowWidth();
11819     const int h = getWindowHeight();
11820 
11821     for (uint32_t i = 0; i < 6; ++i)
11822     {
11823         glUniform1i(mTextureCubeFaceUniformLocation, i);
11824         glClear(GL_COLOR_BUFFER_BIT);
11825         drawQuad(mProgram, "position", 0.5f);
11826 
11827         EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::green);
11828         EXPECT_GL_NO_ERROR();
11829     }
11830 
11831     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11832                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11833     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11834                  GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11835     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11836                  GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11837     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11838                  GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11839 
11840     for (uint32_t i = 0; i < 6; ++i)
11841     {
11842         glUniform1i(mTextureCubeFaceUniformLocation, i);
11843         glClear(GL_COLOR_BUFFER_BIT);
11844         drawQuad(mProgram, "position", 0.5f);
11845 
11846         const bool expectRed = i == 2 || i == 5;
11847         const GLColor expect = expectRed ? GLColor::red : GLColor::green;
11848         EXPECT_PIXEL_RECT_EQ(2, 2, w - 4, h - 4, expect);
11849         EXPECT_GL_NO_ERROR();
11850     }
11851 }
11852 
11853 // Test that the maximum texture layer can allocate enough memory.
TEST_P(TextureCubeTestES32,MaxArrayTextureLayersVerify)11854 TEST_P(TextureCubeTestES32, MaxArrayTextureLayersVerify)
11855 {
11856     GLint maxTextureLayers = 0;
11857     GLTexture texture;
11858 
11859     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
11860     ASSERT_GL_NO_ERROR();
11861 
11862     glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
11863     ASSERT_GL_NO_ERROR();
11864 
11865     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 256, 256, maxTextureLayers, 0, GL_RGBA,
11866                  GL_UNSIGNED_BYTE, nullptr);
11867     ASSERT_GL_NO_ERROR();
11868 
11869     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 256, 256, maxTextureLayers + 1, 0, GL_RGBA,
11870                  GL_UNSIGNED_BYTE, nullptr);
11871     EXPECT_GL_ERROR(GL_INVALID_VALUE);
11872 
11873     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 256, 256, maxTextureLayers);
11874     ASSERT_GL_NO_ERROR();
11875 
11876     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 256, 256, maxTextureLayers + 1);
11877     EXPECT_GL_ERROR(GL_INVALID_VALUE);
11878 }
11879 
11880 // Tests defining a cube map array texture using glTexImage3D().
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexImage)11881 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexImage)
11882 {
11883     GLTexture cubeMapArrayTexture;
11884     glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11885 
11886     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11887                  nullptr);
11888     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, 128, 128, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11889                  nullptr);
11890     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, GL_RGBA, 64, 64, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11891                  nullptr);
11892     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 3, GL_RGBA, 32, 32, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11893                  nullptr);
11894     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 4, GL_RGBA, 16, 16, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11895                  nullptr);
11896     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 5, GL_RGBA, 8, 8, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11897                  nullptr);
11898     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 6, GL_RGBA, 4, 4, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11899                  nullptr);
11900     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 7, GL_RGBA, 2, 2, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11901                  nullptr);
11902     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 8, GL_RGBA, 1, 1, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11903                  nullptr);
11904     EXPECT_GL_NO_ERROR();
11905 }
11906 
11907 // Tests defining a cube map array texture using glTexStorage3D() and filling all levels using
11908 // glTexSubImage3D().
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexStorage)11909 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexStorage)
11910 {
11911     GLTexture cubeMapArrayTexture;
11912     std::vector<GLColor> cubeMapArrayData(256 * 256 * 24, GLColor::red);
11913     glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11914 
11915     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 9, GL_RGBA8, 256, 256, 24);
11916     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, 256, 256, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11917                     cubeMapArrayData.data());
11918     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, 0, 0, 0, 128, 128, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11919                     cubeMapArrayData.data());
11920     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, 0, 0, 0, 64, 64, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11921                     cubeMapArrayData.data());
11922     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 3, 0, 0, 0, 32, 32, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11923                     cubeMapArrayData.data());
11924     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 4, 0, 0, 0, 16, 16, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11925                     cubeMapArrayData.data());
11926     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 5, 0, 0, 0, 8, 8, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11927                     cubeMapArrayData.data());
11928     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 6, 0, 0, 0, 4, 4, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11929                     cubeMapArrayData.data());
11930     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 7, 0, 0, 0, 2, 2, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11931                     cubeMapArrayData.data());
11932     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 8, 0, 0, 0, 1, 1, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11933                     cubeMapArrayData.data());
11934     EXPECT_GL_NO_ERROR();
11935 }
11936 
11937 // Tests defining a single-level cube map array texture and modifying a part of it with unequal
11938 // width and height and a depth that is not a multiple of 6.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexStorageModifyPartially)11939 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexStorageModifyPartially)
11940 {
11941     GLTexture cubeMapArrayTexture;
11942     glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11943 
11944     std::vector<GLColor> cubeMapArrayData(256 * 256 * 6, GLColor::red);
11945     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, 6);
11946     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, 256, 100, 1, GL_RGBA, GL_UNSIGNED_BYTE,
11947                     cubeMapArrayData.data());
11948     EXPECT_GL_NO_ERROR();
11949 }
11950 
11951 // Tests TexSubImage3D with cube map arrays using dims beyond the size limit.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexSubImageGreaterThanSizeLimit)11952 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexSubImageGreaterThanSizeLimit)
11953 {
11954     GLTexture cubeMapArrayTexture;
11955     glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11956 
11957     GLint max3DTextureSize = -1;
11958     glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
11959     EXPECT_GT(max3DTextureSize, 0);
11960 
11961     GLint maxCubeTextureSize = -1;
11962     glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
11963     EXPECT_GT(maxCubeTextureSize, 0);
11964 
11965     GLint maxSizeLimit = std::min(maxCubeTextureSize, max3DTextureSize);
11966     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxSizeLimit, maxSizeLimit, 6, 0, GL_RGBA,
11967                  GL_UNSIGNED_BYTE, nullptr);
11968     ASSERT_GL_NO_ERROR();
11969 
11970     // TexSubImage3D can take unequal values for width and height for cube map arrays. However, they
11971     // should stay below the size limit.
11972     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, maxSizeLimit + 1, maxSizeLimit, 6,
11973                     GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
11974     EXPECT_GL_ERROR(GL_INVALID_VALUE);
11975 
11976     glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, maxSizeLimit, maxSizeLimit + 1, 6,
11977                     GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
11978     EXPECT_GL_ERROR(GL_INVALID_VALUE);
11979 }
11980 
11981 // Tests invalid dim/level input for TexImage3D with cube map arrays.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexImageInvalidInputs)11982 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexImageInvalidInputs)
11983 {
11984     GLTexture cubeMapArrayTexture;
11985     glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11986 
11987     // Negative level and dimensions are not accepted.
11988     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, -1, GL_RGBA, 256, 256, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11989                  nullptr);
11990     EXPECT_GL_ERROR(GL_INVALID_VALUE);
11991 
11992     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, -1, 256, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11993                  nullptr);
11994     EXPECT_GL_ERROR(GL_INVALID_VALUE);
11995 
11996     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, -1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11997                  nullptr);
11998     EXPECT_GL_ERROR(GL_INVALID_VALUE);
11999 
12000     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, -6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12001                  nullptr);
12002     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12003 
12004     // As the number of layer-faces, depth should be a multiple of 6, unless it is partially being
12005     // modified (via TexSubImage).
12006     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12007                  nullptr);
12008     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12009 
12010     // Width and height should be equal, unless it is partially being modified (via TexSubImage).
12011     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 100, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12012                  nullptr);
12013     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12014 
12015     // Width and height should not exceed the maximum cube map texture size for that mip level.
12016     GLint maxCubeTextureSize = -1;
12017     glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
12018     EXPECT_GT(maxCubeTextureSize, 0);
12019 
12020     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxCubeTextureSize + 1, maxCubeTextureSize,
12021                  6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12022     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12023 
12024     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxCubeTextureSize, maxCubeTextureSize + 1,
12025                  6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12026     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12027 
12028     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxCubeTextureSize + 1,
12029                  maxCubeTextureSize + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12030     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12031 
12032     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, maxCubeTextureSize / 2 + 1,
12033                  maxCubeTextureSize / 2 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12034     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12035 
12036     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, GL_RGBA, maxCubeTextureSize / 4 + 1,
12037                  maxCubeTextureSize / 4 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12038     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12039 
12040     // Width and height and depth should not exceed the maximum 3D texture size.
12041     GLint max3DTextureSize = -1;
12042     glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
12043     EXPECT_GT(max3DTextureSize, 0);
12044 
12045     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, max3DTextureSize + 1, 0, GL_RGBA,
12046                  GL_UNSIGNED_BYTE, nullptr);
12047     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12048 
12049     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, max3DTextureSize + 1, max3DTextureSize + 1,
12050                  6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12051     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12052 
12053     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, max3DTextureSize / 2 + 1,
12054                  max3DTextureSize / 2 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12055     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12056 
12057     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, GL_RGBA, max3DTextureSize / 4 + 1,
12058                  max3DTextureSize / 4 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12059     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12060 }
12061 
12062 // Tests invalid dim/level input for TexStorage3D with cube map arrays.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexStorageInvalidInputs)12063 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexStorageInvalidInputs)
12064 {
12065     GLTexture cubeMapArrayTexture;
12066     glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
12067 
12068     // Negative level and dimensions are not accepted.
12069     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, -1, GL_RGBA8, 256, 256, 6);
12070     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12071 
12072     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, -1, 256, 6);
12073     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12074 
12075     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, -1, 6);
12076     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12077 
12078     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, -6);
12079     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12080 
12081     // As the number of layer-faces, depth should be a multiple of 6.
12082     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, 1);
12083     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12084 
12085     // Width and height should be equal.
12086     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 100, 6);
12087     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12088 
12089     // Width and height should not exceed the maximum cube map texture size.
12090     GLint maxCubeTextureSize = -1;
12091     glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
12092     EXPECT_GT(maxCubeTextureSize, 0);
12093 
12094     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, maxCubeTextureSize + 1,
12095                    maxCubeTextureSize + 1, 6);
12096     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12097 
12098     // Width and height and depth should not exceed the maximum 3D texture size.
12099     GLint max3DTextureSize = -1;
12100     glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
12101     EXPECT_GT(max3DTextureSize, 0);
12102 
12103     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, max3DTextureSize + 1,
12104                    max3DTextureSize + 1, 6);
12105     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12106 
12107     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, max3DTextureSize + 1);
12108     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12109 
12110     // Level count must not exceed log2(max(width, height)) + 1.
12111     GLint maxLevelCount256 = 1 + static_cast<GLint>(std::log2(256));
12112     glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, maxLevelCount256 + 1, GL_RGBA8, 256, 256, 6);
12113     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12114 }
12115 
12116 // Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
TEST_P(Texture2DTestES3,NegativeTextureBaseLevelAndMaxLevel)12117 TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
12118 {
12119     GLuint texture = create2DTexture();
12120 
12121     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
12122     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12123 
12124     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
12125     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12126 
12127     glDeleteTextures(1, &texture);
12128     EXPECT_GL_NO_ERROR();
12129 }
12130 
12131 // Test setting base level after calling generateMipmap on a LUMA texture.
12132 // Covers http://anglebug.com/42261204
TEST_P(Texture2DTestES3,GenerateMipmapAndBaseLevelLUMA)12133 TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
12134 {
12135     glActiveTexture(GL_TEXTURE0);
12136     glBindTexture(GL_TEXTURE_2D, mTexture2D);
12137 
12138     constexpr const GLsizei kWidth  = 8;
12139     constexpr const GLsizei kHeight = 8;
12140     std::array<GLubyte, kWidth * kHeight * 2> whiteData;
12141     whiteData.fill(255u);
12142 
12143     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
12144                  GL_UNSIGNED_BYTE, whiteData.data());
12145     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
12146     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
12147     glGenerateMipmap(GL_TEXTURE_2D);
12148     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
12149     EXPECT_GL_NO_ERROR();
12150 
12151     drawQuad(mProgram, "position", 0.5f);
12152     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
12153 }
12154 
12155 // Incompatible levels with non-mipmap filtering should work.
TEST_P(Texture2DTestES3,IncompatibleMipsButNoMipmapFiltering)12156 TEST_P(Texture2DTestES3, IncompatibleMipsButNoMipmapFiltering)
12157 {
12158     // http://anglebug.com/42263372
12159     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsWindows() && (IsAMD() || IsIntel()));
12160 
12161     // http://anglebug.com/40096708
12162     ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsNVIDIAShield());
12163 
12164     glActiveTexture(GL_TEXTURE0);
12165     glBindTexture(GL_TEXTURE_2D, mTexture2D);
12166 
12167     constexpr const GLsizei kSize = 8;
12168     const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
12169     const std::vector<GLColor> kLevel1Data(kSize * kSize, GLColor::red);
12170 
12171     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12172                  kLevel0Data.data());
12173     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12174                  kLevel1Data.data());
12175     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
12176     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
12177     EXPECT_GL_NO_ERROR();
12178 
12179     // Draw with base level 0.  The GL_LINEAR filtering ensures the texture's image is not created
12180     // with mipmap.
12181     drawQuad(mProgram, "position", 0.5f);
12182     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
12183 
12184     // Verify draw with level 1.
12185     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
12186     drawQuad(mProgram, "position", 0.5f);
12187     EXPECT_GL_NO_ERROR();
12188     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel1Data[0]);
12189 
12190     // Verify draw with level 0 again
12191     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
12192     drawQuad(mProgram, "position", 0.5f);
12193     EXPECT_GL_NO_ERROR();
12194     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
12195 }
12196 
12197 // A collection of negative tests for QCOM foveated rendering extensions
TEST_P(Texture2DTestES3Foveation,NegativeTests)12198 TEST_P(Texture2DTestES3Foveation, NegativeTests)
12199 {
12200     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated") ||
12201                        !IsGLExtensionEnabled("GL_QCOM_texture_foveated"));
12202 
12203     // Switch to foveated framebuffer
12204     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12205 
12206     // QCOM framebuffer foveated tests
12207     GLuint providedFeatures = 0;
12208 
12209     // Test invalid numLayers
12210     glFramebufferFoveationConfigQCOM(mFramebuffer, std::numeric_limits<uint32_t>::max(), 1,
12211                                      GL_FOVEATION_ENABLE_BIT_QCOM, &providedFeatures);
12212     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12213 
12214     // Test invalid focal points
12215     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, std::numeric_limits<uint32_t>::max(),
12216                                      GL_FOVEATION_ENABLE_BIT_QCOM, &providedFeatures);
12217     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12218 
12219     // Test setting foveation parameters on a framebuffer that is not configured
12220     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12221     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12222 
12223     // Configure framebuffer correctly
12224     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12225                                      &providedFeatures);
12226     EXPECT_GL_NO_ERROR();
12227     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12228 
12229     // Try to configure it again
12230     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12231                                      &providedFeatures);
12232     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12233 
12234     // Set foveation parameters
12235     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12236     EXPECT_GL_NO_ERROR();
12237 
12238     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12239 
12240     GLTexture texture;
12241     glActiveTexture(GL_TEXTURE0);
12242     glBindTexture(GL_TEXTURE_2D, texture);
12243     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
12244                  GL_UNSIGNED_BYTE, nullptr);
12245     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12246     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12247     EXPECT_GL_NO_ERROR();
12248 
12249     // Change attachments and try to perform a clear and draw
12250     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
12251     ASSERT_GL_NO_ERROR();
12252 
12253     glUseProgram(mProgram);
12254 
12255     // Clear
12256     glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
12257     glClear(GL_COLOR_BUFFER_BIT);
12258     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12259 
12260     // Draw
12261     drawQuad(mProgram, "position", 0.5f);
12262     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12263 
12264     // QCOM texture foveated tests
12265     glBindTexture(GL_TEXTURE_2D, texture);
12266     // Test invalid feature bit
12267     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12268                     GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM);
12269     EXPECT_GL_ERROR(GL_INVALID_ENUM);
12270 
12271     // Test setting foveation parameters on a framebuffer that is not configured
12272     glTextureFoveationParametersQCOM(texture, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12273     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12274 
12275     // Configure texture
12276     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12277                     GL_FOVEATION_ENABLE_BIT_QCOM);
12278     EXPECT_GL_NO_ERROR();
12279 
12280     // Test invalid focal points
12281     GLint supportedNumFocalPoints = 0;
12282     glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM,
12283                         &supportedNumFocalPoints);
12284     EXPECT_GL_NO_ERROR();
12285 
12286     glTextureFoveationParametersQCOM(texture, 0, supportedNumFocalPoints + 1, 0.0f, 0.0f, 8.0f,
12287                                      8.0f, 0.0f);
12288     EXPECT_GL_ERROR(GL_INVALID_VALUE);
12289 
12290     // Attach foveated texture while framebuffer is also fovated and check framebuffer completeness
12291     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
12292     ASSERT_GL_NO_ERROR();
12293     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM,
12294                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
12295 
12296     // Attach multiple foveated textures to an un-foveated framebuffer and check completeness
12297     GLFramebuffer fbo;
12298     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
12299     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
12300     ASSERT_GL_NO_ERROR();
12301     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12302 
12303     glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
12304     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
12305                  GL_UNSIGNED_BYTE, nullptr);
12306     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12307     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12308     EXPECT_GL_NO_ERROR();
12309     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12310                     GL_FOVEATION_ENABLE_BIT_QCOM);
12311     EXPECT_GL_NO_ERROR();
12312 
12313     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
12314                            mFramebufferColorTexture, 0);
12315     ASSERT_GL_NO_ERROR();
12316     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM,
12317                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
12318 }
12319 
12320 // QCOM framebuffer foveated rendering + clear
TEST_P(Texture2DTestES3Foveation,Clear)12321 TEST_P(Texture2DTestES3Foveation, Clear)
12322 {
12323     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12324 
12325     // Switch to foveated framebuffer
12326     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12327 
12328     // Just need 1 focal point
12329     GLuint providedFeatures = 0;
12330     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12331                                      &providedFeatures);
12332     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12333     // Set foveation parameters
12334     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12335     EXPECT_GL_NO_ERROR();
12336 
12337     // Clear
12338     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12339     glClear(GL_COLOR_BUFFER_BIT);
12340     EXPECT_GL_NO_ERROR();
12341 
12342     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12343 }
12344 
12345 // QCOM framebuffer foveated rendering + clear then draw
TEST_P(Texture2DTestES3Foveation,ClearThenDraw)12346 TEST_P(Texture2DTestES3Foveation, ClearThenDraw)
12347 {
12348     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12349 
12350     // Switch to foveated framebuffer
12351     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12352 
12353     // Just need 1 focal point
12354     GLuint providedFeatures = 0;
12355     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12356                                      &providedFeatures);
12357     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12358     // Set foveation parameters
12359     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12360     EXPECT_GL_NO_ERROR();
12361 
12362     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12363     glUseProgram(program);
12364 
12365     // Clear
12366     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12367     glClear(GL_COLOR_BUFFER_BIT);
12368     EXPECT_GL_NO_ERROR();
12369 
12370     // Draw
12371     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12372     EXPECT_GL_NO_ERROR();
12373 
12374     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12375 }
12376 
12377 // QCOM framebuffer foveated rendering with rendebuffer attachment + clear then draw
TEST_P(Texture2DTestES3Foveation,RenderbufferAttachmentClearThenDraw)12378 TEST_P(Texture2DTestES3Foveation, RenderbufferAttachmentClearThenDraw)
12379 {
12380     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12381 
12382     // Switch to foveated framebuffer and attach a renderbuffer
12383     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12384     GLRenderbuffer renderbuffer;
12385     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
12386     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
12387     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
12388     EXPECT_GL_NO_ERROR();
12389 
12390     // Just need 1 focal point
12391     GLuint providedFeatures = 0;
12392     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12393                                      &providedFeatures);
12394     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12395     // Set foveation parameters
12396     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12397     EXPECT_GL_NO_ERROR();
12398 
12399     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12400     glUseProgram(program);
12401 
12402     // Clear
12403     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12404     glClear(GL_COLOR_BUFFER_BIT);
12405     EXPECT_GL_NO_ERROR();
12406 
12407     // Draw
12408     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12409     EXPECT_GL_NO_ERROR();
12410 
12411     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12412 }
12413 
12414 // QCOM framebuffer foveated rendering + draw, clear then draw
TEST_P(Texture2DTestES3Foveation,DrawClearDraw)12415 TEST_P(Texture2DTestES3Foveation, DrawClearDraw)
12416 {
12417     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12418 
12419     // Switch to foveated framebuffer
12420     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12421 
12422     // Just need 1 focal point
12423     GLuint providedFeatures = 0;
12424     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12425                                      &providedFeatures);
12426     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12427     // Set foveation parameters
12428     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12429     EXPECT_GL_NO_ERROR();
12430 
12431     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12432     glUseProgram(greenProgram);
12433 
12434     // Draw
12435     drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12436     EXPECT_GL_NO_ERROR();
12437 
12438     // Clear
12439     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
12440     glClear(GL_COLOR_BUFFER_BIT);
12441     EXPECT_GL_NO_ERROR();
12442 
12443     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12444     glUseProgram(blueProgram);
12445 
12446     // Draw
12447     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12448     EXPECT_GL_NO_ERROR();
12449 
12450     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12451 }
12452 
12453 // QCOM framebuffer foveated rendering - draw before and after enabling foveation
TEST_P(Texture2DTestES3Foveation,DrawThenEnableFoveationAndDraw)12454 TEST_P(Texture2DTestES3Foveation, DrawThenEnableFoveationAndDraw)
12455 {
12456     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12457 
12458     // Switch to foveated framebuffer
12459     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12460 
12461     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12462 
12463     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12464     glUseProgram(program);
12465 
12466     // Clear
12467     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12468     glClear(GL_COLOR_BUFFER_BIT);
12469     EXPECT_GL_NO_ERROR();
12470 
12471     // Draw
12472     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12473     EXPECT_GL_NO_ERROR();
12474 
12475     // Configure foveated rendering for framebuffer
12476     // Just need 1 focal point
12477     GLuint providedFeatures = 0;
12478     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12479                                      &providedFeatures);
12480     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12481     // Set foveation parameters
12482     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12483     EXPECT_GL_NO_ERROR();
12484 
12485     // Draw
12486     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12487     EXPECT_GL_NO_ERROR();
12488 
12489     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12490 }
12491 
12492 // QCOM framebuffer foveated rendering + draw, change foveation parameters and then draw
TEST_P(Texture2DTestES3Foveation,DrawChangeFoveationParametersThenDraw)12493 TEST_P(Texture2DTestES3Foveation, DrawChangeFoveationParametersThenDraw)
12494 {
12495     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12496 
12497     // Switch to foveated framebuffer
12498     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12499 
12500     // Just need 1 focal point
12501     GLuint providedFeatures = 0;
12502     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12503                                      &providedFeatures);
12504     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12505     // Set foveation parameters
12506     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12507     EXPECT_GL_NO_ERROR();
12508 
12509     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12510     glUseProgram(greenProgram);
12511 
12512     // Draw
12513     drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12514     EXPECT_GL_NO_ERROR();
12515 
12516     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12517 
12518     // Change foveation parameters
12519     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.5f, 0.5f, 3.0f, 3.0f, 3.0f);
12520     EXPECT_GL_NO_ERROR();
12521 
12522     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12523     glUseProgram(blueProgram);
12524 
12525     // Draw
12526     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12527     EXPECT_GL_NO_ERROR();
12528 
12529     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12530 }
12531 
12532 // QCOM framebuffer foveated rendering + draw and use as blit source
TEST_P(Texture2DTestES3Foveation,DrawThenUseAsBlitSource)12533 TEST_P(Texture2DTestES3Foveation, DrawThenUseAsBlitSource)
12534 {
12535     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12536 
12537     // Switch to foveated framebuffer
12538     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12539 
12540     glActiveTexture(GL_TEXTURE0);
12541     glBindTexture(GL_TEXTURE_2D, mTexture2D);
12542 
12543     const GLsizei kSizeW = getWindowWidth();
12544     const GLsizei kSizeH = getWindowHeight();
12545     std::vector<GLColor> data(kSizeW * kSizeH, GLColor::blue);
12546     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSizeW, kSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12547                  data.data());
12548     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12549     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12550     EXPECT_GL_NO_ERROR();
12551 
12552     // Just need 1 focal point
12553     GLuint providedFeatures = 0;
12554     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12555                                      &providedFeatures);
12556     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12557     // Set foveation parameters
12558     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12559     EXPECT_GL_NO_ERROR();
12560 
12561     glUseProgram(mProgram);
12562 
12563     // Verify
12564     drawQuad(mProgram, "position", 0.5f);
12565     EXPECT_GL_NO_ERROR();
12566 
12567     // Blit data from foveated framebuffer into default framebuffer
12568     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
12569     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
12570     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
12571                       getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
12572 
12573     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12574 }
12575 
12576 // QCOM framebuffer foveated rendering + draw and use as blit target
TEST_P(Texture2DTestES3Foveation,DrawThenUseAsBlitTarget)12577 TEST_P(Texture2DTestES3Foveation, DrawThenUseAsBlitTarget)
12578 {
12579     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12580 
12581     // Switch to foveated framebuffer
12582     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12583 
12584     // Just need 1 focal point
12585     GLuint providedFeatures = 0;
12586     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12587                                      &providedFeatures);
12588     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12589     // Set foveation parameters
12590     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12591     EXPECT_GL_NO_ERROR();
12592 
12593     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12594     glUseProgram(greenProgram);
12595 
12596     // Draw
12597     drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12598     EXPECT_GL_NO_ERROR();
12599     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12600 
12601     // Switch to default framebuffer and clear to blue
12602     glBindFramebuffer(GL_FRAMEBUFFER, 0);
12603     EXPECT_GL_NO_ERROR();
12604     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12605     glClear(GL_COLOR_BUFFER_BIT);
12606     EXPECT_GL_NO_ERROR();
12607 
12608     // Blit data from default framebuffer into foveated framebuffer
12609     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
12610     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
12611     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
12612                       getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
12613 
12614     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12615 }
12616 
12617 // QCOM framebuffer foveated rendering, reuse texture between 2 foveated framebuffers
TEST_P(Texture2DTestES3Foveation,ReuseTextureForFoveatedDraw)12618 TEST_P(Texture2DTestES3Foveation, ReuseTextureForFoveatedDraw)
12619 {
12620     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12621 
12622     // Switch to foveated framebuffer
12623     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12624 
12625     // Just need 1 focal point
12626     GLuint providedFeatures = 0;
12627     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12628                                      &providedFeatures);
12629     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12630     // Set foveation parameters
12631     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12632     EXPECT_GL_NO_ERROR();
12633 
12634     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12635     glUseProgram(greenProgram);
12636 
12637     // Draw
12638     drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12639     EXPECT_GL_NO_ERROR();
12640 
12641     // Create another framebuffer
12642     GLFramebuffer framebuffer;
12643     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
12644 
12645     // Resuse texture from mFramebuffer
12646     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12647                            mFramebufferColorTexture, 0);
12648 
12649     // Configure foveation parameters of the new framebuffer
12650     // Just need 1 focal point
12651     providedFeatures = 0;
12652     glFramebufferFoveationConfigQCOM(framebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12653                                      &providedFeatures);
12654     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12655     // Set foveation parameters
12656     glFramebufferFoveationParametersQCOM(framebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12657     EXPECT_GL_NO_ERROR();
12658 
12659     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12660     glUseProgram(blueProgram);
12661 
12662     // Draw
12663     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12664     EXPECT_GL_NO_ERROR();
12665 
12666     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12667 }
12668 
12669 // QCOM framebuffer foveated rendering with MSAA framebuffer
TEST_P(Texture2DTestES3Foveation,DrawWithMsaaFramebuffer)12670 TEST_P(Texture2DTestES3Foveation, DrawWithMsaaFramebuffer)
12671 {
12672     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12673     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
12674 
12675     // Create a new MSAA framebuffer
12676     GLFramebuffer msaaFramebuffer;
12677     glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
12678     GLTexture texture;
12679     glActiveTexture(GL_TEXTURE0);
12680     glBindTexture(GL_TEXTURE_2D, texture);
12681     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
12682                  GL_UNSIGNED_BYTE, nullptr);
12683     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12684     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12685     EXPECT_GL_NO_ERROR();
12686 
12687     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12688                                          texture, 0, 4);
12689     ASSERT_GL_NO_ERROR();
12690     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12691 
12692     // Just need 1 focal point
12693     GLuint providedFeatures = 0;
12694     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12695                                      &providedFeatures);
12696     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12697     // Set foveation parameters
12698     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12699     EXPECT_GL_NO_ERROR();
12700 
12701     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12702     glUseProgram(program);
12703 
12704     // Clear
12705     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12706     glClear(GL_COLOR_BUFFER_BIT);
12707     EXPECT_GL_NO_ERROR();
12708 
12709     // Draw
12710     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12711     EXPECT_GL_NO_ERROR();
12712 
12713     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12714 }
12715 
12716 // QCOM framebuffer foveated rendering with multiple attachments
TEST_P(Texture2DTestES3Foveation,DrawWithMultipleAttachments)12717 TEST_P(Texture2DTestES3Foveation, DrawWithMultipleAttachments)
12718 {
12719     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12720 
12721     const GLsizei kSizeW = getWindowWidth();
12722     const GLsizei kSizeH = getWindowHeight();
12723 
12724     // Setup sampling texture
12725     glBindTexture(GL_TEXTURE_2D, mTexture2D);
12726 
12727     std::vector<GLColor> data(kSizeW * kSizeH);
12728     // Generate red / blue checkered pattern
12729     for (int i = 0; i < kSizeH; i++)
12730     {
12731         for (int j = 0; j < kSizeW; j++)
12732         {
12733             data[(i * kSizeW) + j] = ((i + j) % 2 == 0) ? GLColor::red : GLColor::blue;
12734         }
12735     }
12736 
12737     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSizeW, kSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12738                  data.data());
12739     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12740     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12741     EXPECT_GL_NO_ERROR();
12742 
12743     // Draw without foveation
12744     glActiveTexture(GL_TEXTURE0);
12745     glBindTexture(GL_TEXTURE_2D, mTexture2D);
12746 
12747     glBindFramebuffer(GL_FRAMEBUFFER, 0);
12748     glUseProgram(mProgram);
12749     drawQuad(mProgram, "position", 0.5f);
12750     EXPECT_GL_NO_ERROR();
12751 
12752     // Record original data
12753     std::vector<GLColor> originalData(kSizeW * kSizeH, {0, 0, 0, 0});
12754     glReadPixels(0, 0, kSizeW, kSizeH, GL_RGBA, GL_UNSIGNED_BYTE, originalData.data());
12755 
12756     // Switch to foveated framebuffer
12757     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12758 
12759     // Setup mutliple color attachments
12760     std::array<GLTexture, 3> colorAttachments;
12761     GLenum attachmentBase  = GL_COLOR_ATTACHMENT0;
12762     GLuint attachmentIndex = 0;
12763     for (GLTexture &attachment : colorAttachments)
12764     {
12765         glBindTexture(GL_TEXTURE_2D, attachment);
12766         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSizeW, kSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12767                      nullptr);
12768         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12769         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12770         EXPECT_GL_NO_ERROR();
12771 
12772         glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentBase + attachmentIndex, GL_TEXTURE_2D,
12773                                attachment, 0);
12774         ASSERT_GL_NO_ERROR();
12775         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12776 
12777         glBindTexture(GL_TEXTURE_2D, 0);
12778 
12779         attachmentIndex++;
12780     }
12781 
12782     // Setup foveation parameters, just need 1 focal point
12783     GLuint providedFeatures = 0;
12784     glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12785                                      &providedFeatures);
12786     ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12787 
12788     glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12789     EXPECT_GL_NO_ERROR();
12790 
12791     constexpr char kFS[] = R"(#version 300 es
12792 precision highp float;
12793 
12794 in vec2 texcoord;
12795 uniform sampler2D tex;
12796 
12797 layout(location = 0) out vec4 color0;
12798 layout(location = 1) out vec4 color1;
12799 layout(location = 2) out vec4 color2;
12800 
12801 void main()
12802 {
12803     vec4 fragColor = texture(tex, texcoord);
12804     color0 = fragColor;
12805     color1 = fragColor;
12806     color2 = fragColor;
12807 })";
12808 
12809     ANGLE_GL_PROGRAM(program, getVertexShaderSource(), kFS);
12810     glUseProgram(program);
12811 
12812     std::array<GLenum, 3> drawBuffers = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
12813                                          GL_COLOR_ATTACHMENT2};
12814     glDrawBuffers(3, drawBuffers.data());
12815 
12816     // Draw with foveation into multiple attachments
12817     glActiveTexture(GL_TEXTURE0);
12818     glBindTexture(GL_TEXTURE_2D, mTexture2D);
12819     drawQuad(program, "position", 0.5f);
12820     EXPECT_GL_NO_ERROR();
12821 
12822     // Verify
12823     GLFramebuffer readFBO;
12824     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
12825 
12826     // Use colorAttachments[0]'s content as reference data
12827     std::vector<GLColor> referenceData(kSizeW * kSizeH, {0, 0, 0, 0});
12828     std::vector<GLColor> result(kSizeW * kSizeH, {0, 0, 0, 0});
12829     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12830                            colorAttachments[0], 0);
12831     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
12832     glReadPixels(0, 0, kSizeW, kSizeH, GL_RGBA, GL_UNSIGNED_BYTE, referenceData.data());
12833 
12834     // Foveated rendering should produce content that differs from original data
12835     ASSERT(originalData != referenceData);
12836 
12837     // Verify rest of the attachments
12838     for (size_t index = 1; index < colorAttachments.size(); index++)
12839     {
12840         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12841                                colorAttachments[index], 0);
12842         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
12843 
12844         result.assign(result.size(), {0, 0, 0, 0});
12845         glReadPixels(0, 0, kSizeW, kSizeH, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
12846 
12847         ASSERT(referenceData == result);
12848     }
12849 }
12850 
12851 // QCOM texture foveated rendering, basic draw
TEST_P(Texture2DTestES3Foveation,FoveatedTextureDraw)12852 TEST_P(Texture2DTestES3Foveation, FoveatedTextureDraw)
12853 {
12854     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_texture_foveated"));
12855 
12856     // Create non-foveated framebuffer
12857     GLFramebuffer framebuffer;
12858     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
12859     glActiveTexture(GL_TEXTURE0);
12860     glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
12861     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12862                            mFramebufferColorTexture, 0);
12863     ASSERT_GL_NO_ERROR();
12864     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12865 
12866     // Render before configuring foveation on the texture
12867     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12868     glUseProgram(greenProgram);
12869 
12870     // Clear
12871     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12872     glClear(GL_COLOR_BUFFER_BIT);
12873     EXPECT_GL_NO_ERROR();
12874 
12875     // Draw
12876     drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12877     EXPECT_GL_NO_ERROR();
12878 
12879     // Configure foveation for the texture
12880     GLint supportedFoveationFeatures = 0;
12881     glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM,
12882                         &supportedFoveationFeatures);
12883     ASSERT_EQ(supportedFoveationFeatures & GL_FOVEATION_ENABLE_BIT_QCOM,
12884               GL_FOVEATION_ENABLE_BIT_QCOM);
12885     GLint supportedNumFocalPoints = 0;
12886     glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM,
12887                         &supportedNumFocalPoints);
12888     ASSERT_GE(supportedNumFocalPoints, 1);
12889     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12890                     GL_FOVEATION_ENABLE_BIT_QCOM);
12891     EXPECT_GL_NO_ERROR();
12892 
12893     // Set foveation parameters
12894     glTextureFoveationParametersQCOM(mFramebufferColorTexture, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12895     EXPECT_GL_NO_ERROR();
12896 
12897     // Render and verify after configuring foveation on the texture
12898     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12899     glUseProgram(blueProgram);
12900 
12901     // Clear
12902     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
12903     glClear(GL_COLOR_BUFFER_BIT);
12904     EXPECT_GL_NO_ERROR();
12905 
12906     // Draw
12907     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12908     EXPECT_GL_NO_ERROR();
12909 
12910     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12911 }
12912 
12913 // QCOM texture foveated rendering to MSAA texture followed by a blit
TEST_P(Texture2DTestES31Foveation,MsaaTextureDrawThenUseAsBlitSource)12914 TEST_P(Texture2DTestES31Foveation, MsaaTextureDrawThenUseAsBlitSource)
12915 {
12916     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_texture_foveated"));
12917 
12918     // Create a non-foveated framebuffer
12919     GLFramebuffer framebuffer;
12920     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
12921 
12922     // Create an msaa texture and bind to framebuffer
12923     GLTexture textureMS;
12924     glActiveTexture(GL_TEXTURE0);
12925     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS);
12926     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, getWindowWidth(),
12927                               getWindowHeight(), GL_TRUE);
12928     EXPECT_GL_NO_ERROR();
12929 
12930     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
12931                            textureMS, 0);
12932     ASSERT_GL_NO_ERROR();
12933     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12934 
12935     // Just need 1 focal point
12936     glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12937                     GL_FOVEATION_ENABLE_BIT_QCOM);
12938     EXPECT_GL_NO_ERROR();
12939 
12940     // Set foveation parameters
12941     glTextureFoveationParametersQCOM(textureMS, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12942     EXPECT_GL_NO_ERROR();
12943 
12944     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12945     glUseProgram(program);
12946 
12947     // Clear
12948     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12949     glClear(GL_COLOR_BUFFER_BIT);
12950     EXPECT_GL_NO_ERROR();
12951 
12952     // Draw
12953     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12954     EXPECT_GL_NO_ERROR();
12955 
12956     // Blit data from framebuffer with foveated texture into default framebuffer
12957     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
12958     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
12959     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
12960                       getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
12961 
12962     glBindFramebuffer(GL_FRAMEBUFFER, 0);
12963     EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12964 }
12965 
12966 // Enabling mipmap filtering after previously having used the texture without it should work.
TEST_P(Texture2DTestES3,NoMipmapDrawThenMipmapDraw)12967 TEST_P(Texture2DTestES3, NoMipmapDrawThenMipmapDraw)
12968 {
12969     glActiveTexture(GL_TEXTURE0);
12970     glBindTexture(GL_TEXTURE_2D, mTexture2D);
12971 
12972     constexpr const GLsizei kSize = 8;
12973     const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
12974     const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
12975 
12976     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12977                  kLevel0Data.data());
12978     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12979     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12980     EXPECT_GL_NO_ERROR();
12981 
12982     // Draw so the texture's image is allocated.
12983     drawQuad(mProgram, "position", 0.5f);
12984     EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
12985 
12986     // Specify the rest of the image
12987     for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
12988     {
12989         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
12990                      GL_UNSIGNED_BYTE, kLevelOtherData.data());
12991     }
12992     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
12993 
12994     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
12995     glUseProgram(program);
12996     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
12997     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
12998     ASSERT_NE(-1, textureLoc);
12999     ASSERT_NE(-1, lodLoc);
13000     glUniform1i(textureLoc, 0);
13001 
13002     // Verify the mips
13003     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13004     {
13005         glUniform1f(lodLoc, mip);
13006         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13007         EXPECT_GL_NO_ERROR();
13008         EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
13009     }
13010 }
13011 
13012 // Disabling mipmap filtering after previously having used the texture with it should work.
TEST_P(Texture2DTestES3,MipmapDrawThenNoMipmapDraw)13013 TEST_P(Texture2DTestES3, MipmapDrawThenNoMipmapDraw)
13014 {
13015     glActiveTexture(GL_TEXTURE0);
13016     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13017 
13018     constexpr const GLsizei kSize = 8;
13019     const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
13020     const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
13021 
13022     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13023                  kLevel0Data.data());
13024     for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
13025     {
13026         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
13027                      GL_UNSIGNED_BYTE, kLevelOtherData.data());
13028     }
13029     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
13030     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13031     EXPECT_GL_NO_ERROR();
13032 
13033     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
13034     glUseProgram(program);
13035     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
13036     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
13037     ASSERT_NE(-1, textureLoc);
13038     ASSERT_NE(-1, lodLoc);
13039     glUniform1i(textureLoc, 0);
13040 
13041     // Verify the mips.
13042     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13043     {
13044         glUniform1f(lodLoc, mip);
13045         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13046         EXPECT_GL_NO_ERROR();
13047         EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
13048     }
13049 
13050     // Disable mipmapping and verify mips again.
13051     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13052 
13053     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13054     {
13055         glUniform1f(lodLoc, mip);
13056         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13057         EXPECT_GL_NO_ERROR();
13058         EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
13059     }
13060 }
13061 
13062 // Respecify texture with more mips.
TEST_P(Texture2DTestES3,RespecifyWithMoreMips)13063 TEST_P(Texture2DTestES3, RespecifyWithMoreMips)
13064 {
13065     glActiveTexture(GL_TEXTURE0);
13066     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13067 
13068     constexpr const GLsizei kSize = 8;
13069     const std::vector<GLColor> kLevelEvenData(kSize * kSize, GLColor::blue);
13070     const std::vector<GLColor> kLevelOddData(kSize * kSize * 4, GLColor::red);
13071 
13072     auto getLevelData = [&](GLint mip) {
13073         return mip % 2 == 0 ? kLevelEvenData.data() : kLevelOddData.data();
13074     };
13075 
13076     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13077     {
13078         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
13079                      GL_UNSIGNED_BYTE, getLevelData(mip));
13080     }
13081     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
13082     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13083     EXPECT_GL_NO_ERROR();
13084 
13085     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
13086     glUseProgram(program);
13087     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
13088     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
13089     ASSERT_NE(-1, textureLoc);
13090     ASSERT_NE(-1, lodLoc);
13091     glUniform1i(textureLoc, 0);
13092 
13093     // Verify the mips.
13094     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13095     {
13096         glUniform1f(lodLoc, mip);
13097         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13098         EXPECT_GL_NO_ERROR();
13099         EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip)[0]);
13100     }
13101 
13102     // Respecify the texture with more mips, without changing any parameters.
13103     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13104                  kLevelOddData.data());
13105     for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13106     {
13107         glTexImage2D(GL_TEXTURE_2D, mip + 1, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
13108                      GL_UNSIGNED_BYTE, getLevelData(mip));
13109     }
13110 
13111     // Verify the mips.
13112     for (GLint mip = 0; ((kSize * 2) >> mip) >= 1; ++mip)
13113     {
13114         glUniform1f(lodLoc, mip);
13115         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13116         EXPECT_GL_NO_ERROR();
13117         EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip - 1)[0]);
13118     }
13119 }
13120 
13121 // Covers a bug in the D3D11 backend: http://anglebug.com/42261476
13122 // When using a sampler the texture was created as if it has mipmaps,
13123 // regardless what you specified in GL_TEXTURE_MIN_FILTER via
13124 // glSamplerParameteri() -- mistakenly the default value
13125 // GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
13126 // evaluated.
13127 // If you didn't provide mipmaps and didn't let the driver generate them
13128 // this led to not sampling your texture data when minification occurred.
TEST_P(Texture2DTestES3,MinificationWithSamplerNoMipmapping)13129 TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
13130 {
13131     constexpr char kVS[] =
13132         "#version 300 es\n"
13133         "out vec2 texcoord;\n"
13134         "in vec4 position;\n"
13135         "void main()\n"
13136         "{\n"
13137         "    gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
13138         "    texcoord = (position.xy * 0.5) + 0.5;\n"
13139         "}\n";
13140 
13141     constexpr char kFS[] =
13142         "#version 300 es\n"
13143         "precision highp float;\n"
13144         "uniform highp sampler2D tex;\n"
13145         "in vec2 texcoord;\n"
13146         "out vec4 fragColor;\n"
13147         "void main()\n"
13148         "{\n"
13149         "    fragColor = texture(tex, texcoord);\n"
13150         "}\n";
13151 
13152     ANGLE_GL_PROGRAM(program, kVS, kFS);
13153 
13154     GLSampler sampler;
13155     glBindSampler(0, sampler);
13156     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13157     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13158 
13159     glActiveTexture(GL_TEXTURE0);
13160     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13161 
13162     const GLsizei texWidth  = getWindowWidth();
13163     const GLsizei texHeight = getWindowHeight();
13164     const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
13165 
13166     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13167                  whiteData.data());
13168     EXPECT_GL_NO_ERROR();
13169 
13170     drawQuad(program, "position", 0.5f);
13171     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
13172 }
13173 
testUploadThenUseInDifferentStages(const std::vector<UploadThenUseStageParam> & uses)13174 void Texture2DTest::testUploadThenUseInDifferentStages(
13175     const std::vector<UploadThenUseStageParam> &uses)
13176 {
13177     constexpr char kVSSampleVS[] = R"(attribute vec4 a_position;
13178 uniform sampler2D u_tex2D;
13179 varying vec4 v_color;
13180 
13181 void main()
13182 {
13183     gl_Position = vec4(a_position.xy, 0.0, 1.0);
13184     v_color = texture2D(u_tex2D, a_position.xy * 0.5 + vec2(0.5));
13185 })";
13186 
13187     constexpr char kVSSampleFS[] = R"(precision mediump float;
13188 varying vec4 v_color;
13189 
13190 void main()
13191 {
13192     gl_FragColor = v_color;
13193 })";
13194 
13195     ANGLE_GL_PROGRAM(sampleInVS, kVSSampleVS, kVSSampleFS);
13196     ANGLE_GL_PROGRAM(sampleInFS, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
13197 
13198     GLFramebuffer fbo[2];
13199     GLTexture color[2];
13200     for (uint32_t i = 0; i < 2; ++i)
13201     {
13202         glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
13203         glBindTexture(GL_TEXTURE_2D, color[i]);
13204         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
13205         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color[i], 0);
13206     }
13207 
13208     const GLColor kImageColor(63, 31, 0, 255);
13209 
13210     GLTexture tex;
13211     glBindTexture(GL_TEXTURE_2D, tex);
13212     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kImageColor);
13213     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13214     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13215     glActiveTexture(GL_TEXTURE0);
13216     ASSERT_GL_NO_ERROR();
13217 
13218     glEnable(GL_BLEND);
13219     glBlendFunc(GL_ONE, GL_ONE);
13220 
13221     glClearColor(0, 0, 0, 1);
13222 
13223     glBindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
13224     glClear(GL_COLOR_BUFFER_BIT);
13225     glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
13226     glClear(GL_COLOR_BUFFER_BIT);
13227 
13228     uint32_t curFboIndex     = 0;
13229     uint32_t fboDrawCount[2] = {};
13230 
13231     for (const UploadThenUseStageParam &use : uses)
13232     {
13233         const GLProgram &program = use.useStage == GL_VERTEX_SHADER ? sampleInVS : sampleInFS;
13234         drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
13235         ASSERT_GL_NO_ERROR();
13236 
13237         ++fboDrawCount[curFboIndex];
13238 
13239         if (use.closeRenderPassAfterUse)
13240         {
13241             // Close the render pass without accidentally incurring additional barriers.
13242             curFboIndex = 1 - curFboIndex;
13243             glBindFramebuffer(GL_FRAMEBUFFER, fbo[curFboIndex]);
13244         }
13245     }
13246 
13247     // Make sure the transfer operations below aren't reordered with the rendering above and thus
13248     // introduce additional synchronization.
13249     glFinish();
13250 
13251     for (uint32_t i = 0; i < 2; ++i)
13252     {
13253         const GLColor kExpectedColor(63 * std::min(4u, fboDrawCount[i]),
13254                                      31 * std::min(8u, fboDrawCount[i]), 0, 255);
13255 
13256         glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
13257         EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor);
13258     }
13259 }
13260 
13261 // Test synchronization when a texture is used in different shader stages after data upload.
13262 //
13263 // - Use in VS
13264 // - Use in FS
TEST_P(Texture2DTest,UploadThenVSThenFS)13265 TEST_P(Texture2DTest, UploadThenVSThenFS)
13266 {
13267     testUploadThenUseInDifferentStages({
13268         {GL_VERTEX_SHADER, false},
13269         {GL_FRAGMENT_SHADER, false},
13270     });
13271 }
13272 
13273 // Test synchronization when a texture is used in different shader stages after data upload.
13274 //
13275 // - Use in VS
13276 // - Break render pass
13277 // - Use in FS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFS)13278 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFS)
13279 {
13280     testUploadThenUseInDifferentStages({
13281         {GL_VERTEX_SHADER, true},
13282         {GL_FRAGMENT_SHADER, false},
13283     });
13284 }
13285 
13286 // Test synchronization when a texture is used in different shader stages after data upload.
13287 //
13288 // - Use in FS
13289 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenVS)13290 TEST_P(Texture2DTest, UploadThenFSThenVS)
13291 {
13292     testUploadThenUseInDifferentStages({
13293         {GL_FRAGMENT_SHADER, false},
13294         {GL_VERTEX_SHADER, false},
13295     });
13296 }
13297 
13298 // Test synchronization when a texture is used in different shader stages after data upload.
13299 //
13300 // - Use in FS
13301 // - Break render pass
13302 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenVS)13303 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenVS)
13304 {
13305     testUploadThenUseInDifferentStages({
13306         {GL_FRAGMENT_SHADER, true},
13307         {GL_VERTEX_SHADER, false},
13308     });
13309 }
13310 
13311 // Test synchronization when a texture is used in different shader stages after data upload.
13312 //
13313 // - Use in VS
13314 // - Use in FS
13315 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenFSThenVS)13316 TEST_P(Texture2DTest, UploadThenVSThenFSThenVS)
13317 {
13318     testUploadThenUseInDifferentStages({
13319         {GL_VERTEX_SHADER, false},
13320         {GL_FRAGMENT_SHADER, false},
13321         {GL_VERTEX_SHADER, false},
13322     });
13323 }
13324 
13325 // Test synchronization when a texture is used in different shader stages after data upload.
13326 //
13327 // - Use in VS
13328 // - Break render pass
13329 // - Use in FS
13330 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFSThenVS)13331 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFSThenVS)
13332 {
13333     testUploadThenUseInDifferentStages({
13334         {GL_VERTEX_SHADER, true},
13335         {GL_FRAGMENT_SHADER, false},
13336         {GL_VERTEX_SHADER, false},
13337     });
13338 }
13339 
13340 // Test synchronization when a texture is used in different shader stages after data upload.
13341 //
13342 // - Use in VS
13343 // - Break render pass
13344 // - Use in FS
13345 // - Break render pass
13346 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFSThenNewRPThenVS)13347 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFSThenNewRPThenVS)
13348 {
13349     testUploadThenUseInDifferentStages({
13350         {GL_VERTEX_SHADER, true},
13351         {GL_FRAGMENT_SHADER, true},
13352         {GL_VERTEX_SHADER, false},
13353     });
13354 }
13355 
13356 // Test synchronization when a texture is used in different shader stages after data upload.
13357 //
13358 // - Use in FS
13359 // - Use in VS
13360 // - Break render pass
13361 // - Use in FS
TEST_P(Texture2DTest,UploadThenFSThenVSThenNewRPThenFS)13362 TEST_P(Texture2DTest, UploadThenFSThenVSThenNewRPThenFS)
13363 {
13364     testUploadThenUseInDifferentStages({
13365         {GL_FRAGMENT_SHADER, false},
13366         {GL_VERTEX_SHADER, true},
13367         {GL_FRAGMENT_SHADER, false},
13368     });
13369 }
13370 
13371 // Test synchronization when a texture is used in different shader stages after data upload.
13372 //
13373 // - Use in FS
13374 // - Break render pass
13375 // - Use in VS
13376 // - Use in FS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenVSThenFS)13377 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenVSThenFS)
13378 {
13379     testUploadThenUseInDifferentStages({
13380         {GL_FRAGMENT_SHADER, true},
13381         {GL_VERTEX_SHADER, false},
13382         {GL_FRAGMENT_SHADER, false},
13383     });
13384 }
13385 
13386 // Test synchronization when a texture is used in different shader stages after data upload.
13387 //
13388 // - Use in FS
13389 // - Break render pass
13390 // - Use in FS
13391 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenFSThenVS)13392 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenFSThenVS)
13393 {
13394     testUploadThenUseInDifferentStages({
13395         {GL_FRAGMENT_SHADER, true},
13396         {GL_FRAGMENT_SHADER, false},
13397         {GL_VERTEX_SHADER, false},
13398     });
13399 }
13400 
13401 // Test that interleaved updates and draw calls many times work
TEST_P(Texture2DTest,DrawThenUpdateMultipleTimes)13402 TEST_P(Texture2DTest, DrawThenUpdateMultipleTimes)
13403 {
13404     constexpr uint32_t kTexWidth  = 16;
13405     constexpr uint32_t kTexHeight = 16;
13406     constexpr uint32_t kBpp       = 4;
13407 
13408     // Create the texture
13409     glActiveTexture(GL_TEXTURE0);
13410     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13411     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13412     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13413     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13414                  nullptr);
13415     EXPECT_GL_ERROR(GL_NO_ERROR);
13416 
13417     constexpr GLubyte kInitialColor = 16;
13418     GLubyte expectedFinalColorValue = kInitialColor;
13419     glEnable(GL_BLEND);
13420     glBlendFunc(GL_ONE, GL_ONE);
13421     glClearColor(0, 0, 0, 0);
13422     glClear(GL_COLOR_BUFFER_BIT);
13423 
13424     // First draw the screen with initial color
13425     {
13426         ANGLE_GL_PROGRAM(colorProgram, angle::essl1_shaders::vs::Simple(),
13427                          angle::essl1_shaders::fs::UniformColor());
13428         glUseProgram(colorProgram);
13429         GLint colorUniformLocation =
13430             glGetUniformLocation(colorProgram, angle::essl1_shaders::ColorUniform());
13431         ASSERT_NE(colorUniformLocation, -1);
13432         glUniform4f(colorUniformLocation, kInitialColor / 256.f, kInitialColor / 256.f,
13433                     kInitialColor / 256.f, kInitialColor / 256.f);
13434         drawQuad(colorProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
13435     }
13436 
13437     // Then update the texture then draw it multiple times
13438     constexpr GLubyte kColorsToUpdate[] = {16, 64, 64};
13439     setUpProgram();
13440     glUseProgram(mProgram);
13441     glUniform1i(mTexture2DUniformLocation, 0);
13442 
13443     for (auto color : kColorsToUpdate)
13444     {
13445         expectedFinalColorValue += color;
13446         std::vector<GLubyte> fullTextureData(kTexWidth * kTexHeight * kBpp, color);
13447         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
13448                         fullTextureData.data());
13449 
13450         drawQuad(mProgram, "position", 0.5f);
13451     }
13452 
13453     // The final color should be sum of all updated colors.
13454     const GLColor expectedFinalColor(expectedFinalColorValue, expectedFinalColorValue,
13455                                      expectedFinalColorValue, expectedFinalColorValue);
13456     EXPECT_GL_NO_ERROR();
13457     EXPECT_PIXEL_COLOR_EQ(1 * getWindowWidth() / 4, getWindowHeight() / 2, expectedFinalColor);
13458 }
13459 
13460 // Test that clears due to emulated formats are to the correct level given non-zero base level.
TEST_P(Texture2DTestES3,NonZeroBaseEmulatedClear)13461 TEST_P(Texture2DTestES3, NonZeroBaseEmulatedClear)
13462 {
13463     // Tests behavior of the Vulkan backend with emulated formats.
13464     ANGLE_SKIP_TEST_IF(!IsVulkan());
13465 
13466     // TODO(http://anglebug.com/42266496): Skip when using VMA image suballocation on Linux/Intel.
13467     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() &&
13468                        getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
13469 
13470     // This test assumes GL_RGB is always emulated, which overrides the
13471     // Feature::AllocateNonZeroMemory memory feature, clearing the memory to zero. However, if the
13472     // format is *not* emulated and the feature Feature::AllocateNonZeroMemory is enabled, the
13473     // texture memory will contain non-zero memory, which means the color is not black (causing the
13474     // test to fail).
13475     ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::AllocateNonZeroMemory));
13476 
13477     setUpProgram();
13478 
13479     glActiveTexture(GL_TEXTURE0);
13480     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13481     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13482     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13483     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13484     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13485     glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13486     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
13487     EXPECT_GL_NO_ERROR();
13488 
13489     drawQuad(mProgram, "position", 0.5f);
13490 
13491     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
13492 }
13493 
13494 // Test that uploading data to buffer that's in use then using it as PBO to update a texture works.
TEST_P(Texture2DTestES3,UseAsUBOThenUpdateThenAsPBO)13495 TEST_P(Texture2DTestES3, UseAsUBOThenUpdateThenAsPBO)
13496 {
13497     const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
13498                                                  GLColor::red};
13499     const std::array<GLColor, 4> kUpdateData  = {GLColor::blue, GLColor::blue, GLColor::blue,
13500                                                  GLColor::blue};
13501 
13502     GLBuffer buffer;
13503     glBindBuffer(GL_UNIFORM_BUFFER, buffer);
13504     glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_COPY);
13505     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
13506     EXPECT_GL_NO_ERROR();
13507 
13508     constexpr char kVerifyUBO[] = R"(#version 300 es
13509 precision mediump float;
13510 uniform block {
13511     uvec4 data;
13512 } ubo;
13513 out vec4 colorOut;
13514 void main()
13515 {
13516     if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
13517         colorOut = vec4(0, 1.0, 0, 1.0);
13518     else
13519         colorOut = vec4(1.0, 0, 0, 1.0);
13520 })";
13521 
13522     ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
13523     drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
13524     EXPECT_GL_NO_ERROR();
13525 
13526     // Update buffer data
13527     glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
13528     EXPECT_GL_NO_ERROR();
13529 
13530     // Bind as PBO
13531     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
13532     EXPECT_GL_NO_ERROR();
13533 
13534     // Upload from PBO to texture
13535     GLTexture tex;
13536     glBindTexture(GL_TEXTURE_2D, tex);
13537     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
13538     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
13539     EXPECT_GL_NO_ERROR();
13540 
13541     // Make sure uniform data is correct.
13542     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
13543 
13544     // Make sure the texture data is correct.
13545     GLFramebuffer fbo;
13546     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
13547     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
13548     EXPECT_GL_NO_ERROR();
13549     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
13550 
13551     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
13552 }
13553 
13554 // Test if the RenderTargetCache is updated when the TextureStorage object is freed
TEST_P(Texture2DTestES3,UpdateRenderTargetCacheOnDestroyTexStorage)13555 TEST_P(Texture2DTestES3, UpdateRenderTargetCacheOnDestroyTexStorage)
13556 {
13557     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
13558     const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
13559 
13560     GLTexture tex;
13561     GLFramebuffer fb;
13562     glBindTexture(GL_TEXTURE_2D, tex);
13563     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 100, 1);
13564     glBindFramebuffer(GL_FRAMEBUFFER, fb);
13565     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
13566     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments);
13567     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
13568     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 1.0f);
13569     EXPECT_GL_NO_ERROR();
13570 
13571     EXPECT_PIXEL_RECT_EQ(0, 0, 100, 1, GLColor::red);
13572 }
13573 
13574 // Test that we can allocate at least 4096 images, which is the maximum allocation count on some
13575 // platforms. Image suballocation should enable us to allocate more than this limit.
TEST_P(Texture2DTestES3,AllocateMoreThan4096Textures)13576 TEST_P(Texture2DTestES3, AllocateMoreThan4096Textures)
13577 {
13578     ANGLE_SKIP_TEST_IF(!getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
13579 
13580     // The test is skipped when AllocateNonZeroMemory is enabled due to risk of timeout.
13581     ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::AllocateNonZeroMemory));
13582 
13583     constexpr size_t kTextureCount = 8000;
13584     std::vector<GLTexture> textures(kTextureCount);
13585     for (auto &texture : textures)
13586     {
13587         glBindTexture(GL_TEXTURE_2D, texture);
13588         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
13589     }
13590     EXPECT_GL_NO_ERROR();
13591 }
13592 
13593 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
13594 // texture is output.
TEST_P(Texture2DIntegerTestES3,IntegerTextureNonZeroBaseLevel)13595 TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
13596 {
13597     // http://anglebug.com/40644690
13598     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
13599 
13600     glActiveTexture(GL_TEXTURE0);
13601     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13602     int width     = getWindowWidth();
13603     int height    = getWindowHeight();
13604     GLColor color = GLColor::green;
13605     std::vector<GLColor> pixels(width * height, color);
13606     GLint baseLevel = 1;
13607     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
13608     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13609     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13610     glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
13611                  GL_UNSIGNED_BYTE, pixels.data());
13612 
13613     setUpProgram();
13614     glUseProgram(mProgram);
13615     glUniform1i(mTexture2DUniformLocation, 0);
13616     drawQuad(mProgram, "position", 0.5f);
13617 
13618     EXPECT_GL_NO_ERROR();
13619     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13620     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13621 }
13622 
13623 // Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
13624 // the texture is output.
TEST_P(TextureCubeIntegerTestES3,IntegerCubeTextureNonZeroBaseLevel)13625 TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
13626 {
13627     // All output checks returned black, rather than the texture color.
13628     ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL());
13629 
13630     glActiveTexture(GL_TEXTURE0);
13631 
13632     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
13633     GLint baseLevel = 1;
13634     int width       = getWindowWidth();
13635     int height      = getWindowHeight();
13636     GLColor color   = GLColor::green;
13637     std::vector<GLColor> pixels(width * height, color);
13638     for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
13639     {
13640         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
13641                      height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
13642         EXPECT_GL_NO_ERROR();
13643     }
13644     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
13645     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13646     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13647 
13648     glUseProgram(mProgram);
13649     glUniform1i(mTextureCubeUniformLocation, 0);
13650     drawQuad(mProgram, "position", 0.5f);
13651 
13652     EXPECT_GL_NO_ERROR();
13653     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13654     EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
13655     EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
13656     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13657 }
13658 
13659 // This test sets up a cube map with four distincly colored MIP levels.
13660 // The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
13661 // the corners of the screen.
TEST_P(TextureCubeIntegerEdgeTestES3,IntegerCubeTextureCorner)13662 TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
13663 {
13664     glActiveTexture(GL_TEXTURE0);
13665 
13666     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
13667     int width  = getWindowWidth();
13668     int height = getWindowHeight();
13669     ASSERT_EQ(width, height);
13670     GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
13671     for (GLint level = 0; level < 4; level++)
13672     {
13673         for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
13674         {
13675             int levelWidth  = (2 * width) >> level;
13676             int levelHeight = (2 * height) >> level;
13677             std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
13678             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
13679                          levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
13680             EXPECT_GL_NO_ERROR();
13681         }
13682     }
13683     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
13684     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13685     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
13686 
13687     glUseProgram(mProgram);
13688     glUniform1i(mTextureCubeUniformLocation, 0);
13689     drawQuad(mProgram, "position", 0.5f);
13690 
13691     ASSERT_GL_NO_ERROR();
13692     // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
13693     EXPECT_EQ(ReadColor(0, 0).R, 0);
13694     EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
13695     EXPECT_EQ(ReadColor(0, height - 1).R, 0);
13696     EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
13697 }
13698 
13699 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
13700 // texture is output.
TEST_P(Texture2DIntegerProjectiveOffsetTestES3,NonZeroBaseLevel)13701 TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
13702 {
13703     // Fails on AMD: http://crbug.com/967796
13704     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
13705 
13706     glActiveTexture(GL_TEXTURE0);
13707     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13708     int width     = getWindowWidth();
13709     int height    = getWindowHeight();
13710     GLColor color = GLColor::green;
13711     std::vector<GLColor> pixels(width * height, color);
13712     GLint baseLevel = 1;
13713     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
13714     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13715     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13716     glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
13717                  GL_UNSIGNED_BYTE, pixels.data());
13718 
13719     setUpProgram();
13720     glUseProgram(mProgram);
13721     glUniform1i(mTexture2DUniformLocation, 0);
13722     drawQuad(mProgram, "position", 0.5f);
13723 
13724     EXPECT_GL_NO_ERROR();
13725     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13726     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13727 }
13728 
13729 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
13730 // texture is output.
TEST_P(Texture2DArrayIntegerTestES3,NonZeroBaseLevel)13731 TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
13732 {
13733     // Test fail: http://anglebug.com/42264492
13734     ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
13735 
13736     glActiveTexture(GL_TEXTURE0);
13737     glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
13738     int width     = getWindowWidth();
13739     int height    = getWindowHeight();
13740     int depth     = 2;
13741     GLColor color = GLColor::green;
13742     std::vector<GLColor> pixels(width * height * depth, color);
13743     GLint baseLevel = 1;
13744     glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
13745                  GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
13746     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
13747     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13748     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13749 
13750     drawQuad(mProgram, "position", 0.5f);
13751 
13752     EXPECT_GL_NO_ERROR();
13753     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13754     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13755 }
13756 
13757 // Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
13758 // texture is output.
TEST_P(Texture3DIntegerTestES3,NonZeroBaseLevel)13759 TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
13760 {
13761     glActiveTexture(GL_TEXTURE0);
13762     glBindTexture(GL_TEXTURE_3D, mTexture3D);
13763     int width     = getWindowWidth();
13764     int height    = getWindowHeight();
13765     int depth     = 2;
13766     GLColor color = GLColor::green;
13767     std::vector<GLColor> pixels(width * height * depth, color);
13768     GLint baseLevel = 1;
13769     glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
13770                  GL_UNSIGNED_BYTE, pixels.data());
13771     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
13772     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13773     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13774 
13775     drawQuad(mProgram, "position", 0.5f);
13776 
13777     EXPECT_GL_NO_ERROR();
13778     EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13779     EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13780 }
13781 
runCompressedSubImage()13782 void PBOCompressedTextureTest::runCompressedSubImage()
13783 {
13784     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
13785     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
13786     // http://anglebug.com/42262750
13787     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
13788     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
13789 
13790     if (getClientMajorVersion() < 3)
13791     {
13792         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
13793         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
13794         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
13795     }
13796 
13797     const GLuint width  = 4u;
13798     const GLuint height = 4u;
13799 
13800     setWindowWidth(width);
13801     setWindowHeight(height);
13802 
13803     // Setup primary Texture
13804     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13805     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13806     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13807 
13808     if (getClientMajorVersion() < 3)
13809     {
13810         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
13811     }
13812     else
13813     {
13814         glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
13815     }
13816     ASSERT_GL_NO_ERROR();
13817 
13818     // Setup PBO and fill it with a red
13819     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
13820     glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
13821     ASSERT_GL_NO_ERROR();
13822 
13823     // Write PBO to mTexture
13824     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
13825                               width * height / 2u, nullptr);
13826     ASSERT_GL_NO_ERROR();
13827 
13828     setUpProgram();
13829     // Draw using PBO updated texture
13830     glUseProgram(mProgram);
13831     glUniform1i(mTexture2DUniformLocation, 0);
13832     glBindTexture(GL_TEXTURE_2D, mTexture2D);
13833     drawQuad(mProgram, "position", 0.5f);
13834     ASSERT_GL_NO_ERROR();
13835 
13836     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
13837     ASSERT_GL_NO_ERROR();
13838 }
13839 
13840 // Test that uses glCompressedTexSubImage2D combined with a PBO
TEST_P(PBOCompressedTextureTest,PBOCompressedSubImage)13841 TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
13842 {
13843     runCompressedSubImage();
13844 }
13845 
13846 // Verify the row length state is ignored when using compressed tex image calls.
TEST_P(PBOCompressedTextureTest,PBOCompressedSubImageWithUnpackRowLength)13847 TEST_P(PBOCompressedTextureTest, PBOCompressedSubImageWithUnpackRowLength)
13848 {
13849     // ROW_LENGTH requires ES3 or an extension.
13850     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
13851                        !IsGLExtensionEnabled("GL_EXT_unpack_subimage"));
13852 
13853     glPixelStorei(GL_UNPACK_ROW_LENGTH, 1);
13854     runCompressedSubImage();
13855 }
13856 
13857 class PBOCompressedTexture3DTest : public ANGLETest<>
13858 {
13859   protected:
PBOCompressedTexture3DTest()13860     PBOCompressedTexture3DTest() {}
13861 };
13862 
13863 // Test that uses glCompressedTexSubImage3D combined with a PBO
13864 TEST_P(PBOCompressedTexture3DTest, 2DArray)
13865 {
13866     // We use GetTexImage to determine if the internal texture format is emulated
13867     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_get_image"));
13868 
13869     const GLuint width  = 4u;
13870     const GLuint height = 4u;
13871     const GLuint depth  = 1u;
13872 
13873     setWindowWidth(width);
13874     setWindowHeight(height);
13875 
13876     // Setup primary texture as a 2DArray holding ETC2 data
13877     GLTexture texture2DArray;
13878     glBindTexture(GL_TEXTURE_2D_ARRAY, texture2DArray);
13879     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13880     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13881     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_COMPRESSED_RGB8_ETC2, width, height, depth);
13882 
13883     // If the format emulated, we can't transfer it from a PBO
13884     ANGLE_SKIP_TEST_IF(IsFormatEmulated(GL_TEXTURE_2D_ARRAY));
13885 
13886     // Set up a VS that simply passes through position and texcord
13887     const char kVS[] = R"(#version 300 es
13888 in vec4 position;
13889 out vec3 texCoord;
13890 
13891 void main()
13892 {
13893     gl_Position = vec4(position.xy, 0.0, 1.0);
13894     texCoord = vec3(position.xy * 0.5 + vec2(0.5), 0.0);
13895 })";
13896 
13897     // and FS that pulls from the 2DArray, writing out color
13898     const char kFS[] = R"(#version 300 es
13899 precision mediump float;
13900 uniform highp sampler2DArray tex2DArray;
13901 in vec3 texCoord;
13902 out vec4 fragColor;
13903 
13904 void main()
13905 {
13906     fragColor = texture(tex2DArray, texCoord);
13907 })";
13908 
13909     // Compile the shaders and create the program
13910     ANGLE_GL_PROGRAM(program, kVS, kFS);
13911     ASSERT_GL_NO_ERROR();
13912 
13913     // Setup PBO and fill it with a red
13914     GLBuffer pbo;
13915     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
13916     glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height * depth / 2u, kCompressedImageETC2,
13917                  GL_STATIC_DRAW);
13918     ASSERT_GL_NO_ERROR();
13919 
13920     // Write PBO to texture2DArray
13921     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, depth,
13922                               GL_COMPRESSED_RGB8_ETC2, width * height * depth / 2u, nullptr);
13923 
13924     ASSERT_GL_NO_ERROR();
13925 
13926     // Draw using PBO updated texture
13927     glUseProgram(program);
13928     glUniform1i(glGetUniformLocation(program, "tex2DArray"), 0);
13929     glBindTexture(GL_TEXTURE_2D_ARRAY, texture2DArray);
13930     drawQuad(program, "position", 0.5f);
13931     ASSERT_GL_NO_ERROR();
13932 
13933     // Verify the texture now contains data from the PBO
13934     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
13935     ASSERT_GL_NO_ERROR();
13936 }
13937 
13938 // Test using ETC1_RGB8 with subimage updates
TEST_P(ETC1CompressedTextureTest,ETC1CompressedSubImage)13939 TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
13940 {
13941     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
13942     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
13943 
13944     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
13945                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
13946     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
13947 
13948     const GLuint width  = 4u;
13949     const GLuint height = 4u;
13950 
13951     setWindowWidth(width);
13952     setWindowHeight(height);
13953 
13954     // Setup primary Texture
13955     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13956     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13957 
13958     if (getClientMajorVersion() < 3)
13959     {
13960         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
13961     }
13962     else
13963     {
13964         glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
13965     }
13966     ASSERT_GL_NO_ERROR();
13967 
13968     // Populate a subimage of the texture
13969     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
13970                               width * height / 2u, kCompressedImageETC2);
13971     ASSERT_GL_NO_ERROR();
13972 
13973     // Render and ensure we get red
13974     glUseProgram(mProgram);
13975     drawQuad(mProgram, "position", 0.5f);
13976     ASSERT_GL_NO_ERROR();
13977 
13978     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
13979     ASSERT_GL_NO_ERROR();
13980 }
13981 
13982 // Fully-define a NPOT compressed texture and draw; set MAX_LEVEL and draw; then increase
13983 // MAX_LEVEL and draw.  This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageNPOT)13984 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageNPOT)
13985 {
13986     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
13987     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
13988 
13989     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
13990     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
13991 
13992     const GLuint width  = 5u;
13993     const GLuint height = 5u;
13994     // round up to the nearest block size
13995     const GLsizei imageSize = 8 * 8 / 2;
13996     // smallest block size
13997     const GLsizei minImageSize = 4 * 4 / 2;
13998 
13999     uint8_t data[imageSize] = {0};
14000 
14001     setWindowWidth(width);
14002     setWindowHeight(height);
14003 
14004     // Setup primary Texture
14005     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
14006     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
14007     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
14008     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
14009 
14010     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
14011     ASSERT_GL_NO_ERROR();
14012 
14013     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width / 2, height / 2, 0,
14014                            minImageSize, data);
14015     ASSERT_GL_NO_ERROR();
14016 
14017     glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_ETC1_RGB8_OES, width / 4, height / 4, 0,
14018                            minImageSize, data);
14019     ASSERT_GL_NO_ERROR();
14020 
14021     glUseProgram(mProgram);
14022     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14023     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14024     drawQuad(mProgram, "position", 0.5f);
14025     ASSERT_GL_NO_ERROR();
14026 
14027     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
14028     drawQuad(mProgram, "position", 0.5f);
14029     ASSERT_GL_NO_ERROR();
14030 }
14031 
14032 // Define two NPOT compressed textures, set MAX_LEVEL, draw, and swap buffers
14033 // with the two textures. This used to cause release of staging buffers
14034 // that have not been flushed.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageDraws)14035 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageDraws)
14036 {
14037     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
14038     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
14039 
14040     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
14041     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
14042 
14043     const GLuint width  = 384u;
14044     const GLuint height = 384u;
14045     // round up to the nearest block size
14046     const GLsizei imageSize = width * height / 2;
14047 
14048     uint8_t data[imageSize] = {0};
14049 
14050     setWindowWidth(width);
14051     setWindowHeight(height);
14052 
14053     const GLuint smallerWidth  = 384u;
14054     const GLuint smallerHeight = 320u;
14055     // round up to the nearest block size
14056     const GLsizei smallerImageSize = smallerWidth * smallerHeight / 2;
14057 
14058     // Setup primary Texture
14059     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
14060     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
14061     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
14062     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
14063 
14064     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, smallerWidth, smallerHeight, 0,
14065                            smallerImageSize, data);
14066     ASSERT_GL_NO_ERROR();
14067 
14068     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 160, 0, 15360, data);
14069     ASSERT_GL_NO_ERROR();
14070 
14071     GLTexture largerTexture;
14072     glBindTexture(GL_TEXTURE_2D, largerTexture);
14073 
14074     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
14075     ASSERT_GL_NO_ERROR();
14076 
14077     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 192, 0, 18432, data);
14078     ASSERT_GL_NO_ERROR();
14079 
14080     glBindTexture(GL_TEXTURE_2D, mTexture2D);
14081 
14082     glUseProgram(mProgram);
14083     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14084     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14085     drawQuad(mProgram, "position", 0.5f);
14086     ASSERT_GL_NO_ERROR();
14087     swapBuffers();
14088     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
14089     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
14090     drawQuad(mProgram, "position", 0.5f);
14091     ASSERT_GL_NO_ERROR();
14092     swapBuffers();
14093 
14094     glBindTexture(GL_TEXTURE_2D, largerTexture);
14095 
14096     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14097     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14098     drawQuad(mProgram, "position", 0.5f);
14099     ASSERT_GL_NO_ERROR();
14100     swapBuffers();
14101 
14102     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
14103     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
14104     drawQuad(mProgram, "position", 0.5f);
14105     ASSERT_GL_NO_ERROR();
14106     swapBuffers();
14107 
14108     glBindTexture(GL_TEXTURE_2D, mTexture2D);
14109 
14110     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14111     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14112     drawQuad(mProgram, "position", 0.5f);
14113     swapBuffers();
14114     ASSERT_GL_NO_ERROR();
14115 }
14116 
14117 // Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
14118 // MAX_LEVEL and draw.  This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1ShrinkThenGrowMaxLevels)14119 TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
14120 {
14121     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
14122     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
14123 
14124     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
14125     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
14126 
14127     const GLuint width  = 4u;
14128     const GLuint height = 4u;
14129 
14130     setWindowWidth(width);
14131     setWindowHeight(height);
14132 
14133     // Setup primary Texture
14134     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
14135     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
14136 
14137     if (getClientMajorVersion() < 3)
14138     {
14139         glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
14140     }
14141     else
14142     {
14143         glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
14144     }
14145     ASSERT_GL_NO_ERROR();
14146 
14147     // Populate a subimage of the texture
14148     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
14149                               width * height / 2u, kCompressedImageETC2);
14150     glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
14151                               width * height / 2u, kCompressedImageETC2);
14152     glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
14153                               width * height / 2u, kCompressedImageETC2);
14154     ASSERT_GL_NO_ERROR();
14155 
14156     // Set MAX_LEVEL to 2 (the highest level)
14157     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
14158 
14159     // Render and ensure we get red
14160     glUseProgram(mProgram);
14161     drawQuad(mProgram, "position", 0.5f);
14162     ASSERT_GL_NO_ERROR();
14163     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
14164     ASSERT_GL_NO_ERROR();
14165 
14166     // Decrease MAX_LEVEL to 0, render, and ensure we still get red
14167     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14168     drawQuad(mProgram, "position", 0.5f);
14169     ASSERT_GL_NO_ERROR();
14170     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
14171     ASSERT_GL_NO_ERROR();
14172 
14173     // Increase MAX_LEVEL back to 2, render, and ensure we still get red
14174     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
14175     drawQuad(mProgram, "position", 0.5f);
14176     ASSERT_GL_NO_ERROR();
14177     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
14178     ASSERT_GL_NO_ERROR();
14179 }
14180 
14181 class TextureBufferTestBase : public ANGLETest<>
14182 {
14183   protected:
TextureBufferTestBase()14184     TextureBufferTestBase() {}
14185 
14186     void callTexBufferAPI(const APIExtensionVersion usedExtension,
14187                           GLenum target,
14188                           GLenum internalFormat,
14189                           GLuint buffer);
14190     void testTexBuffer(const APIExtensionVersion usedExtension,
14191                        GLenum internalFormat,
14192                        const size_t inputTextureDataSize,
14193                        const void *inputTextureData,
14194                        const GLColor expectedOutputColor);
14195 };
14196 
14197 class TextureBufferTestES31 : public TextureBufferTestBase
14198 {
14199   protected:
TextureBufferTestES31()14200     TextureBufferTestES31() {}
14201 
14202     void drawWithIncompleteOrZeroTexture(bool useCompleteTexture, bool useNonZeroTexture);
14203 };
14204 
14205 class TextureBufferTestES32 : public TextureBufferTestBase
14206 {
14207   protected:
TextureBufferTestES32()14208     TextureBufferTestES32() {}
14209 };
14210 
callTexBufferAPI(const APIExtensionVersion usedExtension,GLenum target,GLenum internalFormat,GLuint buffer)14211 void TextureBufferTestBase::callTexBufferAPI(const APIExtensionVersion usedExtension,
14212                                              GLenum target,
14213                                              GLenum internalFormat,
14214                                              GLuint buffer)
14215 {
14216     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES ||
14217            usedExtension == APIExtensionVersion::Core);
14218     if (usedExtension == APIExtensionVersion::EXT)
14219     {
14220         glTexBufferEXT(target, internalFormat, buffer);
14221     }
14222     else if (usedExtension == APIExtensionVersion::OES)
14223     {
14224         glTexBufferOES(target, internalFormat, buffer);
14225     }
14226     else
14227     {
14228         glTexBuffer(target, internalFormat, buffer);
14229     }
14230 }
14231 
testTexBuffer(const APIExtensionVersion usedExtension,GLenum internalFormat,const size_t inputTextureDataSize,const void * inputTextureData,const GLColor expectedOutputColor)14232 void TextureBufferTestBase::testTexBuffer(const APIExtensionVersion usedExtension,
14233                                           GLenum internalFormat,
14234                                           const size_t inputTextureDataSize,
14235                                           const void *inputTextureData,
14236                                           const GLColor expectedOutputColor)
14237 {
14238     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES ||
14239            usedExtension == APIExtensionVersion::Core);
14240 
14241     // TODO(http://anglebug.com/42264369): Claims to support GL_OES_texture_buffer, but fails
14242     // compilation of shader because "extension 'GL_OES_texture_buffer' is not supported".
14243     ANGLE_SKIP_TEST_IF(usedExtension == APIExtensionVersion::OES && IsQualcomm() && IsOpenGLES());
14244 
14245     GLBuffer buffer;
14246     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14247     glBufferData(GL_TEXTURE_BUFFER, inputTextureDataSize, inputTextureData, GL_DYNAMIC_DRAW);
14248     EXPECT_GL_NO_ERROR();
14249 
14250     // Shaders
14251     std::string simpleVS;
14252     std::string samplerBufferFS;
14253 
14254     constexpr char kGLSLVersion31[] = R"(#version 310 es
14255 )";
14256     constexpr char kGLSLVersion32[] = R"(#version 320 es
14257 )";
14258     constexpr char kTexBufEXT[]     = R"(#extension GL_EXT_texture_buffer : require
14259 )";
14260     constexpr char kTexBufOES[]     = R"(#extension GL_OES_texture_buffer : require
14261 )";
14262 
14263     if (usedExtension == APIExtensionVersion::EXT)
14264     {
14265         simpleVS.append(kGLSLVersion31);
14266         samplerBufferFS.append(kGLSLVersion31);
14267         samplerBufferFS.append(kTexBufEXT);
14268     }
14269     else if (usedExtension == APIExtensionVersion::OES)
14270     {
14271         simpleVS.append(kGLSLVersion31);
14272         samplerBufferFS.append(kGLSLVersion31);
14273         samplerBufferFS.append(kTexBufOES);
14274     }
14275     else
14276     {
14277         simpleVS.append(kGLSLVersion32);
14278         samplerBufferFS.append(kGLSLVersion32);
14279     }
14280 
14281     constexpr char kVSBody[] = R"(
14282 in vec4 a_position;
14283 void main()
14284 {
14285     gl_Position = a_position;
14286 })";
14287     simpleVS.append(kVSBody);
14288 
14289     constexpr char kFSBody[] = R"(
14290 precision mediump float;
14291 uniform highp samplerBuffer s;
14292 out vec4 colorOut;
14293 void main()
14294 {
14295     colorOut = texelFetch(s, 0);
14296 })";
14297     samplerBufferFS.append(kFSBody);
14298 
14299     ANGLE_GL_PROGRAM(program, simpleVS.c_str(), samplerBufferFS.c_str());
14300     ASSERT_GL_NO_ERROR();
14301 
14302     // Draw
14303     callTexBufferAPI(usedExtension, GL_TEXTURE_BUFFER, internalFormat, buffer);
14304     ASSERT_GL_NO_ERROR();
14305 
14306     drawQuad(program, "a_position", 0.5);
14307     ASSERT_GL_NO_ERROR();
14308 
14309     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedOutputColor);
14310 }
14311 
drawWithIncompleteOrZeroTexture(bool useCompleteTexture,bool useNonZeroTexture)14312 void TextureBufferTestES31::drawWithIncompleteOrZeroTexture(bool useCompleteTexture,
14313                                                             bool useNonZeroTexture)
14314 {
14315     constexpr char kSamplerBuffer[] = R"(#version 310 es
14316         #extension GL_OES_texture_buffer : require
14317         precision mediump float;
14318         uniform highp samplerBuffer s;
14319         out vec4 colorOut;
14320         void main()
14321         {
14322             colorOut = texelFetch(s, 0);
14323         })";
14324 
14325     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kSamplerBuffer);
14326     glUseProgram(program);
14327     EXPECT_GL_NO_ERROR();
14328 
14329     // Bind as texture buffer
14330     GLTexture texture;
14331     glActiveTexture(GL_TEXTURE0);
14332     glBindTexture(GL_TEXTURE_BUFFER, useNonZeroTexture ? texture.get() : 0u);
14333     EXPECT_GL_NO_ERROR();
14334 
14335     if (useCompleteTexture)
14336     {
14337         const std::array<GLColor, 4> kData = {GLColor::blue, GLColor::blue, GLColor::blue,
14338                                               GLColor::blue};
14339 
14340         // Create buffer and initialize with data
14341         GLBuffer buffer;
14342         glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14343         glBufferData(GL_TEXTURE_BUFFER, sizeof(kData), kData.data(), GL_DYNAMIC_DRAW);
14344         glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14345         EXPECT_GL_NO_ERROR();
14346     }
14347 
14348     // Draw texture buffer
14349     drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14350     EXPECT_GL_NO_ERROR();
14351 
14352     if (useCompleteTexture)
14353     {
14354         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
14355     }
14356 }
14357 
14358 // Test that mutating a buffer attached to a texture returns correct results in query.
TEST_P(TextureBufferTestES31,QueryWidthAfterBufferResize)14359 TEST_P(TextureBufferTestES31, QueryWidthAfterBufferResize)
14360 {
14361     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14362 
14363     constexpr GLint kInitialSize                  = 128;
14364     constexpr std::array<GLint, 4> kModifiedSizes = {96, 192, 32, 256};
14365 
14366     GLTexture texture;
14367     glBindTexture(GL_TEXTURE_BUFFER, texture);
14368 
14369     GLBuffer buffer;
14370     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14371     glBufferData(GL_TEXTURE_BUFFER, kInitialSize, nullptr, GL_STATIC_DRAW);
14372 
14373     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14374     ASSERT_GL_NO_ERROR();
14375 
14376     GLint queryResult = 0;
14377     glGetTexLevelParameteriv(GL_TEXTURE_BUFFER, 0, GL_TEXTURE_WIDTH, &queryResult);
14378     ASSERT_GL_NO_ERROR();
14379     EXPECT_EQ(queryResult, kInitialSize / 4);
14380 
14381     for (GLint modifiedSize : kModifiedSizes)
14382     {
14383         glBufferData(GL_TEXTURE_BUFFER, modifiedSize, nullptr, GL_STATIC_DRAW);
14384         glGetTexLevelParameteriv(GL_TEXTURE_BUFFER, 0, GL_TEXTURE_WIDTH, &queryResult);
14385         ASSERT_GL_NO_ERROR();
14386         EXPECT_EQ(queryResult, modifiedSize / 4);
14387     }
14388 }
14389 
14390 // Test that glTexBufferEXT can be used in two draw calls.
14391 // Covers a bug where TextureVk::setBuffer releases buffer views and doesn't init them.
TEST_P(TextureBufferTestES31,TexBufferDrawTwice)14392 TEST_P(TextureBufferTestES31, TexBufferDrawTwice)
14393 {
14394     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14395 
14396     // TODO(http://anglebug.com/42264369): Claims to support GL_OES_texture_buffer, but fails
14397     // compilation of shader because "extension 'GL_OES_texture_buffer' is not supported".
14398     ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
14399 
14400     const std::array<GLColor, 1> kTexData = {GLColor::red};
14401 
14402     GLBuffer buffer;
14403     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14404     glBufferData(GL_TEXTURE_BUFFER, sizeof(kTexData), kTexData.data(), GL_DYNAMIC_DRAW);
14405     EXPECT_GL_NO_ERROR();
14406 
14407     constexpr char kSamplerBuffer[] = R"(#version 310 es
14408 #extension GL_OES_texture_buffer : require
14409 precision mediump float;
14410 uniform highp samplerBuffer s;
14411 out vec4 colorOut;
14412 void main()
14413 {
14414     colorOut = texelFetch(s, 0);
14415 })";
14416 
14417     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kSamplerBuffer);
14418 
14419     // Draw once
14420     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14421     drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14422     EXPECT_GL_NO_ERROR();
14423 
14424     // Draw twice
14425     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14426     drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14427     EXPECT_GL_NO_ERROR();
14428 
14429     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
14430 }
14431 
14432 // Test that glTexBufferEXT can be used in a draw call for R8 normalized values.
TEST_P(TextureBufferTestES31,RNorm8EXT)14433 TEST_P(TextureBufferTestES31, RNorm8EXT)
14434 {
14435     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14436 
14437     const std::array<uint8_t, 1> kTexData = {0xFF};
14438     testTexBuffer(APIExtensionVersion::EXT, GL_R8, sizeof(kTexData), kTexData.data(), GLColor::red);
14439 }
14440 
14441 // Test that glTexBufferEXT can be used in a draw call for RG8 normalized values.
TEST_P(TextureBufferTestES31,RGNorm8EXT)14442 TEST_P(TextureBufferTestES31, RGNorm8EXT)
14443 {
14444     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14445 
14446     const std::array<uint8_t, 2> kTexData = {0xFF, 0xFF};
14447     testTexBuffer(APIExtensionVersion::EXT, GL_RG8, sizeof(kTexData), kTexData.data(),
14448                   GLColor::yellow);
14449 }
14450 
14451 // Test that glTexBufferEXT can be used in a draw call for RGBA8 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm8EXT)14452 TEST_P(TextureBufferTestES31, RGBANorm8EXT)
14453 {
14454     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14455 
14456     const std::array<uint8_t, 4> kTexData = {0xFF, 0, 0xFF, 0xFF};
14457     testTexBuffer(APIExtensionVersion::EXT, GL_RGBA8, sizeof(kTexData), kTexData.data(),
14458                   GLColor::magenta);
14459 }
14460 
14461 // Test that glTexBufferEXT can be used in a draw call for R16 normalized values.
TEST_P(TextureBufferTestES31,RNorm16EXT)14462 TEST_P(TextureBufferTestES31, RNorm16EXT)
14463 {
14464     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14465     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14466 
14467     const std::array<uint16_t, 1> kTexData = {0xFFFF};
14468     testTexBuffer(APIExtensionVersion::EXT, GL_R16_EXT, sizeof(kTexData), kTexData.data(),
14469                   GLColor::red);
14470 }
14471 
14472 // Test that glTexBufferEXT can be used in a draw call for RG16 normalized values.
TEST_P(TextureBufferTestES31,RGNorm16EXT)14473 TEST_P(TextureBufferTestES31, RGNorm16EXT)
14474 {
14475     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14476     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14477 
14478     const std::array<uint16_t, 2> kTexData = {0xFFFF, 0xFFFF};
14479     testTexBuffer(APIExtensionVersion::EXT, GL_RG16_EXT, sizeof(kTexData), kTexData.data(),
14480                   GLColor::yellow);
14481 }
14482 
14483 // Test that glTexBufferEXT can be used in a draw call for RGBA16 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm16EXT)14484 TEST_P(TextureBufferTestES31, RGBANorm16EXT)
14485 {
14486     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14487     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14488 
14489     const std::array<uint16_t, 4> kTexData = {0xFFFF, 0, 0xFFFF, 0xFFFF};
14490     testTexBuffer(APIExtensionVersion::EXT, GL_RGBA16_EXT, sizeof(kTexData), kTexData.data(),
14491                   GLColor::magenta);
14492 }
14493 
14494 // Test that glTexBufferOES can be used in a draw call for R8 normalized values.
TEST_P(TextureBufferTestES31,RNorm8OES)14495 TEST_P(TextureBufferTestES31, RNorm8OES)
14496 {
14497     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14498 
14499     const std::array<uint8_t, 1> kTexData = {0xFF};
14500     testTexBuffer(APIExtensionVersion::OES, GL_R8, sizeof(kTexData), kTexData.data(), GLColor::red);
14501 }
14502 
14503 // Test that glTexBufferOES can be used in a draw call for RG8 normalized values.
TEST_P(TextureBufferTestES31,RGNorm8OES)14504 TEST_P(TextureBufferTestES31, RGNorm8OES)
14505 {
14506     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14507 
14508     const std::array<uint8_t, 2> kTexData = {0xFF, 0xFF};
14509     testTexBuffer(APIExtensionVersion::OES, GL_RG8, sizeof(kTexData), kTexData.data(),
14510                   GLColor::yellow);
14511 }
14512 
14513 // Test that glTexBufferOES can be used in a draw call for RGBA8 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm8OES)14514 TEST_P(TextureBufferTestES31, RGBANorm8OES)
14515 {
14516     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14517 
14518     const std::array<uint8_t, 4> kTexData = {0xFF, 0, 0xFF, 0xFF};
14519     testTexBuffer(APIExtensionVersion::OES, GL_RGBA8, sizeof(kTexData), kTexData.data(),
14520                   GLColor::magenta);
14521 }
14522 
14523 // Test that glTexBufferOES can be used in a draw call for R16 normalized values.
TEST_P(TextureBufferTestES31,RNorm16OES)14524 TEST_P(TextureBufferTestES31, RNorm16OES)
14525 {
14526     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14527     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14528 
14529     const std::array<uint16_t, 1> kTexData = {0xFFFF};
14530     testTexBuffer(APIExtensionVersion::OES, GL_R16_EXT, sizeof(kTexData), kTexData.data(),
14531                   GLColor::red);
14532 }
14533 
14534 // Test that glTexBufferOES can be used in a draw call for RG16 normalized values.
TEST_P(TextureBufferTestES31,RGNorm16OES)14535 TEST_P(TextureBufferTestES31, RGNorm16OES)
14536 {
14537     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14538     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14539 
14540     const std::array<uint16_t, 2> kTexData = {0xFFFF, 0xFFFF};
14541     testTexBuffer(APIExtensionVersion::OES, GL_RG16_EXT, sizeof(kTexData), kTexData.data(),
14542                   GLColor::yellow);
14543 }
14544 
14545 // Test that glTexBufferOES can be used in a draw call for RGBA16 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm16OES)14546 TEST_P(TextureBufferTestES31, RGBANorm16OES)
14547 {
14548     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14549     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14550 
14551     const std::array<uint16_t, 4> kTexData = {0xFFFF, 0, 0xFFFF, 0xFFFF};
14552     testTexBuffer(APIExtensionVersion::OES, GL_RGBA16_EXT, sizeof(kTexData), kTexData.data(),
14553                   GLColor::magenta);
14554 }
14555 
14556 // Test that glTexBuffer can be used in a draw call for R8 normalized values.
TEST_P(TextureBufferTestES32,RNorm8)14557 TEST_P(TextureBufferTestES32, RNorm8)
14558 {
14559     const std::array<uint8_t, 1> kTexData = {0xFF};
14560     testTexBuffer(APIExtensionVersion::Core, GL_R8, sizeof(kTexData), kTexData.data(),
14561                   GLColor::red);
14562 }
14563 
14564 // Test that glTexBuffer can be used in a draw call for RG8 normalized values.
TEST_P(TextureBufferTestES32,RGNorm8)14565 TEST_P(TextureBufferTestES32, RGNorm8)
14566 {
14567     const std::array<uint8_t, 2> kTexData = {0xFF, 0xFF};
14568     testTexBuffer(APIExtensionVersion::Core, GL_RG8, sizeof(kTexData), kTexData.data(),
14569                   GLColor::yellow);
14570 }
14571 
14572 // Test that glTexBuffer can be used in a draw call for RGBA8 normalized values.
TEST_P(TextureBufferTestES32,RGBANorm8)14573 TEST_P(TextureBufferTestES32, RGBANorm8)
14574 {
14575     const std::array<uint8_t, 4> kTexData = {0xFF, 0, 0xFF, 0xFF};
14576     testTexBuffer(APIExtensionVersion::Core, GL_RGBA8, sizeof(kTexData), kTexData.data(),
14577                   GLColor::magenta);
14578 }
14579 
14580 // Test that glTexBuffer can be used in a draw call for R16 normalized values.
TEST_P(TextureBufferTestES32,RNorm16)14581 TEST_P(TextureBufferTestES32, RNorm16)
14582 {
14583     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14584 
14585     const std::array<uint16_t, 1> kTexData = {0xFFFF};
14586     testTexBuffer(APIExtensionVersion::Core, GL_R16_EXT, sizeof(kTexData), kTexData.data(),
14587                   GLColor::red);
14588 }
14589 
14590 // Test that glTexBuffer can be used in a draw call for RG16 normalized values.
TEST_P(TextureBufferTestES32,RGNorm16)14591 TEST_P(TextureBufferTestES32, RGNorm16)
14592 {
14593     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14594 
14595     const std::array<uint16_t, 2> kTexData = {0xFFFF, 0xFFFF};
14596     testTexBuffer(APIExtensionVersion::Core, GL_RG16_EXT, sizeof(kTexData), kTexData.data(),
14597                   GLColor::yellow);
14598 }
14599 
14600 // Test that glTexBuffer can be used in a draw call for RGBA16 normalized values.
TEST_P(TextureBufferTestES32,RGBANorm16)14601 TEST_P(TextureBufferTestES32, RGBANorm16)
14602 {
14603     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14604 
14605     const std::array<uint16_t, 4> kTexData = {0xFFFF, 0, 0xFFFF, 0xFFFF};
14606     testTexBuffer(APIExtensionVersion::Core, GL_RGBA16_EXT, sizeof(kTexData), kTexData.data(),
14607                   GLColor::magenta);
14608 }
14609 
14610 // Test that uploading data to buffer that's in use then using it as texture buffer works.
TEST_P(TextureBufferTestES31,UseAsUBOThenUpdateThenAsTextureBuffer)14611 TEST_P(TextureBufferTestES31, UseAsUBOThenUpdateThenAsTextureBuffer)
14612 {
14613     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14614 
14615     // Claims to support GL_OES_texture_buffer, but fails compilation of shader because "extension
14616     // 'GL_OES_texture_buffer' is not supported".  http://anglebug.com/42264369
14617     ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
14618 
14619     const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
14620                                                  GLColor::red};
14621     const std::array<GLColor, 4> kUpdateData  = {GLColor::blue, GLColor::blue, GLColor::blue,
14622                                                  GLColor::blue};
14623 
14624     GLBuffer buffer;
14625     glBindBuffer(GL_UNIFORM_BUFFER, buffer);
14626     glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
14627     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
14628     EXPECT_GL_NO_ERROR();
14629 
14630     constexpr char kVerifyUBO[] = R"(#version 310 es
14631 precision mediump float;
14632 layout(binding = 0) uniform block {
14633     uvec4 data;
14634 } ubo;
14635 out vec4 colorOut;
14636 void main()
14637 {
14638     if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
14639         colorOut = vec4(0, 1.0, 0, 1.0);
14640     else
14641         colorOut = vec4(1.0, 0, 0, 1.0);
14642 })";
14643 
14644     ANGLE_GL_PROGRAM(verifyUbo, essl31_shaders::vs::Simple(), kVerifyUBO);
14645     drawQuad(verifyUbo, essl31_shaders::PositionAttrib(), 0.5);
14646     EXPECT_GL_NO_ERROR();
14647 
14648     // Update buffer data
14649     glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
14650     EXPECT_GL_NO_ERROR();
14651 
14652     // Bind as texture buffer
14653     GLTexture texture;
14654     glBindTexture(GL_TEXTURE_BUFFER, texture);
14655     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14656     EXPECT_GL_NO_ERROR();
14657 
14658     constexpr char kVerifySamplerBuffer[] = R"(#version 310 es
14659 #extension GL_OES_texture_buffer : require
14660 precision mediump float;
14661 uniform highp samplerBuffer s;
14662 out vec4 colorOut;
14663 void main()
14664 {
14665     colorOut = texelFetch(s, 0);
14666 })";
14667 
14668     ANGLE_GL_PROGRAM(verifySamplerBuffer, essl31_shaders::vs::Simple(), kVerifySamplerBuffer);
14669 
14670     glEnable(GL_BLEND);
14671     glBlendFunc(GL_ONE, GL_ONE);
14672     drawQuad(verifySamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14673     EXPECT_GL_NO_ERROR();
14674 
14675     // Make sure both draw calls succeed
14676     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
14677 }
14678 
14679 // Test that mapping a texture buffer with GL_MAP_INVALIDATE_BUFFER_BIT and writing to it works
14680 // correctly.
TEST_P(TextureBufferTestES31,MapTextureBufferInvalidateThenWrite)14681 TEST_P(TextureBufferTestES31, MapTextureBufferInvalidateThenWrite)
14682 {
14683     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14684 
14685     // TODO(http://anglebug.com/42264369): Claims to support GL_OES_texture_buffer, but fails
14686     // compilation of shader because "extension 'GL_OES_texture_buffer' is not supported".
14687     ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
14688     // TODO(http://anglebug.com/42264910): The OpenGL backend doesn't correctly handle texture
14689     // buffers being invalidated when mapped.
14690     ANGLE_SKIP_TEST_IF(IsOpenGL());
14691 
14692     const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
14693                                                  GLColor::red};
14694     const std::array<GLColor, 4> kUpdateData  = {GLColor::blue, GLColor::blue, GLColor::blue,
14695                                                  GLColor::blue};
14696 
14697     GLBuffer buffer;
14698     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14699     glBufferData(GL_TEXTURE_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
14700     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
14701     EXPECT_GL_NO_ERROR();
14702 
14703     // Bind as texture buffer
14704     GLTexture texture;
14705     glBindTexture(GL_TEXTURE_BUFFER, texture);
14706     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14707     EXPECT_GL_NO_ERROR();
14708 
14709     constexpr char kSamplerBuffer[] = R"(#version 310 es
14710 #extension GL_OES_texture_buffer : require
14711 precision mediump float;
14712 uniform highp samplerBuffer s;
14713 out vec4 colorOut;
14714 void main()
14715 {
14716     colorOut = texelFetch(s, 0);
14717 })";
14718 
14719     ANGLE_GL_PROGRAM(initialSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14720     drawQuad(initialSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14721     EXPECT_GL_NO_ERROR();
14722 
14723     // Don't read back, so we don't break the render pass.
14724 
14725     // Map the buffer and update it.
14726     void *mappedBuffer = glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(kInitialData),
14727                                           GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
14728     memcpy(mappedBuffer, kUpdateData.data(), sizeof(kInitialData));
14729 
14730     glUnmapBuffer(GL_TEXTURE_BUFFER);
14731 
14732     // Draw with the updated buffer data.
14733     ANGLE_GL_PROGRAM(updateSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14734     drawQuad(updateSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14735     EXPECT_GL_NO_ERROR();
14736 
14737     // Make sure both draw calls succeed
14738     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
14739 }
14740 
14741 // Test that calling glBufferData on a buffer that is used as texture buffer still works correctly.
TEST_P(TextureBufferTestES31,TextureBufferThenBufferData)14742 TEST_P(TextureBufferTestES31, TextureBufferThenBufferData)
14743 {
14744     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14745 
14746     const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
14747                                                  GLColor::red};
14748     const std::array<GLColor, 4> kUpdateData  = {GLColor::blue, GLColor::blue, GLColor::blue,
14749                                                  GLColor::blue};
14750     // Create buffer and initialize with data
14751     GLBuffer buffer;
14752     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14753     glBufferData(GL_TEXTURE_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
14754 
14755     // Bind as texture buffer
14756     GLTexture texture;
14757     glBindTexture(GL_TEXTURE_BUFFER, texture);
14758     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14759     EXPECT_GL_NO_ERROR();
14760 
14761     constexpr char kSamplerBuffer[] = R"(#version 310 es
14762 #extension GL_OES_texture_buffer : require
14763 precision mediump float;
14764 uniform highp samplerBuffer s;
14765 out vec4 colorOut;
14766 void main()
14767 {
14768     colorOut = texelFetch(s, 0);
14769 })";
14770 
14771     ANGLE_GL_PROGRAM(initialSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14772     drawQuad(initialSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14773 
14774     // Don't read back, so we keep the original buffer busy. Issue a glBufferData call with same
14775     // size and nullptr so that the old buffer storage gets orphaned.
14776     glBufferData(GL_TEXTURE_BUFFER, sizeof(kUpdateData), nullptr, GL_DYNAMIC_DRAW);
14777     glBufferSubData(GL_TEXTURE_BUFFER, 0, sizeof(kUpdateData), kUpdateData.data());
14778 
14779     // Draw with the updated buffer data.
14780     ANGLE_GL_PROGRAM(updateSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14781     drawQuad(updateSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14782     EXPECT_GL_NO_ERROR();
14783     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
14784 }
14785 
14786 // Test that drawing with a texture buffer after changing its content using transform feedback.
TEST_P(TextureBufferTestES31,UseAsXFBThenAsTextureBuffer)14787 TEST_P(TextureBufferTestES31, UseAsXFBThenAsTextureBuffer)
14788 {
14789     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14790 
14791     // Issue a draw call with xfb, set buffer to red
14792     constexpr char kXFBVS[] = R"(#version 310 es
14793     uniform vec4 colorIn;
14794     flat out highp vec4 colorOut;
14795     void main()
14796     {
14797         gl_Position = vec4(0, 0, 0, 1);
14798         colorOut = colorIn;
14799     })";
14800 
14801     // Capture the varying "v".
14802     const std::vector<std::string> tfVaryings = {"colorOut"};
14803     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(programXFB, kXFBVS, essl31_shaders::fs::Green(), tfVaryings,
14804                                         GL_INTERLEAVED_ATTRIBS);
14805     EXPECT_GL_NO_ERROR();
14806     glUseProgram(programXFB);
14807     const GLint colorLoc = glGetUniformLocation(programXFB, "colorIn");
14808     ASSERT_NE(-1, colorLoc);
14809     glUniform4f(colorLoc, 1, 0, 0, 1);
14810     EXPECT_GL_NO_ERROR();
14811 
14812     GLTransformFeedback tf;
14813     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf);
14814     // Initializing the buffer with 0. After the transform feedback writes to it, the data will
14815     // change.
14816     const std::array<GLfloat, 4> data = {0.0, 0.0, 0.0, 0.0};
14817     GLBuffer buffer;
14818     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
14819     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, data.size() * sizeof(data[0]), data.data(),
14820                  GL_DYNAMIC_DRAW);
14821     // Fill the buffer using transform feedback.
14822     glBeginTransformFeedback(GL_POINTS);
14823     glDrawArrays(GL_POINTS, 0, 1);
14824     glEndTransformFeedback();
14825 
14826     // Issue a draw call with samplerBuffer, sample from buffer and write to color attachment
14827     constexpr char kTextureBufferFS[] = R"(#version 310 es
14828     #extension GL_EXT_texture_buffer : require
14829     precision mediump float;
14830     uniform highp samplerBuffer sampler_buffer;
14831     out vec4 colorOut;
14832     void main()
14833     {
14834         colorOut = texelFetch(sampler_buffer, 0);
14835     })";
14836     ANGLE_GL_PROGRAM(programTextureBuffer, essl31_shaders::vs::Simple(), kTextureBufferFS);
14837     glUseProgram(programTextureBuffer);
14838 
14839     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14840     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, buffer);
14841 
14842     drawQuad(programTextureBuffer, essl31_shaders::PositionAttrib(), 0.5);
14843     EXPECT_GL_NO_ERROR();
14844 
14845     // Issue a draw call with xfb, set buffer to green
14846     glUseProgram(programXFB);
14847     glUniform4f(colorLoc, 0, 1, 0, 1);
14848     EXPECT_GL_NO_ERROR();
14849     glBeginTransformFeedback(GL_POINTS);
14850     glDrawArrays(GL_POINTS, 0, 1);
14851     glEndTransformFeedback();
14852 
14853     // Enable blend, with glBlendFunc(GL_ONE, GL_ONE)
14854     glEnable(GL_BLEND);
14855     glBlendFunc(GL_ONE, GL_ONE);
14856 
14857     // Issue a draw call with samplerBuffer
14858     glUseProgram(programTextureBuffer);
14859     drawQuad(programTextureBuffer, essl31_shaders::PositionAttrib(), 0.5);
14860     EXPECT_GL_NO_ERROR();
14861     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(255, 255, 0, 255));
14862 }
14863 
14864 // Test workaround in Vulkan backend for mismatched texture buffer and sampler formats
TEST_P(TextureBufferTestES31,TexBufferFormatMismatch)14865 TEST_P(TextureBufferTestES31, TexBufferFormatMismatch)
14866 {
14867     ANGLE_SKIP_TEST_IF(!IsVulkan());
14868     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14869 
14870     auto runTestCase = [&](auto texData, GLenum format, const char *samplerType) {
14871         std::stringstream fsStream;
14872         fsStream << R"(#version 310 es
14873     #extension GL_EXT_texture_buffer : require
14874     precision mediump float;
14875     uniform highp )"
14876                  << samplerType << R"( s;
14877     out vec4 colorOut;
14878     void main()
14879     {
14880         colorOut = vec4(texelFetch(s, 0).r, 0, 0, 1);
14881     })";
14882         ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), fsStream.str().c_str());
14883 
14884         GLBuffer buffer;
14885         glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14886 
14887         glBufferData(GL_TEXTURE_BUFFER, sizeof(texData), texData.data(), GL_DYNAMIC_DRAW);
14888         glTexBufferEXT(GL_TEXTURE_BUFFER, format, buffer);
14889 
14890         drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14891         EXPECT_GL_NO_ERROR();
14892         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
14893     };
14894 
14895     const std::array<uint8_t, 4> kTexData8n{255};  // 8-bit normalized {1,0,0,0}
14896     const std::array<uint8_t, 4> kTexData8i{1};    // 8-bit (u)int {1,0,0,0}
14897 
14898     // Test all 8-bit formats from EXT_texture_buffer.txt Table texbo.1
14899     for (auto format :
14900          {GL_R8, GL_R8I, GL_R8UI, GL_RG8, GL_RG8I, GL_RG8UI, GL_RGBA8, GL_RGBA8I, GL_RGBA8UI})
14901     {
14902         // float sampler
14903         runTestCase(kTexData8n, format, "samplerBuffer");
14904         // integer samplers
14905         runTestCase(kTexData8i, format, "isamplerBuffer");
14906         runTestCase(kTexData8i, format, "usamplerBuffer");
14907     }
14908 
14909     const uint16_t kHalfFloatOne = 0x3C00;
14910     const std::array<uint16_t, 4> kTexData16f{kHalfFloatOne};  // 16-bit float {1,0,0,0}
14911     const std::array<uint16_t, 4> kTexData16i{1};              // 16-bit (u)int {1,0,0,0}
14912 
14913     // Test all 16-bit formats from EXT_texture_buffer.txt Table texbo.1
14914     for (auto format : {GL_R16F, GL_R16I, GL_R16UI, GL_RG16F, GL_RG16I, GL_RG16UI, GL_RGBA16F,
14915                         GL_RGBA16I, GL_RGBA16UI})
14916     {
14917         // float sampler
14918         runTestCase(kTexData16f, format, "samplerBuffer");
14919         // integer samplers
14920         runTestCase(kTexData16i, format, "isamplerBuffer");
14921         runTestCase(kTexData16i, format, "usamplerBuffer");
14922     }
14923 
14924     const std::array<GLfloat, 4> kTexData32f{1.0f};  // 32-bit float {1,0,0,0}
14925     const std::array<uint32_t, 4> kTexData32i{1};    // 32-bit (u)int {1,0,0,0}
14926 
14927     // Test all 32-bit formats from EXT_texture_buffer.txt Table texbo.1
14928     for (auto format : {GL_R32F, GL_R32I, GL_R32UI, GL_RG32F, GL_RG32I, GL_RG32UI, GL_RGB32F,
14929                         GL_RGB32I, GL_RGB32UI, GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI})
14930     {
14931         // float sampler
14932         runTestCase(kTexData32f, format, "samplerBuffer");
14933         // integer samplers
14934         runTestCase(kTexData32i, format, "isamplerBuffer");
14935         runTestCase(kTexData32i, format, "usamplerBuffer");
14936     }
14937 }
14938 
14939 // Create an integer format texture but specify a FLOAT sampler. OpenGL
14940 // tolerates this but it causes a Vulkan validation error.
TEST_P(Texture2DTestES3,TexImageFormatMismatch)14941 TEST_P(Texture2DTestES3, TexImageFormatMismatch)
14942 {
14943     GLint textureUnit = 2;
14944     GLuint genericBuffer;
14945     GLubyte genericBufferMemory[1024];
14946     GLuint texture;
14947     GLuint sampler;
14948     GLuint vertexArray;
14949 
14950     glGenBuffers(1, &genericBuffer);
14951     glBindBuffer(GL_ARRAY_BUFFER, genericBuffer);
14952     glBufferData(GL_ARRAY_BUFFER, 1024, &genericBufferMemory, GL_STATIC_DRAW);
14953 
14954     glGenTextures(1, &texture);
14955     glBindTexture(GL_TEXTURE_2D, texture);
14956     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14957     glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 8, 8, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT,
14958                  &genericBufferMemory);
14959 
14960     const char *vertexShaderSource   = getVertexShaderSource();
14961     const char *fragmentShaderSource = getFragmentShaderSource();
14962     ANGLE_GL_PROGRAM(testProgram, vertexShaderSource, fragmentShaderSource);
14963 
14964     GLint texLocation = glGetUniformLocation(testProgram, "tex");
14965     glUseProgram(testProgram);
14966 
14967     glUniform1iv(texLocation, 1, &textureUnit);
14968 
14969     glGenSamplers(1, &sampler);
14970     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
14971     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
14972 
14973     glBindBuffer(GL_UNIFORM_BUFFER, genericBuffer);
14974 
14975     glActiveTexture(GL_TEXTURE0 + textureUnit);
14976     glBindTexture(GL_TEXTURE_2D, texture);
14977     glBindSampler(textureUnit, sampler);
14978 
14979     glGenVertexArrays(1, &vertexArray);
14980     glBindVertexArray(vertexArray);
14981     glBindBuffer(GL_ARRAY_BUFFER, genericBuffer);
14982 
14983     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, genericBuffer);
14984     glBindVertexArray(vertexArray);
14985     glDrawElementsInstanced(GL_TRIANGLES, 4, GL_UNSIGNED_SHORT, 0, 1);
14986 }
14987 
14988 // Checks that drawing incomplete zero texture buffer does not crash.
TEST_P(TextureBufferTestES31,DrawIncompleteZeroTexture)14989 TEST_P(TextureBufferTestES31, DrawIncompleteZeroTexture)
14990 {
14991     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14992 
14993     drawWithIncompleteOrZeroTexture(false, false);
14994 }
14995 
14996 // Checks that drawing incomplete non-zero texture buffer does not crash.
TEST_P(TextureBufferTestES31,DrawIncompleteNonZeroTexture)14997 TEST_P(TextureBufferTestES31, DrawIncompleteNonZeroTexture)
14998 {
14999     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
15000 
15001     drawWithIncompleteOrZeroTexture(false, true);
15002 }
15003 
15004 // Checks that drawing complete zero texture buffer produces expected results.
TEST_P(TextureBufferTestES31,DrawCompleteZeroTexture)15005 TEST_P(TextureBufferTestES31, DrawCompleteZeroTexture)
15006 {
15007     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
15008 
15009     drawWithIncompleteOrZeroTexture(true, false);
15010 }
15011 
15012 // Checks that drawing complete non-zero texture buffer produces expected results.
TEST_P(TextureBufferTestES31,DrawCompleteNonZeroTexture)15013 TEST_P(TextureBufferTestES31, DrawCompleteNonZeroTexture)
15014 {
15015     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
15016 
15017     drawWithIncompleteOrZeroTexture(true, true);
15018 }
15019 
15020 // Test that the correct error is generated if texture buffer support used anyway when not enabled.
TEST_P(TextureBufferTestES31,TestErrorWhenNotEnabled)15021 TEST_P(TextureBufferTestES31, TestErrorWhenNotEnabled)
15022 {
15023     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15024 
15025     GLTexture texture;
15026     glBindTexture(GL_TEXTURE_BUFFER, texture);
15027     ASSERT_GL_ERROR(GL_INVALID_ENUM);
15028 }
15029 
15030 class CopyImageTestES31 : public ANGLETest<>
15031 {
15032   protected:
CopyImageTestES31()15033     CopyImageTestES31()
15034     {
15035         setConfigRedBits(8);
15036         setConfigGreenBits(8);
15037         setConfigBlueBits(8);
15038         setConfigAlphaBits(8);
15039     }
15040 };
15041 
15042 // Test that copies between RGB formats doesn't affect the emulated alpha channel, if any.
TEST_P(CopyImageTestES31,PreserveEmulatedAlpha)15043 TEST_P(CopyImageTestES31, PreserveEmulatedAlpha)
15044 {
15045     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15046 
15047     constexpr GLsizei kSize = 1;
15048 
15049     GLTexture src, dst;
15050 
15051     // Set up the textures
15052     glBindTexture(GL_TEXTURE_2D, src);
15053     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, kSize, kSize);
15054 
15055     const GLColor kInitColor(50, 100, 150, 200);
15056     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGB, GL_UNSIGNED_BYTE, &kInitColor);
15057 
15058     glBindTexture(GL_TEXTURE_2D, dst);
15059     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8UI, kSize, kSize);
15060     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
15061     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
15062 
15063     // Copy from src to dst
15064     glCopyImageSubDataEXT(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
15065                           kSize, 1);
15066 
15067     // Bind dst as image
15068     glBindImageTexture(0, dst, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI);
15069 
15070     // Create a buffer for output
15071     constexpr GLsizei kBufferSize = kSize * kSize * sizeof(uint32_t) * 4;
15072     GLBuffer buffer;
15073     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
15074     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
15075     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, buffer);
15076 
15077     constexpr char kCS[] = R"(#version 310 es
15078 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
15079 layout(rgba8ui, binding = 0) readonly uniform highp uimage2D imageIn;
15080  layout(std140, binding = 1) buffer dataOut {
15081      uvec4 data[];
15082  };
15083 void main()
15084 {
15085     uvec4 color = imageLoad(imageIn, ivec2(0));
15086     data[0] = color;
15087 })";
15088 
15089     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
15090     glUseProgram(program);
15091     glDispatchCompute(1, 1, 1);
15092     EXPECT_GL_NO_ERROR();
15093 
15094     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
15095 
15096     const uint32_t *ptr = reinterpret_cast<uint32_t *>(
15097         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
15098 
15099     EXPECT_EQ(ptr[0], kInitColor.R);
15100     EXPECT_EQ(ptr[1], kInitColor.G);
15101     EXPECT_EQ(ptr[2], kInitColor.B);
15102 
15103     // Expect alpha to be 1, even if the RGB format is emulated with RGBA.
15104     EXPECT_EQ(ptr[3], 1u);
15105 
15106     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
15107 }
15108 
15109 // Verify a common pattern used by the Unreal Engine that trips up the tracer
TEST_P(CopyImageTestES31,CubeMapCopyImageSubData)15110 TEST_P(CopyImageTestES31, CubeMapCopyImageSubData)
15111 {
15112     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15113 
15114     constexpr char kVS[] =
15115         R"(#version 300 es
15116         precision mediump float;
15117         in vec3 pos;
15118         void main() {
15119             gl_Position = vec4(pos, 1.0);
15120         })";
15121 
15122     constexpr char kFS[] =
15123         R"(#version 300 es
15124         precision mediump float;
15125         out vec4 color;
15126         uniform samplerCube uTex;
15127         void main(){
15128             // sample from lod 1.0
15129             color = textureLod(uTex, vec3(1.0), 1.0);
15130         })";
15131 
15132     ANGLE_GL_PROGRAM(program, kVS, kFS);
15133     glUseProgram(program);
15134 
15135     // Set up two cube maps, then verify we can copy between them
15136     constexpr size_t kSize = 2;
15137     constexpr int levels   = 2;
15138     std::vector<GLColor> pixelsGreen(kSize * kSize, GLColor::green);
15139     std::vector<GLColor> pixelsRed(kSize * kSize, GLColor::red);
15140 
15141     // Initialize src to green
15142     GLTexture texCubeSrc;
15143     glBindTexture(GL_TEXTURE_CUBE_MAP, texCubeSrc);
15144     for (int i = 0; i < levels; i++)
15145     {
15146         for (GLenum face = 0; face < 6; face++)
15147         {
15148             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, GL_RGBA, kSize >> i, kSize >> i,
15149                          0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsGreen.data());
15150         }
15151     }
15152     ASSERT_GL_NO_ERROR();
15153 
15154     // Initialize dst to red
15155     GLTexture texCubeDst;
15156     glBindTexture(GL_TEXTURE_CUBE_MAP, texCubeDst);
15157     for (int i = 0; i < levels; i++)
15158     {
15159         for (GLenum face = 0; face < 6; face++)
15160         {
15161             glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, GL_RGBA, kSize >> i, kSize >> i,
15162                          0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
15163         }
15164     }
15165     ASSERT_GL_NO_ERROR();
15166 
15167     // Clear to blue
15168     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
15169     glClear(GL_COLOR_BUFFER_BIT);
15170     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
15171 
15172     // Sample from the dst texture to ensure it has the right color
15173     GLint textureLoc = glGetUniformLocation(program, "uTex");
15174     ASSERT_NE(-1, textureLoc);
15175     glUniform1i(textureLoc, 0);
15176 
15177     // Draw once and sample from level 1, which is red
15178     drawQuad(program, "pos", 0.5f);
15179     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
15180 
15181     // Swap to trigger MEC
15182     swapBuffers();
15183 
15184     // Copy level 1 from src to dst
15185     glCopyImageSubDataEXT(texCubeSrc, GL_TEXTURE_CUBE_MAP, 1, 0, 0, 0, texCubeDst,
15186                           GL_TEXTURE_CUBE_MAP, 1, 0, 0, 0, kSize >> 1, kSize >> 1, 6);
15187     ASSERT_GL_NO_ERROR();
15188 
15189     // Draw again and verify we get green
15190     drawQuad(program, "pos", 0.5f);
15191     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
15192 
15193     // Swap again to end the capture
15194     swapBuffers();
15195 
15196     ASSERT_GL_NO_ERROR();
15197 }
15198 
15199 // Verify that copies between texture layers works, including when there is a read after write in a
15200 // level/layer.
TEST_P(CopyImageTestES31,ArraySelfCopyImageSubDataWithReadAfterWrite)15201 TEST_P(CopyImageTestES31, ArraySelfCopyImageSubDataWithReadAfterWrite)
15202 {
15203     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15204 
15205     // Set up a texture with multiple layers, then verify we can copy between them
15206     constexpr uint32_t kWidth  = 13;
15207     constexpr uint32_t kHeight = 57;
15208     constexpr uint32_t kLayers = 5;
15209     constexpr uint32_t kLevels = 2;
15210     std::vector<GLColor> pixelsRed(kWidth * kHeight, GLColor::red);
15211     std::vector<GLColor> pixelsGreen(kWidth * kHeight, GLColor::green);
15212     std::vector<GLColor> pixelsBlue(kWidth * kHeight, GLColor::blue);
15213 
15214     const GLColor *colors[3] = {
15215         pixelsRed.data(),
15216         pixelsGreen.data(),
15217         pixelsBlue.data(),
15218     };
15219 
15220     GLTexture tex;
15221     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
15222     glTexStorage3D(GL_TEXTURE_2D_ARRAY, kLevels, GL_RGBA8, kWidth, kHeight, kLayers);
15223     for (uint32_t level = 0; level < kLevels; ++level)
15224     {
15225         for (uint32_t layer = 0; layer < kLayers; ++layer)
15226         {
15227             glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, layer, kWidth >> level,
15228                             kHeight >> level, 1, GL_RGBA, GL_UNSIGNED_BYTE,
15229                             colors[(level + layer) % 3]);
15230         }
15231     }
15232     ASSERT_GL_NO_ERROR();
15233 
15234     // The texture has the following colors:
15235     //              Layer 0   Layer 1   Layer 2   Layer 3   Layer 4
15236     // Level  0      Red       Green     Blue      Red       Green
15237     // Level  1      Green     Blue      Red       Green     Blue
15238 
15239     // Copy level 0, layer 0 to level 0, layer 2
15240     glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15241                           2, kWidth, kHeight, 1);
15242 
15243     // Copy level 1, layers 3, 4 to level 1, layers 1, 2
15244     glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 1, 0, 0, 3, tex, GL_TEXTURE_2D_ARRAY, 1, 0, 0,
15245                           1, kWidth >> 1, kHeight >> 1, 2);
15246 
15247     // Partially copy level 1, layer 1 to level 0, layer 3
15248     // Level 1/layer 1 will be read from after being written to
15249     glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 1, kWidth / 8, kHeight / 8, 1, tex,
15250                           GL_TEXTURE_2D_ARRAY, 0, kWidth / 4, kHeight / 4, 3, kWidth / 4,
15251                           kHeight / 4, 1);
15252     ASSERT_GL_NO_ERROR();
15253 
15254     // Verify colors
15255     GLFramebuffer FBO;
15256     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
15257     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
15258     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15259 
15260     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
15261     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15262 
15263     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
15264     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15265 
15266     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 3);
15267     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight / 4, GLColor::red);
15268     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 4, kHeight, GLColor::red);
15269     EXPECT_PIXEL_RECT_EQ(0, kHeight / 4 + kHeight / 4, kWidth,
15270                          kHeight - (kHeight / 4 + kHeight / 4), GLColor::red);
15271     EXPECT_PIXEL_RECT_EQ(kWidth / 4 + kWidth / 4, 0, kWidth - (kWidth / 4 + kWidth / 4), kHeight,
15272                          GLColor::red);
15273     EXPECT_PIXEL_RECT_EQ(kWidth / 4, kHeight / 4, kWidth / 4, kHeight / 4, GLColor::green);
15274 
15275     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 4);
15276     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15277 
15278     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 0);
15279     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15280 
15281     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 1);
15282     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15283 
15284     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 2);
15285     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15286 
15287     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 3);
15288     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15289 
15290     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 4);
15291     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15292     ASSERT_GL_NO_ERROR();
15293 }
15294 
15295 // Verify that copies between texture layers works, including when there is a write after read in a
15296 // level/layer.
TEST_P(CopyImageTestES31,ArraySelfCopyImageSubDataWithWriteAfterRead)15297 TEST_P(CopyImageTestES31, ArraySelfCopyImageSubDataWithWriteAfterRead)
15298 {
15299     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15300 
15301     // Set up a texture with multiple layers, then verify we can copy between them
15302     constexpr uint32_t kWidth  = 13;
15303     constexpr uint32_t kHeight = 57;
15304     constexpr uint32_t kLayers = 5;
15305     constexpr uint32_t kLevels = 2;
15306     std::vector<GLColor> pixelsRed(kWidth * kHeight, GLColor::red);
15307     std::vector<GLColor> pixelsGreen(kWidth * kHeight, GLColor::green);
15308     std::vector<GLColor> pixelsBlue(kWidth * kHeight, GLColor::blue);
15309 
15310     const GLColor *colors[3] = {
15311         pixelsRed.data(),
15312         pixelsGreen.data(),
15313         pixelsBlue.data(),
15314     };
15315 
15316     GLTexture tex;
15317     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
15318     glTexStorage3D(GL_TEXTURE_2D_ARRAY, kLevels, GL_RGBA8, kWidth, kHeight, kLayers);
15319     for (uint32_t level = 0; level < kLevels; ++level)
15320     {
15321         for (uint32_t layer = 0; layer < kLayers; ++layer)
15322         {
15323             glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, layer, kWidth >> level,
15324                             kHeight >> level, 1, GL_RGBA, GL_UNSIGNED_BYTE,
15325                             colors[(level + layer) % 3]);
15326         }
15327     }
15328     ASSERT_GL_NO_ERROR();
15329 
15330     // The texture has the following colors:
15331     //              Layer 0   Layer 1   Layer 2   Layer 3   Layer 4
15332     // Level  0      Red       Green     Blue      Red       Green
15333     // Level  1      Green     Blue      Red       Green     Blue
15334 
15335     // Copy level 0, layer 0 to level 0, layer 2
15336     glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15337                           2, kWidth, kHeight, 1);
15338     ASSERT_GL_NO_ERROR();
15339 
15340     // Copy level 0, layer 1 to level 0, layer 3
15341     glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15342                           3, kWidth, kHeight, 1);
15343     ASSERT_GL_NO_ERROR();
15344 
15345     // Copy level 0, layer 0 to level 0, layer 1
15346     // Level 0/layer 1 will be written to from after being read from
15347     glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15348                           1, kWidth, kHeight, 1);
15349     ASSERT_GL_NO_ERROR();
15350 
15351     // Verify colors
15352     GLFramebuffer FBO;
15353     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
15354     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
15355     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15356 
15357     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
15358     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15359 
15360     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
15361     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15362 
15363     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 3);
15364     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15365 
15366     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 4);
15367     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15368 
15369     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 0);
15370     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15371 
15372     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 1);
15373     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15374 
15375     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 2);
15376     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::red);
15377 
15378     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 3);
15379     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15380 
15381     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 4);
15382     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15383     ASSERT_GL_NO_ERROR();
15384 }
15385 
15386 // Verify that copies between 3D texture slices work
TEST_P(CopyImageTestES31,Texture3DSelfCopyImageSubData)15387 TEST_P(CopyImageTestES31, Texture3DSelfCopyImageSubData)
15388 {
15389     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15390 
15391     // Set up a texture with multiple layers, then verify we can copy between them
15392     constexpr uint32_t kWidth  = 23;
15393     constexpr uint32_t kHeight = 47;
15394     constexpr uint32_t kDepth  = 5;
15395     constexpr uint32_t kLevels = 2;
15396     std::vector<GLColor> pixelsRed(kWidth * kHeight, GLColor::red);
15397     std::vector<GLColor> pixelsGreen(kWidth * kHeight, GLColor::green);
15398     std::vector<GLColor> pixelsBlue(kWidth * kHeight, GLColor::blue);
15399 
15400     const GLColor *colors[3] = {
15401         pixelsRed.data(),
15402         pixelsGreen.data(),
15403         pixelsBlue.data(),
15404     };
15405 
15406     GLTexture tex;
15407     glBindTexture(GL_TEXTURE_3D, tex);
15408     glTexStorage3D(GL_TEXTURE_3D, kLevels, GL_RGBA8, kWidth, kHeight, kDepth);
15409     for (uint32_t level = 0; level < kLevels; ++level)
15410     {
15411         for (uint32_t depth = 0; depth < kDepth >> level; ++depth)
15412         {
15413             glTexSubImage3D(GL_TEXTURE_3D, level, 0, 0, depth, kWidth >> level, kHeight >> level, 1,
15414                             GL_RGBA, GL_UNSIGNED_BYTE, colors[(level + depth) % 3]);
15415         }
15416     }
15417     ASSERT_GL_NO_ERROR();
15418 
15419     // The texture has the following colors:
15420     //              Slice 0   Slice 1   Slice 2   Slice 3   Slice 4
15421     // Level  0      Red       Green     Blue      Red       Green
15422     // Level  1      Green     Blue
15423 
15424     // Copy level 1, slice 1 to level 1, slice 0
15425     glCopyImageSubDataEXT(tex, GL_TEXTURE_3D, 1, 0, 0, 1, tex, GL_TEXTURE_3D, 1, 0, 0, 0,
15426                           kWidth >> 1, kHeight >> 1, 1);
15427     ASSERT_GL_NO_ERROR();
15428 
15429     // Copy level 0, slice 3, 4 to level 0, slice 1, 2
15430     glCopyImageSubDataEXT(tex, GL_TEXTURE_3D, 0, 0, 0, 3, tex, GL_TEXTURE_3D, 0, 0, 0, 1, kWidth,
15431                           kHeight, 2);
15432     ASSERT_GL_NO_ERROR();
15433 
15434     // Partially copy level 1, slice 1 to level 0, slice 3
15435     glCopyImageSubDataEXT(tex, GL_TEXTURE_3D, 1, kWidth / 8, kHeight / 8, 1, tex, GL_TEXTURE_3D, 0,
15436                           kWidth / 4, kHeight / 4, 3, kWidth / 4, kHeight / 4, 1);
15437     ASSERT_GL_NO_ERROR();
15438 
15439     // Verify colors
15440     GLFramebuffer FBO;
15441     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
15442     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
15443     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15444 
15445     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
15446     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15447 
15448     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
15449     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15450 
15451     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 3);
15452     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight / 4, GLColor::red);
15453     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 4, kHeight, GLColor::red);
15454     EXPECT_PIXEL_RECT_EQ(0, kHeight / 4 + kHeight / 4, kWidth,
15455                          kHeight - (kHeight / 4 + kHeight / 4), GLColor::red);
15456     EXPECT_PIXEL_RECT_EQ(kWidth / 4 + kWidth / 4, 0, kWidth - (kWidth / 4 + kWidth / 4), kHeight,
15457                          GLColor::red);
15458     EXPECT_PIXEL_RECT_EQ(kWidth / 4, kHeight / 4, kWidth / 4, kHeight / 4, GLColor::blue);
15459 
15460     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 4);
15461     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15462 
15463     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 0);
15464     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15465 
15466     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 1);
15467     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15468     ASSERT_GL_NO_ERROR();
15469 }
15470 
15471 // Verify that copying between multisample renderbuffer work
TEST_P(CopyImageTestES31,MultisampleRenderbufferCopyImageSubData)15472 TEST_P(CopyImageTestES31, MultisampleRenderbufferCopyImageSubData)
15473 {
15474     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15475 
15476     constexpr uint32_t kWidth  = 16;
15477     constexpr uint32_t kHeight = 16;
15478 
15479     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
15480 
15481     GLint maxSample = 0;
15482     glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &maxSample);
15483     ASSERT_GL_NO_ERROR();
15484 
15485     GLFramebuffer fboRenderbuffer;
15486     GLRenderbuffer srcRenderbuffer;
15487     glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
15488     glBindRenderbuffer(GL_RENDERBUFFER, srcRenderbuffer);
15489     glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSample, GL_RGBA8, kWidth, kHeight);
15490     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
15491                               srcRenderbuffer);
15492     ASSERT_GL_NO_ERROR();
15493     glCheckFramebufferStatus(GL_FRAMEBUFFER);
15494     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
15495 
15496     /* Draw red into the source renderbuffer */
15497     glViewport(0, 0, kWidth, kHeight);
15498     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
15499 
15500     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
15501     ASSERT_GL_NO_ERROR();
15502 
15503     /* Copy source renderbuffer to destination renderbuffer*/
15504     GLRenderbuffer dstRenderbuffer;
15505     glBindRenderbuffer(GL_RENDERBUFFER, dstRenderbuffer);
15506     glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSample, GL_RGBA8, kWidth, kHeight);
15507     glCopyImageSubDataEXT(srcRenderbuffer, GL_RENDERBUFFER, 0, 0, 0, 0, dstRenderbuffer,
15508                           GL_RENDERBUFFER, 0, 0, 0, 0, kWidth, kHeight, 1);
15509     ASSERT_GL_NO_ERROR();
15510 
15511     /* Resolve the dstRenderbuffer */
15512     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
15513     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
15514     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
15515                               dstRenderbuffer);
15516     ASSERT_GL_NO_ERROR();
15517     glCheckFramebufferStatus(GL_FRAMEBUFFER);
15518     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
15519 
15520     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
15521     glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
15522     ASSERT_GL_NO_ERROR();
15523 
15524     glBindFramebuffer(GL_FRAMEBUFFER, 0);
15525     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15526 }
15527 
15528 class TextureChangeStorageUploadTest : public ANGLETest<>
15529 {
15530   protected:
TextureChangeStorageUploadTest()15531     TextureChangeStorageUploadTest()
15532     {
15533         setWindowWidth(256);
15534         setWindowHeight(256);
15535         setConfigRedBits(8);
15536         setConfigGreenBits(8);
15537         setConfigBlueBits(8);
15538         setConfigAlphaBits(8);
15539     }
15540 
testSetUp()15541     void testSetUp() override
15542     {
15543         mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
15544         if (mProgram == 0)
15545         {
15546             FAIL() << "shader compilation failed.";
15547         }
15548 
15549         glUseProgram(mProgram);
15550 
15551         glClearColor(0, 0, 0, 0);
15552         glClearDepthf(0.0);
15553         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
15554 
15555         glEnable(GL_BLEND);
15556         glDisable(GL_DEPTH_TEST);
15557 
15558         glGenTextures(1, &mTexture);
15559         ASSERT_GL_NO_ERROR();
15560     }
15561 
testTearDown()15562     void testTearDown() override
15563     {
15564         glDeleteTextures(1, &mTexture);
15565         glDeleteProgram(mProgram);
15566     }
15567 
15568     GLuint mProgram;
15569     GLint mColorLocation;
15570     GLuint mTexture;
15571 };
15572 
15573 // Verify that respecifying storage and re-uploading doesn't crash.
TEST_P(TextureChangeStorageUploadTest,Basic)15574 TEST_P(TextureChangeStorageUploadTest, Basic)
15575 {
15576     constexpr int kImageSize        = 8;  // 4 doesn't trip ASAN
15577     constexpr int kSmallerImageSize = kImageSize / 2;
15578     EXPECT_GT(kImageSize, kSmallerImageSize);
15579     EXPECT_GT(kSmallerImageSize / 2, 0);
15580 
15581     std::array<GLColor, kImageSize * kImageSize> kColor;
15582 
15583     glBindTexture(GL_TEXTURE_2D, mTexture);
15584     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
15585                  kColor.data());
15586     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSmallerImageSize, kSmallerImageSize);
15587     // need partial update to sidestep optimizations that remove the full upload
15588     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSmallerImageSize / 2, kSmallerImageSize / 2, GL_RGBA,
15589                     GL_UNSIGNED_BYTE, kColor.data());
15590     EXPECT_GL_NO_ERROR();
15591 }
15592 
15593 class ExtraSamplerCubeShadowUseTest : public ANGLETest<>
15594 {
15595   protected:
ExtraSamplerCubeShadowUseTest()15596     ExtraSamplerCubeShadowUseTest() : ANGLETest() {}
15597 
getVertexShaderSource()15598     const char *getVertexShaderSource() { return "#version 300 es\nvoid main() {}"; }
15599 
getFragmentShaderSource()15600     const char *getFragmentShaderSource()
15601     {
15602         return R"(#version 300 es
15603 precision mediump float;
15604 
15605 uniform mediump samplerCube var_0002; // this has to be there
15606 uniform highp samplerCubeShadow var_0004; // this has to be a cube shadow sampler
15607 out vec4 color;
15608 void main() {
15609 
15610     vec4 var_0031 = texture(var_0002, vec3(1,1,1));
15611     ivec2 size = textureSize(var_0004, 0) ;
15612     var_0031.x += float(size.y);
15613 
15614     color = var_0031;
15615 })";
15616     }
15617 
testSetUp()15618     void testSetUp() override
15619     {
15620         mProgram = CompileProgram(getVertexShaderSource(), getFragmentShaderSource());
15621         if (mProgram == 0)
15622         {
15623             FAIL() << "shader compilation failed.";
15624         }
15625         glUseProgram(mProgram);
15626         ASSERT_GL_NO_ERROR();
15627     }
15628 
testTearDown()15629     void testTearDown() override { glDeleteProgram(mProgram); }
15630 
15631     GLuint mProgram;
15632 };
15633 
TEST_P(ExtraSamplerCubeShadowUseTest,Basic)15634 TEST_P(ExtraSamplerCubeShadowUseTest, Basic)
15635 {
15636     glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
15637     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
15638 }
15639 
15640 // Tests covering RBG->RGBA emulation path
15641 class RGBTextureBufferTestES31 : public ANGLETest<>
15642 {
15643   protected:
RGBTextureBufferTestES31()15644     RGBTextureBufferTestES31()
15645     {
15646         setWindowWidth(128);
15647         setWindowHeight(128);
15648         setConfigRedBits(8);
15649         setConfigGreenBits(8);
15650         setConfigBlueBits(8);
15651         setConfigAlphaBits(8);
15652     }
15653     void TestInt(GLuint format);
15654 };
15655 
SetupTextureBufferDrawProgram(GLProgram & program,GLuint format)15656 void SetupTextureBufferDrawProgram(GLProgram &program, GLuint format)
15657 {
15658     constexpr char kVS[] = R"(#version 310 es
15659     precision highp float;
15660     in vec4 inputAttribute;
15661 
15662     void main()
15663     {
15664         gl_Position = inputAttribute;
15665     })";
15666 
15667     if (format == GL_RGB32UI)
15668     {
15669         constexpr char kFS[] = R"(#version 310 es
15670         #extension GL_EXT_texture_buffer : require
15671         precision mediump float;
15672         uniform highp usamplerBuffer tex;
15673         layout(location = 0) out mediump vec4 color;
15674 
15675         void main()
15676         {
15677             uvec4 v = texelFetch(tex, 1);
15678             color = vec4(float(v.r)/255.0, float(v.g)/255.0, float(v.b)/255.0, v.a);
15679         })";
15680         program.makeRaster(kVS, kFS);
15681     }
15682     if (format == GL_RGB32I)
15683     {
15684         constexpr char kFS[] = R"(#version 310 es
15685         #extension GL_EXT_texture_buffer : require
15686         precision mediump float;
15687         uniform highp isamplerBuffer tex;
15688         layout(location = 0) out mediump vec4 color;
15689 
15690         void main()
15691         {
15692             ivec4 v = texelFetch(tex, 1);
15693             color = vec4(float(v.r)/255.0, float(v.g)/255.0, float(v.b)/255.0, v.a);
15694         })";
15695         program.makeRaster(kVS, kFS);
15696     }
15697     if (format == GL_RGB32F)
15698     {
15699         constexpr char kFS[] = R"(#version 310 es
15700         #extension GL_EXT_texture_buffer : require
15701         precision mediump float;
15702         uniform highp samplerBuffer tex;
15703         layout(location = 0) out mediump vec4 color;
15704 
15705         void main()
15706         {
15707             vec4 v = texelFetch(tex, 1);
15708             color = vec4(float(v.r)/255.0, float(v.g)/255.0, float(v.b)/255.0, v.a);
15709         })";
15710         program.makeRaster(kVS, kFS);
15711     }
15712     ASSERT_TRUE(program.valid());
15713 }
15714 
TestInt(GLuint format)15715 void RGBTextureBufferTestES31::TestInt(GLuint format)
15716 {
15717     const GLint pixelSize = sizeof(GLuint) * 3;
15718 
15719     // Offset must be aligned to GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT (16, 64, ...)
15720     GLint offsetAlignment = 0;
15721     glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment);
15722     ASSERT(offsetAlignment % sizeof(GLuint) == 0);
15723     GLint byteOffset = ((pixelSize * 2) / offsetAlignment + 1) * offsetAlignment;
15724 
15725     GLint intOffset = byteOffset / sizeof(GLuint);
15726 
15727     std::vector<GLuint> texData(intOffset + 3 * 2);
15728 
15729     // first texel(1) col
15730     GLColor col = MakeGLColor(11, 22, 33, 255);
15731     texData[3]  = col.R;
15732     texData[4]  = col.G;
15733     texData[5]  = col.B;
15734 
15735     // second texel(1) col2
15736     GLColor col2           = MakeGLColor(44, 55, 66, 255);
15737     texData[intOffset + 3] = col2.R;
15738     texData[intOffset + 4] = col2.G;
15739     texData[intOffset + 5] = col2.B;
15740 
15741     GLTexture texture;
15742     glBindTexture(GL_TEXTURE_BUFFER, texture);
15743 
15744     GLBuffer buffer;
15745     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
15746     glBufferData(GL_TEXTURE_BUFFER, sizeof(GLuint) * texData.size(), texData.data(),
15747                  GL_STATIC_DRAW);
15748     ASSERT_GL_NO_ERROR();
15749 
15750     GLProgram program;
15751     SetupTextureBufferDrawProgram(program, format);
15752 
15753     glTexBufferEXT(GL_TEXTURE_BUFFER, format, buffer);
15754 
15755     drawQuad(program, "inputAttribute", 0.5f);
15756     ASSERT_GL_NO_ERROR();
15757     EXPECT_PIXEL_COLOR_NEAR(0, 0, col, 1);
15758 
15759     glTexBufferRangeEXT(GL_TEXTURE_BUFFER, format, buffer, byteOffset, pixelSize * 2);
15760     ASSERT_GL_NO_ERROR();
15761     drawQuad(program, "inputAttribute", 0.5f);
15762     EXPECT_PIXEL_COLOR_NEAR(0, 0, col2, 1);
15763 
15764     // Now update the buffer to check the converted data also gets updated.
15765     GLColor colUpd      = MakeGLColor(77, 88, 99, 255);
15766     GLuint texDataUpd[] = {0, 0, 0, colUpd.R, colUpd.G, colUpd.B};  // second texel(1) colUpd
15767     glBufferSubData(GL_TEXTURE_BUFFER, byteOffset, sizeof(texDataUpd), texDataUpd);
15768     ASSERT_GL_NO_ERROR();
15769     drawQuad(program, "inputAttribute", 0.5f);
15770     EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd, 1);
15771 
15772     // Update with glMapBuffer (hits a different code path...)
15773     GLColor colUpd2      = MakeGLColor(111, 122, 133, 255);
15774     GLuint texDataUpd2[] = {0, 0, 0, colUpd2.R, colUpd2.G, colUpd2.B};  // second texel(1) colUpd2
15775     void *mappedBuffer =
15776         glMapBufferRange(GL_TEXTURE_BUFFER, byteOffset, sizeof(texDataUpd2), GL_MAP_WRITE_BIT);
15777     memcpy(mappedBuffer, texDataUpd2, sizeof(texDataUpd2));
15778     glUnmapBuffer(GL_TEXTURE_BUFFER);
15779     ASSERT_GL_NO_ERROR();
15780     drawQuad(program, "inputAttribute", 0.5f);
15781     EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd2, 1);
15782 }
15783 
15784 // Tests GL_RGB32UI texture buffer
TEST_P(RGBTextureBufferTestES31,Uint)15785 TEST_P(RGBTextureBufferTestES31, Uint)
15786 {
15787     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15788 
15789     TestInt(GL_RGB32UI);
15790 }
15791 
15792 // Tests GL_RGB32I texture buffer
TEST_P(RGBTextureBufferTestES31,Sint)15793 TEST_P(RGBTextureBufferTestES31, Sint)
15794 {
15795     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15796 
15797     TestInt(GL_RGB32I);
15798 }
15799 
15800 // Tests GL_RGB32F texture buffer
TEST_P(RGBTextureBufferTestES31,Float)15801 TEST_P(RGBTextureBufferTestES31, Float)
15802 {
15803     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15804 
15805     // first texel(1) col
15806     GLColor col = MakeGLColor(11, 22, 33, 255);
15807     GLfloat texData[6]{};
15808     texData[3] = col.R;
15809     texData[4] = col.G;
15810     texData[5] = col.B;
15811 
15812     GLTexture texture;
15813     glBindTexture(GL_TEXTURE_BUFFER, texture);
15814 
15815     GLBuffer buffer;
15816     glBindBuffer(GL_TEXTURE_BUFFER, buffer);
15817     glBufferData(GL_TEXTURE_BUFFER, sizeof(texData), texData, GL_STATIC_DRAW);
15818     ASSERT_GL_NO_ERROR();
15819 
15820     GLProgram program;
15821     SetupTextureBufferDrawProgram(program, GL_RGB32F);
15822 
15823     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGB32F, buffer);
15824 
15825     drawQuad(program, "inputAttribute", 0.5f);
15826     ASSERT_GL_NO_ERROR();
15827     EXPECT_PIXEL_COLOR_NEAR(0, 0, col, 1);
15828 
15829     // Now update the buffer to check the converted data also gets updated.
15830     GLColor colUpd = MakeGLColor(77, 88, 99, 255);
15831     GLfloat texDataUpd[6]{};
15832     texDataUpd[3] = colUpd.R;
15833     texDataUpd[4] = colUpd.G;
15834     texDataUpd[5] = colUpd.B;
15835     glBufferSubData(GL_TEXTURE_BUFFER, 0, sizeof(texDataUpd), texDataUpd);
15836     ASSERT_GL_NO_ERROR();
15837     drawQuad(program, "inputAttribute", 0.5f);
15838     EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd, 1);
15839 
15840     // Update with glMapBuffer (hits a different code path...)
15841     GLColor colUpd2 = MakeGLColor(111, 122, 133, 255);
15842     GLfloat texDataUpd2[6]{};
15843     texDataUpd2[3] = colUpd2.R;
15844     texDataUpd2[4] = colUpd2.G;
15845     texDataUpd2[5] = colUpd2.B;
15846     void *mappedBuffer =
15847         glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(texDataUpd2), GL_MAP_WRITE_BIT);
15848     memcpy(mappedBuffer, texDataUpd2, sizeof(texDataUpd2));
15849     glUnmapBuffer(GL_TEXTURE_BUFFER);
15850     ASSERT_GL_NO_ERROR();
15851     drawQuad(program, "inputAttribute", 0.5f);
15852     EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd2, 1);
15853 }
15854 
SetupSSBOProgram(GLProgram & program)15855 void SetupSSBOProgram(GLProgram &program)
15856 {
15857     constexpr char kVS[] = R"(#version 310 es
15858     precision highp float;
15859     in vec4 inputAttribute;
15860 
15861     void main()
15862     {
15863         gl_Position = inputAttribute;
15864     })";
15865 
15866     constexpr char kFS[] = R"(#version 310 es
15867     layout(location = 0) out mediump vec4 color;
15868     layout(std140, binding = 0) buffer outBlock {
15869         uvec4 data[2];  // uvec4 to avoid padding
15870     };
15871     void main (void)
15872     {
15873         data[0] = uvec4(11u, 22u, 33u, 44u);
15874         data[1] = uvec4(55u, 66u, 0u, 0u);
15875         color = vec4(0);
15876     })";
15877 
15878     program.makeRaster(kVS, kFS);
15879     ASSERT_TRUE(program.valid());
15880 }
15881 
15882 // Tests RGB32 texture buffer with a SSBO write
TEST_P(RGBTextureBufferTestES31,SSBOWrite)15883 TEST_P(RGBTextureBufferTestES31, SSBOWrite)
15884 {
15885     GLProgram programSSBO;
15886     SetupSSBOProgram(programSSBO);
15887 
15888     GLProgram programBufferDraw;
15889     SetupTextureBufferDrawProgram(programBufferDraw, GL_RGB32UI);
15890 
15891     constexpr GLint kBufferSize = 2 * 4 * sizeof(GLuint);
15892     GLBuffer buffer;
15893     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
15894     glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
15895     glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kBufferSize);
15896 
15897     drawQuad(programSSBO, "inputAttribute", 0.5f);
15898     ASSERT_GL_NO_ERROR();
15899 
15900     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
15901 
15902     glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGB32UI, buffer);
15903     drawQuad(programBufferDraw, "inputAttribute", 0.5f);
15904     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(44, 55, 66, 255), 1);
15905 }
15906 
15907 class TextureTestES31 : public ANGLETest<>
15908 {
15909   protected:
TextureTestES31()15910     TextureTestES31()
15911     {
15912         setWindowWidth(128);
15913         setWindowHeight(128);
15914         setConfigRedBits(8);
15915         setConfigGreenBits(8);
15916         setConfigBlueBits(8);
15917         setConfigAlphaBits(8);
15918     }
15919 };
15920 
15921 // Verify that image uniforms can link in separable programs
TEST_P(TextureTestES31,LinkedImageUniforms)15922 TEST_P(TextureTestES31, LinkedImageUniforms)
15923 {
15924     ANGLE_SKIP_TEST_IF(!IsVulkan());
15925 
15926     GLint maxVertexImageUniforms;
15927     glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &maxVertexImageUniforms);
15928     ANGLE_SKIP_TEST_IF(maxVertexImageUniforms == 0);
15929 
15930     constexpr char kVS[] = R"(#version 310 es
15931 precision highp float;
15932 precision highp image2D;
15933 layout(binding = 0, r32f) uniform image2D img;
15934 
15935 void main()
15936 {
15937     vec2 position = -imageLoad(img, ivec2(0, 0)).rr;
15938     if (gl_VertexID == 1)
15939         position = vec2(3, -1);
15940     else if (gl_VertexID == 2)
15941         position = vec2(-1, 3);
15942 
15943     gl_Position = vec4(position, 0, 1);
15944 })";
15945 
15946     constexpr char kFS[] = R"(#version 310 es
15947 precision highp float;
15948 precision highp image2D;
15949 layout(binding = 0, r32f) uniform image2D img;
15950 layout(location = 0) out vec4 color;
15951 
15952 void main()
15953 {
15954     color = imageLoad(img, ivec2(0, 0));
15955 })";
15956 
15957     ANGLE_GL_PROGRAM(program, kVS, kFS);
15958 
15959     GLTexture texture;
15960     GLfloat value = 1.0;
15961 
15962     glBindTexture(GL_TEXTURE_2D, texture);
15963     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
15964     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, &value);
15965     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
15966     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
15967 
15968     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
15969 
15970     glUseProgram(program);
15971     glDrawArrays(GL_TRIANGLES, 0, 3);
15972 
15973     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
15974     ASSERT_GL_NO_ERROR();
15975 }
15976 
15977 // Test that layer-related parameters are ignored when binding a 2D texture
TEST_P(TextureTestES31,Texture2DLayered)15978 TEST_P(TextureTestES31, Texture2DLayered)
15979 {
15980     constexpr char kFS[] = R"(#version 310 es
15981 precision highp float;
15982 precision highp image2D;
15983 layout(binding = 0, r32f) uniform image2D img;
15984 layout(location = 0) out vec4 color;
15985 
15986 void main()
15987 {
15988     color = imageLoad(img, ivec2(0, 0));
15989 })";
15990 
15991     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
15992 
15993     GLTexture texture;
15994     GLfloat value = 1.0;
15995 
15996     glBindTexture(GL_TEXTURE_2D, texture);
15997     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
15998     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, &value);
15999     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16000     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16001 
16002     glClearColor(0.0, 1.0, 0.0, 1.0);
16003     for (const bool layered : {true, false})
16004     {
16005         for (const GLint layer : {0, 1})
16006         {
16007             glClear(GL_COLOR_BUFFER_BIT);
16008             glBindImageTexture(0, texture, 0, layered, layer, GL_READ_ONLY, GL_R32F);
16009             ASSERT_GL_NO_ERROR();
16010 
16011             drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16012             EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red)
16013                 << "Layered: " << (layered ? "true" : "false") << ", Layer: " << layer;
16014         }
16015     }
16016 }
16017 
16018 // Test that rebinding the shader image level without changing the program works
TEST_P(TextureTestES31,Texture2DChangeLevel)16019 TEST_P(TextureTestES31, Texture2DChangeLevel)
16020 {
16021     constexpr char kFS[] = R"(#version 310 es
16022 precision highp float;
16023 precision highp image2D;
16024 layout(binding = 0, r32f) uniform image2D img;
16025 layout(location = 0) out vec4 color;
16026 
16027 void main()
16028 {
16029     color = imageLoad(img, ivec2(0, 0));
16030 })";
16031     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
16032 
16033     // Must be active before calling drawQuad to avoid program switches
16034     glUseProgram(program);
16035 
16036     GLTexture texture;
16037     const GLfloat level0[4] = {0.5, 0.5, 0.5, 0.5};
16038     const GLfloat level1[1] = {1.0};
16039 
16040     glBindTexture(GL_TEXTURE_2D, texture);
16041     glTexStorage2D(GL_TEXTURE_2D, 2, GL_R32F, 2, 2);
16042     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RED, GL_FLOAT, level0);
16043     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1, GL_RED, GL_FLOAT, level1);
16044     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16045     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16046 
16047     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16048     ASSERT_GL_NO_ERROR();
16049     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16050     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16051 
16052     glBindImageTexture(0, texture, 1, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16053     ASSERT_GL_NO_ERROR();
16054     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16055     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
16056 }
16057 
16058 // Test that rebinding the shader image layer/level without changing the program works
TEST_P(TextureTestES31,Texture2DArrayChangeLayerLevel)16059 TEST_P(TextureTestES31, Texture2DArrayChangeLayerLevel)
16060 {
16061     constexpr char kFS[] = R"(#version 310 es
16062 precision highp float;
16063 precision highp image2D;
16064 layout(binding = 0, r32f) uniform image2D img;
16065 layout(location = 0) out vec4 color;
16066 
16067 void main()
16068 {
16069     color = imageLoad(img, ivec2(0, 0));
16070 })";
16071     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
16072 
16073     // Must be active before calling drawQuad to avoid program switches
16074     glUseProgram(program);
16075 
16076     GLTexture texture;
16077     const GLfloat level0layer0[4] = {0.25, 0.25, 0.25, 0.25};
16078     const GLfloat level0layer1[4] = {0.50, 0.50, 0.50, 0.50};
16079     const GLfloat level1layer0[1] = {0.75};
16080     const GLfloat level1layer1[1] = {1.00};
16081 
16082     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
16083     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 2, GL_R32F, 2, 2, 2);
16084     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 2, 2, 1, GL_RED, GL_FLOAT, level0layer0);
16085     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 2, 2, 1, GL_RED, GL_FLOAT, level0layer1);
16086     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 0, 1, 1, 1, GL_RED, GL_FLOAT, level1layer0);
16087     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 1, 1, 1, 1, GL_RED, GL_FLOAT, level1layer1);
16088     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16089     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16090 
16091     // Level 0, layer 0
16092     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16093     ASSERT_GL_NO_ERROR();
16094     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16095     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(63, 0, 0, 255), 1);
16096 
16097     // Level 0, layer 1
16098     glBindImageTexture(0, texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
16099     ASSERT_GL_NO_ERROR();
16100     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16101     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16102 
16103     // Level 1, layer 0
16104     glBindImageTexture(0, texture, 1, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16105     ASSERT_GL_NO_ERROR();
16106     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16107     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(191, 0, 0, 255), 1);
16108 
16109     // Level 1, layer 1
16110     glBindImageTexture(0, texture, 1, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
16111     ASSERT_GL_NO_ERROR();
16112     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16113     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 0, 0, 255), 1);
16114 }
16115 
16116 // Test that switching between a 2D texture and a layer of a 2D array texture works
TEST_P(TextureTestES31,Texture2DTo2DArraySwitch)16117 TEST_P(TextureTestES31, Texture2DTo2DArraySwitch)
16118 {
16119     constexpr char kFS[] = R"(#version 310 es
16120 precision highp float;
16121 precision highp image2D;
16122 layout(binding = 0, r32f) uniform image2D img;
16123 layout(location = 0) out vec4 color;
16124 
16125 void main()
16126 {
16127     color = imageLoad(img, ivec2(0, 0));
16128 })";
16129     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
16130 
16131     // Must be active before calling drawQuad to avoid program switches
16132     glUseProgram(program);
16133 
16134     GLTexture texture2D;
16135     GLTexture texture2DArray;
16136     const GLfloat data2D[1]       = {0.50};
16137     const GLfloat data2DArray0[1] = {0.25};
16138     const GLfloat data2DArray1[1] = {0.75};
16139 
16140     glBindTexture(GL_TEXTURE_2D, texture2D);
16141     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
16142     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, data2D);
16143     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16144     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16145 
16146     glBindTexture(GL_TEXTURE_2D_ARRAY, texture2DArray);
16147     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, 1, 1, 2);
16148     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 1, 1, 1, GL_RED, GL_FLOAT, data2DArray0);
16149     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 1, 1, 1, GL_RED, GL_FLOAT, data2DArray1);
16150     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16151     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16152 
16153     // Texture2D
16154     glBindImageTexture(0, texture2D, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16155     ASSERT_GL_NO_ERROR();
16156     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16157     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16158 
16159     // Texture2D array, layer 0
16160     glBindImageTexture(0, texture2DArray, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16161     ASSERT_GL_NO_ERROR();
16162     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16163     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(63, 0, 0, 255), 1);
16164 
16165     // Texture2D again
16166     glBindImageTexture(0, texture2D, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16167     ASSERT_GL_NO_ERROR();
16168     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16169     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16170 
16171     // Texture2D array, layer 1
16172     glBindImageTexture(0, texture2DArray, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
16173     ASSERT_GL_NO_ERROR();
16174     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16175     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(191, 0, 0, 255), 1);
16176 }
16177 
16178 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
16179 // tests should be run against.
16180 #define ES2_EMULATE_COPY_TEX_IMAGE_VIA_SUB()             \
16181     ES2_OPENGL().enable(Feature::EmulateCopyTexImage2D), \
16182         ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2D)
16183 #define ES3_EMULATE_COPY_TEX_IMAGE_VIA_SUB()             \
16184     ES3_OPENGL().enable(Feature::EmulateCopyTexImage2D), \
16185         ES3_OPENGLES().enable(Feature::EmulateCopyTexImage2D)
16186 #define ES2_EMULATE_COPY_TEX_IMAGE()                                      \
16187     ES2_OPENGL().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers), \
16188         ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers)
16189 #define ES3_EMULATE_COPY_TEX_IMAGE()                                      \
16190     ES3_OPENGL().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers), \
16191         ES3_OPENGLES().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers)
16192 ANGLE_INSTANTIATE_TEST(Texture2DTest,
16193                        ANGLE_ALL_TEST_PLATFORMS_ES2,
16194                        ES2_EMULATE_COPY_TEX_IMAGE_VIA_SUB(),
16195                        ES2_EMULATE_COPY_TEX_IMAGE(),
16196                        ES2_WEBGPU());
16197 ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
16198 ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
16199 ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
16200 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
16201 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
16202 
16203 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3);
16204 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DTestES3,
16205                                ES3_VULKAN().enable(Feature::AllocateNonZeroMemory),
16206                                ES3_VULKAN().enable(Feature::ForceFallbackFormat));
16207 
16208 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DMemoryTestES3);
16209 ANGLE_INSTANTIATE_TEST_ES3(Texture2DMemoryTestES3);
16210 
16211 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3YUV);
16212 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DTestES3YUV,
16213                                ES3_VULKAN().enable(Feature::PreferLinearFilterForYUV),
16214                                ES3_VULKAN().enable(Feature::DisableProgramCaching));
16215 
16216 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3RobustInit);
16217 ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3RobustInit);
16218 
16219 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3Foveation);
16220 ANGLE_INSTANTIATE_TEST_ES3_AND(
16221     Texture2DTestES3Foveation,
16222     ES3_VULKAN().enable(Feature::GenerateFragmentShadingRateAttchementWithCpu));
16223 
16224 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES31Foveation);
16225 ANGLE_INSTANTIATE_TEST_ES31_AND(
16226     Texture2DTestES31Foveation,
16227     ES31_VULKAN().enable(Feature::GenerateFragmentShadingRateAttchementWithCpu));
16228 
16229 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES31PPO);
16230 ANGLE_INSTANTIATE_TEST_ES31(Texture2DTestES31PPO);
16231 
16232 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DBaseMaxTestES3);
16233 ANGLE_INSTANTIATE_TEST_ES3(Texture2DBaseMaxTestES3);
16234 
16235 ANGLE_INSTANTIATE_TEST_ES2(Texture3DTestES2);
16236 
16237 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DTestES3);
16238 ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
16239 
16240 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerAlpha1TestES3);
16241 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
16242 
16243 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DUnsignedIntegerAlpha1TestES3);
16244 ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
16245 
16246 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShadowSamplerPlusSampler3DTestES3);
16247 ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
16248 
16249 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplerTypeMixTestES3);
16250 ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
16251 
16252 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayTestES3);
16253 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
16254 
16255 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureSizeTextureArrayTest);
16256 ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
16257 
16258 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
16259 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
16260 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
16261 ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
16262 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
16263 ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
16264 ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
16265 
16266 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBorderClampTestES3);
16267 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
16268 
16269 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBorderClampIntegerTestES3);
16270 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
16271 
16272 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(TextureMirrorClampToEdgeTest);
16273 
16274 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureMirrorClampToEdgeTestES3);
16275 ANGLE_INSTANTIATE_TEST_ES3(TextureMirrorClampToEdgeTestES3);
16276 
16277 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureMirrorClampToEdgeIntegerTestES3);
16278 ANGLE_INSTANTIATE_TEST_ES3(TextureMirrorClampToEdgeIntegerTestES3);
16279 
16280 ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
16281 
16282 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DNorm16TestES3);
16283 ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
16284 
16285 ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
16286                        ANGLE_ALL_TEST_PLATFORMS_ES2,
16287                        ANGLE_ALL_TEST_PLATFORMS_ES3,
16288                        ES2_EMULATE_COPY_TEX_IMAGE_VIA_SUB(),
16289                        ES3_EMULATE_COPY_TEX_IMAGE_VIA_SUB(),
16290                        ES2_EMULATE_COPY_TEX_IMAGE(),
16291                        ES3_EMULATE_COPY_TEX_IMAGE());
16292 
16293 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DFloatTestES3);
16294 ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
16295 
16296 ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
16297 
16298 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeTestES3);
16299 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
16300 
16301 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeTestES32);
16302 ANGLE_INSTANTIATE_TEST_ES32(TextureCubeTestES32);
16303 
16304 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerTestES3);
16305 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
16306 
16307 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeIntegerTestES3);
16308 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
16309 
16310 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeIntegerEdgeTestES3);
16311 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
16312 
16313 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerProjectiveOffsetTestES3);
16314 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
16315 
16316 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayIntegerTestES3);
16317 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
16318 
16319 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DIntegerTestES3);
16320 ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
16321 
16322 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
16323 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
16324 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
16325 ANGLE_INSTANTIATE_TEST_ES3(PBOCompressedTexture3DTest);
16326 
16327 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES31);
16328 ANGLE_INSTANTIATE_TEST_ES31(TextureBufferTestES31);
16329 
16330 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES32);
16331 ANGLE_INSTANTIATE_TEST_ES32(TextureBufferTestES32);
16332 
16333 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureTestES31);
16334 ANGLE_INSTANTIATE_TEST_ES31(TextureTestES31);
16335 
16336 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyImageTestES31);
16337 ANGLE_INSTANTIATE_TEST_ES31(CopyImageTestES31);
16338 
16339 ANGLE_INSTANTIATE_TEST_ES3(TextureChangeStorageUploadTest);
16340 
16341 ANGLE_INSTANTIATE_TEST_ES3(ExtraSamplerCubeShadowUseTest);
16342 
16343 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DDepthStencilTestES3);
16344 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DDepthStencilTestES3,
16345                                ES3_VULKAN().enable(Feature::ForceFallbackFormat));
16346 
16347 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RGBTextureBufferTestES31);
16348 ANGLE_INSTANTIATE_TEST_ES31(RGBTextureBufferTestES31);
16349 
16350 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultisampleTexture2DTestES31);
16351 ANGLE_INSTANTIATE_TEST_ES31(MultisampleTexture2DTestES31);
16352 
16353 }  // anonymous namespace
16354