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 testCopyTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
871 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
872 }
873
TEST_P(CopyTextureVariationsTest,CopySubTexture)874 TEST_P(CopyTextureVariationsTest, CopySubTexture)
875 {
876 testCopySubTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
877 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
878 }
879
TEST_P(CopyTextureVariationsTest,CopyTextureRectangle)880 TEST_P(CopyTextureVariationsTest, CopyTextureRectangle)
881 {
882 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
883
884 testCopyTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
885 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
886 }
887
TEST_P(CopyTextureVariationsTest,CopySubTextureRectangle)888 TEST_P(CopyTextureVariationsTest, CopySubTextureRectangle)
889 {
890 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
891
892 testCopySubTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
893 std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
894 }
895
896 // Test that copying to cube maps works
TEST_P(CopyTextureTest,CubeMapTarget)897 TEST_P(CopyTextureTest, CubeMapTarget)
898 {
899 if (!checkExtensions())
900 {
901 return;
902 }
903
904 // http://anglebug.com/1932
905 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
906
907 // http://anglebug.com/3145
908 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
909
910 GLColor pixels[7] = {
911 GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
912 GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
913 GLColor(70u, 73u, 76u, 79u),
914 };
915
916 GLTexture textures[2];
917
918 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
919 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
920 face++)
921 {
922 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
923 }
924
925 for (size_t i = 0; i < 2; ++i)
926 {
927 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
928 face++)
929 {
930 glBindTexture(GL_TEXTURE_2D, textures[0]);
931 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
932 &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
933
934 glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
935 false, false);
936 }
937
938 EXPECT_GL_NO_ERROR();
939
940 GLFramebuffer fbo;
941 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
942
943 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
944 face++)
945 {
946 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
947
948 // Check that FB is complete.
949 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
950
951 EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
952
953 EXPECT_GL_NO_ERROR();
954 }
955 }
956 }
957
958 // Test that we can successfully copy into incomplete cube maps. Regression test for
959 // http://anglebug.com/3384
TEST_P(CopyTextureTest,IncompleteCubeMap)960 TEST_P(CopyTextureTest, IncompleteCubeMap)
961 {
962 if (!checkExtensions())
963 {
964 return;
965 }
966
967 GLTexture texture2D;
968 GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
969 glBindTexture(GL_TEXTURE_2D, texture2D);
970 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
971
972 GLTexture textureCube;
973 glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
974 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
975 face++)
976 {
977 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
978 }
979
980 // Set one face to 2x2
981 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
982 rgbaPixels);
983
984 // Copy into the incomplete face
985 glCopySubTextureCHROMIUM(texture2D, 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, textureCube, 0, 0, 0, 0,
986 0, 2, 2, false, false, false);
987 EXPECT_GL_NO_ERROR();
988 }
989
990 // Test BGRA to RGBA cube map copy
TEST_P(CopyTextureTest,CubeMapTargetBGRA)991 TEST_P(CopyTextureTest, CubeMapTargetBGRA)
992 {
993 if (!checkExtensions())
994 {
995 return;
996 }
997
998 if (!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
999 {
1000 return;
1001 }
1002
1003 // http://anglebug.com/3145
1004 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1005
1006 GLColor pixels[7] = {
1007 GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
1008 GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
1009 GLColor(70u, 73u, 76u, 79u),
1010 };
1011
1012 GLTexture textures[2];
1013
1014 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1015 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1016 face++)
1017 {
1018 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1019 }
1020
1021 for (size_t i = 0; i < 2; ++i)
1022 {
1023 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1024 face++)
1025 {
1026 glBindTexture(GL_TEXTURE_2D, textures[0]);
1027 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1028 &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1029
1030 glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
1031 false, false);
1032 }
1033
1034 EXPECT_GL_NO_ERROR();
1035
1036 GLFramebuffer fbo;
1037 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1038
1039 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1040 face++)
1041 {
1042 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1043
1044 // Check that FB is complete.
1045 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1046
1047 GLColor converted = pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i];
1048 std::swap(converted.R, converted.B);
1049 EXPECT_PIXEL_COLOR_EQ(0, 0, converted);
1050
1051 EXPECT_GL_NO_ERROR();
1052 }
1053 }
1054 }
1055
1056 // Test cube map copies with RGB format
TEST_P(CopyTextureTest,CubeMapTargetRGB)1057 TEST_P(CopyTextureTest, CubeMapTargetRGB)
1058 {
1059 if (!checkExtensions())
1060 {
1061 return;
1062 }
1063
1064 // http://anglebug.com/1932
1065 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
1066
1067 // http://anglebug.com/3145
1068 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1069
1070 constexpr uint8_t pixels[16 * 7] = {
1071 0u, 3u, 6u, 10u, 13u, 16u, 0, 0, 20u, 23u, 26u, 30u, 33u, 36u, 0, 0, // 2x2
1072 40u, 43u, 46u, 50u, 53u, 56u, 0, 0, 60u, 63u, 66u, 70u, 73u, 76u, 0, 0, // 2x2
1073 80u, 83u, 86u, 90u, 93u, 96u, 0, 0, 100u, 103u, 106u, 110u, 113u, 116u, 0, 0, // 2x2
1074 120u, 123u, 126u, 130u, 133u, 136u, 0, 0, 140u, 143u, 146u, 160u, 163u, 166u, 0, 0, // 2x2
1075 170u, 173u, 176u, 180u, 183u, 186u, 0, 0, 190u, 193u, 196u, 200u, 203u, 206u, 0, 0, // 2x2
1076 210u, 213u, 216u, 220u, 223u, 226u, 0, 0, 230u, 233u, 236u, 240u, 243u, 246u, 0, 0, // 2x2
1077 10u, 50u, 100u, 30u, 80u, 130u, 0, 0, 60u, 110u, 160u, 90u, 140u, 200u, 0, 0, // 2x2
1078 };
1079
1080 GLTexture textures[2];
1081
1082 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1083 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1084 face++)
1085 {
1086 glTexImage2D(face, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1087 }
1088
1089 for (size_t i = 0; i < 2; ++i)
1090 {
1091 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1092 face++)
1093 {
1094 glBindTexture(GL_TEXTURE_2D, textures[0]);
1095 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
1096 &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16]);
1097
1098 glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 2, 2, false,
1099 false, false);
1100 }
1101
1102 EXPECT_GL_NO_ERROR();
1103
1104 GLFramebuffer fbo;
1105 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1106
1107 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1108 face++)
1109 {
1110 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1111
1112 // Check that FB is complete.
1113 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1114
1115 const uint8_t *faceData = &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16];
1116 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(faceData[0], faceData[1], faceData[2], 255));
1117 EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor(faceData[3], faceData[4], faceData[5], 255));
1118 EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor(faceData[8], faceData[9], faceData[10], 255));
1119 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor(faceData[11], faceData[12], faceData[13], 255));
1120
1121 EXPECT_GL_NO_ERROR();
1122 }
1123 }
1124 }
1125
1126 // Test that copying to non-zero mipmaps works
TEST_P(CopyTextureTest,CopyToMipmap)1127 TEST_P(CopyTextureTest, CopyToMipmap)
1128 {
1129 if (!checkExtensions())
1130 {
1131 return;
1132 }
1133
1134 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1135 !IsGLExtensionEnabled("GL_OES_fbo_render_mipmap"));
1136
1137 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel());
1138
1139 GLColor pixels[] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
1140
1141 GLTexture textures[2];
1142
1143 glBindTexture(GL_TEXTURE_2D, textures[0]);
1144 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1145 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1146
1147 glBindTexture(GL_TEXTURE_2D, textures[1]);
1148 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1149 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1150 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1151
1152 std::vector<std::pair<GLint, GLint>> soureDestPairs;
1153 soureDestPairs.push_back(std::make_pair(0, 1));
1154
1155 // ES3 allows copying from non-zero mips
1156 if (getClientMajorVersion() >= 3)
1157 {
1158 soureDestPairs.push_back(std::make_pair(1, 2));
1159 }
1160
1161 for (const auto &sourceDestPair : soureDestPairs)
1162 {
1163 const GLint sourceLevel = sourceDestPair.first;
1164 const GLint destLevel = sourceDestPair.second;
1165
1166 glCopyTextureCHROMIUM(textures[0], sourceLevel, GL_TEXTURE_2D, textures[1], destLevel,
1167 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1168
1169 EXPECT_GL_NO_ERROR();
1170
1171 GLFramebuffer fbo;
1172 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1173 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
1174 destLevel);
1175
1176 // Check that FB is complete.
1177 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1178
1179 EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[0]);
1180
1181 EXPECT_GL_NO_ERROR();
1182 }
1183 }
1184
1185 // Test that copying from an RGBA8 texture to RGBA4 results in exactly 4-bit precision in the result
TEST_P(CopyTextureTest,DownsampleRGBA4444)1186 TEST_P(CopyTextureTest, DownsampleRGBA4444)
1187 {
1188 // Downsampling on copy is only guarenteed on D3D11
1189 ANGLE_SKIP_TEST_IF(!IsD3D11());
1190
1191 GLTexture textures[2];
1192
1193 GLColor pixels[] = {GLColor(0, 5, 6, 7), GLColor(17, 22, 25, 24), GLColor(34, 35, 36, 36),
1194 GLColor(51, 53, 55, 55)};
1195
1196 glBindTexture(GL_TEXTURE_2D, textures[0]);
1197 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1198
1199 glBindTexture(GL_TEXTURE_2D, textures[1]);
1200 glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1201 GL_UNSIGNED_SHORT_4_4_4_4, GL_FALSE, GL_FALSE, GL_FALSE);
1202
1203 GLFramebuffer fbo;
1204 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1205 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1206
1207 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1208 EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(17, 17, 17, 17), 1.0);
1209 EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(34, 34, 34, 34), 1.0);
1210 EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(51, 51, 51, 51), 1.0);
1211
1212 testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, {16, 16, 16, 16});
1213 }
1214
1215 // Test that copying from an RGBA8 texture to RGB565 results in exactly 4-bit precision in the
1216 // result
TEST_P(CopyTextureTest,DownsampleRGB565)1217 TEST_P(CopyTextureTest, DownsampleRGB565)
1218 {
1219 // Downsampling on copy is only guarenteed on D3D11
1220 ANGLE_SKIP_TEST_IF(!IsD3D11());
1221
1222 GLTexture textures[2];
1223
1224 GLColor pixels[] = {GLColor(0, 5, 2, 14), GLColor(17, 22, 25, 30), GLColor(34, 33, 36, 46),
1225 GLColor(50, 54, 49, 60)};
1226
1227 glBindTexture(GL_TEXTURE_2D, textures[0]);
1228 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1229
1230 glBindTexture(GL_TEXTURE_2D, textures[1]);
1231 glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGB,
1232 GL_UNSIGNED_SHORT_5_6_5, GL_FALSE, GL_FALSE, GL_FALSE);
1233
1234 GLFramebuffer fbo;
1235 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1236 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1237
1238 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 4, 0, 255), 1.0);
1239 EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 20, 25, 255), 1.0);
1240 EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 32, 33, 255), 1.0);
1241 EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 53, 49, 255), 1.0);
1242
1243 testGradientDownsampleUniqueValues(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, {32, 64, 32, 1});
1244 }
1245
1246 // Test that copying from an RGBA8 texture to RGBA5551 results in exactly 4-bit precision in the
1247 // result
TEST_P(CopyTextureTest,DownsampleRGBA5551)1248 TEST_P(CopyTextureTest, DownsampleRGBA5551)
1249 {
1250 // Downsampling on copy is only guarenteed on D3D11
1251 ANGLE_SKIP_TEST_IF(!IsD3D11());
1252
1253 GLTexture textures[2];
1254
1255 GLColor pixels[] = {GLColor(0, 1, 2, 3), GLColor(14, 16, 17, 18), GLColor(33, 34, 36, 46),
1256 GLColor(50, 51, 52, 255)};
1257
1258 glBindTexture(GL_TEXTURE_2D, textures[0]);
1259 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1260
1261 glBindTexture(GL_TEXTURE_2D, textures[1]);
1262 glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1263 GL_UNSIGNED_SHORT_5_5_5_1, GL_FALSE, GL_FALSE, GL_FALSE);
1264
1265 GLFramebuffer fbo;
1266 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1267 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1268
1269 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1270 EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 16, 16, 0), 1.0);
1271 EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 33, 33, 0), 1.0);
1272 EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 49, 49, 255), 1.0);
1273
1274 testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, {32, 32, 32, 2});
1275 }
1276
1277 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination
TEST_P(CopyTextureTestDest,Luminance)1278 TEST_P(CopyTextureTestDest, Luminance)
1279 {
1280 if (!checkExtensions())
1281 {
1282 return;
1283 }
1284
1285 GLColor originalPixels(50u, 100u, 150u, 200u);
1286 GLColor expectedPixels(50u, 50u, 50u, 255u);
1287
1288 // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1289 // texture to verify contents.
1290 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1291 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1292 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1293 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1294
1295 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1296 GL_UNSIGNED_BYTE, false, false, false);
1297
1298 EXPECT_GL_NO_ERROR();
1299
1300 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1301 GL_UNSIGNED_BYTE, false, false, false);
1302
1303 EXPECT_GL_NO_ERROR();
1304
1305 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1306 }
1307
1308 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1309 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceMultiply)1310 TEST_P(CopyTextureTestDest, LuminanceMultiply)
1311 {
1312 if (!checkExtensions())
1313 {
1314 return;
1315 }
1316
1317 GLColor originalPixels(50u, 100u, 150u, 200u);
1318 GLColor expectedPixels(39u, 39u, 39u, 255u);
1319
1320 // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1321 // texture to verify contents.
1322 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1323 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1324 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1325 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1326
1327 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1328 GL_UNSIGNED_BYTE, false, true, false);
1329
1330 EXPECT_GL_NO_ERROR();
1331
1332 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1333 GL_UNSIGNED_BYTE, false, false, false);
1334
1335 EXPECT_GL_NO_ERROR();
1336
1337 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1338 }
1339
1340 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1341 // UnpackUnmultiply parameter
TEST_P(CopyTextureTestDest,LuminanceUnmultiply)1342 TEST_P(CopyTextureTestDest, LuminanceUnmultiply)
1343 {
1344 if (!checkExtensions())
1345 {
1346 return;
1347 }
1348
1349 GLColor originalPixels(50u, 100u, 150u, 200u);
1350 GLColor expectedPixels(64u, 64u, 64u, 255u);
1351
1352 // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1353 // texture to verify contents.
1354 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1355 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1356 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1357 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1358
1359 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1360 GL_UNSIGNED_BYTE, false, false, true);
1361
1362 EXPECT_GL_NO_ERROR();
1363
1364 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1365 GL_UNSIGNED_BYTE, false, false, false);
1366
1367 EXPECT_GL_NO_ERROR();
1368
1369 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1370 }
1371
1372 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination
TEST_P(CopyTextureTestDest,LuminanceAlpha)1373 TEST_P(CopyTextureTestDest, LuminanceAlpha)
1374 {
1375 if (!checkExtensions())
1376 {
1377 return;
1378 }
1379
1380 GLColor originalPixels(50u, 100u, 150u, 200u);
1381 GLColor expectedPixels(50u, 50u, 50u, 200u);
1382
1383 // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1384 // RGBA texture to verify contents.
1385 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1386 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1387 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1388 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1389 GL_UNSIGNED_BYTE, nullptr);
1390
1391 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1392 GL_UNSIGNED_BYTE, false, false, false);
1393
1394 EXPECT_GL_NO_ERROR();
1395
1396 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1397 GL_UNSIGNED_BYTE, false, false, false);
1398
1399 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1400 }
1401
1402 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1403 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaMultiply)1404 TEST_P(CopyTextureTestDest, LuminanceAlphaMultiply)
1405 {
1406 if (!checkExtensions())
1407 {
1408 return;
1409 }
1410
1411 GLColor originalPixels(50u, 100u, 150u, 200u);
1412 GLColor expectedPixels(39u, 39u, 39u, 200u);
1413
1414 // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1415 // RGBA texture to verify contents.
1416 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1417 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1418 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1419 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1420 GL_UNSIGNED_BYTE, nullptr);
1421
1422 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1423 GL_UNSIGNED_BYTE, false, true, false);
1424
1425 EXPECT_GL_NO_ERROR();
1426
1427 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1428 GL_UNSIGNED_BYTE, false, false, false);
1429
1430 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1431 }
1432
1433 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1434 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaUnmultiply)1435 TEST_P(CopyTextureTestDest, LuminanceAlphaUnmultiply)
1436 {
1437 if (!checkExtensions())
1438 {
1439 return;
1440 }
1441
1442 GLColor originalPixels(50u, 100u, 150u, 200u);
1443 GLColor expectedPixels(64u, 64u, 64u, 200u);
1444
1445 // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1446 // RGBA texture to verify contents.
1447 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1448 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1449 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1450 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1451 GL_UNSIGNED_BYTE, nullptr);
1452
1453 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1454 GL_UNSIGNED_BYTE, false, false, true);
1455
1456 EXPECT_GL_NO_ERROR();
1457
1458 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1459 GL_UNSIGNED_BYTE, false, false, false);
1460
1461 EXPECT_GL_NO_ERROR();
1462
1463 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1464 }
1465
1466 // Test to ensure that CopyTexture works with ALPHA texture as a destination
TEST_P(CopyTextureTestDest,Alpha)1467 TEST_P(CopyTextureTestDest, Alpha)
1468 {
1469 if (!checkExtensions())
1470 {
1471 return;
1472 }
1473
1474 GLColor originalPixels(50u, 100u, 150u, 155u);
1475 GLColor expectedPixels(0u, 0u, 0u, 155u);
1476
1477 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1478 // texture to verify contents.
1479 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1480 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1481 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1482 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1483
1484 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1485 GL_UNSIGNED_BYTE, false, false, false);
1486
1487 EXPECT_GL_NO_ERROR();
1488
1489 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1490 GL_UNSIGNED_BYTE, false, false, false);
1491
1492 EXPECT_GL_NO_ERROR();
1493
1494 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1495 }
1496
1497 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1498 // UnpackPremultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaMultiply)1499 TEST_P(CopyTextureTestDest, AlphaMultiply)
1500 {
1501 if (!checkExtensions())
1502 {
1503 return;
1504 }
1505
1506 GLColor originalPixels(50u, 100u, 150u, 155u);
1507 GLColor expectedPixels(0u, 0u, 0u, 155u);
1508
1509 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1510 // texture to verify contents.
1511 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1512 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1513 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1514 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1515
1516 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1517 GL_UNSIGNED_BYTE, false, true, false);
1518
1519 EXPECT_GL_NO_ERROR();
1520
1521 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1522 GL_UNSIGNED_BYTE, false, false, false);
1523
1524 EXPECT_GL_NO_ERROR();
1525
1526 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1527 }
1528
1529 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1530 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaUnmultiply)1531 TEST_P(CopyTextureTestDest, AlphaUnmultiply)
1532 {
1533 if (!checkExtensions())
1534 {
1535 return;
1536 }
1537
1538 GLColor originalPixels(50u, 100u, 150u, 155u);
1539 GLColor expectedPixels(0u, 0u, 0u, 155u);
1540
1541 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1542 // texture to verify contents.
1543 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1544 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1545 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1546 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1547
1548 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1549 GL_UNSIGNED_BYTE, false, false, true);
1550
1551 EXPECT_GL_NO_ERROR();
1552
1553 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1554 GL_UNSIGNED_BYTE, false, false, false);
1555
1556 EXPECT_GL_NO_ERROR();
1557
1558 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1559 }
1560
1561 // Test to ensure that CopyTexture uses the correct ALPHA passthrough shader to ensure RGB channels
1562 // are set to 0.
TEST_P(CopyTextureTestDest,AlphaCopyWithRGB)1563 TEST_P(CopyTextureTestDest, AlphaCopyWithRGB)
1564 {
1565 // http://anglebug.com/4121
1566 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
1567 ANGLE_SKIP_TEST_IF(!checkExtensions());
1568
1569 GLColor originalPixels(50u, 100u, 150u, 155u);
1570 GLColor expectedPixels(0u, 0u, 0u, 155u);
1571
1572 // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1573 // texture to verify contents.
1574 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1575 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1576 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1577 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_HALF_FLOAT_OES, nullptr);
1578
1579 glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1580 GL_HALF_FLOAT_OES, false, false, false);
1581
1582 EXPECT_GL_NO_ERROR();
1583
1584 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1585 GL_UNSIGNED_BYTE, false, false, false);
1586
1587 EXPECT_GL_NO_ERROR();
1588
1589 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1590 }
1591
1592 // Bug where TEXTURE_SWIZZLE_RGBA was not reset after the Luminance workaround. (crbug.com/1022080)
TEST_P(CopyTextureTestES3,LuminanceWorkaroundTextureSwizzleBug)1593 TEST_P(CopyTextureTestES3, LuminanceWorkaroundTextureSwizzleBug)
1594 {
1595
1596 {
1597 GLColor pixels(50u, 20u, 100u, 150u);
1598
1599 // Hit BlitGL::copySubImageToLUMAWorkaroundTexture by copying an ALPHA texture
1600 GLTexture srcTexture;
1601 glBindTexture(GL_TEXTURE_2D, srcTexture);
1602 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
1603
1604 GLFramebuffer srcFBO;
1605 glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
1606 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
1607
1608 GLTexture dstTexture;
1609 glBindTexture(GL_TEXTURE_2D, dstTexture);
1610 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1611
1612 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
1613 EXPECT_GL_NO_ERROR();
1614 }
1615
1616 {
1617 // This time hit BlitGL::blitColorBufferWithShader by copying an SRGB texture
1618 GLColor pixels(100u, 200u, 50u, 210u);
1619
1620 GLTexture srcTexture;
1621 glBindTexture(GL_TEXTURE_2D, srcTexture);
1622 glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1623 GL_UNSIGNED_BYTE, &pixels);
1624
1625 GLFramebuffer srcFBO;
1626 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
1627 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture,
1628 0);
1629
1630 GLTexture dstTexture;
1631 glBindTexture(GL_TEXTURE_2D, dstTexture);
1632 glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1633 GL_UNSIGNED_BYTE, nullptr);
1634
1635 GLFramebuffer dstFBO;
1636 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
1637 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture,
1638 0);
1639
1640 glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1641
1642 // The previous workaround should not affect this copy
1643 glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
1644 EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
1645 }
1646 }
1647
1648 // Test to ensure that CopyTexture will fail with a non-zero level and NPOT texture in WebGL
TEST_P(CopyTextureTestWebGL,NPOT)1649 TEST_P(CopyTextureTestWebGL, NPOT)
1650 {
1651 if (IsGLExtensionRequestable("GL_CHROMIUM_copy_texture"))
1652 {
1653 glRequestExtensionANGLE("GL_CHROMIUM_copy_texture");
1654 }
1655 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
1656
1657 std::vector<GLColor> pixelData(10 * 10, GLColor::red);
1658
1659 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1660 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
1661
1662 // Do a basic copy to make sure things work
1663 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1664 GL_UNSIGNED_BYTE, false, false, false);
1665
1666 EXPECT_GL_NO_ERROR();
1667
1668 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1669
1670 // Do the same operation with destLevel 1, which should fail
1671 glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 1, GL_RGBA,
1672 GL_UNSIGNED_BYTE, false, false, false);
1673
1674 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1675 }
1676
1677 // Test the newly added ES3 unorm formats
TEST_P(CopyTextureTestES3,ES3UnormFormats)1678 TEST_P(CopyTextureTestES3, ES3UnormFormats)
1679 {
1680 if (!checkExtensions())
1681 {
1682 return;
1683 }
1684 // http://anglebug.com/4092
1685 ANGLE_SKIP_TEST_IF(IsAndroid());
1686
1687 auto testOutput = [this](GLuint texture, const GLColor &expectedColor) {
1688 constexpr char kVS[] =
1689 "#version 300 es\n"
1690 "in vec4 position;\n"
1691 "out vec2 texcoord;\n"
1692 "void main()\n"
1693 "{\n"
1694 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1695 " texcoord = (position.xy * 0.5) + 0.5;\n"
1696 "}\n";
1697
1698 constexpr char kFS[] =
1699 "#version 300 es\n"
1700 "precision mediump float;\n"
1701 "uniform sampler2D tex;\n"
1702 "in vec2 texcoord;\n"
1703 "out vec4 color;\n"
1704 "void main()\n"
1705 "{\n"
1706 " color = texture(tex, texcoord);\n"
1707 "}\n";
1708
1709 ANGLE_GL_PROGRAM(program, kVS, kFS);
1710 glUseProgram(program);
1711
1712 GLRenderbuffer rbo;
1713 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1714 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
1715
1716 GLFramebuffer fbo;
1717 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1718 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1719
1720 glActiveTexture(GL_TEXTURE0);
1721 glBindTexture(GL_TEXTURE_2D, texture);
1722 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1723 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1724 glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1725
1726 drawQuad(program, "position", 0.5f, 1.0f, true);
1727
1728 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
1729 };
1730
1731 auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1732 GLenum sourceType, const GLColor &sourceColor,
1733 GLenum destInternalFormat, GLenum destType, bool flipY,
1734 bool premultiplyAlpha, bool unmultiplyAlpha,
1735 const GLColor &expectedColor) {
1736 GLTexture sourceTexture;
1737 glBindTexture(GL_TEXTURE_2D, sourceTexture);
1738 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1739 &sourceColor);
1740
1741 GLTexture destTexture;
1742 glBindTexture(GL_TEXTURE_2D, destTexture);
1743
1744 glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1745 destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1746 ASSERT_GL_NO_ERROR();
1747
1748 testOutput(destTexture, expectedColor);
1749 };
1750
1751 auto testSubCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1752 GLenum sourceType, const GLColor &sourceColor,
1753 GLenum destInternalFormat, GLenum destFormat,
1754 GLenum destType, bool flipY, bool premultiplyAlpha,
1755 bool unmultiplyAlpha, const GLColor &expectedColor) {
1756 GLTexture sourceTexture;
1757 glBindTexture(GL_TEXTURE_2D, sourceTexture);
1758 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1759 &sourceColor);
1760
1761 GLTexture destTexture;
1762 glBindTexture(GL_TEXTURE_2D, destTexture);
1763
1764 glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
1765 glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
1766 flipY, premultiplyAlpha, unmultiplyAlpha);
1767 ASSERT_GL_NO_ERROR();
1768
1769 testOutput(destTexture, expectedColor);
1770 };
1771
1772 // New LUMA source formats
1773 testCopyCombination(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGB,
1774 GL_UNSIGNED_BYTE, false, false, false, GLColor(128, 128, 128, 255));
1775 testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1776 GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, false,
1777 GLColor(128, 128, 128, 255));
1778 testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1779 GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, true, false,
1780 GLColor(32, 32, 32, 255));
1781 testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1782 GLColor(128, 128, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, true,
1783 GLColor(255, 255, 255, 255));
1784 testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1785 GL_UNSIGNED_BYTE, false, false, false, GLColor(0, 0, 0, 128));
1786 testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1787 GL_UNSIGNED_BYTE, false, false, true, 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, true, false, GLColor(0, 0, 0, 128));
1790
1791 // New sRGB dest formats
1792 if (IsGLExtensionEnabled("GL_EXT_sRGB"))
1793 {
1794 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1795 GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
1796 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1797 GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
1798 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1799 GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
1800 GLColor(55, 13, 4, 128));
1801
1802 testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1803 GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, false, false,
1804 GLColor(55, 13, 4, 255));
1805 testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1806 GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, true, false,
1807 GLColor(13, 4, 1, 255));
1808 testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1809 GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
1810 false, GLColor(55, 13, 4, 128));
1811 }
1812 }
1813
1814 // Test the newly added ES3 float formats
TEST_P(CopyTextureTestES3,ES3FloatFormats)1815 TEST_P(CopyTextureTestES3, ES3FloatFormats)
1816 {
1817 if (!checkExtensions())
1818 {
1819 return;
1820 }
1821
1822 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
1823
1824 auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
1825 constexpr char kVS[] =
1826 "#version 300 es\n"
1827 "in vec4 position;\n"
1828 "out vec2 texcoord;\n"
1829 "void main()\n"
1830 "{\n"
1831 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1832 " texcoord = (position.xy * 0.5) + 0.5;\n"
1833 "}\n";
1834
1835 constexpr char kFS[] =
1836 "#version 300 es\n"
1837 "precision mediump float;\n"
1838 "uniform sampler2D tex;\n"
1839 "in vec2 texcoord;\n"
1840 "out vec4 color;\n"
1841 "void main()\n"
1842 "{\n"
1843 " color = texture(tex, texcoord);\n"
1844 "}\n";
1845
1846 ANGLE_GL_PROGRAM(program, kVS, kFS);
1847 glUseProgram(program);
1848
1849 GLRenderbuffer rbo;
1850 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1851 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1852
1853 GLFramebuffer fbo;
1854 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1855 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1856
1857 glActiveTexture(GL_TEXTURE0);
1858 glBindTexture(GL_TEXTURE_2D, texture);
1859 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1860 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1861 glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1862
1863 drawQuad(program, "position", 0.5f, 1.0f, true);
1864
1865 EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
1866 };
1867
1868 auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1869 GLenum sourceType, const GLColor &sourceColor,
1870 GLenum destInternalFormat, GLenum destType, bool flipY,
1871 bool premultiplyAlpha, bool unmultiplyAlpha,
1872 const GLColor32F &expectedColor) {
1873 GLTexture sourceTexture;
1874 glBindTexture(GL_TEXTURE_2D, sourceTexture);
1875 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1876 &sourceColor);
1877
1878 GLTexture destTexture;
1879 glBindTexture(GL_TEXTURE_2D, destTexture);
1880
1881 glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1882 destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1883 ASSERT_GL_NO_ERROR();
1884
1885 testOutput(destTexture, expectedColor);
1886 };
1887
1888 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1889 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 0.5f));
1890 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1891 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 0.5f));
1892 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1893 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 0.5f));
1894
1895 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1896 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.0f, 0.0f, 1.0f));
1897 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1898 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.0f, 0.0f, 1.0f));
1899 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1900 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.0f, 0.0f, 1.0f));
1901
1902 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1903 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.0f, 1.0f));
1904 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1905 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0f, 1.0f));
1906 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1907 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.0f, 1.0f));
1908
1909 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1910 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1911 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1912 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1913 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1914 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1915
1916 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1917 GL_R11F_G11F_B10F, GL_FLOAT, false, false, false,
1918 GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1919 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1920 GL_R11F_G11F_B10F, GL_FLOAT, false, true, false,
1921 GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1922 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1923 GL_R11F_G11F_B10F, GL_FLOAT, false, false, true,
1924 GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1925
1926 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1927 GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1928 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1929 GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1930 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1931 GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1932 }
1933
1934 // Test the newly added ES3 unsigned integer formats
TEST_P(CopyTextureTestES3,ES3UintFormats)1935 TEST_P(CopyTextureTestES3, ES3UintFormats)
1936 {
1937 ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsIntel());
1938
1939 if (!checkExtensions())
1940 {
1941 return;
1942 }
1943
1944 using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
1945
1946 auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
1947 constexpr char kVS[] =
1948 "#version 300 es\n"
1949 "in vec4 position;\n"
1950 "out vec2 texcoord;\n"
1951 "void main()\n"
1952 "{\n"
1953 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1954 " texcoord = (position.xy * 0.5) + 0.5;\n"
1955 "}\n";
1956
1957 constexpr char kFS[] =
1958 "#version 300 es\n"
1959 "precision mediump float;\n"
1960 "precision mediump usampler2D;\n"
1961 "in vec2 texcoord;\n"
1962 "uniform usampler2D tex;\n"
1963 "out uvec4 color;\n"
1964 "void main()\n"
1965 "{\n"
1966 " color = texture(tex, texcoord);\n"
1967 "}\n";
1968
1969 ANGLE_GL_PROGRAM(program, kVS, kFS);
1970 glUseProgram(program);
1971
1972 GLRenderbuffer rbo;
1973 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1974 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8UI, 1, 1);
1975
1976 GLFramebuffer fbo;
1977 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1978 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1979
1980 glActiveTexture(GL_TEXTURE0);
1981 glBindTexture(GL_TEXTURE_2D, texture);
1982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1984 glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1985
1986 drawQuad(program, "position", 0.5f, 1.0f, true);
1987 ASSERT_GL_NO_ERROR();
1988
1989 GLuint pixel[4] = {0};
1990 glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixel);
1991 ASSERT_GL_NO_ERROR();
1992 EXPECT_NEAR(std::get<0>(expectedColor), pixel[0], 1);
1993 EXPECT_NEAR(std::get<1>(expectedColor), pixel[1], 1);
1994 EXPECT_NEAR(std::get<2>(expectedColor), pixel[2], 1);
1995 EXPECT_NEAR(std::get<3>(expectedColor), pixel[3], 1);
1996 };
1997
1998 auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1999 GLenum sourceType, const GLColor &sourceColor,
2000 GLenum destInternalFormat, GLenum destType, bool flipY,
2001 bool premultiplyAlpha, bool unmultiplyAlpha,
2002 const GLColor32U &expectedColor) {
2003 GLTexture sourceTexture;
2004 glBindTexture(GL_TEXTURE_2D, sourceTexture);
2005 glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2006 &sourceColor);
2007
2008 GLTexture destTexture;
2009 glBindTexture(GL_TEXTURE_2D, destTexture);
2010
2011 glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2012 destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2013 ASSERT_GL_NO_ERROR();
2014
2015 testOutput(destTexture, expectedColor);
2016 };
2017
2018 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2019 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 128));
2020 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2021 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 128));
2022 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2023 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 128));
2024
2025 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2026 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 1));
2027 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2028 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 1));
2029 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2030 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 1));
2031
2032 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2033 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 0, 1));
2034 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2035 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 0, 1));
2036 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2037 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 0, 1));
2038
2039 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2040 GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 0, 0, 1));
2041 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2042 GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 0, 0, 1));
2043 testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(120, 64, 32, 128), GL_R8UI,
2044 GL_UNSIGNED_BYTE, false, false, true, GLColor32U(240, 0, 0, 1));
2045 }
2046
2047 // Test that using an offset in CopySubTexture works correctly for non-renderable float targets
TEST_P(CopyTextureTestES3,CopySubTextureOffsetNonRenderableFloat)2048 TEST_P(CopyTextureTestES3, CopySubTextureOffsetNonRenderableFloat)
2049 {
2050 if (!checkExtensions())
2051 {
2052 return;
2053 }
2054
2055 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
2056
2057 auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
2058 constexpr char kVS[] =
2059 "#version 300 es\n"
2060 "in vec4 position;\n"
2061 "out vec2 texcoord;\n"
2062 "void main()\n"
2063 "{\n"
2064 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2065 " texcoord = (position.xy * 0.5) + 0.5;\n"
2066 "}\n";
2067
2068 constexpr char kFS[] =
2069 "#version 300 es\n"
2070 "precision mediump float;\n"
2071 "uniform sampler2D tex;\n"
2072 "in vec2 texcoord;\n"
2073 "out vec4 color;\n"
2074 "void main()\n"
2075 "{\n"
2076 " color = texture(tex, texcoord);\n"
2077 "}\n";
2078
2079 ANGLE_GL_PROGRAM(program, kVS, kFS);
2080 glUseProgram(program);
2081
2082 GLRenderbuffer rbo;
2083 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2084 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
2085
2086 GLFramebuffer fbo;
2087 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2088 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2089
2090 glActiveTexture(GL_TEXTURE0);
2091 glBindTexture(GL_TEXTURE_2D, texture);
2092 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2093 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2094 glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
2095
2096 drawQuad(program, "position", 0.5f, 1.0f, true);
2097
2098 EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
2099 };
2100
2101 auto testCopy = [this, testOutput](GLenum destInternalFormat, GLenum destFormat,
2102 GLenum destType) {
2103 GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
2104 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
2105 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
2106
2107 GLTexture destTexture;
2108 glBindTexture(GL_TEXTURE_2D, destTexture);
2109 glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
2110
2111 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
2112 false, false, false);
2113 EXPECT_GL_NO_ERROR();
2114 testOutput(destTexture, kFloatRed);
2115
2116 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 0, 1, 1,
2117 false, false, false);
2118 EXPECT_GL_NO_ERROR();
2119 testOutput(destTexture, kFloatGreen);
2120
2121 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 1, 1, 1,
2122 false, false, false);
2123 EXPECT_GL_NO_ERROR();
2124 testOutput(destTexture, kFloatBlue);
2125
2126 glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 1, 1, 1,
2127 false, false, false);
2128 EXPECT_GL_NO_ERROR();
2129 testOutput(destTexture, kFloatBlack);
2130 };
2131
2132 testCopy(GL_RGB9_E5, GL_RGB, GL_FLOAT);
2133 }
2134
2135 #ifdef Bool
2136 // X11 craziness.
2137 # undef Bool
2138 #endif
2139
2140 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
2141 // tests should be run against.
2142 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTest);
2143 ANGLE_INSTANTIATE_TEST_COMBINE_5(CopyTextureVariationsTest,
2144 CopyTextureVariationsTestPrint,
2145 testing::ValuesIn(kCopyTextureVariationsSrcFormats),
2146 testing::ValuesIn(kCopyTextureVariationsDstFormats),
2147 testing::Bool(), // flipY
2148 testing::Bool(), // premultiplyAlpha
2149 testing::Bool(), // unmultiplyAlpha
2150 ES2_D3D9(),
2151 ES2_D3D11(),
2152 ES2_OPENGL(),
2153 ES2_OPENGLES(),
2154 ES2_VULKAN());
2155 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTestWebGL);
2156 ANGLE_INSTANTIATE_TEST(CopyTextureTestDest,
2157 ES2_D3D11(),
2158 ES2_OPENGL(),
2159 ES2_OPENGLES(),
2160 ES2_VULKAN());
2161 ANGLE_INSTANTIATE_TEST_ES3(CopyTextureTestES3);
2162
2163 } // namespace angle
2164