1 //
2 // Copyright 2018 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 // CopyTexture3DTest.cpp: Tests of the GL_ANGLE_copy_texture_3d extension
8
9 #include "test_utils/ANGLETest.h"
10
11 #include "test_utils/gl_raii.h"
12
13 namespace angle
14 {
15
16 class CopyTexture3DTest : public ANGLETest<>
17 {
18 protected:
CopyTexture3DTest()19 CopyTexture3DTest()
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 const char *vertexShaderSource = getVertexShaderSource();
32 const char *fragmentShaderSource = getFragmentShaderSource();
33
34 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
35 ASSERT_NE(0u, mProgram);
36
37 glUseProgram(mProgram);
38
39 ASSERT_GL_NO_ERROR();
40 }
41
getVertexShaderSource()42 const char *getVertexShaderSource()
43 {
44 return "#version 300 es\n"
45 "out vec3 texcoord;\n"
46 "in vec4 position;\n"
47 "void main()\n"
48 "{\n"
49 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
50 " texcoord = (position.xyz * 0.5) + 0.5;\n"
51 "}\n";
52 }
53
checkExtensions() const54 bool checkExtensions() const
55 {
56 if (!IsGLExtensionEnabled("GL_ANGLE_copy_texture_3d"))
57 {
58 std::cout << "Test skipped because GL_ANGLE_copy_texture_3d is not available."
59 << std::endl;
60 return false;
61 }
62
63 EXPECT_NE(nullptr, glCopyTexture3DANGLE);
64 EXPECT_NE(nullptr, glCopySubTexture3DANGLE);
65 return true;
66 }
67
testCopy(const GLenum testTarget,const GLColor & sourceColor,GLenum destInternalFormat,GLenum destType,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha,const GLColor & expectedColor)68 void testCopy(const GLenum testTarget,
69 const GLColor &sourceColor,
70 GLenum destInternalFormat,
71 GLenum destType,
72 bool flipY,
73 bool premultiplyAlpha,
74 bool unmultiplyAlpha,
75 const GLColor &expectedColor)
76 {
77 std::vector<GLColor> texDataColor(2u * 2u * 2u, sourceColor);
78
79 glBindTexture(testTarget, sourceTexture);
80 glTexImage3D(testTarget, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
81 texDataColor.data());
82 glTexParameteri(testTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
83 glTexParameteri(testTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
84 glTexParameteri(testTarget, GL_TEXTURE_BASE_LEVEL, 0);
85 glTexParameteri(testTarget, GL_TEXTURE_MAX_LEVEL, 0);
86 EXPECT_GL_NO_ERROR();
87
88 glActiveTexture(GL_TEXTURE0);
89 glBindTexture(testTarget, destTexture);
90 glCopyTexture3DANGLE(sourceTexture, 0, testTarget, destTexture, 0, destInternalFormat,
91 destType, flipY, premultiplyAlpha, unmultiplyAlpha);
92 EXPECT_GL_NO_ERROR();
93
94 GLRenderbuffer rbo;
95 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
96
97 GLenum renderType = 0;
98
99 switch (destInternalFormat)
100 {
101 case GL_RGB:
102 case GL_RGBA:
103 case GL_LUMINANCE:
104 case GL_LUMINANCE_ALPHA:
105 case GL_ALPHA:
106 case GL_R8:
107 case GL_RG:
108 case GL_RG8:
109 case GL_RGB8:
110 case GL_RGBA8:
111 case GL_RGBX8_ANGLE:
112 case GL_SRGB8:
113 case GL_RGB565:
114 case GL_SRGB8_ALPHA8:
115 case GL_RGB5_A1:
116 case GL_RGBA4:
117 case GL_R8_SNORM:
118 case GL_RG8_SNORM:
119 case GL_RGB8_SNORM:
120 case GL_RGBA8_SNORM:
121 case GL_RGB10_A2:
122 renderType = GL_RGBA8;
123 break;
124 case GL_R8I:
125 case GL_R16I:
126 case GL_R32I:
127 case GL_RG8I:
128 case GL_RG16I:
129 case GL_RG32I:
130 case GL_RGB8I:
131 case GL_RGB16I:
132 case GL_RGB32I:
133 case GL_RGBA8I:
134 case GL_RGBA16I:
135 case GL_RGBA32I:
136 renderType = GL_RGBA8I;
137 break;
138 case GL_R8UI:
139 case GL_R16UI:
140 case GL_R32UI:
141 case GL_RG8UI:
142 case GL_RG16UI:
143 case GL_RG32UI:
144 case GL_RGB8UI:
145 case GL_RGB16UI:
146 case GL_RGB32UI:
147 case GL_RGBA8UI:
148 case GL_RGBA16UI:
149 case GL_RGBA32UI:
150 case GL_RGB10_A2UI:
151 renderType = GL_RGBA8UI;
152 break;
153 case GL_R16F:
154 case GL_RGB16F:
155 case GL_RGB32F:
156 case GL_R32F:
157 case GL_RG16F:
158 case GL_RG32F:
159 case GL_RGBA16F:
160 case GL_RGBA32F:
161 case GL_R11F_G11F_B10F:
162 case GL_RGB9_E5:
163 renderType = GL_RGBA32F;
164 break;
165 default:
166 ASSERT_TRUE(false);
167 }
168
169 glRenderbufferStorage(GL_RENDERBUFFER, renderType, 1, 1);
170
171 GLFramebuffer fbo;
172 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
173 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
174
175 glTexParameteri(testTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
176 glTexParameteri(testTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
177 glTexParameteri(testTarget, GL_TEXTURE_BASE_LEVEL, 0);
178 glTexParameteri(testTarget, GL_TEXTURE_MAX_LEVEL, 0);
179
180 drawQuad(mProgram, "position", 0.5f);
181 EXPECT_GL_NO_ERROR();
182
183 if (renderType == GL_RGBA8)
184 {
185 uint32_t tolerance = 1;
186 // The destination formats may be emulated, so the precision may be higher than
187 // required. Increase the tolerance to 2^(8-width). 8 is for the 8-bit format used for
188 // emulation. Even though Vulkan recommends round to nearest, it's not a requirement
189 // so the full-range of precision is used as tolerance.
190 switch (destType)
191 {
192 case GL_UNSIGNED_SHORT_5_6_5:
193 tolerance = 8;
194 break;
195 case GL_UNSIGNED_SHORT_5_5_5_1:
196 tolerance = 8;
197 break;
198 case GL_UNSIGNED_SHORT_4_4_4_4:
199 tolerance = 16;
200 break;
201 default:
202 break;
203 }
204 switch (destInternalFormat)
205 {
206 case GL_RGB565:
207 tolerance = 8;
208 break;
209 case GL_RGB5_A1:
210 tolerance = 8;
211 break;
212 case GL_RGBA4:
213 tolerance = 16;
214 break;
215 default:
216 break;
217 }
218
219 // If destination is SNORM, values in between representable values could round either
220 // way.
221 switch (destInternalFormat)
222 {
223 case GL_R8_SNORM:
224 case GL_RG8_SNORM:
225 case GL_RGB8_SNORM:
226 case GL_RGBA8_SNORM:
227 tolerance *= 2;
228 break;
229 default:
230 break;
231 }
232
233 GLColor actual;
234 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
235 EXPECT_GL_NO_ERROR();
236 EXPECT_COLOR_NEAR(expectedColor, actual, tolerance);
237 return;
238 }
239 else if (renderType == GL_RGBA32F)
240 {
241 float expectedColorFloat[4] = {static_cast<float>(expectedColor.R) / 255,
242 static_cast<float>(expectedColor.G) / 255,
243 static_cast<float>(expectedColor.B) / 255,
244 static_cast<float>(expectedColor.A) / 255};
245 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
246 GLColor32F(expectedColorFloat[0], expectedColorFloat[1],
247 expectedColorFloat[2], expectedColorFloat[3]),
248 0.015);
249 return;
250 }
251 else if (renderType == GL_RGBA8UI)
252 {
253 GLuint pixel[4] = {0};
254 glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixel);
255 EXPECT_COLOR_NEAR(
256 expectedColor,
257 GLColor(static_cast<GLubyte>(pixel[0]), static_cast<GLubyte>(pixel[1]),
258 static_cast<GLubyte>(pixel[2]), static_cast<GLubyte>(pixel[3])),
259 0.2);
260 }
261 else if (renderType == GL_RGBA8I)
262 {
263 GLint pixel[4] = {0};
264 glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, pixel);
265 EXPECT_COLOR_NEAR(
266 expectedColor,
267 GLColor(static_cast<GLubyte>(pixel[0]), static_cast<GLubyte>(pixel[1]),
268 static_cast<GLubyte>(pixel[2]), static_cast<GLubyte>(pixel[3])),
269 0.2);
270 }
271 else
272 {
273 ASSERT_TRUE(false);
274 }
275 }
276
277 void testUnsizedFormats(const GLenum testTarget);
278 void testSnormFormats(const GLenum testTarget);
279 void testUnsignedByteFormats(const GLenum testTarget);
280 void testFloatFormats(const GLenum testTarget);
281 void testIntFormats(const GLenum testTarget);
282 void testUintFormats(const GLenum testTarget);
283
284 virtual const char *getFragmentShaderSource() = 0;
285
286 GLuint mProgram = 0;
287 GLTexture sourceTexture;
288 GLTexture destTexture;
289 };
290
291 class Texture3DCopy : public CopyTexture3DTest
292 {
293 protected:
Texture3DCopy()294 Texture3DCopy() {}
295
getFragmentShaderSource()296 const char *getFragmentShaderSource() override
297 {
298 return "#version 300 es\n"
299 "precision highp float;\n"
300 "uniform highp sampler3D tex3D;\n"
301 "in vec3 texcoord;\n"
302 "out vec4 fragColor;\n"
303 "void main()\n"
304 "{\n"
305 " fragColor = texture(tex3D, vec3(texcoord.x, texcoord.z, texcoord.y));\n"
306 "}\n";
307 }
308 };
309
310 class Texture2DArrayCopy : public CopyTexture3DTest
311 {
312 protected:
Texture2DArrayCopy()313 Texture2DArrayCopy() {}
314
getFragmentShaderSource()315 const char *getFragmentShaderSource() override
316 {
317 return "#version 300 es\n"
318 "precision highp float;\n"
319 "uniform highp sampler2DArray tex2DArray;\n"
320 "in vec3 texcoord;\n"
321 "out vec4 fragColor;\n"
322 "void main()\n"
323 "{\n"
324 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.z, texcoord.y));\n"
325 "}\n";
326 }
327 };
328
329 // Test that glCopySubTexture3DANGLE correctly copies to and from a GL_TEXTURE_3D texture.
TEST_P(Texture3DCopy,CopySubTexture)330 TEST_P(Texture3DCopy, CopySubTexture)
331 {
332 ANGLE_SKIP_TEST_IF(!checkExtensions());
333
334 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
335 std::vector<GLColor> texDataRed(2u * 2u * 2u, GLColor::red);
336
337 glBindTexture(GL_TEXTURE_3D, sourceTexture);
338 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
339 texDataGreen.data());
340 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
341 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
342 EXPECT_GL_NO_ERROR();
343
344 glActiveTexture(GL_TEXTURE0);
345 glBindTexture(GL_TEXTURE_3D, destTexture);
346 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
347 texDataRed.data());
348 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
349 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
350 EXPECT_GL_NO_ERROR();
351 glCopySubTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_3D, destTexture, 0, 0, 0, 0, 0, 0, 0, 2, 2,
352 2, false, false, false);
353 glBindTexture(GL_TEXTURE_3D, destTexture);
354 EXPECT_GL_NO_ERROR();
355 drawQuad(mProgram, "position", 0.5f);
356
357 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
358 }
359
360 // Test that glCopyTexture3DANGLE correctly copies from a non-zero mipmap on a GL_TEXTURE_3D
361 // texture.
TEST_P(Texture3DCopy,CopyFromMipmap)362 TEST_P(Texture3DCopy, CopyFromMipmap)
363 {
364 ANGLE_SKIP_TEST_IF(!checkExtensions());
365
366 std::vector<GLColor> texDataGreen(4u * 4u * 4u, GLColor::green);
367
368 glBindTexture(GL_TEXTURE_3D, sourceTexture);
369 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
370 texDataGreen.data());
371 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
372 texDataGreen.data());
373 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
374 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
375 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
376 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
377
378 EXPECT_GL_NO_ERROR();
379
380 glActiveTexture(GL_TEXTURE0);
381 glBindTexture(GL_TEXTURE_3D, destTexture);
382 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
383 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
384 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
385 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
386 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
387 EXPECT_GL_NO_ERROR();
388
389 glCopyTexture3DANGLE(sourceTexture, 1, GL_TEXTURE_3D, destTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE,
390 false, false, false);
391 glBindTexture(GL_TEXTURE_3D, destTexture);
392 EXPECT_GL_NO_ERROR();
393 drawQuad(mProgram, "position", 0.5f);
394
395 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
396 }
397
398 // Test that glCopySubTexture3DANGLE's offset and dimension parameters work correctly with a
399 // GL_TEXTURE_3D texture.
TEST_P(Texture3DCopy,OffsetSubCopy)400 TEST_P(Texture3DCopy, OffsetSubCopy)
401 {
402 ANGLE_SKIP_TEST_IF(!checkExtensions());
403
404 GLColor rgbaPixels[27];
405
406 // Create pixel data for a 3x3x3 red cube
407 for (int i = 0; i < 27; i++)
408 {
409 rgbaPixels[i] = GLColor(255u, 0u, 0u, 255u);
410 }
411
412 // Change a pixel to create a 1x1x1 blue cube at (0, 0, 0)
413 rgbaPixels[0] = GLColor(0u, 0u, 255u, 255u);
414
415 // Change some pixels to green to create a 2x2x2 cube starting at (1, 1, 1)
416 rgbaPixels[13] = GLColor(0u, 255u, 0u, 255u);
417 rgbaPixels[14] = GLColor(0u, 255u, 0u, 255u);
418 rgbaPixels[16] = GLColor(0u, 255u, 0u, 255u);
419 rgbaPixels[17] = GLColor(0u, 255u, 0u, 255u);
420 rgbaPixels[22] = GLColor(0u, 255u, 0u, 255u);
421 rgbaPixels[23] = GLColor(0u, 255u, 0u, 255u);
422 rgbaPixels[25] = GLColor(0u, 255u, 0u, 255u);
423 rgbaPixels[26] = GLColor(0u, 255u, 0u, 255u);
424
425 glBindTexture(GL_TEXTURE_3D, sourceTexture);
426 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 3, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
427 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
428 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
429 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
430 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
431 EXPECT_GL_NO_ERROR();
432
433 glActiveTexture(GL_TEXTURE0);
434 glBindTexture(GL_TEXTURE_3D, destTexture);
435 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
436 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
437 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
438 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
439 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
440 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
441 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
442 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
443
444 EXPECT_GL_NO_ERROR();
445 // Copy the 2x2x2 green cube into a new texture
446 glCopySubTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_3D, destTexture, 0, 0, 0, 0, 1, 1, 1, 2, 2,
447 2, false, false, false);
448 glBindTexture(GL_TEXTURE_3D, destTexture);
449 EXPECT_GL_NO_ERROR();
450 drawQuad(mProgram, "position", 1.0f);
451 int width = getWindowWidth() - 1;
452 int height = getWindowHeight() - 1;
453
454 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
455 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::green);
456 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::green);
457 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::green);
458
459 // Copy the 1x1x1 blue cube into the the 2x2x2 green cube at location (1, 1, 1)
460 glCopySubTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_3D, destTexture, 0, 1, 1, 1, 0, 0, 0, 1, 1,
461 1, false, false, false);
462 EXPECT_GL_NO_ERROR();
463 drawQuad(mProgram, "position", 1.0f);
464 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
465 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::green);
466 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::green);
467 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::blue);
468 }
469
470 // Test that the flipY parameter works with a GL_TEXTURE_3D texture.
TEST_P(Texture3DCopy,FlipY)471 TEST_P(Texture3DCopy, FlipY)
472 {
473 ANGLE_SKIP_TEST_IF(!checkExtensions());
474
475 // Create a 2x2x2 cube. The top half is red. The bottom half is green.
476 GLColor rgbaPixels[8] = {GLColor::green, GLColor::green, GLColor::red, GLColor::red,
477 GLColor::green, GLColor::green, GLColor::red, GLColor::red};
478
479 glBindTexture(GL_TEXTURE_3D, sourceTexture);
480 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
481 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
482 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
483 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
484 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
485 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
486 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
487 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
488
489 // mProgram creates a quad with the colors from the top (y-direction) layer of the 3D texture.
490 // 3D pixel (<x>, <y>, <z>) is drawn to 2D pixel (<x>, <z>) for <y> = 1.
491 drawQuad(mProgram, "position", 1.0f);
492
493 int width = getWindowWidth() - 1;
494 int height = getWindowHeight() - 1;
495
496 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
497 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::red);
498 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::red);
499 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::red);
500
501 EXPECT_GL_NO_ERROR();
502
503 glActiveTexture(GL_TEXTURE0);
504 glBindTexture(GL_TEXTURE_3D, destTexture);
505 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
506 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
507 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
508 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
509 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
510 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
511 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
512 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
513 EXPECT_GL_NO_ERROR();
514
515 // Flip the y coordinate. This will put the greem half on top, and the red half on the bottom.
516 glCopyTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_3D, destTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE,
517 true, false, false);
518
519 glBindTexture(GL_TEXTURE_3D, destTexture);
520 EXPECT_GL_NO_ERROR();
521 drawQuad(mProgram, "position", 1.0f);
522
523 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
524 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::green);
525 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::green);
526 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::green);
527 }
528
testUnsizedFormats(const GLenum testTarget)529 void CopyTexture3DTest::testUnsizedFormats(const GLenum testTarget)
530 {
531 const GLColor kColorNoAlpha(250, 200, 150, 100);
532 const GLColor kColorPreAlpha(250, 200, 150, 100);
533 const GLColor kColorUnAlpha(101, 150, 200, 200);
534
535 testCopy(testTarget, kColorNoAlpha, GL_RGB, GL_UNSIGNED_BYTE, false, false, false,
536 GLColor(250, 200, 150, 255));
537 testCopy(testTarget, kColorPreAlpha, GL_RGB, GL_UNSIGNED_BYTE, false, true, false,
538 GLColor(98, 78, 59, 255));
539 testCopy(testTarget, kColorUnAlpha, GL_RGB, GL_UNSIGNED_BYTE, false, false, true,
540 GLColor(128, 191, 255, 255));
541
542 testCopy(testTarget, kColorNoAlpha, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false, false, false,
543 GLColor(247, 199, 148, 255));
544 testCopy(testTarget, kColorPreAlpha, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false, true, false,
545 GLColor(99, 77, 57, 255));
546 testCopy(testTarget, kColorUnAlpha, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false, false, true,
547 GLColor(132, 190, 255, 255));
548
549 testCopy(testTarget, kColorNoAlpha, GL_RGBA, GL_UNSIGNED_BYTE, false, false, false,
550 GLColor(250, 200, 150, 100));
551 testCopy(testTarget, kColorPreAlpha, GL_RGBA, GL_UNSIGNED_BYTE, false, true, false,
552 GLColor(98, 78, 59, 100));
553 testCopy(testTarget, kColorUnAlpha, GL_RGBA, GL_UNSIGNED_BYTE, false, false, true,
554 GLColor(128, 191, 255, 200));
555
556 testCopy(testTarget, kColorNoAlpha, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, false, false, false,
557 GLColor(250, 200, 150, 100));
558 testCopy(testTarget, kColorPreAlpha, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, false, true, false,
559 GLColor(98, 78, 59, 100));
560 testCopy(testTarget, kColorUnAlpha, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, false, false, true,
561 GLColor(128, 191, 255, 200));
562
563 testCopy(testTarget, kColorNoAlpha, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, false, false, false,
564 GLColor(247, 198, 148, 0));
565 testCopy(testTarget, kColorPreAlpha, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, false, true, false,
566 GLColor(99, 82, 57, 0));
567 testCopy(testTarget, kColorUnAlpha, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, false, false, true,
568 GLColor(132, 189, 255, 255));
569
570 testCopy(testTarget, kColorNoAlpha, GL_LUMINANCE, GL_UNSIGNED_BYTE, false, false, false,
571 GLColor(250, 250, 250, 255));
572 testCopy(testTarget, kColorPreAlpha, GL_LUMINANCE, GL_UNSIGNED_BYTE, false, true, false,
573 GLColor(98, 98, 98, 255));
574 testCopy(testTarget, kColorUnAlpha, GL_LUMINANCE, GL_UNSIGNED_BYTE, false, false, true,
575 GLColor(128, 128, 128, 255));
576
577 testCopy(testTarget, kColorNoAlpha, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, false, false, false,
578 GLColor(250, 250, 250, 100));
579 testCopy(testTarget, kColorPreAlpha, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, false, true, false,
580 GLColor(98, 98, 98, 100));
581 testCopy(testTarget, kColorUnAlpha, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, false, false, true,
582 GLColor(128, 128, 128, 200));
583
584 testCopy(testTarget, kColorNoAlpha, GL_ALPHA, GL_UNSIGNED_BYTE, false, false, false,
585 GLColor(0, 0, 0, 100));
586 testCopy(testTarget, kColorNoAlpha, GL_ALPHA, GL_UNSIGNED_BYTE, false, false, false,
587 GLColor(0, 0, 0, 100));
588 testCopy(testTarget, kColorNoAlpha, GL_ALPHA, GL_UNSIGNED_BYTE, false, false, false,
589 GLColor(0, 0, 0, 100));
590 }
591
592 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_3D with unsized
593 // formats.
TEST_P(Texture3DCopy,UnsizedFormats)594 TEST_P(Texture3DCopy, UnsizedFormats)
595 {
596 ANGLE_SKIP_TEST_IF(!checkExtensions());
597
598 testUnsizedFormats(GL_TEXTURE_3D);
599 }
600
testSnormFormats(const GLenum testTarget)601 void CopyTexture3DTest::testSnormFormats(const GLenum testTarget)
602 {
603 const GLColor kColorNoAlpha(250, 200, 150, 190);
604 const GLColor kColorPreAlpha(250, 200, 150, 190);
605 const GLColor kColorUnAlpha(200, 150, 100, 230);
606
607 testCopy(testTarget, kColorNoAlpha, GL_R8_SNORM, GL_BYTE, false, false, false,
608 GLColor(251, 0, 0, 255));
609 testCopy(testTarget, kColorPreAlpha, GL_R8_SNORM, GL_BYTE, false, true, false,
610 GLColor(187, 0, 0, 255));
611 testCopy(testTarget, kColorUnAlpha, GL_R8_SNORM, GL_BYTE, false, false, true,
612 GLColor(221, 0, 0, 255));
613
614 testCopy(testTarget, kColorNoAlpha, GL_RG8_SNORM, GL_BYTE, false, false, false,
615 GLColor(251, 201, 0, 255));
616 testCopy(testTarget, kColorPreAlpha, GL_RG8_SNORM, GL_BYTE, false, true, false,
617 GLColor(187, 149, 0, 255));
618 testCopy(testTarget, kColorUnAlpha, GL_RG8_SNORM, GL_BYTE, false, false, true,
619 GLColor(221, 167, 0, 255));
620
621 testCopy(testTarget, kColorNoAlpha, GL_RGB8_SNORM, GL_BYTE, false, false, false,
622 GLColor(251, 201, 151, 255));
623 testCopy(testTarget, kColorPreAlpha, GL_RGB8_SNORM, GL_BYTE, false, true, false,
624 GLColor(187, 149, 112, 255));
625 testCopy(testTarget, kColorUnAlpha, GL_RGB8_SNORM, GL_BYTE, false, false, true,
626 GLColor(221, 167, 110, 255));
627
628 testCopy(testTarget, kColorNoAlpha, GL_RGBA8_SNORM, GL_BYTE, false, false, false,
629 GLColor(251, 201, 151, 191));
630 testCopy(testTarget, kColorPreAlpha, GL_RGBA8_SNORM, GL_BYTE, false, true, false,
631 GLColor(187, 149, 112, 191));
632 testCopy(testTarget, kColorUnAlpha, GL_RGBA8_SNORM, GL_BYTE, false, false, true,
633 GLColor(221, 167, 110, 231));
634
635 testCopy(testTarget, GLColor(250, 200, 150, 100), GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV,
636 false, false, false, GLColor(250, 200, 150, 85));
637 testCopy(testTarget, GLColor(250, 200, 150, 200), GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV,
638 false, true, false, GLColor(196, 157, 118, 170));
639 testCopy(testTarget, GLColor(101, 150, 190, 200), GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV,
640 false, false, true, GLColor(128, 191, 242, 170));
641 }
642
643 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_3D with snorm
644 // formats.
TEST_P(Texture3DCopy,SnormFormats)645 TEST_P(Texture3DCopy, SnormFormats)
646 {
647 ANGLE_SKIP_TEST_IF(!checkExtensions());
648
649 testSnormFormats(GL_TEXTURE_3D);
650 }
651
testUnsignedByteFormats(const GLenum testTarget)652 void CopyTexture3DTest::testUnsignedByteFormats(const GLenum testTarget)
653 {
654 {
655 const GLColor kColorNoAlpha(250, 200, 150, 100);
656 const GLColor kColorPreAlpha(250, 200, 150, 100);
657 const GLColor kColorUnAlpha(200, 150, 100, 230);
658
659 testCopy(testTarget, kColorNoAlpha, GL_R8, GL_UNSIGNED_BYTE, false, false, false,
660 GLColor(250, 0, 0, 255));
661 testCopy(testTarget, kColorPreAlpha, GL_R8, GL_UNSIGNED_BYTE, false, true, false,
662 GLColor(98, 0, 0, 255));
663 testCopy(testTarget, kColorUnAlpha, GL_R8, GL_UNSIGNED_BYTE, false, false, true,
664 GLColor(221, 0, 0, 255));
665
666 testCopy(testTarget, kColorNoAlpha, GL_RG8, GL_UNSIGNED_BYTE, false, false, false,
667 GLColor(250, 200, 0, 255));
668 testCopy(testTarget, kColorPreAlpha, GL_RG8, GL_UNSIGNED_BYTE, false, true, false,
669 GLColor(98, 78, 0, 255));
670 testCopy(testTarget, kColorUnAlpha, GL_RG8, GL_UNSIGNED_BYTE, false, false, true,
671 GLColor(221, 167, 0, 255));
672
673 testCopy(testTarget, kColorNoAlpha, GL_RGB8, GL_UNSIGNED_BYTE, false, false, false,
674 GLColor(250, 200, 150, 255));
675 testCopy(testTarget, kColorPreAlpha, GL_RGB8, GL_UNSIGNED_BYTE, false, true, false,
676 GLColor(98, 78, 59, 255));
677 testCopy(testTarget, kColorUnAlpha, GL_RGB8, GL_UNSIGNED_BYTE, false, false, true,
678 GLColor(221, 167, 110, 255));
679
680 testCopy(testTarget, kColorNoAlpha, GL_RGBA8, GL_UNSIGNED_BYTE, false, false, false,
681 GLColor(250, 200, 150, 100));
682 testCopy(testTarget, kColorPreAlpha, GL_RGBA8, GL_UNSIGNED_BYTE, false, true, false,
683 GLColor(98, 78, 59, 100));
684 testCopy(testTarget, kColorUnAlpha, GL_RGBA8, GL_UNSIGNED_BYTE, false, false, true,
685 GLColor(221, 167, 110, 230));
686
687 testCopy(testTarget, kColorNoAlpha, GL_RGBA4, GL_UNSIGNED_BYTE, false, false, false,
688 GLColor(250, 200, 150, 100));
689 testCopy(testTarget, kColorPreAlpha, GL_RGBA4, GL_UNSIGNED_BYTE, false, true, false,
690 GLColor(98, 78, 59, 100));
691 testCopy(testTarget, kColorUnAlpha, GL_RGBA4, GL_UNSIGNED_BYTE, false, false, true,
692 GLColor(221, 167, 110, 230));
693
694 testCopy(testTarget, kColorNoAlpha, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, false, false,
695 false, GLColor(250, 200, 150, 100));
696 testCopy(testTarget, kColorPreAlpha, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, false, true,
697 false, GLColor(98, 78, 59, 100));
698 testCopy(testTarget, kColorUnAlpha, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, false, false, true,
699 GLColor(221, 167, 110, 230));
700
701 testCopy(testTarget, kColorNoAlpha, GL_SRGB8, GL_UNSIGNED_BYTE, false, false, false,
702 GLColor(244, 148, 78, 255));
703 testCopy(testTarget, kColorPreAlpha, GL_SRGB8, GL_UNSIGNED_BYTE, false, true, false,
704 GLColor(31, 19, 11, 255));
705 testCopy(testTarget, GLColor(100, 150, 200, 210), GL_SRGB8, GL_UNSIGNED_BYTE, false, false,
706 true, GLColor(49, 120, 228, 255));
707
708 testCopy(testTarget, kColorNoAlpha, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, false, false, false,
709 GLColor(244, 148, 78, 100));
710 testCopy(testTarget, kColorPreAlpha, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, false, true, false,
711 GLColor(31, 19, 11, 100));
712 testCopy(testTarget, GLColor(100, 150, 200, 210), GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, false,
713 false, true, GLColor(49, 120, 228, 210));
714
715 testCopy(testTarget, GLColor(250, 200, 150, 200), GL_RGB5_A1, GL_UNSIGNED_BYTE, false,
716 false, false, GLColor(247, 198, 148, 255));
717 testCopy(testTarget, kColorPreAlpha, GL_RGB5_A1, GL_UNSIGNED_BYTE, false, true, false,
718 GLColor(99, 82, 57, 0));
719 testCopy(testTarget, kColorUnAlpha, GL_RGB5_A1, GL_UNSIGNED_BYTE, false, false, true,
720 GLColor(221, 167, 110, 255));
721
722 if (IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"))
723 {
724 testCopy(testTarget, kColorNoAlpha, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, false, false,
725 false, GLColor(250, 200, 150, 255));
726 testCopy(testTarget, kColorPreAlpha, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, false, true,
727 false, GLColor(98, 78, 59, 255));
728 testCopy(testTarget, kColorUnAlpha, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, false, false,
729 true, GLColor(221, 167, 110, 255));
730 }
731 }
732
733 {
734 const GLColor kColorNoAlpha(250, 200, 150, 200);
735 const GLColor kColorPreAlpha(250, 200, 150, 200);
736 const GLColor kColorUnAlpha(101, 150, 190, 200);
737
738 testCopy(testTarget, kColorNoAlpha, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, false,
739 false, false, GLColor(247, 198, 148, 255));
740 testCopy(testTarget, kColorPreAlpha, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, false,
741 true, false, GLColor(198, 156, 115, 255));
742 testCopy(testTarget, kColorUnAlpha, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, false,
743 false, true, GLColor(132, 189, 242, 255));
744
745 testCopy(testTarget, kColorNoAlpha, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, false, false,
746 false, GLColor(247, 198, 148, 255));
747 testCopy(testTarget, kColorPreAlpha, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, false, true,
748 false, GLColor(198, 156, 115, 255));
749 testCopy(testTarget, kColorUnAlpha, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, false, false,
750 true, GLColor(132, 189, 242, 255));
751
752 testCopy(testTarget, kColorNoAlpha, GL_RGB565, GL_UNSIGNED_BYTE, false, false, false,
753 GLColor(247, 199, 148, 255));
754 testCopy(testTarget, kColorPreAlpha, GL_RGB565, GL_UNSIGNED_BYTE, false, true, false,
755 GLColor(198, 158, 115, 255));
756 testCopy(testTarget, kColorUnAlpha, GL_RGB565, GL_UNSIGNED_BYTE, false, false, true,
757 GLColor(132, 190, 242, 255));
758
759 testCopy(testTarget, kColorNoAlpha, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, false, false, false,
760 GLColor(247, 199, 148, 255));
761 testCopy(testTarget, kColorPreAlpha, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, false, true, false,
762 GLColor(198, 158, 115, 255));
763 testCopy(testTarget, kColorUnAlpha, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, false, false, true,
764 GLColor(132, 190, 242, 255));
765 }
766 }
767
768 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_3D with unsigned
769 // byte formats.
TEST_P(Texture3DCopy,UnsignedByteFormats)770 TEST_P(Texture3DCopy, UnsignedByteFormats)
771 {
772 ANGLE_SKIP_TEST_IF(!checkExtensions());
773
774 testUnsignedByteFormats(GL_TEXTURE_3D);
775 }
776
testFloatFormats(const GLenum testTarget)777 void CopyTexture3DTest::testFloatFormats(const GLenum testTarget)
778 {
779 std::vector<GLenum> floatTypes = {GL_FLOAT, GL_HALF_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV,
780 GL_UNSIGNED_INT_5_9_9_9_REV};
781
782 const GLColor kColor(210, 200, 150, 235);
783
784 for (GLenum floatType : floatTypes)
785 {
786 if (floatType != GL_UNSIGNED_INT_5_9_9_9_REV &&
787 floatType != GL_UNSIGNED_INT_10F_11F_11F_REV)
788 {
789 testCopy(testTarget, kColor, GL_R16F, floatType, false, false, false,
790 GLColor(210, 0, 0, 255));
791 testCopy(testTarget, kColor, GL_R16F, floatType, false, true, false,
792 GLColor(191, 0, 0, 255));
793 testCopy(testTarget, kColor, GL_R16F, floatType, false, false, true,
794 GLColor(227, 0, 0, 255));
795
796 testCopy(testTarget, kColor, GL_RG16F, floatType, false, false, false,
797 GLColor(210, 200, 0, 255));
798 testCopy(testTarget, kColor, GL_RG16F, floatType, false, true, false,
799 GLColor(191, 184, 0, 255));
800 testCopy(testTarget, kColor, GL_RG16F, floatType, false, false, true,
801 GLColor(227, 217, 0, 255));
802
803 testCopy(testTarget, kColor, GL_RGB16F, floatType, false, false, false,
804 GLColor(210, 200, 150, 255));
805 testCopy(testTarget, kColor, GL_RGB16F, floatType, false, true, false,
806 GLColor(191, 184, 138, 255));
807 testCopy(testTarget, kColor, GL_RGB16F, floatType, false, false, true,
808 GLColor(227, 217, 161, 255));
809
810 testCopy(testTarget, kColor, GL_RGBA16F, floatType, false, false, false,
811 GLColor(210, 200, 150, 235));
812 testCopy(testTarget, kColor, GL_RGBA16F, floatType, false, true, false,
813 GLColor(191, 184, 138, 235));
814 testCopy(testTarget, kColor, GL_RGBA16F, floatType, false, false, true,
815 GLColor(227, 217, 161, 235));
816 }
817
818 if (floatType != GL_UNSIGNED_INT_5_9_9_9_REV)
819 {
820 testCopy(testTarget, kColor, GL_R11F_G11F_B10F, floatType, false, false, false,
821 GLColor(210, 200, 148, 255));
822 testCopy(testTarget, kColor, GL_R11F_G11F_B10F, floatType, false, true, false,
823 GLColor(191, 184, 138, 255));
824 testCopy(testTarget, kColor, GL_R11F_G11F_B10F, floatType, false, false, true,
825 GLColor(227, 217, 161, 255));
826 }
827
828 if (floatType != GL_UNSIGNED_INT_10F_11F_11F_REV)
829 {
830 testCopy(testTarget, kColor, GL_RGB9_E5, floatType, false, false, false,
831 GLColor(210, 200, 148, 255));
832 testCopy(testTarget, kColor, GL_RGB9_E5, floatType, false, true, false,
833 GLColor(192, 184, 138, 255));
834 testCopy(testTarget, kColor, GL_RGB9_E5, floatType, false, false, true,
835 GLColor(227, 217, 161, 255));
836 }
837 }
838
839 testCopy(testTarget, kColor, GL_R32F, GL_FLOAT, false, false, false, GLColor(210, 0, 0, 255));
840 testCopy(testTarget, kColor, GL_R32F, GL_FLOAT, false, true, false, GLColor(191, 0, 0, 255));
841 testCopy(testTarget, kColor, GL_R32F, GL_FLOAT, false, false, true, GLColor(227, 0, 0, 255));
842
843 testCopy(testTarget, kColor, GL_RG32F, GL_FLOAT, false, false, false,
844 GLColor(210, 200, 0, 255));
845 testCopy(testTarget, kColor, GL_RG32F, GL_FLOAT, false, true, false, GLColor(191, 184, 0, 255));
846 testCopy(testTarget, kColor, GL_RG32F, GL_FLOAT, false, false, true, GLColor(227, 217, 0, 255));
847
848 testCopy(testTarget, kColor, GL_RGB32F, GL_FLOAT, false, false, false,
849 GLColor(210, 200, 150, 255));
850 testCopy(testTarget, kColor, GL_RGB32F, GL_FLOAT, false, true, false,
851 GLColor(191, 184, 138, 255));
852 testCopy(testTarget, kColor, GL_RGB32F, GL_FLOAT, false, false, true,
853 GLColor(227, 217, 161, 255));
854
855 testCopy(testTarget, kColor, GL_RGBA32F, GL_FLOAT, false, false, false,
856 GLColor(210, 200, 150, 235));
857 testCopy(testTarget, kColor, GL_RGBA32F, GL_FLOAT, false, true, false,
858 GLColor(191, 184, 138, 235));
859 testCopy(testTarget, kColor, GL_RGBA32F, GL_FLOAT, false, false, true,
860 GLColor(227, 217, 161, 235));
861 }
862
863 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_3D with float
864 // formats.
TEST_P(Texture3DCopy,FloatFormats)865 TEST_P(Texture3DCopy, FloatFormats)
866 {
867 ANGLE_SKIP_TEST_IF(!checkExtensions());
868
869 testFloatFormats(GL_TEXTURE_3D);
870 }
871
testIntFormats(const GLenum testTarget)872 void CopyTexture3DTest::testIntFormats(const GLenum testTarget)
873 {
874 const GLColor kColor(255, 140, 150, 230);
875
876 // Pixels will be read as if the most significant bit is data, not the sign. The expected colors
877 // reflect this.
878 testCopy(testTarget, kColor, GL_R8I, GL_BYTE, false, false, false, GLColor(127, 0, 0, 1));
879 testCopy(testTarget, kColor, GL_R8I, GL_BYTE, false, true, false, GLColor(115, 0, 0, 1));
880 testCopy(testTarget, kColor, GL_R8I, GL_BYTE, false, false, true, GLColor(127, 0, 0, 1));
881
882 testCopy(testTarget, kColor, GL_R16I, GL_SHORT, false, false, false, GLColor(127, 0, 0, 1));
883 testCopy(testTarget, kColor, GL_R16I, GL_SHORT, false, true, false, GLColor(115, 0, 0, 1));
884 testCopy(testTarget, kColor, GL_R16I, GL_SHORT, false, false, true, GLColor(127, 0, 0, 1));
885
886 testCopy(testTarget, kColor, GL_R32I, GL_INT, false, false, false, GLColor(127, 0, 0, 1));
887 testCopy(testTarget, kColor, GL_R32I, GL_INT, false, true, false, GLColor(115, 0, 0, 1));
888 testCopy(testTarget, kColor, GL_R32I, GL_INT, false, false, true, GLColor(127, 0, 0, 1));
889
890 testCopy(testTarget, kColor, GL_RG8I, GL_BYTE, false, false, false, GLColor(127, 70, 0, 1));
891 testCopy(testTarget, kColor, GL_RG8I, GL_BYTE, false, true, false, GLColor(115, 63, 0, 1));
892 testCopy(testTarget, kColor, GL_RG8I, GL_BYTE, false, false, true, GLColor(127, 77, 0, 1));
893
894 testCopy(testTarget, kColor, GL_RG16I, GL_SHORT, false, false, false, GLColor(127, 70, 0, 1));
895 testCopy(testTarget, kColor, GL_RG16I, GL_SHORT, false, true, false, GLColor(115, 63, 0, 1));
896 testCopy(testTarget, kColor, GL_RG16I, GL_SHORT, false, false, true, GLColor(127, 77, 0, 1));
897
898 testCopy(testTarget, kColor, GL_RG32I, GL_INT, false, false, false, GLColor(127, 70, 0, 1));
899 testCopy(testTarget, kColor, GL_RG32I, GL_INT, false, true, false, GLColor(115, 63, 0, 1));
900 testCopy(testTarget, kColor, GL_RG32I, GL_INT, false, false, true, GLColor(127, 77, 0, 1));
901
902 testCopy(testTarget, kColor, GL_RGB8I, GL_BYTE, false, false, false, GLColor(127, 70, 75, 1));
903 testCopy(testTarget, kColor, GL_RGB8I, GL_BYTE, false, true, false, GLColor(115, 63, 67, 1));
904 testCopy(testTarget, kColor, GL_RGB8I, GL_BYTE, false, false, true, GLColor(127, 77, 83, 1));
905
906 testCopy(testTarget, kColor, GL_RGB16I, GL_SHORT, false, false, false, GLColor(127, 70, 75, 1));
907 testCopy(testTarget, kColor, GL_RGB16I, GL_SHORT, false, true, false, GLColor(115, 63, 67, 1));
908 testCopy(testTarget, kColor, GL_RGB16I, GL_SHORT, false, false, true, GLColor(127, 77, 83, 1));
909
910 testCopy(testTarget, kColor, GL_RGB32I, GL_INT, false, false, false, GLColor(127, 70, 75, 1));
911 testCopy(testTarget, kColor, GL_RGB32I, GL_INT, false, true, false, GLColor(115, 63, 67, 1));
912 testCopy(testTarget, kColor, GL_RGB32I, GL_INT, false, false, true, GLColor(127, 77, 83, 1));
913
914 testCopy(testTarget, kColor, GL_RGBA8I, GL_BYTE, false, false, false,
915 GLColor(127, 70, 75, 115));
916 testCopy(testTarget, kColor, GL_RGBA8I, GL_BYTE, false, true, false, GLColor(115, 63, 67, 115));
917 testCopy(testTarget, kColor, GL_RGBA8I, GL_BYTE, false, false, true, GLColor(127, 77, 83, 115));
918
919 testCopy(testTarget, kColor, GL_RGBA16I, GL_SHORT, false, false, false,
920 GLColor(127, 70, 75, 115));
921 testCopy(testTarget, kColor, GL_RGBA16I, GL_SHORT, false, true, false,
922 GLColor(115, 63, 67, 115));
923 testCopy(testTarget, kColor, GL_RGBA16I, GL_SHORT, false, false, true,
924 GLColor(127, 77, 83, 115));
925
926 testCopy(testTarget, kColor, GL_RGBA32I, GL_INT, false, false, false,
927 GLColor(127, 70, 75, 115));
928 testCopy(testTarget, kColor, GL_RGBA32I, GL_INT, false, true, false, GLColor(115, 63, 67, 115));
929 testCopy(testTarget, kColor, GL_RGBA32I, GL_INT, false, false, true, GLColor(127, 77, 83, 115));
930 }
931
932 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_3D with integer
933 // formats.
TEST_P(Texture3DCopy,IntFormats)934 TEST_P(Texture3DCopy, IntFormats)
935 {
936 ANGLE_SKIP_TEST_IF(!checkExtensions());
937
938 // Vulkan multiplies source by 255 unconditionally, which is wrong for signed integer formats.
939 // http://anglebug.com/42263339
940 ANGLE_SKIP_TEST_IF(IsVulkan());
941
942 constexpr char kFS[] =
943 "#version 300 es\n"
944 "precision highp float;\n"
945 "uniform highp isampler3D tex3D;\n"
946 "in vec3 texcoord;\n"
947 "out ivec4 fragColor;\n"
948 "void main()\n"
949 "{\n"
950 " fragColor = texture(tex3D, vec3(texcoord.x, texcoord.z, texcoord.y));\n"
951 "}\n";
952
953 mProgram = CompileProgram(getVertexShaderSource(), kFS);
954 ASSERT_NE(0u, mProgram);
955 ASSERT_GL_NO_ERROR();
956
957 glUseProgram(mProgram);
958
959 testIntFormats(GL_TEXTURE_3D);
960 }
961
testUintFormats(const GLenum testTarget)962 void CopyTexture3DTest::testUintFormats(const GLenum testTarget)
963 {
964 const GLColor kColor(128, 84, 32, 100);
965
966 testCopy(testTarget, kColor, GL_R8UI, GL_UNSIGNED_BYTE, false, false, false,
967 GLColor(128, 0, 0, 1));
968 testCopy(testTarget, kColor, GL_R8UI, GL_UNSIGNED_BYTE, false, true, false,
969 GLColor(50, 0, 0, 1));
970 testCopy(testTarget, kColor, GL_R8UI, GL_UNSIGNED_BYTE, false, false, true,
971 GLColor(255, 0, 0, 1));
972
973 testCopy(testTarget, kColor, GL_R16UI, GL_UNSIGNED_SHORT, false, false, false,
974 GLColor(128, 0, 0, 1));
975 testCopy(testTarget, kColor, GL_R16UI, GL_UNSIGNED_SHORT, false, true, false,
976 GLColor(50, 0, 0, 1));
977 testCopy(testTarget, kColor, GL_R16UI, GL_UNSIGNED_SHORT, false, false, true,
978 GLColor(255, 0, 0, 1));
979
980 testCopy(testTarget, kColor, GL_R32UI, GL_UNSIGNED_INT, false, false, false,
981 GLColor(128, 0, 0, 1));
982 testCopy(testTarget, kColor, GL_R32UI, GL_UNSIGNED_INT, false, true, false,
983 GLColor(50, 0, 0, 1));
984 testCopy(testTarget, kColor, GL_R32UI, GL_UNSIGNED_INT, false, false, true,
985 GLColor(255, 0, 0, 1));
986
987 testCopy(testTarget, kColor, GL_RG8UI, GL_UNSIGNED_BYTE, false, false, false,
988 GLColor(128, 84, 0, 1));
989 testCopy(testTarget, kColor, GL_RG8UI, GL_UNSIGNED_BYTE, false, true, false,
990 GLColor(50, 32, 0, 1));
991 testCopy(testTarget, kColor, GL_RG8UI, GL_UNSIGNED_BYTE, false, false, true,
992 GLColor(255, 214, 0, 1));
993
994 testCopy(testTarget, kColor, GL_RG16UI, GL_UNSIGNED_SHORT, false, false, false,
995 GLColor(128, 84, 0, 1));
996 testCopy(testTarget, kColor, GL_RG16UI, GL_UNSIGNED_SHORT, false, true, false,
997 GLColor(50, 32, 0, 1));
998 testCopy(testTarget, kColor, GL_RG16UI, GL_UNSIGNED_SHORT, false, false, true,
999 GLColor(255, 214, 0, 1));
1000
1001 testCopy(testTarget, kColor, GL_RG32UI, GL_UNSIGNED_INT, false, false, false,
1002 GLColor(128, 84, 0, 1));
1003 testCopy(testTarget, kColor, GL_RG32UI, GL_UNSIGNED_INT, false, true, false,
1004 GLColor(50, 32, 0, 1));
1005 testCopy(testTarget, kColor, GL_RG32UI, GL_UNSIGNED_INT, false, false, true,
1006 GLColor(255, 214, 0, 1));
1007
1008 testCopy(testTarget, kColor, GL_RGB8UI, GL_UNSIGNED_BYTE, false, false, false,
1009 GLColor(128, 84, 32, 1));
1010 testCopy(testTarget, kColor, GL_RGB8UI, GL_UNSIGNED_BYTE, false, true, false,
1011 GLColor(50, 32, 12, 1));
1012 testCopy(testTarget, kColor, GL_RGB8UI, GL_UNSIGNED_BYTE, false, false, true,
1013 GLColor(255, 214, 81, 1));
1014
1015 testCopy(testTarget, kColor, GL_RGB16UI, GL_UNSIGNED_SHORT, false, false, false,
1016 GLColor(128, 84, 32, 1));
1017 testCopy(testTarget, kColor, GL_RGB16UI, GL_UNSIGNED_SHORT, false, true, false,
1018 GLColor(50, 32, 12, 1));
1019 testCopy(testTarget, kColor, GL_RGB16UI, GL_UNSIGNED_SHORT, false, false, true,
1020 GLColor(255, 214, 81, 1));
1021
1022 testCopy(testTarget, kColor, GL_RGB32UI, GL_UNSIGNED_INT, false, false, false,
1023 GLColor(128, 84, 32, 1));
1024 testCopy(testTarget, kColor, GL_RGB32UI, GL_UNSIGNED_INT, false, true, false,
1025 GLColor(50, 32, 12, 1));
1026 testCopy(testTarget, kColor, GL_RGB32UI, GL_UNSIGNED_INT, false, false, true,
1027 GLColor(255, 214, 81, 1));
1028
1029 testCopy(testTarget, kColor, GL_RGBA8UI, GL_UNSIGNED_BYTE, false, false, false,
1030 GLColor(128, 84, 32, 100));
1031 testCopy(testTarget, kColor, GL_RGBA8UI, GL_UNSIGNED_BYTE, false, true, false,
1032 GLColor(50, 32, 12, 100));
1033 testCopy(testTarget, kColor, GL_RGBA8UI, GL_UNSIGNED_BYTE, false, false, true,
1034 GLColor(255, 214, 81, 100));
1035
1036 testCopy(testTarget, kColor, GL_RGBA16UI, GL_UNSIGNED_SHORT, false, false, false,
1037 GLColor(128, 84, 32, 100));
1038 testCopy(testTarget, kColor, GL_RGBA16UI, GL_UNSIGNED_SHORT, false, true, false,
1039 GLColor(50, 32, 12, 100));
1040 testCopy(testTarget, kColor, GL_RGBA16UI, GL_UNSIGNED_SHORT, false, false, true,
1041 GLColor(255, 214, 81, 100));
1042
1043 testCopy(testTarget, kColor, GL_RGBA32UI, GL_UNSIGNED_INT, false, false, false,
1044 GLColor(128, 84, 32, 100));
1045 testCopy(testTarget, kColor, GL_RGBA32UI, GL_UNSIGNED_INT, false, true, false,
1046 GLColor(50, 32, 12, 100));
1047 testCopy(testTarget, kColor, GL_RGBA32UI, GL_UNSIGNED_INT, false, false, true,
1048 GLColor(255, 214, 81, 100));
1049
1050 testCopy(testTarget, kColor, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, false, false, false,
1051 GLColor(128, 84, 32, 3));
1052 testCopy(testTarget, kColor, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, false, true, false,
1053 GLColor(50, 32, 12, 3));
1054 testCopy(testTarget, kColor, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, false, false, true,
1055 GLColor(255, 214, 81, 3));
1056 }
1057
1058 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_3D with unsigned
1059 // integer formats.
TEST_P(Texture3DCopy,UintFormats)1060 TEST_P(Texture3DCopy, UintFormats)
1061 {
1062 ANGLE_SKIP_TEST_IF(!checkExtensions());
1063
1064 // Vulkan multiplies source by 255 unconditionally, which is wrong for non-8-bit integer
1065 // formats. http://anglebug.com/42263339
1066 ANGLE_SKIP_TEST_IF(IsVulkan());
1067
1068 constexpr char kFS[] =
1069 "#version 300 es\n"
1070 "precision highp float;\n"
1071 "uniform highp usampler3D tex3D;\n"
1072 "in vec3 texcoord;\n"
1073 "out uvec4 fragColor;\n"
1074 "void main()\n"
1075 "{\n"
1076 " fragColor = texture(tex3D, vec3(texcoord.x, texcoord.z, texcoord.y));\n"
1077 "}\n";
1078
1079 mProgram = CompileProgram(getVertexShaderSource(), kFS);
1080 ASSERT_NE(0u, mProgram);
1081 ASSERT_GL_NO_ERROR();
1082
1083 glUseProgram(mProgram);
1084
1085 testUintFormats(GL_TEXTURE_3D);
1086 }
1087
1088 // Test that glCopySubTexture3DANGLE correctly copies to and from a GL_TEXTURE_2D_ARRAY texture.
TEST_P(Texture2DArrayCopy,CopySubTexture)1089 TEST_P(Texture2DArrayCopy, CopySubTexture)
1090 {
1091 ANGLE_SKIP_TEST_IF(!checkExtensions());
1092
1093 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1094 std::vector<GLColor> texDataRed(2u * 2u * 2u, GLColor::red);
1095
1096 glBindTexture(GL_TEXTURE_2D_ARRAY, sourceTexture);
1097 EXPECT_GL_NO_ERROR();
1098 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1099 texDataGreen.data());
1100 EXPECT_GL_NO_ERROR();
1101 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1102 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1103 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
1104 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
1105 EXPECT_GL_NO_ERROR();
1106
1107 glActiveTexture(GL_TEXTURE0);
1108 glBindTexture(GL_TEXTURE_2D_ARRAY, destTexture);
1109 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1110 texDataRed.data());
1111 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1112 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1113 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
1114 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
1115 EXPECT_GL_NO_ERROR();
1116 glCopySubTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_2D_ARRAY, destTexture, 0, 0, 0, 0, 0, 0, 0,
1117 2, 2, 2, false, false, false);
1118 EXPECT_GL_NO_ERROR();
1119 drawQuad(mProgram, "position", 0.5f);
1120
1121 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1122 }
1123
1124 // Test that glCopyTexture3DANGLE correctly copies from a non-zero mipmap on a GL_TEXTURE_2D_ARRAY
1125 // texture.
TEST_P(Texture2DArrayCopy,CopyFromMipmap)1126 TEST_P(Texture2DArrayCopy, CopyFromMipmap)
1127 {
1128 ANGLE_SKIP_TEST_IF(!checkExtensions());
1129
1130 std::vector<GLColor> texDataGreen4(4u * 4u * 4u, GLColor::green);
1131 std::vector<GLColor> texDataGreen2(2u * 2u * 2u, GLColor::green);
1132 std::vector<GLColor> texDataRed2(2u * 2u * 2u, GLColor::red);
1133
1134 glBindTexture(GL_TEXTURE_2D_ARRAY, sourceTexture);
1135 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1136 texDataGreen4.data());
1137 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1138 texDataGreen2.data());
1139 EXPECT_GL_NO_ERROR();
1140 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1141 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1142 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1143 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1144 EXPECT_GL_NO_ERROR();
1145
1146 glActiveTexture(GL_TEXTURE0);
1147 glBindTexture(GL_TEXTURE_2D_ARRAY, destTexture);
1148 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1149 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1150 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1151 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
1152 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
1153
1154 EXPECT_GL_NO_ERROR();
1155 glCopyTexture3DANGLE(sourceTexture, 1, GL_TEXTURE_2D_ARRAY, destTexture, 0, GL_RGBA,
1156 GL_UNSIGNED_BYTE, false, false, false);
1157
1158 EXPECT_GL_NO_ERROR();
1159 drawQuad(mProgram, "position", 1.0f);
1160
1161 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1162 }
1163
1164 // Test that glCopySubTexture3DANGLE's offset and dimension parameters work correctly with a
1165 // GL_TEXTURE_2D_ARRAY texture.
TEST_P(Texture2DArrayCopy,OffsetSubCopy)1166 TEST_P(Texture2DArrayCopy, OffsetSubCopy)
1167 {
1168 ANGLE_SKIP_TEST_IF(!checkExtensions());
1169
1170 GLColor rgbaPixels[27];
1171
1172 // Create pixel data for a 3x3x3 red cube
1173 for (int i = 0; i < 27; i++)
1174 {
1175 rgbaPixels[i] = GLColor(255u, 0u, 0u, 255u);
1176 }
1177
1178 // Change a pixel to create a 1x1x1 blue cube at (0, 0, 0)
1179 rgbaPixels[0] = GLColor(0u, 0u, 255u, 255u);
1180
1181 // Change some pixels to green to create a 2x2x2 cube starting at (1, 1, 1)
1182 rgbaPixels[13] = GLColor(0u, 255u, 0u, 255u);
1183 rgbaPixels[14] = GLColor(0u, 255u, 0u, 255u);
1184 rgbaPixels[16] = GLColor(0u, 255u, 0u, 255u);
1185 rgbaPixels[17] = GLColor(0u, 255u, 0u, 255u);
1186 rgbaPixels[22] = GLColor(0u, 255u, 0u, 255u);
1187 rgbaPixels[23] = GLColor(0u, 255u, 0u, 255u);
1188 rgbaPixels[25] = GLColor(0u, 255u, 0u, 255u);
1189 rgbaPixels[26] = GLColor(0u, 255u, 0u, 255u);
1190
1191 glBindTexture(GL_TEXTURE_2D_ARRAY, sourceTexture);
1192 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 3, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1193 rgbaPixels);
1194 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1195 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1196 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
1197 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
1198 EXPECT_GL_NO_ERROR();
1199
1200 glActiveTexture(GL_TEXTURE0);
1201 glBindTexture(GL_TEXTURE_2D_ARRAY, destTexture);
1202 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1203 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1204 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1205 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
1206 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
1207 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1208 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1209 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1210
1211 EXPECT_GL_NO_ERROR();
1212 // Copy the 2x2x2 green cube into a new texture
1213 glCopySubTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_2D_ARRAY, destTexture, 0, 0, 0, 0, 1, 1, 1,
1214 2, 2, 2, false, false, false);
1215 glBindTexture(GL_TEXTURE_2D_ARRAY, destTexture);
1216 EXPECT_GL_NO_ERROR();
1217 drawQuad(mProgram, "position", 1.0f);
1218 int width = getWindowWidth() - 1;
1219 int height = getWindowHeight() - 1;
1220
1221 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1222 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::green);
1223 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::green);
1224 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::green);
1225
1226 // Copy the 1x1x1 blue cube into the the 2x2x2 green cube at location (1, 1, 1)
1227 glCopySubTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_2D_ARRAY, destTexture, 0, 1, 1, 1, 0, 0, 0,
1228 1, 1, 1, false, false, false);
1229 EXPECT_GL_NO_ERROR();
1230 drawQuad(mProgram, "position", 1.0f);
1231 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1232 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::green);
1233 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::green);
1234 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::blue);
1235 }
1236
1237 // Test that the flipY parameter works with a GL_TEXTURE_2D_ARRAY texture.
TEST_P(Texture2DArrayCopy,FlipY)1238 TEST_P(Texture2DArrayCopy, FlipY)
1239 {
1240 ANGLE_SKIP_TEST_IF(!checkExtensions());
1241
1242 // Create a 2x2x2 cube. The top half is red. The bottom half is green.
1243 GLColor rgbaPixels[8] = {GLColor::green, GLColor::green, GLColor::red, GLColor::red,
1244 GLColor::green, GLColor::green, GLColor::red, GLColor::red};
1245
1246 glBindTexture(GL_TEXTURE_2D_ARRAY, sourceTexture);
1247 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1248 rgbaPixels);
1249 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1250 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1251 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
1252 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
1253 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1254 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1255 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1256
1257 drawQuad(mProgram, "position", 1.0f);
1258
1259 int width = getWindowWidth() - 1;
1260 int height = getWindowHeight() - 1;
1261
1262 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1263 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::red);
1264 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::red);
1265 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::red);
1266
1267 EXPECT_GL_NO_ERROR();
1268
1269 glActiveTexture(GL_TEXTURE0);
1270 glBindTexture(GL_TEXTURE_2D_ARRAY, destTexture);
1271 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1272 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1273 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1274 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
1275 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
1276 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1277 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1278 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1279 EXPECT_GL_NO_ERROR();
1280
1281 // Flip the y coordinate. This will put the greem half on top, and the red half on the bottom.
1282 glCopyTexture3DANGLE(sourceTexture, 0, GL_TEXTURE_2D_ARRAY, destTexture, 0, GL_RGBA,
1283 GL_UNSIGNED_BYTE, true, false, false);
1284
1285 glBindTexture(GL_TEXTURE_2D_ARRAY, destTexture);
1286 EXPECT_GL_NO_ERROR();
1287 drawQuad(mProgram, "position", 1.0f);
1288
1289 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1290 EXPECT_PIXEL_COLOR_EQ(0, height, GLColor::green);
1291 EXPECT_PIXEL_COLOR_EQ(width, 0, GLColor::green);
1292 EXPECT_PIXEL_COLOR_EQ(width, height, GLColor::green);
1293 }
1294
1295 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_2D_ARRAY with
1296 // unsized formats.
TEST_P(Texture2DArrayCopy,UnsizedFormats)1297 TEST_P(Texture2DArrayCopy, UnsizedFormats)
1298 {
1299 ANGLE_SKIP_TEST_IF(!checkExtensions());
1300
1301 testUnsizedFormats(GL_TEXTURE_2D_ARRAY);
1302 }
1303
1304 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_2D_ARRAY with
1305 // snorm formats.
TEST_P(Texture2DArrayCopy,SnormFormats)1306 TEST_P(Texture2DArrayCopy, SnormFormats)
1307 {
1308 ANGLE_SKIP_TEST_IF(!checkExtensions());
1309
1310 testSnormFormats(GL_TEXTURE_2D_ARRAY);
1311 }
1312
1313 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_2D_ARRAY with
1314 // unsigned byte formats.
TEST_P(Texture2DArrayCopy,UnsignedByteFormats)1315 TEST_P(Texture2DArrayCopy, UnsignedByteFormats)
1316 {
1317 ANGLE_SKIP_TEST_IF(!checkExtensions());
1318
1319 // Flay on Windows D3D11. http://anglebug.com/40644660
1320 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
1321
1322 testUnsignedByteFormats(GL_TEXTURE_2D_ARRAY);
1323 }
1324
1325 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_2D_ARRAY with
1326 // float formats.
TEST_P(Texture2DArrayCopy,FloatFormats)1327 TEST_P(Texture2DArrayCopy, FloatFormats)
1328 {
1329 ANGLE_SKIP_TEST_IF(!checkExtensions());
1330
1331 testFloatFormats(GL_TEXTURE_2D_ARRAY);
1332 }
1333
1334 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_2D_ARRAY with
1335 // integer formats.
TEST_P(Texture2DArrayCopy,IntFormats)1336 TEST_P(Texture2DArrayCopy, IntFormats)
1337 {
1338 ANGLE_SKIP_TEST_IF(!checkExtensions());
1339
1340 // Vulkan multiplies source by 255 unconditionally, which is wrong for signed integer formats.
1341 // http://anglebug.com/42263339
1342 ANGLE_SKIP_TEST_IF(IsVulkan());
1343
1344 constexpr char kFS[] =
1345 "#version 300 es\n"
1346 "precision highp float;\n"
1347 "uniform highp isampler2DArray tex2DArray;\n"
1348 "in vec3 texcoord;\n"
1349 "out ivec4 fragColor;\n"
1350 "void main()\n"
1351 "{\n"
1352 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.z, texcoord.y));\n"
1353 "}\n";
1354
1355 mProgram = CompileProgram(getVertexShaderSource(), kFS);
1356 ASSERT_NE(0u, mProgram);
1357 ASSERT_GL_NO_ERROR();
1358
1359 glUseProgram(mProgram);
1360
1361 testIntFormats(GL_TEXTURE_2D_ARRAY);
1362 }
1363
1364 // Test passthrough, premultiply alpha, and unmultiply alpha copies for GL_TEXTURE_2D_ARRAY with
1365 // unsigned integer formats.
TEST_P(Texture2DArrayCopy,UintFormats)1366 TEST_P(Texture2DArrayCopy, UintFormats)
1367 {
1368 ANGLE_SKIP_TEST_IF(!checkExtensions());
1369
1370 // Vulkan multiplies source by 255 unconditionally, which is wrong for non-8-bit integer
1371 // formats. http://anglebug.com/42263339
1372 ANGLE_SKIP_TEST_IF(IsVulkan());
1373
1374 constexpr char kFS[] =
1375 "#version 300 es\n"
1376 "precision highp float;\n"
1377 "uniform highp usampler2DArray tex2DArray;\n"
1378 "in vec3 texcoord;\n"
1379 "out uvec4 fragColor;\n"
1380 "void main()\n"
1381 "{\n"
1382 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.z, texcoord.y));\n"
1383 "}\n";
1384
1385 mProgram = CompileProgram(getVertexShaderSource(), kFS);
1386 ASSERT_NE(0u, mProgram);
1387 ASSERT_GL_NO_ERROR();
1388
1389 glUseProgram(mProgram);
1390
1391 testUintFormats(GL_TEXTURE_2D_ARRAY);
1392 }
1393
1394 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DCopy);
1395 ANGLE_INSTANTIATE_TEST_ES3(Texture3DCopy);
1396
1397 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayCopy);
1398 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayCopy);
1399
1400 } // namespace angle
1401