xref: /aosp_15_r20/external/angle/src/tests/gl_tests/CopyTextureTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 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 // CopyTextureTest.cpp: Tests of the GL_CHROMIUM_copy_texture extension
8 
9 #include "test_utils/ANGLETest.h"
10 
11 #include "test_utils/gl_raii.h"
12 
13 namespace angle
14 {
15 
16 class CopyTextureTest : public ANGLETest<>
17 {
18   protected:
CopyTextureTest()19     CopyTextureTest()
20     {
21         setWindowWidth(256);
22         setWindowHeight(256);
23         setConfigRedBits(8);
24         setConfigGreenBits(8);
25         setConfigBlueBits(8);
26         setConfigAlphaBits(8);
27     }
28 
testSetUp()29     void testSetUp() override
30     {
31         glGenTextures(2, mTextures);
32         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
33 
34         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
35         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
36         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
37         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
38 
39         glGenFramebuffers(1, &mFramebuffer);
40         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
41         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
42                                0);
43     }
44 
testTearDown()45     void testTearDown() override
46     {
47         glDeleteTextures(2, mTextures);
48         glDeleteFramebuffers(1, &mFramebuffer);
49     }
50 
checkExtensions() const51     bool checkExtensions() const
52     {
53         if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"))
54         {
55             std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
56                       << std::endl;
57             return false;
58         }
59 
60         EXPECT_NE(nullptr, glCopyTextureCHROMIUM);
61         EXPECT_NE(nullptr, glCopySubTextureCHROMIUM);
62         return true;
63     }
64 
testGradientDownsampleUniqueValues(GLenum destFormat,GLenum destType,const std::array<size_t,4> & expectedUniqueValues)65     void testGradientDownsampleUniqueValues(GLenum destFormat,
66                                             GLenum destType,
67                                             const std::array<size_t, 4> &expectedUniqueValues)
68     {
69         std::array<GLColor, 256> sourceGradient;
70         for (size_t i = 0; i < sourceGradient.size(); i++)
71         {
72             GLubyte value     = static_cast<GLubyte>(i);
73             sourceGradient[i] = GLColor(value, value, value, value);
74         }
75         GLTexture sourceTexture;
76         glBindTexture(GL_TEXTURE_2D, sourceTexture);
77         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
78                      sourceGradient.data());
79 
80         GLTexture destTexture;
81         glBindTexture(GL_TEXTURE_2D, destTexture);
82         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destFormat, destType,
83                               GL_FALSE, GL_FALSE, GL_FALSE);
84         EXPECT_GL_NO_ERROR();
85 
86         GLFramebuffer fbo;
87         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
88         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
89 
90         std::array<GLColor, 256> destData;
91         glReadPixels(0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, destData.data());
92         EXPECT_GL_NO_ERROR();
93 
94         std::set<GLubyte> uniqueValues[4];
95         for (size_t i = 0; i < destData.size(); i++)
96         {
97             GLColor color = destData[i];
98             uniqueValues[0].insert(color.R);
99             uniqueValues[1].insert(color.G);
100             uniqueValues[2].insert(color.B);
101             uniqueValues[3].insert(color.A);
102         }
103 
104         EXPECT_EQ(expectedUniqueValues[0], uniqueValues[0].size());
105         EXPECT_EQ(expectedUniqueValues[1], uniqueValues[1].size());
106         EXPECT_EQ(expectedUniqueValues[2], uniqueValues[2].size());
107         EXPECT_EQ(expectedUniqueValues[3], uniqueValues[3].size());
108     }
109 
testSrgbToRgb(GLenum internalformat,GLenum format)110     void testSrgbToRgb(GLenum internalformat, GLenum format)
111     {
112         const size_t kTestCount                = 4;
113         const GLColor kSourceColor[kTestCount] = {
114             GLColor(89, 67, 45, 123),
115             GLColor(87, 69, 45, 123),
116             GLColor(180, 143, 93, 123),
117             GLColor(89, 67, 45, 123),
118         };
119         const GLColor kExpectedColor[kTestCount] = {
120             GLColor(89, 67, 45, 123),
121             GLColor(180, 143, 93, 123),
122             GLColor(87, 69, 45, 123),
123             GLColor(89, 67, 45, 123),
124         };
125         bool kPremultiply[kTestCount] = {false, false, true, true};
126         bool kUnmultiply[kTestCount]  = {false, true, false, true};
127 
128         for (size_t test = 0; test < kTestCount; ++test)
129         {
130             // Create image as sRGB.
131             GLTexture sourceTexture;
132             glBindTexture(GL_TEXTURE_2D, sourceTexture);
133             glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, GL_UNSIGNED_BYTE,
134                          &kSourceColor[test]);
135             ASSERT_GL_NO_ERROR();
136 
137             GLTexture destTexture;
138             glBindTexture(GL_TEXTURE_2D, destTexture);
139             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
140             ASSERT_GL_NO_ERROR();
141 
142             // Note: flipY is used to avoid direct transfer between textures and force a draw-based
143             // path.
144             glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0,  // level,
145                                      0, 0,                                             // src x,y
146                                      0, 0,                                             // dst x,y
147                                      1, 1,                // width, height
148                                      true,                // flip-y
149                                      kPremultiply[test],  // premul
150                                      kUnmultiply[test]);  // unmul
151             ASSERT_GL_NO_ERROR();
152 
153             // Verify the copy.
154             ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(),
155                              essl1_shaders::fs::Texture2D());
156             glUseProgram(program);
157 
158             glActiveTexture(GL_TEXTURE0);
159             glBindTexture(GL_TEXTURE_2D, destTexture);
160             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
161             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
162 
163             GLint textureLocation =
164                 glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
165             ASSERT_NE(-1, textureLocation);
166             glUniform1i(textureLocation, 0);
167 
168             glBindFramebuffer(GL_FRAMEBUFFER, 0);
169 
170             drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
171             ASSERT_GL_NO_ERROR();
172 
173             EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpectedColor[test], 2);
174         }
175     }
176 
177     GLuint mTextures[2] = {
178         0,
179         0,
180     };
181     GLuint mFramebuffer = 0;
182 };
183 
184 using CopyTextureVariationsTestParams =
185     std::tuple<angle::PlatformParameters, GLenum, GLenum, bool, bool, bool, GLint>;
186 
CopyTextureVariationsTestPrint(const::testing::TestParamInfo<CopyTextureVariationsTestParams> & paramsInfo)187 std::string CopyTextureVariationsTestPrint(
188     const ::testing::TestParamInfo<CopyTextureVariationsTestParams> &paramsInfo)
189 {
190     const CopyTextureVariationsTestParams &params = paramsInfo.param;
191     std::ostringstream out;
192 
193     out << std::get<0>(params) << "__";
194 
195     switch (std::get<1>(params))
196     {
197         case GL_ALPHA:
198             out << "A";
199             break;
200         case GL_RGB:
201             out << "RGB";
202             break;
203         case GL_RGBA:
204             out << "RGBA";
205             break;
206         case GL_LUMINANCE:
207             out << "L";
208             break;
209         case GL_LUMINANCE_ALPHA:
210             out << "LA";
211             break;
212         case GL_BGRA_EXT:
213             out << "BGRA";
214             break;
215         case GL_SRGB_ALPHA_EXT:
216             out << "SRGBA";
217             break;
218         default:
219             out << "UPDATE_THIS_SWITCH";
220     }
221 
222     out << "To";
223 
224     switch (std::get<2>(params))
225     {
226         case GL_RGB:
227             out << "RGB";
228             break;
229         case GL_RGBA:
230             out << "RGBA";
231             break;
232         case GL_BGRA_EXT:
233             out << "BGRA";
234             break;
235         case GL_SRGB_ALPHA_EXT:
236             out << "SRGBA";
237             break;
238         default:
239             out << "UPDATE_THIS_SWITCH";
240     }
241 
242     if (std::get<3>(params))
243     {
244         out << "FlipY";
245     }
246     if (std::get<4>(params))
247     {
248         out << "PremultiplyAlpha";
249     }
250     if (std::get<5>(params))
251     {
252         out << "UnmultiplyAlpha";
253     }
254     if (std::get<6>(params))
255     {
256         out << "MesaYFlip";
257     }
258 
259     return out.str();
260 }
261 
262 class CopyTextureVariationsTest : public ANGLETest<CopyTextureVariationsTestParams>
263 {
264   protected:
CopyTextureVariationsTest()265     CopyTextureVariationsTest()
266     {
267         setWindowWidth(256);
268         setWindowHeight(256);
269         setConfigRedBits(8);
270         setConfigGreenBits(8);
271         setConfigBlueBits(8);
272         setConfigAlphaBits(8);
273     }
274 
testSetUp()275     void testSetUp() override
276     {
277         glGenTextures(2, mTextures);
278         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
279 
280         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
281         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
282         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
283         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
284 
285         glGenFramebuffers(1, &mFramebuffer);
286         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
287         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
288                                0);
289     }
290 
testTearDown()291     void testTearDown() override
292     {
293         glDeleteTextures(2, mTextures);
294         glDeleteFramebuffers(1, &mFramebuffer);
295     }
296 
checkExtensions(GLenum sourceFormat,GLenum destFormat) const297     bool checkExtensions(GLenum sourceFormat, GLenum destFormat) const
298     {
299         if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"))
300         {
301             std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
302                       << std::endl;
303             return false;
304         }
305 
306         if ((sourceFormat == GL_BGRA_EXT || destFormat == GL_BGRA_EXT) &&
307             !IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
308         {
309             return false;
310         }
311 
312         if ((sourceFormat == GL_SRGB_ALPHA_EXT || destFormat == GL_SRGB_ALPHA_EXT) &&
313             !IsGLExtensionEnabled("GL_EXT_sRGB"))
314         {
315             return false;
316         }
317 
318         return true;
319     }
320 
calculateCopyTextureResults(GLenum sourceFormat,GLenum destFormat,bool premultiplyAlpha,bool unmultiplyAlpha,const uint8_t * sourceColor,GLColor * destColor)321     void calculateCopyTextureResults(GLenum sourceFormat,
322                                      GLenum destFormat,
323                                      bool premultiplyAlpha,
324                                      bool unmultiplyAlpha,
325                                      const uint8_t *sourceColor,
326                                      GLColor *destColor)
327     {
328         GLColor color;
329 
330         switch (sourceFormat)
331         {
332             case GL_RGB:
333                 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], 255);
334                 break;
335             case GL_RGBA:
336                 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], sourceColor[3]);
337                 break;
338             case GL_LUMINANCE:
339                 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], 255);
340                 break;
341             case GL_ALPHA:
342                 color = GLColor(0, 0, 0, sourceColor[0]);
343                 break;
344             case GL_LUMINANCE_ALPHA:
345                 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], sourceColor[1]);
346                 break;
347             case GL_BGRA_EXT:
348                 color = GLColor(sourceColor[2], sourceColor[1], sourceColor[0], sourceColor[3]);
349                 break;
350             default:
351                 EXPECT_EQ(true, false);
352         }
353 
354         if (premultiplyAlpha != unmultiplyAlpha)
355         {
356             float alpha = color.A / 255.0f;
357             if (premultiplyAlpha)
358             {
359                 color.R = static_cast<GLubyte>(static_cast<float>(color.R) * alpha);
360                 color.G = static_cast<GLubyte>(static_cast<float>(color.G) * alpha);
361                 color.B = static_cast<GLubyte>(static_cast<float>(color.B) * alpha);
362             }
363             else if (unmultiplyAlpha && color.A != 0)
364             {
365                 color.R = static_cast<GLubyte>(static_cast<float>(color.R) / alpha);
366                 color.G = static_cast<GLubyte>(static_cast<float>(color.G) / alpha);
367                 color.B = static_cast<GLubyte>(static_cast<float>(color.B) / alpha);
368             }
369         }
370 
371         switch (destFormat)
372         {
373             case GL_RGB:
374                 color.A = 255;
375                 break;
376             case GL_RGBA:
377             case GL_BGRA_EXT:
378             case GL_SRGB_ALPHA_EXT:
379                 break;
380             default:
381                 EXPECT_EQ(true, false);
382         }
383 
384         *destColor = color;
385     }
386 
getSourceColors(GLenum sourceFormat,size_t * colorCount,uint8_t * componentCount)387     const uint8_t *getSourceColors(GLenum sourceFormat, size_t *colorCount, uint8_t *componentCount)
388     {
389         // Note: in all the following values, alpha is larger than RGB so unmultiply alpha doesn't
390         // overflow
391         constexpr static uint8_t kRgbaColors[7 * 4] = {
392             255u, 127u, 63u,  255u,  // 0
393             31u,  127u, 63u,  127u,  // 1
394             31u,  63u,  127u, 255u,  // 2
395             15u,  127u, 31u,  127u,  // 3
396             127u, 255u, 63u,  0u,    // 4
397             31u,  63u,  127u, 0u,    // 5
398             15u,  31u,  63u,  63u,   // 6
399         };
400 
401         constexpr static uint8_t kRgbColors[7 * 3] = {
402             255u, 127u, 63u,   // 0
403             31u,  127u, 63u,   // 1
404             31u,  63u,  127u,  // 2
405             15u,  127u, 31u,   // 3
406             127u, 255u, 63u,   // 4
407             31u,  63u,  127u,  // 5
408             15u,  31u,  63u,   // 6
409         };
410 
411         constexpr static uint8_t kLumColors[7 * 1] = {
412             255u,  // 0
413             163u,  // 1
414             78u,   // 2
415             114u,  // 3
416             51u,   // 4
417             0u,    // 5
418             217u,  // 6
419         };
420 
421         constexpr static uint8_t kLumaColors[7 * 2] = {
422             255u, 255u,  // 0
423             67u,  163u,  // 1
424             78u,  231u,  // 2
425             8u,   114u,  // 3
426             51u,  199u,  // 4
427             0u,   173u,  // 5
428             34u,  217u,  // 6
429         };
430 
431         constexpr static uint8_t kAlphaColors[7 * 1] = {
432             255u,  // 0
433             67u,   // 1
434             231u,  // 2
435             8u,    // 3
436             199u,  // 4
437             173u,  // 5
438             34u,   // 6
439         };
440 
441         *colorCount = 7;
442 
443         switch (sourceFormat)
444         {
445             case GL_RGB:
446                 *componentCount = 3;
447                 return kRgbColors;
448             case GL_RGBA:
449             case GL_BGRA_EXT:
450                 *componentCount = 4;
451                 return kRgbaColors;
452             case GL_LUMINANCE:
453                 *componentCount = 1;
454                 return kLumColors;
455             case GL_ALPHA:
456                 *componentCount = 1;
457                 return kAlphaColors;
458             case GL_LUMINANCE_ALPHA:
459                 *componentCount = 2;
460                 return kLumaColors;
461             default:
462                 EXPECT_EQ(true, false);
463                 return nullptr;
464         }
465     }
466 
initializeSourceTexture(GLenum target,GLenum sourceFormat,const uint8_t * srcColors,uint8_t componentCount)467     void initializeSourceTexture(GLenum target,
468                                  GLenum sourceFormat,
469                                  const uint8_t *srcColors,
470                                  uint8_t componentCount)
471     {
472         // The texture is initialized as 2x2.  If the componentCount is 1 or 3, then the input data
473         // will have a row pitch of 2 or 6, which needs to be padded to 4 or 8 respectively.
474         uint8_t srcColorsPadded[4 * 4];
475         size_t srcRowPitch =
476             2 * componentCount + (componentCount == 1 || componentCount == 3 ? 2 : 0);
477         size_t inputRowPitch = 2 * componentCount;
478         for (size_t row = 0; row < 2; ++row)
479         {
480             memcpy(&srcColorsPadded[row * srcRowPitch], &srcColors[row * inputRowPitch],
481                    inputRowPitch);
482             memset(&srcColorsPadded[row * srcRowPitch + inputRowPitch], 0,
483                    srcRowPitch - inputRowPitch);
484         }
485 
486         glBindTexture(target, mTextures[0]);
487         glTexImage2D(target, 0, sourceFormat, 2, 2, 0, sourceFormat, GL_UNSIGNED_BYTE,
488                      srcColorsPadded);
489     }
490 
testCopyTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha,GLint mesaYFlipParam)491     void testCopyTexture(GLenum sourceTarget,
492                          GLenum sourceFormat,
493                          GLenum destFormat,
494                          bool flipY,
495                          bool premultiplyAlpha,
496                          bool unmultiplyAlpha,
497                          GLint mesaYFlipParam)
498     {
499         if (!checkExtensions(sourceFormat, destFormat))
500         {
501             return;
502         }
503 
504         const bool hasMesaFbFlipYExt = IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y");
505         if (mesaYFlipParam && !hasMesaFbFlipYExt)
506             ASSERT_TRUE(hasMesaFbFlipYExt);
507 
508         if (sourceFormat == GL_LUMINANCE || sourceFormat == GL_LUMINANCE_ALPHA ||
509             sourceFormat == GL_ALPHA || destFormat == GL_LUMINANCE ||
510             destFormat == GL_LUMINANCE_ALPHA || destFormat == GL_ALPHA)
511         {
512             // http://anglebug.com/42263512
513             ANGLE_SKIP_TEST_IF(IsOpenGL() && destFormat == GL_SRGB_ALPHA_EXT);
514         }
515 
516         size_t colorCount;
517         uint8_t componentCount;
518         const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
519 
520         std::vector<GLColor> destColors(colorCount);
521         for (size_t i = 0; i < colorCount; ++i)
522         {
523             calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
524                                         &srcColors[i * componentCount], &destColors[i]);
525         }
526 
527         for (size_t i = 0; i < colorCount - 3; ++i)
528         {
529             initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
530                                     componentCount);
531 
532             if (hasMesaFbFlipYExt)
533             {
534                 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
535                                             mesaYFlipParam);
536             }
537             glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
538                                   GL_UNSIGNED_BYTE, flipY, premultiplyAlpha, unmultiplyAlpha);
539 
540             EXPECT_GL_NO_ERROR();
541 
542             // Check that FB is complete.
543             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
544 
545             if (flipY)
546             {
547                 if (mesaYFlipParam)
548                 {
549                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
550                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
551                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
552                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
553                 }
554                 else
555                 {
556                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
557                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
558                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
559                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
560                 }
561             }
562             else
563             {
564                 if (mesaYFlipParam)
565                 {
566                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
567                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
568                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
569                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
570                 }
571                 else
572                 {
573                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
574                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
575                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
576                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
577                 }
578             }
579 
580             EXPECT_GL_NO_ERROR();
581         }
582     }
583 
testCopySubTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha,GLint mesaYFlipParam)584     void testCopySubTexture(GLenum sourceTarget,
585                             GLenum sourceFormat,
586                             GLenum destFormat,
587                             bool flipY,
588                             bool premultiplyAlpha,
589                             bool unmultiplyAlpha,
590                             GLint mesaYFlipParam)
591     {
592         if (!checkExtensions(sourceFormat, destFormat))
593         {
594             return;
595         }
596 
597         const bool hasMesaFbFlipYExt = IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y");
598         if (mesaYFlipParam && !hasMesaFbFlipYExt)
599             ASSERT_TRUE(hasMesaFbFlipYExt);
600 
601         if (sourceFormat == GL_LUMINANCE || sourceFormat == GL_LUMINANCE_ALPHA ||
602             sourceFormat == GL_ALPHA || destFormat == GL_LUMINANCE ||
603             destFormat == GL_LUMINANCE_ALPHA || destFormat == GL_ALPHA)
604         {
605             // http://anglebug.com/42263512
606             ANGLE_SKIP_TEST_IF(IsOpenGL() && destFormat == GL_SRGB_ALPHA_EXT);
607         }
608 
609         size_t colorCount;
610         uint8_t componentCount;
611         const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
612 
613         std::vector<GLColor> destColors(colorCount);
614         for (size_t i = 0; i < colorCount; ++i)
615         {
616             calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
617                                         &srcColors[i * componentCount], &destColors[i]);
618         }
619 
620         for (size_t i = 0; i < colorCount - 3; ++i)
621         {
622             initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
623                                     componentCount);
624 
625             glBindTexture(GL_TEXTURE_2D, mTextures[1]);
626             glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 2, 2, 0, destFormat, GL_UNSIGNED_BYTE,
627                          nullptr);
628 
629             if (hasMesaFbFlipYExt)
630             {
631                 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
632                                             mesaYFlipParam);
633             }
634             glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 2,
635                                      2, flipY, premultiplyAlpha, unmultiplyAlpha);
636 
637             EXPECT_GL_NO_ERROR();
638 
639             if (sourceFormat != GL_LUMINANCE && sourceFormat != GL_LUMINANCE_ALPHA &&
640                 sourceFormat != GL_ALPHA)
641             {
642                 // Check that FB is complete.
643                 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
644             }
645 
646             if (flipY)
647             {
648                 if (mesaYFlipParam)
649                 {
650                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
651                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
652                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
653                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
654                 }
655                 else
656                 {
657                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
658                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
659                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
660                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
661                 }
662             }
663             else
664             {
665                 if (mesaYFlipParam)
666                 {
667                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
668                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
669                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
670                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
671                 }
672                 else
673                 {
674                     EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
675                     EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
676                     EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
677                     EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
678                 }
679             }
680 
681             EXPECT_GL_NO_ERROR();
682         }
683     }
684 
685     GLuint mTextures[2] = {
686         0,
687         0,
688     };
689     GLuint mFramebuffer = 0;
690 };
691 
692 class CopyTextureTestDest : public CopyTextureTest
693 {};
694 
695 class CopyTextureTestWebGL : public CopyTextureTest
696 {
697   protected:
CopyTextureTestWebGL()698     CopyTextureTestWebGL() : CopyTextureTest() { setWebGLCompatibilityEnabled(true); }
699 };
700 
701 class CopyTextureTestES3 : public CopyTextureTest
702 {
703   protected:
704     void invalidateBlitThenBlendCommon(GLsizei layerCount);
705 };
706 
707 // Test that CopyTexture cannot redefine an immutable texture and CopySubTexture can copy data to
708 // immutable textures
TEST_P(CopyTextureTest,ImmutableTexture)709 TEST_P(CopyTextureTest, ImmutableTexture)
710 {
711     if (!checkExtensions())
712     {
713         return;
714     }
715 
716     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
717                        (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
718                         !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
719 
720     GLColor pixels = GLColor::red;
721 
722     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
723     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
724     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
725 
726     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
727     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
728     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
729     EXPECT_GL_NO_ERROR();
730 
731     // Should generate an error when the texture is redefined
732     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
733                           GL_UNSIGNED_BYTE, false, false, false);
734     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
735 
736     // Should succeed when using CopySubTexture
737     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1, 1,
738                              false, false, false);
739     EXPECT_GL_NO_ERROR();
740 
741     // Check that FB is complete.
742     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
743 
744     EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
745 
746     EXPECT_GL_NO_ERROR();
747 }
748 
749 struct FormatPair
750 {
FormatPairangle::FormatPair751     explicit FormatPair(GLenum format) : format(format), internalFormat(format) {}
FormatPairangle::FormatPair752     FormatPair(GLenum format, GLint internalFormat) : format(format), internalFormat(internalFormat)
753     {}
754 
755     GLenum format;
756     GLint internalFormat;
757 };
758 
759 // Test validation of internal formats in CopyTexture and CopySubTexture
TEST_P(CopyTextureTest,InternalFormat)760 TEST_P(CopyTextureTest, InternalFormat)
761 {
762     if (!checkExtensions())
763     {
764         return;
765     }
766 
767     std::vector<FormatPair> sourceFormats;
768     sourceFormats.push_back(FormatPair(GL_ALPHA));
769     sourceFormats.push_back(FormatPair(GL_RGB));
770     sourceFormats.push_back(FormatPair(GL_RGBA));
771     sourceFormats.push_back(FormatPair(GL_LUMINANCE));
772     sourceFormats.push_back(FormatPair(GL_LUMINANCE_ALPHA));
773 
774     std::vector<FormatPair> destFormats;
775     destFormats.push_back(FormatPair(GL_RGB));
776     destFormats.push_back(FormatPair(GL_RGBA));
777 
778     if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
779     {
780         sourceFormats.push_back(FormatPair(GL_BGRA_EXT));
781         destFormats.push_back(FormatPair(GL_BGRA_EXT));
782     }
783 
784     if (IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"))
785     {
786         sourceFormats.push_back(FormatPair(GL_RGB, GL_RGBX8_ANGLE));
787         destFormats.push_back(FormatPair(GL_RGB, GL_RGBX8_ANGLE));
788     }
789 
790     // Test with glCopyTexture
791     for (FormatPair &sourceFormat : sourceFormats)
792     {
793         for (FormatPair &destFormat : destFormats)
794         {
795             glBindTexture(GL_TEXTURE_2D, mTextures[0]);
796             glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat.internalFormat, 1, 1, 0,
797                          sourceFormat.format, GL_UNSIGNED_BYTE, nullptr);
798             EXPECT_GL_NO_ERROR();
799 
800             glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0,
801                                   destFormat.internalFormat, GL_UNSIGNED_BYTE, false, false, false);
802 
803             EXPECT_GL_NO_ERROR();
804         }
805     }
806 
807     // Test with glCopySubTexture
808     for (FormatPair &sourceFormat : sourceFormats)
809     {
810         for (FormatPair &destFormat : destFormats)
811         {
812             glBindTexture(GL_TEXTURE_2D, mTextures[0]);
813             glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat.internalFormat, 1, 1, 0,
814                          sourceFormat.format, GL_UNSIGNED_BYTE, nullptr);
815             EXPECT_GL_NO_ERROR();
816 
817             glBindTexture(GL_TEXTURE_2D, mTextures[1]);
818             glTexImage2D(GL_TEXTURE_2D, 0, destFormat.internalFormat, 1, 1, 0, destFormat.format,
819                          GL_UNSIGNED_BYTE, nullptr);
820             EXPECT_GL_NO_ERROR();
821 
822             glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1,
823                                      1, false, false, false);
824 
825             EXPECT_GL_NO_ERROR();
826         }
827     }
828 }
829 
830 // Test to ensure that the destination texture is redefined if the properties are different.
TEST_P(CopyTextureTest,RedefineDestinationTexture)831 TEST_P(CopyTextureTest, RedefineDestinationTexture)
832 {
833     ANGLE_SKIP_TEST_IF(!checkExtensions());
834     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
835 
836     GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
837 
838     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
839     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
840 
841     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
842     glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
843     EXPECT_GL_NO_ERROR();
844 
845     // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
846     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
847     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
848     // GL_INVALID_VALUE due to bad dimensions.
849     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
850     EXPECT_GL_ERROR(GL_INVALID_VALUE);
851 
852     // If the dest texture has different properties, glCopyTextureCHROMIUM()
853     // redefines them.
854     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
855                           GL_UNSIGNED_BYTE, false, false, false);
856     EXPECT_GL_NO_ERROR();
857 
858     // glTexSubImage2D() succeeds because mTextures[1] is redefined into 2x2
859     // dimension and GL_RGBA format.
860     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
861     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
862     EXPECT_GL_NO_ERROR();
863 
864     // Check that FB is complete.
865     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
866 
867     EXPECT_PIXEL_COLOR_EQ(1, 1, pixels[3]);
868     EXPECT_GL_NO_ERROR();
869 }
870 
871 // Test that invalid dimensions in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureDimension)872 TEST_P(CopyTextureTest, CopySubTextureDimension)
873 {
874     if (!checkExtensions())
875     {
876         return;
877     }
878 
879     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
880     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
881 
882     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
883     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
884 
885     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
886                              false, false, false);
887     EXPECT_GL_NO_ERROR();
888 
889     // xoffset < 0
890     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, -1, 1, 0, 0, 1, 1,
891                              false, false, false);
892     EXPECT_GL_ERROR(GL_INVALID_VALUE);
893 
894     // x < 0
895     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, -1, 0, 1, 1,
896                              false, false, false);
897     EXPECT_GL_ERROR(GL_INVALID_VALUE);
898 
899     // xoffset + width > dest_width
900     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 2, 2, 0, 0, 2, 2,
901                              false, false, false);
902     EXPECT_GL_ERROR(GL_INVALID_VALUE);
903 
904     // x + width > source_width
905     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 1, 1, 2, 2,
906                              false, false, false);
907     EXPECT_GL_ERROR(GL_INVALID_VALUE);
908 }
909 
910 // Test that invalid IDs in CopyTexture are validated
TEST_P(CopyTextureTest,CopyTextureInvalidTextureIds)911 TEST_P(CopyTextureTest, CopyTextureInvalidTextureIds)
912 {
913     if (!checkExtensions())
914     {
915         return;
916     }
917 
918     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
919     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
920 
921     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
922     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
923 
924     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, GL_RGBA, GL_UNSIGNED_BYTE,
925                           false, false, false);
926     EXPECT_GL_ERROR(GL_INVALID_VALUE);
927 
928     glCopyTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA, GL_UNSIGNED_BYTE,
929                           false, false, false);
930     EXPECT_GL_ERROR(GL_INVALID_VALUE);
931 
932     glCopyTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, GL_RGBA, GL_UNSIGNED_BYTE, false,
933                           false, false);
934     EXPECT_GL_ERROR(GL_INVALID_VALUE);
935 
936     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
937                           GL_UNSIGNED_BYTE, false, false, false);
938     EXPECT_GL_NO_ERROR();
939 }
940 
941 // Test that the right error type is triggered when
942 // OES_EGL_image_external_essl3 is required but not supported
TEST_P(CopyTextureTest,CopyTextureMissingRequiredExtension)943 TEST_P(CopyTextureTest, CopyTextureMissingRequiredExtension)
944 {
945     if (!checkExtensions())
946     {
947         return;
948     }
949 
950     // decide if the test is relevant
951     // If GL_OES_EGL_image_external_essl3 is supported, then no need to test
952     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_OES_EGL_image_external_essl3"));
953     // GL_OES_EGL_image_external extension is required to use TEXTURE_EXTERNAL_OES
954     // as the texture target.  So if GL_OES_EGL_image_external is not supported,
955     // the error case cannot happen.
956     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
957     EGLWindow *window = getEGLWindow();
958     EGLDisplay dpy    = window->getDisplay();
959     // If EGL_KHR_image_base is not supported, then eglImageKHR cannot be used,
960     // and therefore the error case cannot happen
961     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_image_base"));
962 
963     // prepare test data
964     // create the texture data
965     GLTexture texture;
966     glBindTexture(GL_TEXTURE_2D, texture);
967     EXPECT_GL_NO_ERROR();
968     const std::vector<GLColor> kSourceColor(2 * 2, GLColor::green);
969     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
970                  kSourceColor.data());
971     EXPECT_GL_NO_ERROR();
972 
973     // create the image and load the texture data
974     constexpr EGLint attribs[] = {
975         EGL_IMAGE_PRESERVED,
976         EGL_TRUE,
977         EGL_NONE,
978     };
979     EGLImageKHR image = eglCreateImageKHR(
980         window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
981         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), attribs);
982     EXPECT_GL_NO_ERROR();
983     // source is from the image
984     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextures[0]);
985     EXPECT_GL_NO_ERROR();
986     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
987     EXPECT_GL_NO_ERROR();
988 
989     // dest
990     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
991     EXPECT_GL_NO_ERROR();
992     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
993     EXPECT_GL_NO_ERROR();
994 
995     // This copying needs EGLImageExternalEssl3OES extension
996     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGB32UI,
997                           GL_UNSIGNED_BYTE, false, false, false);
998 
999     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1000 
1001     // Non-integer dest internal format doesn't need the extension
1002     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1003                           GL_UNSIGNED_BYTE, false, false, false);
1004     EXPECT_GL_NO_ERROR();
1005 }
1006 
1007 // Test that invalid IDs in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureInvalidTextureIds)1008 TEST_P(CopyTextureTest, CopySubTextureInvalidTextureIds)
1009 {
1010     if (!checkExtensions())
1011     {
1012         return;
1013     }
1014 
1015     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1016     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1017 
1018     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1019     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1020 
1021     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, 1, 1, 0, 0, 1, 1, false,
1022                              false, false);
1023     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1024 
1025     glCopySubTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1, false,
1026                              false, false);
1027     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1028 
1029     glCopySubTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, 1, 1, 0, 0, 1, 1, false, false,
1030                              false);
1031     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1032 
1033     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
1034                              false, false, false);
1035     EXPECT_GL_NO_ERROR();
1036 }
1037 
TEST_P(CopyTextureTest,InvalidTarget)1038 TEST_P(CopyTextureTest, InvalidTarget)
1039 {
1040     ANGLE_SKIP_TEST_IF(!checkExtensions());
1041 
1042     GLTexture textures[2];
1043 
1044     glBindTexture(GL_TEXTURE_2D, textures[0]);
1045     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1046 
1047     glBindTexture(GL_TEXTURE_2D, textures[1]);
1048     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1049 
1050     // Invalid enum for a completely invalid target
1051     glCopySubTextureCHROMIUM(textures[0], 0, GL_INVALID_VALUE, textures[1], 0, 1, 1, 0, 0, 1, 1,
1052                              false, false, false);
1053     EXPECT_GL_ERROR(GL_INVALID_ENUM);
1054 
1055     // Invalid value for a valid target enum but is not valid for the destination texture
1056     glCopySubTextureCHROMIUM(textures[0], 0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textures[1], 0, 1, 1,
1057                              0, 0, 1, 1, false, false, false);
1058     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1059 }
1060 
1061 // Test that using an offset in CopySubTexture works correctly
TEST_P(CopyTextureTest,CopySubTextureOffset)1062 TEST_P(CopyTextureTest, CopySubTextureOffset)
1063 {
1064     if (!checkExtensions())
1065     {
1066         return;
1067     }
1068 
1069     GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
1070     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1071     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
1072 
1073     GLColor transparentPixels[4 * 4] = {GLColor::transparentBlack, GLColor::transparentBlack,
1074                                         GLColor::transparentBlack, GLColor::transparentBlack};
1075     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1076     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, transparentPixels);
1077 
1078     // Check that FB is complete.
1079     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1080 
1081     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
1082                              false, false, false);
1083     EXPECT_GL_NO_ERROR();
1084     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
1085 
1086     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 0, 1, 0, 1, 1,
1087                              false, false, false);
1088     EXPECT_GL_NO_ERROR();
1089     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
1090 
1091     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 1, 0, 1, 1, 1,
1092                              false, false, false);
1093     EXPECT_GL_NO_ERROR();
1094     EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue);
1095 
1096     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
1097     EXPECT_GL_NO_ERROR();
1098 }
1099 
1100 // Test that copying a texture attached to a framebuffer into a L texture does not break a
1101 // subsequent clear
TEST_P(CopyTextureTest,ClearAfterCopySubTextureLuminance)1102 TEST_P(CopyTextureTest, ClearAfterCopySubTextureLuminance)
1103 {
1104     if (!checkExtensions())
1105     {
1106         return;
1107     }
1108 
1109     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1110     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1111 
1112     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1113     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1114 
1115     glClearColor(1.0, 0.0, 0.0, 1.0);
1116     glClear(GL_COLOR_BUFFER_BIT);
1117     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1118 
1119     glCopySubTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, 0, 0, 0, 0, 4, 4,
1120                              GL_TRUE, GL_FALSE, GL_TRUE);
1121 
1122     glClearColor(0.0, 1.0, 0.0, 1.0);
1123     glClear(GL_COLOR_BUFFER_BIT);
1124     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1125 }
1126 
1127 // Test that copying a texture attached to a framebuffer into a LA texture does not break a
1128 // subsequent clear
TEST_P(CopyTextureTest,ClearAfterCopySubTextureLuminanceAlpha)1129 TEST_P(CopyTextureTest, ClearAfterCopySubTextureLuminanceAlpha)
1130 {
1131     if (!checkExtensions())
1132     {
1133         return;
1134     }
1135 
1136     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1137     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 4, 4, 0, GL_LUMINANCE_ALPHA,
1138                  GL_UNSIGNED_BYTE, nullptr);
1139 
1140     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1141     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1142 
1143     glClearColor(1.0, 0.0, 0.0, 1.0);
1144     glClear(GL_COLOR_BUFFER_BIT);
1145     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1146 
1147     glCopySubTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, 0, 0, 0, 0, 4, 4,
1148                              GL_TRUE, GL_FALSE, GL_TRUE);
1149 
1150     glClearColor(0.0, 1.0, 0.0, 1.0);
1151     glClear(GL_COLOR_BUFFER_BIT);
1152     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1153 }
1154 
1155 // Test every combination of copy [sub]texture parameters:
1156 // source: ALPHA, RGB, RGBA, LUMINANCE, LUMINANCE_ALPHA, BGRA_EXT
1157 // destination: RGB, RGBA, BGRA_EXT
1158 // flipY: false, true
1159 // premultiplyAlpha: false, true
1160 // unmultiplyAlpha: false, true
1161 namespace
1162 {
1163 constexpr GLenum kCopyTextureVariationsSrcFormats[] = {
1164     GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
1165 constexpr GLenum kCopyTextureVariationsDstFormats[] = {GL_RGB, GL_RGBA, GL_BGRA_EXT,
1166                                                        GL_SRGB_ALPHA_EXT};
1167 constexpr GLint kMesaYFlips[]                       = {0, 1};
1168 }  // anonymous namespace
1169 
TEST_P(CopyTextureVariationsTest,CopyTexture)1170 TEST_P(CopyTextureVariationsTest, CopyTexture)
1171 {
1172     // http://anglebug.com/42264260
1173     ANGLE_SKIP_TEST_IF(IsOzone());
1174     // http://anglebug.com/42263799
1175     if (std::get<1>(GetParam()) == GL_ALPHA && std::get<2>(GetParam()) == GL_RGB &&
1176         std::get<3>(GetParam()) && std::get<5>(GetParam()))
1177     {
1178         ANGLE_SKIP_TEST_IF(IsWindows7() && IsNVIDIA() && IsOpenGLES());
1179     }
1180 
1181     if (std::get<6>(GetParam()))
1182     {
1183         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1184     }
1185 
1186     testCopyTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
1187                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()),
1188                     std::get<6>(GetParam()));
1189 }
1190 
TEST_P(CopyTextureVariationsTest,CopySubTexture)1191 TEST_P(CopyTextureVariationsTest, CopySubTexture)
1192 {
1193     // http://anglebug.com/42264260
1194     ANGLE_SKIP_TEST_IF(IsOzone());
1195 
1196     if (std::get<6>(GetParam()))
1197     {
1198         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1199     }
1200 
1201     testCopySubTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
1202                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()),
1203                        std::get<6>(GetParam()));
1204 }
1205 
TEST_P(CopyTextureVariationsTest,CopyTextureRectangle)1206 TEST_P(CopyTextureVariationsTest, CopyTextureRectangle)
1207 {
1208     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
1209 
1210     if (std::get<6>(GetParam()))
1211     {
1212         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1213     }
1214 
1215     testCopyTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
1216                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()),
1217                     std::get<6>(GetParam()));
1218 }
1219 
TEST_P(CopyTextureVariationsTest,CopySubTextureRectangle)1220 TEST_P(CopyTextureVariationsTest, CopySubTextureRectangle)
1221 {
1222     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
1223 
1224     if (std::get<6>(GetParam()))
1225     {
1226         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1227     }
1228 
1229     testCopySubTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
1230                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()),
1231                        std::get<6>(GetParam()));
1232 }
1233 
1234 // Test that copying to cube maps works
TEST_P(CopyTextureTest,CubeMapTarget)1235 TEST_P(CopyTextureTest, CubeMapTarget)
1236 {
1237     if (!checkExtensions())
1238     {
1239         return;
1240     }
1241 
1242     // http://anglebug.com/42260718
1243     ANGLE_SKIP_TEST_IF(IsMac() && IsIntel() && IsDesktopOpenGL());
1244 
1245     // http://anglebug.com/42261821
1246     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1247 
1248     GLColor pixels[7] = {
1249         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
1250         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
1251         GLColor(70u, 73u, 76u, 79u),
1252     };
1253 
1254     GLTexture textures[2];
1255 
1256     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1257     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1258          face++)
1259     {
1260         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1261     }
1262 
1263     for (size_t i = 0; i < 2; ++i)
1264     {
1265         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1266              face++)
1267         {
1268             glBindTexture(GL_TEXTURE_2D, textures[0]);
1269             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1270                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1271 
1272             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
1273                                      false, false);
1274         }
1275 
1276         EXPECT_GL_NO_ERROR();
1277 
1278         GLFramebuffer fbo;
1279         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1280 
1281         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1282              face++)
1283         {
1284             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1285 
1286             // Check that FB is complete.
1287             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1288 
1289             EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1290 
1291             EXPECT_GL_NO_ERROR();
1292         }
1293     }
1294 }
1295 
1296 // Test that we can successfully copy into incomplete cube maps. Regression test for
1297 // http://anglebug.com/42262051
TEST_P(CopyTextureTest,IncompleteCubeMap)1298 TEST_P(CopyTextureTest, IncompleteCubeMap)
1299 {
1300     if (!checkExtensions())
1301     {
1302         return;
1303     }
1304 
1305     GLTexture texture2D;
1306     GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
1307     glBindTexture(GL_TEXTURE_2D, texture2D);
1308     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
1309 
1310     GLTexture textureCube;
1311     glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
1312     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1313          face++)
1314     {
1315         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1316     }
1317 
1318     // Set one face to 2x2
1319     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1320                  rgbaPixels);
1321 
1322     // Copy into the incomplete face
1323     glCopySubTextureCHROMIUM(texture2D, 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, textureCube, 0, 0, 0, 0,
1324                              0, 2, 2, false, false, false);
1325     EXPECT_GL_NO_ERROR();
1326 }
1327 
1328 // Test BGRA to RGBA cube map copy
TEST_P(CopyTextureTest,CubeMapTargetBGRA)1329 TEST_P(CopyTextureTest, CubeMapTargetBGRA)
1330 {
1331     if (!checkExtensions())
1332     {
1333         return;
1334     }
1335 
1336     if (!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1337     {
1338         return;
1339     }
1340 
1341     // http://anglebug.com/42261821
1342     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1343 
1344     GLColor pixels[7] = {
1345         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
1346         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
1347         GLColor(70u, 73u, 76u, 79u),
1348     };
1349 
1350     GLTexture textures[2];
1351 
1352     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1353     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1354          face++)
1355     {
1356         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1357     }
1358 
1359     for (size_t i = 0; i < 2; ++i)
1360     {
1361         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1362              face++)
1363         {
1364             glBindTexture(GL_TEXTURE_2D, textures[0]);
1365             glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1366                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1367 
1368             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
1369                                      false, false);
1370         }
1371 
1372         EXPECT_GL_NO_ERROR();
1373 
1374         GLFramebuffer fbo;
1375         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1376 
1377         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1378              face++)
1379         {
1380             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1381 
1382             // Check that FB is complete.
1383             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1384 
1385             GLColor converted = pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i];
1386             std::swap(converted.R, converted.B);
1387             EXPECT_PIXEL_COLOR_EQ(0, 0, converted);
1388 
1389             EXPECT_GL_NO_ERROR();
1390         }
1391     }
1392 }
1393 
1394 // Test cube map copies with RGB format
TEST_P(CopyTextureTest,CubeMapTargetRGB)1395 TEST_P(CopyTextureTest, CubeMapTargetRGB)
1396 {
1397     if (!checkExtensions())
1398     {
1399         return;
1400     }
1401 
1402     // http://anglebug.com/42260718
1403     ANGLE_SKIP_TEST_IF(IsMac() && IsIntel() && IsDesktopOpenGL());
1404 
1405     // http://anglebug.com/42261821
1406     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1407 
1408     constexpr uint8_t pixels[16 * 7] = {
1409         0u,   3u,   6u,   10u,  13u,  16u,  0, 0, 20u,  23u,  26u,  30u,  33u,  36u,  0, 0,  // 2x2
1410         40u,  43u,  46u,  50u,  53u,  56u,  0, 0, 60u,  63u,  66u,  70u,  73u,  76u,  0, 0,  // 2x2
1411         80u,  83u,  86u,  90u,  93u,  96u,  0, 0, 100u, 103u, 106u, 110u, 113u, 116u, 0, 0,  // 2x2
1412         120u, 123u, 126u, 130u, 133u, 136u, 0, 0, 140u, 143u, 146u, 160u, 163u, 166u, 0, 0,  // 2x2
1413         170u, 173u, 176u, 180u, 183u, 186u, 0, 0, 190u, 193u, 196u, 200u, 203u, 206u, 0, 0,  // 2x2
1414         210u, 213u, 216u, 220u, 223u, 226u, 0, 0, 230u, 233u, 236u, 240u, 243u, 246u, 0, 0,  // 2x2
1415         10u,  50u,  100u, 30u,  80u,  130u, 0, 0, 60u,  110u, 160u, 90u,  140u, 200u, 0, 0,  // 2x2
1416     };
1417 
1418     GLTexture textures[2];
1419 
1420     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1421     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1422          face++)
1423     {
1424         glTexImage2D(face, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1425     }
1426 
1427     for (size_t i = 0; i < 2; ++i)
1428     {
1429         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1430              face++)
1431         {
1432             glBindTexture(GL_TEXTURE_2D, textures[0]);
1433             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
1434                          &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16]);
1435 
1436             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 2, 2, false,
1437                                      false, false);
1438         }
1439 
1440         EXPECT_GL_NO_ERROR();
1441 
1442         GLFramebuffer fbo;
1443         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1444 
1445         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1446              face++)
1447         {
1448             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1449 
1450             // Check that FB is complete.
1451             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1452 
1453             const uint8_t *faceData = &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16];
1454             EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(faceData[0], faceData[1], faceData[2], 255));
1455             EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor(faceData[3], faceData[4], faceData[5], 255));
1456             EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor(faceData[8], faceData[9], faceData[10], 255));
1457             EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor(faceData[11], faceData[12], faceData[13], 255));
1458 
1459             EXPECT_GL_NO_ERROR();
1460         }
1461     }
1462 }
1463 
1464 // Test that copying to non-zero mipmaps works
TEST_P(CopyTextureTest,CopyToMipmap)1465 TEST_P(CopyTextureTest, CopyToMipmap)
1466 {
1467     if (!checkExtensions())
1468     {
1469         return;
1470     }
1471 
1472     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1473                        !IsGLExtensionEnabled("GL_OES_fbo_render_mipmap"));
1474 
1475     GLColor pixels[] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
1476 
1477     GLTexture textures[2];
1478 
1479     glBindTexture(GL_TEXTURE_2D, textures[0]);
1480     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1481     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1482 
1483     glBindTexture(GL_TEXTURE_2D, textures[1]);
1484     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1485     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1486     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1487 
1488     std::vector<std::pair<GLint, GLint>> soureDestPairs;
1489     soureDestPairs.push_back(std::make_pair(0, 1));
1490 
1491     // ES3 allows copying from non-zero mips
1492     if (getClientMajorVersion() >= 3)
1493     {
1494         soureDestPairs.push_back(std::make_pair(1, 2));
1495     }
1496 
1497     for (const auto &sourceDestPair : soureDestPairs)
1498     {
1499         const GLint sourceLevel = sourceDestPair.first;
1500         const GLint destLevel   = sourceDestPair.second;
1501 
1502         glCopyTextureCHROMIUM(textures[0], sourceLevel, GL_TEXTURE_2D, textures[1], destLevel,
1503                               GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1504 
1505         EXPECT_GL_NO_ERROR();
1506 
1507         GLFramebuffer fbo;
1508         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1509         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
1510                                destLevel);
1511 
1512         // Check that FB is complete.
1513         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1514 
1515         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[0]);
1516 
1517         EXPECT_GL_NO_ERROR();
1518     }
1519 }
1520 
1521 // Test that copying outside the mipmap range works
TEST_P(CopyTextureTest,CopyOutsideMipmap)1522 TEST_P(CopyTextureTest, CopyOutsideMipmap)
1523 {
1524     if (!checkExtensions())
1525     {
1526         return;
1527     }
1528 
1529     // http://anglebug.com/42263316
1530     ANGLE_SKIP_TEST_IF(IsD3D());
1531 
1532     // http://anglebug.com/42263799
1533     ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsOpenGL());
1534 
1535     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1536 
1537     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
1538     glUseProgram(program);
1539     GLint textureLoc = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
1540     ASSERT_NE(-1, textureLoc);
1541     glUniform1i(textureLoc, 0);
1542 
1543     GLTexture textures[2];
1544 
1545     // Create two single-mip textures.
1546     glActiveTexture(GL_TEXTURE0);
1547     glBindTexture(GL_TEXTURE_2D, textures[0]);
1548     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
1549     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1550     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1551 
1552     glBindTexture(GL_TEXTURE_2D, textures[1]);
1553     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
1554     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1555     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1556 
1557     // Commit texture 0
1558     glBindTexture(GL_TEXTURE_2D, textures[0]);
1559     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
1560     ASSERT_GL_NO_ERROR();
1561     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1562 
1563     // Copy texture 1 into mip 1 of texture 0.  This mip is outside the range of the image allocated
1564     // for texture 0.
1565     glCopyTextureCHROMIUM(textures[1], 0, GL_TEXTURE_2D, textures[0], 1, GL_RGBA, GL_UNSIGNED_BYTE,
1566                           false, false, false);
1567     EXPECT_GL_NO_ERROR();
1568 
1569     // Draw with texture 0 again
1570     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
1571     ASSERT_GL_NO_ERROR();
1572     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1573 }
1574 
1575 // Test that copying from an RGBA8 texture to RGBA4 results in exactly 4-bit precision in the result
TEST_P(CopyTextureTest,DownsampleRGBA4444)1576 TEST_P(CopyTextureTest, DownsampleRGBA4444)
1577 {
1578     // Downsampling on copy is only guarenteed on D3D11
1579     ANGLE_SKIP_TEST_IF(!IsD3D11());
1580 
1581     GLTexture textures[2];
1582 
1583     GLColor pixels[] = {GLColor(0, 5, 6, 7), GLColor(17, 22, 25, 24), GLColor(34, 35, 36, 36),
1584                         GLColor(51, 53, 55, 55)};
1585 
1586     glBindTexture(GL_TEXTURE_2D, textures[0]);
1587     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1588 
1589     glBindTexture(GL_TEXTURE_2D, textures[1]);
1590     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1591                           GL_UNSIGNED_SHORT_4_4_4_4, GL_FALSE, GL_FALSE, GL_FALSE);
1592 
1593     GLFramebuffer fbo;
1594     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1595     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1596 
1597     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1598     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(17, 17, 17, 17), 1.0);
1599     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(34, 34, 34, 34), 1.0);
1600     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(51, 51, 51, 51), 1.0);
1601 
1602     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, {16, 16, 16, 16});
1603 }
1604 
1605 // Test that copying from an RGBA8 texture to RGB565 results in exactly 4-bit precision in the
1606 // result
TEST_P(CopyTextureTest,DownsampleRGB565)1607 TEST_P(CopyTextureTest, DownsampleRGB565)
1608 {
1609     // Downsampling on copy is only guarenteed on D3D11
1610     ANGLE_SKIP_TEST_IF(!IsD3D11());
1611 
1612     GLTexture textures[2];
1613 
1614     GLColor pixels[] = {GLColor(0, 5, 2, 14), GLColor(17, 22, 25, 30), GLColor(34, 33, 36, 46),
1615                         GLColor(50, 54, 49, 60)};
1616 
1617     glBindTexture(GL_TEXTURE_2D, textures[0]);
1618     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1619 
1620     glBindTexture(GL_TEXTURE_2D, textures[1]);
1621     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGB,
1622                           GL_UNSIGNED_SHORT_5_6_5, GL_FALSE, GL_FALSE, GL_FALSE);
1623 
1624     GLFramebuffer fbo;
1625     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1626     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1627 
1628     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 4, 0, 255), 1.0);
1629     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 20, 25, 255), 1.0);
1630     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 32, 33, 255), 1.0);
1631     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 53, 49, 255), 1.0);
1632 
1633     testGradientDownsampleUniqueValues(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, {32, 64, 32, 1});
1634 }
1635 
1636 // Test that copying from an RGBA8 texture to RGBA5551 results in exactly 4-bit precision in the
1637 // result
TEST_P(CopyTextureTest,DownsampleRGBA5551)1638 TEST_P(CopyTextureTest, DownsampleRGBA5551)
1639 {
1640     // Downsampling on copy is only guarenteed on D3D11
1641     ANGLE_SKIP_TEST_IF(!IsD3D11());
1642 
1643     GLTexture textures[2];
1644 
1645     GLColor pixels[] = {GLColor(0, 1, 2, 3), GLColor(14, 16, 17, 18), GLColor(33, 34, 36, 46),
1646                         GLColor(50, 51, 52, 255)};
1647 
1648     glBindTexture(GL_TEXTURE_2D, textures[0]);
1649     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1650 
1651     glBindTexture(GL_TEXTURE_2D, textures[1]);
1652     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1653                           GL_UNSIGNED_SHORT_5_5_5_1, GL_FALSE, GL_FALSE, GL_FALSE);
1654 
1655     GLFramebuffer fbo;
1656     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1657     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1658 
1659     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1660     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 16, 16, 0), 1.0);
1661     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 33, 33, 0), 1.0);
1662     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 49, 49, 255), 1.0);
1663 
1664     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, {32, 32, 32, 2});
1665 }
1666 
1667 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination
TEST_P(CopyTextureTestDest,Luminance)1668 TEST_P(CopyTextureTestDest, Luminance)
1669 {
1670     if (!checkExtensions())
1671     {
1672         return;
1673     }
1674 
1675     GLColor originalPixels(50u, 100u, 150u, 200u);
1676     GLColor expectedPixels(50u, 50u, 50u, 255u);
1677 
1678     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1679     // texture to verify contents.
1680     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1681     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1682     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1683     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1684 
1685     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1686                           GL_UNSIGNED_BYTE, false, false, false);
1687 
1688     EXPECT_GL_NO_ERROR();
1689 
1690     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1691                           GL_UNSIGNED_BYTE, false, false, false);
1692 
1693     EXPECT_GL_NO_ERROR();
1694 
1695     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1696 }
1697 
1698 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1699 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceMultiply)1700 TEST_P(CopyTextureTestDest, LuminanceMultiply)
1701 {
1702     if (!checkExtensions())
1703     {
1704         return;
1705     }
1706 
1707     GLColor originalPixels(50u, 100u, 150u, 200u);
1708     GLColor expectedPixels(39u, 39u, 39u, 255u);
1709 
1710     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1711     // texture to verify contents.
1712     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1713     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1714     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1715     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1716 
1717     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1718                           GL_UNSIGNED_BYTE, false, true, false);
1719 
1720     EXPECT_GL_NO_ERROR();
1721 
1722     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1723                           GL_UNSIGNED_BYTE, false, false, false);
1724 
1725     EXPECT_GL_NO_ERROR();
1726 
1727     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1728 }
1729 
1730 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1731 // UnpackUnmultiply parameter
TEST_P(CopyTextureTestDest,LuminanceUnmultiply)1732 TEST_P(CopyTextureTestDest, LuminanceUnmultiply)
1733 {
1734     if (!checkExtensions())
1735     {
1736         return;
1737     }
1738 
1739     GLColor originalPixels(50u, 100u, 150u, 200u);
1740     GLColor expectedPixels(64u, 64u, 64u, 255u);
1741 
1742     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1743     // texture to verify contents.
1744     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1745     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1746     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1747     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1748 
1749     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1750                           GL_UNSIGNED_BYTE, false, false, true);
1751 
1752     EXPECT_GL_NO_ERROR();
1753 
1754     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1755                           GL_UNSIGNED_BYTE, false, false, false);
1756 
1757     EXPECT_GL_NO_ERROR();
1758 
1759     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1760 }
1761 
1762 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination
TEST_P(CopyTextureTestDest,LuminanceAlpha)1763 TEST_P(CopyTextureTestDest, LuminanceAlpha)
1764 {
1765     if (!checkExtensions())
1766     {
1767         return;
1768     }
1769 
1770     GLColor originalPixels(50u, 100u, 150u, 200u);
1771     GLColor expectedPixels(50u, 50u, 50u, 200u);
1772 
1773     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1774     // RGBA texture to verify contents.
1775     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1776     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1777     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1778     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1779                  GL_UNSIGNED_BYTE, nullptr);
1780 
1781     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1782                           GL_UNSIGNED_BYTE, false, false, false);
1783 
1784     EXPECT_GL_NO_ERROR();
1785 
1786     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1787                           GL_UNSIGNED_BYTE, false, false, false);
1788 
1789     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1790 }
1791 
1792 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1793 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaMultiply)1794 TEST_P(CopyTextureTestDest, LuminanceAlphaMultiply)
1795 {
1796     if (!checkExtensions())
1797     {
1798         return;
1799     }
1800 
1801     GLColor originalPixels(50u, 100u, 150u, 200u);
1802     GLColor expectedPixels(39u, 39u, 39u, 200u);
1803 
1804     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1805     // RGBA texture to verify contents.
1806     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1807     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1808     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1809     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1810                  GL_UNSIGNED_BYTE, nullptr);
1811 
1812     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1813                           GL_UNSIGNED_BYTE, false, true, false);
1814 
1815     EXPECT_GL_NO_ERROR();
1816 
1817     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1818                           GL_UNSIGNED_BYTE, false, false, false);
1819 
1820     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1821 }
1822 
1823 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1824 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaUnmultiply)1825 TEST_P(CopyTextureTestDest, LuminanceAlphaUnmultiply)
1826 {
1827     if (!checkExtensions())
1828     {
1829         return;
1830     }
1831 
1832     GLColor originalPixels(50u, 100u, 150u, 200u);
1833     GLColor expectedPixels(64u, 64u, 64u, 200u);
1834 
1835     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1836     // RGBA texture to verify contents.
1837     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1838     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1839     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1840     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1841                  GL_UNSIGNED_BYTE, nullptr);
1842 
1843     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1844                           GL_UNSIGNED_BYTE, false, false, true);
1845 
1846     EXPECT_GL_NO_ERROR();
1847 
1848     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1849                           GL_UNSIGNED_BYTE, false, false, false);
1850 
1851     EXPECT_GL_NO_ERROR();
1852 
1853     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1854 }
1855 
1856 // Test to ensure that CopyTexture works with ALPHA texture as a destination
TEST_P(CopyTextureTestDest,Alpha)1857 TEST_P(CopyTextureTestDest, Alpha)
1858 {
1859     if (!checkExtensions())
1860     {
1861         return;
1862     }
1863 
1864     GLColor originalPixels(50u, 100u, 150u, 155u);
1865     GLColor expectedPixels(0u, 0u, 0u, 155u);
1866 
1867     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1868     // texture to verify contents.
1869     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1870     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1871     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1872     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1873 
1874     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1875                           GL_UNSIGNED_BYTE, false, false, false);
1876 
1877     EXPECT_GL_NO_ERROR();
1878 
1879     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1880                           GL_UNSIGNED_BYTE, false, false, false);
1881 
1882     EXPECT_GL_NO_ERROR();
1883 
1884     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1885 }
1886 
1887 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1888 // UnpackPremultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaMultiply)1889 TEST_P(CopyTextureTestDest, AlphaMultiply)
1890 {
1891     if (!checkExtensions())
1892     {
1893         return;
1894     }
1895 
1896     GLColor originalPixels(50u, 100u, 150u, 155u);
1897     GLColor expectedPixels(0u, 0u, 0u, 155u);
1898 
1899     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1900     // texture to verify contents.
1901     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1902     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1903     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1904     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1905 
1906     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1907                           GL_UNSIGNED_BYTE, false, true, false);
1908 
1909     EXPECT_GL_NO_ERROR();
1910 
1911     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1912                           GL_UNSIGNED_BYTE, false, false, false);
1913 
1914     EXPECT_GL_NO_ERROR();
1915 
1916     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1917 }
1918 
1919 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1920 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaUnmultiply)1921 TEST_P(CopyTextureTestDest, AlphaUnmultiply)
1922 {
1923     if (!checkExtensions())
1924     {
1925         return;
1926     }
1927 
1928     GLColor originalPixels(50u, 100u, 150u, 155u);
1929     GLColor expectedPixels(0u, 0u, 0u, 155u);
1930 
1931     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1932     // texture to verify contents.
1933     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1934     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1935     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1936     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1937 
1938     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1939                           GL_UNSIGNED_BYTE, false, false, true);
1940 
1941     EXPECT_GL_NO_ERROR();
1942 
1943     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1944                           GL_UNSIGNED_BYTE, false, false, false);
1945 
1946     EXPECT_GL_NO_ERROR();
1947 
1948     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1949 }
1950 
1951 // Test to ensure that CopyTexture uses the correct ALPHA passthrough shader to ensure RGB channels
1952 // are set to 0.
TEST_P(CopyTextureTestDest,AlphaCopyWithRGB)1953 TEST_P(CopyTextureTestDest, AlphaCopyWithRGB)
1954 {
1955     // http://anglebug.com/40644706
1956     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
1957     ANGLE_SKIP_TEST_IF(!checkExtensions());
1958     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
1959 
1960     GLColor originalPixels(50u, 100u, 150u, 155u);
1961     GLColor expectedPixels(0u, 0u, 0u, 155u);
1962 
1963     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1964     // texture to verify contents.
1965     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1966     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1967     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1968     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_HALF_FLOAT_OES, nullptr);
1969 
1970     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1971                           GL_HALF_FLOAT_OES, false, false, false);
1972 
1973     EXPECT_GL_NO_ERROR();
1974 
1975     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1976                           GL_UNSIGNED_BYTE, false, false, false);
1977 
1978     EXPECT_GL_NO_ERROR();
1979 
1980     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1981 }
1982 
1983 // Bug where TEXTURE_SWIZZLE_RGBA was not reset after the Luminance workaround. (crbug.com/1022080)
TEST_P(CopyTextureTestES3,LuminanceWorkaroundTextureSwizzleBug)1984 TEST_P(CopyTextureTestES3, LuminanceWorkaroundTextureSwizzleBug)
1985 {
1986     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB"));
1987 
1988     {
1989         GLColor pixels(50u, 20u, 100u, 150u);
1990 
1991         // Hit BlitGL::copySubImageToLUMAWorkaroundTexture by copying an ALPHA texture
1992         GLTexture srcTexture;
1993         glBindTexture(GL_TEXTURE_2D, srcTexture);
1994         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
1995 
1996         GLFramebuffer srcFBO;
1997         glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
1998         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
1999 
2000         GLTexture dstTexture;
2001         glBindTexture(GL_TEXTURE_2D, dstTexture);
2002         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
2003 
2004         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
2005         EXPECT_GL_NO_ERROR();
2006     }
2007 
2008     {
2009         // This time hit BlitGL::blitColorBufferWithShader by copying an SRGB texture
2010         GLColor pixels(100u, 200u, 50u, 210u);
2011 
2012         GLTexture srcTexture;
2013         glBindTexture(GL_TEXTURE_2D, srcTexture);
2014         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
2015                      GL_UNSIGNED_BYTE, &pixels);
2016 
2017         GLFramebuffer srcFBO;
2018         glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
2019         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture,
2020                                0);
2021 
2022         GLTexture dstTexture;
2023         glBindTexture(GL_TEXTURE_2D, dstTexture);
2024         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
2025                      GL_UNSIGNED_BYTE, nullptr);
2026 
2027         GLFramebuffer dstFBO;
2028         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
2029         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture,
2030                                0);
2031 
2032         glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2033 
2034         // The previous workaround should not affect this copy
2035         glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
2036         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
2037     }
2038 }
2039 
2040 // Test to ensure that CopyTexture will fail with a non-zero level and NPOT texture in WebGL
TEST_P(CopyTextureTestWebGL,NPOT)2041 TEST_P(CopyTextureTestWebGL, NPOT)
2042 {
2043     if (IsGLExtensionRequestable("GL_CHROMIUM_copy_texture"))
2044     {
2045         glRequestExtensionANGLE("GL_CHROMIUM_copy_texture");
2046     }
2047     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
2048 
2049     std::vector<GLColor> pixelData(10 * 10, GLColor::red);
2050 
2051     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
2052     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
2053 
2054     // Do a basic copy to make sure things work
2055     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
2056                           GL_UNSIGNED_BYTE, false, false, false);
2057 
2058     EXPECT_GL_NO_ERROR();
2059 
2060     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2061 
2062     // Do the same operation with destLevel 1, which should fail
2063     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 1, GL_RGBA,
2064                           GL_UNSIGNED_BYTE, false, false, false);
2065 
2066     EXPECT_GL_ERROR(GL_INVALID_VALUE);
2067 }
2068 
2069 // Test the newly added ES3 unorm formats
TEST_P(CopyTextureTestES3,ES3UnormFormats)2070 TEST_P(CopyTextureTestES3, ES3UnormFormats)
2071 {
2072     if (!checkExtensions())
2073     {
2074         return;
2075     }
2076     // http://anglebug.com/40096654
2077     ANGLE_SKIP_TEST_IF(IsAndroid());
2078 
2079     // http://anglebug.com/42263690
2080     ANGLE_SKIP_TEST_IF(IsWindows() && IsOpenGL() && IsIntel());
2081 
2082     auto testOutput = [this](GLuint texture, const GLColor &expectedColor) {
2083         constexpr char kVS[] =
2084             "#version 300 es\n"
2085             "in vec4 position;\n"
2086             "out vec2 texcoord;\n"
2087             "void main()\n"
2088             "{\n"
2089             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2090             "    texcoord = (position.xy * 0.5) + 0.5;\n"
2091             "}\n";
2092 
2093         constexpr char kFS[] =
2094             "#version 300 es\n"
2095             "precision mediump float;\n"
2096             "uniform sampler2D tex;\n"
2097             "in vec2 texcoord;\n"
2098             "out vec4 color;\n"
2099             "void main()\n"
2100             "{\n"
2101             "    color = texture(tex, texcoord);\n"
2102             "}\n";
2103 
2104         ANGLE_GL_PROGRAM(program, kVS, kFS);
2105         glUseProgram(program);
2106 
2107         GLRenderbuffer rbo;
2108         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2109         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
2110 
2111         GLFramebuffer fbo;
2112         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2113         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2114 
2115         glActiveTexture(GL_TEXTURE0);
2116         glBindTexture(GL_TEXTURE_2D, texture);
2117         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2118         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2119         glUniform1i(glGetUniformLocation(program, "tex"), 0);
2120 
2121         drawQuad(program, "position", 0.5f, 1.0f, true);
2122 
2123         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
2124     };
2125 
2126     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
2127                                             GLenum sourceType, const GLColor &sourceColor,
2128                                             GLenum destInternalFormat, GLenum destType, bool flipY,
2129                                             bool premultiplyAlpha, bool unmultiplyAlpha,
2130                                             const GLColor &expectedColor) {
2131         GLTexture sourceTexture;
2132         glBindTexture(GL_TEXTURE_2D, sourceTexture);
2133         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2134                      &sourceColor);
2135 
2136         GLTexture destTexture;
2137         glBindTexture(GL_TEXTURE_2D, destTexture);
2138 
2139         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2140                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2141         ASSERT_GL_NO_ERROR();
2142 
2143         testOutput(destTexture, expectedColor);
2144     };
2145 
2146     auto testSubCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
2147                                                GLenum sourceType, const GLColor &sourceColor,
2148                                                GLenum destInternalFormat, GLenum destFormat,
2149                                                GLenum destType, bool flipY, bool premultiplyAlpha,
2150                                                bool unmultiplyAlpha, const GLColor &expectedColor) {
2151         GLTexture sourceTexture;
2152         glBindTexture(GL_TEXTURE_2D, sourceTexture);
2153         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2154                      &sourceColor);
2155 
2156         GLTexture destTexture;
2157         glBindTexture(GL_TEXTURE_2D, destTexture);
2158 
2159         glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
2160         glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
2161                                  flipY, premultiplyAlpha, unmultiplyAlpha);
2162         ASSERT_GL_NO_ERROR();
2163 
2164         testOutput(destTexture, expectedColor);
2165     };
2166 
2167     // New LUMA source formats
2168     testCopyCombination(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGB,
2169                         GL_UNSIGNED_BYTE, false, false, false, GLColor(128, 128, 128, 255));
2170     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
2171                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, false,
2172                         GLColor(128, 128, 128, 255));
2173     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
2174                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, true, false,
2175                         GLColor(32, 32, 32, 255));
2176     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
2177                         GLColor(128, 128, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, true,
2178                         GLColor(255, 255, 255, 255));
2179     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
2180                         GL_UNSIGNED_BYTE, false, false, false, GLColor(0, 0, 0, 128));
2181     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
2182                         GL_UNSIGNED_BYTE, false, false, true, GLColor(0, 0, 0, 128));
2183     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
2184                         GL_UNSIGNED_BYTE, false, true, false, GLColor(0, 0, 0, 128));
2185 
2186     // New sRGB dest formats
2187     if (IsGLExtensionEnabled("GL_EXT_sRGB"))
2188     {
2189         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
2190                             GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
2191         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
2192                             GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
2193         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2194                             GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
2195                             GLColor(55, 13, 4, 128));
2196 
2197         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2198                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, false, false,
2199                                GLColor(55, 13, 4, 255));
2200         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2201                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, true, false,
2202                                GLColor(13, 4, 1, 255));
2203         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2204                                GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
2205                                false, GLColor(55, 13, 4, 128));
2206     }
2207 }
2208 
2209 // Test the newly added ES3 float formats
TEST_P(CopyTextureTestES3,ES3FloatFormats)2210 TEST_P(CopyTextureTestES3, ES3FloatFormats)
2211 {
2212     if (!checkExtensions())
2213     {
2214         return;
2215     }
2216 
2217     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
2218 
2219     auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
2220         constexpr char kVS[] =
2221             "#version 300 es\n"
2222             "in vec4 position;\n"
2223             "out vec2 texcoord;\n"
2224             "void main()\n"
2225             "{\n"
2226             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2227             "    texcoord = (position.xy * 0.5) + 0.5;\n"
2228             "}\n";
2229 
2230         constexpr char kFS[] =
2231             "#version 300 es\n"
2232             "precision mediump float;\n"
2233             "uniform sampler2D tex;\n"
2234             "in vec2 texcoord;\n"
2235             "out vec4 color;\n"
2236             "void main()\n"
2237             "{\n"
2238             "    color = texture(tex, texcoord);\n"
2239             "}\n";
2240 
2241         ANGLE_GL_PROGRAM(program, kVS, kFS);
2242         glUseProgram(program);
2243 
2244         GLRenderbuffer rbo;
2245         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2246         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
2247 
2248         GLFramebuffer fbo;
2249         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2250         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2251 
2252         glActiveTexture(GL_TEXTURE0);
2253         glBindTexture(GL_TEXTURE_2D, texture);
2254         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2255         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2256         glUniform1i(glGetUniformLocation(program, "tex"), 0);
2257 
2258         drawQuad(program, "position", 0.5f, 1.0f, true);
2259 
2260         EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
2261     };
2262 
2263     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
2264                                             GLenum sourceType, const GLColor &sourceColor,
2265                                             GLenum destInternalFormat, GLenum destType, bool flipY,
2266                                             bool premultiplyAlpha, bool unmultiplyAlpha,
2267                                             const GLColor32F &expectedColor) {
2268         GLTexture sourceTexture;
2269         glBindTexture(GL_TEXTURE_2D, sourceTexture);
2270         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2271                      &sourceColor);
2272 
2273         GLTexture destTexture;
2274         glBindTexture(GL_TEXTURE_2D, destTexture);
2275 
2276         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2277                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2278         ASSERT_GL_NO_ERROR();
2279 
2280         testOutput(destTexture, expectedColor);
2281     };
2282 
2283     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
2284                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 0.5f));
2285     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
2286                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 0.5f));
2287     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
2288                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 0.5f));
2289 
2290     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
2291                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.0f, 0.0f, 1.0f));
2292     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
2293                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.0f, 0.0f, 1.0f));
2294     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
2295                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.0f, 0.0f, 1.0f));
2296 
2297     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
2298                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.0f, 1.0f));
2299     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
2300                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0f, 1.0f));
2301     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
2302                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.0f, 1.0f));
2303 
2304     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
2305                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
2306     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
2307                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
2308     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
2309                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
2310 
2311     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2312                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, false,
2313                         GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
2314     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2315                         GL_R11F_G11F_B10F, GL_FLOAT, false, true, false,
2316                         GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
2317     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2318                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, true,
2319                         GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
2320 
2321     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
2322                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
2323     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
2324                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
2325     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
2326                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
2327 }
2328 
2329 // Test the newly added ES3 unsigned integer formats
TEST_P(CopyTextureTestES3,ES3UintFormats)2330 TEST_P(CopyTextureTestES3, ES3UintFormats)
2331 {
2332     ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsIntel());
2333 
2334     if (!checkExtensions())
2335     {
2336         return;
2337     }
2338 
2339     using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
2340 
2341     auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
2342         constexpr char kVS[] =
2343             "#version 300 es\n"
2344             "in vec4 position;\n"
2345             "out vec2 texcoord;\n"
2346             "void main()\n"
2347             "{\n"
2348             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2349             "    texcoord = (position.xy * 0.5) + 0.5;\n"
2350             "}\n";
2351 
2352         constexpr char kFS[] =
2353             "#version 300 es\n"
2354             "precision mediump float;\n"
2355             "precision mediump usampler2D;\n"
2356             "in vec2 texcoord;\n"
2357             "uniform usampler2D tex;\n"
2358             "out uvec4 color;\n"
2359             "void main()\n"
2360             "{\n"
2361             "    color = texture(tex, texcoord);\n"
2362             "}\n";
2363 
2364         ANGLE_GL_PROGRAM(program, kVS, kFS);
2365         glUseProgram(program);
2366 
2367         GLRenderbuffer rbo;
2368         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2369         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8UI, 1, 1);
2370 
2371         GLFramebuffer fbo;
2372         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2373         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2374 
2375         glActiveTexture(GL_TEXTURE0);
2376         glBindTexture(GL_TEXTURE_2D, texture);
2377         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2378         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2379         glUniform1i(glGetUniformLocation(program, "tex"), 0);
2380 
2381         drawQuad(program, "position", 0.5f, 1.0f, true);
2382         ASSERT_GL_NO_ERROR();
2383 
2384         GLuint pixel[4] = {0};
2385         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixel);
2386         ASSERT_GL_NO_ERROR();
2387         EXPECT_NEAR(std::get<0>(expectedColor), pixel[0], 1);
2388         EXPECT_NEAR(std::get<1>(expectedColor), pixel[1], 1);
2389         EXPECT_NEAR(std::get<2>(expectedColor), pixel[2], 1);
2390         EXPECT_NEAR(std::get<3>(expectedColor), pixel[3], 1);
2391     };
2392 
2393     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
2394                                             GLenum sourceType, const GLColor &sourceColor,
2395                                             GLenum destInternalFormat, GLenum destType, bool flipY,
2396                                             bool premultiplyAlpha, bool unmultiplyAlpha,
2397                                             const GLColor32U &expectedColor) {
2398         GLTexture sourceTexture;
2399         glBindTexture(GL_TEXTURE_2D, sourceTexture);
2400         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2401                      &sourceColor);
2402 
2403         GLTexture destTexture;
2404         glBindTexture(GL_TEXTURE_2D, destTexture);
2405 
2406         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2407                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2408         ASSERT_GL_NO_ERROR();
2409 
2410         testOutput(destTexture, expectedColor);
2411     };
2412 
2413     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2414                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 128));
2415     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2416                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 128));
2417     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2418                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 128));
2419 
2420     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2421                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 1));
2422     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2423                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 1));
2424     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2425                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 1));
2426 
2427     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2428                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 0, 1));
2429     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2430                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 0, 1));
2431     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2432                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 0, 1));
2433 
2434     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2435                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 0, 0, 1));
2436     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2437                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 0, 0, 1));
2438     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(120, 64, 32, 128), GL_R8UI,
2439                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(240, 0, 0, 1));
2440 }
2441 
2442 // Test that using an offset in CopySubTexture works correctly for non-renderable float targets
TEST_P(CopyTextureTestES3,CopySubTextureOffsetNonRenderableFloat)2443 TEST_P(CopyTextureTestES3, CopySubTextureOffsetNonRenderableFloat)
2444 {
2445     if (!checkExtensions())
2446     {
2447         return;
2448     }
2449 
2450     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
2451 
2452     auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
2453         constexpr char kVS[] =
2454             "#version 300 es\n"
2455             "in vec4 position;\n"
2456             "out vec2 texcoord;\n"
2457             "void main()\n"
2458             "{\n"
2459             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2460             "    texcoord = (position.xy * 0.5) + 0.5;\n"
2461             "}\n";
2462 
2463         constexpr char kFS[] =
2464             "#version 300 es\n"
2465             "precision mediump float;\n"
2466             "uniform sampler2D tex;\n"
2467             "in vec2 texcoord;\n"
2468             "out vec4 color;\n"
2469             "void main()\n"
2470             "{\n"
2471             "    color = texture(tex, texcoord);\n"
2472             "}\n";
2473 
2474         ANGLE_GL_PROGRAM(program, kVS, kFS);
2475         glUseProgram(program);
2476 
2477         GLRenderbuffer rbo;
2478         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2479         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
2480 
2481         GLFramebuffer fbo;
2482         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2483         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2484 
2485         glActiveTexture(GL_TEXTURE0);
2486         glBindTexture(GL_TEXTURE_2D, texture);
2487         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2488         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2489         glUniform1i(glGetUniformLocation(program, "tex"), 0);
2490 
2491         drawQuad(program, "position", 0.5f, 1.0f, true);
2492 
2493         EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
2494     };
2495 
2496     auto testCopy = [this, testOutput](GLenum destInternalFormat, GLenum destFormat,
2497                                        GLenum destType) {
2498         GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
2499         glBindTexture(GL_TEXTURE_2D, mTextures[0]);
2500         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
2501 
2502         GLTexture destTexture;
2503         glBindTexture(GL_TEXTURE_2D, destTexture);
2504         glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
2505 
2506         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
2507                                  false, false, false);
2508         EXPECT_GL_NO_ERROR();
2509         testOutput(destTexture, kFloatRed);
2510 
2511         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 0, 1, 1,
2512                                  false, false, false);
2513         EXPECT_GL_NO_ERROR();
2514         testOutput(destTexture, kFloatGreen);
2515 
2516         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 1, 1, 1,
2517                                  false, false, false);
2518         EXPECT_GL_NO_ERROR();
2519         testOutput(destTexture, kFloatBlue);
2520 
2521         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 1, 1, 1,
2522                                  false, false, false);
2523         EXPECT_GL_NO_ERROR();
2524         testOutput(destTexture, kFloatBlack);
2525     };
2526 
2527     testCopy(GL_RGB9_E5, GL_RGB, GL_FLOAT);
2528 }
2529 
2530 // Test that copying from one mip to another works
TEST_P(CopyTextureTestES3,CopyBetweenMips)2531 TEST_P(CopyTextureTestES3, CopyBetweenMips)
2532 {
2533     if (!checkExtensions())
2534     {
2535         return;
2536     }
2537 
2538     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2539 
2540     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
2541     glUseProgram(program);
2542     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
2543     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
2544     ASSERT_NE(-1, textureLoc);
2545     ASSERT_NE(-1, lodLoc);
2546     glUniform1i(textureLoc, 0);
2547     glUniform1f(lodLoc, 0);
2548 
2549     GLTexture texture;
2550 
2551     // Create a texture with 3 mips.  Mip0 will contain an image as follows:
2552     //
2553     //     G G B G
2554     //     G R R G
2555     //     G R R G
2556     //     G G G G
2557     //
2558     // The 2x2 red square and 1x1 blue square will be copied to the other mips.
2559     const GLColor kMip0InitColor[4 * 4] = {
2560         GLColor::green, GLColor::green, GLColor::blue,  GLColor::green,
2561         GLColor::green, GLColor::red,   GLColor::red,   GLColor::green,
2562         GLColor::green, GLColor::red,   GLColor::red,   GLColor::green,
2563         GLColor::green, GLColor::green, GLColor::green, GLColor::green,
2564     };
2565     const GLColor kMipOtherInitColor[4] = {
2566         GLColor::black,
2567         GLColor::black,
2568         GLColor::black,
2569         GLColor::black,
2570     };
2571 
2572     glActiveTexture(GL_TEXTURE0);
2573     glBindTexture(GL_TEXTURE_2D, texture);
2574     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMip0InitColor);
2575     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMipOtherInitColor);
2576     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMipOtherInitColor);
2577     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
2578     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2579     ASSERT_GL_NO_ERROR();
2580 
2581     // Commit texture
2582     glUniform1f(lodLoc, 0);
2583     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2584     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip0InitColor[0]);
2585 
2586     glUniform1f(lodLoc, 1);
2587     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2588     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipOtherInitColor[0]);
2589 
2590     glUniform1f(lodLoc, 2);
2591     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2592     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipOtherInitColor[0]);
2593 
2594     ASSERT_GL_NO_ERROR();
2595 
2596     // Copy from mip 0 to mip 1.  The level is not redefined, so a direct copy can potentially be
2597     // done.
2598     glCopySubTextureCHROMIUM(texture, 0, GL_TEXTURE_2D, texture, 1, 0, 0, 1, 1, 2, 2, false, false,
2599                              false);
2600     EXPECT_GL_NO_ERROR();
2601 
2602     // Copy from mip 0 to mip 2.  Again, the level is not redefined.
2603     glCopySubTextureCHROMIUM(texture, 0, GL_TEXTURE_2D, texture, 2, 0, 0, 2, 0, 1, 1, false, false,
2604                              false);
2605     EXPECT_GL_NO_ERROR();
2606 
2607     // Verify mips 1 and 2.
2608     int w = getWindowWidth() - 1;
2609     int h = getWindowHeight() - 1;
2610 
2611     glUniform1f(lodLoc, 1);
2612     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2613     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip0InitColor[4 * 1 + 1]);
2614     EXPECT_PIXEL_COLOR_EQ(w, 0, kMip0InitColor[4 * 1 + 2]);
2615     EXPECT_PIXEL_COLOR_EQ(0, h, kMip0InitColor[4 * 2 + 1]);
2616     EXPECT_PIXEL_COLOR_EQ(w, h, kMip0InitColor[4 * 2 + 2]);
2617 
2618     glUniform1f(lodLoc, 2);
2619     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2620     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip0InitColor[4 * 0 + 2]);
2621     EXPECT_PIXEL_COLOR_EQ(w, 0, kMip0InitColor[4 * 0 + 2]);
2622     EXPECT_PIXEL_COLOR_EQ(0, h, kMip0InitColor[4 * 0 + 2]);
2623     EXPECT_PIXEL_COLOR_EQ(w, h, kMip0InitColor[4 * 0 + 2]);
2624 }
2625 
2626 // Test that swizzle on source texture does not affect the copy.
TEST_P(CopyTextureTestES3,SwizzleOnSource)2627 TEST_P(CopyTextureTestES3, SwizzleOnSource)
2628 {
2629     const GLColor kSourceColor = GLColor(31, 73, 146, 228);
2630 
2631     // Create image with swizzle.  If swizzle is mistakenly applied, resulting color would be
2632     // kSourceColor.gbar
2633     GLTexture sourceTexture;
2634     glBindTexture(GL_TEXTURE_2D, sourceTexture);
2635     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kSourceColor);
2636     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
2637     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
2638     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ALPHA);
2639     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
2640 
2641     GLTexture destTexture;
2642     glBindTexture(GL_TEXTURE_2D, destTexture);
2643 
2644     // Note: flipY is used to avoid direct transfer between textures and force a draw-based path.
2645     glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, GL_RGBA8,
2646                           GL_UNSIGNED_BYTE, true, false, false);
2647     ASSERT_GL_NO_ERROR();
2648 
2649     // Verify the copy.
2650     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
2651     glUseProgram(program);
2652 
2653     glActiveTexture(GL_TEXTURE0);
2654     glBindTexture(GL_TEXTURE_2D, destTexture);
2655     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2656     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2657 
2658     GLint textureLocation = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
2659     ASSERT_NE(-1, textureLocation);
2660     glUniform1i(textureLocation, 0);
2661 
2662     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2663 
2664     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2665     ASSERT_GL_NO_ERROR();
2666 
2667     EXPECT_PIXEL_COLOR_EQ(0, 0, kSourceColor);
2668 }
2669 
2670 // Test that the right error type is triggered when
2671 // OES_EGL_image_external_essl3 is required but not supported
TEST_P(CopyTextureTestES3,CopySubTextureMissingRequiredExtension)2672 TEST_P(CopyTextureTestES3, CopySubTextureMissingRequiredExtension)
2673 {
2674     if (!checkExtensions())
2675     {
2676         return;
2677     }
2678 
2679     // decide if the test is relevant
2680     // If GL_OES_EGL_image_external_essl3 is supported, then no need to test
2681     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_OES_EGL_image_external_essl3"));
2682     // GL_OES_EGL_image_external extension is required to use TEXTURE_EXTERNAL_OES
2683     // as the texture target.  So if GL_OES_EGL_image_external is not supported,
2684     // the error case cannot happen.
2685     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
2686     EGLWindow *window = getEGLWindow();
2687     EGLDisplay dpy    = window->getDisplay();
2688     // If EGL_KHR_image_base is not supported, then eglImageKHR cannot be used,
2689     // and therefore the error case cannot happen
2690     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_image_base"));
2691 
2692     // prepare test data
2693     // create the texture data
2694     GLTexture texture;
2695     glBindTexture(GL_TEXTURE_2D, texture);
2696     EXPECT_GL_NO_ERROR();
2697     const std::vector<GLColor> kSourceColor(2 * 2, GLColor::green);
2698     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2699                  kSourceColor.data());
2700     EXPECT_GL_NO_ERROR();
2701 
2702     // create the image and load the texture data
2703     constexpr EGLint attribs[] = {
2704         EGL_IMAGE_PRESERVED,
2705         EGL_TRUE,
2706         EGL_NONE,
2707     };
2708     EGLImageKHR image = eglCreateImageKHR(
2709         window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
2710         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), attribs);
2711     EXPECT_GL_NO_ERROR();
2712     // source is from the image
2713     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextures[0]);
2714     EXPECT_GL_NO_ERROR();
2715     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
2716     EXPECT_GL_NO_ERROR();
2717 
2718     // dest
2719     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
2720     EXPECT_GL_NO_ERROR();
2721     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 3, 3, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
2722     EXPECT_GL_NO_ERROR();
2723 
2724     // This copying needs EGLImageExternalEssl3OES extension
2725     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
2726                              false, false, false);
2727     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
2728 
2729     // Non-integer dest internal format doesn't need the extension
2730     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
2731     EXPECT_GL_NO_ERROR();
2732     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2733     EXPECT_GL_NO_ERROR();
2734 
2735     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
2736                              false, false, false);
2737     EXPECT_GL_NO_ERROR();
2738 }
2739 
2740 // Test copying from gles texture to EGLImage
TEST_P(CopyTextureTestES3,CopyImageSubDataToEGLImage)2741 TEST_P(CopyTextureTestES3, CopyImageSubDataToEGLImage)
2742 {
2743     // GL_OES_EGL_image_external extension is required to use TEXTURE_EXTERNAL_OES
2744     // as the texture target.  So if GL_OES_EGL_image_external is not supported,
2745     // the error case cannot happen.
2746     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
2747     // GL_EXT_copy_image extension is required to use glCopyImageSubDataEXT to
2748     // copy from/to GL_TEXTURE_EXTERNAL_OES texture target. If  GL_EXT_copy_image
2749     // is not supported, then no need to test.
2750     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
2751 
2752     EGLWindow *window = getEGLWindow();
2753     EGLDisplay dpy    = window->getDisplay();
2754     // If EGL_KHR_image_base is not supported, then eglImageKHR cannot be used,
2755     // and therefore the error case cannot happen
2756     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_image_base"));
2757 
2758     // Prepare test data
2759     GLTexture texture;
2760     glBindTexture(GL_TEXTURE_2D, texture);
2761     EXPECT_GL_NO_ERROR();
2762     const std::vector<GLColor> kDstColor(4 * 4, GLColor::red);
2763     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, kDstColor.data());
2764     EXPECT_GL_NO_ERROR();
2765 
2766     // Create the egl image and bind it to target GL_TEXTURE_EXTERNAL_OES
2767     constexpr EGLint attribs[] = {
2768         EGL_IMAGE_PRESERVED,
2769         EGL_TRUE,
2770         EGL_NONE,
2771     };
2772     EGLImageKHR image = eglCreateImageKHR(
2773         window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
2774         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), attribs);
2775     EXPECT_GL_NO_ERROR();
2776 
2777     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextures[0]);
2778     EXPECT_GL_NO_ERROR();
2779     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
2780     EXPECT_GL_NO_ERROR();
2781 
2782     // Prepare the source texture data
2783     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
2784     EXPECT_GL_NO_ERROR();
2785     const std::vector<GLColor> kSourceColor(4 * 4, GLColor::green);
2786     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2787                  kSourceColor.data());
2788     EXPECT_GL_NO_ERROR();
2789 
2790     // Copy from gles texture to EGLImage.
2791     // This copying needs EGLImageExternalEssl3OES and GL_EXT_copy_image extension
2792     glCopyImageSubDataEXT(mTextures[1], GL_TEXTURE_2D, 0, 0, 0, 0, mTextures[0],
2793                           GL_TEXTURE_EXTERNAL_OES, 0, 0, 0, 0, 4, 4, 1);
2794     EXPECT_GL_NO_ERROR();
2795 
2796     // Check the results
2797     glBindTexture(GL_TEXTURE_2D, texture);
2798     GLFramebuffer framebuffer;
2799     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2800     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2801     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2802 
2803     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
2804 }
2805 
2806 // Test copying from EGLImage to gles texture
TEST_P(CopyTextureTestES3,CopyImageSubDataFromEGLImage)2807 TEST_P(CopyTextureTestES3, CopyImageSubDataFromEGLImage)
2808 {
2809     // GL_OES_EGL_image_external extension is required to use TEXTURE_EXTERNAL_OES
2810     // as the texture target.  So if GL_OES_EGL_image_external is not supported,
2811     // the error case cannot happen.
2812     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
2813     // GL_EXT_copy_image extension is required to use glCopyImageSubDataEXT to
2814     // copy from/to GL_TEXTURE_EXTERNAL_OES texture target. If  GL_EXT_copy_image
2815     // is not supported, then no need to test.
2816     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
2817 
2818     // Prepare test data
2819     GLTexture texture;
2820     glBindTexture(GL_TEXTURE_2D, texture);
2821     EXPECT_GL_NO_ERROR();
2822     const std::vector<GLColor> kSourceColor(4 * 4, GLColor::green);
2823     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2824                  kSourceColor.data());
2825     EXPECT_GL_NO_ERROR();
2826 
2827     EGLWindow *window = getEGLWindow();
2828     EGLDisplay dpy    = window->getDisplay();
2829     // If EGL_KHR_image_base is not supported, then eglImageKHR cannot be used,
2830     // and therefore the error case cannot happen
2831     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_image_base"));
2832 
2833     // Create the egl image and bind it to target GL_TEXTURE_EXTERNAL_OES
2834     constexpr EGLint attribs[] = {
2835         EGL_IMAGE_PRESERVED,
2836         EGL_TRUE,
2837         EGL_NONE,
2838     };
2839     EGLImageKHR image = eglCreateImageKHR(
2840         window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
2841         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), attribs);
2842     EXPECT_GL_NO_ERROR();
2843     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextures[0]);
2844     EXPECT_GL_NO_ERROR();
2845     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
2846     EXPECT_GL_NO_ERROR();
2847 
2848     // Prepare the destination texture
2849     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
2850     EXPECT_GL_NO_ERROR();
2851     const std::vector<GLColor> kDstColor(4 * 4, GLColor::red);
2852     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, kDstColor.data());
2853     EXPECT_GL_NO_ERROR();
2854 
2855     // Copy from egl texture to gles texture.
2856     glCopyImageSubDataEXT(mTextures[0], GL_TEXTURE_EXTERNAL_OES, 0, 0, 0, 0, mTextures[1],
2857                           GL_TEXTURE_2D, 0, 0, 0, 0, 4, 4, 1);
2858     EXPECT_GL_NO_ERROR();
2859 
2860     // Check the results.
2861     EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::green);
2862 }
2863 
2864 // Test that copy after invalidate works
TEST_P(CopyTextureTestES3,InvalidateCopyThenBlend)2865 TEST_P(CopyTextureTestES3, InvalidateCopyThenBlend)
2866 {
2867     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2868 
2869     // http://anglebug.com/42263716
2870     ANGLE_SKIP_TEST_IF(IsMac() && IsIntel() && IsOpenGL());
2871 
2872     // http://anglebug.com/42263717
2873     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsOpenGL());
2874 
2875     constexpr GLsizei kSize = 4;
2876 
2877     GLTexture texture;
2878     glBindTexture(GL_TEXTURE_2D, texture);
2879     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2880                  nullptr);
2881     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2882                  nullptr);
2883     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2884     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, kSize / 2, kSize / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2885                  nullptr);
2886     glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, kSize / 4, kSize / 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2887                  nullptr);
2888     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2889     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
2890 
2891     GLFramebuffer framebuffer;
2892     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2893     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
2894     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2895 
2896     // Invalidate the framebuffer.
2897     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
2898     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
2899     ASSERT_GL_NO_ERROR();
2900 
2901     // Copy into the framebuffer attachment.
2902     const std::vector<GLColor> kSourceColor(kSize * kSize, GLColor::green);
2903     GLTexture sourceTexture;
2904     glBindTexture(GL_TEXTURE_2D, sourceTexture);
2905     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2906                  kSourceColor.data());
2907     // Note: flipY is used to avoid direct transfer between textures and force a draw-based path.
2908     glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, texture, 2, GL_RGBA8, GL_UNSIGNED_BYTE,
2909                           true, false, false);
2910     ASSERT_GL_NO_ERROR();
2911 
2912     // Draw and blend, making sure both the copy and draw happen correctly.
2913     glEnable(GL_BLEND);
2914     glBlendFunc(GL_ONE, GL_ONE);
2915     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
2916     ASSERT_GL_NO_ERROR();
2917 
2918     // Make sure the blend was correctly done.
2919     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
2920     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::yellow);
2921     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::yellow);
2922     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow);
2923 }
2924 
2925 // Test that sRGB-to-RGB copy does not change pixel values.
2926 // http://anglebug.com/40096868
TEST_P(CopyTextureTest,NoConvertSRGBToRGB)2927 TEST_P(CopyTextureTest, NoConvertSRGBToRGB)
2928 {
2929     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB"));
2930     testSrgbToRgb(GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT);
2931 }
2932 
2933 // Test that sRGB-to-RGB copy does not change pixel values.
2934 // http://anglebug.com/40096868
TEST_P(CopyTextureTestES3,NoConvertSRGBToRGB)2935 TEST_P(CopyTextureTestES3, NoConvertSRGBToRGB)
2936 {
2937     testSrgbToRgb(GL_SRGB8_ALPHA8, GL_RGBA);
2938 }
2939 
invalidateBlitThenBlendCommon(GLsizei layerCount)2940 void CopyTextureTestES3::invalidateBlitThenBlendCommon(GLsizei layerCount)
2941 {
2942     // http://anglebug.com/42263713
2943     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL());
2944 
2945     // http://anglebug.com/42263716
2946     ANGLE_SKIP_TEST_IF(IsMac() && IsIntel() && IsOpenGL());
2947 
2948     // http://anglebug.com/42263717
2949     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsOpenGL());
2950 
2951     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2952 
2953     constexpr GLsizei kSize = 4;
2954 
2955     GLTexture texture;
2956     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
2957     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kSize * 2, kSize * 2, layerCount, 0, GL_RGBA,
2958                  GL_UNSIGNED_BYTE, nullptr);
2959     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kSize * 2, kSize * 2, layerCount, 0, GL_RGBA,
2960                  GL_UNSIGNED_BYTE, nullptr);
2961     glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, kSize, kSize, layerCount, 0, GL_RGBA,
2962                  GL_UNSIGNED_BYTE, nullptr);
2963     glTexImage3D(GL_TEXTURE_2D_ARRAY, 3, GL_RGBA8, kSize / 2, kSize / 2, layerCount, 0, GL_RGBA,
2964                  GL_UNSIGNED_BYTE, nullptr);
2965     glTexImage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RGBA8, kSize / 4, kSize / 4, layerCount, 0, GL_RGBA,
2966                  GL_UNSIGNED_BYTE, nullptr);
2967     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2968     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 4);
2969 
2970     GLFramebuffer framebuffer;
2971     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2972     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 2, layerCount / 2);
2973     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2974 
2975     // Invalidate the framebuffer.
2976     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
2977     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
2978     ASSERT_GL_NO_ERROR();
2979 
2980     // Blit into the framebuffer attachment.
2981     const std::vector<GLColor> kSourceColor(kSize * kSize, GLColor::green);
2982     GLTexture sourceTexture;
2983     glBindTexture(GL_TEXTURE_2D, sourceTexture);
2984     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2985                  kSourceColor.data());
2986     GLFramebuffer sourceFramebuffer;
2987     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebuffer);
2988     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture,
2989                            0);
2990     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2991 
2992     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2993     ASSERT_GL_NO_ERROR();
2994 
2995     // Draw and blend, making sure both the blit and draw happen correctly.
2996     glEnable(GL_BLEND);
2997     glBlendFunc(GL_ONE, GL_ONE);
2998     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
2999     ASSERT_GL_NO_ERROR();
3000 
3001     // Make sure the blend was correctly done.
3002     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
3003     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3004     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::yellow);
3005     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::yellow);
3006     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow);
3007 }
3008 
3009 // Test that blit after invalidate works with non-zero layer
TEST_P(CopyTextureTestES3,InvalidateBlitThenBlend3Layers)3010 TEST_P(CopyTextureTestES3, InvalidateBlitThenBlend3Layers)
3011 {
3012     invalidateBlitThenBlendCommon(3);
3013 }
3014 
3015 // Test that blit after invalidate works with non-zero layer that is very large
TEST_P(CopyTextureTestES3,InvalidateBlitThenBlend1000Layers)3016 TEST_P(CopyTextureTestES3, InvalidateBlitThenBlend1000Layers)
3017 {
3018     invalidateBlitThenBlendCommon(1000);
3019 }
3020 
TEST_P(CopyTextureTestES3,DrawThenCopyThenBlend)3021 TEST_P(CopyTextureTestES3, DrawThenCopyThenBlend)
3022 {
3023     // Regression test for anglebug.com/42265446.
3024     //
3025     // Reproduces two behaviors:
3026     //
3027     // 1) The initial draw disappearing entirely from the default back
3028     // buffer. The current test case does not show this behavior
3029     // independently from the other, but a previous iteration, with the
3030     // textured quad scaled to half size and translated (-0.5, -0.5), did.
3031     //
3032     // 2) With Metal debug layers and load/store validation turned on on
3033     // Intel Macs, the transparent area of the texture prior to the bug
3034     // fix was magenta = undefined. Similar behavior would presumably
3035     // reproduce on M1 hardware without debug layers or validation.
3036 
3037     constexpr GLsizei kSize     = 64;
3038     constexpr GLsizei kHalfSize = kSize / 2;
3039 
3040     setWindowWidth(kSize);
3041     setWindowHeight(kSize);
3042 
3043     // Define destination texture for the CopyTexSubImage2D operation.
3044     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
3045     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3046     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3047     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3048     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3049     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kHalfSize, kHalfSize);
3050 
3051     // Redefine framebuffer's texture already allocated in testSetUp.
3052     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
3053     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
3054     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
3055     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3056 
3057     GLRenderbuffer rbo;
3058     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
3059     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize, kSize);
3060 
3061     GLFramebuffer srcFBO;
3062     glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
3063     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
3064     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3065 
3066     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
3067     ANGLE_GL_PROGRAM(drawTexture, essl3_shaders::vs::Texture2DLod(),
3068                      essl3_shaders::fs::Texture2DLod());
3069 
3070     glDisable(GL_BLEND);
3071 
3072     // Draw a square half the size of the viewport, centered in the viewport.
3073     glViewport(0, 0, kSize, kSize);
3074     glClearColor(0, 0, 0, 0);
3075     glClear(GL_COLOR_BUFFER_BIT);
3076     glUseProgram(drawGreen);
3077     drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f, 0.5f, true);
3078     ASSERT_GL_NO_ERROR();
3079 
3080     // Resolve the multisampled framebuffer.
3081     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
3082     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
3083     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3084     ASSERT_GL_NO_ERROR();
3085 
3086     // Copy the upper right quarter of the framebuffer to mTextures[0].
3087     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
3088     glActiveTexture(GL_TEXTURE0);
3089     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
3090     ASSERT_GL_NO_ERROR();
3091     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kHalfSize, kHalfSize, kHalfSize, kHalfSize);
3092     ASSERT_GL_NO_ERROR();
3093 
3094     glUseProgram(drawTexture);
3095     GLint textureLoc = glGetUniformLocation(drawTexture, essl3_shaders::Texture2DUniform());
3096     GLint lodLoc     = glGetUniformLocation(drawTexture, essl3_shaders::LodUniform());
3097     ASSERT_NE(-1, textureLoc);
3098     ASSERT_NE(-1, lodLoc);
3099     glUniform1i(textureLoc, 0);  // to match GL_TEXTURE0
3100     glUniform1f(lodLoc, 0);
3101 
3102     // Magnify and blend this texture over the current framebuffer.
3103     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, srcFBO);
3104     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
3105     glEnable(GL_BLEND);
3106     drawQuad(drawTexture, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3107 
3108     // Resolve the multisampled framebuffer again.
3109     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
3110     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
3111     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3112     ASSERT_GL_NO_ERROR();
3113 
3114     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
3115 
3116     // Center quad should be rendered correctly.
3117     EXPECT_PIXEL_RECT_EQ(kHalfSize / 2 + 1, kHalfSize / 2 + 1, kHalfSize - 2, kHalfSize - 2,
3118                          GLColor::green);
3119 
3120     // Overlapping lower-left quad should be green as well.
3121     EXPECT_PIXEL_RECT_EQ(1, 1, kHalfSize - 2, kHalfSize - 2, GLColor::green);
3122 
3123     // Leftmost area above the lower-left quad should be transparent.
3124     EXPECT_PIXEL_RECT_EQ(1, kHalfSize + 1, kHalfSize / 2 - 2, kHalfSize / 2 - 2,
3125                          GLColor::transparentBlack);
3126 
3127     // Bottommost area to the right of the lower-left quad should be transparent.
3128     EXPECT_PIXEL_RECT_EQ(kHalfSize + 1, 1, kHalfSize / 2 - 2, kHalfSize / 2 - 2,
3129                          GLColor::transparentBlack);
3130 }
3131 
3132 // Test that copy multiple slices between 2D_ARRAY and 3D textures work when their texture formats
3133 // are different.
3134 // Simplified from
3135 // dEQP-GLES31.functional.copy_image.non_compressed.viewclass_128_bits.rgba32f_rgba32i.texture2d_array_to_texture3d
TEST_P(CopyTextureTestES3,TextureCopyMultipleSlicesBetween2DArrayAnd3D)3136 TEST_P(CopyTextureTestES3, TextureCopyMultipleSlicesBetween2DArrayAnd3D)
3137 {
3138     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
3139 
3140     constexpr GLColor32F kFloatYellow          = {1.0f, 1.0f, 0.0f, 1.0f};
3141     constexpr GLColor32I kIntBlue              = {0, 0, 255, 255};
3142     constexpr GLColor32I kIntGreen             = {0, 255, 0, 255};
3143     constexpr GLsizei kTexWidth                = 16;
3144     constexpr GLsizei kTexHeight               = 16;
3145     constexpr int32_t kIntEquivalentOfFloatOne = 1065353216;
3146 
3147     GLTexture tex2DArray;
3148     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3149     ASSERT_GL_NO_ERROR();
3150     glBindTexture(GL_TEXTURE_2D_ARRAY, tex2DArray);
3151     std::vector<GLColor32F> tex2DArraySlice0(kTexWidth * kTexHeight, kFloatRed);
3152     std::vector<GLColor32F> tex2DArraySlice1(kTexWidth * kTexHeight, kFloatYellow);
3153     std::vector<GLColor32F> tex2DArrayPixels(kTexWidth * kTexHeight * 2);
3154     auto pos = tex2DArrayPixels.begin();
3155     tex2DArrayPixels.insert(pos, tex2DArraySlice1.begin(), tex2DArraySlice1.end());
3156     pos = tex2DArrayPixels.begin();
3157     tex2DArrayPixels.insert(pos, tex2DArraySlice0.begin(), tex2DArraySlice0.end());
3158     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA32F, kTexWidth, kTexHeight, 2, 0, GL_RGBA, GL_FLOAT,
3159                  tex2DArrayPixels.data());
3160     ASSERT_GL_NO_ERROR();
3161     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3162     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3163     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3164     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3165     ASSERT_GL_NO_ERROR();
3166     glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
3167 
3168     GLTexture tex3D;
3169     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3170     ASSERT_GL_NO_ERROR();
3171     glBindTexture(GL_TEXTURE_3D, tex3D);
3172     std::vector<GLColor32I> tex3DSlice0(kTexWidth * kTexHeight, kIntBlue);
3173     std::vector<GLColor32I> tex3DSlice1(kTexWidth * kTexHeight, kIntGreen);
3174     std::vector<GLColor32I> tex3DPixels(kTexWidth * kTexHeight * 2);
3175     auto pos2 = tex3DPixels.begin();
3176     tex3DPixels.insert(pos2, tex3DSlice1.begin(), tex3DSlice1.end());
3177     pos2 = tex3DPixels.begin();
3178     tex3DPixels.insert(pos2, tex3DSlice0.begin(), tex3DSlice0.end());
3179     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32I, kTexWidth, kTexHeight, 2, 0, GL_RGBA_INTEGER, GL_INT,
3180                  tex3DPixels.data());
3181     ASSERT_GL_NO_ERROR();
3182     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3183     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3184     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3185     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3186     ASSERT_GL_NO_ERROR();
3187     glBindTexture(GL_TEXTURE_3D, 0);
3188 
3189     // Verify color before copy
3190     GLFramebuffer FBO;
3191     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
3192     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0);
3193     EXPECT_PIXEL_RECT32F_EQ(0, 0, kTexWidth, kTexHeight, kFloatRed);
3194 
3195     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 1);
3196     EXPECT_PIXEL_RECT32F_EQ(0, 0, kTexWidth, kTexHeight, kFloatYellow);
3197 
3198     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, 0, 0);
3199     EXPECT_PIXEL_RECT32I_EQ(0, 0, kTexWidth, kTexHeight, kIntBlue);
3200 
3201     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, 0, 1);
3202     EXPECT_PIXEL_RECT32I_EQ(0, 0, kTexWidth, kTexHeight, kIntGreen);
3203 
3204     // Copy GL_TEXTURE_2D_ARRAY to GL_TEXTURE_3D with copy size = (texWidth, texHeight/2, 2)
3205     glCopyImageSubDataEXT(tex2DArray, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, tex3D, GL_TEXTURE_3D, 0, 0,
3206                           0, 0, kTexWidth, kTexHeight / 2, 2);
3207 
3208     // Verify colors after copy
3209     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
3210     // verify tex2DArray
3211     // layer 0 should remain unchanged
3212     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0);
3213     EXPECT_PIXEL_RECT32F_EQ(0, 0, kTexWidth, kTexHeight, kFloatRed);
3214     // layer 1 should remain unchanged
3215     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 1);
3216     EXPECT_PIXEL_RECT32F_EQ(0, 0, kTexWidth, kTexHeight, kFloatYellow);
3217 
3218     // verify tex3D content
3219     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, 0, 0);
3220     // part of tex3D slice 0 should contain the copied content from tex2DArray layer 0
3221     EXPECT_PIXEL_RECT32I_EQ(0, 0, kTexWidth, kTexHeight / 2,
3222                             GLColor32I(kIntEquivalentOfFloatOne, 0, 0, kIntEquivalentOfFloatOne));
3223     // part of tex3D slice 0 should remain unchanged
3224     EXPECT_PIXEL_RECT32I_EQ(0, kTexHeight / 2, kTexWidth, kTexHeight / 2, kIntBlue);
3225     // verify slice 1
3226     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, 0, 1);
3227     // part of tex3D slice 1 should contain the copied content from tex2DArray layer 1
3228     EXPECT_PIXEL_RECT32I_EQ(0, 0, kTexWidth, kTexHeight / 2,
3229                             GLColor32I(kIntEquivalentOfFloatOne, kIntEquivalentOfFloatOne, 0,
3230                                        kIntEquivalentOfFloatOne));
3231     // part of tex3D slice 1 should remain unchanged
3232     EXPECT_PIXEL_RECT32I_EQ(0, kTexHeight / 2, kTexWidth, kTexHeight / 2, kIntGreen);
3233 }
3234 
3235 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTest);
3236 ANGLE_INSTANTIATE_TEST_COMBINE_6(CopyTextureVariationsTest,
3237                                  CopyTextureVariationsTestPrint,
3238                                  testing::ValuesIn(kCopyTextureVariationsSrcFormats),
3239                                  testing::ValuesIn(kCopyTextureVariationsDstFormats),
3240                                  testing::Bool(),  // flipY
3241                                  testing::Bool(),  // premultiplyAlpha
3242                                  testing::Bool(),  // unmultiplyAlpha
3243                                  testing::ValuesIn(kMesaYFlips),
3244                                  ES2_D3D9(),
3245                                  ES2_D3D11(),
3246                                  ES2_OPENGL(),
3247                                  ES2_OPENGLES(),
3248                                  ES2_VULKAN(),
3249                                  ES2_METAL());
3250 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTestWebGL);
3251 ANGLE_INSTANTIATE_TEST(CopyTextureTestDest,
3252                        ES2_D3D11(),
3253                        ES2_OPENGL(),
3254                        ES2_OPENGLES(),
3255                        ES2_VULKAN(),
3256                        ES2_METAL());
3257 
3258 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyTextureTestES3);
3259 ANGLE_INSTANTIATE_TEST_ES3(CopyTextureTestES3);
3260 
3261 }  // namespace angle
3262