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