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