1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // CopyTextureTest.cpp: Tests of the GL_CHROMIUM_copy_texture extension
8
9 #include "test_utils/ANGLETest.h"
10
11 #include "test_utils/gl_raii.h"
12
13 namespace angle
14 {
15
16 class CopyTextureTest : public ANGLETest
17 {
18 protected:
CopyTextureTest()19 CopyTextureTest()
20 {
21 setWindowWidth(256);
22 setWindowHeight(256);
23 setConfigRedBits(8);
24 setConfigGreenBits(8);
25 setConfigBlueBits(8);
26 setConfigAlphaBits(8);
27 }
28
testSetUp()29 void testSetUp() override
30 {
31 glGenTextures(2, mTextures);
32 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
33
34 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
35 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
36 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
37 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
38
39 glGenFramebuffers(1, &mFramebuffer);
40 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
41 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
42 0);
43 }
44
testTearDown()45 void testTearDown() override
46 {
47 glDeleteTextures(2, mTextures);
48 glDeleteFramebuffers(1, &mFramebuffer);
49 }
50
checkExtensions() const51 bool checkExtensions() const
52 {
53 if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"))
54 {
55 std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
56 << std::endl;
57 return false;
58 }
59
60 EXPECT_NE(nullptr, glCopyTextureCHROMIUM);
61 EXPECT_NE(nullptr, glCopySubTextureCHROMIUM);
62 return true;
63 }
64
testGradientDownsampleUniqueValues(GLenum destFormat,GLenum destType,const std::array<size_t,4> & expectedUniqueValues)65 void testGradientDownsampleUniqueValues(GLenum destFormat,
66 GLenum destType,
67 const std::array<size_t, 4> &expectedUniqueValues)
68 {
69 std::array<GLColor, 256> sourceGradient;
70 for (size_t i = 0; i < sourceGradient.size(); i++)
71 {
72 GLubyte value = static_cast<GLubyte>(i);
73 sourceGradient[i] = GLColor(value, value, value, value);
74 }
75 GLTexture sourceTexture;
76 glBindTexture(GL_TEXTURE_2D, sourceTexture);
77 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
78 sourceGradient.data());
79
80 GLTexture destTexture;
81 glBindTexture(GL_TEXTURE_2D, destTexture);
82 glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destFormat, destType,
83 GL_FALSE, GL_FALSE, GL_FALSE);
84 EXPECT_GL_NO_ERROR();
85
86 GLFramebuffer fbo;
87 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
88 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
89
90 std::array<GLColor, 256> destData;
91 glReadPixels(0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, destData.data());
92 EXPECT_GL_NO_ERROR();
93
94 std::set<GLubyte> uniqueValues[4];
95 for (size_t i = 0; i < destData.size(); i++)
96 {
97 GLColor color = destData[i];
98 uniqueValues[0].insert(color.R);
99 uniqueValues[1].insert(color.G);
100 uniqueValues[2].insert(color.B);
101 uniqueValues[3].insert(color.A);
102 }
103
104 EXPECT_EQ(expectedUniqueValues[0], uniqueValues[0].size());
105 EXPECT_EQ(expectedUniqueValues[1], uniqueValues[1].size());
106 EXPECT_EQ(expectedUniqueValues[2], uniqueValues[2].size());
107 EXPECT_EQ(expectedUniqueValues[3], uniqueValues[3].size());
108 }
109
110 GLuint mTextures[2] = {
111 0,
112 0,
113 };
114 GLuint mFramebuffer = 0;
115 };
116
117 using CopyTextureVariationsTestParams =
118 std::tuple<angle::PlatformParameters, GLenum, GLenum, bool, bool, bool>;
119
CopyTextureVariationsTestPrint(const::testing::TestParamInfo<CopyTextureVariationsTestParams> & paramsInfo)120 std::string CopyTextureVariationsTestPrint(
121 const ::testing::TestParamInfo<CopyTextureVariationsTestParams> ¶msInfo)
122 {
123 const CopyTextureVariationsTestParams ¶ms = paramsInfo.param;
124 std::ostringstream out;
125
126 out << std::get<0>(params) << '_';
127
128 switch (std::get<1>(params))
129 {
130 case GL_ALPHA:
131 out << "A";
132 break;
133 case GL_RGB:
134 out << "RGB";
135 break;
136 case GL_RGBA:
137 out << "RGBA";
138 break;
139 case GL_LUMINANCE:
140 out << "L";
141 break;
142 case GL_LUMINANCE_ALPHA:
143 out << "LA";
144 break;
145 case GL_BGRA_EXT:
146 out << "BGRA";
147 break;
148 default:
149 out << "UPDATE_THIS_SWITCH";
150 }
151
152 out << "To";
153
154 switch (std::get<2>(params))
155 {
156 case GL_RGB:
157 out << "RGB";
158 break;
159 case GL_RGBA:
160 out << "RGBA";
161 break;
162 case GL_BGRA_EXT:
163 out << "BGRA";
164 break;
165 default:
166 out << "UPDATE_THIS_SWITCH";
167 }
168
169 if (std::get<3>(params))
170 {
171 out << "FlipY";
172 }
173 if (std::get<4>(params))
174 {
175 out << "PremultiplyAlpha";
176 }
177 if (std::get<5>(params))
178 {
179 out << "UnmultiplyAlpha";
180 }
181
182 return out.str();
183 }
184
185 class CopyTextureVariationsTest : public ANGLETestWithParam<CopyTextureVariationsTestParams>
186 {
187 protected:
CopyTextureVariationsTest()188 CopyTextureVariationsTest()
189 {
190 setWindowWidth(256);
191 setWindowHeight(256);
192 setConfigRedBits(8);
193 setConfigGreenBits(8);
194 setConfigBlueBits(8);
195 setConfigAlphaBits(8);
196 }
197
testSetUp()198 void testSetUp() override
199 {
200 glGenTextures(2, mTextures);
201 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
202
203 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
204 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
207
208 glGenFramebuffers(1, &mFramebuffer);
209 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
210 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
211 0);
212 }
213
testTearDown()214 void testTearDown() override
215 {
216 glDeleteTextures(2, mTextures);
217 glDeleteFramebuffers(1, &mFramebuffer);
218 }
219
checkExtensions(GLenum sourceFormat,GLenum destFormat) const220 bool checkExtensions(GLenum sourceFormat, GLenum destFormat) const
221 {
222 if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"))
223 {
224 std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
225 << std::endl;
226 return false;
227 }
228
229 if ((sourceFormat == GL_BGRA_EXT || destFormat == GL_BGRA_EXT) &&
230 !IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
231 {
232 return false;
233 }
234
235 return true;
236 }
237
calculateCopyTextureResults(GLenum sourceFormat,GLenum destFormat,bool premultiplyAlpha,bool unmultiplyAlpha,const uint8_t * sourceColor,GLColor * destColor)238 void calculateCopyTextureResults(GLenum sourceFormat,
239 GLenum destFormat,
240 bool premultiplyAlpha,
241 bool unmultiplyAlpha,
242 const uint8_t *sourceColor,
243 GLColor *destColor)
244 {
245 GLColor color;
246
247 switch (sourceFormat)
248 {
249 case GL_RGB:
250 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], 255);
251 break;
252 case GL_RGBA:
253 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], sourceColor[3]);
254 break;
255 case GL_LUMINANCE:
256 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], 255);
257 break;
258 case GL_ALPHA:
259 color = GLColor(0, 0, 0, sourceColor[0]);
260 break;
261 case GL_LUMINANCE_ALPHA:
262 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], sourceColor[1]);
263 break;
264 case GL_BGRA_EXT:
265 color = GLColor(sourceColor[2], sourceColor[1], sourceColor[0], sourceColor[3]);
266 break;
267 default:
268 EXPECT_EQ(true, false);
269 }
270
271 if (premultiplyAlpha != unmultiplyAlpha)
272 {
273 float alpha = color.A / 255.0f;
274 if (premultiplyAlpha)
275 {
276 color.R = static_cast<GLubyte>(static_cast<float>(color.R) * alpha);
277 color.G = static_cast<GLubyte>(static_cast<float>(color.G) * alpha);
278 color.B = static_cast<GLubyte>(static_cast<float>(color.B) * alpha);
279 }
280 else if (unmultiplyAlpha && color.A != 0)
281 {
282 color.R = static_cast<GLubyte>(static_cast<float>(color.R) / alpha);
283 color.G = static_cast<GLubyte>(static_cast<float>(color.G) / alpha);
284 color.B = static_cast<GLubyte>(static_cast<float>(color.B) / alpha);
285 }
286 }
287
288 switch (destFormat)
289 {
290 case GL_RGB:
291 color.A = 255;
292 break;
293 case GL_RGBA:
294 case GL_BGRA_EXT:
295 break;
296 default:
297 EXPECT_EQ(true, false);
298 }
299
300 *destColor = color;
301 }
302
getSourceColors(GLenum sourceFormat,size_t * colorCount,uint8_t * componentCount)303 const uint8_t *getSourceColors(GLenum sourceFormat, size_t *colorCount, uint8_t *componentCount)
304 {
305 // Note: in all the following values, alpha is larger than RGB so unmultiply alpha doesn't
306 // overflow
307 constexpr static uint8_t kRgbaColors[7 * 4] = {
308 255u, 127u, 63u, 255u, // 0
309 31u, 127u, 63u, 127u, // 1
310 31u, 63u, 127u, 255u, // 2
311 15u, 127u, 31u, 127u, // 3
312 127u, 255u, 63u, 0u, // 4
313 31u, 63u, 127u, 0u, // 5
314 15u, 31u, 63u, 63u, // 6
315 };
316
317 constexpr static uint8_t kRgbColors[7 * 3] = {
318 255u, 127u, 63u, // 0
319 31u, 127u, 63u, // 1
320 31u, 63u, 127u, // 2
321 15u, 127u, 31u, // 3
322 127u, 255u, 63u, // 4
323 31u, 63u, 127u, // 5
324 15u, 31u, 63u, // 6
325 };
326
327 constexpr static uint8_t kLumColors[7 * 1] = {
328 255u, // 0
329 163u, // 1
330 78u, // 2
331 114u, // 3
332 51u, // 4
333 0u, // 5
334 217u, // 6
335 };
336
337 constexpr static uint8_t kLumaColors[7 * 2] = {
338 255u, 255u, // 0
339 67u, 163u, // 1
340 78u, 231u, // 2
341 8u, 114u, // 3
342 51u, 199u, // 4
343 0u, 173u, // 5
344 34u, 217u, // 6
345 };
346
347 constexpr static uint8_t kAlphaColors[7 * 1] = {
348 255u, // 0
349 67u, // 1
350 231u, // 2
351 8u, // 3
352 199u, // 4
353 173u, // 5
354 34u, // 6
355 };
356
357 *colorCount = 7;
358
359 switch (sourceFormat)
360 {
361 case GL_RGB:
362 *componentCount = 3;
363 return kRgbColors;
364 case GL_RGBA:
365 case GL_BGRA_EXT:
366 *componentCount = 4;
367 return kRgbaColors;
368 case GL_LUMINANCE:
369 *componentCount = 1;
370 return kLumColors;
371 case GL_ALPHA:
372 *componentCount = 1;
373 return kAlphaColors;
374 case GL_LUMINANCE_ALPHA:
375 *componentCount = 2;
376 return kLumaColors;
377 default:
378 EXPECT_EQ(true, false);
379 return nullptr;
380 }
381 }
382
initializeSourceTexture(GLenum target,GLenum sourceFormat,const uint8_t * srcColors,uint8_t componentCount)383 void initializeSourceTexture(GLenum target,
384 GLenum sourceFormat,
385 const uint8_t *srcColors,
386 uint8_t componentCount)
387 {
388 // The texture is initialized as 2x2. If the componentCount is 1 or 3, then the input data
389 // will have a row pitch of 2 or 6, which needs to be padded to 4 or 8 respectively.
390 uint8_t srcColorsPadded[4 * 4];
391 size_t srcRowPitch =
392 2 * componentCount + (componentCount == 1 || componentCount == 3 ? 2 : 0);
393 size_t inputRowPitch = 2 * componentCount;
394 for (size_t row = 0; row < 2; ++row)
395 {
396 memcpy(&srcColorsPadded[row * srcRowPitch], &srcColors[row * inputRowPitch],
397 inputRowPitch);
398 memset(&srcColorsPadded[row * srcRowPitch + inputRowPitch], 0,
399 srcRowPitch - inputRowPitch);
400 }
401
402 glBindTexture(target, mTextures[0]);
403 glTexImage2D(target, 0, sourceFormat, 2, 2, 0, sourceFormat, GL_UNSIGNED_BYTE,
404 srcColorsPadded);
405 }
406
testCopyTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha)407 void testCopyTexture(GLenum sourceTarget,
408 GLenum sourceFormat,
409 GLenum destFormat,
410 bool flipY,
411 bool premultiplyAlpha,
412 bool unmultiplyAlpha)
413 {
414 if (!checkExtensions(sourceFormat, destFormat))
415 {
416 return;
417 }
418
419 size_t colorCount;
420 uint8_t componentCount;
421 const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
422
423 std::vector<GLColor> destColors(colorCount);
424 for (size_t i = 0; i < colorCount; ++i)
425 {
426 calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
427 &srcColors[i * componentCount], &destColors[i]);
428 }
429
430 for (size_t i = 0; i < colorCount - 3; ++i)
431 {
432 initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
433 componentCount);
434
435 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
436 GL_UNSIGNED_BYTE, flipY, premultiplyAlpha, unmultiplyAlpha);
437
438 EXPECT_GL_NO_ERROR();
439
440 // Check that FB is complete.
441 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
442
443 if (flipY)
444 {
445 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
446 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
447 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
448 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
449 }
450 else
451 {
452 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
453 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
454 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
455 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
456 }
457
458 EXPECT_GL_NO_ERROR();
459 }
460 }
461
testCopySubTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha)462 void testCopySubTexture(GLenum sourceTarget,
463 GLenum sourceFormat,
464 GLenum destFormat,
465 bool flipY,
466 bool premultiplyAlpha,
467 bool unmultiplyAlpha)
468 {
469 if (!checkExtensions(sourceFormat, destFormat))
470 {
471 return;
472 }
473
474 size_t colorCount;
475 uint8_t componentCount;
476 const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
477
478 std::vector<GLColor> destColors(colorCount);
479 for (size_t i = 0; i < colorCount; ++i)
480 {
481 calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
482 &srcColors[i * componentCount], &destColors[i]);
483 }
484
485 for (size_t i = 0; i < colorCount - 3; ++i)
486 {
487 initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
488 componentCount);
489
490 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
491 glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 2, 2, 0, destFormat, GL_UNSIGNED_BYTE,
492 nullptr);
493
494 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 2,
495 2, flipY, premultiplyAlpha, unmultiplyAlpha);
496
497 EXPECT_GL_NO_ERROR();
498
499 if (sourceFormat != GL_LUMINANCE && sourceFormat != GL_LUMINANCE_ALPHA &&
500 sourceFormat != GL_ALPHA)
501 {
502 // Check that FB is complete.
503 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
504 }
505
506 if (flipY)
507 {
508 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
509 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
510 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
511 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
512 }
513 else
514 {
515 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
516 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
517 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
518 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
519 }
520
521 EXPECT_GL_NO_ERROR();
522 }
523 }
524
525 GLuint mTextures[2] = {
526 0,
527 0,
528 };
529 GLuint mFramebuffer = 0;
530 };
531
532 class CopyTextureTestDest : public CopyTextureTest
533 {};
534
535 class CopyTextureTestWebGL : public CopyTextureTest
536 {
537 protected:
CopyTextureTestWebGL()538 CopyTextureTestWebGL() : CopyTextureTest() { setWebGLCompatibilityEnabled(true); }
539 };
540
541 class CopyTextureTestES3 : public CopyTextureTest
542 {};
543
544 // Test that CopyTexture cannot redefine an immutable texture and CopySubTexture can copy data to
545 // immutable textures
TEST_P(CopyTextureTest,ImmutableTexture)546 TEST_P(CopyTextureTest, ImmutableTexture)
547 {
548 if (!checkExtensions())
549 {
550 return;
551 }
552
553 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
554 (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
555 !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
556
557 GLColor pixels = GLColor::red;
558
559 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
560 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
561 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
562
563 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
564 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
565 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
566 EXPECT_GL_NO_ERROR();
567
568 // Should generate an error when the texture is redefined
569 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
570 GL_UNSIGNED_BYTE, false, false, false);
571 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
572
573 // Should succeed when using CopySubTexture
574 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1, 1,
575 false, false, false);
576 EXPECT_GL_NO_ERROR();
577
578 // Check that FB is complete.
579 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
580
581 EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
582
583 EXPECT_GL_NO_ERROR();
584 }
585
586 // Test validation of internal formats in CopyTexture and CopySubTexture
TEST_P(CopyTextureTest,InternalFormat)587 TEST_P(CopyTextureTest, InternalFormat)
588 {
589 if (!checkExtensions())
590 {
591 return;
592 }
593
594 std::vector<GLint> sourceFormats;
595 sourceFormats.push_back(GL_ALPHA);
596 sourceFormats.push_back(GL_RGB);
597 sourceFormats.push_back(GL_RGBA);
598 sourceFormats.push_back(GL_LUMINANCE);
599 sourceFormats.push_back(GL_LUMINANCE_ALPHA);
600
601 std::vector<GLint> destFormats;
602 destFormats.push_back(GL_RGB);
603 destFormats.push_back(GL_RGBA);
604
605 if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
606 {
607 sourceFormats.push_back(GL_BGRA_EXT);
608 destFormats.push_back(GL_BGRA_EXT);
609 }
610
611 // Test with glCopyTexture
612 for (GLint sourceFormat : sourceFormats)
613 {
614 for (GLint destFormat : destFormats)
615 {
616 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
617 glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
618 nullptr);
619 EXPECT_GL_NO_ERROR();
620
621 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
622 GL_UNSIGNED_BYTE, false, false, false);
623
624 EXPECT_GL_NO_ERROR();
625 }
626 }
627
628 // Test with glCopySubTexture
629 for (GLint sourceFormat : sourceFormats)
630 {
631 for (GLint destFormat : destFormats)
632 {
633 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
634 glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
635 nullptr);
636 EXPECT_GL_NO_ERROR();
637
638 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
639 glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 1, 1, 0, destFormat, GL_UNSIGNED_BYTE,
640 nullptr);
641 EXPECT_GL_NO_ERROR();
642
643 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1,
644 1, false, false, false);
645
646 EXPECT_GL_NO_ERROR();
647 }
648 }
649 }
650
651 // Test to ensure that the destination texture is redefined if the properties are different.
TEST_P(CopyTextureTest,RedefineDestinationTexture)652 TEST_P(CopyTextureTest, RedefineDestinationTexture)
653 {
654 ANGLE_SKIP_TEST_IF(!checkExtensions());
655 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
656
657 GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
658
659 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
660 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
661
662 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
663 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
664 EXPECT_GL_NO_ERROR();
665
666 // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
667 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
668 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
669 // GL_INVALID_VALUE due to bad dimensions.
670 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
671 EXPECT_GL_ERROR(GL_INVALID_VALUE);
672
673 // If the dest texture has different properties, glCopyTextureCHROMIUM()
674 // redefines them.
675 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
676 GL_UNSIGNED_BYTE, false, false, false);
677 EXPECT_GL_NO_ERROR();
678
679 // glTexSubImage2D() succeeds because mTextures[1] is redefined into 2x2
680 // dimension and GL_RGBA format.
681 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
682 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
683 EXPECT_GL_NO_ERROR();
684
685 // Check that FB is complete.
686 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
687
688 EXPECT_PIXEL_COLOR_EQ(1, 1, pixels[3]);
689 EXPECT_GL_NO_ERROR();
690 }
691
692 // Test that invalid dimensions in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureDimension)693 TEST_P(CopyTextureTest, CopySubTextureDimension)
694 {
695 if (!checkExtensions())
696 {
697 return;
698 }
699
700 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
701 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
702
703 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
704 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
705
706 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
707 false, false, false);
708 EXPECT_GL_NO_ERROR();
709
710 // xoffset < 0
711 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, -1, 1, 0, 0, 1, 1,
712 false, false, false);
713 EXPECT_GL_ERROR(GL_INVALID_VALUE);
714
715 // x < 0
716 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, -1, 0, 1, 1,
717 false, false, false);
718 EXPECT_GL_ERROR(GL_INVALID_VALUE);
719
720 // xoffset + width > dest_width
721 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 2, 2, 0, 0, 2, 2,
722 false, false, false);
723 EXPECT_GL_ERROR(GL_INVALID_VALUE);
724
725 // x + width > source_width
726 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 1, 1, 2, 2,
727 false, false, false);
728 EXPECT_GL_ERROR(GL_INVALID_VALUE);
729 }
730
731 // Test that invalid IDs in CopyTexture are validated
TEST_P(CopyTextureTest,CopyTextureInvalidTextureIds)732 TEST_P(CopyTextureTest, CopyTextureInvalidTextureIds)
733 {
734 if (!checkExtensions())
735 {
736 return;
737 }
738
739 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
740 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
741
742 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
743 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
744
745 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, GL_RGBA, GL_UNSIGNED_BYTE,
746 false, false, false);
747 EXPECT_GL_ERROR(GL_INVALID_VALUE);
748
749 glCopyTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA, GL_UNSIGNED_BYTE,
750 false, false, false);
751 EXPECT_GL_ERROR(GL_INVALID_VALUE);
752
753 glCopyTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, GL_RGBA, GL_UNSIGNED_BYTE, false,
754 false, false);
755 EXPECT_GL_ERROR(GL_INVALID_VALUE);
756
757 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
758 GL_UNSIGNED_BYTE, false, false, false);
759 EXPECT_GL_NO_ERROR();
760 }
761
762 // Test that invalid IDs in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureInvalidTextureIds)763 TEST_P(CopyTextureTest, CopySubTextureInvalidTextureIds)
764 {
765 if (!checkExtensions())
766 {
767 return;
768 }
769
770 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
771 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
772
773 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
774 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
775
776 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, 1, 1, 0, 0, 1, 1, false,
777 false, false);
778 EXPECT_GL_ERROR(GL_INVALID_VALUE);
779
780 glCopySubTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1, false,
781 false, false);
782 EXPECT_GL_ERROR(GL_INVALID_VALUE);
783
784 glCopySubTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, 1, 1, 0, 0, 1, 1, false, false,
785 false);
786 EXPECT_GL_ERROR(GL_INVALID_VALUE);
787
788 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
789 false, false, false);
790 EXPECT_GL_NO_ERROR();
791 }
792
TEST_P(CopyTextureTest,InvalidTarget)793 TEST_P(CopyTextureTest, InvalidTarget)
794 {
795 ANGLE_SKIP_TEST_IF(!checkExtensions());
796
797 GLTexture textures[2];
798
799 glBindTexture(GL_TEXTURE_2D, textures[0]);
800 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
801
802 glBindTexture(GL_TEXTURE_2D, textures[1]);
803 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
804
805 // Invalid enum for a completely invalid target
806 glCopySubTextureCHROMIUM(textures[0], 0, GL_INVALID_VALUE, textures[1], 0, 1, 1, 0, 0, 1, 1,
807 false, false, false);
808 EXPECT_GL_ERROR(GL_INVALID_ENUM);
809
810 // Invalid value for a valid target enum but is not valid for the destination texture
811 glCopySubTextureCHROMIUM(textures[0], 0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textures[1], 0, 1, 1,
812 0, 0, 1, 1, false, false, false);
813 EXPECT_GL_ERROR(GL_INVALID_VALUE);
814 }
815
816 // Test that using an offset in CopySubTexture works correctly
TEST_P(CopyTextureTest,CopySubTextureOffset)817 TEST_P(CopyTextureTest, CopySubTextureOffset)
818 {
819 if (!checkExtensions())
820 {
821 return;
822 }
823
824 GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
825 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
826 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
827
828 GLColor transparentPixels[4 * 4] = {GLColor::transparentBlack, GLColor::transparentBlack,
829 GLColor::transparentBlack, GLColor::transparentBlack};
830 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
831 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, transparentPixels);
832
833 // Check that FB is complete.
834 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
835
836 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
837 false, false, false);
838 EXPECT_GL_NO_ERROR();
839 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
840
841 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 0, 1, 0, 1, 1,
842 false, false, false);
843 EXPECT_GL_NO_ERROR();
844 EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
845
846 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 1, 0, 1, 1, 1,
847 false, false, false);
848 EXPECT_GL_NO_ERROR();
849 EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue);
850
851 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
852 EXPECT_GL_NO_ERROR();
853 }
854
855 // Test every combination of copy [sub]texture parameters:
856 // source: ALPHA, RGB, RGBA, LUMINANCE, LUMINANCE_ALPHA, BGRA_EXT
857 // destination: RGB, RGBA, BGRA_EXT
858 // flipY: false, true
859 // premultiplyAlpha: false, true
860 // unmultiplyAlpha: false, true
861 namespace
862 {
863 constexpr GLenum kCopyTextureVariationsSrcFormats[] = {
864 GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
865 constexpr GLenum kCopyTextureVariationsDstFormats[] = {GL_RGB, GL_RGBA, GL_BGRA_EXT};
866 } // anonymous namespace
867
TEST_P(CopyTextureVariationsTest,CopyTexture)868 TEST_P(CopyTextureVariationsTest, CopyTexture)
869 {
870 // http://anglebug.com/4092
871 ANGLE_SKIP_TEST_IF(IsVulkan());
872 testCopyTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
873 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
874 }
875
TEST_P(CopyTextureVariationsTest,CopySubTexture)876 TEST_P(CopyTextureVariationsTest, CopySubTexture)
877 {
878 testCopySubTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
879 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
880 }
881
TEST_P(CopyTextureVariationsTest,CopyTextureRectangle)882 TEST_P(CopyTextureVariationsTest, CopyTextureRectangle)
883 {
884 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
885
886 testCopyTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
887 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
888 }
889
TEST_P(CopyTextureVariationsTest,CopySubTextureRectangle)890 TEST_P(CopyTextureVariationsTest, CopySubTextureRectangle)
891 {
892 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
893
894 testCopySubTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
895 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
896 }
897
898 // Test that copying to cube maps works
TEST_P(CopyTextureTest,CubeMapTarget)899 TEST_P(CopyTextureTest, CubeMapTarget)
900 {
901 if (!checkExtensions())
902 {
903 return;
904 }
905
906 // http://anglebug.com/1932
907 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
908
909 // http://anglebug.com/3145
910 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
911
912 GLColor pixels[7] = {
913 GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
914 GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
915 GLColor(70u, 73u, 76u, 79u),
916 };
917
918 GLTexture textures[2];
919
920 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
921 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
922 face++)
923 {
924 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
925 }
926
927 for (size_t i = 0; i < 2; ++i)
928 {
929 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
930 face++)
931 {
932 glBindTexture(GL_TEXTURE_2D, textures[0]);
933 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
934 &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
935
936 glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
937 false, false);
938 }
939
940 EXPECT_GL_NO_ERROR();
941
942 GLFramebuffer fbo;
943 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
944
945 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
946 face++)
947 {
948 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
949
950 // Check that FB is complete.
951 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
952
953 EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
954
955 EXPECT_GL_NO_ERROR();
956 }
957 }
958 }
959
960 // Test that we can successfully copy into incomplete cube maps. Regression test for
961 // http://anglebug.com/3384
TEST_P(CopyTextureTest,IncompleteCubeMap)962 TEST_P(CopyTextureTest, IncompleteCubeMap)
963 {
964 if (!checkExtensions())
965 {
966 return;
967 }
968
969 GLTexture texture2D;
970 GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
971 glBindTexture(GL_TEXTURE_2D, texture2D);
972 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
973
974 GLTexture textureCube;
975 glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
976 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
977 face++)
978 {
979 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
980 }
981
982 // Set one face to 2x2
983 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
984 rgbaPixels);
985
986 // Copy into the incomplete face
987 glCopySubTextureCHROMIUM(texture2D, 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, textureCube, 0, 0, 0, 0,
988 0, 2, 2, false, false, false);
989 EXPECT_GL_NO_ERROR();
990 }
991
992 // Test BGRA to RGBA cube map copy
TEST_P(CopyTextureTest,CubeMapTargetBGRA)993 TEST_P(CopyTextureTest, CubeMapTargetBGRA)
994 {
995 if (!checkExtensions())
996 {
997 return;
998 }
999
1000 if (!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1001 {
1002 return;
1003 }
1004
1005 // http://anglebug.com/3145
1006 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1007
1008 GLColor pixels[7] = {
1009 GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
1010 GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
1011 GLColor(70u, 73u, 76u, 79u),
1012 };
1013
1014 GLTexture textures[2];
1015
1016 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1017 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1018 face++)
1019 {
1020 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1021 }
1022
1023 for (size_t i = 0; i < 2; ++i)
1024 {
1025 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1026 face++)
1027 {
1028 glBindTexture(GL_TEXTURE_2D, textures[0]);
1029 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1030 &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1031
1032 glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
1033 false, false);
1034 }
1035
1036 EXPECT_GL_NO_ERROR();
1037
1038 GLFramebuffer fbo;
1039 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1040
1041 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1042 face++)
1043 {
1044 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1045
1046 // Check that FB is complete.
1047 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1048
1049 GLColor converted = pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i];
1050 std::swap(converted.R, converted.B);
1051 EXPECT_PIXEL_COLOR_EQ(0, 0, converted);
1052
1053 EXPECT_GL_NO_ERROR();
1054 }
1055 }
1056 }
1057
1058 // Test cube map copies with RGB format
TEST_P(CopyTextureTest,CubeMapTargetRGB)1059 TEST_P(CopyTextureTest, CubeMapTargetRGB)
1060 {
1061 if (!checkExtensions())
1062 {
1063 return;
1064 }
1065
1066 // http://anglebug.com/1932
1067 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
1068
1069 // http://anglebug.com/3145
1070 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1071
1072 constexpr uint8_t pixels[16 * 7] = {
1073 0u, 3u, 6u, 10u, 13u, 16u, 0, 0, 20u, 23u, 26u, 30u, 33u, 36u, 0, 0, // 2x2
1074 40u, 43u, 46u, 50u, 53u, 56u, 0, 0, 60u, 63u, 66u, 70u, 73u, 76u, 0, 0, // 2x2
1075 80u, 83u, 86u, 90u, 93u, 96u, 0, 0, 100u, 103u, 106u, 110u, 113u, 116u, 0, 0, // 2x2
1076 120u, 123u, 126u, 130u, 133u, 136u, 0, 0, 140u, 143u, 146u, 160u, 163u, 166u, 0, 0, // 2x2
1077 170u, 173u, 176u, 180u, 183u, 186u, 0, 0, 190u, 193u, 196u, 200u, 203u, 206u, 0, 0, // 2x2
1078 210u, 213u, 216u, 220u, 223u, 226u, 0, 0, 230u, 233u, 236u, 240u, 243u, 246u, 0, 0, // 2x2
1079 10u, 50u, 100u, 30u, 80u, 130u, 0, 0, 60u, 110u, 160u, 90u, 140u, 200u, 0, 0, // 2x2
1080 };
1081
1082 GLTexture textures[2];
1083
1084 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1085 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1086 face++)
1087 {
1088 glTexImage2D(face, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1089 }
1090
1091 for (size_t i = 0; i < 2; ++i)
1092 {
1093 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1094 face++)
1095 {
1096 glBindTexture(GL_TEXTURE_2D, textures[0]);
1097 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
1098 &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16]);
1099
1100 glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 2, 2, false,
1101 false, false);
1102 }
1103
1104 EXPECT_GL_NO_ERROR();
1105
1106 GLFramebuffer fbo;
1107 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1108
1109 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1110 face++)
1111 {
1112 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1113
1114 // Check that FB is complete.
1115 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1116
1117 const uint8_t *faceData = &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16];
1118 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(faceData[0], faceData[1], faceData[2], 255));
1119 EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor(faceData[3], faceData[4], faceData[5], 255));
1120 EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor(faceData[8], faceData[9], faceData[10], 255));
1121 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor(faceData[11], faceData[12], faceData[13], 255));
1122
1123 EXPECT_GL_NO_ERROR();
1124 }
1125 }
1126 }
1127
1128 // Test that copying to non-zero mipmaps works
TEST_P(CopyTextureTest,CopyToMipmap)1129 TEST_P(CopyTextureTest, CopyToMipmap)
1130 {
1131 if (!checkExtensions())
1132 {
1133 return;
1134 }
1135
1136 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1137 !IsGLExtensionEnabled("GL_OES_fbo_render_mipmap"));
1138
1139 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel());
1140
1141 GLColor pixels[] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
1142
1143 GLTexture textures[2];
1144
1145 glBindTexture(GL_TEXTURE_2D, textures[0]);
1146 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1147 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1148
1149 glBindTexture(GL_TEXTURE_2D, textures[1]);
1150 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1151 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1152 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1153
1154 std::vector<std::pair<GLint, GLint>> soureDestPairs;
1155 soureDestPairs.push_back(std::make_pair(0, 1));
1156
1157 // ES3 allows copying from non-zero mips
1158 if (getClientMajorVersion() >= 3)
1159 {
1160 soureDestPairs.push_back(std::make_pair(1, 2));
1161 }
1162
1163 for (const auto &sourceDestPair : soureDestPairs)
1164 {
1165 const GLint sourceLevel = sourceDestPair.first;
1166 const GLint destLevel = sourceDestPair.second;
1167
1168 glCopyTextureCHROMIUM(textures[0], sourceLevel, GL_TEXTURE_2D, textures[1], destLevel,
1169 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1170
1171 EXPECT_GL_NO_ERROR();
1172
1173 GLFramebuffer fbo;
1174 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1175 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
1176 destLevel);
1177
1178 // Check that FB is complete.
1179 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1180
1181 EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[0]);
1182
1183 EXPECT_GL_NO_ERROR();
1184 }
1185 }
1186
1187 // Test that copying from an RGBA8 texture to RGBA4 results in exactly 4-bit precision in the result
TEST_P(CopyTextureTest,DownsampleRGBA4444)1188 TEST_P(CopyTextureTest, DownsampleRGBA4444)
1189 {
1190 // Downsampling on copy is only guarenteed on D3D11
1191 ANGLE_SKIP_TEST_IF(!IsD3D11());
1192
1193 GLTexture textures[2];
1194
1195 GLColor pixels[] = {GLColor(0, 5, 6, 7), GLColor(17, 22, 25, 24), GLColor(34, 35, 36, 36),
1196 GLColor(51, 53, 55, 55)};
1197
1198 glBindTexture(GL_TEXTURE_2D, textures[0]);
1199 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1200
1201 glBindTexture(GL_TEXTURE_2D, textures[1]);
1202 glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1203 GL_UNSIGNED_SHORT_4_4_4_4, GL_FALSE, GL_FALSE, GL_FALSE);
1204
1205 GLFramebuffer fbo;
1206 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1207 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1208
1209 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1210 EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(17, 17, 17, 17), 1.0);
1211 EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(34, 34, 34, 34), 1.0);
1212 EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(51, 51, 51, 51), 1.0);
1213
1214 testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, {16, 16, 16, 16});
1215 }
1216
1217 // Test that copying from an RGBA8 texture to RGB565 results in exactly 4-bit precision in the
1218 // result
TEST_P(CopyTextureTest,DownsampleRGB565)1219 TEST_P(CopyTextureTest, DownsampleRGB565)
1220 {
1221 // Downsampling on copy is only guarenteed on D3D11
1222 ANGLE_SKIP_TEST_IF(!IsD3D11());
1223
1224 GLTexture textures[2];
1225
1226 GLColor pixels[] = {GLColor(0, 5, 2, 14), GLColor(17, 22, 25, 30), GLColor(34, 33, 36, 46),
1227 GLColor(50, 54, 49, 60)};
1228
1229 glBindTexture(GL_TEXTURE_2D, textures[0]);
1230 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1231
1232 glBindTexture(GL_TEXTURE_2D, textures[1]);
1233 glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGB,
1234 GL_UNSIGNED_SHORT_5_6_5, GL_FALSE, GL_FALSE, GL_FALSE);
1235
1236 GLFramebuffer fbo;
1237 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1238 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1239
1240 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 4, 0, 255), 1.0);
1241 EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 20, 25, 255), 1.0);
1242 EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 32, 33, 255), 1.0);
1243 EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 53, 49, 255), 1.0);
1244
1245 testGradientDownsampleUniqueValues(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, {32, 64, 32, 1});
1246 }
1247
1248 // Test that copying from an RGBA8 texture to RGBA5551 results in exactly 4-bit precision in the
1249 // result
TEST_P(CopyTextureTest,DownsampleRGBA5551)1250 TEST_P(CopyTextureTest, DownsampleRGBA5551)
1251 {
1252 // Downsampling on copy is only guarenteed on D3D11
1253 ANGLE_SKIP_TEST_IF(!IsD3D11());
1254
1255 GLTexture textures[2];
1256
1257 GLColor pixels[] = {GLColor(0, 1, 2, 3), GLColor(14, 16, 17, 18), GLColor(33, 34, 36, 46),
1258 GLColor(50, 51, 52, 255)};
1259
1260 glBindTexture(GL_TEXTURE_2D, textures[0]);
1261 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1262
1263 glBindTexture(GL_TEXTURE_2D, textures[1]);
1264 glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1265 GL_UNSIGNED_SHORT_5_5_5_1, GL_FALSE, GL_FALSE, GL_FALSE);
1266
1267 GLFramebuffer fbo;
1268 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1269 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1270
1271 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1272 EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 16, 16, 0), 1.0);
1273 EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 33, 33, 0), 1.0);
1274 EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 49, 49, 255), 1.0);
1275
1276 testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, {32, 32, 32, 2});
1277 }
1278
1279 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination
TEST_P(CopyTextureTestDest,Luminance)1280 TEST_P(CopyTextureTestDest, Luminance)
1281 {
1282 if (!checkExtensions())
1283 {
1284 return;
1285 }
1286
1287 GLColor originalPixels(50u, 100u, 150u, 200u);
1288 GLColor expectedPixels(50u, 50u, 50u, 255u);
1289
1290 // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1291 // texture to verify contents.
1292 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1293 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1294 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1295 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1296
1297 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1298 GL_UNSIGNED_BYTE, false, false, false);
1299
1300 EXPECT_GL_NO_ERROR();
1301
1302 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1303 GL_UNSIGNED_BYTE, false, false, false);
1304
1305 EXPECT_GL_NO_ERROR();
1306
1307 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1308 }
1309
1310 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1311 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceMultiply)1312 TEST_P(CopyTextureTestDest, LuminanceMultiply)
1313 {
1314 if (!checkExtensions())
1315 {
1316 return;
1317 }
1318
1319 GLColor originalPixels(50u, 100u, 150u, 200u);
1320 GLColor expectedPixels(39u, 39u, 39u, 255u);
1321
1322 // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1323 // texture to verify contents.
1324 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1325 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1326 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1327 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1328
1329 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1330 GL_UNSIGNED_BYTE, false, true, false);
1331
1332 EXPECT_GL_NO_ERROR();
1333
1334 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1335 GL_UNSIGNED_BYTE, false, false, false);
1336
1337 EXPECT_GL_NO_ERROR();
1338
1339 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1340 }
1341
1342 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1343 // UnpackUnmultiply parameter
TEST_P(CopyTextureTestDest,LuminanceUnmultiply)1344 TEST_P(CopyTextureTestDest, LuminanceUnmultiply)
1345 {
1346 if (!checkExtensions())
1347 {
1348 return;
1349 }
1350
1351 GLColor originalPixels(50u, 100u, 150u, 200u);
1352 GLColor expectedPixels(64u, 64u, 64u, 255u);
1353
1354 // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1355 // texture to verify contents.
1356 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1357 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1358 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1359 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1360
1361 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1362 GL_UNSIGNED_BYTE, false, false, true);
1363
1364 EXPECT_GL_NO_ERROR();
1365
1366 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1367 GL_UNSIGNED_BYTE, false, false, false);
1368
1369 EXPECT_GL_NO_ERROR();
1370
1371 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1372 }
1373
1374 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination
TEST_P(CopyTextureTestDest,LuminanceAlpha)1375 TEST_P(CopyTextureTestDest, LuminanceAlpha)
1376 {
1377 if (!checkExtensions())
1378 {
1379 return;
1380 }
1381
1382 GLColor originalPixels(50u, 100u, 150u, 200u);
1383 GLColor expectedPixels(50u, 50u, 50u, 200u);
1384
1385 // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1386 // RGBA texture to verify contents.
1387 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1388 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1389 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1390 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1391 GL_UNSIGNED_BYTE, nullptr);
1392
1393 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1394 GL_UNSIGNED_BYTE, false, false, false);
1395
1396 EXPECT_GL_NO_ERROR();
1397
1398 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1399 GL_UNSIGNED_BYTE, false, false, false);
1400
1401 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1402 }
1403
1404 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1405 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaMultiply)1406 TEST_P(CopyTextureTestDest, LuminanceAlphaMultiply)
1407 {
1408 if (!checkExtensions())
1409 {
1410 return;
1411 }
1412
1413 GLColor originalPixels(50u, 100u, 150u, 200u);
1414 GLColor expectedPixels(39u, 39u, 39u, 200u);
1415
1416 // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1417 // RGBA texture to verify contents.
1418 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1419 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1420 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1421 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1422 GL_UNSIGNED_BYTE, nullptr);
1423
1424 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1425 GL_UNSIGNED_BYTE, false, true, false);
1426
1427 EXPECT_GL_NO_ERROR();
1428
1429 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1430 GL_UNSIGNED_BYTE, false, false, false);
1431
1432 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1433 }
1434
1435 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1436 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaUnmultiply)1437 TEST_P(CopyTextureTestDest, LuminanceAlphaUnmultiply)
1438 {
1439 if (!checkExtensions())
1440 {
1441 return;
1442 }
1443
1444 GLColor originalPixels(50u, 100u, 150u, 200u);
1445 GLColor expectedPixels(64u, 64u, 64u, 200u);
1446
1447 // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1448 // RGBA texture to verify contents.
1449 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1450 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1451 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1452 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1453 GL_UNSIGNED_BYTE, nullptr);
1454
1455 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1456 GL_UNSIGNED_BYTE, false, false, true);
1457
1458 EXPECT_GL_NO_ERROR();
1459
1460 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1461 GL_UNSIGNED_BYTE, false, false, false);
1462
1463 EXPECT_GL_NO_ERROR();
1464
1465 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1466 }
1467
1468 // Test to ensure that CopyTexture works with ALPHA texture as a destination
TEST_P(CopyTextureTestDest,Alpha)1469 TEST_P(CopyTextureTestDest, Alpha)
1470 {
1471 if (!checkExtensions())
1472 {
1473 return;
1474 }
1475
1476 GLColor originalPixels(50u, 100u, 150u, 155u);
1477 GLColor expectedPixels(0u, 0u, 0u, 155u);
1478
1479 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1480 // texture to verify contents.
1481 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1482 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1483 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1484 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1485
1486 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1487 GL_UNSIGNED_BYTE, false, false, false);
1488
1489 EXPECT_GL_NO_ERROR();
1490
1491 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1492 GL_UNSIGNED_BYTE, false, false, false);
1493
1494 EXPECT_GL_NO_ERROR();
1495
1496 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1497 }
1498
1499 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1500 // UnpackPremultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaMultiply)1501 TEST_P(CopyTextureTestDest, AlphaMultiply)
1502 {
1503 if (!checkExtensions())
1504 {
1505 return;
1506 }
1507
1508 GLColor originalPixels(50u, 100u, 150u, 155u);
1509 GLColor expectedPixels(0u, 0u, 0u, 155u);
1510
1511 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1512 // texture to verify contents.
1513 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1514 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1515 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1516 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1517
1518 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1519 GL_UNSIGNED_BYTE, false, true, false);
1520
1521 EXPECT_GL_NO_ERROR();
1522
1523 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1524 GL_UNSIGNED_BYTE, false, false, false);
1525
1526 EXPECT_GL_NO_ERROR();
1527
1528 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1529 }
1530
1531 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1532 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaUnmultiply)1533 TEST_P(CopyTextureTestDest, AlphaUnmultiply)
1534 {
1535 if (!checkExtensions())
1536 {
1537 return;
1538 }
1539
1540 GLColor originalPixels(50u, 100u, 150u, 155u);
1541 GLColor expectedPixels(0u, 0u, 0u, 155u);
1542
1543 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1544 // texture to verify contents.
1545 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1546 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1547 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1548 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1549
1550 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1551 GL_UNSIGNED_BYTE, false, false, true);
1552
1553 EXPECT_GL_NO_ERROR();
1554
1555 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1556 GL_UNSIGNED_BYTE, false, false, false);
1557
1558 EXPECT_GL_NO_ERROR();
1559
1560 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1561 }
1562
1563 // Test to ensure that CopyTexture uses the correct ALPHA passthrough shader to ensure RGB channels
1564 // are set to 0.
TEST_P(CopyTextureTestDest,AlphaCopyWithRGB)1565 TEST_P(CopyTextureTestDest, AlphaCopyWithRGB)
1566 {
1567 // http://anglebug.com/4121
1568 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
1569 ANGLE_SKIP_TEST_IF(!checkExtensions());
1570
1571 GLColor originalPixels(50u, 100u, 150u, 155u);
1572 GLColor expectedPixels(0u, 0u, 0u, 155u);
1573
1574 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1575 // texture to verify contents.
1576 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1577 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1578 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1579 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_HALF_FLOAT_OES, nullptr);
1580
1581 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1582 GL_HALF_FLOAT_OES, false, false, false);
1583
1584 EXPECT_GL_NO_ERROR();
1585
1586 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1587 GL_UNSIGNED_BYTE, false, false, false);
1588
1589 EXPECT_GL_NO_ERROR();
1590
1591 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1592 }
1593
1594 // Bug where TEXTURE_SWIZZLE_RGBA was not reset after the Luminance workaround. (crbug.com/1022080)
TEST_P(CopyTextureTestES3,LuminanceWorkaroundTextureSwizzleBug)1595 TEST_P(CopyTextureTestES3, LuminanceWorkaroundTextureSwizzleBug)
1596 {
1597
1598 {
1599 GLColor pixels(50u, 20u, 100u, 150u);
1600
1601 // Hit BlitGL::copySubImageToLUMAWorkaroundTexture by copying an ALPHA texture
1602 GLTexture srcTexture;
1603 glBindTexture(GL_TEXTURE_2D, srcTexture);
1604 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
1605
1606 GLFramebuffer srcFBO;
1607 glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
1608 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
1609
1610 GLTexture dstTexture;
1611 glBindTexture(GL_TEXTURE_2D, dstTexture);
1612 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1613
1614 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
1615 EXPECT_GL_NO_ERROR();
1616 }
1617
1618 {
1619 // This time hit BlitGL::blitColorBufferWithShader by copying an SRGB texture
1620 GLColor pixels(100u, 200u, 50u, 210u);
1621
1622 GLTexture srcTexture;
1623 glBindTexture(GL_TEXTURE_2D, srcTexture);
1624 glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1625 GL_UNSIGNED_BYTE, &pixels);
1626
1627 GLFramebuffer srcFBO;
1628 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
1629 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture,
1630 0);
1631
1632 GLTexture dstTexture;
1633 glBindTexture(GL_TEXTURE_2D, dstTexture);
1634 glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1635 GL_UNSIGNED_BYTE, nullptr);
1636
1637 GLFramebuffer dstFBO;
1638 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
1639 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture,
1640 0);
1641
1642 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1643
1644 // The previous workaround should not affect this copy
1645 glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
1646 EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
1647 }
1648 }
1649
1650 // Test to ensure that CopyTexture will fail with a non-zero level and NPOT texture in WebGL
TEST_P(CopyTextureTestWebGL,NPOT)1651 TEST_P(CopyTextureTestWebGL, NPOT)
1652 {
1653 if (IsGLExtensionRequestable("GL_CHROMIUM_copy_texture"))
1654 {
1655 glRequestExtensionANGLE("GL_CHROMIUM_copy_texture");
1656 }
1657 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
1658
1659 std::vector<GLColor> pixelData(10 * 10, GLColor::red);
1660
1661 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1662 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
1663
1664 // Do a basic copy to make sure things work
1665 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1666 GL_UNSIGNED_BYTE, false, false, false);
1667
1668 EXPECT_GL_NO_ERROR();
1669
1670 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1671
1672 // Do the same operation with destLevel 1, which should fail
1673 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 1, GL_RGBA,
1674 GL_UNSIGNED_BYTE, false, false, false);
1675
1676 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1677 }
1678
1679 // Test the newly added ES3 unorm formats
TEST_P(CopyTextureTestES3,ES3UnormFormats)1680 TEST_P(CopyTextureTestES3, ES3UnormFormats)
1681 {
1682 if (!checkExtensions())
1683 {
1684 return;
1685 }
1686 // http://anglebug.com/4092
1687 ANGLE_SKIP_TEST_IF(IsAndroid() || IsVulkan());
1688
1689 auto testOutput = [this](GLuint texture, const GLColor &expectedColor) {
1690 constexpr char kVS[] =
1691 "#version 300 es\n"
1692 "in vec4 position;\n"
1693 "out vec2 texcoord;\n"
1694 "void main()\n"
1695 "{\n"
1696 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1697 " texcoord = (position.xy * 0.5) + 0.5;\n"
1698 "}\n";
1699
1700 constexpr char kFS[] =
1701 "#version 300 es\n"
1702 "precision mediump float;\n"
1703 "uniform sampler2D tex;\n"
1704 "in vec2 texcoord;\n"
1705 "out vec4 color;\n"
1706 "void main()\n"
1707 "{\n"
1708 " color = texture(tex, texcoord);\n"
1709 "}\n";
1710
1711 ANGLE_GL_PROGRAM(program, kVS, kFS);
1712 glUseProgram(program);
1713
1714 GLRenderbuffer rbo;
1715 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1716 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
1717
1718 GLFramebuffer fbo;
1719 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1720 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1721
1722 glActiveTexture(GL_TEXTURE0);
1723 glBindTexture(GL_TEXTURE_2D, texture);
1724 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1725 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1726 glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1727
1728 drawQuad(program, "position", 0.5f, 1.0f, true);
1729
1730 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
1731 };
1732
1733 auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1734 GLenum sourceType, const GLColor &sourceColor,
1735 GLenum destInternalFormat, GLenum destType, bool flipY,
1736 bool premultiplyAlpha, bool unmultiplyAlpha,
1737 const GLColor &expectedColor) {
1738 GLTexture sourceTexture;
1739 glBindTexture(GL_TEXTURE_2D, sourceTexture);
1740 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1741 &sourceColor);
1742
1743 GLTexture destTexture;
1744 glBindTexture(GL_TEXTURE_2D, destTexture);
1745
1746 glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1747 destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1748 ASSERT_GL_NO_ERROR();
1749
1750 testOutput(destTexture, expectedColor);
1751 };
1752
1753 auto testSubCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1754 GLenum sourceType, const GLColor &sourceColor,
1755 GLenum destInternalFormat, GLenum destFormat,
1756 GLenum destType, bool flipY, bool premultiplyAlpha,
1757 bool unmultiplyAlpha, const GLColor &expectedColor) {
1758 GLTexture sourceTexture;
1759 glBindTexture(GL_TEXTURE_2D, sourceTexture);
1760 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1761 &sourceColor);
1762
1763 GLTexture destTexture;
1764 glBindTexture(GL_TEXTURE_2D, destTexture);
1765
1766 glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
1767 glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
1768 flipY, premultiplyAlpha, unmultiplyAlpha);
1769 ASSERT_GL_NO_ERROR();
1770
1771 testOutput(destTexture, expectedColor);
1772 };
1773
1774 // New LUMA source formats
1775 testCopyCombination(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGB,
1776 GL_UNSIGNED_BYTE, false, false, false, GLColor(128, 128, 128, 255));
1777 testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1778 GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, false,
1779 GLColor(128, 128, 128, 255));
1780 testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1781 GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, true, false,
1782 GLColor(32, 32, 32, 255));
1783 testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1784 GLColor(128, 128, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, true,
1785 GLColor(255, 255, 255, 255));
1786 testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1787 GL_UNSIGNED_BYTE, false, false, false, GLColor(0, 0, 0, 128));
1788 testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1789 GL_UNSIGNED_BYTE, false, false, true, GLColor(0, 0, 0, 128));
1790 testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1791 GL_UNSIGNED_BYTE, false, true, false, GLColor(0, 0, 0, 128));
1792
1793 // New sRGB dest formats
1794 if (IsGLExtensionEnabled("GL_EXT_sRGB"))
1795 {
1796 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1797 GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
1798 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1799 GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
1800 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1801 GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
1802 GLColor(55, 13, 4, 128));
1803
1804 testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1805 GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, false, false,
1806 GLColor(55, 13, 4, 255));
1807 testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1808 GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, true, false,
1809 GLColor(13, 4, 1, 255));
1810 testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1811 GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
1812 false, GLColor(55, 13, 4, 128));
1813 }
1814 }
1815
1816 // Test the newly added ES3 float formats
TEST_P(CopyTextureTestES3,ES3FloatFormats)1817 TEST_P(CopyTextureTestES3, ES3FloatFormats)
1818 {
1819 if (!checkExtensions())
1820 {
1821 return;
1822 }
1823
1824 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
1825 // http://anglebug.com/4092
1826 ANGLE_SKIP_TEST_IF(IsVulkan());
1827
1828 auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
1829 constexpr char kVS[] =
1830 "#version 300 es\n"
1831 "in vec4 position;\n"
1832 "out vec2 texcoord;\n"
1833 "void main()\n"
1834 "{\n"
1835 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1836 " texcoord = (position.xy * 0.5) + 0.5;\n"
1837 "}\n";
1838
1839 constexpr char kFS[] =
1840 "#version 300 es\n"
1841 "precision mediump float;\n"
1842 "uniform sampler2D tex;\n"
1843 "in vec2 texcoord;\n"
1844 "out vec4 color;\n"
1845 "void main()\n"
1846 "{\n"
1847 " color = texture(tex, texcoord);\n"
1848 "}\n";
1849
1850 ANGLE_GL_PROGRAM(program, kVS, kFS);
1851 glUseProgram(program);
1852
1853 GLRenderbuffer rbo;
1854 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1855 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1856
1857 GLFramebuffer fbo;
1858 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1859 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1860
1861 glActiveTexture(GL_TEXTURE0);
1862 glBindTexture(GL_TEXTURE_2D, texture);
1863 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1864 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1865 glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1866
1867 drawQuad(program, "position", 0.5f, 1.0f, true);
1868
1869 EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
1870 };
1871
1872 auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1873 GLenum sourceType, const GLColor &sourceColor,
1874 GLenum destInternalFormat, GLenum destType, bool flipY,
1875 bool premultiplyAlpha, bool unmultiplyAlpha,
1876 const GLColor32F &expectedColor) {
1877 GLTexture sourceTexture;
1878 glBindTexture(GL_TEXTURE_2D, sourceTexture);
1879 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1880 &sourceColor);
1881
1882 GLTexture destTexture;
1883 glBindTexture(GL_TEXTURE_2D, destTexture);
1884
1885 glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1886 destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1887 ASSERT_GL_NO_ERROR();
1888
1889 testOutput(destTexture, expectedColor);
1890 };
1891
1892 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1893 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 0.5f));
1894 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1895 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 0.5f));
1896 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1897 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 0.5f));
1898
1899 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1900 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.0f, 0.0f, 1.0f));
1901 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1902 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.0f, 0.0f, 1.0f));
1903 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1904 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.0f, 0.0f, 1.0f));
1905
1906 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1907 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.0f, 1.0f));
1908 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1909 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0f, 1.0f));
1910 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1911 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.0f, 1.0f));
1912
1913 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1914 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1915 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1916 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1917 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1918 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1919
1920 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1921 GL_R11F_G11F_B10F, GL_FLOAT, false, false, false,
1922 GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1923 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1924 GL_R11F_G11F_B10F, GL_FLOAT, false, true, false,
1925 GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1926 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1927 GL_R11F_G11F_B10F, GL_FLOAT, false, false, true,
1928 GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1929
1930 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1931 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1932 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1933 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1934 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1935 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1936 }
1937
1938 // Test the newly added ES3 unsigned integer formats
TEST_P(CopyTextureTestES3,ES3UintFormats)1939 TEST_P(CopyTextureTestES3, ES3UintFormats)
1940 {
1941 ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsIntel());
1942 // http://anglebug.com/4092
1943 ANGLE_SKIP_TEST_IF(IsVulkan());
1944
1945 if (!checkExtensions())
1946 {
1947 return;
1948 }
1949
1950 using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
1951
1952 auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
1953 constexpr char kVS[] =
1954 "#version 300 es\n"
1955 "in vec4 position;\n"
1956 "out vec2 texcoord;\n"
1957 "void main()\n"
1958 "{\n"
1959 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1960 " texcoord = (position.xy * 0.5) + 0.5;\n"
1961 "}\n";
1962
1963 constexpr char kFS[] =
1964 "#version 300 es\n"
1965 "precision mediump float;\n"
1966 "precision mediump usampler2D;\n"
1967 "in vec2 texcoord;\n"
1968 "uniform usampler2D tex;\n"
1969 "out uvec4 color;\n"
1970 "void main()\n"
1971 "{\n"
1972 " color = texture(tex, texcoord);\n"
1973 "}\n";
1974
1975 ANGLE_GL_PROGRAM(program, kVS, kFS);
1976 glUseProgram(program);
1977
1978 GLRenderbuffer rbo;
1979 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1980 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8UI, 1, 1);
1981
1982 GLFramebuffer fbo;
1983 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1984 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1985
1986 glActiveTexture(GL_TEXTURE0);
1987 glBindTexture(GL_TEXTURE_2D, texture);
1988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1990 glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1991
1992 drawQuad(program, "position", 0.5f, 1.0f, true);
1993 ASSERT_GL_NO_ERROR();
1994
1995 GLuint pixel[4] = {0};
1996 glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixel);
1997 ASSERT_GL_NO_ERROR();
1998 EXPECT_NEAR(std::get<0>(expectedColor), pixel[0], 1);
1999 EXPECT_NEAR(std::get<1>(expectedColor), pixel[1], 1);
2000 EXPECT_NEAR(std::get<2>(expectedColor), pixel[2], 1);
2001 EXPECT_NEAR(std::get<3>(expectedColor), pixel[3], 1);
2002 };
2003
2004 auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
2005 GLenum sourceType, const GLColor &sourceColor,
2006 GLenum destInternalFormat, GLenum destType, bool flipY,
2007 bool premultiplyAlpha, bool unmultiplyAlpha,
2008 const GLColor32U &expectedColor) {
2009 GLTexture sourceTexture;
2010 glBindTexture(GL_TEXTURE_2D, sourceTexture);
2011 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2012 &sourceColor);
2013
2014 GLTexture destTexture;
2015 glBindTexture(GL_TEXTURE_2D, destTexture);
2016
2017 glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2018 destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2019 ASSERT_GL_NO_ERROR();
2020
2021 testOutput(destTexture, expectedColor);
2022 };
2023
2024 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2025 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 128));
2026 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2027 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 128));
2028 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2029 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 128));
2030
2031 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2032 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 1));
2033 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2034 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 1));
2035 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2036 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 1));
2037
2038 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2039 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 0, 1));
2040 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2041 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 0, 1));
2042 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2043 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 0, 1));
2044
2045 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2046 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 0, 0, 1));
2047 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2048 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 0, 0, 1));
2049 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(120, 64, 32, 128), GL_R8UI,
2050 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(240, 0, 0, 1));
2051 }
2052
2053 #ifdef Bool
2054 // X11 craziness.
2055 # undef Bool
2056 #endif
2057
2058 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
2059 // tests should be run against.
2060 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTest);
2061 ANGLE_INSTANTIATE_TEST_COMBINE_5(CopyTextureVariationsTest,
2062 CopyTextureVariationsTestPrint,
2063 testing::ValuesIn(kCopyTextureVariationsSrcFormats),
2064 testing::ValuesIn(kCopyTextureVariationsDstFormats),
2065 testing::Bool(), // flipY
2066 testing::Bool(), // premultiplyAlpha
2067 testing::Bool(), // unmultiplyAlpha
2068 ES2_D3D9(),
2069 ES2_D3D11(),
2070 ES2_OPENGL(),
2071 ES2_OPENGLES(),
2072 ES2_VULKAN());
2073 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTestWebGL);
2074 ANGLE_INSTANTIATE_TEST(CopyTextureTestDest,
2075 ES2_D3D11(),
2076 ES2_OPENGL(),
2077 ES2_OPENGLES(),
2078 ES2_VULKAN());
2079 ANGLE_INSTANTIATE_TEST_ES3(CopyTextureTestES3);
2080
2081 } // namespace angle
2082