• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
110     GLuint mTextures[2] = {
111         0,
112         0,
113     };
114     GLuint mFramebuffer = 0;
115 };
116 
117 using CopyTextureVariationsTestParams =
118     std::tuple<angle::PlatformParameters, GLenum, GLenum, bool, bool, bool>;
119 
CopyTextureVariationsTestPrint(const::testing::TestParamInfo<CopyTextureVariationsTestParams> & paramsInfo)120 std::string CopyTextureVariationsTestPrint(
121     const ::testing::TestParamInfo<CopyTextureVariationsTestParams> &paramsInfo)
122 {
123     const CopyTextureVariationsTestParams &params = paramsInfo.param;
124     std::ostringstream out;
125 
126     out << std::get<0>(params) << "__";
127 
128     switch (std::get<1>(params))
129     {
130         case GL_ALPHA:
131             out << "A";
132             break;
133         case GL_RGB:
134             out << "RGB";
135             break;
136         case GL_RGBA:
137             out << "RGBA";
138             break;
139         case GL_LUMINANCE:
140             out << "L";
141             break;
142         case GL_LUMINANCE_ALPHA:
143             out << "LA";
144             break;
145         case GL_BGRA_EXT:
146             out << "BGRA";
147             break;
148         case GL_SRGB_ALPHA_EXT:
149             out << "SRGBA";
150             break;
151         default:
152             out << "UPDATE_THIS_SWITCH";
153     }
154 
155     out << "To";
156 
157     switch (std::get<2>(params))
158     {
159         case GL_RGB:
160             out << "RGB";
161             break;
162         case GL_RGBA:
163             out << "RGBA";
164             break;
165         case GL_BGRA_EXT:
166             out << "BGRA";
167             break;
168         case GL_SRGB_ALPHA_EXT:
169             out << "SRGBA";
170             break;
171         default:
172             out << "UPDATE_THIS_SWITCH";
173     }
174 
175     if (std::get<3>(params))
176     {
177         out << "FlipY";
178     }
179     if (std::get<4>(params))
180     {
181         out << "PremultiplyAlpha";
182     }
183     if (std::get<5>(params))
184     {
185         out << "UnmultiplyAlpha";
186     }
187 
188     return out.str();
189 }
190 
191 class CopyTextureVariationsTest : public ANGLETestWithParam<CopyTextureVariationsTestParams>
192 {
193   protected:
CopyTextureVariationsTest()194     CopyTextureVariationsTest()
195     {
196         setWindowWidth(256);
197         setWindowHeight(256);
198         setConfigRedBits(8);
199         setConfigGreenBits(8);
200         setConfigBlueBits(8);
201         setConfigAlphaBits(8);
202     }
203 
testSetUp()204     void testSetUp() override
205     {
206         glGenTextures(2, mTextures);
207         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
208 
209         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
210         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
211         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
212         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
213 
214         glGenFramebuffers(1, &mFramebuffer);
215         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
216         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
217                                0);
218     }
219 
testTearDown()220     void testTearDown() override
221     {
222         glDeleteTextures(2, mTextures);
223         glDeleteFramebuffers(1, &mFramebuffer);
224     }
225 
checkExtensions(GLenum sourceFormat,GLenum destFormat) const226     bool checkExtensions(GLenum sourceFormat, GLenum destFormat) const
227     {
228         if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"))
229         {
230             std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
231                       << std::endl;
232             return false;
233         }
234 
235         if ((sourceFormat == GL_BGRA_EXT || destFormat == GL_BGRA_EXT) &&
236             !IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
237         {
238             return false;
239         }
240 
241         if ((sourceFormat == GL_SRGB_ALPHA_EXT || destFormat == GL_SRGB_ALPHA_EXT) &&
242             !IsGLExtensionEnabled("GL_EXT_sRGB"))
243         {
244             return false;
245         }
246 
247         return true;
248     }
249 
calculateCopyTextureResults(GLenum sourceFormat,GLenum destFormat,bool premultiplyAlpha,bool unmultiplyAlpha,const uint8_t * sourceColor,GLColor * destColor)250     void calculateCopyTextureResults(GLenum sourceFormat,
251                                      GLenum destFormat,
252                                      bool premultiplyAlpha,
253                                      bool unmultiplyAlpha,
254                                      const uint8_t *sourceColor,
255                                      GLColor *destColor)
256     {
257         GLColor color;
258 
259         switch (sourceFormat)
260         {
261             case GL_RGB:
262                 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], 255);
263                 break;
264             case GL_RGBA:
265                 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], sourceColor[3]);
266                 break;
267             case GL_LUMINANCE:
268                 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], 255);
269                 break;
270             case GL_ALPHA:
271                 color = GLColor(0, 0, 0, sourceColor[0]);
272                 break;
273             case GL_LUMINANCE_ALPHA:
274                 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], sourceColor[1]);
275                 break;
276             case GL_BGRA_EXT:
277                 color = GLColor(sourceColor[2], sourceColor[1], sourceColor[0], sourceColor[3]);
278                 break;
279             default:
280                 EXPECT_EQ(true, false);
281         }
282 
283         if (premultiplyAlpha != unmultiplyAlpha)
284         {
285             float alpha = color.A / 255.0f;
286             if (premultiplyAlpha)
287             {
288                 color.R = static_cast<GLubyte>(static_cast<float>(color.R) * alpha);
289                 color.G = static_cast<GLubyte>(static_cast<float>(color.G) * alpha);
290                 color.B = static_cast<GLubyte>(static_cast<float>(color.B) * alpha);
291             }
292             else if (unmultiplyAlpha && color.A != 0)
293             {
294                 color.R = static_cast<GLubyte>(static_cast<float>(color.R) / alpha);
295                 color.G = static_cast<GLubyte>(static_cast<float>(color.G) / alpha);
296                 color.B = static_cast<GLubyte>(static_cast<float>(color.B) / alpha);
297             }
298         }
299 
300         switch (destFormat)
301         {
302             case GL_RGB:
303                 color.A = 255;
304                 break;
305             case GL_RGBA:
306             case GL_BGRA_EXT:
307             case GL_SRGB_ALPHA_EXT:
308                 break;
309             default:
310                 EXPECT_EQ(true, false);
311         }
312 
313         *destColor = color;
314     }
315 
getSourceColors(GLenum sourceFormat,size_t * colorCount,uint8_t * componentCount)316     const uint8_t *getSourceColors(GLenum sourceFormat, size_t *colorCount, uint8_t *componentCount)
317     {
318         // Note: in all the following values, alpha is larger than RGB so unmultiply alpha doesn't
319         // overflow
320         constexpr static uint8_t kRgbaColors[7 * 4] = {
321             255u, 127u, 63u,  255u,  // 0
322             31u,  127u, 63u,  127u,  // 1
323             31u,  63u,  127u, 255u,  // 2
324             15u,  127u, 31u,  127u,  // 3
325             127u, 255u, 63u,  0u,    // 4
326             31u,  63u,  127u, 0u,    // 5
327             15u,  31u,  63u,  63u,   // 6
328         };
329 
330         constexpr static uint8_t kRgbColors[7 * 3] = {
331             255u, 127u, 63u,   // 0
332             31u,  127u, 63u,   // 1
333             31u,  63u,  127u,  // 2
334             15u,  127u, 31u,   // 3
335             127u, 255u, 63u,   // 4
336             31u,  63u,  127u,  // 5
337             15u,  31u,  63u,   // 6
338         };
339 
340         constexpr static uint8_t kLumColors[7 * 1] = {
341             255u,  // 0
342             163u,  // 1
343             78u,   // 2
344             114u,  // 3
345             51u,   // 4
346             0u,    // 5
347             217u,  // 6
348         };
349 
350         constexpr static uint8_t kLumaColors[7 * 2] = {
351             255u, 255u,  // 0
352             67u,  163u,  // 1
353             78u,  231u,  // 2
354             8u,   114u,  // 3
355             51u,  199u,  // 4
356             0u,   173u,  // 5
357             34u,  217u,  // 6
358         };
359 
360         constexpr static uint8_t kAlphaColors[7 * 1] = {
361             255u,  // 0
362             67u,   // 1
363             231u,  // 2
364             8u,    // 3
365             199u,  // 4
366             173u,  // 5
367             34u,   // 6
368         };
369 
370         *colorCount = 7;
371 
372         switch (sourceFormat)
373         {
374             case GL_RGB:
375                 *componentCount = 3;
376                 return kRgbColors;
377             case GL_RGBA:
378             case GL_BGRA_EXT:
379                 *componentCount = 4;
380                 return kRgbaColors;
381             case GL_LUMINANCE:
382                 *componentCount = 1;
383                 return kLumColors;
384             case GL_ALPHA:
385                 *componentCount = 1;
386                 return kAlphaColors;
387             case GL_LUMINANCE_ALPHA:
388                 *componentCount = 2;
389                 return kLumaColors;
390             default:
391                 EXPECT_EQ(true, false);
392                 return nullptr;
393         }
394     }
395 
initializeSourceTexture(GLenum target,GLenum sourceFormat,const uint8_t * srcColors,uint8_t componentCount)396     void initializeSourceTexture(GLenum target,
397                                  GLenum sourceFormat,
398                                  const uint8_t *srcColors,
399                                  uint8_t componentCount)
400     {
401         // The texture is initialized as 2x2.  If the componentCount is 1 or 3, then the input data
402         // will have a row pitch of 2 or 6, which needs to be padded to 4 or 8 respectively.
403         uint8_t srcColorsPadded[4 * 4];
404         size_t srcRowPitch =
405             2 * componentCount + (componentCount == 1 || componentCount == 3 ? 2 : 0);
406         size_t inputRowPitch = 2 * componentCount;
407         for (size_t row = 0; row < 2; ++row)
408         {
409             memcpy(&srcColorsPadded[row * srcRowPitch], &srcColors[row * inputRowPitch],
410                    inputRowPitch);
411             memset(&srcColorsPadded[row * srcRowPitch + inputRowPitch], 0,
412                    srcRowPitch - inputRowPitch);
413         }
414 
415         glBindTexture(target, mTextures[0]);
416         glTexImage2D(target, 0, sourceFormat, 2, 2, 0, sourceFormat, GL_UNSIGNED_BYTE,
417                      srcColorsPadded);
418     }
419 
testCopyTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha)420     void testCopyTexture(GLenum sourceTarget,
421                          GLenum sourceFormat,
422                          GLenum destFormat,
423                          bool flipY,
424                          bool premultiplyAlpha,
425                          bool unmultiplyAlpha)
426     {
427         if (!checkExtensions(sourceFormat, destFormat))
428         {
429             return;
430         }
431 
432         if (sourceFormat == GL_LUMINANCE || sourceFormat == GL_LUMINANCE_ALPHA ||
433             sourceFormat == GL_ALPHA || destFormat == GL_LUMINANCE ||
434             destFormat == GL_LUMINANCE_ALPHA || destFormat == GL_ALPHA)
435         {
436             // Old drivers buggy with optimized ImageCopy shader given LUMA textures.
437             // http://anglebug.com/4721
438             ANGLE_SKIP_TEST_IF(IsLinux() && IsNVIDIA() && IsVulkan());
439 
440             // http://anglebug.com/4939
441             ANGLE_SKIP_TEST_IF(IsOpenGL() && destFormat == GL_SRGB_ALPHA_EXT);
442         }
443 
444         size_t colorCount;
445         uint8_t componentCount;
446         const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
447 
448         std::vector<GLColor> destColors(colorCount);
449         for (size_t i = 0; i < colorCount; ++i)
450         {
451             calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
452                                         &srcColors[i * componentCount], &destColors[i]);
453         }
454 
455         for (size_t i = 0; i < colorCount - 3; ++i)
456         {
457             initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
458                                     componentCount);
459 
460             glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
461                                   GL_UNSIGNED_BYTE, flipY, premultiplyAlpha, unmultiplyAlpha);
462 
463             EXPECT_GL_NO_ERROR();
464 
465             // Check that FB is complete.
466             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
467 
468             if (flipY)
469             {
470                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
471                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
472                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
473                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
474             }
475             else
476             {
477                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
478                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
479                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
480                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
481             }
482 
483             EXPECT_GL_NO_ERROR();
484         }
485     }
486 
testCopySubTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha)487     void testCopySubTexture(GLenum sourceTarget,
488                             GLenum sourceFormat,
489                             GLenum destFormat,
490                             bool flipY,
491                             bool premultiplyAlpha,
492                             bool unmultiplyAlpha)
493     {
494         if (!checkExtensions(sourceFormat, destFormat))
495         {
496             return;
497         }
498 
499         if (sourceFormat == GL_LUMINANCE || sourceFormat == GL_LUMINANCE_ALPHA ||
500             sourceFormat == GL_ALPHA || destFormat == GL_LUMINANCE ||
501             destFormat == GL_LUMINANCE_ALPHA || destFormat == GL_ALPHA)
502         {
503             // Old drivers buggy with optimized ImageCopy shader given LUMA textures.
504             // http://anglebug.com/4721
505             ANGLE_SKIP_TEST_IF(IsLinux() && IsNVIDIA() && IsVulkan());
506 
507             // http://anglebug.com/4939
508             ANGLE_SKIP_TEST_IF(IsOpenGL() && destFormat == GL_SRGB_ALPHA_EXT);
509         }
510 
511         size_t colorCount;
512         uint8_t componentCount;
513         const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
514 
515         std::vector<GLColor> destColors(colorCount);
516         for (size_t i = 0; i < colorCount; ++i)
517         {
518             calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
519                                         &srcColors[i * componentCount], &destColors[i]);
520         }
521 
522         for (size_t i = 0; i < colorCount - 3; ++i)
523         {
524             initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
525                                     componentCount);
526 
527             glBindTexture(GL_TEXTURE_2D, mTextures[1]);
528             glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 2, 2, 0, destFormat, GL_UNSIGNED_BYTE,
529                          nullptr);
530 
531             glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 2,
532                                      2, flipY, premultiplyAlpha, unmultiplyAlpha);
533 
534             EXPECT_GL_NO_ERROR();
535 
536             if (sourceFormat != GL_LUMINANCE && sourceFormat != GL_LUMINANCE_ALPHA &&
537                 sourceFormat != GL_ALPHA)
538             {
539                 // Check that FB is complete.
540                 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
541             }
542 
543             if (flipY)
544             {
545                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
546                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
547                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
548                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
549             }
550             else
551             {
552                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
553                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
554                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
555                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
556             }
557 
558             EXPECT_GL_NO_ERROR();
559         }
560     }
561 
562     GLuint mTextures[2] = {
563         0,
564         0,
565     };
566     GLuint mFramebuffer = 0;
567 };
568 
569 class CopyTextureTestDest : public CopyTextureTest
570 {};
571 
572 class CopyTextureTestWebGL : public CopyTextureTest
573 {
574   protected:
CopyTextureTestWebGL()575     CopyTextureTestWebGL() : CopyTextureTest() { setWebGLCompatibilityEnabled(true); }
576 };
577 
578 class CopyTextureTestES3 : public CopyTextureTest
579 {
580   protected:
581     void invalidateBlitThenBlendCommon(GLsizei layerCount);
582 };
583 
584 // Test that CopyTexture cannot redefine an immutable texture and CopySubTexture can copy data to
585 // immutable textures
TEST_P(CopyTextureTest,ImmutableTexture)586 TEST_P(CopyTextureTest, ImmutableTexture)
587 {
588     if (!checkExtensions())
589     {
590         return;
591     }
592 
593     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
594                        (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
595                         !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
596 
597     GLColor pixels = GLColor::red;
598 
599     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
600     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
601     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
602 
603     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
604     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
605     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
606     EXPECT_GL_NO_ERROR();
607 
608     // Should generate an error when the texture is redefined
609     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
610                           GL_UNSIGNED_BYTE, false, false, false);
611     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
612 
613     // Should succeed when using CopySubTexture
614     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1, 1,
615                              false, false, false);
616     EXPECT_GL_NO_ERROR();
617 
618     // Check that FB is complete.
619     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
620 
621     EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
622 
623     EXPECT_GL_NO_ERROR();
624 }
625 
626 // Test validation of internal formats in CopyTexture and CopySubTexture
TEST_P(CopyTextureTest,InternalFormat)627 TEST_P(CopyTextureTest, InternalFormat)
628 {
629     if (!checkExtensions())
630     {
631         return;
632     }
633 
634     std::vector<GLint> sourceFormats;
635     sourceFormats.push_back(GL_ALPHA);
636     sourceFormats.push_back(GL_RGB);
637     sourceFormats.push_back(GL_RGBA);
638     sourceFormats.push_back(GL_LUMINANCE);
639     sourceFormats.push_back(GL_LUMINANCE_ALPHA);
640 
641     std::vector<GLint> destFormats;
642     destFormats.push_back(GL_RGB);
643     destFormats.push_back(GL_RGBA);
644 
645     if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
646     {
647         sourceFormats.push_back(GL_BGRA_EXT);
648         destFormats.push_back(GL_BGRA_EXT);
649     }
650 
651     // Test with glCopyTexture
652     for (GLint sourceFormat : sourceFormats)
653     {
654         for (GLint destFormat : destFormats)
655         {
656             glBindTexture(GL_TEXTURE_2D, mTextures[0]);
657             glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
658                          nullptr);
659             EXPECT_GL_NO_ERROR();
660 
661             glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
662                                   GL_UNSIGNED_BYTE, false, false, false);
663 
664             EXPECT_GL_NO_ERROR();
665         }
666     }
667 
668     // Test with glCopySubTexture
669     for (GLint sourceFormat : sourceFormats)
670     {
671         for (GLint destFormat : destFormats)
672         {
673             glBindTexture(GL_TEXTURE_2D, mTextures[0]);
674             glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
675                          nullptr);
676             EXPECT_GL_NO_ERROR();
677 
678             glBindTexture(GL_TEXTURE_2D, mTextures[1]);
679             glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 1, 1, 0, destFormat, GL_UNSIGNED_BYTE,
680                          nullptr);
681             EXPECT_GL_NO_ERROR();
682 
683             glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1,
684                                      1, false, false, false);
685 
686             EXPECT_GL_NO_ERROR();
687         }
688     }
689 }
690 
691 // Test to ensure that the destination texture is redefined if the properties are different.
TEST_P(CopyTextureTest,RedefineDestinationTexture)692 TEST_P(CopyTextureTest, RedefineDestinationTexture)
693 {
694     ANGLE_SKIP_TEST_IF(!checkExtensions());
695     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
696 
697     GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
698 
699     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
700     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
701 
702     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
703     glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
704     EXPECT_GL_NO_ERROR();
705 
706     // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
707     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
708     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
709     // GL_INVALID_VALUE due to bad dimensions.
710     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
711     EXPECT_GL_ERROR(GL_INVALID_VALUE);
712 
713     // If the dest texture has different properties, glCopyTextureCHROMIUM()
714     // redefines them.
715     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
716                           GL_UNSIGNED_BYTE, false, false, false);
717     EXPECT_GL_NO_ERROR();
718 
719     // glTexSubImage2D() succeeds because mTextures[1] is redefined into 2x2
720     // dimension and GL_RGBA format.
721     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
722     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
723     EXPECT_GL_NO_ERROR();
724 
725     // Check that FB is complete.
726     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
727 
728     EXPECT_PIXEL_COLOR_EQ(1, 1, pixels[3]);
729     EXPECT_GL_NO_ERROR();
730 }
731 
732 // Test that invalid dimensions in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureDimension)733 TEST_P(CopyTextureTest, CopySubTextureDimension)
734 {
735     if (!checkExtensions())
736     {
737         return;
738     }
739 
740     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
741     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
742 
743     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
744     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
745 
746     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
747                              false, false, false);
748     EXPECT_GL_NO_ERROR();
749 
750     // xoffset < 0
751     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, -1, 1, 0, 0, 1, 1,
752                              false, false, false);
753     EXPECT_GL_ERROR(GL_INVALID_VALUE);
754 
755     // x < 0
756     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, -1, 0, 1, 1,
757                              false, false, false);
758     EXPECT_GL_ERROR(GL_INVALID_VALUE);
759 
760     // xoffset + width > dest_width
761     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 2, 2, 0, 0, 2, 2,
762                              false, false, false);
763     EXPECT_GL_ERROR(GL_INVALID_VALUE);
764 
765     // x + width > source_width
766     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 1, 1, 2, 2,
767                              false, false, false);
768     EXPECT_GL_ERROR(GL_INVALID_VALUE);
769 }
770 
771 // Test that invalid IDs in CopyTexture are validated
TEST_P(CopyTextureTest,CopyTextureInvalidTextureIds)772 TEST_P(CopyTextureTest, CopyTextureInvalidTextureIds)
773 {
774     if (!checkExtensions())
775     {
776         return;
777     }
778 
779     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
780     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
781 
782     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
783     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
784 
785     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, GL_RGBA, GL_UNSIGNED_BYTE,
786                           false, false, false);
787     EXPECT_GL_ERROR(GL_INVALID_VALUE);
788 
789     glCopyTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA, GL_UNSIGNED_BYTE,
790                           false, false, false);
791     EXPECT_GL_ERROR(GL_INVALID_VALUE);
792 
793     glCopyTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, GL_RGBA, GL_UNSIGNED_BYTE, false,
794                           false, false);
795     EXPECT_GL_ERROR(GL_INVALID_VALUE);
796 
797     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
798                           GL_UNSIGNED_BYTE, false, false, false);
799     EXPECT_GL_NO_ERROR();
800 }
801 
802 // Test that invalid IDs in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureInvalidTextureIds)803 TEST_P(CopyTextureTest, CopySubTextureInvalidTextureIds)
804 {
805     if (!checkExtensions())
806     {
807         return;
808     }
809 
810     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
811     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
812 
813     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
814     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
815 
816     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, 1, 1, 0, 0, 1, 1, false,
817                              false, false);
818     EXPECT_GL_ERROR(GL_INVALID_VALUE);
819 
820     glCopySubTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1, false,
821                              false, false);
822     EXPECT_GL_ERROR(GL_INVALID_VALUE);
823 
824     glCopySubTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, 1, 1, 0, 0, 1, 1, false, false,
825                              false);
826     EXPECT_GL_ERROR(GL_INVALID_VALUE);
827 
828     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
829                              false, false, false);
830     EXPECT_GL_NO_ERROR();
831 }
832 
TEST_P(CopyTextureTest,InvalidTarget)833 TEST_P(CopyTextureTest, InvalidTarget)
834 {
835     ANGLE_SKIP_TEST_IF(!checkExtensions());
836 
837     GLTexture textures[2];
838 
839     glBindTexture(GL_TEXTURE_2D, textures[0]);
840     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
841 
842     glBindTexture(GL_TEXTURE_2D, textures[1]);
843     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
844 
845     // Invalid enum for a completely invalid target
846     glCopySubTextureCHROMIUM(textures[0], 0, GL_INVALID_VALUE, textures[1], 0, 1, 1, 0, 0, 1, 1,
847                              false, false, false);
848     EXPECT_GL_ERROR(GL_INVALID_ENUM);
849 
850     // Invalid value for a valid target enum but is not valid for the destination texture
851     glCopySubTextureCHROMIUM(textures[0], 0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textures[1], 0, 1, 1,
852                              0, 0, 1, 1, false, false, false);
853     EXPECT_GL_ERROR(GL_INVALID_VALUE);
854 }
855 
856 // Test that using an offset in CopySubTexture works correctly
TEST_P(CopyTextureTest,CopySubTextureOffset)857 TEST_P(CopyTextureTest, CopySubTextureOffset)
858 {
859     if (!checkExtensions())
860     {
861         return;
862     }
863 
864     GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
865     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
866     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
867 
868     GLColor transparentPixels[4 * 4] = {GLColor::transparentBlack, GLColor::transparentBlack,
869                                         GLColor::transparentBlack, GLColor::transparentBlack};
870     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
871     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, transparentPixels);
872 
873     // Check that FB is complete.
874     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
875 
876     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
877                              false, false, false);
878     EXPECT_GL_NO_ERROR();
879     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
880 
881     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 0, 1, 0, 1, 1,
882                              false, false, false);
883     EXPECT_GL_NO_ERROR();
884     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
885 
886     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 1, 0, 1, 1, 1,
887                              false, false, false);
888     EXPECT_GL_NO_ERROR();
889     EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue);
890 
891     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
892     EXPECT_GL_NO_ERROR();
893 }
894 
895 // Test every combination of copy [sub]texture parameters:
896 // source: ALPHA, RGB, RGBA, LUMINANCE, LUMINANCE_ALPHA, BGRA_EXT
897 // destination: RGB, RGBA, BGRA_EXT
898 // flipY: false, true
899 // premultiplyAlpha: false, true
900 // unmultiplyAlpha: false, true
901 namespace
902 {
903 constexpr GLenum kCopyTextureVariationsSrcFormats[] = {
904     GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
905 constexpr GLenum kCopyTextureVariationsDstFormats[] = {GL_RGB, GL_RGBA, GL_BGRA_EXT,
906                                                        GL_SRGB_ALPHA_EXT};
907 }  // anonymous namespace
908 
TEST_P(CopyTextureVariationsTest,CopyTexture)909 TEST_P(CopyTextureVariationsTest, CopyTexture)
910 {
911     // http://anglebug.com/5723
912     ANGLE_SKIP_TEST_IF(IsOzone());
913     // http://anglebug.com/5246
914     if (std::get<1>(GetParam()) == GL_ALPHA && std::get<2>(GetParam()) == GL_RGB &&
915         std::get<3>(GetParam()) && std::get<5>(GetParam()))
916     {
917         ANGLE_SKIP_TEST_IF(IsWindows7() && IsNVIDIA() && IsOpenGLES());
918     }
919 
920     testCopyTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
921                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
922 }
923 
TEST_P(CopyTextureVariationsTest,CopySubTexture)924 TEST_P(CopyTextureVariationsTest, CopySubTexture)
925 {
926     // http://anglebug.com/5723
927     ANGLE_SKIP_TEST_IF(IsOzone());
928     testCopySubTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
929                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
930 }
931 
TEST_P(CopyTextureVariationsTest,CopyTextureRectangle)932 TEST_P(CopyTextureVariationsTest, CopyTextureRectangle)
933 {
934     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
935 
936     testCopyTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
937                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
938 }
939 
TEST_P(CopyTextureVariationsTest,CopySubTextureRectangle)940 TEST_P(CopyTextureVariationsTest, CopySubTextureRectangle)
941 {
942     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
943 
944     testCopySubTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
945                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
946 }
947 
948 // Test that copying to cube maps works
TEST_P(CopyTextureTest,CubeMapTarget)949 TEST_P(CopyTextureTest, CubeMapTarget)
950 {
951     if (!checkExtensions())
952     {
953         return;
954     }
955 
956     // http://anglebug.com/1932
957     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
958 
959     // http://anglebug.com/3145
960     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
961 
962     GLColor pixels[7] = {
963         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
964         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
965         GLColor(70u, 73u, 76u, 79u),
966     };
967 
968     GLTexture textures[2];
969 
970     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
971     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
972          face++)
973     {
974         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
975     }
976 
977     for (size_t i = 0; i < 2; ++i)
978     {
979         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
980              face++)
981         {
982             glBindTexture(GL_TEXTURE_2D, textures[0]);
983             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
984                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
985 
986             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
987                                      false, false);
988         }
989 
990         EXPECT_GL_NO_ERROR();
991 
992         GLFramebuffer fbo;
993         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
994 
995         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
996              face++)
997         {
998             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
999 
1000             // Check that FB is complete.
1001             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1002 
1003             EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1004 
1005             EXPECT_GL_NO_ERROR();
1006         }
1007     }
1008 }
1009 
1010 // Test that we can successfully copy into incomplete cube maps. Regression test for
1011 // http://anglebug.com/3384
TEST_P(CopyTextureTest,IncompleteCubeMap)1012 TEST_P(CopyTextureTest, IncompleteCubeMap)
1013 {
1014     if (!checkExtensions())
1015     {
1016         return;
1017     }
1018 
1019     GLTexture texture2D;
1020     GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
1021     glBindTexture(GL_TEXTURE_2D, texture2D);
1022     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
1023 
1024     GLTexture textureCube;
1025     glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
1026     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1027          face++)
1028     {
1029         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1030     }
1031 
1032     // Set one face to 2x2
1033     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1034                  rgbaPixels);
1035 
1036     // Copy into the incomplete face
1037     glCopySubTextureCHROMIUM(texture2D, 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, textureCube, 0, 0, 0, 0,
1038                              0, 2, 2, false, false, false);
1039     EXPECT_GL_NO_ERROR();
1040 }
1041 
1042 // Test BGRA to RGBA cube map copy
TEST_P(CopyTextureTest,CubeMapTargetBGRA)1043 TEST_P(CopyTextureTest, CubeMapTargetBGRA)
1044 {
1045     if (!checkExtensions())
1046     {
1047         return;
1048     }
1049 
1050     if (!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1051     {
1052         return;
1053     }
1054 
1055     // http://anglebug.com/3145
1056     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1057 
1058     GLColor pixels[7] = {
1059         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
1060         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
1061         GLColor(70u, 73u, 76u, 79u),
1062     };
1063 
1064     GLTexture textures[2];
1065 
1066     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1067     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1068          face++)
1069     {
1070         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1071     }
1072 
1073     for (size_t i = 0; i < 2; ++i)
1074     {
1075         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1076              face++)
1077         {
1078             glBindTexture(GL_TEXTURE_2D, textures[0]);
1079             glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1080                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1081 
1082             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
1083                                      false, false);
1084         }
1085 
1086         EXPECT_GL_NO_ERROR();
1087 
1088         GLFramebuffer fbo;
1089         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1090 
1091         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1092              face++)
1093         {
1094             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1095 
1096             // Check that FB is complete.
1097             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1098 
1099             GLColor converted = pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i];
1100             std::swap(converted.R, converted.B);
1101             EXPECT_PIXEL_COLOR_EQ(0, 0, converted);
1102 
1103             EXPECT_GL_NO_ERROR();
1104         }
1105     }
1106 }
1107 
1108 // Test cube map copies with RGB format
TEST_P(CopyTextureTest,CubeMapTargetRGB)1109 TEST_P(CopyTextureTest, CubeMapTargetRGB)
1110 {
1111     if (!checkExtensions())
1112     {
1113         return;
1114     }
1115 
1116     // http://anglebug.com/1932
1117     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
1118 
1119     // http://anglebug.com/3145
1120     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1121 
1122     constexpr uint8_t pixels[16 * 7] = {
1123         0u,   3u,   6u,   10u,  13u,  16u,  0, 0, 20u,  23u,  26u,  30u,  33u,  36u,  0, 0,  // 2x2
1124         40u,  43u,  46u,  50u,  53u,  56u,  0, 0, 60u,  63u,  66u,  70u,  73u,  76u,  0, 0,  // 2x2
1125         80u,  83u,  86u,  90u,  93u,  96u,  0, 0, 100u, 103u, 106u, 110u, 113u, 116u, 0, 0,  // 2x2
1126         120u, 123u, 126u, 130u, 133u, 136u, 0, 0, 140u, 143u, 146u, 160u, 163u, 166u, 0, 0,  // 2x2
1127         170u, 173u, 176u, 180u, 183u, 186u, 0, 0, 190u, 193u, 196u, 200u, 203u, 206u, 0, 0,  // 2x2
1128         210u, 213u, 216u, 220u, 223u, 226u, 0, 0, 230u, 233u, 236u, 240u, 243u, 246u, 0, 0,  // 2x2
1129         10u,  50u,  100u, 30u,  80u,  130u, 0, 0, 60u,  110u, 160u, 90u,  140u, 200u, 0, 0,  // 2x2
1130     };
1131 
1132     GLTexture textures[2];
1133 
1134     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1135     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1136          face++)
1137     {
1138         glTexImage2D(face, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1139     }
1140 
1141     for (size_t i = 0; i < 2; ++i)
1142     {
1143         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1144              face++)
1145         {
1146             glBindTexture(GL_TEXTURE_2D, textures[0]);
1147             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
1148                          &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16]);
1149 
1150             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 2, 2, false,
1151                                      false, false);
1152         }
1153 
1154         EXPECT_GL_NO_ERROR();
1155 
1156         GLFramebuffer fbo;
1157         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1158 
1159         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1160              face++)
1161         {
1162             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1163 
1164             // Check that FB is complete.
1165             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1166 
1167             const uint8_t *faceData = &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16];
1168             EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(faceData[0], faceData[1], faceData[2], 255));
1169             EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor(faceData[3], faceData[4], faceData[5], 255));
1170             EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor(faceData[8], faceData[9], faceData[10], 255));
1171             EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor(faceData[11], faceData[12], faceData[13], 255));
1172 
1173             EXPECT_GL_NO_ERROR();
1174         }
1175     }
1176 }
1177 
1178 // Test that copying to non-zero mipmaps works
TEST_P(CopyTextureTest,CopyToMipmap)1179 TEST_P(CopyTextureTest, CopyToMipmap)
1180 {
1181     if (!checkExtensions())
1182     {
1183         return;
1184     }
1185 
1186     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1187                        !IsGLExtensionEnabled("GL_OES_fbo_render_mipmap"));
1188 
1189     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel());
1190 
1191     GLColor pixels[] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
1192 
1193     GLTexture textures[2];
1194 
1195     glBindTexture(GL_TEXTURE_2D, textures[0]);
1196     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1197     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1198 
1199     glBindTexture(GL_TEXTURE_2D, textures[1]);
1200     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1201     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1202     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1203 
1204     std::vector<std::pair<GLint, GLint>> soureDestPairs;
1205     soureDestPairs.push_back(std::make_pair(0, 1));
1206 
1207     // ES3 allows copying from non-zero mips
1208     if (getClientMajorVersion() >= 3)
1209     {
1210         soureDestPairs.push_back(std::make_pair(1, 2));
1211     }
1212 
1213     for (const auto &sourceDestPair : soureDestPairs)
1214     {
1215         const GLint sourceLevel = sourceDestPair.first;
1216         const GLint destLevel   = sourceDestPair.second;
1217 
1218         glCopyTextureCHROMIUM(textures[0], sourceLevel, GL_TEXTURE_2D, textures[1], destLevel,
1219                               GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1220 
1221         EXPECT_GL_NO_ERROR();
1222 
1223         GLFramebuffer fbo;
1224         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1225         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
1226                                destLevel);
1227 
1228         // Check that FB is complete.
1229         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1230 
1231         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[0]);
1232 
1233         EXPECT_GL_NO_ERROR();
1234     }
1235 }
1236 
1237 // Test that copying outside the mipmap range works
TEST_P(CopyTextureTest,CopyOutsideMipmap)1238 TEST_P(CopyTextureTest, CopyOutsideMipmap)
1239 {
1240     if (!checkExtensions())
1241     {
1242         return;
1243     }
1244 
1245     // http://anglebug.com/4716
1246     ANGLE_SKIP_TEST_IF(IsD3D());
1247 
1248     // Failing on older drivers.  http://anglebug.com/4718
1249     ANGLE_SKIP_TEST_IF(IsLinux() && IsNVIDIA() && IsOpenGL());
1250 
1251     // http://anglebug.com/5246
1252     ANGLE_SKIP_TEST_IF(IsWindows7() && IsNVIDIA() && IsOpenGLES());
1253 
1254     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1255 
1256     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
1257     glUseProgram(program);
1258     GLint textureLoc = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
1259     ASSERT_NE(-1, textureLoc);
1260     glUniform1i(textureLoc, 0);
1261 
1262     GLTexture textures[2];
1263 
1264     // Create two single-mip textures.
1265     glActiveTexture(GL_TEXTURE0);
1266     glBindTexture(GL_TEXTURE_2D, textures[0]);
1267     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
1268     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1269     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1270 
1271     glBindTexture(GL_TEXTURE_2D, textures[1]);
1272     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
1273     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1274     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1275 
1276     // Commit texture 0
1277     glBindTexture(GL_TEXTURE_2D, textures[0]);
1278     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
1279     ASSERT_GL_NO_ERROR();
1280     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1281 
1282     // Copy texture 1 into mip 1 of texture 0.  This mip is outside the range of the image allocated
1283     // for texture 0.
1284     glCopyTextureCHROMIUM(textures[1], 0, GL_TEXTURE_2D, textures[0], 1, GL_RGBA, GL_UNSIGNED_BYTE,
1285                           false, false, false);
1286     EXPECT_GL_NO_ERROR();
1287 
1288     // Draw with texture 0 again
1289     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
1290     ASSERT_GL_NO_ERROR();
1291     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1292 }
1293 
1294 // Test that copying from an RGBA8 texture to RGBA4 results in exactly 4-bit precision in the result
TEST_P(CopyTextureTest,DownsampleRGBA4444)1295 TEST_P(CopyTextureTest, DownsampleRGBA4444)
1296 {
1297     // Downsampling on copy is only guarenteed on D3D11
1298     ANGLE_SKIP_TEST_IF(!IsD3D11());
1299 
1300     GLTexture textures[2];
1301 
1302     GLColor pixels[] = {GLColor(0, 5, 6, 7), GLColor(17, 22, 25, 24), GLColor(34, 35, 36, 36),
1303                         GLColor(51, 53, 55, 55)};
1304 
1305     glBindTexture(GL_TEXTURE_2D, textures[0]);
1306     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1307 
1308     glBindTexture(GL_TEXTURE_2D, textures[1]);
1309     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1310                           GL_UNSIGNED_SHORT_4_4_4_4, GL_FALSE, GL_FALSE, GL_FALSE);
1311 
1312     GLFramebuffer fbo;
1313     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1314     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1315 
1316     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1317     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(17, 17, 17, 17), 1.0);
1318     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(34, 34, 34, 34), 1.0);
1319     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(51, 51, 51, 51), 1.0);
1320 
1321     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, {16, 16, 16, 16});
1322 }
1323 
1324 // Test that copying from an RGBA8 texture to RGB565 results in exactly 4-bit precision in the
1325 // result
TEST_P(CopyTextureTest,DownsampleRGB565)1326 TEST_P(CopyTextureTest, DownsampleRGB565)
1327 {
1328     // Downsampling on copy is only guarenteed on D3D11
1329     ANGLE_SKIP_TEST_IF(!IsD3D11());
1330 
1331     GLTexture textures[2];
1332 
1333     GLColor pixels[] = {GLColor(0, 5, 2, 14), GLColor(17, 22, 25, 30), GLColor(34, 33, 36, 46),
1334                         GLColor(50, 54, 49, 60)};
1335 
1336     glBindTexture(GL_TEXTURE_2D, textures[0]);
1337     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1338 
1339     glBindTexture(GL_TEXTURE_2D, textures[1]);
1340     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGB,
1341                           GL_UNSIGNED_SHORT_5_6_5, GL_FALSE, GL_FALSE, GL_FALSE);
1342 
1343     GLFramebuffer fbo;
1344     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1345     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1346 
1347     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 4, 0, 255), 1.0);
1348     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 20, 25, 255), 1.0);
1349     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 32, 33, 255), 1.0);
1350     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 53, 49, 255), 1.0);
1351 
1352     testGradientDownsampleUniqueValues(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, {32, 64, 32, 1});
1353 }
1354 
1355 // Test that copying from an RGBA8 texture to RGBA5551 results in exactly 4-bit precision in the
1356 // result
TEST_P(CopyTextureTest,DownsampleRGBA5551)1357 TEST_P(CopyTextureTest, DownsampleRGBA5551)
1358 {
1359     // Downsampling on copy is only guarenteed on D3D11
1360     ANGLE_SKIP_TEST_IF(!IsD3D11());
1361 
1362     GLTexture textures[2];
1363 
1364     GLColor pixels[] = {GLColor(0, 1, 2, 3), GLColor(14, 16, 17, 18), GLColor(33, 34, 36, 46),
1365                         GLColor(50, 51, 52, 255)};
1366 
1367     glBindTexture(GL_TEXTURE_2D, textures[0]);
1368     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1369 
1370     glBindTexture(GL_TEXTURE_2D, textures[1]);
1371     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1372                           GL_UNSIGNED_SHORT_5_5_5_1, GL_FALSE, GL_FALSE, GL_FALSE);
1373 
1374     GLFramebuffer fbo;
1375     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1376     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1377 
1378     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1379     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 16, 16, 0), 1.0);
1380     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 33, 33, 0), 1.0);
1381     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 49, 49, 255), 1.0);
1382 
1383     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, {32, 32, 32, 2});
1384 }
1385 
1386 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination
TEST_P(CopyTextureTestDest,Luminance)1387 TEST_P(CopyTextureTestDest, Luminance)
1388 {
1389     if (!checkExtensions())
1390     {
1391         return;
1392     }
1393 
1394     GLColor originalPixels(50u, 100u, 150u, 200u);
1395     GLColor expectedPixels(50u, 50u, 50u, 255u);
1396 
1397     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1398     // texture to verify contents.
1399     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1400     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1401     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1402     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1403 
1404     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1405                           GL_UNSIGNED_BYTE, false, false, false);
1406 
1407     EXPECT_GL_NO_ERROR();
1408 
1409     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1410                           GL_UNSIGNED_BYTE, false, false, false);
1411 
1412     EXPECT_GL_NO_ERROR();
1413 
1414     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1415 }
1416 
1417 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1418 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceMultiply)1419 TEST_P(CopyTextureTestDest, LuminanceMultiply)
1420 {
1421     if (!checkExtensions())
1422     {
1423         return;
1424     }
1425 
1426     GLColor originalPixels(50u, 100u, 150u, 200u);
1427     GLColor expectedPixels(39u, 39u, 39u, 255u);
1428 
1429     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1430     // texture to verify contents.
1431     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1432     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1433     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1434     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1435 
1436     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1437                           GL_UNSIGNED_BYTE, false, true, false);
1438 
1439     EXPECT_GL_NO_ERROR();
1440 
1441     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1442                           GL_UNSIGNED_BYTE, false, false, false);
1443 
1444     EXPECT_GL_NO_ERROR();
1445 
1446     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1447 }
1448 
1449 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1450 // UnpackUnmultiply parameter
TEST_P(CopyTextureTestDest,LuminanceUnmultiply)1451 TEST_P(CopyTextureTestDest, LuminanceUnmultiply)
1452 {
1453     if (!checkExtensions())
1454     {
1455         return;
1456     }
1457 
1458     GLColor originalPixels(50u, 100u, 150u, 200u);
1459     GLColor expectedPixels(64u, 64u, 64u, 255u);
1460 
1461     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1462     // texture to verify contents.
1463     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1464     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1465     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1466     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1467 
1468     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1469                           GL_UNSIGNED_BYTE, false, false, true);
1470 
1471     EXPECT_GL_NO_ERROR();
1472 
1473     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1474                           GL_UNSIGNED_BYTE, false, false, false);
1475 
1476     EXPECT_GL_NO_ERROR();
1477 
1478     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1479 }
1480 
1481 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination
TEST_P(CopyTextureTestDest,LuminanceAlpha)1482 TEST_P(CopyTextureTestDest, LuminanceAlpha)
1483 {
1484     if (!checkExtensions())
1485     {
1486         return;
1487     }
1488 
1489     GLColor originalPixels(50u, 100u, 150u, 200u);
1490     GLColor expectedPixels(50u, 50u, 50u, 200u);
1491 
1492     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1493     // RGBA texture to verify contents.
1494     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1495     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1496     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1497     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1498                  GL_UNSIGNED_BYTE, nullptr);
1499 
1500     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1501                           GL_UNSIGNED_BYTE, false, false, false);
1502 
1503     EXPECT_GL_NO_ERROR();
1504 
1505     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1506                           GL_UNSIGNED_BYTE, false, false, false);
1507 
1508     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1509 }
1510 
1511 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1512 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaMultiply)1513 TEST_P(CopyTextureTestDest, LuminanceAlphaMultiply)
1514 {
1515     if (!checkExtensions())
1516     {
1517         return;
1518     }
1519 
1520     GLColor originalPixels(50u, 100u, 150u, 200u);
1521     GLColor expectedPixels(39u, 39u, 39u, 200u);
1522 
1523     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1524     // RGBA texture to verify contents.
1525     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1526     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1527     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1528     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1529                  GL_UNSIGNED_BYTE, nullptr);
1530 
1531     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1532                           GL_UNSIGNED_BYTE, false, true, false);
1533 
1534     EXPECT_GL_NO_ERROR();
1535 
1536     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1537                           GL_UNSIGNED_BYTE, false, false, false);
1538 
1539     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1540 }
1541 
1542 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1543 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaUnmultiply)1544 TEST_P(CopyTextureTestDest, LuminanceAlphaUnmultiply)
1545 {
1546     if (!checkExtensions())
1547     {
1548         return;
1549     }
1550 
1551     GLColor originalPixels(50u, 100u, 150u, 200u);
1552     GLColor expectedPixels(64u, 64u, 64u, 200u);
1553 
1554     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1555     // RGBA texture to verify contents.
1556     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1557     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1558     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1559     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1560                  GL_UNSIGNED_BYTE, nullptr);
1561 
1562     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1563                           GL_UNSIGNED_BYTE, false, false, true);
1564 
1565     EXPECT_GL_NO_ERROR();
1566 
1567     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1568                           GL_UNSIGNED_BYTE, false, false, false);
1569 
1570     EXPECT_GL_NO_ERROR();
1571 
1572     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1573 }
1574 
1575 // Test to ensure that CopyTexture works with ALPHA texture as a destination
TEST_P(CopyTextureTestDest,Alpha)1576 TEST_P(CopyTextureTestDest, Alpha)
1577 {
1578     if (!checkExtensions())
1579     {
1580         return;
1581     }
1582 
1583     GLColor originalPixels(50u, 100u, 150u, 155u);
1584     GLColor expectedPixels(0u, 0u, 0u, 155u);
1585 
1586     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1587     // texture to verify contents.
1588     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1589     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1590     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1591     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1592 
1593     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1594                           GL_UNSIGNED_BYTE, false, false, false);
1595 
1596     EXPECT_GL_NO_ERROR();
1597 
1598     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1599                           GL_UNSIGNED_BYTE, false, false, false);
1600 
1601     EXPECT_GL_NO_ERROR();
1602 
1603     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1604 }
1605 
1606 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1607 // UnpackPremultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaMultiply)1608 TEST_P(CopyTextureTestDest, AlphaMultiply)
1609 {
1610     if (!checkExtensions())
1611     {
1612         return;
1613     }
1614 
1615     GLColor originalPixels(50u, 100u, 150u, 155u);
1616     GLColor expectedPixels(0u, 0u, 0u, 155u);
1617 
1618     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1619     // texture to verify contents.
1620     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1621     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1622     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1623     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1624 
1625     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1626                           GL_UNSIGNED_BYTE, false, true, false);
1627 
1628     EXPECT_GL_NO_ERROR();
1629 
1630     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1631                           GL_UNSIGNED_BYTE, false, false, false);
1632 
1633     EXPECT_GL_NO_ERROR();
1634 
1635     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1636 }
1637 
1638 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1639 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaUnmultiply)1640 TEST_P(CopyTextureTestDest, AlphaUnmultiply)
1641 {
1642     if (!checkExtensions())
1643     {
1644         return;
1645     }
1646 
1647     GLColor originalPixels(50u, 100u, 150u, 155u);
1648     GLColor expectedPixels(0u, 0u, 0u, 155u);
1649 
1650     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1651     // texture to verify contents.
1652     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1653     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1654     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1655     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1656 
1657     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1658                           GL_UNSIGNED_BYTE, false, false, true);
1659 
1660     EXPECT_GL_NO_ERROR();
1661 
1662     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1663                           GL_UNSIGNED_BYTE, false, false, false);
1664 
1665     EXPECT_GL_NO_ERROR();
1666 
1667     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1668 }
1669 
1670 // Test to ensure that CopyTexture uses the correct ALPHA passthrough shader to ensure RGB channels
1671 // are set to 0.
TEST_P(CopyTextureTestDest,AlphaCopyWithRGB)1672 TEST_P(CopyTextureTestDest, AlphaCopyWithRGB)
1673 {
1674     // http://anglebug.com/4121
1675     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
1676     ANGLE_SKIP_TEST_IF(!checkExtensions());
1677     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
1678 
1679     GLColor originalPixels(50u, 100u, 150u, 155u);
1680     GLColor expectedPixels(0u, 0u, 0u, 155u);
1681 
1682     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1683     // texture to verify contents.
1684     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1685     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1686     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1687     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_HALF_FLOAT_OES, nullptr);
1688 
1689     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1690                           GL_HALF_FLOAT_OES, false, false, false);
1691 
1692     EXPECT_GL_NO_ERROR();
1693 
1694     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1695                           GL_UNSIGNED_BYTE, false, false, false);
1696 
1697     EXPECT_GL_NO_ERROR();
1698 
1699     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1700 }
1701 
1702 // Bug where TEXTURE_SWIZZLE_RGBA was not reset after the Luminance workaround. (crbug.com/1022080)
TEST_P(CopyTextureTestES3,LuminanceWorkaroundTextureSwizzleBug)1703 TEST_P(CopyTextureTestES3, LuminanceWorkaroundTextureSwizzleBug)
1704 {
1705     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB"));
1706 
1707     {
1708         GLColor pixels(50u, 20u, 100u, 150u);
1709 
1710         // Hit BlitGL::copySubImageToLUMAWorkaroundTexture by copying an ALPHA texture
1711         GLTexture srcTexture;
1712         glBindTexture(GL_TEXTURE_2D, srcTexture);
1713         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
1714 
1715         GLFramebuffer srcFBO;
1716         glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
1717         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
1718 
1719         GLTexture dstTexture;
1720         glBindTexture(GL_TEXTURE_2D, dstTexture);
1721         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1722 
1723         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
1724         EXPECT_GL_NO_ERROR();
1725     }
1726 
1727     {
1728         // This time hit BlitGL::blitColorBufferWithShader by copying an SRGB texture
1729         GLColor pixels(100u, 200u, 50u, 210u);
1730 
1731         GLTexture srcTexture;
1732         glBindTexture(GL_TEXTURE_2D, srcTexture);
1733         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1734                      GL_UNSIGNED_BYTE, &pixels);
1735 
1736         GLFramebuffer srcFBO;
1737         glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
1738         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture,
1739                                0);
1740 
1741         GLTexture dstTexture;
1742         glBindTexture(GL_TEXTURE_2D, dstTexture);
1743         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1744                      GL_UNSIGNED_BYTE, nullptr);
1745 
1746         GLFramebuffer dstFBO;
1747         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
1748         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture,
1749                                0);
1750 
1751         glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1752 
1753         // The previous workaround should not affect this copy
1754         glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
1755         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
1756     }
1757 }
1758 
1759 // Test to ensure that CopyTexture will fail with a non-zero level and NPOT texture in WebGL
TEST_P(CopyTextureTestWebGL,NPOT)1760 TEST_P(CopyTextureTestWebGL, NPOT)
1761 {
1762     if (IsGLExtensionRequestable("GL_CHROMIUM_copy_texture"))
1763     {
1764         glRequestExtensionANGLE("GL_CHROMIUM_copy_texture");
1765     }
1766     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
1767 
1768     std::vector<GLColor> pixelData(10 * 10, GLColor::red);
1769 
1770     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1771     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
1772 
1773     // Do a basic copy to make sure things work
1774     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1775                           GL_UNSIGNED_BYTE, false, false, false);
1776 
1777     EXPECT_GL_NO_ERROR();
1778 
1779     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1780 
1781     // Do the same operation with destLevel 1, which should fail
1782     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 1, GL_RGBA,
1783                           GL_UNSIGNED_BYTE, false, false, false);
1784 
1785     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1786 }
1787 
1788 // Test the newly added ES3 unorm formats
TEST_P(CopyTextureTestES3,ES3UnormFormats)1789 TEST_P(CopyTextureTestES3, ES3UnormFormats)
1790 {
1791     if (!checkExtensions())
1792     {
1793         return;
1794     }
1795     // http://anglebug.com/4092
1796     ANGLE_SKIP_TEST_IF(IsAndroid());
1797 
1798     // http://anglebug.com/5127
1799     ANGLE_SKIP_TEST_IF(IsWindows() && IsOpenGL() && IsIntel());
1800 
1801     auto testOutput = [this](GLuint texture, const GLColor &expectedColor) {
1802         constexpr char kVS[] =
1803             "#version 300 es\n"
1804             "in vec4 position;\n"
1805             "out vec2 texcoord;\n"
1806             "void main()\n"
1807             "{\n"
1808             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1809             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1810             "}\n";
1811 
1812         constexpr char kFS[] =
1813             "#version 300 es\n"
1814             "precision mediump float;\n"
1815             "uniform sampler2D tex;\n"
1816             "in vec2 texcoord;\n"
1817             "out vec4 color;\n"
1818             "void main()\n"
1819             "{\n"
1820             "    color = texture(tex, texcoord);\n"
1821             "}\n";
1822 
1823         ANGLE_GL_PROGRAM(program, kVS, kFS);
1824         glUseProgram(program);
1825 
1826         GLRenderbuffer rbo;
1827         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1828         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
1829 
1830         GLFramebuffer fbo;
1831         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1832         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1833 
1834         glActiveTexture(GL_TEXTURE0);
1835         glBindTexture(GL_TEXTURE_2D, texture);
1836         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1837         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1838         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1839 
1840         drawQuad(program, "position", 0.5f, 1.0f, true);
1841 
1842         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
1843     };
1844 
1845     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1846                                             GLenum sourceType, const GLColor &sourceColor,
1847                                             GLenum destInternalFormat, GLenum destType, bool flipY,
1848                                             bool premultiplyAlpha, bool unmultiplyAlpha,
1849                                             const GLColor &expectedColor) {
1850         GLTexture sourceTexture;
1851         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1852         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1853                      &sourceColor);
1854 
1855         GLTexture destTexture;
1856         glBindTexture(GL_TEXTURE_2D, destTexture);
1857 
1858         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1859                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1860         ASSERT_GL_NO_ERROR();
1861 
1862         testOutput(destTexture, expectedColor);
1863     };
1864 
1865     auto testSubCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1866                                                GLenum sourceType, const GLColor &sourceColor,
1867                                                GLenum destInternalFormat, GLenum destFormat,
1868                                                GLenum destType, bool flipY, bool premultiplyAlpha,
1869                                                bool unmultiplyAlpha, const GLColor &expectedColor) {
1870         GLTexture sourceTexture;
1871         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1872         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1873                      &sourceColor);
1874 
1875         GLTexture destTexture;
1876         glBindTexture(GL_TEXTURE_2D, destTexture);
1877 
1878         glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
1879         glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
1880                                  flipY, premultiplyAlpha, unmultiplyAlpha);
1881         ASSERT_GL_NO_ERROR();
1882 
1883         testOutput(destTexture, expectedColor);
1884     };
1885 
1886     // New LUMA source formats
1887     testCopyCombination(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGB,
1888                         GL_UNSIGNED_BYTE, false, false, false, GLColor(128, 128, 128, 255));
1889     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1890                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, false,
1891                         GLColor(128, 128, 128, 255));
1892     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1893                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, true, false,
1894                         GLColor(32, 32, 32, 255));
1895     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1896                         GLColor(128, 128, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, true,
1897                         GLColor(255, 255, 255, 255));
1898     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1899                         GL_UNSIGNED_BYTE, false, false, false, GLColor(0, 0, 0, 128));
1900     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1901                         GL_UNSIGNED_BYTE, false, false, true, GLColor(0, 0, 0, 128));
1902     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1903                         GL_UNSIGNED_BYTE, false, true, false, GLColor(0, 0, 0, 128));
1904 
1905     // New sRGB dest formats
1906     if (IsGLExtensionEnabled("GL_EXT_sRGB"))
1907     {
1908         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1909                             GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
1910         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1911                             GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
1912         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1913                             GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
1914                             GLColor(55, 13, 4, 128));
1915 
1916         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1917                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, false, false,
1918                                GLColor(55, 13, 4, 255));
1919         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1920                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, true, false,
1921                                GLColor(13, 4, 1, 255));
1922         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1923                                GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
1924                                false, GLColor(55, 13, 4, 128));
1925     }
1926 }
1927 
1928 // Test the newly added ES3 float formats
TEST_P(CopyTextureTestES3,ES3FloatFormats)1929 TEST_P(CopyTextureTestES3, ES3FloatFormats)
1930 {
1931     if (!checkExtensions())
1932     {
1933         return;
1934     }
1935 
1936     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
1937 
1938     auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
1939         constexpr char kVS[] =
1940             "#version 300 es\n"
1941             "in vec4 position;\n"
1942             "out vec2 texcoord;\n"
1943             "void main()\n"
1944             "{\n"
1945             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1946             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1947             "}\n";
1948 
1949         constexpr char kFS[] =
1950             "#version 300 es\n"
1951             "precision mediump float;\n"
1952             "uniform sampler2D tex;\n"
1953             "in vec2 texcoord;\n"
1954             "out vec4 color;\n"
1955             "void main()\n"
1956             "{\n"
1957             "    color = texture(tex, texcoord);\n"
1958             "}\n";
1959 
1960         ANGLE_GL_PROGRAM(program, kVS, kFS);
1961         glUseProgram(program);
1962 
1963         GLRenderbuffer rbo;
1964         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1965         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1966 
1967         GLFramebuffer fbo;
1968         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1969         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1970 
1971         glActiveTexture(GL_TEXTURE0);
1972         glBindTexture(GL_TEXTURE_2D, texture);
1973         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1974         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1975         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1976 
1977         drawQuad(program, "position", 0.5f, 1.0f, true);
1978 
1979         EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
1980     };
1981 
1982     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1983                                             GLenum sourceType, const GLColor &sourceColor,
1984                                             GLenum destInternalFormat, GLenum destType, bool flipY,
1985                                             bool premultiplyAlpha, bool unmultiplyAlpha,
1986                                             const GLColor32F &expectedColor) {
1987         GLTexture sourceTexture;
1988         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1989         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1990                      &sourceColor);
1991 
1992         GLTexture destTexture;
1993         glBindTexture(GL_TEXTURE_2D, destTexture);
1994 
1995         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1996                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1997         ASSERT_GL_NO_ERROR();
1998 
1999         testOutput(destTexture, expectedColor);
2000     };
2001 
2002     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
2003                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 0.5f));
2004     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
2005                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 0.5f));
2006     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
2007                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 0.5f));
2008 
2009     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
2010                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.0f, 0.0f, 1.0f));
2011     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
2012                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.0f, 0.0f, 1.0f));
2013     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
2014                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.0f, 0.0f, 1.0f));
2015 
2016     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
2017                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.0f, 1.0f));
2018     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
2019                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0f, 1.0f));
2020     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
2021                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.0f, 1.0f));
2022 
2023     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
2024                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
2025     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
2026                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
2027     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
2028                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
2029 
2030     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2031                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, false,
2032                         GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
2033     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2034                         GL_R11F_G11F_B10F, GL_FLOAT, false, true, false,
2035                         GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
2036     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
2037                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, true,
2038                         GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
2039 
2040     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
2041                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
2042     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
2043                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
2044     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
2045                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
2046 }
2047 
2048 // Test the newly added ES3 unsigned integer formats
TEST_P(CopyTextureTestES3,ES3UintFormats)2049 TEST_P(CopyTextureTestES3, ES3UintFormats)
2050 {
2051     ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsIntel());
2052 
2053     if (!checkExtensions())
2054     {
2055         return;
2056     }
2057 
2058     using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
2059 
2060     auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
2061         constexpr char kVS[] =
2062             "#version 300 es\n"
2063             "in vec4 position;\n"
2064             "out vec2 texcoord;\n"
2065             "void main()\n"
2066             "{\n"
2067             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2068             "    texcoord = (position.xy * 0.5) + 0.5;\n"
2069             "}\n";
2070 
2071         constexpr char kFS[] =
2072             "#version 300 es\n"
2073             "precision mediump float;\n"
2074             "precision mediump usampler2D;\n"
2075             "in vec2 texcoord;\n"
2076             "uniform usampler2D tex;\n"
2077             "out uvec4 color;\n"
2078             "void main()\n"
2079             "{\n"
2080             "    color = texture(tex, texcoord);\n"
2081             "}\n";
2082 
2083         ANGLE_GL_PROGRAM(program, kVS, kFS);
2084         glUseProgram(program);
2085 
2086         GLRenderbuffer rbo;
2087         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2088         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8UI, 1, 1);
2089 
2090         GLFramebuffer fbo;
2091         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2092         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2093 
2094         glActiveTexture(GL_TEXTURE0);
2095         glBindTexture(GL_TEXTURE_2D, texture);
2096         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2097         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2098         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
2099 
2100         drawQuad(program, "position", 0.5f, 1.0f, true);
2101         ASSERT_GL_NO_ERROR();
2102 
2103         GLuint pixel[4] = {0};
2104         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixel);
2105         ASSERT_GL_NO_ERROR();
2106         EXPECT_NEAR(std::get<0>(expectedColor), pixel[0], 1);
2107         EXPECT_NEAR(std::get<1>(expectedColor), pixel[1], 1);
2108         EXPECT_NEAR(std::get<2>(expectedColor), pixel[2], 1);
2109         EXPECT_NEAR(std::get<3>(expectedColor), pixel[3], 1);
2110     };
2111 
2112     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
2113                                             GLenum sourceType, const GLColor &sourceColor,
2114                                             GLenum destInternalFormat, GLenum destType, bool flipY,
2115                                             bool premultiplyAlpha, bool unmultiplyAlpha,
2116                                             const GLColor32U &expectedColor) {
2117         GLTexture sourceTexture;
2118         glBindTexture(GL_TEXTURE_2D, sourceTexture);
2119         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2120                      &sourceColor);
2121 
2122         GLTexture destTexture;
2123         glBindTexture(GL_TEXTURE_2D, destTexture);
2124 
2125         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2126                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2127         ASSERT_GL_NO_ERROR();
2128 
2129         testOutput(destTexture, expectedColor);
2130     };
2131 
2132     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2133                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 128));
2134     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2135                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 128));
2136     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2137                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 128));
2138 
2139     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2140                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 1));
2141     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2142                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 1));
2143     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2144                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 1));
2145 
2146     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2147                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 0, 1));
2148     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2149                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 0, 1));
2150     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2151                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 0, 1));
2152 
2153     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2154                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 0, 0, 1));
2155     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2156                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 0, 0, 1));
2157     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(120, 64, 32, 128), GL_R8UI,
2158                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(240, 0, 0, 1));
2159 }
2160 
2161 // Test that using an offset in CopySubTexture works correctly for non-renderable float targets
TEST_P(CopyTextureTestES3,CopySubTextureOffsetNonRenderableFloat)2162 TEST_P(CopyTextureTestES3, CopySubTextureOffsetNonRenderableFloat)
2163 {
2164     if (!checkExtensions())
2165     {
2166         return;
2167     }
2168 
2169     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
2170 
2171     auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
2172         constexpr char kVS[] =
2173             "#version 300 es\n"
2174             "in vec4 position;\n"
2175             "out vec2 texcoord;\n"
2176             "void main()\n"
2177             "{\n"
2178             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2179             "    texcoord = (position.xy * 0.5) + 0.5;\n"
2180             "}\n";
2181 
2182         constexpr char kFS[] =
2183             "#version 300 es\n"
2184             "precision mediump float;\n"
2185             "uniform sampler2D tex;\n"
2186             "in vec2 texcoord;\n"
2187             "out vec4 color;\n"
2188             "void main()\n"
2189             "{\n"
2190             "    color = texture(tex, texcoord);\n"
2191             "}\n";
2192 
2193         ANGLE_GL_PROGRAM(program, kVS, kFS);
2194         glUseProgram(program);
2195 
2196         GLRenderbuffer rbo;
2197         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2198         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
2199 
2200         GLFramebuffer fbo;
2201         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2202         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2203 
2204         glActiveTexture(GL_TEXTURE0);
2205         glBindTexture(GL_TEXTURE_2D, texture);
2206         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2207         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2208         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
2209 
2210         drawQuad(program, "position", 0.5f, 1.0f, true);
2211 
2212         EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
2213     };
2214 
2215     auto testCopy = [this, testOutput](GLenum destInternalFormat, GLenum destFormat,
2216                                        GLenum destType) {
2217         GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
2218         glBindTexture(GL_TEXTURE_2D, mTextures[0]);
2219         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
2220 
2221         GLTexture destTexture;
2222         glBindTexture(GL_TEXTURE_2D, destTexture);
2223         glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
2224 
2225         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
2226                                  false, false, false);
2227         EXPECT_GL_NO_ERROR();
2228         testOutput(destTexture, kFloatRed);
2229 
2230         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 0, 1, 1,
2231                                  false, false, false);
2232         EXPECT_GL_NO_ERROR();
2233         testOutput(destTexture, kFloatGreen);
2234 
2235         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 1, 1, 1,
2236                                  false, false, false);
2237         EXPECT_GL_NO_ERROR();
2238         testOutput(destTexture, kFloatBlue);
2239 
2240         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 1, 1, 1,
2241                                  false, false, false);
2242         EXPECT_GL_NO_ERROR();
2243         testOutput(destTexture, kFloatBlack);
2244     };
2245 
2246     testCopy(GL_RGB9_E5, GL_RGB, GL_FLOAT);
2247 }
2248 
2249 // Test that copying from one mip to another works
TEST_P(CopyTextureTestES3,CopyBetweenMips)2250 TEST_P(CopyTextureTestES3, CopyBetweenMips)
2251 {
2252     if (!checkExtensions())
2253     {
2254         return;
2255     }
2256 
2257     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2258 
2259     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
2260     glUseProgram(program);
2261     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
2262     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
2263     ASSERT_NE(-1, textureLoc);
2264     ASSERT_NE(-1, lodLoc);
2265     glUniform1i(textureLoc, 0);
2266     glUniform1f(lodLoc, 0);
2267 
2268     GLTexture texture;
2269 
2270     // Create a texture with 3 mips.  Mip0 will contain an image as follows:
2271     //
2272     //     G G B G
2273     //     G R R G
2274     //     G R R G
2275     //     G G G G
2276     //
2277     // The 2x2 red square and 1x1 blue square will be copied to the other mips.
2278     const GLColor kMip0InitColor[4 * 4] = {
2279         GLColor::green, GLColor::green, GLColor::blue,  GLColor::green,
2280         GLColor::green, GLColor::red,   GLColor::red,   GLColor::green,
2281         GLColor::green, GLColor::red,   GLColor::red,   GLColor::green,
2282         GLColor::green, GLColor::green, GLColor::green, GLColor::green,
2283     };
2284     const GLColor kMipOtherInitColor[4] = {
2285         GLColor::black,
2286         GLColor::black,
2287         GLColor::black,
2288         GLColor::black,
2289     };
2290 
2291     glActiveTexture(GL_TEXTURE0);
2292     glBindTexture(GL_TEXTURE_2D, texture);
2293     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMip0InitColor);
2294     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMipOtherInitColor);
2295     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMipOtherInitColor);
2296     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
2297     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2298     ASSERT_GL_NO_ERROR();
2299 
2300     // Commit texture
2301     glUniform1f(lodLoc, 0);
2302     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2303     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip0InitColor[0]);
2304 
2305     glUniform1f(lodLoc, 1);
2306     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2307     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipOtherInitColor[0]);
2308 
2309     glUniform1f(lodLoc, 2);
2310     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2311     EXPECT_PIXEL_COLOR_EQ(0, 0, kMipOtherInitColor[0]);
2312 
2313     ASSERT_GL_NO_ERROR();
2314 
2315     // Copy from mip 0 to mip 1.  The level is not redefined, so a direct copy can potentially be
2316     // done.
2317     glCopySubTextureCHROMIUM(texture, 0, GL_TEXTURE_2D, texture, 1, 0, 0, 1, 1, 2, 2, false, false,
2318                              false);
2319     EXPECT_GL_NO_ERROR();
2320 
2321     // Copy from mip 0 to mip 2.  Again, the level is not redefined.
2322     glCopySubTextureCHROMIUM(texture, 0, GL_TEXTURE_2D, texture, 2, 0, 0, 2, 0, 1, 1, false, false,
2323                              false);
2324     EXPECT_GL_NO_ERROR();
2325 
2326     // Verify mips 1 and 2.
2327     int w = getWindowWidth() - 1;
2328     int h = getWindowHeight() - 1;
2329 
2330     glUniform1f(lodLoc, 1);
2331     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2332     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip0InitColor[4 * 1 + 1]);
2333     EXPECT_PIXEL_COLOR_EQ(w, 0, kMip0InitColor[4 * 1 + 2]);
2334     EXPECT_PIXEL_COLOR_EQ(0, h, kMip0InitColor[4 * 2 + 1]);
2335     EXPECT_PIXEL_COLOR_EQ(w, h, kMip0InitColor[4 * 2 + 2]);
2336 
2337     glUniform1f(lodLoc, 2);
2338     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
2339     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip0InitColor[4 * 0 + 2]);
2340     EXPECT_PIXEL_COLOR_EQ(w, 0, kMip0InitColor[4 * 0 + 2]);
2341     EXPECT_PIXEL_COLOR_EQ(0, h, kMip0InitColor[4 * 0 + 2]);
2342     EXPECT_PIXEL_COLOR_EQ(w, h, kMip0InitColor[4 * 0 + 2]);
2343 }
2344 
2345 // Test that swizzle on source texture does not affect the copy.
TEST_P(CopyTextureTestES3,SwizzleOnSource)2346 TEST_P(CopyTextureTestES3, SwizzleOnSource)
2347 {
2348     const GLColor kSourceColor = GLColor(31, 73, 146, 228);
2349 
2350     // Create image with swizzle.  If swizzle is mistakenly applied, resulting color would be
2351     // kSourceColor.gbar
2352     GLTexture sourceTexture;
2353     glBindTexture(GL_TEXTURE_2D, sourceTexture);
2354     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kSourceColor);
2355     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
2356     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
2357     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ALPHA);
2358     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
2359 
2360     GLTexture destTexture;
2361     glBindTexture(GL_TEXTURE_2D, destTexture);
2362 
2363     // Note: flipY is used to avoid direct transfer between textures and force a draw-based path.
2364     glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, GL_RGBA8,
2365                           GL_UNSIGNED_BYTE, true, false, false);
2366     ASSERT_GL_NO_ERROR();
2367 
2368     // Verify the copy.
2369     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
2370     glUseProgram(program);
2371 
2372     glActiveTexture(GL_TEXTURE0);
2373     glBindTexture(GL_TEXTURE_2D, destTexture);
2374     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2375     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2376 
2377     GLint textureLocation = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
2378     ASSERT_NE(-1, textureLocation);
2379     glUniform1i(textureLocation, 0);
2380 
2381     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2382 
2383     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2384     ASSERT_GL_NO_ERROR();
2385 
2386     EXPECT_PIXEL_COLOR_EQ(0, 0, kSourceColor);
2387 }
2388 
2389 // Test that copy after invalidate works
TEST_P(CopyTextureTestES3,InvalidateCopyThenBlend)2390 TEST_P(CopyTextureTestES3, InvalidateCopyThenBlend)
2391 {
2392     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2393 
2394     // http://anglebug.com/5155
2395     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsOpenGL());
2396 
2397     // http://anglebug.com/5156
2398     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsOpenGL());
2399 
2400     constexpr GLsizei kSize = 4;
2401 
2402     GLTexture texture;
2403     glBindTexture(GL_TEXTURE_2D, texture);
2404     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2405                  nullptr);
2406     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2407                  nullptr);
2408     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2409     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, kSize / 2, kSize / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2410                  nullptr);
2411     glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, kSize / 4, kSize / 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2412                  nullptr);
2413     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2414     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
2415 
2416     GLFramebuffer framebuffer;
2417     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2418     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
2419     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2420 
2421     // Invalidate the framebuffer.
2422     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
2423     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
2424     ASSERT_GL_NO_ERROR();
2425 
2426     // Copy into the framebuffer attachment.
2427     const std::vector<GLColor> kSourceColor(kSize * kSize, GLColor::green);
2428     GLTexture sourceTexture;
2429     glBindTexture(GL_TEXTURE_2D, sourceTexture);
2430     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2431                  kSourceColor.data());
2432     // Note: flipY is used to avoid direct transfer between textures and force a draw-based path.
2433     glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, texture, 2, GL_RGBA8, GL_UNSIGNED_BYTE,
2434                           true, false, false);
2435     ASSERT_GL_NO_ERROR();
2436 
2437     // Draw and blend, making sure both the copy and draw happen correctly.
2438     glEnable(GL_BLEND);
2439     glBlendFunc(GL_ONE, GL_ONE);
2440     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
2441     ASSERT_GL_NO_ERROR();
2442 
2443     // Make sure the blend was correctly done.
2444     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
2445     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::yellow);
2446     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::yellow);
2447     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow);
2448 }
2449 
invalidateBlitThenBlendCommon(GLsizei layerCount)2450 void CopyTextureTestES3::invalidateBlitThenBlendCommon(GLsizei layerCount)
2451 {
2452     // http://anglebug.com/5152
2453     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL());
2454 
2455     // http://anglebug.com/5155
2456     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsOpenGL());
2457 
2458     // http://anglebug.com/5156
2459     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsOpenGL());
2460 
2461     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2462 
2463     constexpr GLsizei kSize = 4;
2464 
2465     GLTexture texture;
2466     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
2467     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kSize * 2, kSize * 2, layerCount, 0, GL_RGBA,
2468                  GL_UNSIGNED_BYTE, nullptr);
2469     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kSize * 2, kSize * 2, layerCount, 0, GL_RGBA,
2470                  GL_UNSIGNED_BYTE, nullptr);
2471     glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, kSize, kSize, layerCount, 0, GL_RGBA,
2472                  GL_UNSIGNED_BYTE, nullptr);
2473     glTexImage3D(GL_TEXTURE_2D_ARRAY, 3, GL_RGBA8, kSize / 2, kSize / 2, layerCount, 0, GL_RGBA,
2474                  GL_UNSIGNED_BYTE, nullptr);
2475     glTexImage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RGBA8, kSize / 4, kSize / 4, layerCount, 0, GL_RGBA,
2476                  GL_UNSIGNED_BYTE, nullptr);
2477     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2478     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 4);
2479 
2480     GLFramebuffer framebuffer;
2481     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2482     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 2, layerCount / 2);
2483     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2484 
2485     // Invalidate the framebuffer.
2486     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
2487     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
2488     ASSERT_GL_NO_ERROR();
2489 
2490     // Blit into the framebuffer attachment.
2491     const std::vector<GLColor> kSourceColor(kSize * kSize, GLColor::green);
2492     GLTexture sourceTexture;
2493     glBindTexture(GL_TEXTURE_2D, sourceTexture);
2494     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2495                  kSourceColor.data());
2496     GLFramebuffer sourceFramebuffer;
2497     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebuffer);
2498     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture,
2499                            0);
2500     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2501 
2502     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2503     ASSERT_GL_NO_ERROR();
2504 
2505     // Draw and blend, making sure both the blit and draw happen correctly.
2506     glEnable(GL_BLEND);
2507     glBlendFunc(GL_ONE, GL_ONE);
2508     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
2509     ASSERT_GL_NO_ERROR();
2510 
2511     // Make sure the blend was correctly done.
2512     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2513     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
2514     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::yellow);
2515     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::yellow);
2516     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow);
2517 }
2518 
2519 // Test that blit after invalidate works with non-zero layer
TEST_P(CopyTextureTestES3,InvalidateBlitThenBlend3Layers)2520 TEST_P(CopyTextureTestES3, InvalidateBlitThenBlend3Layers)
2521 {
2522     invalidateBlitThenBlendCommon(3);
2523 }
2524 
2525 // Test that blit after invalidate works with non-zero layer that is very large
TEST_P(CopyTextureTestES3,InvalidateBlitThenBlend1000Layers)2526 TEST_P(CopyTextureTestES3, InvalidateBlitThenBlend1000Layers)
2527 {
2528     invalidateBlitThenBlendCommon(1000);
2529 }
2530 
2531 #ifdef Bool
2532 // X11 craziness.
2533 #    undef Bool
2534 #endif
2535 
2536 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTest);
2537 ANGLE_INSTANTIATE_TEST_COMBINE_5(CopyTextureVariationsTest,
2538                                  CopyTextureVariationsTestPrint,
2539                                  testing::ValuesIn(kCopyTextureVariationsSrcFormats),
2540                                  testing::ValuesIn(kCopyTextureVariationsDstFormats),
2541                                  testing::Bool(),  // flipY
2542                                  testing::Bool(),  // premultiplyAlpha
2543                                  testing::Bool(),  // unmultiplyAlpha
2544                                  ES2_D3D9(),
2545                                  ES2_D3D11(),
2546                                  ES2_OPENGL(),
2547                                  ES2_OPENGLES(),
2548                                  ES2_VULKAN(),
2549                                  ES2_METAL());
2550 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTestWebGL);
2551 ANGLE_INSTANTIATE_TEST(CopyTextureTestDest,
2552                        ES2_D3D11(),
2553                        ES2_OPENGL(),
2554                        ES2_OPENGLES(),
2555                        ES2_VULKAN(),
2556                        ES2_METAL());
2557 
2558 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyTextureTestES3);
2559 ANGLE_INSTANTIATE_TEST_ES3(CopyTextureTestES3);
2560 
2561 }  // namespace angle
2562