1 //
2 // Copyright 2015 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 #include "common/mathutil.h"
8 #include "test_utils/ANGLETest.h"
9 #include "test_utils/gl_raii.h"
10
11 #include <limits>
12
13 using namespace angle;
14
15 namespace
16 {
17
18 constexpr GLuint kPixelTolerance = 1u;
19 constexpr GLfloat kPixelTolerance32F = 0.01f;
20
21 // Single compressed ETC2 block of source pixels all set red
22 constexpr uint8_t kCompressedImageETC2[] = {0x7E, 0x80, 0x04, 0x7F, 0x00, 0x07, 0xE0, 0x00};
23
24 // Take a pixel, and reset the components not covered by the format to default
25 // values. In particular, the default value for the alpha component is 255
26 // (1.0 as unsigned normalized fixed point value).
27 // For legacy formats, the components may be reordered to match the color that
28 // would be created if a pixel of that format was initialized from the given color
SliceFormatColor(GLenum format,GLColor full)29 GLColor SliceFormatColor(GLenum format, GLColor full)
30 {
31 switch (format)
32 {
33 case GL_RED:
34 return GLColor(full.R, 0, 0, 255u);
35 case GL_RG:
36 return GLColor(full.R, full.G, 0, 255u);
37 case GL_RGB:
38 return GLColor(full.R, full.G, full.B, 255u);
39 case GL_RGBA:
40 return full;
41 case GL_LUMINANCE:
42 return GLColor(full.R, full.R, full.R, 255u);
43 case GL_ALPHA:
44 return GLColor(0, 0, 0, full.R);
45 case GL_LUMINANCE_ALPHA:
46 return GLColor(full.R, full.R, full.R, full.G);
47 default:
48 EXPECT_TRUE(false);
49 return GLColor::white;
50 }
51 }
52
SliceFormatColor16(GLenum format,GLColor16 full)53 GLColor16 SliceFormatColor16(GLenum format, GLColor16 full)
54 {
55 switch (format)
56 {
57 case GL_RED:
58 return GLColor16(full.R, 0, 0, 0xFFFF);
59 case GL_RG:
60 return GLColor16(full.R, full.G, 0, 0xFFFF);
61 case GL_RGB:
62 return GLColor16(full.R, full.G, full.B, 0xFFFF);
63 case GL_RGBA:
64 return full;
65 case GL_LUMINANCE:
66 return GLColor16(full.R, full.R, full.R, 0xFFFF);
67 case GL_ALPHA:
68 return GLColor16(0, 0, 0, full.R);
69 case GL_LUMINANCE_ALPHA:
70 return GLColor16(full.R, full.R, full.R, full.G);
71 default:
72 EXPECT_TRUE(false);
73 return GLColor16(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
74 }
75 }
76
77 // As above, for 32F colors
SliceFormatColor32F(GLenum format,GLColor32F full)78 GLColor32F SliceFormatColor32F(GLenum format, GLColor32F full)
79 {
80 switch (format)
81 {
82 case GL_RED:
83 return GLColor32F(full.R, 0.0f, 0.0f, 1.0f);
84 case GL_RG:
85 return GLColor32F(full.R, full.G, 0.0f, 1.0f);
86 case GL_RGB:
87 return GLColor32F(full.R, full.G, full.B, 1.0f);
88 case GL_RGBA:
89 return full;
90 case GL_LUMINANCE:
91 return GLColor32F(full.R, full.R, full.R, 1.0f);
92 case GL_ALPHA:
93 return GLColor32F(0.0f, 0.0f, 0.0f, full.R);
94 case GL_LUMINANCE_ALPHA:
95 return GLColor32F(full.R, full.R, full.R, full.G);
96 default:
97 EXPECT_TRUE(false);
98 return GLColor32F(1.0f, 1.0f, 1.0f, 1.0f);
99 }
100 }
101
102 class TexCoordDrawTest : public ANGLETest<>
103 {
104 protected:
TexCoordDrawTest()105 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
106 {
107 setWindowWidth(128);
108 setWindowHeight(128);
109 setConfigRedBits(8);
110 setConfigGreenBits(8);
111 setConfigBlueBits(8);
112 setConfigAlphaBits(8);
113 }
114
getVertexShaderSource()115 virtual const char *getVertexShaderSource()
116 {
117 return R"(precision highp float;
118 attribute vec4 position;
119 varying vec2 texcoord;
120
121 void main()
122 {
123 gl_Position = vec4(position.xy, 0.0, 1.0);
124 texcoord = (position.xy * 0.5) + 0.5;
125 })";
126 }
127
128 virtual const char *getFragmentShaderSource() = 0;
129
setUpProgram()130 virtual void setUpProgram()
131 {
132 const char *vertexShaderSource = getVertexShaderSource();
133 const char *fragmentShaderSource = getFragmentShaderSource();
134
135 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
136 ASSERT_NE(0u, mProgram);
137 ASSERT_GL_NO_ERROR();
138 }
139
testSetUp()140 void testSetUp() override { setUpFramebuffer(); }
141
testTearDown()142 void testTearDown() override
143 {
144 glBindFramebuffer(GL_FRAMEBUFFER, 0);
145 glDeleteFramebuffers(1, &mFramebuffer);
146 glDeleteTextures(1, &mFramebufferColorTexture);
147 glDeleteProgram(mProgram);
148 }
149
setUpFramebuffer()150 void setUpFramebuffer()
151 {
152 // We use an FBO to work around an issue where the default framebuffer applies SRGB
153 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
154 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
155 // section 4.4 says that the format of the default framebuffer is entirely up to the window
156 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
157 // SRGB conversion like desktop GL does.
158 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
159 glGenFramebuffers(1, &mFramebuffer);
160 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
161
162 glGenTextures(1, &mFramebufferColorTexture);
163 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
164 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
165 GL_UNSIGNED_BYTE, nullptr);
166 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
167 mFramebufferColorTexture, 0);
168 ASSERT_GL_NO_ERROR();
169 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
170 glBindTexture(GL_TEXTURE_2D, 0);
171 }
172
173 // Returns the created texture ID.
create2DTexture()174 GLuint create2DTexture()
175 {
176 GLuint texture2D;
177 glGenTextures(1, &texture2D);
178 glBindTexture(GL_TEXTURE_2D, texture2D);
179 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
180 EXPECT_GL_NO_ERROR();
181 return texture2D;
182 }
183
184 GLuint mProgram;
185 GLuint mFramebuffer;
186
187 protected:
188 GLuint mFramebufferColorTexture;
189 };
190
191 class Texture2DTest : public TexCoordDrawTest
192 {
193 protected:
Texture2DTest()194 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
195
getFragmentShaderSource()196 const char *getFragmentShaderSource() override
197 {
198 return R"(precision highp float;
199 uniform sampler2D tex;
200 varying vec2 texcoord;
201
202 void main()
203 {
204 gl_FragColor = texture2D(tex, texcoord);
205 })";
206 }
207
getTextureUniformName()208 virtual const char *getTextureUniformName() { return "tex"; }
209
setUpProgram()210 void setUpProgram() override
211 {
212 TexCoordDrawTest::setUpProgram();
213 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
214 ASSERT_NE(-1, mTexture2DUniformLocation);
215 }
216
testSetUp()217 void testSetUp() override
218 {
219 TexCoordDrawTest::testSetUp();
220 mTexture2D = create2DTexture();
221
222 ASSERT_GL_NO_ERROR();
223 }
224
testTearDown()225 void testTearDown() override
226 {
227 glDeleteTextures(1, &mTexture2D);
228 TexCoordDrawTest::testTearDown();
229 }
230
231 // Tests CopyTexSubImage with floating point textures of various formats.
testFloatCopySubImage(int sourceImageChannels,int destImageChannels)232 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
233 {
234 setUpProgram();
235
236 if (getClientMajorVersion() < 3)
237 {
238 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
239 !IsGLExtensionEnabled("GL_OES_texture_float"));
240
241 ANGLE_SKIP_TEST_IF((sourceImageChannels < 3 || destImageChannels < 3) &&
242 !IsGLExtensionEnabled("GL_EXT_texture_rg"));
243
244 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
245 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
246
247 ANGLE_SKIP_TEST_IF(destImageChannels == 4 &&
248 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"));
249
250 ANGLE_SKIP_TEST_IF(destImageChannels <= 2);
251 }
252 else
253 {
254 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_color_buffer_float"));
255
256 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
257 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
258 }
259
260 // clang-format off
261 GLfloat sourceImageData[4][16] =
262 {
263 { // R
264 1.0f,
265 0.0f,
266 0.0f,
267 1.0f
268 },
269 { // RG
270 1.0f, 0.0f,
271 0.0f, 1.0f,
272 0.0f, 0.0f,
273 1.0f, 1.0f
274 },
275 { // RGB
276 1.0f, 0.0f, 0.0f,
277 0.0f, 1.0f, 0.0f,
278 0.0f, 0.0f, 1.0f,
279 1.0f, 1.0f, 0.0f
280 },
281 { // RGBA
282 1.0f, 0.0f, 0.0f, 1.0f,
283 0.0f, 1.0f, 0.0f, 1.0f,
284 0.0f, 0.0f, 1.0f, 1.0f,
285 1.0f, 1.0f, 0.0f, 1.0f
286 },
287 };
288 // clang-format on
289
290 GLenum imageFormats[] = {
291 GL_R32F,
292 GL_RG32F,
293 GL_RGB32F,
294 GL_RGBA32F,
295 };
296
297 GLenum sourceUnsizedFormats[] = {
298 GL_RED,
299 GL_RG,
300 GL_RGB,
301 GL_RGBA,
302 };
303
304 GLTexture textures[2];
305
306 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
307 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
308 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
309 GLenum destImageFormat = imageFormats[destImageChannels - 1];
310
311 glBindTexture(GL_TEXTURE_2D, textures[0]);
312 if (getClientMajorVersion() >= 3)
313 {
314 glTexStorage2D(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
315 }
316 else
317 {
318 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
319 }
320 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
321 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
322 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
323
324 if (sourceImageChannels < 3 && !IsGLExtensionEnabled("GL_EXT_texture_rg"))
325 {
326 // This is not supported
327 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
328 }
329 else
330 {
331 ASSERT_GL_NO_ERROR();
332 }
333
334 GLuint fbo;
335 glGenFramebuffers(1, &fbo);
336 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
337 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
338
339 glBindTexture(GL_TEXTURE_2D, textures[1]);
340 if (getClientMajorVersion() >= 3)
341 {
342 glTexStorage2D(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
343 }
344 else
345 {
346 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
347 }
348 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350
351 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
352 ASSERT_GL_NO_ERROR();
353
354 glBindFramebuffer(GL_FRAMEBUFFER, 0);
355 drawQuad(mProgram, "position", 0.5f);
356
357 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
358
359 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
360 if (testImageChannels > 1)
361 {
362 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
363 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
364 if (testImageChannels > 2)
365 {
366 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
367 }
368 }
369
370 glDeleteFramebuffers(1, &fbo);
371
372 ASSERT_GL_NO_ERROR();
373 }
374
375 void testTextureSize(int testCaseIndex);
376 void testTextureSizeError();
377
378 struct UploadThenUseStageParam
379 {
380 GLenum useStage;
381 bool closeRenderPassAfterUse;
382 };
383
384 void testUploadThenUseInDifferentStages(const std::vector<UploadThenUseStageParam> &uses);
385
386 GLuint mTexture2D;
387 GLint mTexture2DUniformLocation;
388 };
389
390 class Texture2DTestES3 : public Texture2DTest
391 {
392 protected:
Texture2DTestES3()393 Texture2DTestES3() : Texture2DTest() {}
394
getVertexShaderSource()395 const char *getVertexShaderSource() override
396 {
397 return "#version 300 es\n"
398 "out vec2 texcoord;\n"
399 "in vec4 position;\n"
400 "void main()\n"
401 "{\n"
402 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
403 " texcoord = (position.xy * 0.5) + 0.5;\n"
404 "}\n";
405 }
406
getFragmentShaderSource()407 const char *getFragmentShaderSource() override
408 {
409 return "#version 300 es\n"
410 "precision highp float;\n"
411 "uniform highp sampler2D tex;\n"
412 "in vec2 texcoord;\n"
413 "out vec4 fragColor;\n"
414 "void main()\n"
415 "{\n"
416 " fragColor = texture(tex, texcoord);\n"
417 "}\n";
418 }
419
testSetUp()420 void testSetUp() override
421 {
422 Texture2DTest::testSetUp();
423 setUpProgram();
424 }
425
createImmutableTexture2D(GLuint texture,size_t width,size_t height,GLenum format,GLenum internalFormat,GLenum type,GLsizei levels,GLubyte data[4])426 void createImmutableTexture2D(GLuint texture,
427 size_t width,
428 size_t height,
429 GLenum format,
430 GLenum internalFormat,
431 GLenum type,
432 GLsizei levels,
433 GLubyte data[4])
434 {
435 // Support only 1 level for now
436 ASSERT(levels == 1);
437
438 glBindTexture(GL_TEXTURE_2D, texture);
439
440 glTexStorage2D(GL_TEXTURE_2D, levels, internalFormat, width, height);
441 ASSERT_GL_NO_ERROR();
442
443 if (data != nullptr)
444 {
445 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data);
446 ASSERT_GL_NO_ERROR();
447 }
448
449 // Disable mipmapping
450 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
451 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
452 ASSERT_GL_NO_ERROR();
453 }
454
verifyResults2D(GLuint texture,GLubyte referenceColor[4])455 void verifyResults2D(GLuint texture, GLubyte referenceColor[4])
456 {
457 // Draw a quad with the target texture
458 glUseProgram(mProgram);
459 glBindTexture(GL_TEXTURE_2D, texture);
460 glUniform1i(mTexture2DUniformLocation, 0);
461
462 drawQuad(mProgram, "position", 0.5f);
463
464 // Expect that the rendered quad's color is the same as the reference color with a tolerance
465 // of 1
466 EXPECT_PIXEL_NEAR(0, 0, referenceColor[0], referenceColor[1], referenceColor[2],
467 referenceColor[3], 1);
468 }
469
470 void testCopyImage(const APIExtensionVersion usedExtension);
471 void testCopyImageDepthStencil(const APIExtensionVersion usedExtension);
472 };
473
474 class MultisampleTexture2DTestES31 : public Texture2DTest
475 {
476 protected:
MultisampleTexture2DTestES31()477 MultisampleTexture2DTestES31() : Texture2DTest() {}
478
479 void testCopyMultisampleImage(const APIExtensionVersion usedExtension,
480 const GLenum internalFormat);
481 void testCopyMultisampleArrayImage(const APIExtensionVersion usedExtension,
482 const GLenum internalFormat);
483 };
484
485 class Texture2DMemoryTestES3 : public Texture2DTestES3
486 {
487 protected:
getPerfCounters()488 angle::VulkanPerfCounters getPerfCounters()
489 {
490 if (mIndexMap.empty())
491 {
492 mIndexMap = BuildCounterNameToIndexMap();
493 }
494
495 return GetPerfCounters(mIndexMap);
496 }
497
498 CounterNameToIndexMap mIndexMap;
499 };
500
501 class Texture2DTestES3YUV : public Texture2DTestES3
502 {};
503
504 class Texture2DTestES3RobustInit : public Texture2DTestES3
505 {
506 protected:
Texture2DTestES3RobustInit()507 Texture2DTestES3RobustInit() : Texture2DTestES3() { setRobustResourceInit(true); }
508 };
509
510 class Texture2DTestES3Foveation : public Texture2DTestES3
511 {
512 protected:
Texture2DTestES3Foveation()513 Texture2DTestES3Foveation() : Texture2DTestES3()
514 {
515 setWindowWidth(256);
516 setWindowHeight(256);
517 }
518 };
519
520 class Texture2DTestES31Foveation : public Texture2DTestES3Foveation
521 {};
522
523 class Texture2DBaseMaxTestES3 : public ANGLETest<>
524 {
525 protected:
526 static constexpr size_t kMip0Size = 13;
527 static constexpr uint32_t kMipCount = 4;
528
Texture2DBaseMaxTestES3()529 Texture2DBaseMaxTestES3() : ANGLETest(), mTextureLocation(0), mLodLocation(0)
530 {
531 setWindowWidth(128);
532 setWindowHeight(128);
533 setConfigRedBits(8);
534 setConfigGreenBits(8);
535 setConfigBlueBits(8);
536 setConfigAlphaBits(8);
537 }
538
getMipDataSize(size_t mip0Size,size_t mip)539 static constexpr size_t getMipDataSize(size_t mip0Size, size_t mip)
540 {
541 size_t mipSize = std::max<size_t>(1u, mip0Size >> mip);
542 return mipSize * mipSize;
543 }
544
getTotalMipDataSize(size_t mip0Size)545 static constexpr size_t getTotalMipDataSize(size_t mip0Size)
546 {
547 size_t totalCount = 0;
548 for (size_t mip = 0; mip < kMipCount; ++mip)
549 {
550 totalCount += getMipDataSize(mip0Size, mip);
551 }
552 return totalCount;
553 }
554
getMipDataOffset(size_t mip0Size,size_t mip)555 static constexpr size_t getMipDataOffset(size_t mip0Size, size_t mip)
556 {
557 // This calculates:
558 //
559 // mip == 0: 0
560 // o.w.: sum(0, mip-1) getMipDataSize(i)
561 //
562 // The above can be calculated simply as:
563 //
564 // (mip0 >> (kMipCount-1))^2 * (0x55555555 & ((1 << (2*mip)) - 1))
565 // \__________ ___________/ \_______________ ________________/
566 // \/ \/
567 // last mip size sum(0, mip-1) (4^i)
568 //
569 // But let's loop explicitly for clarity.
570 size_t offset = 0;
571 for (size_t m = 0; m < mip; ++m)
572 {
573 offset += getMipDataSize(mip0Size, m);
574 }
575 return offset;
576 }
577
578 template <typename colorType = GLColor>
fillMipData(colorType * data,size_t mip0Size,const colorType mipColors[kMipCount])579 void fillMipData(colorType *data, size_t mip0Size, const colorType mipColors[kMipCount])
580 {
581 for (size_t mip = 0; mip < kMipCount; ++mip)
582 {
583 size_t offset = getMipDataOffset(mip0Size, mip);
584 size_t size = getMipDataSize(mip0Size, mip);
585 std::fill(data + offset, data + offset + size, mipColors[mip]);
586 }
587 }
588
initTest(bool immutable)589 void initTest(bool immutable)
590 {
591 // Set up program to sample from specific lod level.
592 mProgram.makeRaster(essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
593 ASSERT(mProgram.valid());
594
595 glUseProgram(mProgram);
596
597 mTextureLocation = glGetUniformLocation(mProgram, essl3_shaders::Texture2DUniform());
598 ASSERT_NE(-1, mTextureLocation);
599
600 mLodLocation = glGetUniformLocation(mProgram, essl3_shaders::LodUniform());
601 ASSERT_NE(-1, mLodLocation);
602
603 // Set up texture with a handful of lods.
604 glActiveTexture(GL_TEXTURE0);
605 glBindTexture(GL_TEXTURE_2D, mTexture);
606
607 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
608 fillMipData(mipData.data(), kMip0Size, kMipColors);
609
610 if (immutable)
611 {
612 glTexStorage2D(GL_TEXTURE_2D, kMipCount, GL_RGBA8, kMip0Size, kMip0Size);
613 for (size_t mip = 0; mip < kMipCount; ++mip)
614 {
615 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip,
616 GL_RGBA, GL_UNSIGNED_BYTE,
617 mipData.data() + getMipDataOffset(kMip0Size, mip));
618 }
619 }
620 else
621 {
622 for (size_t mip = 0; mip < kMipCount; ++mip)
623 {
624 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0,
625 GL_RGBA, GL_UNSIGNED_BYTE,
626 mipData.data() + getMipDataOffset(kMip0Size, mip));
627 }
628 }
629
630 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
631 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
632
633 EXPECT_GL_NO_ERROR();
634 }
635
setLodUniform(uint32_t lod)636 void setLodUniform(uint32_t lod) { glUniform1f(mLodLocation, lod); }
637
638 void testPingPongBaseLevel(bool immutable);
639 void testGenerateMipmapAfterRebase(bool immutable);
640
641 GLProgram mProgram;
642 GLTexture mTexture;
643 GLint mTextureLocation;
644 GLint mLodLocation;
645
646 const GLColor kMipColors[kMipCount] = {
647 GLColor::red,
648 GLColor::green,
649 GLColor::blue,
650 GLColor::magenta,
651 };
652 };
653
654 class TextureES31PPO
655 {
656 protected:
TextureES31PPO()657 TextureES31PPO() : mVertProg(0), mFragProg(0), mPipeline(0) {}
658
get2DTexturedVertexShaderSource()659 const char *get2DTexturedVertexShaderSource()
660 {
661 return "#version 310 es\n"
662 "precision mediump float;\n"
663 "in vec2 position;\n"
664 "out vec2 texCoord;\n"
665 "void main()\n"
666 "{\n"
667 " gl_Position = vec4(position, 0, 1);\n"
668 " texCoord = position * 0.5 + vec2(0.5);\n"
669 "}";
670 }
671
get2DTexturedFragmentShaderSource()672 const char *get2DTexturedFragmentShaderSource()
673 {
674 return "#version 310 es\n"
675 "precision mediump float;\n"
676 "in vec2 texCoord;\n"
677 "uniform sampler2D tex1;\n"
678 "uniform sampler2D tex2;\n"
679 "uniform sampler2D tex3;\n"
680 "uniform sampler2D tex4;\n"
681 "out vec4 color;\n"
682 "void main()\n"
683 "{\n"
684 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
685 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
686 "}";
687 }
688
bindProgramPipeline(const GLchar * vertString,const GLchar * fragString)689 void bindProgramPipeline(const GLchar *vertString, const GLchar *fragString)
690 {
691 mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
692 ASSERT_NE(mVertProg, 0u);
693 mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
694 ASSERT_NE(mFragProg, 0u);
695
696 // Generate a program pipeline and attach the programs to their respective stages
697 glGenProgramPipelines(1, &mPipeline);
698 EXPECT_GL_NO_ERROR();
699 glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
700 EXPECT_GL_NO_ERROR();
701 glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
702 EXPECT_GL_NO_ERROR();
703 glBindProgramPipeline(mPipeline);
704 EXPECT_GL_NO_ERROR();
705 }
706
bind2DTexturedQuadProgramPipeline()707 void bind2DTexturedQuadProgramPipeline()
708 {
709 const char *vertexShaderSource = get2DTexturedVertexShaderSource();
710 const char *fragmentShaderSource = get2DTexturedFragmentShaderSource();
711
712 m2DTexturedQuadVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertexShaderSource);
713 ASSERT_NE(m2DTexturedQuadVertProg, 0u);
714 m2DTexturedQuadFragProg =
715 glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentShaderSource);
716 ASSERT_NE(m2DTexturedQuadFragProg, 0u);
717
718 // Generate a program pipeline and attach the programs to their respective stages
719 glGenProgramPipelines(1, &m2DTexturedQuadPipeline);
720 EXPECT_GL_NO_ERROR();
721 glUseProgramStages(m2DTexturedQuadPipeline, GL_VERTEX_SHADER_BIT, m2DTexturedQuadVertProg);
722 EXPECT_GL_NO_ERROR();
723 glUseProgramStages(m2DTexturedQuadPipeline, GL_FRAGMENT_SHADER_BIT,
724 m2DTexturedQuadFragProg);
725 EXPECT_GL_NO_ERROR();
726 glBindProgramPipeline(m2DTexturedQuadPipeline);
727 EXPECT_GL_NO_ERROR();
728 }
729
ppoDrawQuad(std::array<Vector3,6> & quadVertices,const std::string & positionAttribName,const GLfloat positionAttribZ,const GLfloat positionAttribXYScale)730 void ppoDrawQuad(std::array<Vector3, 6> &quadVertices,
731 const std::string &positionAttribName,
732 const GLfloat positionAttribZ,
733 const GLfloat positionAttribXYScale)
734 {
735 glUseProgram(0);
736
737 for (Vector3 &vertex : quadVertices)
738 {
739 vertex.x() *= positionAttribXYScale;
740 vertex.y() *= positionAttribXYScale;
741 vertex.z() = positionAttribZ;
742 }
743
744 GLint positionLocation = glGetAttribLocation(mVertProg, positionAttribName.c_str());
745
746 glBindBuffer(GL_ARRAY_BUFFER, 0);
747 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
748 glEnableVertexAttribArray(positionLocation);
749
750 glDrawArrays(GL_TRIANGLES, 0, 6);
751
752 glDisableVertexAttribArray(positionLocation);
753 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
754 }
755
756 GLuint mVertProg;
757 GLuint mFragProg;
758 GLuint mPipeline;
759 GLuint m2DTexturedQuadVertProg;
760 GLuint m2DTexturedQuadFragProg;
761 GLuint m2DTexturedQuadPipeline;
762 };
763
764 class Texture2DTestES31PPO : public TextureES31PPO, public Texture2DTest
765 {
766 protected:
Texture2DTestES31PPO()767 Texture2DTestES31PPO() : TextureES31PPO(), Texture2DTest() {}
768
testSetUp()769 void testSetUp() override { Texture2DTest::testSetUp(); }
770 };
771
772 class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
773 {
774 protected:
Texture2DIntegerAlpha1TestES3()775 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
776
getVertexShaderSource()777 const char *getVertexShaderSource() override
778 {
779 return "#version 300 es\n"
780 "out vec2 texcoord;\n"
781 "in vec4 position;\n"
782 "void main()\n"
783 "{\n"
784 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
785 " texcoord = (position.xy * 0.5) + 0.5;\n"
786 "}\n";
787 }
788
getFragmentShaderSource()789 const char *getFragmentShaderSource() override
790 {
791 return "#version 300 es\n"
792 "precision highp float;\n"
793 "uniform highp isampler2D tex;\n"
794 "in vec2 texcoord;\n"
795 "out vec4 fragColor;\n"
796 "void main()\n"
797 "{\n"
798 " vec4 green = vec4(0, 1, 0, 1);\n"
799 " vec4 black = vec4(0, 0, 0, 0);\n"
800 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
801 "}\n";
802 }
803
testSetUp()804 void testSetUp() override
805 {
806 Texture2DTest::testSetUp();
807 setUpProgram();
808 }
809 };
810
811 class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
812 {
813 protected:
Texture2DUnsignedIntegerAlpha1TestES3()814 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
815
getVertexShaderSource()816 const char *getVertexShaderSource() override
817 {
818 return "#version 300 es\n"
819 "out vec2 texcoord;\n"
820 "in vec4 position;\n"
821 "void main()\n"
822 "{\n"
823 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
824 " texcoord = (position.xy * 0.5) + 0.5;\n"
825 "}\n";
826 }
827
getFragmentShaderSource()828 const char *getFragmentShaderSource() override
829 {
830 return "#version 300 es\n"
831 "precision highp float;\n"
832 "uniform highp usampler2D tex;\n"
833 "in vec2 texcoord;\n"
834 "out vec4 fragColor;\n"
835 "void main()\n"
836 "{\n"
837 " vec4 green = vec4(0, 1, 0, 1);\n"
838 " vec4 black = vec4(0, 0, 0, 0);\n"
839 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
840 "}\n";
841 }
842
testSetUp()843 void testSetUp() override
844 {
845 Texture2DTest::testSetUp();
846 setUpProgram();
847 }
848 };
849
850 class Texture2DTestWithDrawScale : public Texture2DTest
851 {
852 protected:
Texture2DTestWithDrawScale()853 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
854
getVertexShaderSource()855 const char *getVertexShaderSource() override
856 {
857 return
858 R"(precision highp float;
859 attribute vec4 position;
860 varying vec2 texcoord;
861
862 uniform vec2 drawScale;
863
864 void main()
865 {
866 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
867 texcoord = (position.xy * 0.5) + 0.5;
868 })";
869 }
870
testSetUp()871 void testSetUp() override
872 {
873 Texture2DTest::testSetUp();
874
875 setUpProgram();
876
877 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
878 ASSERT_NE(-1, mDrawScaleUniformLocation);
879
880 glUseProgram(mProgram);
881 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
882 glUseProgram(0);
883 ASSERT_GL_NO_ERROR();
884 }
885
886 GLint mDrawScaleUniformLocation;
887 };
888
889 class Sampler2DAsFunctionParameterTest : public Texture2DTest
890 {
891 protected:
Sampler2DAsFunctionParameterTest()892 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
893
getFragmentShaderSource()894 const char *getFragmentShaderSource() override
895 {
896 return
897 R"(precision highp float;
898 uniform sampler2D tex;
899 varying vec2 texcoord;
900
901 vec4 computeFragColor(sampler2D aTex)
902 {
903 return texture2D(aTex, texcoord);
904 }
905
906 void main()
907 {
908 gl_FragColor = computeFragColor(tex);
909 })";
910 }
911
testSetUp()912 void testSetUp() override
913 {
914 Texture2DTest::testSetUp();
915 setUpProgram();
916 }
917 };
918
919 class TextureCubeTest : public TexCoordDrawTest
920 {
921 protected:
TextureCubeTest()922 TextureCubeTest()
923 : TexCoordDrawTest(),
924 mTexture2D(0),
925 mTextureCube(0),
926 mTexture2DUniformLocation(-1),
927 mTextureCubeUniformLocation(-1)
928 {}
929
getFragmentShaderSource()930 const char *getFragmentShaderSource() override
931 {
932 return
933 R"(precision highp float;
934 uniform sampler2D tex2D;
935 uniform samplerCube texCube;
936 uniform int cubeFace;
937 varying vec2 texcoord;
938
939 void main()
940 {
941 gl_FragColor = texture2D(tex2D, texcoord);
942
943 vec2 scaled = vec2(1) - vec2(2) * texcoord.xy;
944 vec3 cubecoord = vec3(1, scaled.xy);
945 if (cubeFace == 1)
946 cubecoord = vec3(-1, scaled.xy);
947 else if (cubeFace == 2)
948 cubecoord = vec3(scaled.x, 1, scaled.y);
949 else if (cubeFace == 3)
950 cubecoord = vec3(scaled.x, -1, scaled.y);
951 else if (cubeFace == 4)
952 cubecoord = vec3(scaled.xy, 1);
953 else if (cubeFace == 5)
954 cubecoord = vec3(scaled.xy, -1);
955
956 gl_FragColor += textureCube(texCube, cubecoord);
957 })";
958 }
959
testSetUp()960 void testSetUp() override
961 {
962 TexCoordDrawTest::testSetUp();
963
964 glGenTextures(1, &mTextureCube);
965 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
966 for (GLenum face = 0; face < 6; face++)
967 {
968 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
969 GL_UNSIGNED_BYTE, nullptr);
970 }
971 EXPECT_GL_NO_ERROR();
972
973 mTexture2D = create2DTexture();
974
975 setUpProgram();
976
977 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
978 ASSERT_NE(-1, mTexture2DUniformLocation);
979 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
980 ASSERT_NE(-1, mTextureCubeUniformLocation);
981 mTextureCubeFaceUniformLocation = glGetUniformLocation(mProgram, "cubeFace");
982 ASSERT_NE(-1, mTextureCubeFaceUniformLocation);
983 }
984
testTearDown()985 void testTearDown() override
986 {
987 glDeleteTextures(1, &mTextureCube);
988 TexCoordDrawTest::testTearDown();
989 }
990
991 GLuint mTexture2D;
992 GLuint mTextureCube;
993 GLint mTexture2DUniformLocation;
994 GLint mTextureCubeUniformLocation;
995 GLint mTextureCubeFaceUniformLocation;
996 };
997
998 class TextureCubeTestES3 : public TextureCubeTest
999 {
1000 protected:
TextureCubeTestES3()1001 TextureCubeTestES3() {}
1002 };
1003
1004 class TextureCubeTestES32 : public TextureCubeTest
1005 {
1006 protected:
TextureCubeTestES32()1007 TextureCubeTestES32() {}
1008 };
1009
1010 class SamplerArrayTest : public TexCoordDrawTest
1011 {
1012 protected:
SamplerArrayTest()1013 SamplerArrayTest()
1014 : TexCoordDrawTest(),
1015 mTexture2DA(0),
1016 mTexture2DB(0),
1017 mTexture0UniformLocation(-1),
1018 mTexture1UniformLocation(-1)
1019 {}
1020
getFragmentShaderSource()1021 const char *getFragmentShaderSource() override
1022 {
1023 return
1024 R"(precision mediump float;
1025 uniform highp sampler2D tex2DArray[2];
1026 varying vec2 texcoord;
1027 void main()
1028 {
1029 gl_FragColor = texture2D(tex2DArray[0], texcoord);
1030 gl_FragColor += texture2D(tex2DArray[1], texcoord);
1031 })";
1032 }
1033
testSetUp()1034 void testSetUp() override
1035 {
1036 TexCoordDrawTest::testSetUp();
1037
1038 setUpProgram();
1039
1040 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
1041 ASSERT_NE(-1, mTexture0UniformLocation);
1042 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
1043 ASSERT_NE(-1, mTexture1UniformLocation);
1044
1045 mTexture2DA = create2DTexture();
1046 mTexture2DB = create2DTexture();
1047 ASSERT_GL_NO_ERROR();
1048 }
1049
testTearDown()1050 void testTearDown() override
1051 {
1052 glDeleteTextures(1, &mTexture2DA);
1053 glDeleteTextures(1, &mTexture2DB);
1054 TexCoordDrawTest::testTearDown();
1055 }
1056
testSamplerArrayDraw()1057 void testSamplerArrayDraw()
1058 {
1059 GLubyte texData[4];
1060 texData[0] = 0;
1061 texData[1] = 60;
1062 texData[2] = 0;
1063 texData[3] = 255;
1064
1065 glActiveTexture(GL_TEXTURE0);
1066 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
1067 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1068
1069 texData[1] = 120;
1070 glActiveTexture(GL_TEXTURE1);
1071 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
1072 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1073 EXPECT_GL_ERROR(GL_NO_ERROR);
1074
1075 glUseProgram(mProgram);
1076 glUniform1i(mTexture0UniformLocation, 0);
1077 glUniform1i(mTexture1UniformLocation, 1);
1078 drawQuad(mProgram, "position", 0.5f);
1079 EXPECT_GL_NO_ERROR();
1080
1081 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
1082 }
1083
1084 GLuint mTexture2DA;
1085 GLuint mTexture2DB;
1086 GLint mTexture0UniformLocation;
1087 GLint mTexture1UniformLocation;
1088 };
1089
1090 class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
1091 {
1092 protected:
SamplerArrayAsFunctionParameterTest()1093 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
1094
getFragmentShaderSource()1095 const char *getFragmentShaderSource() override
1096 {
1097 return
1098 R"(precision mediump float;
1099 uniform highp sampler2D tex2DArray[2];
1100 varying vec2 texcoord;
1101
1102 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
1103 {
1104 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
1105 }
1106
1107 void main()
1108 {
1109 gl_FragColor = computeFragColor(tex2DArray);
1110 })";
1111 }
1112 };
1113
1114 class Texture2DArrayTestES3 : public TexCoordDrawTest
1115 {
1116 protected:
Texture2DArrayTestES3()1117 Texture2DArrayTestES3()
1118 : TexCoordDrawTest(),
1119 m2DArrayTexture(0),
1120 mTextureArrayLocation(-1),
1121 mTextureArraySliceUniformLocation(-1)
1122 {}
1123
getVertexShaderSource()1124 const char *getVertexShaderSource() override
1125 {
1126 return R"(#version 300 es
1127 out vec2 texcoord;
1128 in vec4 position;
1129 void main()
1130 {
1131 gl_Position = vec4(position.xy, 0.0, 1.0);
1132 texcoord = (position.xy * 0.5) + 0.5;
1133 })";
1134 }
1135
getFragmentShaderSource()1136 const char *getFragmentShaderSource() override
1137 {
1138 return R"(#version 300 es
1139 precision highp float;
1140 uniform highp sampler2DArray tex2DArray;
1141 uniform int slice;
1142 in vec2 texcoord;
1143 out vec4 fragColor;
1144 void main()
1145 {
1146 fragColor = texture(tex2DArray, vec3(texcoord, float(slice)));
1147 })";
1148 }
1149
testSetUp()1150 void testSetUp() override
1151 {
1152 TexCoordDrawTest::testSetUp();
1153
1154 setUpProgram();
1155
1156 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
1157 ASSERT_NE(-1, mTextureArrayLocation);
1158
1159 mTextureArraySliceUniformLocation = glGetUniformLocation(mProgram, "slice");
1160 ASSERT_NE(-1, mTextureArraySliceUniformLocation);
1161
1162 glGenTextures(1, &m2DArrayTexture);
1163 ASSERT_GL_NO_ERROR();
1164 }
1165
testTearDown()1166 void testTearDown() override
1167 {
1168 glDeleteTextures(1, &m2DArrayTexture);
1169 TexCoordDrawTest::testTearDown();
1170 }
1171
1172 GLuint m2DArrayTexture;
1173 GLint mTextureArrayLocation;
1174 GLint mTextureArraySliceUniformLocation;
1175 };
1176
1177 class TextureSizeTextureArrayTest : public TexCoordDrawTest
1178 {
1179 protected:
TextureSizeTextureArrayTest()1180 TextureSizeTextureArrayTest()
1181 : TexCoordDrawTest(),
1182 mTexture2DA(0),
1183 mTexture2DB(0),
1184 mTexture0Location(-1),
1185 mTexture1Location(-1)
1186 {}
1187
getVertexShaderSource()1188 const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
1189
getFragmentShaderSource()1190 const char *getFragmentShaderSource() override
1191 {
1192 return "#version 300 es\n"
1193 "precision highp float;\n"
1194 "uniform highp sampler2D tex2DArray[2];\n"
1195 "out vec4 fragColor;\n"
1196 "void main()\n"
1197 "{\n"
1198 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
1199 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
1200 " fragColor = vec4(red, green, 0.0, 1.0);\n"
1201 "}\n";
1202 }
1203
testSetUp()1204 void testSetUp() override
1205 {
1206 TexCoordDrawTest::testSetUp();
1207
1208 setUpProgram();
1209
1210 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
1211 ASSERT_NE(-1, mTexture0Location);
1212 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
1213 ASSERT_NE(-1, mTexture1Location);
1214
1215 mTexture2DA = create2DTexture();
1216 mTexture2DB = create2DTexture();
1217 ASSERT_GL_NO_ERROR();
1218 }
1219
testTearDown()1220 void testTearDown() override
1221 {
1222 glDeleteTextures(1, &mTexture2DA);
1223 glDeleteTextures(1, &mTexture2DB);
1224 TexCoordDrawTest::testTearDown();
1225 }
1226
1227 GLuint mTexture2DA;
1228 GLuint mTexture2DB;
1229 GLint mTexture0Location;
1230 GLint mTexture1Location;
1231 };
1232
1233 // Test for GL_OES_texture_3D extension
1234 class Texture3DTestES2 : public TexCoordDrawTest
1235 {
1236 protected:
Texture3DTestES2()1237 Texture3DTestES2() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
1238
getVertexShaderSource()1239 const char *getVertexShaderSource() override
1240 {
1241 return "#version 100\n"
1242 "varying vec2 texcoord;\n"
1243 "attribute vec4 position;\n"
1244 "void main()\n"
1245 "{\n"
1246 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1247 " texcoord = (position.xy * 0.5) + 0.5;\n"
1248 "}\n";
1249 }
1250
getFragmentShaderSource()1251 const char *getFragmentShaderSource() override
1252 {
1253 if (!hasTexture3DExt())
1254 {
1255 return "#version 100\n"
1256 "precision highp float;\n"
1257 "varying vec2 texcoord;\n"
1258 "void main()\n"
1259 "{\n"
1260 " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1261 "}\n";
1262 }
1263 return "#version 100\n"
1264 "#extension GL_OES_texture_3D : enable\n"
1265 "precision highp float;\n"
1266 "uniform highp sampler3D tex3D;\n"
1267 "uniform highp float level;\n"
1268 "varying vec2 texcoord;\n"
1269 "void main()\n"
1270 "{\n"
1271 " gl_FragColor = texture3DLod(tex3D, vec3(texcoord, 0.0), level);\n"
1272 "}\n";
1273 }
1274
testSetUp()1275 void testSetUp() override
1276 {
1277 // http://anglebug.com/42264265
1278 ANGLE_SKIP_TEST_IF(IsOzone());
1279
1280 TexCoordDrawTest::testSetUp();
1281
1282 glGenTextures(1, &mTexture3D);
1283
1284 setUpProgram();
1285
1286 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1287 if (hasTexture3DExt())
1288 {
1289 ASSERT_NE(-1, mTexture3DUniformLocation);
1290 }
1291 }
1292
testTearDown()1293 void testTearDown() override
1294 {
1295 glDeleteTextures(1, &mTexture3D);
1296 TexCoordDrawTest::testTearDown();
1297 }
1298
hasTexture3DExt() const1299 bool hasTexture3DExt() const
1300 {
1301 // http://anglebug.com/42263501
1302 if ((IsPixel2() || IsNexus5X()) && IsOpenGLES())
1303 {
1304 return false;
1305 }
1306 return IsGLExtensionEnabled("GL_OES_texture_3D");
1307 }
1308
1309 GLuint mTexture3D;
1310 GLint mTexture3DUniformLocation;
1311 };
1312
1313 class Texture3DTestES3 : public Texture3DTestES2
1314 {
1315 protected:
Texture3DTestES3()1316 Texture3DTestES3() : Texture3DTestES2() {}
1317
getVertexShaderSource()1318 const char *getVertexShaderSource() override
1319 {
1320 return "#version 300 es\n"
1321 "out vec2 texcoord;\n"
1322 "in vec4 position;\n"
1323 "void main()\n"
1324 "{\n"
1325 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1326 " texcoord = (position.xy * 0.5) + 0.5;\n"
1327 "}\n";
1328 }
1329
getFragmentShaderSource()1330 const char *getFragmentShaderSource() override
1331 {
1332 return "#version 300 es\n"
1333 "precision highp float;\n"
1334 "uniform highp sampler3D tex3D;\n"
1335 "in vec2 texcoord;\n"
1336 "out vec4 fragColor;\n"
1337 "void main()\n"
1338 "{\n"
1339 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
1340 "}\n";
1341 }
1342 };
1343
1344 class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
1345 {
1346 protected:
ShadowSamplerPlusSampler3DTestES3()1347 ShadowSamplerPlusSampler3DTestES3()
1348 : TexCoordDrawTest(),
1349 mTextureShadow(0),
1350 mTexture3D(0),
1351 mTextureShadowUniformLocation(-1),
1352 mTexture3DUniformLocation(-1),
1353 mDepthRefUniformLocation(-1)
1354 {}
1355
getVertexShaderSource()1356 const char *getVertexShaderSource() override
1357 {
1358 return "#version 300 es\n"
1359 "out vec2 texcoord;\n"
1360 "in vec4 position;\n"
1361 "void main()\n"
1362 "{\n"
1363 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1364 " texcoord = (position.xy * 0.5) + 0.5;\n"
1365 "}\n";
1366 }
1367
getFragmentShaderSource()1368 const char *getFragmentShaderSource() override
1369 {
1370 return "#version 300 es\n"
1371 "precision highp float;\n"
1372 "uniform highp sampler2DShadow tex2DShadow;\n"
1373 "uniform highp sampler3D tex3D;\n"
1374 "in vec2 texcoord;\n"
1375 "uniform float depthRef;\n"
1376 "out vec4 fragColor;\n"
1377 "void main()\n"
1378 "{\n"
1379 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
1380 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
1381 "}\n";
1382 }
1383
testSetUp()1384 void testSetUp() override
1385 {
1386 TexCoordDrawTest::testSetUp();
1387
1388 glGenTextures(1, &mTexture3D);
1389
1390 glGenTextures(1, &mTextureShadow);
1391 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1393
1394 setUpProgram();
1395
1396 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1397 ASSERT_NE(-1, mTextureShadowUniformLocation);
1398 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1399 ASSERT_NE(-1, mTexture3DUniformLocation);
1400 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1401 ASSERT_NE(-1, mDepthRefUniformLocation);
1402 }
1403
testTearDown()1404 void testTearDown() override
1405 {
1406 glDeleteTextures(1, &mTextureShadow);
1407 glDeleteTextures(1, &mTexture3D);
1408 TexCoordDrawTest::testTearDown();
1409 }
1410
1411 GLuint mTextureShadow;
1412 GLuint mTexture3D;
1413 GLint mTextureShadowUniformLocation;
1414 GLint mTexture3DUniformLocation;
1415 GLint mDepthRefUniformLocation;
1416 };
1417
1418 class SamplerTypeMixTestES3 : public TexCoordDrawTest
1419 {
1420 protected:
SamplerTypeMixTestES3()1421 SamplerTypeMixTestES3()
1422 : TexCoordDrawTest(),
1423 mTexture2D(0),
1424 mTextureCube(0),
1425 mTexture2DShadow(0),
1426 mTextureCubeShadow(0),
1427 mTexture2DUniformLocation(-1),
1428 mTextureCubeUniformLocation(-1),
1429 mTexture2DShadowUniformLocation(-1),
1430 mTextureCubeShadowUniformLocation(-1),
1431 mDepthRefUniformLocation(-1)
1432 {}
1433
getVertexShaderSource()1434 const char *getVertexShaderSource() override
1435 {
1436 return "#version 300 es\n"
1437 "out vec2 texcoord;\n"
1438 "in vec4 position;\n"
1439 "void main()\n"
1440 "{\n"
1441 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1442 " texcoord = (position.xy * 0.5) + 0.5;\n"
1443 "}\n";
1444 }
1445
getFragmentShaderSource()1446 const char *getFragmentShaderSource() override
1447 {
1448 return "#version 300 es\n"
1449 "precision highp float;\n"
1450 "uniform highp sampler2D tex2D;\n"
1451 "uniform highp samplerCube texCube;\n"
1452 "uniform highp sampler2DShadow tex2DShadow;\n"
1453 "uniform highp samplerCubeShadow texCubeShadow;\n"
1454 "in vec2 texcoord;\n"
1455 "uniform float depthRef;\n"
1456 "out vec4 fragColor;\n"
1457 "void main()\n"
1458 "{\n"
1459 " fragColor = texture(tex2D, texcoord);\n"
1460 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1461 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1462 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1463 "0.125);\n"
1464 "}\n";
1465 }
1466
testSetUp()1467 void testSetUp() override
1468 {
1469 TexCoordDrawTest::testSetUp();
1470
1471 glGenTextures(1, &mTexture2D);
1472 glGenTextures(1, &mTextureCube);
1473
1474 glGenTextures(1, &mTexture2DShadow);
1475 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1476 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1477
1478 glGenTextures(1, &mTextureCubeShadow);
1479 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1480 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1481
1482 setUpProgram();
1483
1484 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1485 ASSERT_NE(-1, mTexture2DUniformLocation);
1486 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1487 ASSERT_NE(-1, mTextureCubeUniformLocation);
1488 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1489 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1490 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1491 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1492 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1493 ASSERT_NE(-1, mDepthRefUniformLocation);
1494
1495 ASSERT_GL_NO_ERROR();
1496 }
1497
testTearDown()1498 void testTearDown() override
1499 {
1500 glDeleteTextures(1, &mTexture2D);
1501 glDeleteTextures(1, &mTextureCube);
1502 glDeleteTextures(1, &mTexture2DShadow);
1503 glDeleteTextures(1, &mTextureCubeShadow);
1504 TexCoordDrawTest::testTearDown();
1505 }
1506
1507 GLuint mTexture2D;
1508 GLuint mTextureCube;
1509 GLuint mTexture2DShadow;
1510 GLuint mTextureCubeShadow;
1511 GLint mTexture2DUniformLocation;
1512 GLint mTextureCubeUniformLocation;
1513 GLint mTexture2DShadowUniformLocation;
1514 GLint mTextureCubeShadowUniformLocation;
1515 GLint mDepthRefUniformLocation;
1516 };
1517
1518 class SamplerInStructTest : public Texture2DTest
1519 {
1520 protected:
SamplerInStructTest()1521 SamplerInStructTest() : Texture2DTest() {}
1522
getTextureUniformName()1523 const char *getTextureUniformName() override { return "us.tex"; }
1524
getFragmentShaderSource()1525 const char *getFragmentShaderSource() override
1526 {
1527 return "precision highp float;\n"
1528 "struct S\n"
1529 "{\n"
1530 " vec4 a;\n"
1531 " highp sampler2D tex;\n"
1532 "};\n"
1533 "uniform S us;\n"
1534 "varying vec2 texcoord;\n"
1535 "void main()\n"
1536 "{\n"
1537 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1538 "}\n";
1539 }
1540
runSamplerInStructTest()1541 void runSamplerInStructTest()
1542 {
1543 setUpProgram();
1544
1545 glActiveTexture(GL_TEXTURE0);
1546 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1547 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1548 &GLColor::green);
1549 drawQuad(mProgram, "position", 0.5f);
1550 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1551 }
1552 };
1553
1554 class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1555 {
1556 protected:
SamplerInStructAsFunctionParameterTest()1557 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1558
getFragmentShaderSource()1559 const char *getFragmentShaderSource() override
1560 {
1561 return "precision highp float;\n"
1562 "struct S\n"
1563 "{\n"
1564 " vec4 a;\n"
1565 " highp sampler2D tex;\n"
1566 "};\n"
1567 "uniform S us;\n"
1568 "varying vec2 texcoord;\n"
1569 "vec4 sampleFrom(S s) {\n"
1570 " return texture2D(s.tex, texcoord + s.a.x);\n"
1571 "}\n"
1572 "void main()\n"
1573 "{\n"
1574 " gl_FragColor = sampleFrom(us);\n"
1575 "}\n";
1576 }
1577 };
1578
1579 class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1580 {
1581 protected:
SamplerInStructArrayAsFunctionParameterTest()1582 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1583
getTextureUniformName()1584 const char *getTextureUniformName() override { return "us[0].tex"; }
1585
getFragmentShaderSource()1586 const char *getFragmentShaderSource() override
1587 {
1588 return "precision highp float;\n"
1589 "struct S\n"
1590 "{\n"
1591 " vec4 a;\n"
1592 " highp sampler2D tex;\n"
1593 "};\n"
1594 "uniform S us[1];\n"
1595 "varying vec2 texcoord;\n"
1596 "vec4 sampleFrom(S s) {\n"
1597 " return texture2D(s.tex, texcoord + s.a.x);\n"
1598 "}\n"
1599 "void main()\n"
1600 "{\n"
1601 " gl_FragColor = sampleFrom(us[0]);\n"
1602 "}\n";
1603 }
1604 };
1605
1606 class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1607 {
1608 protected:
SamplerInNestedStructAsFunctionParameterTest()1609 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1610
getTextureUniformName()1611 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1612
getFragmentShaderSource()1613 const char *getFragmentShaderSource() override
1614 {
1615 return "precision highp float;\n"
1616 "struct SUB\n"
1617 "{\n"
1618 " vec4 a;\n"
1619 " highp sampler2D tex;\n"
1620 "};\n"
1621 "struct S\n"
1622 "{\n"
1623 " SUB sub;\n"
1624 "};\n"
1625 "uniform S us[1];\n"
1626 "varying vec2 texcoord;\n"
1627 "vec4 sampleFrom(SUB s) {\n"
1628 " return texture2D(s.tex, texcoord + s.a.x);\n"
1629 "}\n"
1630 "void main()\n"
1631 "{\n"
1632 " gl_FragColor = sampleFrom(us[0].sub);\n"
1633 "}\n";
1634 }
1635 };
1636
1637 class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1638 {
1639 protected:
SamplerInStructAndOtherVariableTest()1640 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1641
getFragmentShaderSource()1642 const char *getFragmentShaderSource() override
1643 {
1644 return "precision highp float;\n"
1645 "struct S\n"
1646 "{\n"
1647 " vec4 a;\n"
1648 " highp sampler2D tex;\n"
1649 "};\n"
1650 "uniform S us;\n"
1651 "uniform float us_tex;\n"
1652 "varying vec2 texcoord;\n"
1653 "void main()\n"
1654 "{\n"
1655 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1656 "}\n";
1657 }
1658 };
1659
1660 class Texture2DIntegerTestES3 : public Texture2DTest
1661 {
1662 protected:
Texture2DIntegerTestES3()1663 Texture2DIntegerTestES3() : Texture2DTest() {}
1664
getVertexShaderSource()1665 const char *getVertexShaderSource() override
1666 {
1667 return "#version 300 es\n"
1668 "out vec2 texcoord;\n"
1669 "in vec4 position;\n"
1670 "void main()\n"
1671 "{\n"
1672 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1673 " texcoord = (position.xy * 0.5) + 0.5;\n"
1674 "}\n";
1675 }
1676
getFragmentShaderSource()1677 const char *getFragmentShaderSource() override
1678 {
1679 return "#version 300 es\n"
1680 "precision highp float;\n"
1681 "precision highp usampler2D;\n"
1682 "uniform usampler2D tex;\n"
1683 "in vec2 texcoord;\n"
1684 "out vec4 fragColor;\n"
1685 "void main()\n"
1686 "{\n"
1687 " fragColor = vec4(texture(tex, texcoord))/255.0;\n"
1688 "}\n";
1689 }
1690 };
1691
1692 class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1693 {
1694 protected:
TextureCubeIntegerTestES3()1695 TextureCubeIntegerTestES3()
1696 : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1697 {}
1698
getVertexShaderSource()1699 const char *getVertexShaderSource() override
1700 {
1701 return "#version 300 es\n"
1702 "out vec2 texcoord;\n"
1703 "in vec4 position;\n"
1704 "void main()\n"
1705 "{\n"
1706 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1707 " texcoord = 0.5*position.xy;\n"
1708 "}\n";
1709 }
1710
getFragmentShaderSource()1711 const char *getFragmentShaderSource() override
1712 {
1713 return "#version 300 es\n"
1714 "precision highp float;\n"
1715 "precision highp usamplerCube;\n"
1716 "uniform usamplerCube texCube;\n"
1717 "in vec2 texcoord;\n"
1718 "out vec4 fragColor;\n"
1719 "void main()\n"
1720 "{\n"
1721 " fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1722 "}\n";
1723 }
1724
testSetUp()1725 void testSetUp() override
1726 {
1727 TexCoordDrawTest::testSetUp();
1728 glGenTextures(1, &mTextureCube);
1729 setUpProgram();
1730
1731 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1732 ASSERT_NE(-1, mTextureCubeUniformLocation);
1733 }
1734
testTearDown()1735 void testTearDown() override
1736 {
1737 glDeleteTextures(1, &mTextureCube);
1738 TexCoordDrawTest::testTearDown();
1739 }
1740
1741 GLuint mTextureCube;
1742 GLint mTextureCubeUniformLocation;
1743 };
1744
1745 class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1746 {
1747 protected:
TextureCubeIntegerEdgeTestES3()1748 TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1749
getVertexShaderSource()1750 const char *getVertexShaderSource() override
1751 {
1752 return "#version 300 es\n"
1753 "out vec2 texcoord;\n"
1754 "in vec4 position;\n"
1755 "void main()\n"
1756 "{\n"
1757 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1758 " texcoord = position.xy;\n"
1759 "}\n";
1760 }
1761
getFragmentShaderSource()1762 const char *getFragmentShaderSource() override
1763 {
1764 return "#version 300 es\n"
1765 "precision highp float;\n"
1766 "precision highp usamplerCube;\n"
1767 "uniform usamplerCube texCube;\n"
1768 "in vec2 texcoord;\n"
1769 "out vec4 fragColor;\n"
1770 "void main()\n"
1771 "{\n"
1772 " fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1773 "}\n";
1774 }
1775 };
1776
1777 class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1778 {
1779 protected:
Texture2DIntegerProjectiveOffsetTestES3()1780 Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1781
getVertexShaderSource()1782 const char *getVertexShaderSource() override
1783 {
1784 return "#version 300 es\n"
1785 "out vec2 texcoord;\n"
1786 "in vec4 position;\n"
1787 "void main()\n"
1788 "{\n"
1789 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1790 " texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1791 "}\n";
1792 }
1793
getFragmentShaderSource()1794 const char *getFragmentShaderSource() override
1795 {
1796 return "#version 300 es\n"
1797 "precision highp float;\n"
1798 "precision highp usampler2D;\n"
1799 "uniform usampler2D tex;\n"
1800 "in vec2 texcoord;\n"
1801 "out vec4 fragColor;\n"
1802 "void main()\n"
1803 "{\n"
1804 " fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1805 "0.0))/255.0;\n"
1806 "}\n";
1807 }
1808 };
1809
1810 class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1811 {
1812 protected:
Texture2DArrayIntegerTestES3()1813 Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1814
getVertexShaderSource()1815 const char *getVertexShaderSource() override
1816 {
1817 return R"(#version 300 es
1818 out vec2 texcoord;
1819 in vec4 position;
1820 void main()
1821 {
1822 gl_Position = vec4(position.xy, 0.0, 1.0);
1823 texcoord = (position.xy * 0.5) + 0.5;
1824 })";
1825 }
1826
getFragmentShaderSource()1827 const char *getFragmentShaderSource() override
1828 {
1829 return R"(#version 300 es
1830 precision highp float;
1831 uniform highp usampler2DArray tex2DArray;
1832 uniform int slice;
1833 in vec2 texcoord;
1834 out vec4 fragColor;
1835 void main()
1836 {
1837 fragColor = vec4(texture(tex2DArray, vec3(texcoord, slice)))/255.0;
1838 })";
1839 }
1840 };
1841
1842 class Texture3DIntegerTestES3 : public Texture3DTestES3
1843 {
1844 protected:
Texture3DIntegerTestES3()1845 Texture3DIntegerTestES3() : Texture3DTestES3() {}
1846
getVertexShaderSource()1847 const char *getVertexShaderSource() override
1848 {
1849 return "#version 300 es\n"
1850 "out vec2 texcoord;\n"
1851 "in vec4 position;\n"
1852 "void main()\n"
1853 "{\n"
1854 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1855 " texcoord = (position.xy * 0.5) + 0.5;\n"
1856 "}\n";
1857 }
1858
getFragmentShaderSource()1859 const char *getFragmentShaderSource() override
1860 {
1861 return "#version 300 es\n"
1862 "precision highp float;\n"
1863 "uniform highp usampler3D tex3D;\n"
1864 "in vec2 texcoord;\n"
1865 "out vec4 fragColor;\n"
1866 "void main()\n"
1867 "{\n"
1868 " fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1869 "}\n";
1870 }
1871 };
1872
1873 class PBOCompressedTextureTest : public Texture2DTest
1874 {
1875 protected:
PBOCompressedTextureTest()1876 PBOCompressedTextureTest() : Texture2DTest() {}
1877
testSetUp()1878 void testSetUp() override
1879 {
1880 TexCoordDrawTest::testSetUp();
1881 glGenTextures(1, &mTexture2D);
1882 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1883 EXPECT_GL_NO_ERROR();
1884
1885 setUpProgram();
1886
1887 glGenBuffers(1, &mPBO);
1888 }
1889
testTearDown()1890 void testTearDown() override
1891 {
1892 glDeleteBuffers(1, &mPBO);
1893 Texture2DTest::testTearDown();
1894 }
1895
1896 void runCompressedSubImage();
1897
1898 GLuint mPBO;
1899 };
1900
1901 class ETC1CompressedTextureTest : public Texture2DTest
1902 {
1903 protected:
ETC1CompressedTextureTest()1904 ETC1CompressedTextureTest() : Texture2DTest() {}
1905
testSetUp()1906 void testSetUp() override
1907 {
1908 TexCoordDrawTest::testSetUp();
1909 glGenTextures(1, &mTexture2D);
1910 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1911 EXPECT_GL_NO_ERROR();
1912
1913 setUpProgram();
1914 }
1915
testTearDown()1916 void testTearDown() override { Texture2DTest::testTearDown(); }
1917 };
1918
1919 class Texture2DDepthStencilTestES3 : public Texture2DTest
1920 {
1921 protected:
Texture2DDepthStencilTestES3()1922 Texture2DDepthStencilTestES3() : Texture2DTest() {}
1923
1924 void TestSampleWithDepthStencilMode(GLenum format, GLenum mode, bool swizzle);
1925 };
1926
TestSampleWithDepthStencilMode(GLenum format,GLenum mode,bool swizzle)1927 void Texture2DDepthStencilTestES3::TestSampleWithDepthStencilMode(GLenum format,
1928 GLenum mode,
1929 bool swizzle)
1930 {
1931 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_stencil_texturing"));
1932
1933 constexpr GLsizei kSize = 4;
1934
1935 ASSERT(mode == GL_STENCIL_INDEX || mode == GL_DEPTH_COMPONENT);
1936
1937 bool isStencilMode;
1938 GLenum attachment;
1939 switch (format)
1940 {
1941 case GL_DEPTH_COMPONENT16:
1942 case GL_DEPTH_COMPONENT24:
1943 case GL_DEPTH_COMPONENT32F:
1944 attachment = GL_DEPTH_ATTACHMENT;
1945 isStencilMode = false;
1946 break;
1947 case GL_DEPTH24_STENCIL8:
1948 case GL_DEPTH32F_STENCIL8:
1949 attachment = GL_DEPTH_STENCIL_ATTACHMENT;
1950 isStencilMode = mode == GL_STENCIL_INDEX;
1951 break;
1952 case GL_STENCIL_INDEX8:
1953 attachment = GL_STENCIL_ATTACHMENT;
1954 isStencilMode = true;
1955 break;
1956 default:
1957 UNREACHABLE();
1958 }
1959
1960 // Set up a color texture.
1961 GLTexture colorTexture;
1962 glBindTexture(GL_TEXTURE_2D, colorTexture);
1963 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
1964 ASSERT_GL_NO_ERROR();
1965
1966 // Set up a depth/stencil texture to be sampled as mode.
1967 GLTexture depthStencilTexture;
1968 glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
1969 glTexStorage2D(GL_TEXTURE_2D, 1, format, kSize, kSize);
1970 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1971 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1972 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE_ANGLE, mode);
1973 if (swizzle)
1974 {
1975 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
1976 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
1977 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_GREEN);
1978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
1979 }
1980 ASSERT_GL_NO_ERROR();
1981
1982 constexpr char kStencilFS[] =
1983 R"(#version 300 es
1984 precision mediump float;
1985 uniform highp usampler2D tex;
1986 out vec4 color;
1987 void main()
1988 {
1989 color = vec4(texelFetch(tex, ivec2(0, 0), 0)) / 255.0f;
1990 })";
1991
1992 constexpr char kDepthFS[] =
1993 R"(#version 300 es
1994 precision mediump float;
1995 uniform highp sampler2D tex;
1996 out vec4 color;
1997 void main()
1998 {
1999 color = texture(tex, vec2(0, 0));
2000 })";
2001
2002 // Clear stencil to 42.
2003 GLFramebuffer clearFBO;
2004 glBindFramebuffer(GL_FRAMEBUFFER, clearFBO);
2005 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, depthStencilTexture, 0);
2006 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2007 glClearDepthf(0.5);
2008 glClearStencil(42);
2009 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2010 ASSERT_GL_NO_ERROR();
2011
2012 glActiveTexture(GL_TEXTURE0);
2013 glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
2014 EXPECT_GL_ERROR(GL_NO_ERROR);
2015
2016 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), isStencilMode ? kStencilFS : kDepthFS);
2017 GLint texLocation = glGetUniformLocation(program, "tex");
2018 ASSERT_NE(-1, texLocation);
2019 ASSERT_GL_NO_ERROR();
2020
2021 glUseProgram(program);
2022 glUniform1i(texLocation, 0);
2023
2024 GLFramebuffer drawFBO;
2025 glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
2026 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2027 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2028 ASSERT_GL_NO_ERROR();
2029
2030 drawQuad(program, essl3_shaders::PositionAttrib(), 0.95f);
2031 ASSERT_GL_NO_ERROR();
2032
2033 if (isStencilMode)
2034 {
2035 GLColor expected = swizzle ? GLColor(1, 0, 0, 42) : GLColor(42, 0, 0, 1);
2036 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, expected);
2037 }
2038 else
2039 {
2040 GLColor expected = swizzle ? GLColor(255, 0, 0, 127) : GLColor(127, 0, 0, 255);
2041 EXPECT_PIXEL_COLOR_NEAR(0, 0, expected, 1);
2042 }
2043 }
2044
TEST_P(Texture2DTest,NegativeAPISubImage)2045 TEST_P(Texture2DTest, NegativeAPISubImage)
2046 {
2047 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2048 EXPECT_GL_ERROR(GL_NO_ERROR);
2049
2050 setUpProgram();
2051
2052 const GLubyte *pixels[20] = {0};
2053 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2054 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2055
2056 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
2057 {
2058 // Create a 1-level immutable texture.
2059 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
2060
2061 // Try calling sub image on the second level.
2062 glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2063 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2064 }
2065 }
2066
2067 // Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
TEST_P(Texture2DTest,QueryBinding)2068 TEST_P(Texture2DTest, QueryBinding)
2069 {
2070 glBindTexture(GL_TEXTURE_2D, 0);
2071 EXPECT_GL_ERROR(GL_NO_ERROR);
2072
2073 GLint textureBinding;
2074 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
2075 EXPECT_GL_NO_ERROR();
2076 EXPECT_EQ(0, textureBinding);
2077
2078 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
2079 if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
2080 IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
2081 {
2082 EXPECT_GL_NO_ERROR();
2083 EXPECT_EQ(0, textureBinding);
2084 }
2085 else
2086 {
2087 EXPECT_GL_ERROR(GL_INVALID_ENUM);
2088 }
2089 }
2090
TEST_P(Texture2DTest,ZeroSizedUploads)2091 TEST_P(Texture2DTest, ZeroSizedUploads)
2092 {
2093 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2094 EXPECT_GL_ERROR(GL_NO_ERROR);
2095
2096 setUpProgram();
2097
2098 // Use the texture first to make sure it's in video memory
2099 glUseProgram(mProgram);
2100 glUniform1i(mTexture2DUniformLocation, 0);
2101 drawQuad(mProgram, "position", 0.5f);
2102
2103 const GLubyte *pixel[4] = {0};
2104
2105 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
2106 EXPECT_GL_NO_ERROR();
2107
2108 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
2109 EXPECT_GL_NO_ERROR();
2110
2111 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
2112 EXPECT_GL_NO_ERROR();
2113 }
2114
2115 // Tests uploading a red texture and immediately reading from it.
TEST_P(Texture2DTest,SimpleUpload)2116 TEST_P(Texture2DTest, SimpleUpload)
2117 {
2118 const GLuint width = getWindowWidth();
2119 const GLuint height = getWindowHeight();
2120 const GLuint windowPixelCount = width * height;
2121 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
2122 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2123 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2124 pixelsRed.data());
2125 EXPECT_GL_ERROR(GL_NO_ERROR);
2126
2127 GLFramebuffer fbo;
2128 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2129
2130 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
2131
2132 EXPECT_GL_ERROR(GL_NO_ERROR);
2133 std::vector<GLColor> output(windowPixelCount, GLColor::green);
2134 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, output.data());
2135 EXPECT_EQ(pixelsRed, output);
2136 }
2137
2138 // Test that interleaved superseded updates work as expected
TEST_P(Texture2DTest,InterleavedSupersedingTextureUpdates)2139 TEST_P(Texture2DTest, InterleavedSupersedingTextureUpdates)
2140 {
2141 constexpr uint32_t kTexWidth = 3840;
2142 constexpr uint32_t kTexHeight = 2160;
2143 constexpr uint32_t kBpp = 4;
2144
2145 // Create the texture
2146 glActiveTexture(GL_TEXTURE0);
2147 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2150 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2151 nullptr);
2152 EXPECT_GL_ERROR(GL_NO_ERROR);
2153
2154 // 1. One big upload followed by many small identical uploads
2155 // Update the entire texture
2156 std::vector<GLubyte> fullTextureData(kTexWidth * kTexHeight * kBpp, 128);
2157 constexpr GLColor kFullTextureColor = GLColor(128u, 128u, 128u, 128u);
2158 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2159 fullTextureData.data());
2160
2161 // Make a number of identical updates to the right half of the texture
2162 std::vector<GLubyte> rightHalfData(kTexWidth * kTexHeight * kBpp, 201);
2163 constexpr GLColor kRightHalfColor = GLColor(201u, 201u, 201u, 201u);
2164 for (uint32_t iteration = 0; iteration < 10; iteration++)
2165 {
2166 glTexSubImage2D(GL_TEXTURE_2D, 0, kTexWidth / 2, 0, kTexWidth / 2, kTexHeight, GL_RGBA,
2167 GL_UNSIGNED_BYTE, rightHalfData.data());
2168 }
2169
2170 setUpProgram();
2171 glUseProgram(mProgram);
2172 glUniform1i(mTexture2DUniformLocation, 0);
2173 drawQuad(mProgram, "position", 0.5f);
2174 EXPECT_GL_NO_ERROR();
2175 EXPECT_PIXEL_COLOR_EQ(1 * getWindowWidth() / 4, getWindowHeight() / 2, kFullTextureColor);
2176 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 2, kRightHalfColor);
2177
2178 // 2. Some small uploads followed by one big upload followed by many identical uploads
2179 // Clear the entire texture
2180 std::vector<GLubyte> zeroTextureData(kTexWidth * kTexHeight * kBpp, 255);
2181 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2182 zeroTextureData.data());
2183
2184 // Update the top left quadrant of the texture
2185 std::vector<GLubyte> topLeftQuadrantData(kTexWidth * kTexHeight * kBpp, 128);
2186 constexpr GLColor kTopLeftQuandrantTextureColor = GLColor(128u, 128u, 128u, 128u);
2187 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, kTexHeight / 2, kTexWidth / 2, kTexHeight / 2, GL_RGBA,
2188 GL_UNSIGNED_BYTE, topLeftQuadrantData.data());
2189
2190 // Update the top right quadrant of the texture
2191 std::vector<GLubyte> topRightQuadrantData(kTexWidth * kTexHeight * kBpp, 156);
2192 constexpr GLColor kTopRightQuadrantTextureColor = GLColor(156u, 156u, 156u, 156u);
2193 glTexSubImage2D(GL_TEXTURE_2D, 0, kTexWidth / 2, kTexHeight / 2, kTexWidth / 2, kTexHeight / 2,
2194 GL_RGBA, GL_UNSIGNED_BYTE, topRightQuadrantData.data());
2195
2196 // Update the bottom half of the texture
2197 std::vector<GLubyte> bottomHalfTextureData(kTexWidth * kTexHeight * kBpp, 187);
2198 constexpr GLColor kBottomHalfTextureColor = GLColor(187u, 187u, 187u, 187u);
2199 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight / 2, GL_RGBA, GL_UNSIGNED_BYTE,
2200 bottomHalfTextureData.data());
2201
2202 // Make a number of identical updates to the bottom right quadrant of the texture
2203 std::vector<GLubyte> bottomRightQuadrantData(kTexWidth * kTexHeight * kBpp, 201);
2204 constexpr GLColor kBottomRightQuadrantColor = GLColor(201u, 201u, 201u, 201u);
2205 for (uint32_t iteration = 0; iteration < 10; iteration++)
2206 {
2207 glTexSubImage2D(GL_TEXTURE_2D, 0, kTexWidth / 2, 0, kTexWidth / 2, kTexHeight / 2, GL_RGBA,
2208 GL_UNSIGNED_BYTE, bottomRightQuadrantData.data());
2209 }
2210
2211 setUpProgram();
2212 glUseProgram(mProgram);
2213 glUniform1i(mTexture2DUniformLocation, 0);
2214 drawQuad(mProgram, "position", 0.5f);
2215 EXPECT_GL_NO_ERROR();
2216 EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, kTopLeftQuandrantTextureColor);
2217 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1,
2218 kTopRightQuadrantTextureColor);
2219 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, kBottomHalfTextureColor);
2220 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4,
2221 kBottomRightQuadrantColor);
2222
2223 // 3. Many small uploads folloed by one big upload
2224 // Clear the entire texture
2225 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2226 zeroTextureData.data());
2227
2228 // Make a number of small updates to different parts of the texture
2229 std::vector<std::pair<GLint, GLint>> xyOffsets = {
2230 {1, 4}, {128, 34}, {1208, 1090}, {2560, 2022}};
2231 constexpr GLColor kRandomColor = GLColor(55u, 128u, 201u, 255u);
2232 for (const std::pair<GLint, GLint> &xyOffset : xyOffsets)
2233 {
2234 glTexSubImage2D(GL_TEXTURE_2D, 0, xyOffset.first, xyOffset.second, 1, 1, GL_RGBA,
2235 GL_UNSIGNED_BYTE, kRandomColor.data());
2236 }
2237
2238 // Update the entire texture
2239 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2240 fullTextureData.data());
2241
2242 setUpProgram();
2243 glUseProgram(mProgram);
2244 glUniform1i(mTexture2DUniformLocation, 0);
2245 drawQuad(mProgram, "position", 0.5f);
2246 EXPECT_GL_NO_ERROR();
2247 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() - 1, getWindowHeight() - 1, kFullTextureColor);
2248 }
2249
2250 // Test that repeated calls to glTexSubImage2D with superseding updates works
TEST_P(Texture2DTest,ManySupersedingTextureUpdates)2251 TEST_P(Texture2DTest, ManySupersedingTextureUpdates)
2252 {
2253 constexpr uint32_t kTexWidth = 3840;
2254 constexpr uint32_t kTexHeight = 2160;
2255 constexpr uint32_t kBpp = 4;
2256 std::vector<GLubyte> data(kTexWidth * kTexHeight * kBpp, 0);
2257
2258 // Create the texture
2259 glActiveTexture(GL_TEXTURE0);
2260 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2263 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2264 nullptr);
2265 EXPECT_GL_ERROR(GL_NO_ERROR);
2266
2267 // Make a large number of superseding updates
2268 for (uint32_t width = kTexWidth / 2, height = kTexHeight / 2;
2269 width < kTexWidth && height < kTexHeight; width++, height++)
2270 {
2271 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
2272 data.data());
2273 }
2274
2275 // Upload different color to the whole texture thus superseding all prior updates.
2276 std::vector<GLubyte> supersedingData(kTexWidth * kTexHeight * kBpp, 128);
2277 constexpr GLColor kGray = GLColor(128u, 128u, 128u, 128u);
2278 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2279 supersedingData.data());
2280
2281 setUpProgram();
2282 glUseProgram(mProgram);
2283 glUniform1i(mTexture2DUniformLocation, 0);
2284 drawQuad(mProgram, "position", 0.5f);
2285 EXPECT_GL_NO_ERROR();
2286 EXPECT_PIXEL_COLOR_EQ(0, 0, kGray);
2287 }
2288
TEST_P(Texture2DTest,DefineMultipleLevelsWithoutMipmapping)2289 TEST_P(Texture2DTest, DefineMultipleLevelsWithoutMipmapping)
2290 {
2291 setUpProgram();
2292
2293 constexpr size_t kImageSize = 256;
2294 std::array<GLColor, kImageSize * kImageSize> kMipColors[2];
2295
2296 std::fill(kMipColors[0].begin(), kMipColors[0].end(), GLColor::red);
2297 std::fill(kMipColors[1].begin(), kMipColors[1].end(), GLColor::green);
2298
2299 glActiveTexture(GL_TEXTURE0);
2300 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2303
2304 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2305 kMipColors[0].data());
2306 EXPECT_GL_NO_ERROR();
2307
2308 // Draw so the image is created.
2309 glUseProgram(mProgram);
2310 glUniform1i(mTexture2DUniformLocation, 0);
2311 drawQuad(mProgram, "position", 0.5f);
2312
2313 // Define level 1 of the texture.
2314 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2315 kMipColors[1].data());
2316 EXPECT_GL_NO_ERROR();
2317
2318 // Draw again.
2319 drawQuad(mProgram, "position", 0.5f);
2320 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0][0]);
2321 }
2322
2323 // Test drawing with two texture types, to trigger an ANGLE bug in validation
TEST_P(TextureCubeTest,CubeMapBug)2324 TEST_P(TextureCubeTest, CubeMapBug)
2325 {
2326 glActiveTexture(GL_TEXTURE0);
2327 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2328 glActiveTexture(GL_TEXTURE1);
2329 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2330 EXPECT_GL_ERROR(GL_NO_ERROR);
2331
2332 glUseProgram(mProgram);
2333 glUniform1i(mTexture2DUniformLocation, 0);
2334 glUniform1i(mTextureCubeUniformLocation, 1);
2335 drawQuad(mProgram, "position", 0.5f);
2336 EXPECT_GL_NO_ERROR();
2337 }
2338
2339 // Test drawing with two texture types accessed from the same shader and check that the result of
2340 // drawing is correct.
TEST_P(TextureCubeTest,CubeMapDraw)2341 TEST_P(TextureCubeTest, CubeMapDraw)
2342 {
2343 GLubyte texData[4];
2344 texData[0] = 0;
2345 texData[1] = 60;
2346 texData[2] = 0;
2347 texData[3] = 255;
2348
2349 glActiveTexture(GL_TEXTURE0);
2350 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2351 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2352
2353 glActiveTexture(GL_TEXTURE1);
2354 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2355 texData[1] = 120;
2356 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2357 texData);
2358 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2359 texData);
2360 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2361 texData);
2362 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2363 texData);
2364 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2365 texData);
2366 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2367 texData);
2368 EXPECT_GL_ERROR(GL_NO_ERROR);
2369
2370 glUseProgram(mProgram);
2371 glUniform1i(mTexture2DUniformLocation, 0);
2372 glUniform1i(mTextureCubeUniformLocation, 1);
2373 drawQuad(mProgram, "position", 0.5f);
2374 EXPECT_GL_NO_ERROR();
2375
2376 int px = getWindowWidth() - 1;
2377 int py = 0;
2378 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
2379 }
2380
TEST_P(Sampler2DAsFunctionParameterTest,Sampler2DAsFunctionParameter)2381 TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
2382 {
2383 glActiveTexture(GL_TEXTURE0);
2384 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2385 GLubyte texData[4];
2386 texData[0] = 0;
2387 texData[1] = 128;
2388 texData[2] = 0;
2389 texData[3] = 255;
2390 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2391 glUseProgram(mProgram);
2392 glUniform1i(mTexture2DUniformLocation, 0);
2393 drawQuad(mProgram, "position", 0.5f);
2394 EXPECT_GL_NO_ERROR();
2395
2396 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
2397 }
2398
2399 // Test drawing with two textures passed to the shader in a sampler array.
TEST_P(SamplerArrayTest,SamplerArrayDraw)2400 TEST_P(SamplerArrayTest, SamplerArrayDraw)
2401 {
2402 testSamplerArrayDraw();
2403 }
2404
2405 // Test drawing with two textures passed to the shader in a sampler array which is passed to a
2406 // user-defined function in the shader.
TEST_P(SamplerArrayAsFunctionParameterTest,SamplerArrayAsFunctionParameter)2407 TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
2408 {
2409 // TODO: Diagnose and fix. http://anglebug.com/42261649
2410 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
2411
2412 testSamplerArrayDraw();
2413 }
2414
2415 // Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
TEST_P(Texture2DTestWithDrawScale,MipmapsTwice)2416 TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
2417 {
2418 int px = getWindowWidth() / 2;
2419 int py = getWindowHeight() / 2;
2420
2421 glActiveTexture(GL_TEXTURE0);
2422 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2423
2424 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
2425
2426 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
2427 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2428 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2429 glGenerateMipmap(GL_TEXTURE_2D);
2430
2431 glUseProgram(mProgram);
2432 glUniform1i(mTexture2DUniformLocation, 0);
2433 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
2434 drawQuad(mProgram, "position", 0.5f);
2435 EXPECT_GL_NO_ERROR();
2436 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
2437
2438 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
2439
2440 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2441 pixelsBlue.data());
2442 glGenerateMipmap(GL_TEXTURE_2D);
2443
2444 drawQuad(mProgram, "position", 0.5f);
2445
2446 EXPECT_GL_NO_ERROR();
2447 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::blue);
2448
2449 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
2450
2451 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2452 pixelsGreen.data());
2453 glGenerateMipmap(GL_TEXTURE_2D);
2454
2455 drawQuad(mProgram, "position", 0.5f);
2456
2457 EXPECT_GL_NO_ERROR();
2458 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
2459 }
2460
2461 // Test creating a FBO with a cube map render target, to test an ANGLE bug
2462 // https://code.google.com/p/angleproject/issues/detail?id=849
TEST_P(TextureCubeTest,CubeMapFBO)2463 TEST_P(TextureCubeTest, CubeMapFBO)
2464 {
2465 // http://anglebug.com/42261821
2466 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
2467
2468 GLFramebuffer fbo;
2469 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2470
2471 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2472 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2473 mTextureCube, 0);
2474
2475 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2476 EXPECT_GL_NO_ERROR();
2477
2478 // Test clearing the six mip faces individually.
2479 std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
2480 GLColor::yellow, GLColor::cyan, GLColor::magenta}};
2481
2482 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2483 {
2484 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2485 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2486
2487 Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
2488 glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
2489 glClear(GL_COLOR_BUFFER_BIT);
2490
2491 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
2492 }
2493
2494 // Iterate the faces again to make sure the colors haven't changed.
2495 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2496 {
2497 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2498 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2499 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
2500 << "face color " << faceIndex << " shouldn't change";
2501 }
2502 }
2503
2504 // Tests clearing a cube map with a scissor enabled.
TEST_P(TextureCubeTest,CubeMapFBOScissoredClear)2505 TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
2506 {
2507 // http://anglebug.com/42261821
2508 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
2509
2510 constexpr size_t kSize = 16;
2511
2512 GLFramebuffer fbo;
2513 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2514 glViewport(0, 0, kSize, kSize);
2515
2516 GLTexture texcube;
2517 glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
2518 for (GLenum face = 0; face < 6; face++)
2519 {
2520 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
2521 GL_UNSIGNED_BYTE, nullptr);
2522 }
2523 ASSERT_GL_NO_ERROR();
2524
2525 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2526 texcube, 0);
2527
2528 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2529 ASSERT_GL_NO_ERROR();
2530
2531 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2532 glClear(GL_COLOR_BUFFER_BIT);
2533 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2534
2535 glEnable(GL_SCISSOR_TEST);
2536 glScissor(kSize / 2, 0, kSize / 2, kSize);
2537 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2538 glClear(GL_COLOR_BUFFER_BIT);
2539
2540 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2541 EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
2542
2543 ASSERT_GL_NO_ERROR();
2544 }
2545
2546 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
2547 // default color.
TEST_P(Texture2DTest,TexStorage)2548 TEST_P(Texture2DTest, TexStorage)
2549 {
2550 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
2551 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
2552
2553 int width = getWindowWidth();
2554 int height = getWindowHeight();
2555
2556 GLTexture tex2D;
2557 glActiveTexture(GL_TEXTURE0);
2558 glBindTexture(GL_TEXTURE_2D, tex2D);
2559
2560 // Fill with red
2561 std::vector<GLubyte> pixels(3 * 16 * 16);
2562 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2563 {
2564 pixels[pixelId * 3 + 0] = 255;
2565 pixels[pixelId * 3 + 1] = 0;
2566 pixels[pixelId * 3 + 2] = 0;
2567 }
2568
2569 // ANGLE internally uses RGBA as the DirectX format for RGB images
2570 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2571 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2572 if (getClientMajorVersion() >= 3)
2573 {
2574 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2575 }
2576 else
2577 {
2578 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2579 }
2580
2581 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2582 // glTexSubImage2D should take into account that the image is dirty.
2583 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2586
2587 setUpProgram();
2588
2589 glUseProgram(mProgram);
2590 glUniform1i(mTexture2DUniformLocation, 0);
2591 drawQuad(mProgram, "position", 0.5f);
2592 EXPECT_GL_NO_ERROR();
2593 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2594
2595 // Validate that the region of the texture without data has an alpha of 1.0
2596 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
2597 EXPECT_EQ(255, pixel.A);
2598 }
2599
2600 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2601 // initialized the image with a default color.
TEST_P(Texture2DTest,TexStorageWithPBO)2602 TEST_P(Texture2DTest, TexStorageWithPBO)
2603 {
2604 if (getClientMajorVersion() < 3)
2605 {
2606 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2607 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2608 }
2609
2610 const int width = getWindowWidth();
2611 const int height = getWindowHeight();
2612 const size_t pixelCount = width * height;
2613 const int componentCount = 3;
2614
2615 GLTexture tex2D;
2616 glActiveTexture(GL_TEXTURE0);
2617 glBindTexture(GL_TEXTURE_2D, tex2D);
2618
2619 // Fill with red
2620 std::vector<GLubyte> pixels(componentCount * pixelCount);
2621 for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
2622 {
2623 pixels[pixelId * componentCount + 0] = 255;
2624 pixels[pixelId * componentCount + 1] = 0;
2625 pixels[pixelId * componentCount + 2] = 0;
2626 }
2627
2628 // Read 16x16 region from red backbuffer to PBO
2629 GLuint pbo;
2630 glGenBuffers(1, &pbo);
2631 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2632 glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
2633 GL_STATIC_DRAW);
2634
2635 // ANGLE internally uses RGBA as the DirectX format for RGB images
2636 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2637 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2638 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
2639
2640 // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
2641 // untouched. glTexSubImage2D should take into account that the image is dirty.
2642 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
2643 nullptr);
2644 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2645 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2646
2647 setUpProgram();
2648
2649 glUseProgram(mProgram);
2650 glUniform1i(mTexture2DUniformLocation, 0);
2651 drawQuad(mProgram, "position", 0.5f);
2652 glDeleteBuffers(1, &pbo);
2653 EXPECT_GL_NO_ERROR();
2654 EXPECT_PIXEL_RECT_EQ(0, 0, width / 2, height / 2, GLColor(255, 0, 0, 255));
2655 }
2656
2657 // Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
2658 // and drawing with the texture
2659 // Pseudo code for the follow test:
2660 // 1. Upload PBO to mTexture2D
2661 // 2. Delete PBO
2662 // 3. Draw with otherTexture (x5)
2663 // 4. Draw with mTexture2D
2664 // 5. Validate color output
TEST_P(Texture2DTest,PBOWithMultipleDraws)2665 TEST_P(Texture2DTest, PBOWithMultipleDraws)
2666 {
2667 if (getClientMajorVersion() < 3)
2668 {
2669 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2670 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2671 }
2672
2673 const GLuint width = getWindowWidth();
2674 const GLuint height = getWindowHeight();
2675 const GLuint windowPixelCount = width * height;
2676 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
2677 std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
2678
2679 // Create secondary draw that does not use mTexture
2680 const char *vertexShaderSource = getVertexShaderSource();
2681 const char *fragmentShaderSource = getFragmentShaderSource();
2682 ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
2683
2684 GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
2685 ASSERT_NE(-1, uniformLoc);
2686 glUseProgram(0);
2687
2688 // Create secondary Texture to draw with
2689 GLTexture otherTexture;
2690 glActiveTexture(GL_TEXTURE0);
2691 glBindTexture(GL_TEXTURE_2D, otherTexture);
2692 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2693 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
2694 pixelsRed.data());
2695 ASSERT_GL_NO_ERROR();
2696
2697 // Setup primary Texture
2698 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2699 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2700 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2701 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2702 ASSERT_GL_NO_ERROR();
2703
2704 // Setup PBO
2705 GLuint pbo = 0;
2706 glGenBuffers(1, &pbo);
2707 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2708 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
2709 GL_STATIC_DRAW);
2710 ASSERT_GL_NO_ERROR();
2711
2712 // Write PBO to mTexture
2713 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2714 ASSERT_GL_NO_ERROR();
2715 // Delete PBO as ANGLE should be properly handling refcount of this buffer
2716 glDeleteBuffers(1, &pbo);
2717 pixelsGreen.clear();
2718
2719 // Do 5 draws not involving primary texture that the PBO updated
2720 glUseProgram(otherProgram);
2721 glUniform1i(uniformLoc, 0);
2722 glBindTexture(GL_TEXTURE_2D, otherTexture);
2723 drawQuad(otherProgram, "position", 0.5f);
2724 glBindTexture(GL_TEXTURE_2D, 0);
2725 glUseProgram(0);
2726
2727 glUseProgram(otherProgram);
2728 glUniform1i(uniformLoc, 0);
2729 glBindTexture(GL_TEXTURE_2D, otherTexture);
2730 drawQuad(otherProgram, "position", 0.5f);
2731 glBindTexture(GL_TEXTURE_2D, 0);
2732 glUseProgram(0);
2733
2734 glUseProgram(otherProgram);
2735 glUniform1i(uniformLoc, 0);
2736 glBindTexture(GL_TEXTURE_2D, otherTexture);
2737 drawQuad(otherProgram, "position", 0.5f);
2738 glBindTexture(GL_TEXTURE_2D, 0);
2739 glUseProgram(0);
2740
2741 glUseProgram(otherProgram);
2742 glUniform1i(uniformLoc, 0);
2743 glBindTexture(GL_TEXTURE_2D, otherTexture);
2744 drawQuad(otherProgram, "position", 0.5f);
2745 glBindTexture(GL_TEXTURE_2D, 0);
2746 glUseProgram(0);
2747 ASSERT_GL_NO_ERROR();
2748
2749 std::vector<GLColor> output(windowPixelCount, GLColor::black);
2750 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2751 output.data());
2752 EXPECT_EQ(pixelsRed, output);
2753
2754 setUpProgram();
2755 // Draw using PBO updated texture
2756 glUseProgram(mProgram);
2757 glUniform1i(mTexture2DUniformLocation, 0);
2758 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2759 drawQuad(mProgram, "position", 0.5f);
2760 ASSERT_GL_NO_ERROR();
2761
2762 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
2763 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2764 actual.data());
2765 // Value should be green as it was updated during PBO transfer to mTexture
2766 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
2767 EXPECT_EQ(expected, actual);
2768 }
2769
2770 // Almost mirrors UnitTest_DMSAA_dst_read test from Android skqp test suite
TEST_P(Texture2DTestES3,UnitTest_DMSAA_dst_read)2771 TEST_P(Texture2DTestES3, UnitTest_DMSAA_dst_read)
2772 {
2773 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB_write_control"));
2774
2775 GLTexture texture;
2776 glActiveTexture(GL_TEXTURE31);
2777 glBindTexture(GL_TEXTURE_2D, texture);
2778 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2779 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2780 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2781 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2782 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 16, 16);
2783 glBindTexture(GL_TEXTURE_2D, 0);
2784
2785 GLFramebuffer fboTexture;
2786 glBindFramebuffer(GL_FRAMEBUFFER, fboTexture);
2787 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2788 glCheckFramebufferStatus(GL_FRAMEBUFFER);
2789
2790 GLFramebuffer fboRenderbuffer;
2791 GLRenderbuffer renderbuffer;
2792 glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2793 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
2794 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 16, 16);
2795 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
2796 glCheckFramebufferStatus(GL_FRAMEBUFFER);
2797
2798 glActiveTexture(GL_TEXTURE0);
2799 glBindTexture(GL_TEXTURE_2D, texture);
2800 GLSampler sampler;
2801 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2802 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2803 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2804 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2805 glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.000000);
2806 glBindSampler(0, sampler);
2807 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2808
2809 glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2810 glViewport(0, 0, 16, 16);
2811 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2812
2813 // Create texture program
2814 ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
2815 ASSERT_GL_NO_ERROR();
2816 GLint texLocation = glGetUniformLocation(drawTexture, essl1_shaders::Texture2DUniform());
2817 ASSERT_NE(-1, texLocation);
2818 glUseProgram(drawTexture);
2819 glUniform1i(texLocation, 0);
2820
2821 glDisable(GL_BLEND);
2822 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2823 glDisable(GL_SCISSOR_TEST);
2824 glDisable(GL_STENCIL_TEST);
2825
2826 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
2827 drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2828
2829 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2830 glEnable(GL_SCISSOR_TEST);
2831 glScissor(0, 6, 10, 10);
2832
2833 drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2834
2835 // Blit fboRenderbuffer onto fboTexture
2836 glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
2837 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboTexture);
2838 glDisable(GL_SCISSOR_TEST);
2839 glBlitFramebuffer(0, 6, 10, 16, 0, 6, 10, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2840 GLenum attachment = GL_COLOR_ATTACHMENT0;
2841 glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, &attachment);
2842
2843 glBindFramebuffer(GL_FRAMEBUFFER, fboTexture);
2844 std::array<GLubyte, 10 * 10 * 4> pixelData;
2845 glReadPixels(0, 6, 10, 10, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
2846 glFinish();
2847
2848 glClearColor(1.000000, 1.000000, 1.000000, 1.000000);
2849 glClear(GL_COLOR_BUFFER_BIT);
2850
2851 glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2852 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
2853 drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2854
2855 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2856 glEnable(GL_SCISSOR_TEST);
2857 drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2858
2859 // Blit fboRenderbuffer onto fboTexture
2860 glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
2861 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboTexture);
2862 glDisable(GL_SCISSOR_TEST);
2863 glBlitFramebuffer(0, 6, 10, 16, 0, 6, 10, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2864 attachment = GL_COLOR_ATTACHMENT0;
2865 glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, &attachment);
2866 glFinish();
2867
2868 glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
2869 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
2870 drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2871
2872 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2873 glEnable(GL_SCISSOR_TEST);
2874 drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
2875
2876 // Blit fboRenderbuffer onto fboTexture
2877 glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
2878 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboTexture);
2879 glDisable(GL_SCISSOR_TEST);
2880 glBlitFramebuffer(0, 6, 10, 16, 0, 6, 10, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2881 attachment = GL_COLOR_ATTACHMENT0;
2882 glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, &attachment);
2883 glFinish();
2884
2885 glBindFramebuffer(GL_FRAMEBUFFER, fboTexture);
2886 glReadPixels(0, 6, 10, 10, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
2887 glFinish();
2888 }
2889
2890 // Test that stencil texture uploads work.
TEST_P(Texture2DTestES3,TexImageWithStencilData)2891 TEST_P(Texture2DTestES3, TexImageWithStencilData)
2892 {
2893 constexpr GLsizei kSize = 4;
2894
2895 const std::array<std::tuple<GLenum, GLenum, int, int>, 3> testConfigs = {
2896 std::make_tuple(GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, 4),
2897 std::make_tuple(GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, 4, 0),
2898 std::make_tuple(GL_STENCIL_INDEX8, GL_UNSIGNED_BYTE, 1, 0)};
2899
2900 for (auto testConfig : testConfigs)
2901 {
2902 const GLenum format = std::get<0>(testConfig);
2903 const GLenum type = std::get<1>(testConfig);
2904 const GLenum typeLength = std::get<2>(testConfig);
2905 const GLenum typeOffset = std::get<3>(testConfig);
2906
2907 ANGLE_SKIP_TEST_IF(format == GL_STENCIL_INDEX8 &&
2908 !IsGLExtensionEnabled("GL_OES_texture_stencil8"));
2909
2910 // Set up the framebuffer
2911 GLTexture colorTexture;
2912 glBindTexture(GL_TEXTURE_2D, colorTexture);
2913 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2914 nullptr);
2915 ASSERT_GL_NO_ERROR();
2916
2917 GLTexture depthStencilTexture;
2918 glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
2919
2920 GLubyte pixels[kSize * kSize * 8] = {};
2921 for (size_t pixelId = 0; pixelId < kSize * kSize; ++pixelId)
2922 {
2923 pixels[pixelId * typeLength + typeOffset] = 0xD5;
2924 }
2925 glTexImage2D(GL_TEXTURE_2D, 0, format, kSize, kSize, 0,
2926 format == GL_STENCIL_INDEX8 ? GL_STENCIL_INDEX : GL_DEPTH_STENCIL, type,
2927 pixels);
2928 ASSERT_GL_NO_ERROR();
2929
2930 GLFramebuffer fbo;
2931 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2932 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture,
2933 0);
2934 glFramebufferTexture2D(
2935 GL_FRAMEBUFFER,
2936 format == GL_STENCIL_INDEX8 ? GL_STENCIL_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT,
2937 GL_TEXTURE_2D, depthStencilTexture, 0);
2938 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2939 ASSERT_GL_NO_ERROR();
2940
2941 // Clear only color.
2942 glClearColor(0, 0, 0, 1);
2943 glClear(GL_COLOR_BUFFER_BIT);
2944 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2945
2946 // If stencil is not set to 0xD5, rendering would fail.
2947 glEnable(GL_STENCIL_TEST);
2948 glStencilFunc(GL_EQUAL, 0xD5, 0xFF);
2949 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2950 glStencilMask(0xFF);
2951
2952 // Draw red
2953 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2954 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
2955 ASSERT_GL_NO_ERROR();
2956
2957 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2958 }
2959 }
2960
2961 // Test that glTexSubImage2D combined with a PBO works properly. PBO has all pixels as red
2962 // except the middle one being green.
TEST_P(Texture2DTest,TexStorageWithPBOMiddlePixelDifferent)2963 TEST_P(Texture2DTest, TexStorageWithPBOMiddlePixelDifferent)
2964 {
2965 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2966 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2967
2968 int width = getWindowWidth();
2969 int height = getWindowHeight();
2970
2971 GLTexture tex2D;
2972 glActiveTexture(GL_TEXTURE0);
2973 glBindTexture(GL_TEXTURE_2D, tex2D);
2974
2975 std::vector<GLubyte> pixels(3 * 16 * 16);
2976
2977 // Initialize texture with default black color.
2978 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2979 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2980
2981 // Fill PBO's data with red, with middle one as green
2982 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2983 {
2984 if (pixelId == 8 * 7 + 7)
2985 {
2986 pixels[pixelId * 3 + 0] = 0;
2987 pixels[pixelId * 3 + 1] = 255;
2988 pixels[pixelId * 3 + 2] = 0;
2989 }
2990 else
2991 {
2992 pixels[pixelId * 3 + 0] = 255;
2993 pixels[pixelId * 3 + 1] = 0;
2994 pixels[pixelId * 3 + 2] = 0;
2995 }
2996 }
2997
2998 GLuint pbo;
2999 glGenBuffers(1, &pbo);
3000 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3001 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3002
3003 // Update the color of the texture's upper-left 8x8 pixels, leaves the other pixels untouched.
3004 // glTexSubImage2D should take into account that the image is dirty.
3005 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
3006 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3007 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3008
3009 setUpProgram();
3010
3011 glUseProgram(mProgram);
3012 glUniform1i(mTexture2DUniformLocation, 0);
3013 drawQuad(mProgram, "position", 0.5f);
3014 glDeleteBuffers(1, &pbo);
3015 EXPECT_GL_NO_ERROR();
3016 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
3017 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3018 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3019 }
3020
3021 // Test that glTexSubImage2D combined with a PBO works properly when glTexImage2D has
3022 // initialized the image with a luminance color
TEST_P(Texture2DTest,TexImageWithLuminancePBO)3023 TEST_P(Texture2DTest, TexImageWithLuminancePBO)
3024 {
3025 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3026
3027 int width = getWindowWidth();
3028 int height = getWindowHeight();
3029
3030 GLTexture tex2D;
3031 glActiveTexture(GL_TEXTURE0);
3032 glBindTexture(GL_TEXTURE_2D, tex2D);
3033
3034 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3035 nullptr);
3036
3037 // Fill PBO with white, with middle one as grey
3038 std::vector<GLubyte> pixels(16 * 16);
3039 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3040 {
3041 if (pixelId == 8 * 7 + 7)
3042 {
3043 pixels[pixelId] = 128;
3044 }
3045 else
3046 {
3047 pixels[pixelId] = 255;
3048 }
3049 }
3050
3051 GLuint pbo;
3052 glGenBuffers(1, &pbo);
3053 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3054 glBufferData(GL_PIXEL_UNPACK_BUFFER, 16 * 16, pixels.data(), GL_STATIC_DRAW);
3055
3056 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3057 // glTexSubImage2D should take into account that the image is dirty.
3058 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
3059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3061
3062 setUpProgram();
3063
3064 glUseProgram(mProgram);
3065 glUniform1i(mTexture2DUniformLocation, 0);
3066 drawQuad(mProgram, "position", 0.5f);
3067 glDeleteBuffers(1, &pbo);
3068 EXPECT_GL_NO_ERROR();
3069 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 255, 255, 255);
3070 EXPECT_PIXEL_NEAR(width / 2 - 1, height / 2 - 1, 128, 128, 128, 255, 1);
3071 }
3072
3073 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
3074 // initialized the image with a RGB656 color
TEST_P(Texture2DTest,TexImageWithRGB565PBO)3075 TEST_P(Texture2DTest, TexImageWithRGB565PBO)
3076 {
3077 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3078 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3079
3080 int width = getWindowWidth();
3081 int height = getWindowHeight();
3082
3083 GLTexture tex2D;
3084 glActiveTexture(GL_TEXTURE0);
3085 glBindTexture(GL_TEXTURE_2D, tex2D);
3086
3087 // Fill PBO with red, with middle one as green
3088 std::vector<GLushort> pixels(16 * 16);
3089 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3090 {
3091 if (pixelId == 8 * 7 + 8)
3092 {
3093 pixels[pixelId] = 0x7E0;
3094 }
3095 else
3096 {
3097 pixels[pixelId] = 0xF800;
3098 }
3099 }
3100
3101 GLuint pbo;
3102 glGenBuffers(1, &pbo);
3103 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3104 glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3105
3106 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB565, 16, 16);
3107
3108 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3109 // glTexSubImage2D should take into account that the image is dirty.
3110 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
3111 reinterpret_cast<void *>(2));
3112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3114
3115 setUpProgram();
3116
3117 glUseProgram(mProgram);
3118 glUniform1i(mTexture2DUniformLocation, 0);
3119 drawQuad(mProgram, "position", 0.5f);
3120 glDeleteBuffers(1, &pbo);
3121 EXPECT_GL_NO_ERROR();
3122 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3123 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3124 }
3125
3126 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
3127 // initialized the image with a RGBA4444 color
TEST_P(Texture2DTest,TexImageWithRGBA4444PBO)3128 TEST_P(Texture2DTest, TexImageWithRGBA4444PBO)
3129 {
3130 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3131 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3132
3133 int width = getWindowWidth();
3134 int height = getWindowHeight();
3135
3136 GLTexture tex2D;
3137 glActiveTexture(GL_TEXTURE0);
3138 glBindTexture(GL_TEXTURE_2D, tex2D);
3139
3140 // Fill PBO with red, with middle one as green
3141 std::vector<GLushort> pixels(16 * 16);
3142 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3143 {
3144 if (pixelId == 8 * 7 + 8)
3145 {
3146 pixels[pixelId] = 0xF0F;
3147 }
3148 else
3149 {
3150 pixels[pixelId] = 0xF00F;
3151 }
3152 }
3153
3154 GLuint pbo;
3155 glGenBuffers(1, &pbo);
3156 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3157 glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3158
3159 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA4, 16, 16);
3160
3161 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3162 // glTexSubImage2D should take into account that the image is dirty.
3163 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
3164 reinterpret_cast<void *>(2));
3165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3167
3168 setUpProgram();
3169
3170 glUseProgram(mProgram);
3171 glUniform1i(mTexture2DUniformLocation, 0);
3172 drawQuad(mProgram, "position", 0.5f);
3173 glDeleteBuffers(1, &pbo);
3174 EXPECT_GL_NO_ERROR();
3175 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3176 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3177 }
3178
3179 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
3180 // initialized the image with a RGBA5551 color
TEST_P(Texture2DTest,TexImageWithRGBA5551PBO)3181 TEST_P(Texture2DTest, TexImageWithRGBA5551PBO)
3182 {
3183 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3184 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3185
3186 int width = getWindowWidth();
3187 int height = getWindowHeight();
3188
3189 GLTexture tex2D;
3190 glActiveTexture(GL_TEXTURE0);
3191 glBindTexture(GL_TEXTURE_2D, tex2D);
3192
3193 // Fill PBO with red, with middle one as green
3194 std::vector<GLushort> pixels(16 * 16);
3195 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
3196 {
3197 if (pixelId == 8 * 7 + 7)
3198 {
3199 pixels[pixelId] = 0x7C1;
3200 }
3201 else
3202 {
3203 pixels[pixelId] = 0xF801;
3204 }
3205 }
3206
3207 GLuint pbo;
3208 glGenBuffers(1, &pbo);
3209 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3210 glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
3211
3212 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB5_A1, 16, 16);
3213
3214 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
3215 // glTexSubImage2D should take into account that the image is dirty.
3216 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr);
3217 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3219
3220 setUpProgram();
3221
3222 glUseProgram(mProgram);
3223 glUniform1i(mTexture2DUniformLocation, 0);
3224 drawQuad(mProgram, "position", 0.5f);
3225 glDeleteBuffers(1, &pbo);
3226 EXPECT_GL_NO_ERROR();
3227 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
3228 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
3229 }
3230
3231 // Test that glTexSubImage2D from a PBO respects GL_UNPACK_ROW_LENGTH.
TEST_P(Texture2DTest,TexImageUnpackRowLengthPBO)3232 TEST_P(Texture2DTest, TexImageUnpackRowLengthPBO)
3233 {
3234 if (getClientMajorVersion() < 3)
3235 {
3236 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3237 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3238 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_unpack_subimage"));
3239 }
3240
3241 const int width = getWindowWidth() / 2;
3242 const int height = getWindowHeight();
3243 const int rowLength = getWindowWidth();
3244 const int bufferSize = rowLength * height;
3245
3246 GLTexture tex2D;
3247 glActiveTexture(GL_TEXTURE0);
3248 glBindTexture(GL_TEXTURE_2D, tex2D);
3249
3250 std::vector<GLColor> pixels(bufferSize);
3251 for (int y = 0; y < rowLength; ++y)
3252 {
3253 for (int x = 0; x < width; ++x)
3254 {
3255 pixels[y * rowLength + x] =
3256 x < width ? (y < height / 2 ? GLColor::green : GLColor::blue) : GLColor::red;
3257 }
3258 }
3259
3260 GLuint pbo;
3261 glGenBuffers(1, &pbo);
3262 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3263 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize * sizeof(GLColor), pixels.data(),
3264 GL_STATIC_DRAW);
3265
3266 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
3267
3268 // Initializes the texture from width x height of the PBO.
3269 glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength);
3270 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3273
3274 setUpProgram();
3275
3276 glUseProgram(mProgram);
3277 glUniform1i(mTexture2DUniformLocation, 0);
3278 drawQuad(mProgram, "position", 0.5f);
3279 glDeleteBuffers(1, &pbo);
3280 EXPECT_GL_NO_ERROR();
3281 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3282 EXPECT_PIXEL_COLOR_EQ(0, height - 1, GLColor::blue);
3283 }
3284
3285 // Test if the KHR debug label is set and passed to D3D correctly using glCopyTexImage2D.
TEST_P(Texture2DTest,TextureKHRDebugLabelWithCopyTexImage2D)3286 TEST_P(Texture2DTest, TextureKHRDebugLabelWithCopyTexImage2D)
3287 {
3288 GLTexture texture2D;
3289 glBindTexture(GL_TEXTURE_2D, texture2D);
3290
3291 // Create a texture and copy into, to initialize storage object.
3292 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 32, 32, 0);
3293
3294 // Set KHR Debug Label.
3295 std::string label = "TestKHR.DebugLabel";
3296 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3297
3298 std::vector<char> labelBuf(label.length() + 1);
3299 GLsizei labelLengthBuf = 0;
3300
3301 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3302 &labelLengthBuf, labelBuf.data());
3303
3304 EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
3305 EXPECT_STREQ(label.c_str(), labelBuf.data());
3306
3307 // Delete the texture.
3308 texture2D.reset();
3309 EXPECT_GL_NO_ERROR();
3310
3311 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3312 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3313
3314 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3315 &labelLengthBuf, labelBuf.data());
3316 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3317 }
3318
3319 // Test to call labeling API before the storage texture is created.
TEST_P(Texture2DTest,CallKHRDebugLabelBeforeTexStorageCreation)3320 TEST_P(Texture2DTest, CallKHRDebugLabelBeforeTexStorageCreation)
3321 {
3322 GLTexture texture2D;
3323 glBindTexture(GL_TEXTURE_2D, texture2D);
3324
3325 // Set label before texture storage creation.
3326 std::string label = "TestKHR.DebugLabel";
3327 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3328
3329 // Create a texture and copy into, to initialize storage object.
3330 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 32, 32, 0);
3331
3332 std::vector<char> labelBuf(label.length() + 1);
3333 GLsizei labelLengthBuf = 0;
3334
3335 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3336 &labelLengthBuf, labelBuf.data());
3337
3338 EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
3339 EXPECT_STREQ(label.c_str(), labelBuf.data());
3340
3341 // Delete the texture.
3342 texture2D.reset();
3343 EXPECT_GL_NO_ERROR();
3344
3345 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
3346 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3347
3348 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
3349 &labelLengthBuf, labelBuf.data());
3350 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3351 }
3352
3353 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
3354 // initialized the image with a depth-only format.
TEST_P(Texture2DTestES3,TexImageWithDepthPBO)3355 TEST_P(Texture2DTestES3, TexImageWithDepthPBO)
3356 {
3357 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3358 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3359
3360 // http://anglebug.com/42263861
3361 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
3362
3363 constexpr GLsizei kSize = 4;
3364
3365 // Set up the framebuffer.
3366 GLTexture colorTexture;
3367 glBindTexture(GL_TEXTURE_2D, colorTexture);
3368 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3369 ASSERT_GL_NO_ERROR();
3370
3371 GLTexture depthTexture;
3372 glBindTexture(GL_TEXTURE_2D, depthTexture);
3373 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, kSize, kSize);
3374 ASSERT_GL_NO_ERROR();
3375
3376 GLFramebuffer fbo;
3377 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3378 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3379 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3380 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3381 ASSERT_GL_NO_ERROR();
3382
3383 // Clear depth to 0, ensuring the texture's image is allocated.
3384 glClearDepthf(0);
3385 glClearColor(0, 0, 0, 1);
3386 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3387 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3388
3389 // Fill depth with 1.0f.
3390 std::vector<GLushort> pixels(kSize * kSize);
3391 for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
3392 {
3393 pixels[pixelId] = 0xFFFF;
3394 }
3395
3396 GLuint pbo;
3397 glGenBuffers(1, &pbo);
3398 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3399 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
3400 GL_STATIC_DRAW);
3401 ASSERT_GL_NO_ERROR();
3402
3403 // Upload PBO data.
3404 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
3405 nullptr);
3406
3407 // If depth is not set to 1, rendering would fail.
3408 glEnable(GL_DEPTH_TEST);
3409 glDepthFunc(GL_LESS);
3410
3411 // Draw red
3412 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3413 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
3414 ASSERT_GL_NO_ERROR();
3415
3416 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
3417 }
3418
3419 // Test sampling modes with a DEPTH_COMPONENT16 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth16)3420 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth16)
3421 {
3422 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, false);
3423 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX, false);
3424 }
3425
3426 // Test sampling modes with a swizzled DEPTH_COMPONENT16 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth16Swizzled)3427 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth16Swizzled)
3428 {
3429 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, true);
3430 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX, true);
3431 }
3432
3433 // Test sampling modes with a DEPTH_COMPONENT24 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24)3434 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24)
3435 {
3436 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, false);
3437 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_STENCIL_INDEX, false);
3438 }
3439
3440 // Test sampling modes with a swizzled DEPTH_COMPONENT24 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24Swizzled)3441 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24Swizzled)
3442 {
3443 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, true);
3444 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT24, GL_STENCIL_INDEX, true);
3445 }
3446
3447 // Test depth sampling with a DEPTH_COMPONENT32F texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32f)3448 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32f)
3449 {
3450 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, false);
3451 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_STENCIL_INDEX, false);
3452 }
3453
3454 // Test depth sampling with a swizzled DEPTH_COMPONENT32F texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32fSwizzled)3455 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32fSwizzled)
3456 {
3457 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, true);
3458 TestSampleWithDepthStencilMode(GL_DEPTH_COMPONENT32F, GL_STENCIL_INDEX, true);
3459 }
3460
3461 // Test sampling modes with a DEPTH24_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24Stencil8)3462 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24Stencil8)
3463 {
3464 TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_DEPTH_COMPONENT, false);
3465 TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_STENCIL_INDEX, false);
3466 }
3467
3468 // Test sampling modes with a swizzled DEPTH24_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth24Stencil8Swizzled)3469 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth24Stencil8Swizzled)
3470 {
3471 TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_DEPTH_COMPONENT, true);
3472 TestSampleWithDepthStencilMode(GL_DEPTH24_STENCIL8, GL_STENCIL_INDEX, true);
3473 }
3474
3475 // Test sampling modes with a DEPTH32F_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32fStencil8)3476 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32fStencil8)
3477 {
3478 TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT, false);
3479 TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_STENCIL_INDEX, false);
3480 }
3481
3482 // Test sampling modes with a swizzled DEPTH32F_STENCIL8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithDepth32fStencil8Swizzled)3483 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithDepth32fStencil8Swizzled)
3484 {
3485 TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT, true);
3486 TestSampleWithDepthStencilMode(GL_DEPTH32F_STENCIL8, GL_STENCIL_INDEX, true);
3487 }
3488
3489 // Test sampling modes with a STENCIL_INDEX8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithStencil8)3490 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithStencil8)
3491 {
3492 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_stencil8"));
3493 TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_DEPTH_COMPONENT, false);
3494 TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, false);
3495 }
3496
3497 // Test sampling modes with a swizzled STENCIL_INDEX8 texture.
TEST_P(Texture2DDepthStencilTestES3,TexSampleModesWithStencil8Swizzled)3498 TEST_P(Texture2DDepthStencilTestES3, TexSampleModesWithStencil8Swizzled)
3499 {
3500 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_stencil8"));
3501 TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_DEPTH_COMPONENT, true);
3502 TestSampleWithDepthStencilMode(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, true);
3503 }
3504
3505 // Test that updating a texture format triggers depth/stencil mode resync.
TEST_P(Texture2DDepthStencilTestES3,Redefinition)3506 TEST_P(Texture2DDepthStencilTestES3, Redefinition)
3507 {
3508 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_stencil_texturing"));
3509
3510 constexpr char kDepthFS[] =
3511 R"(#version 300 es
3512 precision mediump float;
3513 uniform highp sampler2D tex;
3514 out vec4 color;
3515 void main()
3516 {
3517 color = texture(tex, vec2(0, 0));
3518 })";
3519 ANGLE_GL_PROGRAM(programDepth, essl3_shaders::vs::Simple(), kDepthFS);
3520
3521 constexpr char kStencilFS[] =
3522 R"(#version 300 es
3523 precision mediump float;
3524 uniform highp usampler2D tex;
3525 out vec4 color;
3526 void main()
3527 {
3528 color = vec4(texelFetch(tex, ivec2(0, 0), 0)) / 255.0;
3529 })";
3530 ANGLE_GL_PROGRAM(programStencil, essl3_shaders::vs::Simple(), kStencilFS);
3531
3532 // Set up a D32F with stencil mode.
3533 GLTexture texture;
3534 glBindTexture(GL_TEXTURE_2D, texture);
3535 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3536 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3537 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE_ANGLE, GL_STENCIL_INDEX);
3538
3539 const GLfloat d32f = 0.5f;
3540 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
3541 &d32f);
3542 ASSERT_GL_NO_ERROR();
3543
3544 drawQuad(programDepth, essl3_shaders::PositionAttrib(), 0.5f);
3545 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
3546
3547 // Redefine the same texture as D24S8
3548 const GLuint d24s8 = 0xC0;
3549 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL,
3550 GL_UNSIGNED_INT_24_8, &d24s8);
3551 ASSERT_GL_NO_ERROR();
3552
3553 drawQuad(programStencil, essl3_shaders::PositionAttrib(), 0.5f);
3554 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(192, 0, 0, 1), 1);
3555
3556 // Redefine the same texture as D16
3557 const GLushort d16 = 0x4000;
3558 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 1, 1, 0, GL_DEPTH_COMPONENT,
3559 GL_UNSIGNED_SHORT, &d16);
3560 ASSERT_GL_NO_ERROR();
3561
3562 drawQuad(programDepth, essl3_shaders::PositionAttrib(), 0.5f);
3563 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(64, 0, 0, 255), 1);
3564 }
3565
3566 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
3567 // initialized the image with a stencil-only format.
TEST_P(Texture2DTestES3,TexImageWithStencilPBO)3568 TEST_P(Texture2DTestES3, TexImageWithStencilPBO)
3569 {
3570 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3571 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3572
3573 // http://anglebug.com/42263861
3574 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
3575
3576 constexpr GLsizei kSize = 4;
3577
3578 // Set up the framebuffer.
3579 GLTexture colorTexture;
3580 glBindTexture(GL_TEXTURE_2D, colorTexture);
3581 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3582 ASSERT_GL_NO_ERROR();
3583
3584 GLTexture stencilTexture;
3585 glBindTexture(GL_TEXTURE_2D, stencilTexture);
3586 glTexStorage2D(GL_TEXTURE_2D, 1, GL_STENCIL_INDEX8, kSize, kSize);
3587 ASSERT_GL_NO_ERROR();
3588
3589 GLFramebuffer fbo;
3590 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3591 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3592 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 0);
3593 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3594 ASSERT_GL_NO_ERROR();
3595
3596 // Clear stencil to 0, ensuring the texture's image is allocated.
3597 glClearStencil(0);
3598 glClearColor(0, 0, 0, 1);
3599 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3600 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3601
3602 // Fill stencil with 0x4E
3603 std::vector<GLubyte> pixels(kSize * kSize);
3604 for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
3605 {
3606 pixels[pixelId] = 0x4E;
3607 }
3608
3609 GLuint pbo;
3610 glGenBuffers(1, &pbo);
3611 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3612 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
3613 GL_STATIC_DRAW);
3614 ASSERT_GL_NO_ERROR();
3615
3616 // Upload PBO data.
3617 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
3618 nullptr);
3619 ASSERT_GL_NO_ERROR();
3620
3621 // If stencil is not set to 0x4E, rendering would fail.
3622 glEnable(GL_STENCIL_TEST);
3623 glStencilFunc(GL_EQUAL, 0x4E, 0xFF);
3624 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3625 glStencilMask(0xFF);
3626
3627 // Draw red
3628 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3629 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
3630 ASSERT_GL_NO_ERROR();
3631
3632 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
3633 }
3634
3635 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
3636 // initialized the image with a depth/stencil format.
TEST_P(Texture2DTestES3,TexImageWithDepthStencilPBO)3637 TEST_P(Texture2DTestES3, TexImageWithDepthStencilPBO)
3638 {
3639 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
3640 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
3641
3642 // http://anglebug.com/42263861
3643 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
3644
3645 constexpr GLsizei kSize = 4;
3646
3647 // Set up the framebuffer.
3648 GLTexture colorTexture;
3649 glBindTexture(GL_TEXTURE_2D, colorTexture);
3650 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3651 ASSERT_GL_NO_ERROR();
3652
3653 GLTexture depthStencilTexture;
3654 glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
3655 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
3656 ASSERT_GL_NO_ERROR();
3657
3658 GLFramebuffer fbo;
3659 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3660 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3661 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
3662 depthStencilTexture, 0);
3663 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3664 ASSERT_GL_NO_ERROR();
3665
3666 // Clear depth and stencil to 0, ensuring the texture's image is allocated.
3667 glClearDepthf(0);
3668 glClearStencil(0);
3669 glClearColor(0, 0, 0, 1);
3670 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3671 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3672
3673 // Fill depth with 1.0f and stencil with 0xD5
3674 std::vector<GLuint> pixels(kSize * kSize);
3675 for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
3676 {
3677 pixels[pixelId] = 0xFFFFFFD5;
3678 }
3679
3680 GLuint pbo;
3681 glGenBuffers(1, &pbo);
3682 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
3683 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
3684 GL_STATIC_DRAW);
3685 ASSERT_GL_NO_ERROR();
3686
3687 // Upload PBO data.
3688 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
3689 nullptr);
3690
3691 // If depth is not set to 1, rendering would fail.
3692 glEnable(GL_DEPTH_TEST);
3693 glDepthFunc(GL_LESS);
3694
3695 // If stencil is not set to 0xD5, rendering would fail.
3696 glEnable(GL_STENCIL_TEST);
3697 glStencilFunc(GL_EQUAL, 0xD5, 0xFF);
3698 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3699 glStencilMask(0xFF);
3700
3701 // Draw red
3702 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3703 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
3704 ASSERT_GL_NO_ERROR();
3705
3706 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
3707 }
3708
3709 // Test that it is possible to upload to a texture, upload a second texture and delete the first.
TEST_P(Texture2DTestES3,Texture1UploadThenTexture2UploadThenTexture1Delete)3710 TEST_P(Texture2DTestES3, Texture1UploadThenTexture2UploadThenTexture1Delete)
3711 {
3712 constexpr size_t kMaxBufferToImageCopySize = 64 * 1024 * 1024;
3713 constexpr size_t kTexSize = 4096;
3714 constexpr uint32_t kPixelSizeRGBA = 4;
3715 static_assert(kTexSize * kTexSize * kPixelSizeRGBA == kMaxBufferToImageCopySize);
3716
3717 std::vector<GLColor> textureColors(kTexSize * kTexSize, GLColor::red);
3718
3719 // A mutable texture is defined here. The second texture is used to flush the first one when the
3720 // relevant feature (mutableMipmapTextureUpload) is enabled. If flushed, the update on level 0
3721 // is large enough to trigger one submission using Vulkan, but the rest of its updates will not
3722 // trigger a second one. In that case, the texture should not be deleted until all updates are
3723 // processed.
3724 GLuint texture1;
3725 glGenTextures(1, &texture1);
3726 glBindTexture(GL_TEXTURE_2D, texture1);
3727 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3728 textureColors.data());
3729 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
3730 GL_UNSIGNED_BYTE, textureColors.data());
3731 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3732 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3733 ASSERT_GL_NO_ERROR();
3734
3735 GLTexture texture2;
3736 glBindTexture(GL_TEXTURE_2D, texture2);
3737 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3738 textureColors.data());
3739 ASSERT_GL_NO_ERROR();
3740
3741 glDeleteTextures(1, &texture1);
3742 ASSERT_GL_NO_ERROR();
3743 }
3744
3745 // Test that the driver performs a flush when there is a large amount of image updates.
TEST_P(Texture2DMemoryTestES3,TextureDataInLoopUntilFlush)3746 TEST_P(Texture2DMemoryTestES3, TextureDataInLoopUntilFlush)
3747 {
3748 // Run this test for Vulkan only.
3749 ANGLE_SKIP_TEST_IF(!IsVulkan());
3750
3751 // If VK_EXT_host_image_copy is used, uploads will all be done on the CPU and there would be no
3752 // submissions.
3753 ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::SupportsHostImageCopy));
3754
3755 GLPerfMonitor monitor;
3756 glBeginPerfMonitorAMD(monitor);
3757
3758 uint64_t expectedSubmitCalls = getPerfCounters().commandQueueSubmitCallsTotal + 1;
3759
3760 // Set up program
3761 const char *kFS = R"(#version 300 es
3762 precision highp float;
3763 uniform uni { vec4 color; };
3764 out vec4 fragColor;
3765 void main()
3766 {
3767 fragColor = color;
3768 })";
3769 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
3770 ASSERT_NE(program, 0u);
3771
3772 // Set up the uniform buffer and framebuffer
3773 GLint uniformBufferIndex;
3774 uniformBufferIndex = glGetUniformBlockIndex(program, "uni");
3775 ASSERT_NE(uniformBufferIndex, -1);
3776
3777 glClear(GL_COLOR_BUFFER_BIT);
3778 constexpr size_t kBufferSize = 4 * 1024 * 1024;
3779 std::vector<float> floatData;
3780 floatData.resize(kBufferSize / (sizeof(float)), 0.0f);
3781 floatData[0] = 0.5f;
3782 floatData[1] = 0.75f;
3783 floatData[2] = 0.25f;
3784 floatData[3] = 1.0f;
3785
3786 GLBuffer uniformBuffer;
3787 glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer);
3788 glBufferData(GL_UNIFORM_BUFFER, kBufferSize, floatData.data(), GL_STATIC_DRAW);
3789 glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniformBuffer);
3790 glUniformBlockBinding(program, uniformBufferIndex, 0);
3791
3792 GLFramebuffer fbo;
3793 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3794
3795 // Create textures and draw
3796 constexpr uint32_t kTextureWidth = 512;
3797 constexpr uint32_t kTextureHeight = 512;
3798 std::vector<GLColor> textureColor(kTextureWidth * kTextureHeight, GLColor::red);
3799 constexpr uint32_t kIterationCount = 4096;
3800 GLTexture textures[kIterationCount];
3801
3802 for (auto &texture : textures)
3803 {
3804 glBindTexture(GL_TEXTURE_2D, texture);
3805 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
3806 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RGBA,
3807 GL_UNSIGNED_BYTE, textureColor.data());
3808
3809 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3810 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3811 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3812
3813 if (getPerfCounters().commandQueueSubmitCallsTotal == expectedSubmitCalls)
3814 {
3815 break;
3816 }
3817 }
3818 glEndPerfMonitorAMD(monitor);
3819
3820 EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedSubmitCalls);
3821 ASSERT_GL_NO_ERROR();
3822 EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1);
3823 }
3824
3825 // Creating a texture and drawing with it in a loop without glFlush() should still work. Driver is
3826 // supposedly to issue flush if needed. There should be no fallbacks to allocate outside the device
3827 // memory.
TEST_P(Texture2DMemoryTestES3,TextureDataInLoopManyTimes)3828 TEST_P(Texture2DMemoryTestES3, TextureDataInLoopManyTimes)
3829 {
3830 // Run this test for Vulkan only.
3831 ANGLE_SKIP_TEST_IF(!IsVulkan());
3832
3833 GLPerfMonitor monitor;
3834 glBeginPerfMonitorAMD(monitor);
3835
3836 uint64_t expectedSubmitCalls = getPerfCounters().commandQueueSubmitCallsTotal + 1;
3837 uint64_t expectedDeviceMemoryFallbacks = getPerfCounters().deviceMemoryImageAllocationFallbacks;
3838
3839 // Set up program
3840 const char *kFS = R"(#version 300 es
3841 precision highp float;
3842 uniform uni { vec4 color; };
3843 out vec4 fragColor;
3844 void main()
3845 {
3846 fragColor = color;
3847 })";
3848 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
3849 ASSERT_NE(program, 0u);
3850
3851 // Set up the uniform buffer and framebuffer
3852 GLint uniformBufferIndex;
3853 uniformBufferIndex = glGetUniformBlockIndex(program, "uni");
3854 ASSERT_NE(uniformBufferIndex, -1);
3855
3856 glClear(GL_COLOR_BUFFER_BIT);
3857 constexpr size_t kBufferSize = 4 * 1024 * 1024;
3858 std::vector<float> floatData;
3859 floatData.resize(kBufferSize / (sizeof(float)), 0.0f);
3860 floatData[0] = 0.5f;
3861 floatData[1] = 0.75f;
3862 floatData[2] = 0.25f;
3863 floatData[3] = 1.0f;
3864
3865 GLBuffer uniformBuffer;
3866 glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer);
3867 glBufferData(GL_UNIFORM_BUFFER, kBufferSize, floatData.data(), GL_STATIC_DRAW);
3868 glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniformBuffer);
3869 glUniformBlockBinding(program, uniformBufferIndex, 0);
3870
3871 GLFramebuffer fbo;
3872 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3873
3874 // Create textures and draw. We will use very small image updates to prevent flush before the
3875 // device runs out of memory.
3876 constexpr uint32_t kTextureWidth = 4096;
3877 constexpr uint32_t kTextureHeight = 4096;
3878 std::vector<GLColor> textureColor(kTextureWidth * kTextureHeight, GLColor::red);
3879 constexpr uint32_t kIterationCount = 4096;
3880
3881 uint32_t iteration = 0;
3882 for (; iteration < kIterationCount; iteration++)
3883 {
3884 GLTexture texture;
3885 glBindTexture(GL_TEXTURE_2D, texture);
3886 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureWidth, kTextureHeight, 0, GL_RGBA,
3887 GL_UNSIGNED_BYTE, nullptr);
3888 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
3889 textureColor.data());
3890
3891 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3892 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3893 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3894
3895 if (getPerfCounters().commandQueueSubmitCallsTotal >= expectedSubmitCalls)
3896 {
3897 break;
3898 }
3899 }
3900
3901 glEndPerfMonitorAMD(monitor);
3902 EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedSubmitCalls)
3903 << "iteration " << iteration;
3904 EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks,
3905 expectedDeviceMemoryFallbacks);
3906 ASSERT_GL_NO_ERROR();
3907 }
3908
3909 // Test functionality of GL_ANGLE_yuv_internal_format with min/mag filters
3910 // set to nearest and linear modes.
TEST_P(Texture2DTestES3YUV,TexStorage2DYuvFilterModes)3911 TEST_P(Texture2DTestES3YUV, TexStorage2DYuvFilterModes)
3912 {
3913 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3914
3915 // Create YUV texture
3916 GLTexture yuvTexture;
3917 GLubyte yuvColor[] = {40, 40, 40, 40, 40, 40, 40, 40, 240, 109, 240, 109};
3918 GLubyte expectedRgbColor[] = {0, 0, 255, 255};
3919 createImmutableTexture2D(yuvTexture, 2, 4, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3920 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
3921
3922 // Default is nearest filter mode
3923 verifyResults2D(yuvTexture, expectedRgbColor);
3924 ASSERT_GL_NO_ERROR();
3925
3926 // Enable linear filter mode
3927 glBindTexture(GL_TEXTURE_2D, yuvTexture);
3928 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3929 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3930 verifyResults2D(yuvTexture, expectedRgbColor);
3931 ASSERT_GL_NO_ERROR();
3932
3933 const int windowHeight = getWindowHeight();
3934 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::blue, 1);
3935 EXPECT_PIXEL_COLOR_NEAR(0, windowHeight - 1, GLColor::blue, 1);
3936 EXPECT_PIXEL_COLOR_NEAR(0, windowHeight / 2, GLColor::blue, 1);
3937 }
3938
3939 // Test functionality of GL_ANGLE_yuv_internal_format while cycling through RGB and YUV sources
TEST_P(Texture2DTestES3,TexStorage2DCycleThroughYuvAndRgbSources)3940 TEST_P(Texture2DTestES3, TexStorage2DCycleThroughYuvAndRgbSources)
3941 {
3942 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3943
3944 // Create YUV texture
3945 GLTexture yuvTexture;
3946 GLubyte yuvColor[6] = {40, 40, 40, 40, 240, 109};
3947 GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
3948 createImmutableTexture2D(yuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3949 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
3950
3951 // Create RGBA texture
3952 GLTexture rgbaTexture;
3953 GLubyte rgbaColor[4] = {0, 0, 255, 255};
3954 createImmutableTexture2D(rgbaTexture, 1, 1, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, 1, rgbaColor);
3955
3956 // Cycle through source textures
3957 // RGBA source
3958 verifyResults2D(rgbaTexture, rgbaColor);
3959 ASSERT_GL_NO_ERROR();
3960
3961 // YUV source
3962 verifyResults2D(yuvTexture, expectedRgbColor);
3963 ASSERT_GL_NO_ERROR();
3964
3965 // RGBA source
3966 verifyResults2D(rgbaTexture, rgbaColor);
3967 ASSERT_GL_NO_ERROR();
3968 }
3969
3970 // Test functionality of GL_ANGLE_yuv_internal_format with large number of YUV sources
TEST_P(Texture2DTestES3,TexStorage2DLargeYuvTextureCount)3971 TEST_P(Texture2DTestES3, TexStorage2DLargeYuvTextureCount)
3972 {
3973 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3974
3975 constexpr uint32_t kTextureCount = 16;
3976
3977 // Create YUV texture
3978 GLTexture yuvTexture[kTextureCount];
3979 for (uint32_t i = 0; i < kTextureCount; i++)
3980 {
3981 // Create 2 plane YCbCr 420 texture
3982 createImmutableTexture2D(yuvTexture[i], 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3983 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
3984 }
3985
3986 // Cycle through YUV source textures
3987 glUseProgram(mProgram);
3988 glUniform1i(mTexture2DUniformLocation, 0);
3989
3990 for (uint32_t i = 0; i < kTextureCount; i++)
3991 {
3992 glBindTexture(GL_TEXTURE_2D, yuvTexture[i]);
3993 drawQuad(mProgram, "position", 0.5f);
3994 ASSERT_GL_NO_ERROR();
3995 }
3996 }
3997
3998 // Test functionality of GL_ANGLE_yuv_internal_format with simultaneous use of multiple YUV sources
TEST_P(Texture2DTestES3,TexStorage2DSimultaneousUseOfMultipleYuvSourcesNoData)3999 TEST_P(Texture2DTestES3, TexStorage2DSimultaneousUseOfMultipleYuvSourcesNoData)
4000 {
4001 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4002
4003 // Create YUV texture
4004 // Create 2 plane YCbCr 420 texture
4005 GLTexture twoPlaneYuvTexture;
4006 createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4007 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4008
4009 // Create 3 plane YCbCr 420 texture
4010 GLTexture threePlaneYuvTexture;
4011 createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4012 GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4013
4014 // Cycle through YUV source textures
4015 // Create program with 2 samplers
4016 const char *vertexShaderSource = getVertexShaderSource();
4017 const char *fragmentShaderSource = R"(#version 300 es
4018 precision highp float;
4019 uniform sampler2D tex0;
4020 uniform sampler2D tex1;
4021 in vec2 texcoord;
4022 out vec4 fragColor;
4023
4024 void main()
4025 {
4026 vec4 color0 = texture(tex0, texcoord);
4027 vec4 color1 = texture(tex1, texcoord);
4028 fragColor = color0 + color1;
4029 })";
4030
4031 ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
4032 glUseProgram(twoSamplersProgram);
4033 GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
4034 ASSERT_NE(-1, tex0Location);
4035 GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
4036 ASSERT_NE(-1, tex1Location);
4037
4038 glUniform1i(tex0Location, 0);
4039 glUniform1i(tex1Location, 1);
4040
4041 // Bind 2 plane YUV source
4042 glActiveTexture(GL_TEXTURE0);
4043 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4044 ASSERT_GL_NO_ERROR();
4045
4046 // Bind 3 plane YUV source
4047 glActiveTexture(GL_TEXTURE1);
4048 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4049 ASSERT_GL_NO_ERROR();
4050
4051 drawQuad(twoSamplersProgram, "position", 0.5f);
4052 ASSERT_GL_NO_ERROR();
4053
4054 // Switch active texture index and draw again
4055 // Bind 2 plane YUV source
4056 glActiveTexture(GL_TEXTURE1);
4057 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4058 ASSERT_GL_NO_ERROR();
4059
4060 // Bind 3 plane YUV source
4061 glActiveTexture(GL_TEXTURE0);
4062 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4063 ASSERT_GL_NO_ERROR();
4064
4065 drawQuad(twoSamplersProgram, "position", 0.5f);
4066 ASSERT_GL_NO_ERROR();
4067 }
4068
4069 // Test functional of GL_ANGLE_yuv_internal_format while cycling through YUV sources
TEST_P(Texture2DTestES3,TexStorage2DCycleThroughYuvSourcesNoData)4070 TEST_P(Texture2DTestES3, TexStorage2DCycleThroughYuvSourcesNoData)
4071 {
4072 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4073
4074 // Create YUV texture
4075 // Create 2 plane YCbCr 420 texture
4076 GLTexture twoPlaneYuvTexture;
4077 createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4078 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4079
4080 // Create 3 plane YCbCr 420 texture
4081 GLTexture threePlaneYuvTexture;
4082 createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4083 GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4084
4085 // Cycle through YUV source textures
4086 glUseProgram(mProgram);
4087 glUniform1i(mTexture2DUniformLocation, 0);
4088
4089 // 2 plane YUV source
4090 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4091 drawQuad(mProgram, "position", 0.5f);
4092 ASSERT_GL_NO_ERROR();
4093
4094 // 3 plane YUV source
4095 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4096 drawQuad(mProgram, "position", 0.5f);
4097 ASSERT_GL_NO_ERROR();
4098
4099 // 2 plane YUV source
4100 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4101 drawQuad(mProgram, "position", 0.5f);
4102 ASSERT_GL_NO_ERROR();
4103 }
4104
4105 // Test functionality of GL_ANGLE_yuv_internal_format with multiple YUV samplers while
4106 // switching sampler uniform values.
TEST_P(Texture2DTestES3,TexStorage2DMultipleYuvSamplersSwitchSamplerUniformValues)4107 TEST_P(Texture2DTestES3, TexStorage2DMultipleYuvSamplersSwitchSamplerUniformValues)
4108 {
4109 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4110
4111 // Create YUV texture
4112 GLTexture yuvTexture;
4113 GLubyte yuvColor[6] = {40, 40, 40, 40, 240, 109};
4114 GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
4115
4116 // Create YUV texture
4117 // Create 2 plane YCbCr 420 texture
4118 GLTexture twoPlaneYuvTexture;
4119 createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4120 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
4121 // Create 3 plane YCbCr 420 texture
4122 GLTexture threePlaneYuvTexture;
4123 createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4124 GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4125 // Create program with 2 samplers
4126 const char *vertexShaderSource = getVertexShaderSource();
4127 const char *fragmentShaderSource = R"(#version 300 es
4128 precision highp float;
4129 uniform sampler2D tex0;
4130 uniform sampler2D tex1;
4131 uniform int texIndex;
4132 in vec2 texcoord;
4133 out vec4 fragColor;
4134 void main()
4135 {
4136 vec4 color0 = texture(tex0, texcoord);
4137 vec4 color1 = texture(tex1, texcoord);
4138 if (texIndex == 0)
4139 {
4140 fragColor = color0;
4141 }
4142 else
4143 {
4144 fragColor = color1;
4145 }
4146 })";
4147 ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
4148 glUseProgram(twoSamplersProgram);
4149 GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
4150 ASSERT_NE(-1, tex0Location);
4151 GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
4152 ASSERT_NE(-1, tex1Location);
4153 GLint texIndexLocation = glGetUniformLocation(twoSamplersProgram, "texIndex");
4154 ASSERT_NE(-1, texIndexLocation);
4155 // Bind 2 plane YUV source
4156 glActiveTexture(GL_TEXTURE0);
4157 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4158 ASSERT_GL_NO_ERROR();
4159 // Bind 3 plane YUV source
4160 glActiveTexture(GL_TEXTURE1);
4161 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4162 ASSERT_GL_NO_ERROR();
4163
4164 // Set sampler uniform values and draw
4165 glUniform1i(tex0Location, 0);
4166 glUniform1i(tex1Location, 1);
4167 // Set texture index selector to the 2 plane texture unit
4168 glUniform1i(texIndexLocation, 0);
4169 drawQuad(twoSamplersProgram, "position", 0.5f);
4170 ASSERT_GL_NO_ERROR();
4171 EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4172 expectedRgbColor[3], 1);
4173 ASSERT_GL_NO_ERROR();
4174
4175 // Switch sampler uniform values and draw
4176 glUniform1i(tex0Location, 1);
4177 glUniform1i(tex1Location, 0);
4178 // Set texture index selector to the 2 plane texture unit
4179 glUniform1i(texIndexLocation, 1);
4180 drawQuad(twoSamplersProgram, "position", 0.5f);
4181 ASSERT_GL_NO_ERROR();
4182 EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4183 expectedRgbColor[3], 1);
4184 ASSERT_GL_NO_ERROR();
4185
4186 // Switch back sampler uniform values and draw
4187 glUniform1i(tex0Location, 0);
4188 glUniform1i(tex1Location, 1);
4189 // Set texture index selector to the 2 plane texture unit
4190 glUniform1i(texIndexLocation, 0);
4191 drawQuad(twoSamplersProgram, "position", 0.5f);
4192 ASSERT_GL_NO_ERROR();
4193 EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4194 expectedRgbColor[3], 1);
4195 ASSERT_GL_NO_ERROR();
4196 }
4197
4198 // Test functionality of GL_ANGLE_yuv_internal_format with multiple YUV samplers while
4199 // switching bound textures.
TEST_P(Texture2DTestES3,TexStorage2DMultipleYuvSamplersSwitchBoundTextures)4200 TEST_P(Texture2DTestES3, TexStorage2DMultipleYuvSamplersSwitchBoundTextures)
4201 {
4202 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
4203
4204 // Create YUV texture
4205 GLTexture yuvTexture;
4206 GLubyte yuvColor[6] = {40, 40, 40, 40, 240, 109};
4207 GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
4208
4209 // Create YUV texture
4210 // Create 2 plane YCbCr 420 texture
4211 GLTexture twoPlaneYuvTexture;
4212 createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
4213 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
4214 // Create 3 plane YCbCr 420 texture
4215 GLTexture threePlaneYuvTexture;
4216 createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
4217 GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
4218 // Create program with 2 samplers
4219 const char *vertexShaderSource = getVertexShaderSource();
4220 const char *fragmentShaderSource = R"(#version 300 es
4221 precision highp float;
4222 uniform sampler2D tex0;
4223 uniform sampler2D tex1;
4224 uniform int texIndex;
4225 in vec2 texcoord;
4226 out vec4 fragColor;
4227 void main()
4228 {
4229 vec4 color0 = texture(tex0, texcoord);
4230 vec4 color1 = texture(tex1, texcoord);
4231 if (texIndex == 0)
4232 {
4233 fragColor = color0;
4234 }
4235 else
4236 {
4237 fragColor = color1;
4238 }
4239 })";
4240 ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
4241 glUseProgram(twoSamplersProgram);
4242 GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
4243 ASSERT_NE(-1, tex0Location);
4244 GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
4245 ASSERT_NE(-1, tex1Location);
4246 GLint texIndexLocation = glGetUniformLocation(twoSamplersProgram, "texIndex");
4247 ASSERT_NE(-1, texIndexLocation);
4248 // Set sampler uniform values
4249 glUniform1i(tex0Location, 0);
4250 glUniform1i(tex1Location, 1);
4251
4252 // Bind 2 plane YUV source
4253 glActiveTexture(GL_TEXTURE0);
4254 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4255 ASSERT_GL_NO_ERROR();
4256 // Bind 3 plane YUV source
4257 glActiveTexture(GL_TEXTURE1);
4258 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4259 ASSERT_GL_NO_ERROR();
4260 // Set texture index selector to the 2 plane texture unit
4261 glUniform1i(texIndexLocation, 0);
4262 // Draw
4263 drawQuad(twoSamplersProgram, "position", 0.5f);
4264 ASSERT_GL_NO_ERROR();
4265 EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4266 expectedRgbColor[3], 1);
4267 ASSERT_GL_NO_ERROR();
4268
4269 // Bind 3 plane YUV source
4270 glActiveTexture(GL_TEXTURE0);
4271 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
4272 ASSERT_GL_NO_ERROR();
4273 // Bind 2 plane YUV source
4274 glActiveTexture(GL_TEXTURE1);
4275 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
4276 ASSERT_GL_NO_ERROR();
4277 // Set texture index selector to the 2 plane texture unit
4278 glUniform1i(texIndexLocation, 1);
4279 // Draw
4280 drawQuad(twoSamplersProgram, "position", 0.5f);
4281 ASSERT_GL_NO_ERROR();
4282 EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
4283 expectedRgbColor[3], 1);
4284 ASSERT_GL_NO_ERROR();
4285 }
4286
4287 // Tests CopySubImage for float formats
TEST_P(Texture2DTest,CopySubImageFloat_R_R)4288 TEST_P(Texture2DTest, CopySubImageFloat_R_R)
4289 {
4290 testFloatCopySubImage(1, 1);
4291 }
4292
TEST_P(Texture2DTest,CopySubImageFloat_RG_R)4293 TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
4294 {
4295 testFloatCopySubImage(2, 1);
4296 }
4297
TEST_P(Texture2DTest,CopySubImageFloat_RG_RG)4298 TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
4299 {
4300 testFloatCopySubImage(2, 2);
4301 }
4302
TEST_P(Texture2DTest,CopySubImageFloat_RGB_R)4303 TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
4304 {
4305 testFloatCopySubImage(3, 1);
4306 }
4307
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RG)4308 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
4309 {
4310 testFloatCopySubImage(3, 2);
4311 }
4312
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RGB)4313 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
4314 {
4315 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/40096350)
4316 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
4317
4318 testFloatCopySubImage(3, 3);
4319 }
4320
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_R)4321 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
4322 {
4323 testFloatCopySubImage(4, 1);
4324 }
4325
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RG)4326 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
4327 {
4328 testFloatCopySubImage(4, 2);
4329 }
4330
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGB)4331 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
4332 {
4333 testFloatCopySubImage(4, 3);
4334 }
4335
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGBA)4336 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
4337 {
4338 testFloatCopySubImage(4, 4);
4339 }
4340
4341 // Port of
4342 // https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
4343 // Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
4344 // handles GL_ALPHA
TEST_P(Texture2DTest,TextureNPOT_GL_ALPHA_UBYTE)4345 TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
4346 {
4347 const int npotTexSize = 5;
4348 const int potTexSize = 4; // Should be less than npotTexSize
4349 GLTexture tex2D;
4350
4351 if (IsGLExtensionEnabled("GL_OES_texture_npot"))
4352 {
4353 // This test isn't applicable if texture_npot is enabled
4354 return;
4355 }
4356
4357 setUpProgram();
4358
4359 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
4360
4361 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
4362 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4363
4364 glActiveTexture(GL_TEXTURE0);
4365 glBindTexture(GL_TEXTURE_2D, tex2D);
4366
4367 const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
4368
4369 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4371
4372 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
4373 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
4374 GL_UNSIGNED_BYTE, pixels.data());
4375 EXPECT_GL_ERROR(GL_INVALID_VALUE);
4376
4377 // Check that an NPOT texture on level 0 succeeds
4378 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
4379 GL_UNSIGNED_BYTE, pixels.data());
4380 EXPECT_GL_NO_ERROR();
4381
4382 // Check that generateMipmap fails on NPOT
4383 glGenerateMipmap(GL_TEXTURE_2D);
4384 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4385
4386 // Check that nothing is drawn if filtering is not correct for NPOT
4387 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
4390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
4391 glClear(GL_COLOR_BUFFER_BIT);
4392 drawQuad(mProgram, "position", 1.0f);
4393 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
4394
4395 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
4396 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4397 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4398 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
4399 glClear(GL_COLOR_BUFFER_BIT);
4400 drawQuad(mProgram, "position", 1.0f);
4401 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
4402
4403 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
4404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4405 glClear(GL_COLOR_BUFFER_BIT);
4406 drawQuad(mProgram, "position", 1.0f);
4407 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
4408
4409 // Check that glTexImage2D for POT texture succeeds
4410 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
4411 pixels.data());
4412 EXPECT_GL_NO_ERROR();
4413
4414 // Check that generateMipmap for an POT texture succeeds
4415 glGenerateMipmap(GL_TEXTURE_2D);
4416 EXPECT_GL_NO_ERROR();
4417
4418 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
4419 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4420 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4421 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
4422 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
4423 glClear(GL_COLOR_BUFFER_BIT);
4424 drawQuad(mProgram, "position", 1.0f);
4425 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
4426 EXPECT_GL_NO_ERROR();
4427 }
4428
4429 // Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
4430 // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
TEST_P(Texture2DTest,NPOTSubImageParameters)4431 TEST_P(Texture2DTest, NPOTSubImageParameters)
4432 {
4433 glActiveTexture(GL_TEXTURE0);
4434 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4435
4436 // Create an 8x8 (i.e. power-of-two) texture.
4437 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4438 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4439 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4440 glGenerateMipmap(GL_TEXTURE_2D);
4441
4442 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
4443 // This should always work, even if GL_OES_texture_npot isn't active.
4444 std::array<GLColor, 3 * 3> data;
4445 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
4446
4447 EXPECT_GL_NO_ERROR();
4448 }
4449
4450 // Regression test for https://crbug.com/1222516 to prevent integer overflow during validation.
TEST_P(Texture2DTest,SubImageValidationOverflow)4451 TEST_P(Texture2DTest, SubImageValidationOverflow)
4452 {
4453 glActiveTexture(GL_TEXTURE0);
4454 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4455
4456 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4457 EXPECT_GL_NO_ERROR();
4458
4459 glTexSubImage2D(GL_TEXTURE_2D, 0, -4, 0, 2147483647, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4460 EXPECT_GL_ERROR(GL_INVALID_VALUE);
4461
4462 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, -4, 1, 2147483647, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4463 EXPECT_GL_ERROR(GL_INVALID_VALUE);
4464 }
4465
4466 // Test that when a mutable texture is deleted, its corresponding pointer in the Vulkan backend,
4467 // which is used for mutable texture flushing, is also deleted, and is not accessed by the new
4468 // mutable texture after it.
TEST_P(Texture2DTest,MutableUploadThenDeleteThenMutableUpload)4469 TEST_P(Texture2DTest, MutableUploadThenDeleteThenMutableUpload)
4470 {
4471 GLTexture texture1;
4472 glBindTexture(GL_TEXTURE_2D, texture1);
4473 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4474 GLColor::red.data());
4475 texture1.reset();
4476 EXPECT_GL_NO_ERROR();
4477
4478 GLTexture texture2;
4479 glBindTexture(GL_TEXTURE_2D, texture2);
4480 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4481 GLColor::green.data());
4482 texture2.reset();
4483 EXPECT_GL_NO_ERROR();
4484 }
4485
4486 // Test to ensure that glTexStorage3D accepts ASTC sliced 3D. https://crbug.com/1060012
TEST_P(Texture3DTestES3,ImmutableASTCSliced3D)4487 TEST_P(Texture3DTestES3, ImmutableASTCSliced3D)
4488 {
4489 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_texture_compression_astc_sliced_3d"));
4490
4491 glBindTexture(GL_TEXTURE_3D, mTexture3D);
4492 glTexStorage3D(GL_TEXTURE_3D, 1, GL_COMPRESSED_RGBA_ASTC_4x4, 4, 4, 1);
4493 EXPECT_GL_NO_ERROR();
4494 }
4495
FillLevel(GLint level,GLuint width,GLuint height,const GLColor & color,bool cubemap,bool subTex)4496 void FillLevel(GLint level,
4497 GLuint width,
4498 GLuint height,
4499 const GLColor &color,
4500 bool cubemap,
4501 bool subTex)
4502 {
4503 std::vector<GLColor> pixels(width * height, color);
4504 std::vector<GLenum> targets;
4505 if (cubemap)
4506 {
4507 targets = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
4508 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
4509 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
4510 }
4511 else
4512 {
4513 targets = {GL_TEXTURE_2D};
4514 }
4515
4516 for (GLenum target : targets)
4517 {
4518 if (subTex)
4519 {
4520 glTexSubImage2D(target, level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
4521 pixels.data());
4522 }
4523 else
4524 {
4525 glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4526 pixels.data());
4527 }
4528 }
4529 }
4530
4531 // This is part of tests that webgl_conformance_vulkan_passthrough_tests
4532 // conformance/textures/misc/texture-size.html does
testTextureSize(int testCaseIndex)4533 void Texture2DTest::testTextureSize(int testCaseIndex)
4534 {
4535 std::array<GLColor, 6> kNewMipColors = {
4536 GLColor::green, GLColor::red, GLColor::blue,
4537 GLColor::yellow, GLColor::magenta, GLColor::cyan,
4538 };
4539 GLuint colorCount = 0;
4540
4541 setUpProgram();
4542
4543 constexpr char kVS[] =
4544 R"(precision highp float;
4545 attribute vec4 position;
4546 varying vec3 texcoord;
4547 void main()
4548 {
4549 gl_Position = position;
4550 texcoord = (position.xyz * 0.5) + 0.5;
4551 }
4552 )";
4553 constexpr char kFS[] =
4554 R"(precision mediump float;
4555 uniform samplerCube tex;
4556 varying vec3 texcoord;
4557 void main()
4558 {
4559 gl_FragColor = textureCube(tex, texcoord);
4560 })";
4561 ANGLE_GL_PROGRAM(programCubeMap, kVS, kFS);
4562 GLint textureCubeUniformLocation = glGetUniformLocation(programCubeMap, "tex");
4563 ASSERT_NE(-1, textureCubeUniformLocation);
4564 ASSERT_GL_NO_ERROR();
4565
4566 GLint max2DSize = 0;
4567 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
4568 GLint maxCubeMapSize = 0;
4569 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapSize);
4570 // Assuming 2048x2048xRGBA (22 mb with mips) will run on all WebGL platforms
4571 GLint max2DSquareSize = std::min(max2DSize, 2048);
4572 // I'd prefer this to be 2048 but that's 16 mb x 6 faces or 128 mb (with mips)
4573 // 1024 is 33.5 mb (with mips)
4574 maxCubeMapSize = std::min(maxCubeMapSize, 1024);
4575 ASSERT_GL_NO_ERROR();
4576
4577 for (GLint size = 1; size <= max2DSize; size *= 2)
4578 {
4579 bool cubeMap = testCaseIndex == 3;
4580 GLenum texTarget = cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
4581 GLuint program = cubeMap ? programCubeMap : mProgram;
4582 GLint texWidth = 0, texHeight = 0;
4583
4584 switch (testCaseIndex)
4585 {
4586 case 0:
4587 texWidth = size;
4588 texHeight = 1;
4589 break;
4590 case 1:
4591 texWidth = 1;
4592 texHeight = size;
4593 break;
4594 case 2:
4595 case 3:
4596 texWidth = size;
4597 texHeight = size;
4598 break;
4599 }
4600
4601 if (texWidth == texHeight && size > max2DSquareSize)
4602 {
4603 return;
4604 }
4605
4606 if (cubeMap && size > maxCubeMapSize)
4607 {
4608 return;
4609 }
4610
4611 GLTexture texture;
4612 glActiveTexture(GL_TEXTURE0);
4613 glBindTexture(texTarget, texture);
4614 FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
4615 glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4616 glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4617 glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4618 glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4619 ASSERT_GL_NO_ERROR();
4620
4621 glClear(GL_COLOR_BUFFER_BIT);
4622 ASSERT_GL_NO_ERROR();
4623
4624 glUseProgram(program);
4625 if (cubeMap)
4626 {
4627 glUniform1i(textureCubeUniformLocation, 0);
4628 }
4629 else
4630 {
4631 glUniform1i(mTexture2DUniformLocation, 0);
4632 }
4633
4634 drawQuad(program, "position", 1.0f);
4635 ASSERT_GL_NO_ERROR();
4636 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
4637
4638 colorCount = (colorCount + 1) % kNewMipColors.size();
4639 FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
4640 glGenerateMipmap(texTarget);
4641 ASSERT_GL_NO_ERROR();
4642
4643 glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4644 glClear(GL_COLOR_BUFFER_BIT);
4645 drawQuad(program, "position", 1.0f);
4646 ASSERT_GL_NO_ERROR();
4647 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
4648
4649 colorCount = (colorCount + 1) % kNewMipColors.size();
4650 FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, true);
4651 glGenerateMipmap(texTarget);
4652
4653 glClear(GL_COLOR_BUFFER_BIT);
4654 drawQuad(program, "position", 1.0f);
4655 ASSERT_GL_NO_ERROR();
4656 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
4657 }
4658 }
4659
testTextureSizeError()4660 void Texture2DTest::testTextureSizeError()
4661 {
4662 GLint max2DSize = 0;
4663 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
4664 glActiveTexture(GL_TEXTURE0);
4665 GLTexture texture;
4666 glBindTexture(GL_TEXTURE_2D, texture);
4667 FillLevel(0, max2DSize, max2DSize, GLColor::red, false, false);
4668 GLenum err = glGetError();
4669 bool passed = (err == GL_NO_ERROR || err == GL_OUT_OF_MEMORY);
4670 ASSERT_TRUE(passed);
4671 }
4672
4673 // Permutation 0 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase0)4674 TEST_P(Texture2DTest, TextureSizeCase0)
4675 {
4676 testTextureSize(0);
4677 }
4678
4679 // Permutation 1 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase1)4680 TEST_P(Texture2DTest, TextureSizeCase1)
4681 {
4682 testTextureSize(1);
4683 }
4684
4685 // Permutation 2 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase2)4686 TEST_P(Texture2DTest, TextureSizeCase2)
4687 {
4688 testTextureSize(2);
4689 }
4690
4691 // Permutation 3 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase3)4692 TEST_P(Texture2DTest, TextureSizeCase3)
4693 {
4694 testTextureSize(3);
4695 }
4696
4697 // Test allocating a very large texture
TEST_P(Texture2DTest,TextureMaxSize)4698 TEST_P(Texture2DTest, TextureMaxSize)
4699 {
4700 testTextureSizeError();
4701 }
4702
4703 // Test that drawing works correctly RGBA 3D texture
TEST_P(Texture3DTestES2,RGBA)4704 TEST_P(Texture3DTestES2, RGBA)
4705 {
4706 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4707
4708 // http://anglebug.com/42264265
4709 ANGLE_SKIP_TEST_IF(IsOzone());
4710
4711 glActiveTexture(GL_TEXTURE0);
4712 glBindTexture(GL_TEXTURE_3D, mTexture3D);
4713 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
4714 std::vector<GLColor> texDataRed(1u * 1u * 1u, GLColor::red);
4715 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4716 texDataGreen.data());
4717 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4718 texDataRed.data());
4719 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4720 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4721
4722 EXPECT_GL_NO_ERROR();
4723
4724 drawQuad(mProgram, "position", 0.5f);
4725
4726 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4727 }
4728
4729 // Test that drawing works correctly Luminance 3D texture
TEST_P(Texture3DTestES2,Luminance)4730 TEST_P(Texture3DTestES2, Luminance)
4731 {
4732 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4733
4734 // http://anglebug.com/42264265
4735 ANGLE_SKIP_TEST_IF(IsOzone());
4736
4737 glActiveTexture(GL_TEXTURE0);
4738 glBindTexture(GL_TEXTURE_3D, mTexture3D);
4739 std::vector<GLubyte> texData(2u * 2u * 2u, 125);
4740 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4741 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4742 texData.data());
4743 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4744 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4745
4746 EXPECT_GL_NO_ERROR();
4747
4748 drawQuad(mProgram, "position", 0.5f);
4749
4750 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(125, 125, 125, 255));
4751 }
4752
4753 // Test that drawing works correctly with glCopyTexSubImage3D
TEST_P(Texture3DTestES2,CopySubImageRGBA)4754 TEST_P(Texture3DTestES2, CopySubImageRGBA)
4755 {
4756 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4757
4758 // http://anglebug.com/42264265
4759 ANGLE_SKIP_TEST_IF(IsOzone());
4760
4761 glClearColor(0, 0, 1, 1);
4762 glClear(GL_COLOR_BUFFER_BIT);
4763
4764 glActiveTexture(GL_TEXTURE0);
4765 glBindTexture(GL_TEXTURE_3D, mTexture3D);
4766 std::vector<GLColor> texDataRed(4u * 4u * 4u, GLColor::red);
4767 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4768 texDataRed.data());
4769 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4770 texDataRed.data());
4771 glTexImage3DOES(GL_TEXTURE_3D, 2, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4772 texDataRed.data());
4773 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
4774 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
4775 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4776 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4777
4778 EXPECT_GL_NO_ERROR();
4779
4780 glClearColor(0, 1, 0, 1);
4781 glClear(GL_COLOR_BUFFER_BIT);
4782 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4783
4784 glUseProgram(mProgram);
4785 glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
4786 drawQuad(mProgram, "position", 0.5f);
4787
4788 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
4789 }
4790
TEST_P(Texture3DTestES2,CopySubImageLuminance)4791 TEST_P(Texture3DTestES2, CopySubImageLuminance)
4792 {
4793 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4794
4795 // http://anglebug.com/42264265
4796 ANGLE_SKIP_TEST_IF(IsOzone());
4797
4798 glClearColor(1, 0, 0, 1);
4799 glClear(GL_COLOR_BUFFER_BIT);
4800
4801 glActiveTexture(GL_TEXTURE0);
4802 glBindTexture(GL_TEXTURE_3D, mTexture3D);
4803 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 4, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4804 nullptr);
4805 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4806 nullptr);
4807 glTexImage3DOES(GL_TEXTURE_3D, 2, GL_LUMINANCE, 1, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4808 nullptr);
4809 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
4810 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
4811 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4812 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4813
4814 EXPECT_GL_NO_ERROR();
4815
4816 glClearColor(0, 1, 0, 1);
4817 glClear(GL_COLOR_BUFFER_BIT);
4818 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4819
4820 glUseProgram(mProgram);
4821 glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
4822 drawQuad(mProgram, "position", 0.5f);
4823
4824 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
4825 }
4826
TEST_P(Texture3DTestES2,CopySubImageAlpha)4827 TEST_P(Texture3DTestES2, CopySubImageAlpha)
4828 {
4829 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4830
4831 // http://anglebug.com/42264265
4832 ANGLE_SKIP_TEST_IF(IsOzone());
4833
4834 glClearColor(1, 0, 0, 0.5);
4835 glClear(GL_COLOR_BUFFER_BIT);
4836
4837 glActiveTexture(GL_TEXTURE0);
4838 glBindTexture(GL_TEXTURE_3D, mTexture3D);
4839 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_ALPHA, 4, 4, 4, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
4840 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_ALPHA, 2, 2, 2, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
4841 glTexImage3DOES(GL_TEXTURE_3D, 2, GL_ALPHA, 1, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
4842 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
4843 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
4844 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4845 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
4846
4847 EXPECT_GL_NO_ERROR();
4848
4849 glClearColor(0, 1, 0, 1);
4850 glClear(GL_COLOR_BUFFER_BIT);
4851 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4852
4853 glUseProgram(mProgram);
4854 glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
4855 drawQuad(mProgram, "position", 0.5f);
4856
4857 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 128), 1.0);
4858 }
4859
4860 // Test that defining a 2D texture array fails with Texture3DOES on ES2.
TEST_P(Texture3DTestES2,DefineTexture2DArrayShouldFail)4861 TEST_P(Texture3DTestES2, DefineTexture2DArrayShouldFail)
4862 {
4863 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
4864
4865 // http://anglebug.com/42264265
4866 ANGLE_SKIP_TEST_IF(IsOzone());
4867
4868 glClearColor(1, 0, 0, 1);
4869 glClear(GL_COLOR_BUFFER_BIT);
4870
4871 glActiveTexture(GL_TEXTURE0);
4872 glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
4873 EXPECT_GL_ERROR(GL_INVALID_ENUM);
4874
4875 glTexImage3DOES(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4876 nullptr);
4877 glTexImage3DOES(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4878 nullptr);
4879 glTexImage3DOES(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA, 1, 1, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4880 nullptr);
4881 EXPECT_GL_ERROR(GL_INVALID_ENUM);
4882 }
4883
4884 // Verify shrinking a texture with glTexStorage2D works correctly
TEST_P(Texture2DTestES3,ChangeTexSizeWithTexStorage)4885 TEST_P(Texture2DTestES3, ChangeTexSizeWithTexStorage)
4886 {
4887 // TODO: http://anglebug.com/42263810
4888 ANGLE_SKIP_TEST_IF(IsWindows() && IsOpenGL());
4889
4890 constexpr uint32_t kSizeLarge = 128;
4891 constexpr uint32_t kSizeSmall = 64;
4892
4893 glActiveTexture(GL_TEXTURE0);
4894 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4895 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4896 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4897
4898 // Create the texture with 'large' dimensions
4899 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSizeLarge, kSizeLarge, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4900 nullptr);
4901 ASSERT_GL_NO_ERROR();
4902
4903 GLFramebuffer destFbo;
4904 glBindFramebuffer(GL_FRAMEBUFFER, destFbo);
4905 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
4906 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4907
4908 // Draw with the new texture so it's created in the back end
4909 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
4910 glUseProgram(blueProgram);
4911 drawQuad(blueProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
4912 ASSERT_GL_NO_ERROR();
4913 EXPECT_PIXEL_RECT_EQ(0, 0, kSizeLarge, kSizeLarge, GLColor::blue);
4914
4915 // Shrink the texture
4916 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
4917 ASSERT_GL_NO_ERROR();
4918
4919 // Create a source texture/FBO to blit from
4920 GLTexture sourceTex;
4921 glBindTexture(GL_TEXTURE_2D, sourceTex);
4922 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
4923 ASSERT_GL_NO_ERROR();
4924 GLFramebuffer sourceFbo;
4925 glBindFramebuffer(GL_FRAMEBUFFER, sourceFbo);
4926 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTex, 0);
4927 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4928 // Fill the source texture with green
4929 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
4930 glUseProgram(greenProgram);
4931 drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
4932 ASSERT_GL_NO_ERROR();
4933 EXPECT_PIXEL_RECT_EQ(0, 0, kSizeSmall, kSizeSmall, GLColor::green);
4934
4935 // Blit the source (green) to the destination
4936 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFbo);
4937 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFbo);
4938 glBlitFramebuffer(0, 0, kSizeSmall, kSizeSmall, 0, 0, kSizeSmall, kSizeSmall,
4939 GL_COLOR_BUFFER_BIT, GL_NEAREST);
4940 ASSERT_GL_NO_ERROR();
4941
4942 // Render to the default framebuffer sampling from the blited texture and verify it's green
4943 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4944 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4945 ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4946 glUseProgram(texProgram);
4947 drawQuad(texProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
4948 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
4949 }
4950
4951 // Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
4952 // TextureImpl and the texture is synced before being used in a draw call.
TEST_P(Texture2DTestES3,TextureImplPropogatesDirtyBits)4953 TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
4954 {
4955 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4956 // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/42262039
4957 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
4958 // D3D Debug device reports an error. http://anglebug.com/40096590
4959 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
4960 // Support copy from levels outside the image range. http://anglebug.com/42263331
4961 ANGLE_SKIP_TEST_IF(IsVulkan());
4962
4963 // The workaround in the GL backend required to trigger this bug generates driver warning
4964 // messages.
4965 ScopedIgnorePlatformMessages ignoreMessages;
4966
4967 setUpProgram();
4968 glUseProgram(mProgram);
4969 glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
4970
4971 GLTexture dest;
4972 glBindTexture(GL_TEXTURE_2D, dest);
4973
4974 GLTexture source;
4975 glBindTexture(GL_TEXTURE_2D, source);
4976
4977 // Put data in mip 0 and 1
4978 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4979 GLColor::red.data());
4980 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4981 GLColor::green.data());
4982
4983 // Disable mipmapping so source is complete
4984 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4985 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4986
4987 // Force the dirty bits to be synchronized in source
4988 drawQuad(mProgram, "position", 1.0f);
4989
4990 // Copy from mip 1 of the source. In the GL backend this internally sets the base level to mip
4991 // 1 and sets a dirty bit.
4992 glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
4993 GL_FALSE, GL_FALSE);
4994
4995 // Draw again, assertions are generated if the texture has internal dirty bits at draw time
4996 drawQuad(mProgram, "position", 1.0f);
4997 }
4998
4999 // This test case changes the base level of a texture that's attached to a framebuffer, clears every
5000 // level to green, and then samples the texture when rendering. Test is taken from
5001 // https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
TEST_P(Texture2DTestES3,FramebufferTextureChangingBaselevel)5002 TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
5003 {
5004 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/42262633
5005 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
5006
5007 setUpProgram();
5008
5009 constexpr GLint width = 8;
5010 constexpr GLint height = 4;
5011
5012 GLTexture texture;
5013 glBindTexture(GL_TEXTURE_2D, texture);
5014 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5015 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5016 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5017 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5018
5019 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
5020 GLint level = 0;
5021 GLint levelW = width;
5022 GLint levelH = height;
5023 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5024 nullptr);
5025 while (levelW > 1 || levelH > 1)
5026 {
5027 ++level;
5028 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
5029 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
5030 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5031 nullptr);
5032 }
5033
5034 // Clear each level of the texture using an FBO. Change the base level to match the level used
5035 // for the FBO on each iteration.
5036 GLFramebuffer fbo;
5037 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5038 level = 0;
5039 levelW = width;
5040 levelH = height;
5041 while (levelW > 1 || levelH > 1)
5042 {
5043 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
5044 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
5045
5046 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
5047 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
5048
5049 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5050 EXPECT_GL_NO_ERROR();
5051
5052 glClearColor(0, 1, 0, 1);
5053 glClear(GL_COLOR_BUFFER_BIT);
5054
5055 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5056
5057 ++level;
5058 }
5059
5060 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5061 glViewport(0, 0, 16, 16);
5062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5063
5064 drawQuad(mProgram, "position", 0.5f);
5065
5066 EXPECT_GL_NO_ERROR();
5067 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5068 }
5069
5070 // Test that changing the base level of a texture after redefining a level outside the mip-chain
5071 // preserves the other mips' data.
TEST_P(Texture2DBaseMaxTestES3,ExtendMipChainAfterRedefine)5072 TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
5073 {
5074 // http://anglebug.com/42263298
5075 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
5076
5077 // http://anglebug.com/42263714
5078 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && IsMac());
5079
5080 GLFramebuffer framebuffer;
5081 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
5082
5083 GLTexture texture;
5084 glBindTexture(GL_TEXTURE_2D, texture);
5085
5086 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
5087 fillMipData(mipData.data(), kMip0Size, kMipColors);
5088
5089 for (size_t mip = 1; mip < kMipCount; ++mip)
5090 {
5091 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
5092 GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
5093 }
5094
5095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5096 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
5097 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5098
5099 // Mip 1 is green. Verify this.
5100 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
5101
5102 // http://anglebug.com/42263308
5103 ANGLE_SKIP_TEST_IF(IsOpenGL() && (IsIntel() || IsAMD()) && IsWindows());
5104
5105 // Add mip 0 and rebase the mip chain.
5106 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5107 mipData.data() + getMipDataOffset(kMip0Size, 0));
5108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5109
5110 // Mip 1 should still be green.
5111 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
5112
5113 // Verify the other mips too.
5114 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
5115 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5116 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[2]);
5117
5118 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
5119 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5120 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[3]);
5121
5122 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
5123 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5124
5125 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
5126 }
5127
5128 // Test that changing the base level of a texture multiple times preserves the data.
TEST_P(Texture2DBaseMaxTestES3,PingPongBaseLevel)5129 TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevel)
5130 {
5131 testPingPongBaseLevel(false);
5132 }
TEST_P(Texture2DBaseMaxTestES3,PingPongBaseLevelImmutable)5133 TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevelImmutable)
5134 {
5135 testPingPongBaseLevel(true);
5136 }
testPingPongBaseLevel(bool immutable)5137 void Texture2DBaseMaxTestES3::testPingPongBaseLevel(bool immutable)
5138 {
5139 // http://anglebug.com/42263310
5140 ANGLE_SKIP_TEST_IF(IsD3D());
5141
5142 // http://anglebug.com/42263311
5143 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsAMD() && IsWindows());
5144
5145 // http://anglebug.com/42263301
5146 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
5147
5148 initTest(immutable);
5149
5150 // Ping pong a few times.
5151 for (uint32_t tries = 0; tries < 2; ++tries)
5152 {
5153 // Rebase to different mips and verify mips.
5154 for (uint32_t base = 0; base < kMipCount; ++base)
5155 {
5156 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
5157 for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
5158 {
5159 setLodUniform(lod);
5160 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5161 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
5162 }
5163 }
5164
5165 // Rebase backwards and verify mips.
5166 for (uint32_t base = kMipCount - 2; base > 0; --base)
5167 {
5168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
5169 for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
5170 {
5171 setLodUniform(lod);
5172 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5173 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
5174 }
5175 }
5176 }
5177 }
5178
5179 // Test that glTexSubImage2D after incompatibly redefining a mip level correctly applies the update
5180 // after the redefine data.
TEST_P(Texture2DBaseMaxTestES3,SubImageAfterRedefine)5181 TEST_P(Texture2DBaseMaxTestES3, SubImageAfterRedefine)
5182 {
5183 initTest(false);
5184
5185 // Test that all mips have the expected data initially (this makes sure the texture image is
5186 // created already).
5187 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5188 {
5189 setLodUniform(lod);
5190 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5191 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5192 }
5193
5194 // Redefine every level, followed by a glTexSubImage2D
5195 const GLColor kNewMipColors[kMipCount] = {
5196 GLColor::yellow,
5197 GLColor::cyan,
5198 GLColor(127, 0, 0, 255),
5199 GLColor(0, 127, 0, 255),
5200 };
5201 std::array<GLColor, getTotalMipDataSize(kMip0Size * 2)> newMipData;
5202 fillMipData(newMipData.data(), kMip0Size * 2, kNewMipColors);
5203
5204 const GLColor kSubImageMipColors[kMipCount] = {
5205 GLColor(0, 0, 127, 255),
5206 GLColor(127, 127, 0, 255),
5207 GLColor(0, 127, 127, 255),
5208 GLColor(127, 0, 127, 255),
5209 };
5210 std::array<GLColor, getTotalMipDataSize(kMip0Size)> subImageMipData;
5211 fillMipData(subImageMipData.data(), kMip0Size, kSubImageMipColors);
5212
5213 for (size_t mip = 0; mip < kMipCount; ++mip)
5214 {
5215 // Redefine the level.
5216 size_t newMipSize = (kMip0Size * 2) >> mip;
5217 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, newMipSize, newMipSize, 0, GL_RGBA,
5218 GL_UNSIGNED_BYTE, newMipData.data() + getMipDataOffset(kMip0Size * 2, mip));
5219
5220 // Immediately follow that with a subimage update.
5221 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
5222 GL_UNSIGNED_BYTE,
5223 subImageMipData.data() + getMipDataOffset(kMip0Size, mip));
5224 }
5225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
5226
5227 // Test that the texture looks as expected.
5228 const int w = getWindowWidth() - 1;
5229 const int h = getWindowHeight() - 1;
5230 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5231 {
5232 setLodUniform(lod);
5233 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5234 EXPECT_PIXEL_COLOR_EQ(0, 0, kSubImageMipColors[lod]);
5235 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColors[lod]);
5236 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColors[lod]);
5237 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColors[lod]);
5238 }
5239 }
5240
5241 // Test that incompatibly redefining a level then redefining it back to its original size works.
TEST_P(Texture2DBaseMaxTestES3,IncompatiblyRedefineLevelThenRevert)5242 TEST_P(Texture2DBaseMaxTestES3, IncompatiblyRedefineLevelThenRevert)
5243 {
5244 initTest(false);
5245
5246 // Test that all mips have the expected data initially (this makes sure the texture image is
5247 // created already).
5248 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5249 {
5250 setLodUniform(lod);
5251 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5252 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5253 }
5254
5255 // Redefine Mip 1 to be larger.
5256 constexpr size_t kLargeMip1Size = getMipDataSize(kMip0Size * 2, 1);
5257 std::array<GLColor, kLargeMip1Size> interimMipData;
5258 std::fill(interimMipData.data(), interimMipData.data() + kLargeMip1Size, GLColor::yellow);
5259
5260 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5261 interimMipData.data());
5262
5263 // Redefine Mip 1 back to its original size.
5264 constexpr size_t kNormalMip1Size = getMipDataSize(kMip0Size, 1);
5265 std::array<GLColor, kLargeMip1Size> newMipData;
5266 std::fill(newMipData.data(), newMipData.data() + kNormalMip1Size, GLColor::cyan);
5267
5268 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size / 2, kMip0Size / 2, 0, GL_RGBA,
5269 GL_UNSIGNED_BYTE, newMipData.data());
5270
5271 // Verify texture colors.
5272 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5273 {
5274 setLodUniform(lod);
5275 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5276 EXPECT_PIXEL_COLOR_EQ(0, 0, lod == 1 ? GLColor::cyan : kMipColors[lod]);
5277 }
5278 }
5279
5280 // Test that redefining every level of a texture to another format works. The format uses more
5281 // bits per component, to ensure alignment requirements for the new format are taken into account.
TEST_P(Texture2DBaseMaxTestES3,RedefineEveryLevelToAnotherFormat)5282 TEST_P(Texture2DBaseMaxTestES3, RedefineEveryLevelToAnotherFormat)
5283 {
5284 initTest(false);
5285
5286 // Test that all mips have the expected data initially (this makes sure the texture image is
5287 // created already).
5288 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5289 {
5290 setLodUniform(lod);
5291 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5292 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5293 }
5294
5295 const GLColor32F kNewMipColors[kMipCount] = {
5296 GLColor32F(1.0, 1.0, 0.0, 1.0f),
5297 GLColor32F(1.0, 0.0, 1.0, 1.0f),
5298 GLColor32F(0.0, 1.0, 1.0, 1.0f),
5299 GLColor32F(1.0, 1.0, 1.0, 1.0f),
5300 };
5301
5302 std::array<GLColor32F, getTotalMipDataSize(kMip0Size)> newMipData;
5303 fillMipData(newMipData.data(), kMip0Size, kNewMipColors);
5304
5305 // Redefine every level with the new format.
5306 for (size_t mip = 0; mip < kMipCount; ++mip)
5307 {
5308 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA32F, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
5309 GL_FLOAT, newMipData.data() + getMipDataOffset(kMip0Size, mip));
5310 }
5311
5312 // Verify texture colors.
5313 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5314 {
5315 setLodUniform(lod);
5316 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5317
5318 GLColor32F mipColor32F = kNewMipColors[lod];
5319 GLColor mipColor(static_cast<GLubyte>(std::roundf(mipColor32F.R * 255)),
5320 static_cast<GLubyte>(std::roundf(mipColor32F.G * 255)),
5321 static_cast<GLubyte>(std::roundf(mipColor32F.B * 255)),
5322 static_cast<GLubyte>(std::roundf(mipColor32F.A * 255)));
5323
5324 EXPECT_PIXEL_COLOR_EQ(0, 0, mipColor);
5325 }
5326 }
5327
5328 // Test that generating mipmaps after change base level.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRebase)5329 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRebase)
5330 {
5331 // http://anglebug.com/42264421
5332 ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
5333
5334 testGenerateMipmapAfterRebase(false);
5335 }
5336
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRebaseImmutable)5337 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRebaseImmutable)
5338 {
5339 // http://anglebug.com/42263310
5340 ANGLE_SKIP_TEST_IF(IsD3D());
5341 // http://anglebug.com/42264332
5342 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA());
5343 // http://anglebug.com/42264421
5344 ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
5345
5346 testGenerateMipmapAfterRebase(true);
5347 }
5348
testGenerateMipmapAfterRebase(bool immutable)5349 void Texture2DBaseMaxTestES3::testGenerateMipmapAfterRebase(bool immutable)
5350 {
5351 initTest(immutable);
5352
5353 // Test that all mips have the expected data initially (this makes sure the texture image is
5354 // created already).
5355 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5356 {
5357 setLodUniform(lod);
5358 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5359 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5360 }
5361
5362 // Update level 1 (any level would do other than 0) with new data
5363 const GLColor kNewMipColor = GLColor::yellow;
5364 std::array<GLColor, getMipDataSize(kMip0Size >> 1, 0)> newMipData;
5365 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5366
5367 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kMip0Size >> 1, kMip0Size >> 1, GL_RGBA,
5368 GL_UNSIGNED_BYTE, newMipData.data());
5369
5370 // Change base level and max level and then generate mipmaps. This should redefine level 1 and 2
5371 // with kNewMipColor and leave levels 0 and 3 unchanged.
5372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 2);
5374 glGenerateMipmap(GL_TEXTURE_2D);
5375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
5377
5378 // Test that the texture looks as expected.
5379 const int w = getWindowWidth() - 1;
5380 const int h = getWindowHeight() - 1;
5381 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5382 {
5383 setLodUniform(lod);
5384 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5385 if (lod == 0)
5386 {
5387 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]) << "lod " << lod;
5388 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]) << "lod " << lod;
5389 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]) << "lod " << lod;
5390 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]) << "lod " << lod;
5391 }
5392 else if (lod == kMipCount - 1)
5393 {
5394 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]) << "lod " << lod;
5395 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]) << "lod " << lod;
5396 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]) << "lod " << lod;
5397 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]) << "lod " << lod;
5398 }
5399 else
5400 {
5401 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor) << "lod " << lod;
5402 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor) << "lod " << lod;
5403 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor) << "lod " << lod;
5404 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor) << "lod " << lod;
5405 }
5406 }
5407 }
5408
5409 // Test that generating mipmaps after incompatibly redefining a level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefine)5410 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefine)
5411 {
5412 initTest(false);
5413
5414 // Test that all mips have the expected data initially (this makes sure the texture image is
5415 // created already).
5416 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5417 {
5418 setLodUniform(lod);
5419 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5420 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5421 }
5422
5423 // Redefine level 1 (any level would do other than 0) to an incompatible size, say the same size
5424 // as level 0.
5425 const GLColor kNewMipColor = GLColor::yellow;
5426 std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
5427 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5428
5429 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5430 newMipData.data());
5431
5432 // Generate mipmaps. This should redefine level 1 back to being compatible with level 0.
5433 glGenerateMipmap(GL_TEXTURE_2D);
5434
5435 // Test that the texture looks as expected.
5436 const int w = getWindowWidth() - 1;
5437 const int h = getWindowHeight() - 1;
5438 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5439 {
5440 setLodUniform(lod);
5441 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5442 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
5443 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]);
5444 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]);
5445 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]);
5446 }
5447 }
5448
5449 // Test that generating mipmaps after incompatibly redefining a level while simultaneously changing
5450 // the base level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefineAndRebase)5451 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefineAndRebase)
5452 {
5453 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
5454
5455 // http://crbug.com/1100613
5456 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
5457
5458 // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
5459 ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && IsDesktopOpenGL());
5460
5461 initTest(false);
5462
5463 // Test that all mips have the expected data initially (this makes sure the texture image is
5464 // created already).
5465 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5466 {
5467 setLodUniform(lod);
5468 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5469 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]) << lod;
5470 }
5471
5472 // Redefine level 2 to an incompatible size, say the same size as level 0.
5473 const GLColor kNewMipColor = GLColor::yellow;
5474 std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
5475 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5476
5477 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5478 newMipData.data());
5479
5480 // Set base level of the texture to 1 then generate mipmaps. Level 2 that's redefined should
5481 // go back to being compatibly defined.
5482 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5483 glGenerateMipmap(GL_TEXTURE_2D);
5484
5485 // Test that the texture looks as expected.
5486 const int w = getWindowWidth() - 1;
5487 const int h = getWindowHeight() - 1;
5488 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5489 {
5490 setLodUniform(lod);
5491 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5492 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]) << lod;
5493 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[1]) << lod;
5494 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[1]) << lod;
5495 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[1]) << lod;
5496 }
5497
5498 // Redefine level 1 (current base level) to an incompatible size.
5499 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5500 newMipData.data());
5501
5502 // Set base level of the texture back to 0 then generate mipmaps. Level 1 should go back to
5503 // being compatibly defined.
5504 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5505 glGenerateMipmap(GL_TEXTURE_2D);
5506
5507 // Test that the texture looks as expected.
5508 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5509 {
5510 setLodUniform(lod);
5511 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5512 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]) << lod;
5513 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]) << lod;
5514 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]) << lod;
5515 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]) << lod;
5516 }
5517 }
5518
5519 // Test that generating mipmaps after incompatibly redefining the base level of the texture works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBase)5520 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBase)
5521 {
5522 initTest(false);
5523
5524 // Test that all mips have the expected data initially (this makes sure the texture image is
5525 // created already).
5526 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5527 {
5528 setLodUniform(lod);
5529 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5530 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5531 }
5532
5533 // Redefine level 0 to an incompatible size.
5534 const GLColor kNewMipColor = GLColor::yellow;
5535 std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
5536 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5537
5538 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
5539 GL_UNSIGNED_BYTE, newMipData.data());
5540
5541 // Generate mipmaps.
5542 glGenerateMipmap(GL_TEXTURE_2D);
5543
5544 // Test that the texture looks as expected.
5545 const int w = getWindowWidth() - 1;
5546 const int h = getWindowHeight() - 1;
5547 for (uint32_t lod = 0; lod < kMipCount + 1; ++lod)
5548 {
5549 setLodUniform(lod);
5550 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5551 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
5552 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
5553 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
5554 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
5555 }
5556 }
5557
5558 // Test that generating mipmaps after incompatibly redefining the base level while simultaneously
5559 // changing MAX_LEVEL works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBaseAndChangingMax)5560 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBaseAndChangingMax)
5561 {
5562 initTest(false);
5563
5564 // Test that all mips have the expected data initially (this makes sure the texture image is
5565 // created already).
5566 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5567 {
5568 setLodUniform(lod);
5569 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5570 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5571 }
5572
5573 // Redefine level 0 to an incompatible size.
5574 const GLColor kNewMipColor = GLColor::yellow;
5575 std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
5576 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
5577
5578 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
5579 GL_UNSIGNED_BYTE, newMipData.data());
5580
5581 // Set max level of the texture to 2 then generate mipmaps.
5582 constexpr uint32_t kMaxLevel = 2;
5583 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMaxLevel);
5584 glGenerateMipmap(GL_TEXTURE_2D);
5585
5586 // Test that the texture looks as expected.
5587 const int w = getWindowWidth() - 1;
5588 const int h = getWindowHeight() - 1;
5589 for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
5590 {
5591 setLodUniform(lod);
5592 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5593 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
5594 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
5595 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
5596 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
5597 }
5598 }
5599
5600 // Test that stage invalid texture levels work.
TEST_P(Texture2DBaseMaxTestES3,StageInvalidLevels)5601 TEST_P(Texture2DBaseMaxTestES3, StageInvalidLevels)
5602 {
5603 constexpr uint32_t kMaxLevel = 2;
5604 const GLColor kMipColor[kMaxLevel + 1] = {GLColor::red, GLColor::green, GLColor::blue};
5605
5606 initTest(false);
5607
5608 GLTexture texture;
5609 glBindTexture(GL_TEXTURE_2D, texture);
5610
5611 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5612 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5613 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
5614 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataCyan.data());
5615 setLodUniform(0);
5616 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5617 EXPECT_GL_NO_ERROR();
5618
5619 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
5620 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5621 texDataGreen.data());
5622 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
5623 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5624 EXPECT_GL_NO_ERROR();
5625
5626 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
5627 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
5628 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5629 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5630
5631 // Test that the texture looks as expected.
5632 const int w = getWindowWidth() - 1;
5633 const int h = getWindowHeight() - 1;
5634 for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
5635 {
5636 setLodUniform(lod);
5637 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5638 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColor[lod]);
5639 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColor[lod]);
5640 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColor[lod]);
5641 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColor[lod]);
5642 }
5643 }
5644
5645 // Test redefine a mutable texture into an immutable texture.
TEST_P(Texture2DBaseMaxTestES3,RedefineMutableToImmutable)5646 TEST_P(Texture2DBaseMaxTestES3, RedefineMutableToImmutable)
5647 {
5648 // http://anglebug.com/42263310
5649 ANGLE_SKIP_TEST_IF(IsD3D());
5650
5651 // http://anglebug.com/42263301
5652 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
5653
5654 constexpr uint32_t kBaseLevel = 1;
5655 const GLColor kNewMipColors[kMipCount] = {
5656 GLColor::yellow,
5657 GLColor::cyan,
5658 GLColor::white,
5659 GLColor(127u, 127u, 127u, 255u),
5660 };
5661
5662 initTest(false);
5663
5664 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, kBaseLevel);
5665
5666 // Test that all mips have the expected data
5667 for (uint32_t lod = kBaseLevel; lod < kMipCount; ++lod)
5668 {
5669 setLodUniform(lod - kBaseLevel);
5670 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5671 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5672 }
5673
5674 glTexStorage2D(GL_TEXTURE_2D, kMipCount, GL_RGBA8, kMip0Size, kMip0Size);
5675 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
5676 fillMipData(mipData.data(), kMip0Size, kNewMipColors);
5677 for (size_t mip = 0; mip < kMipCount; ++mip)
5678 {
5679 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
5680 GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
5681 }
5682
5683 // Test that all enabled mips have the expected data
5684 for (uint32_t lod = kBaseLevel; lod < kMipCount; ++lod)
5685 {
5686 setLodUniform(lod - kBaseLevel);
5687 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5688 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[lod]);
5689 }
5690
5691 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5692 for (uint32_t lod = 0; lod < kBaseLevel; ++lod)
5693 {
5694 setLodUniform(lod);
5695 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5696 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[lod]);
5697 }
5698 }
5699
5700 // Test that redefine a level with incompatible size beyond the max level.
TEST_P(Texture2DBaseMaxTestES3,RedefineIncompatibleLevelBeyondMaxLevel)5701 TEST_P(Texture2DBaseMaxTestES3, RedefineIncompatibleLevelBeyondMaxLevel)
5702 {
5703 initTest(false);
5704
5705 // Test that all mips have the expected data initially (this makes sure the texture image is
5706 // created already).
5707 for (uint32_t lod = 0; lod < kMipCount; ++lod)
5708 {
5709 setLodUniform(lod);
5710 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5711 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5712 }
5713
5714 uint32_t maxLevel = 1;
5715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel);
5716
5717 // Update level 0
5718 const GLColor kNewMipLevle0Color = GLColor::yellow;
5719 std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
5720 std::fill(newMipData.begin(), newMipData.end(), kNewMipLevle0Color);
5721 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kMip0Size, kMip0Size, GL_RGBA, GL_UNSIGNED_BYTE,
5722 newMipData.data());
5723
5724 // Update level 2 with incompatible data
5725 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5726 newMipData.data());
5727 EXPECT_GL_NO_ERROR();
5728
5729 // Test that the texture looks as expected.
5730 const int w = getWindowWidth() - 1;
5731 const int h = getWindowHeight() - 1;
5732 for (uint32_t lod = 0; lod < maxLevel; ++lod)
5733 {
5734 setLodUniform(lod);
5735 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5736 if (lod == 0)
5737 {
5738 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipLevle0Color);
5739 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipLevle0Color);
5740 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipLevle0Color);
5741 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipLevle0Color);
5742 }
5743 else
5744 {
5745 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
5746 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]);
5747 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]);
5748 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]);
5749 }
5750 }
5751 }
5752
5753 // Port test from web_gl/conformance2/textures/misc/fuzz-545-immutable-tex-render-feedback.html.
5754 // What this tries to do is create a render feedback loop and ensure it is not crashing.
TEST_P(Texture2DBaseMaxTestES3,Fuzz545ImmutableTexRenderFeedback)5755 TEST_P(Texture2DBaseMaxTestES3, Fuzz545ImmutableTexRenderFeedback)
5756 {
5757 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5758
5759 constexpr uint32_t MIPS = 2;
5760 constexpr uint32_t SIZE = 10;
5761
5762 GLTexture immutTex;
5763 glBindTexture(GL_TEXTURE_2D, immutTex);
5764 glTexStorage2D(GL_TEXTURE_2D, MIPS, GL_RGBA8, SIZE, SIZE);
5765
5766 GLTexture mutTex;
5767 glBindTexture(GL_TEXTURE_2D, mutTex);
5768 for (uint32_t mip = 0; mip < MIPS; mip++)
5769 {
5770 const uint32_t size = SIZE >> mip;
5771 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5772 nullptr);
5773 }
5774
5775 constexpr GLenum MAG_FILTERS[] = {GL_LINEAR, GL_NEAREST};
5776 constexpr GLenum MIN_FILTERS[] = {
5777 GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST,
5778 GL_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_NEAREST};
5779
5780 GLFramebuffer fbo;
5781 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5782
5783 const GLuint texs[] = {immutTex, mutTex};
5784 for (const GLuint tex : texs)
5785 {
5786 glBindTexture(GL_TEXTURE_2D, tex);
5787
5788 for (GLuint level_prime_base = 0; level_prime_base < (MIPS + 1); level_prime_base++)
5789 { // `level_base` in GLES
5790 // ES 3.0.6 p150
5791 GLuint _level_base = level_prime_base;
5792 if (tex == immutTex)
5793 {
5794 _level_base = std::min(_level_base, MIPS - 1);
5795 }
5796 const GLuint level_base = _level_base;
5797
5798 for (GLuint _level_prime_max = (level_prime_base - 1); _level_prime_max < (MIPS + 2);
5799 _level_prime_max++)
5800 { // `q` in GLES
5801 if (_level_prime_max < 0)
5802 continue;
5803 if (_level_prime_max == (MIPS + 1))
5804 {
5805 _level_prime_max = 10000; // This is the default, after all!
5806 }
5807 const GLuint level_prime_max = _level_prime_max;
5808
5809 // ES 3.0.6 p150
5810 GLuint _level_max = level_prime_max;
5811 if (tex == immutTex)
5812 {
5813 _level_max = std::min(std::max(level_base, level_prime_max), MIPS - 1);
5814 }
5815 const GLuint level_max = _level_max;
5816
5817 const GLuint p = std::floor((float)std::log2(SIZE)) + level_base;
5818 const GLuint q = std::min(p, level_max);
5819
5820 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level_prime_base);
5821 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level_prime_max);
5822
5823 const bool mipComplete = (q <= MIPS - 1);
5824
5825 for (const GLenum minFilter : MIN_FILTERS)
5826 {
5827 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
5828
5829 for (const GLenum magFilter : MAG_FILTERS)
5830 {
5831 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
5832
5833 for (GLuint dstMip = 0; dstMip < (MIPS + 1); dstMip++)
5834 {
5835 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5836 GL_TEXTURE_2D, tex, dstMip);
5837
5838 // ES3.0 p213-214
5839 bool fbComplete = true;
5840
5841 // * "The width and height of `image` are non-zero"
5842 fbComplete &= (0 <= dstMip && dstMip <= MIPS - 1);
5843
5844 if (tex != immutTex)
5845 { // "...does not name an immutable-format texture..."
5846 // * "...the value of [level] must be in the range `[level_base,
5847 // q]`"
5848 fbComplete &= (level_base <= dstMip && dstMip <= q);
5849
5850 // * "...the value of [level] is not `level_base`, then the texture
5851 // must be mipmap complete"
5852 if (dstMip != level_base)
5853 {
5854 fbComplete &= mipComplete;
5855 }
5856 }
5857
5858 // -
5859 GLenum expectError = 0;
5860 GLenum expectStatus = GL_FRAMEBUFFER_COMPLETE;
5861 if (!fbComplete)
5862 {
5863 expectStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
5864 expectError = GL_INVALID_FRAMEBUFFER_OPERATION;
5865 }
5866
5867 // -
5868 EXPECT_GLENUM_EQ(expectStatus,
5869 glCheckFramebufferStatus(GL_FRAMEBUFFER));
5870
5871 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
5872 EXPECT_EQ(expectError, glGetError());
5873 }
5874 }
5875 }
5876 }
5877 }
5878 }
5879 }
5880
5881 // Test sampling from a texture of a (usually) not color-renderable
5882 // base format with a color-renderable level beyond the max level.
TEST_P(Texture2DBaseMaxTestES3,NotColorRenderableWithColorRenderableBeyondMaxLevel)5883 TEST_P(Texture2DBaseMaxTestES3, NotColorRenderableWithColorRenderableBeyondMaxLevel)
5884 {
5885 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5886
5887 GLTexture texture;
5888 glBindTexture(GL_TEXTURE_2D, texture);
5889 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5890 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5891
5892 const GLuint data[4] = {0xC0040200, 0xC0040200, 0xC0040200, 0xC0040200};
5893 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 2, 2, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, data);
5894 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5895 ASSERT_GL_NO_ERROR();
5896
5897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5898 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5899 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5900 }
5901
5902 // Test sampling from a texture of a depth-renderable base format
5903 // with a color-renderable level beyond the max level.
TEST_P(Texture2DBaseMaxTestES3,DepthRenderableWithColorRenderableBeyondMaxLevel)5904 TEST_P(Texture2DBaseMaxTestES3, DepthRenderableWithColorRenderableBeyondMaxLevel)
5905 {
5906 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5907
5908 GLTexture texture;
5909 glBindTexture(GL_TEXTURE_2D, texture);
5910 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5911 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5912
5913 const GLfloat data[4] = {1.0f, 1.0f, 1.0f, 1.0f};
5914 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 2, 2, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
5915 data);
5916 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5917 ASSERT_GL_NO_ERROR();
5918
5919 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5920 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5921 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5922 }
5923
5924 // Test texture sampling while changing the base format from color-renderable
5925 // to (usually) not color-renderable by manipulating base and max levels.
TEST_P(Texture2DBaseMaxTestES3,NotColorRenderableAfterColorRenderableBelowBaseLevel)5926 TEST_P(Texture2DBaseMaxTestES3, NotColorRenderableAfterColorRenderableBelowBaseLevel)
5927 {
5928 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5929
5930 GLTexture texture;
5931 glBindTexture(GL_TEXTURE_2D, texture);
5932 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5933 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5934
5935 std::array<GLColor, 4> data0;
5936 data0.fill(GLColor::green);
5937 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data0.data());
5938
5939 const GLuint data1[1] = {0xC0040200};
5940 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, data1);
5941 ASSERT_GL_NO_ERROR();
5942
5943 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5944 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5945 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5946
5947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5948 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
5949 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5950 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5951 }
5952
5953 // Test texture sampling while changing the base format from color-renderable
5954 // to depth-renderable by manipulating base and max levels.
TEST_P(Texture2DBaseMaxTestES3,DepthRenderableAfterColorRenderableBelowBaseLevel)5955 TEST_P(Texture2DBaseMaxTestES3, DepthRenderableAfterColorRenderableBelowBaseLevel)
5956 {
5957 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5958
5959 GLTexture texture;
5960 glBindTexture(GL_TEXTURE_2D, texture);
5961 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5962 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5963
5964 std::array<GLColor, 4> data0;
5965 data0.fill(GLColor::green);
5966 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data0.data());
5967
5968 const GLfloat data1[1] = {1.0f};
5969 glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
5970 data1);
5971 ASSERT_GL_NO_ERROR();
5972
5973 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5974 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5975 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5976
5977 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
5979 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
5980 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5981 }
5982
5983 // Test that the following scenario works:
5984 // - change a texture's max level to 0.
5985 // - clear the texture with glClear.
5986 // - sample the texture and draw to another FBO.
5987 // - draw to the texture again.
5988 // - The texture's final color should be clear color in 1st pass + draw color.
TEST_P(Texture2DBaseMaxTestES3,SetMaxLevelToZeroThenClearThenSampleThenDraw)5989 TEST_P(Texture2DBaseMaxTestES3, SetMaxLevelToZeroThenClearThenSampleThenDraw)
5990 {
5991 ANGLE_GL_PROGRAM(textureProgram, angle::essl3_shaders::vs::Texture2DLod(),
5992 angle::essl3_shaders::fs::Texture2DLod());
5993 ANGLE_GL_PROGRAM(blueProgram, angle::essl1_shaders::vs::Simple(),
5994 angle::essl1_shaders::fs::Blue());
5995
5996 GLTexture texture;
5997 glBindTexture(GL_TEXTURE_2D, texture);
5998 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5999 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6000 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6001
6002 // 1. Change the texture's max level to 0.
6003 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6004 EXPECT_GL_NO_ERROR();
6005
6006 // 2. Attach the texture to a FBO and clear it.
6007 GLFramebuffer fbo;
6008 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6009 EXPECT_GL_NO_ERROR();
6010 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
6011 glEnable(GL_BLEND);
6012 glBlendFunc(GL_ONE, GL_ONE);
6013 glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);
6014 glClear(GL_COLOR_BUFFER_BIT);
6015
6016 // 3. Draw the bound texture to default FBO.
6017 glBindFramebuffer(GL_FRAMEBUFFER, 0);
6018 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6019 glClear(GL_COLOR_BUFFER_BIT);
6020 glUseProgram(textureProgram);
6021 drawQuad(textureProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6022
6023 // 4. Draw to the texture again
6024 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6025 glUseProgram(blueProgram);
6026 drawQuad(blueProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6027
6028 // Expect the final color to be accumulated color
6029 EXPECT_GL_NO_ERROR();
6030 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(1, 2, 255, 255));
6031 }
6032
6033 // Test that the following scenario works:
6034 // - change a texture's max level to 1.
6035 // - clear the texture with glClear.
6036 // - change the texture's max level to 0.
6037 // - sample the texture and draw to another FBO.
6038 // - draw to the texture again.
6039 // - The texture's final color should be clear color in 1st pass + draw color.
TEST_P(Texture2DBaseMaxTestES3,SetMaxLevelToOneThenClearThenSetMaxLevelToZeroThenSampleThenDraw)6040 TEST_P(Texture2DBaseMaxTestES3, SetMaxLevelToOneThenClearThenSetMaxLevelToZeroThenSampleThenDraw)
6041 {
6042 ANGLE_GL_PROGRAM(textureProgram, angle::essl3_shaders::vs::Texture2DLod(),
6043 angle::essl3_shaders::fs::Texture2DLod());
6044 ANGLE_GL_PROGRAM(blueProgram, angle::essl1_shaders::vs::Simple(),
6045 angle::essl1_shaders::fs::Blue());
6046
6047 GLTexture texture;
6048 glBindTexture(GL_TEXTURE_2D, texture);
6049 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6050 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6051 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6052 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6053
6054 // 1. Change the texture's max level to 1.
6055 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6056 EXPECT_GL_NO_ERROR();
6057
6058 // 2. Attach the texture to a FBO and clear it.
6059 GLFramebuffer fbo;
6060 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6061 EXPECT_GL_NO_ERROR();
6062 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
6063 glEnable(GL_BLEND);
6064 glBlendFunc(GL_ONE, GL_ONE);
6065 glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);
6066 glClear(GL_COLOR_BUFFER_BIT);
6067
6068 // 3. Change the texture's max level to 0.
6069 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6070
6071 // 4. Draw the bound texture to default FBO.
6072 glBindFramebuffer(GL_FRAMEBUFFER, 0);
6073 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6074 glClear(GL_COLOR_BUFFER_BIT);
6075 glUseProgram(textureProgram);
6076 drawQuad(textureProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6077
6078 // 5. Draw to the texture again
6079 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6080 glUseProgram(blueProgram);
6081 drawQuad(blueProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
6082
6083 // Expect the final color to be accumulated color
6084 EXPECT_GL_NO_ERROR();
6085 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(1, 2, 255, 255));
6086 }
6087
6088 // Test to check that texture completeness is determined correctly when the texture base level is
6089 // greater than 0, and also that level 0 is not sampled when base level is greater than 0.
TEST_P(Texture2DTestES3,DrawWithBaseLevel1)6090 TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
6091 {
6092 glActiveTexture(GL_TEXTURE0);
6093 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6094
6095 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6096 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6097 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6098 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6099 texDataGreen.data());
6100 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6101 texDataGreen.data());
6102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6105
6106 EXPECT_GL_NO_ERROR();
6107
6108 drawQuad(mProgram, "position", 0.5f);
6109
6110 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6111 }
6112
testCopyImage(const APIExtensionVersion usedExtension)6113 void Texture2DTestES3::testCopyImage(const APIExtensionVersion usedExtension)
6114 {
6115 ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6116
6117 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6118 GLTexture srcTexture;
6119 GLTexture destTexture;
6120
6121 glActiveTexture(GL_TEXTURE0);
6122 glBindTexture(GL_TEXTURE_2D, destTexture);
6123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6127 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6128
6129 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6130 glBindTexture(GL_TEXTURE_2D, srcTexture);
6131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6135 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6136 texDataGreen.data());
6137
6138 glBindTexture(GL_TEXTURE_2D, 0);
6139
6140 // copy
6141 if (usedExtension == APIExtensionVersion::OES)
6142 {
6143 glCopyImageSubDataOES(srcTexture, GL_TEXTURE_2D, 0, 2, 2, 0, destTexture, GL_TEXTURE_2D, 0,
6144 2, 2, 0, 2, 2, 1);
6145 }
6146 else
6147 {
6148 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 2, 2, 0, destTexture, GL_TEXTURE_2D, 0,
6149 2, 2, 0, 2, 2, 1);
6150 }
6151 glBindTexture(GL_TEXTURE_2D, destTexture);
6152 EXPECT_GL_NO_ERROR();
6153
6154 glViewport(0, 0, 4, 4);
6155 drawQuad(mProgram, "position", 0.5f);
6156 EXPECT_GL_NO_ERROR();
6157
6158 EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
6159 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
6160 EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
6161 }
6162
testCopyMultisampleImage(const APIExtensionVersion usedExtension,const GLenum internalFormat)6163 void MultisampleTexture2DTestES31::testCopyMultisampleImage(const APIExtensionVersion usedExtension,
6164 const GLenum internalFormat)
6165 {
6166 ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6167
6168 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
6169
6170 GLTexture srcTexture;
6171 GLTexture destTexture;
6172 const GLenum target = GL_TEXTURE_2D_MULTISAMPLE;
6173
6174 GLint maxSamples = 0;
6175 glGetInternalformativ(target, internalFormat, GL_SAMPLES, 1, &maxSamples);
6176 EXPECT_GL_NO_ERROR();
6177
6178 glActiveTexture(GL_TEXTURE0);
6179 glBindTexture(target, destTexture);
6180 glTexStorage2DMultisample(target, maxSamples, internalFormat, 4, 4, false);
6181 EXPECT_GL_NO_ERROR();
6182
6183 glBindTexture(target, srcTexture);
6184 glTexStorage2DMultisample(target, maxSamples, internalFormat, 4, 4, false);
6185 EXPECT_GL_NO_ERROR();
6186
6187 GLFramebuffer fbo;
6188 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6189 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, srcTexture, 0);
6190 EXPECT_GL_NO_ERROR();
6191
6192 // Draw red into the source texture
6193 glViewport(0, 0, 4, 4);
6194 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6195
6196 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
6197 ASSERT_GL_NO_ERROR();
6198
6199 glBindTexture(target, 0);
6200
6201 // Copy
6202 if (usedExtension == APIExtensionVersion::OES)
6203 {
6204 glCopyImageSubDataOES(srcTexture, target, 0, 0, 0, 0, destTexture, target, 0, 0, 0, 0, 4, 4,
6205 1);
6206 }
6207 else
6208 {
6209 glCopyImageSubDataEXT(srcTexture, target, 0, 0, 0, 0, destTexture, target, 0, 0, 0, 0, 4, 4,
6210 1);
6211 }
6212 EXPECT_GL_NO_ERROR();
6213
6214 // Resolve the target texture
6215 GLTexture resolveTexture;
6216 glBindTexture(GL_TEXTURE_2D, resolveTexture);
6217 glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 4, 4);
6218
6219 GLFramebuffer resolveFbo;
6220 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
6221 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
6222 0);
6223
6224 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
6225 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, destTexture, 0);
6226 ASSERT_GL_NO_ERROR();
6227 glCheckFramebufferStatus(GL_FRAMEBUFFER);
6228 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6229
6230 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6231 glBlitFramebuffer(0, 0, 4, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT, GL_LINEAR);
6232 ASSERT_GL_NO_ERROR();
6233
6234 glBindFramebuffer(GL_FRAMEBUFFER, resolveFbo);
6235 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
6236 }
6237
testCopyMultisampleArrayImage(const APIExtensionVersion usedExtension,const GLenum internalFormat)6238 void MultisampleTexture2DTestES31::testCopyMultisampleArrayImage(
6239 const APIExtensionVersion usedExtension,
6240 const GLenum internalFormat)
6241 {
6242 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_storage_multisample_2d_array"));
6243
6244 ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6245
6246 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
6247
6248 GLTexture srcTexture;
6249 GLTexture destTexture;
6250
6251 GLint maxSamples = 0;
6252 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalFormat, GL_SAMPLES, 1, &maxSamples);
6253 EXPECT_GL_NO_ERROR();
6254
6255 glActiveTexture(GL_TEXTURE0);
6256 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, destTexture);
6257 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamples, internalFormat, 4,
6258 4, 3, false);
6259 EXPECT_GL_NO_ERROR();
6260
6261 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, srcTexture);
6262 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamples, internalFormat, 4,
6263 4, 3, false);
6264 EXPECT_GL_NO_ERROR();
6265
6266 GLFramebuffer fbo;
6267 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6268 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTexture, 0, 1);
6269 EXPECT_GL_NO_ERROR();
6270
6271 // Draw red into the source texture layer 1
6272 glViewport(0, 0, 4, 4);
6273 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6274
6275 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
6276 ASSERT_GL_NO_ERROR();
6277
6278 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0);
6279
6280 // Copy
6281 if (usedExtension == APIExtensionVersion::OES)
6282 {
6283 glCopyImageSubDataOES(srcTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 1,
6284 destTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 2, 4, 4,
6285 1);
6286 }
6287 else
6288 {
6289 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 1,
6290 destTexture, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, 0, 0, 2, 4, 4,
6291 1);
6292 }
6293 EXPECT_GL_NO_ERROR();
6294
6295 // Resolve the target texture
6296 GLTexture resolveTexture;
6297 glBindTexture(GL_TEXTURE_2D, resolveTexture);
6298 glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 4, 4);
6299
6300 GLFramebuffer resolveFbo;
6301 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
6302 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
6303 0);
6304
6305 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
6306 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, 2);
6307 ASSERT_GL_NO_ERROR();
6308 glCheckFramebufferStatus(GL_FRAMEBUFFER);
6309 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6310
6311 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6312 glBlitFramebuffer(0, 0, 4, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT, GL_LINEAR);
6313 ASSERT_GL_NO_ERROR();
6314
6315 glBindFramebuffer(GL_FRAMEBUFFER, resolveFbo);
6316 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
6317 }
6318
6319 // Test basic GL_EXT_copy_image copy without any bound textures
TEST_P(Texture2DTestES3,CopyImageEXT)6320 TEST_P(Texture2DTestES3, CopyImageEXT)
6321 {
6322 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6323 testCopyImage(APIExtensionVersion::EXT);
6324 }
6325
6326 // Test basic GL_OES_copy_image copy without any bound textures
TEST_P(Texture2DTestES3,CopyImageOES)6327 TEST_P(Texture2DTestES3, CopyImageOES)
6328 {
6329 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6330 testCopyImage(APIExtensionVersion::OES);
6331 }
6332
testCopyImageDepthStencil(const APIExtensionVersion usedExtension)6333 void Texture2DTestES3::testCopyImageDepthStencil(const APIExtensionVersion usedExtension)
6334 {
6335 ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES);
6336
6337 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6338 GLTexture srcTexture;
6339 GLTexture destTexture;
6340
6341 constexpr GLsizei kSize = 4;
6342
6343 GLTexture src;
6344 glBindTexture(GL_TEXTURE_2D, src);
6345 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
6346
6347 GLTexture dst;
6348 glBindTexture(GL_TEXTURE_2D, dst);
6349 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
6350
6351 // A color image for testing depth/stencil
6352 GLTexture color;
6353 glBindTexture(GL_TEXTURE_2D, color);
6354 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
6355
6356 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
6357 glUseProgram(program);
6358 GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
6359 ASSERT_NE(colorLoc, -1);
6360
6361 // Initialize the src depth image
6362 GLFramebuffer fbo;
6363 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6364 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
6365 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, src, 0);
6366 glClearDepthf(0.3f);
6367 glClearStencil(0x57);
6368 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6369
6370 glEnable(GL_DEPTH_TEST);
6371 glDepthMask(GL_FALSE);
6372 glEnable(GL_STENCIL_TEST);
6373 glStencilFunc(GL_EQUAL, 0x57, 0xFF);
6374 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
6375 glStencilMask(0xFF);
6376
6377 glDepthFunc(GL_LESS);
6378 glUniform4f(colorLoc, 1, 0, 0, 1);
6379 drawQuad(program, essl1_shaders::PositionAttrib(), -0.41f);
6380 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6381
6382 glDepthFunc(GL_GREATER);
6383 glUniform4f(colorLoc, 0, 1, 0, 1);
6384 drawQuad(program, essl1_shaders::PositionAttrib(), -0.39f);
6385 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6386 ASSERT_GL_NO_ERROR();
6387
6388 // Now that the depth stencil image is definitely initialized, copy it into the destination
6389 if (usedExtension == APIExtensionVersion::OES)
6390 {
6391 glCopyImageSubDataOES(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
6392 kSize, 1);
6393 }
6394 else
6395 {
6396 glCopyImageSubDataEXT(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
6397 kSize, 1);
6398 }
6399 ASSERT_GL_NO_ERROR();
6400
6401 // Verify the dst texture has the right depth/stencil values
6402 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst, 0);
6403
6404 glDepthFunc(GL_LESS);
6405 glUniform4f(colorLoc, 0, 0, 1, 1);
6406 drawQuad(program, essl1_shaders::PositionAttrib(), -0.41f);
6407 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
6408
6409 glDepthFunc(GL_GREATER);
6410 glUniform4f(colorLoc, 1, 1, 0, 1);
6411 drawQuad(program, essl1_shaders::PositionAttrib(), -0.39f);
6412 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
6413 ASSERT_GL_NO_ERROR();
6414 }
6415
6416 // Test basic GL_EXT_copy_image copy with a depth/stencil texture
TEST_P(Texture2DTestES3,CopyImageEXTDepthStencil)6417 TEST_P(Texture2DTestES3, CopyImageEXTDepthStencil)
6418 {
6419 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6420 testCopyImageDepthStencil(APIExtensionVersion::EXT);
6421 }
6422
6423 // Test basic GL_OES_copy_image copy with a depth/stencil texture
TEST_P(Texture2DTestES3,CopyImageOESDepthStencil)6424 TEST_P(Texture2DTestES3, CopyImageOESDepthStencil)
6425 {
6426 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6427 testCopyImageDepthStencil(APIExtensionVersion::OES);
6428 }
6429
6430 // Test GL_EXT_copy_image compressed texture copy with mipmaps smaller than the block size
TEST_P(Texture2DTestES3,CopyCompressedImageMipMaps)6431 TEST_P(Texture2DTestES3, CopyCompressedImageMipMaps)
6432 {
6433 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6434 // TODO(http://anglebug.com/42264170): Fix calls to vkCmdCopyBufferToImage() with images smaller
6435 // than the compressed format block size.
6436 ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::AllocateNonZeroMemory));
6437
6438 constexpr uint32_t kSize = 4;
6439 constexpr size_t kNumLevels = 3;
6440 const uint8_t CompressedImageETC1[8] = {0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0};
6441
6442 GLTexture srcTexture;
6443 glBindTexture(GL_TEXTURE_2D, srcTexture);
6444 for (size_t level = 0; level < kNumLevels; ++level)
6445 {
6446 glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
6447 kSize >> level, 0, 8, CompressedImageETC1);
6448 EXPECT_GL_NO_ERROR();
6449 }
6450
6451 GLTexture destTexture;
6452 glBindTexture(GL_TEXTURE_2D, destTexture);
6453 for (size_t level = 0; level < kNumLevels; ++level)
6454 {
6455 glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
6456 kSize >> level, 0, 8, nullptr);
6457 EXPECT_GL_NO_ERROR();
6458 }
6459
6460 glBindTexture(GL_TEXTURE_2D, 0);
6461
6462 // copy
6463 for (size_t level = 0; level < kNumLevels; ++level)
6464 {
6465 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, level, 0, 0, 0, destTexture, GL_TEXTURE_2D,
6466 level, 0, 0, 0, kSize >> level, kSize >> level, 1);
6467 EXPECT_GL_NO_ERROR();
6468 }
6469 }
6470
6471 // Test GL_EXT_copy_image copy with a non-zero base level
TEST_P(Texture2DTestES3,CopyImageBaseLevel1)6472 TEST_P(Texture2DTestES3, CopyImageBaseLevel1)
6473 {
6474 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6475
6476 std::vector<GLColor> texDataBlack(8u * 8u, GLColor::black);
6477 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6478 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6479 std::vector<GLColor> texDataBlue(4u * 4u, GLColor::blue);
6480
6481 GLTexture srcTexture;
6482 GLTexture destTexture;
6483
6484 glActiveTexture(GL_TEXTURE0);
6485 glBindTexture(GL_TEXTURE_2D, destTexture);
6486 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6487 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6488 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6489 texDataBlack.data());
6490 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6491 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6492 texDataGreen.data());
6493 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
6494 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6495 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6496
6497 glBindTexture(GL_TEXTURE_2D, srcTexture);
6498 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6499 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6500 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6501 texDataBlack.data());
6502 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6503 texDataGreen.data());
6504 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
6505 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6506 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6507 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6508
6509 glBindTexture(GL_TEXTURE_2D, 0);
6510
6511 // copy
6512 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 1, 2, 2, 0, destTexture, GL_TEXTURE_2D, 1, 2,
6513 2, 0, 2, 2, 1);
6514
6515 glBindTexture(GL_TEXTURE_2D, destTexture);
6516
6517 EXPECT_GL_NO_ERROR();
6518
6519 glViewport(0, 0, 4, 4);
6520 drawQuad(mProgram, "position", 0.5f);
6521 EXPECT_GL_NO_ERROR();
6522
6523 EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
6524 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
6525 EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
6526 }
6527
6528 // Test basic GL_EXT_copy_image copy without any draw calls by attaching the texture
6529 // to a framebuffer and reads from the framebuffer to validate the copy
TEST_P(Texture2DTestES3,CopyImageFB)6530 TEST_P(Texture2DTestES3, CopyImageFB)
6531 {
6532 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6533
6534 glViewport(0, 0, 4, 4);
6535 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
6536 GLTexture srcTexture;
6537 GLTexture destTexture;
6538
6539 glActiveTexture(GL_TEXTURE0);
6540 glBindTexture(GL_TEXTURE_2D, destTexture);
6541 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6542 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6543 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6544 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6545 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6546
6547 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6548 glBindTexture(GL_TEXTURE_2D, srcTexture);
6549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6550 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6551 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6552 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6553 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6554 texDataGreen.data());
6555 glBindTexture(GL_TEXTURE_2D, 0);
6556
6557 // copy
6558 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, destTexture, GL_TEXTURE_2D, 0, 0,
6559 1, 0, 3, 3, 1);
6560
6561 EXPECT_GL_NO_ERROR();
6562
6563 GLFramebuffer fb;
6564 glBindFramebuffer(GL_FRAMEBUFFER, fb);
6565 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
6566 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6567
6568 EXPECT_PIXEL_RECT_EQ(0, 1, 3, 3, GLColor::green);
6569 EXPECT_PIXEL_RECT_EQ(3, 0, 1, 4, GLColor::red);
6570 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 1, GLColor::red);
6571
6572 glBindFramebuffer(GL_FRAMEBUFFER, 0);
6573 }
6574
6575 // Test GL_EXT_copy_image copy to a framebuffer attachment after
6576 // invalidation. Then draw with blending onto the framebuffer.
TEST_P(Texture2DTestES3,CopyImageFBInvalidateThenBlend)6577 TEST_P(Texture2DTestES3, CopyImageFBInvalidateThenBlend)
6578 {
6579 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6580
6581 ANGLE_GL_PROGRAM(drawBlueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
6582 ANGLE_GL_PROGRAM(drawRedProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
6583
6584 glViewport(0, 0, 4, 4);
6585 GLTexture srcTexture;
6586 GLTexture textureAttachment;
6587
6588 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
6589 glBindTexture(GL_TEXTURE_2D, srcTexture);
6590 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
6591 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6592 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6593 texDataGreen.data());
6594 glBindTexture(GL_TEXTURE_2D, 0);
6595
6596 glBindTexture(GL_TEXTURE_2D, textureAttachment);
6597 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
6598 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
6599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6600 glBindTexture(GL_TEXTURE_2D, 0);
6601
6602 GLFramebuffer fb;
6603 glBindFramebuffer(GL_FRAMEBUFFER, fb);
6604 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureAttachment,
6605 0);
6606 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
6607
6608 // Draw something in the texture to make sure it's image is defined.
6609 drawQuad(drawRedProgram, essl1_shaders::PositionAttrib(), 0.0f);
6610
6611 // Invalidate the framebuffer.
6612 const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
6613 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
6614 ASSERT_GL_NO_ERROR();
6615
6616 // Copy into the framebuffer attachment.
6617 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, textureAttachment, GL_TEXTURE_2D,
6618 0, 0, 0, 0, 4, 4, 1);
6619 EXPECT_GL_NO_ERROR();
6620
6621 // Draw and blend, making sure both the copy and draw happen correctly.
6622 glEnable(GL_BLEND);
6623 glBlendFunc(GL_ONE, GL_ONE);
6624 drawQuad(drawBlueProgram, essl1_shaders::PositionAttrib(), 0.0f);
6625 ASSERT_GL_NO_ERROR();
6626
6627 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::cyan);
6628
6629 glBindFramebuffer(GL_FRAMEBUFFER, 0);
6630 }
6631
6632 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
6633 // have images defined.
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeUndefined)6634 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
6635 {
6636 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
6637 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
6638
6639 glActiveTexture(GL_TEXTURE0);
6640 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6641 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6642 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6643 texDataGreen.data());
6644 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6645 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6646 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6647 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6648
6649 EXPECT_GL_NO_ERROR();
6650
6651 drawQuad(mProgram, "position", 0.5f);
6652
6653 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6654 }
6655
6656 // Test that drawing works correctly when level 0 is undefined and base level is 1.
TEST_P(Texture2DTestES3,DrawWithLevelZeroUndefined)6657 TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
6658 {
6659 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
6660 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
6661
6662 glActiveTexture(GL_TEXTURE0);
6663 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6664 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6665 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6666 texDataGreen.data());
6667 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6668 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6669 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6670 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6671
6672 EXPECT_GL_NO_ERROR();
6673
6674 // Texture is incomplete.
6675 drawQuad(mProgram, "position", 0.5f);
6676 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
6677
6678 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6679 texDataGreen.data());
6680
6681 // Texture is now complete.
6682 drawQuad(mProgram, "position", 0.5f);
6683 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6684 }
6685
6686 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
6687 // dimensions that don't fit the images inside the range.
6688 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)6689 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
6690 {
6691 glActiveTexture(GL_TEXTURE0);
6692 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6693 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
6694 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
6695 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
6696
6697 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6698 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6699
6700 // Two levels that are initially unused.
6701 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
6702 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6703 texDataCyan.data());
6704
6705 // One level that is used - only this level should affect completeness.
6706 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6707 texDataGreen.data());
6708
6709 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6710 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
6711
6712 EXPECT_GL_NO_ERROR();
6713
6714 drawQuad(mProgram, "position", 0.5f);
6715
6716 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6717
6718 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
6719
6720 // Switch the level that is being used to the cyan level 2.
6721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
6722 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6723
6724 EXPECT_GL_NO_ERROR();
6725
6726 drawQuad(mProgram, "position", 0.5f);
6727
6728 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
6729 }
6730
6731 // Test glCopyImageSubDataEXT with GL_TEXTURE_2D_MULTISAMPLE,
6732 // RGBA8->RGBA8 copy
6733 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleImageEXT)6734 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleImageEXT)
6735 {
6736 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6737 testCopyMultisampleImage(APIExtensionVersion::EXT, GL_RGBA8);
6738 testCopyMultisampleImage(APIExtensionVersion::EXT, GL_RGB8);
6739 }
6740
6741 // Test glCopyImageSubDataOES with GL_TEXTURE_2D_MULTISAMPLE,
6742 // RGBA8->RGBA8 copy
6743 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleImageOES)6744 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleImageOES)
6745 {
6746 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6747 testCopyMultisampleImage(APIExtensionVersion::OES, GL_RGBA8);
6748 testCopyMultisampleImage(APIExtensionVersion::OES, GL_RGB8);
6749 }
6750
6751 // Test glCopyImageSubDataEXT with GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
6752 // RGBA8->RGBA8 copy
6753 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleArrayImageEXT)6754 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleArrayImageEXT)
6755 {
6756 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
6757 testCopyMultisampleArrayImage(APIExtensionVersion::EXT, GL_RGBA8);
6758 testCopyMultisampleArrayImage(APIExtensionVersion::EXT, GL_RGB8);
6759 }
6760
6761 // Test glCopyImageSubDataOES with GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
6762 // RGBA8->RGBA8 copy
6763 // RGB8->RGB8 copy
TEST_P(MultisampleTexture2DTestES31,CopyMultisampleArrayImageOES)6764 TEST_P(MultisampleTexture2DTestES31, CopyMultisampleArrayImageOES)
6765 {
6766 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_copy_image"));
6767 testCopyMultisampleArrayImage(APIExtensionVersion::OES, GL_RGBA8);
6768 testCopyMultisampleArrayImage(APIExtensionVersion::OES, GL_RGB8);
6769 }
6770
6771 // Depth/Stencil textures cannot be 3D.
TEST_P(Texture3DTestES3,DepthStencil3DDisallowed)6772 TEST_P(Texture3DTestES3, DepthStencil3DDisallowed)
6773 {
6774 const std::array<std::tuple<GLenum, GLenum, GLenum>, 6> testConfigs = {
6775 std::make_tuple(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT),
6776 std::make_tuple(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT),
6777 std::make_tuple(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT),
6778 std::make_tuple(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV),
6779 std::make_tuple(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8),
6780 std::make_tuple(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE)};
6781
6782 for (auto testConfig : testConfigs)
6783 {
6784 const GLenum internalformat = std::get<0>(testConfig);
6785 const GLenum format = std::get<1>(testConfig);
6786 const GLenum type = std::get<2>(testConfig);
6787
6788 if (internalformat == GL_STENCIL_INDEX8 && !IsGLExtensionEnabled("GL_OES_texture_stencil8"))
6789 {
6790 continue;
6791 }
6792
6793 GLTexture depthTexture;
6794 glBindTexture(GL_TEXTURE_3D, depthTexture);
6795 glTexImage3D(GL_TEXTURE_3D, 0, internalformat, 16, 16, 16, 0, format, type, nullptr);
6796 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6797
6798 glTexStorage3D(GL_TEXTURE_3D, 2, internalformat, 16, 16, 16);
6799 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6800 }
6801 }
6802
6803 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
6804 // have images defined.
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeUndefined)6805 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
6806 {
6807 glActiveTexture(GL_TEXTURE0);
6808 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6809 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6810 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6811 texDataGreen.data());
6812 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6813 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6814 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
6815 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
6816
6817 EXPECT_GL_NO_ERROR();
6818
6819 drawQuad(mProgram, "position", 0.5f);
6820
6821 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6822 }
6823
6824 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
6825 // dimensions that don't fit the images inside the range.
6826 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)6827 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
6828 {
6829 glActiveTexture(GL_TEXTURE0);
6830 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6831 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
6832 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6833 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
6834
6835 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6836 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6837
6838 // Two levels that are initially unused.
6839 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6840 texDataRed.data());
6841 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6842 texDataCyan.data());
6843
6844 // One level that is used - only this level should affect completeness.
6845 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6846 texDataGreen.data());
6847
6848 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
6849 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
6850
6851 EXPECT_GL_NO_ERROR();
6852
6853 drawQuad(mProgram, "position", 0.5f);
6854
6855 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6856
6857 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
6858
6859 // Switch the level that is being used to the cyan level 2.
6860 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
6861 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
6862
6863 EXPECT_GL_NO_ERROR();
6864
6865 drawQuad(mProgram, "position", 0.5f);
6866
6867 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
6868 }
6869
6870 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
6871 // have images defined.
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeUndefined)6872 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
6873 {
6874 glActiveTexture(GL_TEXTURE0);
6875 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6876 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6877 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6878 texDataGreen.data());
6879 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6880 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6881 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
6882 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
6883
6884 EXPECT_GL_NO_ERROR();
6885
6886 drawQuad(mProgram, "position", 0.5f);
6887
6888 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6889 }
6890
6891 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
6892 // dimensions that don't fit the images inside the range.
6893 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)6894 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
6895 {
6896 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
6897 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
6898
6899 glActiveTexture(GL_TEXTURE0);
6900 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
6901 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
6902 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
6903 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
6904
6905 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6906 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
6907
6908 // Two levels that are initially unused.
6909 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6910 texDataRed.data());
6911 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6912 texDataCyan.data());
6913
6914 // One level that is used - only this level should affect completeness.
6915 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6916 texDataGreen.data());
6917
6918 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
6919 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
6920
6921 EXPECT_GL_NO_ERROR();
6922
6923 drawQuad(mProgram, "position", 0.5f);
6924
6925 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6926
6927 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
6928
6929 // Switch the level that is being used to the cyan level 2.
6930 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
6931 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
6932
6933 EXPECT_GL_NO_ERROR();
6934
6935 drawQuad(mProgram, "position", 0.5f);
6936
6937 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
6938 }
6939
6940 // Create a 2D array, then immediately redefine it to have fewer layers. Regression test for a bug
6941 // in the Vulkan backend where the old higher-layer-count data upload was not removed.
TEST_P(Texture2DArrayTestES3,TextureArrayRedefineThenUse)6942 TEST_P(Texture2DArrayTestES3, TextureArrayRedefineThenUse)
6943 {
6944 int px = getWindowWidth() / 2;
6945 int py = getWindowHeight() / 2;
6946
6947 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6948
6949 // Fill the whole texture with red, then redefine it and fill with green
6950 std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
6951 std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
6952 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6953 pixelsRed.data());
6954 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6955 pixelsGreen.data());
6956
6957 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6958 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6959 EXPECT_GL_NO_ERROR();
6960
6961 glUseProgram(mProgram);
6962 EXPECT_GL_NO_ERROR();
6963
6964 // Draw the first slice
6965 glUniform1i(mTextureArraySliceUniformLocation, 0);
6966 drawQuad(mProgram, "position", 0.5f);
6967 EXPECT_GL_NO_ERROR();
6968 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
6969
6970 // Draw the second slice
6971 glUniform1i(mTextureArraySliceUniformLocation, 1);
6972 drawQuad(mProgram, "position", 0.5f);
6973 EXPECT_GL_NO_ERROR();
6974 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
6975 }
6976
6977 // Create a 2D array texture and update layers with data and test that pruning
6978 // of superseded updates works as expected.
TEST_P(Texture2DArrayTestES3,TextureArrayPruneSupersededUpdates)6979 TEST_P(Texture2DArrayTestES3, TextureArrayPruneSupersededUpdates)
6980 {
6981 constexpr uint32_t kTexWidth = 256;
6982 constexpr uint32_t kTexHeight = 256;
6983 constexpr uint32_t kTexLayers = 3;
6984
6985 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6986 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6987 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6988 EXPECT_GL_NO_ERROR();
6989
6990 // Initialize entire texture.
6991 constexpr GLColor kInitialExpectedColor = GLColor(201u, 201u, 201u, 201u);
6992 std::vector<GLColor> initialData(kTexWidth * kTexHeight * kTexLayers, kInitialExpectedColor);
6993 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kTexWidth, kTexHeight, kTexLayers, 0, GL_RGBA,
6994 GL_UNSIGNED_BYTE, initialData.data());
6995
6996 // Upate different layers with different colors, these together should supersed
6997 // the entire init update
6998 constexpr GLColor kExpectedColor[] = {GLColor(32u, 32u, 32u, 32u), GLColor(64u, 64u, 64u, 64u),
6999 GLColor(128u, 128u, 128u, 128u)};
7000 std::vector<GLColor> supersedingData[] = {
7001 std::vector<GLColor>(kTexWidth * kTexHeight, kExpectedColor[0]),
7002 std::vector<GLColor>(kTexWidth * kTexHeight, kExpectedColor[1]),
7003 std::vector<GLColor>(kTexWidth * kTexHeight, kExpectedColor[2])};
7004
7005 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kTexWidth, kTexHeight, 1, GL_RGBA,
7006 GL_UNSIGNED_BYTE, supersedingData[0].data());
7007 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, kTexWidth, kTexHeight, 1, GL_RGBA,
7008 GL_UNSIGNED_BYTE, supersedingData[1].data());
7009 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, kTexWidth, kTexHeight, 1, GL_RGBA,
7010 GL_UNSIGNED_BYTE, supersedingData[2].data());
7011
7012 glUseProgram(mProgram);
7013 EXPECT_GL_NO_ERROR();
7014
7015 // Draw layer 0
7016 glUniform1i(mTextureArraySliceUniformLocation, 0);
7017 drawQuad(mProgram, "position", 0.5f);
7018 EXPECT_GL_NO_ERROR();
7019 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor[0]);
7020
7021 // Draw layer 1
7022 glUniform1i(mTextureArraySliceUniformLocation, 1);
7023 drawQuad(mProgram, "position", 0.5f);
7024 EXPECT_GL_NO_ERROR();
7025 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor[1]);
7026
7027 // Draw layer 2
7028 glUniform1i(mTextureArraySliceUniformLocation, 2);
7029 drawQuad(mProgram, "position", 0.5f);
7030 EXPECT_GL_NO_ERROR();
7031 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor[2]);
7032 }
7033
7034 // Create a 2D array, use it, then redefine it to have fewer layers. Regression test for a bug in
7035 // the Vulkan backend where the old higher-layer-count data upload was not removed.
TEST_P(Texture2DArrayTestES3,TextureArrayUseThenRedefineThenUse)7036 TEST_P(Texture2DArrayTestES3, TextureArrayUseThenRedefineThenUse)
7037 {
7038 int px = getWindowWidth() / 2;
7039 int py = getWindowHeight() / 2;
7040
7041 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
7042
7043 // Fill the whole texture with red.
7044 std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
7045 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7046 pixelsRed.data());
7047
7048 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7049 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7050 EXPECT_GL_NO_ERROR();
7051
7052 glUseProgram(mProgram);
7053 EXPECT_GL_NO_ERROR();
7054
7055 // Draw the first slice
7056 glUniform1i(mTextureArraySliceUniformLocation, 0);
7057 drawQuad(mProgram, "position", 0.5f);
7058 EXPECT_GL_NO_ERROR();
7059 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
7060
7061 // Draw the fourth slice
7062 glUniform1i(mTextureArraySliceUniformLocation, 3);
7063 drawQuad(mProgram, "position", 0.5f);
7064 EXPECT_GL_NO_ERROR();
7065 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
7066
7067 // Redefine the image and fill with green
7068 std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
7069 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7070 pixelsGreen.data());
7071
7072 // Draw the first slice
7073 glUniform1i(mTextureArraySliceUniformLocation, 0);
7074 drawQuad(mProgram, "position", 0.5f);
7075 EXPECT_GL_NO_ERROR();
7076 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
7077
7078 // Draw the second slice
7079 glUniform1i(mTextureArraySliceUniformLocation, 1);
7080 drawQuad(mProgram, "position", 0.5f);
7081 EXPECT_GL_NO_ERROR();
7082 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
7083 }
7084
7085 // Create a 2D array texture, use it, then redefine one level without changing dimensions.
TEST_P(Texture2DArrayTestES3,RedefineLevelData)7086 TEST_P(Texture2DArrayTestES3, RedefineLevelData)
7087 {
7088 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
7089
7090 // Fill both levels with red
7091 std::vector<GLColor> pixelsRed(2 * 2 * 1, GLColor::red);
7092 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7093 pixelsRed.data());
7094 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7095 pixelsRed.data());
7096 ASSERT_GL_NO_ERROR();
7097
7098 // Check that both levels are red
7099 GLFramebuffer fbo;
7100 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7101 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
7102 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7103 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 1, 0);
7104 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7105
7106 // Redefine level 1 with green
7107 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7108 &GLColor::green);
7109 ASSERT_GL_NO_ERROR();
7110
7111 // Check that level 0 is red and level 1 is green
7112 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 0, 0);
7113 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7114 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m2DArrayTexture, 1, 0);
7115 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7116 }
7117
7118 // Create a 3D texture, use it, then redefine one level without changing dimensions.
TEST_P(Texture3DTestES3,RedefineLevelData)7119 TEST_P(Texture3DTestES3, RedefineLevelData)
7120 {
7121 glBindTexture(GL_TEXTURE_3D, mTexture3D);
7122
7123 // Fill both levels with red
7124 std::vector<GLColor> pixelsRed(2 * 2 * 1, GLColor::red);
7125 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7126 pixelsRed.data());
7127 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7128 pixelsRed.data());
7129 ASSERT_GL_NO_ERROR();
7130
7131 // Check that both levels are red
7132 GLFramebuffer fbo;
7133 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7134 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 0, 0);
7135 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7136 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 1, 0);
7137 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7138
7139 // Redefine level 1 with green
7140 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7141 &GLColor::green);
7142 ASSERT_GL_NO_ERROR();
7143
7144 // Check that level 0 is red and level 1 is green
7145 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 0, 0);
7146 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7147 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture3D, 1, 0);
7148 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7149 }
7150
7151 // Test that texture completeness is updated if texture max level changes.
7152 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithMaxLevel)7153 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
7154 {
7155 glActiveTexture(GL_TEXTURE0);
7156 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7157 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
7158
7159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7161
7162 // A level that is initially unused.
7163 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7164 texDataGreen.data());
7165
7166 // One level that is initially used - only this level should affect completeness.
7167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7168 texDataGreen.data());
7169
7170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7172
7173 EXPECT_GL_NO_ERROR();
7174
7175 drawQuad(mProgram, "position", 0.5f);
7176
7177 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7178
7179 // Switch the max level to level 1. The levels within the used range now have inconsistent
7180 // dimensions and the texture should be incomplete.
7181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
7182
7183 EXPECT_GL_NO_ERROR();
7184
7185 drawQuad(mProgram, "position", 0.5f);
7186
7187 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7188 }
7189
7190 // Test a bug that staged clear overlaps with glTexSubImage with multiple layers may incorrectly
7191 // keep the staged clear. http://anglebug.com/345532371
TEST_P(Texture2DArrayTestES3,ClearThenTexSubImageWithOverlappingLayersThenRead)7192 TEST_P(Texture2DArrayTestES3, ClearThenTexSubImageWithOverlappingLayersThenRead)
7193 {
7194 constexpr GLsizei kTexWidth = 128;
7195 constexpr GLsizei kTexHeight = 128;
7196 constexpr GLsizei kTexDepth = 6;
7197 // Create a single leveled texture with 6 layers
7198 GLTexture tex;
7199 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
7200 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth);
7201
7202 // Stage clear to red on all layers
7203 GLFramebuffer drawFBO;
7204 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
7205 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
7206 for (GLsizei layer = 0; layer < kTexDepth; layer++)
7207 {
7208 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7209 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
7210 glClear(GL_COLOR_BUFFER_BIT);
7211 }
7212
7213 // TexSubImage with green color on half of the image of layer 2,3,4
7214 std::vector<GLColor> updateData((kTexWidth / 2) * kTexHeight * 3, GLColor::green);
7215 GLsizei layerStart = 2;
7216 GLsizei layerCount = 3;
7217 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerStart, kTexWidth / 2, kTexHeight, layerCount,
7218 GL_RGBA, GL_UNSIGNED_BYTE, updateData.data());
7219
7220 // Now read out layer 2/3/4
7221 GLFramebuffer readFBO;
7222 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
7223 for (GLsizei layer = layerStart; layer < layerStart + layerCount; layer++)
7224 {
7225 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7226 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
7227 EXPECT_PIXEL_EQ(kTexWidth / 4, kTexHeight / 2, GLColor::green.R, GLColor::green.G,
7228 GLColor::green.B, GLColor::green.A);
7229 EXPECT_PIXEL_EQ(3 * kTexWidth / 4, kTexHeight / 2, GLColor::red.R, GLColor::red.G,
7230 GLColor::red.B, GLColor::red.A);
7231 }
7232 ASSERT_GL_NO_ERROR();
7233 }
7234
7235 // Test a bug that staged clear overlaps with glTexSubImage with multiple layers may incorrectly
7236 // keep the staged clear. http://anglebug.com/345532371
TEST_P(Texture2DArrayTestES3,ClearThenTexSubImageWithOverlappingLayersThenDrawAndRead)7237 TEST_P(Texture2DArrayTestES3, ClearThenTexSubImageWithOverlappingLayersThenDrawAndRead)
7238 {
7239 constexpr GLsizei kTexWidth = 128;
7240 constexpr GLsizei kTexHeight = 128;
7241 constexpr GLsizei kTexDepth = 6;
7242 // Create a single leveled texture with 6 layers
7243 GLTexture tex;
7244 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
7245 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth);
7246
7247 // Stage clear to red on all layers
7248 GLFramebuffer drawFBO;
7249 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
7250 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
7251 for (GLsizei layer = 0; layer < kTexDepth; layer++)
7252 {
7253 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7254 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
7255 glClear(GL_COLOR_BUFFER_BIT);
7256 }
7257
7258 // TexSubImage with green color on half of the image of layer 2,3,4
7259 std::vector<GLColor> updateData((kTexWidth / 2) * kTexHeight * 3, GLColor::green);
7260 GLsizei layerStart = 2;
7261 GLsizei layerCount = 3;
7262 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerStart, kTexWidth / 2, kTexHeight, layerCount,
7263 GL_RGBA, GL_UNSIGNED_BYTE, updateData.data());
7264
7265 // Now Draw to fbo on layerStart with blue color
7266 GLsizei blueQuadLayer = 2;
7267 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, blueQuadLayer);
7268 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
7269 glEnable(GL_BLEND);
7270 glBlendFunc(GL_ONE, GL_ONE);
7271 ANGLE_GL_PROGRAM(blueProgram, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
7272 glUseProgram(blueProgram);
7273 drawQuad(blueProgram, essl3_shaders::PositionAttrib(), 0.5f);
7274
7275 // Now read out layer 2/3/4
7276 GLFramebuffer readFBO;
7277 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
7278 for (GLsizei layer = layerStart; layer < layerStart + layerCount; layer++)
7279 {
7280 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, layer);
7281 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
7282 if (layer == blueQuadLayer)
7283 {
7284 // green + blue = cyan
7285 EXPECT_PIXEL_EQ(kTexWidth / 4, kTexHeight / 2, GLColor::cyan.R, GLColor::cyan.G,
7286 GLColor::cyan.B, GLColor::cyan.A);
7287 // red + blue = magenta
7288 EXPECT_PIXEL_EQ(3 * kTexWidth / 4, kTexHeight / 2, GLColor::magenta.R,
7289 GLColor::magenta.G, GLColor::magenta.B, GLColor::magenta.A);
7290 }
7291 else
7292 {
7293 EXPECT_PIXEL_EQ(kTexWidth / 4, kTexHeight / 2, GLColor::green.R, GLColor::green.G,
7294 GLColor::green.B, GLColor::green.A);
7295 EXPECT_PIXEL_EQ(3 * kTexWidth / 4, kTexHeight / 2, GLColor::red.R, GLColor::red.G,
7296 GLColor::red.B, GLColor::red.A);
7297 }
7298 }
7299 ASSERT_GL_NO_ERROR();
7300 }
7301
7302 // Test that compressed textures ignore the pixel unpack state.
7303 // (https://crbug.org/1267496)
TEST_P(Texture3DTestES3,PixelUnpackStateTexImage)7304 TEST_P(Texture3DTestES3, PixelUnpackStateTexImage)
7305 {
7306 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
7307 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
7308
7309 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 5);
7310 glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
7311
7312 uint8_t data[64] = {0};
7313 glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 4, 4, 4, 0, 64,
7314 data);
7315 EXPECT_GL_NO_ERROR();
7316 }
7317
7318 // Test that compressed textures ignore the pixel unpack state.
7319 // (https://crbug.org/1267496)
TEST_P(Texture3DTestES3,PixelUnpackStateTexSubImage)7320 TEST_P(Texture3DTestES3, PixelUnpackStateTexSubImage)
7321 {
7322 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
7323 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
7324
7325 glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
7326
7327 uint8_t data[64] = {0};
7328 glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 4, 4, 4, 0, 64,
7329 data);
7330 EXPECT_GL_NO_ERROR();
7331
7332 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 5);
7333
7334 glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 4, 4, 4,
7335 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 64, data);
7336 EXPECT_GL_NO_ERROR();
7337 }
7338
7339 // Test that 3D texture completeness is updated if texture max level changes.
7340 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,Texture3DCompletenessChangesWithMaxLevel)7341 TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
7342 {
7343 glActiveTexture(GL_TEXTURE0);
7344 glBindTexture(GL_TEXTURE_3D, mTexture3D);
7345 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
7346
7347 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7348 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7349
7350 // A level that is initially unused.
7351 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7352 texDataGreen.data());
7353
7354 // One level that is initially used - only this level should affect completeness.
7355 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7356 texDataGreen.data());
7357
7358 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
7359 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
7360
7361 EXPECT_GL_NO_ERROR();
7362
7363 drawQuad(mProgram, "position", 0.5f);
7364
7365 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7366
7367 // Switch the max level to level 1. The levels within the used range now have inconsistent
7368 // dimensions and the texture should be incomplete.
7369 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
7370
7371 EXPECT_GL_NO_ERROR();
7372
7373 drawQuad(mProgram, "position", 0.5f);
7374
7375 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7376 }
7377
7378 // Test that texture completeness is updated if texture base level changes.
7379 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithBaseLevel)7380 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
7381 {
7382 glActiveTexture(GL_TEXTURE0);
7383 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7384 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
7385
7386 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7387 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7388
7389 // Two levels that are initially unused.
7390 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7391 texDataGreen.data());
7392 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7393 texDataGreen.data());
7394
7395 // One level that is initially used - only this level should affect completeness.
7396 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7397 texDataGreen.data());
7398
7399 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
7400 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
7401
7402 EXPECT_GL_NO_ERROR();
7403
7404 drawQuad(mProgram, "position", 0.5f);
7405
7406 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7407
7408 // Switch the base level to level 1. The levels within the used range now have inconsistent
7409 // dimensions and the texture should be incomplete.
7410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7411
7412 EXPECT_GL_NO_ERROR();
7413
7414 drawQuad(mProgram, "position", 0.5f);
7415
7416 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7417 }
7418
7419 // Test that texture is not complete if base level is greater than max level.
7420 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureBaseLevelGreaterThanMaxLevel)7421 TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
7422 {
7423 glActiveTexture(GL_TEXTURE0);
7424 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7425
7426 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7427 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7428
7429 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
7430
7431 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
7432 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7433
7434 EXPECT_GL_NO_ERROR();
7435
7436 drawQuad(mProgram, "position", 0.5f);
7437
7438 // Texture should be incomplete.
7439 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7440 }
7441
7442 // Test that immutable texture base level and max level are clamped.
7443 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
TEST_P(Texture2DTestES3,ImmutableTextureBaseLevelOutOfRange)7444 TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
7445 {
7446 glActiveTexture(GL_TEXTURE0);
7447 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7448
7449 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7450 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7451
7452 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
7453
7454 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
7455
7456 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
7457 // should be clamped to [base_level, levels - 1].
7458 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
7459 // In the case of this test, those rules make the effective base level and max level 0.
7460 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
7461 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
7462
7463 EXPECT_GL_NO_ERROR();
7464
7465 drawQuad(mProgram, "position", 0.5f);
7466
7467 // Texture should be complete.
7468 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7469 }
7470
7471 // Test that changing base level works when it affects the format of the texture.
TEST_P(Texture2DTestES3,TextureFormatChangesWithBaseLevel)7472 TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
7473 {
7474 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
7475 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
7476
7477 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
7478
7479 // Observed incorrect rendering on AMD OpenGL.
7480 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
7481
7482 glActiveTexture(GL_TEXTURE0);
7483 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7484 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
7485 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
7486
7487 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7488 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7489
7490 // RGBA8 level that's initially unused.
7491 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7492 texDataCyan.data());
7493
7494 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7495 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
7496
7497 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
7498 // format. It reads green channel data from the green and alpha channels of texDataGreen
7499 // (this is a bit hacky but works).
7500 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
7501
7502 EXPECT_GL_NO_ERROR();
7503
7504 drawQuad(mProgram, "position", 0.5f);
7505
7506 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7507
7508 // Switch the texture to use the cyan level 0 with the RGBA format.
7509 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7510 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7511
7512 EXPECT_GL_NO_ERROR();
7513
7514 drawQuad(mProgram, "position", 0.5f);
7515
7516 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
7517 }
7518
7519 // Test that setting a texture image works when base level is out of range.
TEST_P(Texture2DTestES3,SetImageWhenBaseLevelOutOfRange)7520 TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
7521 {
7522 glActiveTexture(GL_TEXTURE0);
7523 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7524
7525 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7526 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7527
7528 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
7529 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
7530
7531 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
7532
7533 EXPECT_GL_NO_ERROR();
7534
7535 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7536
7537 drawQuad(mProgram, "position", 0.5f);
7538
7539 // Texture should be complete.
7540 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7541 }
7542
7543 // In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
7544 // RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
7545 // with these formats does not work as expected.
TEST_P(Texture2DArrayTestES3,RedefineInittableArray)7546 TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
7547 {
7548 std::vector<GLubyte> pixelData;
7549 for (size_t count = 0; count < 5000; count++)
7550 {
7551 pixelData.push_back(0u);
7552 pixelData.push_back(255u);
7553 pixelData.push_back(0u);
7554 }
7555
7556 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
7557 glUseProgram(mProgram);
7558 glUniform1i(mTextureArrayLocation, 0);
7559
7560 // The first draw worked correctly.
7561 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
7562 &pixelData[0]);
7563
7564 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7565 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7566 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
7567 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
7568 drawQuad(mProgram, "position", 1.0f);
7569 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7570
7571 // The dimension of the respecification must match the original exactly to trigger the bug.
7572 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
7573 &pixelData[0]);
7574 drawQuad(mProgram, "position", 1.0f);
7575 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7576
7577 ASSERT_GL_NO_ERROR();
7578 }
7579
7580 // Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
7581 // This test is needed especially to confirm that sampler registers get assigned correctly on
7582 // the HLSL backend even when there's a mix of different HLSL sampler and texture types.
TEST_P(ShadowSamplerPlusSampler3DTestES3,ShadowSamplerPlusSampler3DDraw)7583 TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
7584 {
7585 glActiveTexture(GL_TEXTURE0);
7586 glBindTexture(GL_TEXTURE_3D, mTexture3D);
7587 GLubyte texData[4];
7588 texData[0] = 0;
7589 texData[1] = 60;
7590 texData[2] = 0;
7591 texData[3] = 255;
7592 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
7593
7594 glActiveTexture(GL_TEXTURE1);
7595 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
7596 GLfloat depthTexData[1];
7597 depthTexData[0] = 0.5f;
7598 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
7599 depthTexData);
7600
7601 glUseProgram(mProgram);
7602 glUniform1f(mDepthRefUniformLocation, 0.3f);
7603 glUniform1i(mTexture3DUniformLocation, 0);
7604 glUniform1i(mTextureShadowUniformLocation, 1);
7605
7606 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
7607 drawQuad(mProgram, "position", 0.5f);
7608 EXPECT_GL_NO_ERROR();
7609 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
7610 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
7611
7612 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
7613 drawQuad(mProgram, "position", 0.5f);
7614 EXPECT_GL_NO_ERROR();
7615 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
7616 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
7617 }
7618
7619 // Test multiple different sampler types in the same shader.
7620 // This test makes sure that even if sampler / texture registers get grouped together based on type
7621 // or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
7622 // still has the right register index information for each ESSL sampler.
7623 // The tested ESSL samplers have the following types in D3D11 HLSL:
7624 // sampler2D: Texture2D + SamplerState
7625 // samplerCube: TextureCube + SamplerState
7626 // sampler2DShadow: Texture2D + SamplerComparisonState
7627 // samplerCubeShadow: TextureCube + SamplerComparisonState
TEST_P(SamplerTypeMixTestES3,SamplerTypeMixDraw)7628 TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
7629 {
7630 glActiveTexture(GL_TEXTURE0);
7631 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7632 GLubyte texData[4];
7633 texData[0] = 0;
7634 texData[1] = 0;
7635 texData[2] = 120;
7636 texData[3] = 255;
7637 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
7638
7639 glActiveTexture(GL_TEXTURE1);
7640 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
7641 texData[0] = 0;
7642 texData[1] = 90;
7643 texData[2] = 0;
7644 texData[3] = 255;
7645 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
7646 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
7647 texData);
7648
7649 glActiveTexture(GL_TEXTURE2);
7650 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
7651 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
7652 GLfloat depthTexData[1];
7653 depthTexData[0] = 0.5f;
7654 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
7655 depthTexData);
7656
7657 glActiveTexture(GL_TEXTURE3);
7658 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
7659 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
7660 depthTexData[0] = 0.2f;
7661 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
7662 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
7663 depthTexData);
7664
7665 // http://anglebug.com/42262588: TODO: Add a DS texture case
7666
7667 EXPECT_GL_NO_ERROR();
7668
7669 glUseProgram(mProgram);
7670 glUniform1f(mDepthRefUniformLocation, 0.3f);
7671 glUniform1i(mTexture2DUniformLocation, 0);
7672 glUniform1i(mTextureCubeUniformLocation, 1);
7673 glUniform1i(mTexture2DShadowUniformLocation, 2);
7674 glUniform1i(mTextureCubeShadowUniformLocation, 3);
7675
7676 drawQuad(mProgram, "position", 0.5f);
7677 EXPECT_GL_NO_ERROR();
7678 // The shader writes:
7679 // <texture 2d color> +
7680 // <cube map color> +
7681 // 0.25 * <comparison result (1.0)> +
7682 // 0.125 * <comparison result (0.0)>
7683 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
7684 }
7685
7686 // Test different base levels on textures accessed through the same sampler array.
7687 // Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
TEST_P(TextureSizeTextureArrayTest,BaseLevelVariesInTextureArray)7688 TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
7689 {
7690 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
7691
7692 // http://anglebug.com/42263017
7693 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
7694
7695 glActiveTexture(GL_TEXTURE0);
7696 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
7697 GLsizei size = 64;
7698 for (GLint level = 0; level < 7; ++level)
7699 {
7700 ASSERT_LT(0, size);
7701 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7702 nullptr);
7703 size = size / 2;
7704 }
7705 ASSERT_EQ(0, size);
7706 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7707
7708 glActiveTexture(GL_TEXTURE1);
7709 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
7710 size = 128;
7711 for (GLint level = 0; level < 8; ++level)
7712 {
7713 ASSERT_LT(0, size);
7714 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7715 nullptr);
7716 size = size / 2;
7717 }
7718 ASSERT_EQ(0, size);
7719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
7720 EXPECT_GL_NO_ERROR();
7721
7722 glUseProgram(mProgram);
7723 glUniform1i(mTexture0Location, 0);
7724 glUniform1i(mTexture1Location, 1);
7725
7726 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
7727 EXPECT_GL_NO_ERROR();
7728 // Red channel: width of level 1 of texture A: 32.
7729 // Green channel: width of level 3 of texture B: 16.
7730 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
7731 }
7732
7733 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7734 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBImplicitAlpha1)7735 TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
7736 {
7737 glActiveTexture(GL_TEXTURE0);
7738 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7739 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
7740 EXPECT_GL_NO_ERROR();
7741
7742 drawQuad(mProgram, "position", 0.5f);
7743
7744 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7745 }
7746
7747 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7748 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBXImplicitAlpha1)7749 TEST_P(Texture2DTestES3, TextureRGBXImplicitAlpha1)
7750 {
7751 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
7752
7753 GLTexture texture2D;
7754 glBindTexture(GL_TEXTURE_2D, texture2D);
7755 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBX8_ANGLE, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
7756 glActiveTexture(GL_TEXTURE0);
7757 EXPECT_GL_NO_ERROR();
7758
7759 drawQuad(mProgram, "position", 0.5f);
7760
7761 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7762 }
7763
7764 // Test that data upload to RGBX works.
TEST_P(Texture2DTestES3,TextureRGBXUpload)7765 TEST_P(Texture2DTestES3, TextureRGBXUpload)
7766 {
7767 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
7768
7769 const size_t kWidth = 32;
7770 const size_t kHeight = 32;
7771
7772 GLTexture color;
7773 glBindTexture(GL_TEXTURE_2D, color);
7774 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
7775
7776 GLFramebuffer fbo;
7777 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7778 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
7779 ASSERT_GL_NO_ERROR();
7780 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
7781
7782 // Upload data to an RGBX texture
7783 const GLColorRGB kColor(100, 200, 55);
7784 std::vector<GLColorRGB> data(kWidth * kHeight, kColor);
7785
7786 GLTexture texture;
7787 glBindTexture(GL_TEXTURE_2D, texture);
7788 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBX8_ANGLE, kWidth, kHeight);
7789 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7791 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, data.data());
7792 ASSERT_GL_NO_ERROR();
7793
7794 // Sample from the texture
7795 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
7796 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
7797
7798 const GLColor kExpect(kColor.R, kColor.G, kColor.B, 255);
7799 EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpect, 1);
7800 EXPECT_PIXEL_COLOR_NEAR(0, 1, kExpect, 1);
7801 EXPECT_PIXEL_COLOR_NEAR(1, 0, kExpect, 1);
7802 EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, 0, kExpect, 1);
7803 EXPECT_PIXEL_COLOR_NEAR(0, kHeight - 1, kExpect, 1);
7804 EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, kHeight - 1, kExpect, 1);
7805 EXPECT_PIXEL_COLOR_NEAR(kWidth / 2, kHeight / 2, kExpect, 1);
7806 ASSERT_GL_NO_ERROR();
7807 }
7808
7809 // Test that data download from RGBX works.
TEST_P(Texture2DTestES3,TextureRGBXDownload)7810 TEST_P(Texture2DTestES3, TextureRGBXDownload)
7811 {
7812 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
7813
7814 const size_t kWidth = 32;
7815 const size_t kHeight = 32;
7816
7817 GLTexture color;
7818 glBindTexture(GL_TEXTURE_2D, color);
7819 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBX8_ANGLE, kWidth, kHeight);
7820
7821 GLFramebuffer fbo;
7822 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7823 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
7824 ASSERT_GL_NO_ERROR();
7825 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
7826
7827 // Render to the RGBX texture
7828 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
7829 glUseProgram(program);
7830 GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
7831 ASSERT_NE(colorLoc, -1);
7832
7833 glUniform4f(colorLoc, 0.3f, 0.6f, 0.8f, 0.2f);
7834 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
7835 ASSERT_GL_NO_ERROR();
7836
7837 // Readback as RGBX.
7838 std::vector<GLColor> readback(kWidth * kHeight);
7839 glReadPixels(0, 0, kWidth, kHeight, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, readback.data());
7840 ASSERT_GL_NO_ERROR();
7841
7842 const GLColor kExpect(76, // 0.3f * 255
7843 153, // 0.6f * 255
7844 204, // 0.8f * 255
7845 255);
7846
7847 for (size_t y = 0; y < kHeight; y++)
7848 {
7849 for (size_t x = 0; x < kWidth; x++)
7850 {
7851 const GLColor actualColor = readback[y * kWidth + x];
7852
7853 EXPECT_NEAR(actualColor.R, kExpect.R, 1) << x << "x" << y;
7854 EXPECT_NEAR(actualColor.G, kExpect.G, 1) << x << "x" << y;
7855 EXPECT_NEAR(actualColor.B, kExpect.B, 1) << x << "x" << y;
7856 EXPECT_EQ(actualColor.A, kExpect.A) << x << "x" << y;
7857 }
7858 }
7859 ASSERT_GL_NO_ERROR();
7860 }
7861
7862 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7863 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminanceImplicitAlpha1)7864 TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
7865 {
7866 setUpProgram();
7867
7868 glActiveTexture(GL_TEXTURE0);
7869 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7870 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
7871 EXPECT_GL_NO_ERROR();
7872
7873 drawQuad(mProgram, "position", 0.5f);
7874
7875 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7876 }
7877
7878 // Validate that every component of the pixel will be equal to the luminance value we've set
7879 // and that the alpha channel will be 1 (or 255 to be exact).
TEST_P(Texture2DTest,TextureLuminanceRGBSame)7880 TEST_P(Texture2DTest, TextureLuminanceRGBSame)
7881 {
7882 setUpProgram();
7883
7884 glActiveTexture(GL_TEXTURE0);
7885 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7886 uint8_t pixel = 50;
7887 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
7888 EXPECT_GL_NO_ERROR();
7889
7890 drawQuad(mProgram, "position", 0.5f);
7891
7892 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
7893 }
7894
7895 // Validate that every component of the pixel will be equal to the luminance value we've set
7896 // and that the alpha channel will be the second component.
TEST_P(Texture2DTest,TextureLuminanceAlphaRGBSame)7897 TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
7898 {
7899 setUpProgram();
7900
7901 glActiveTexture(GL_TEXTURE0);
7902 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7903 uint8_t pixel[] = {50, 25};
7904 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
7905 GL_UNSIGNED_BYTE, pixel);
7906 EXPECT_GL_NO_ERROR();
7907
7908 drawQuad(mProgram, "position", 0.5f);
7909
7910 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
7911 }
7912
7913 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7914 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance32ImplicitAlpha1)7915 TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
7916 {
7917 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7918 ANGLE_SKIP_TEST_IF(IsD3D9());
7919 ANGLE_SKIP_TEST_IF(IsVulkan());
7920
7921 setUpProgram();
7922
7923 glActiveTexture(GL_TEXTURE0);
7924 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7925 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
7926 EXPECT_GL_NO_ERROR();
7927
7928 drawQuad(mProgram, "position", 0.5f);
7929
7930 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7931 }
7932
7933 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7934 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance16ImplicitAlpha1)7935 TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
7936 {
7937 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7938 ANGLE_SKIP_TEST_IF(IsD3D9());
7939 ANGLE_SKIP_TEST_IF(IsVulkan());
7940 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/42260416 is fixed
7941 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
7942
7943 setUpProgram();
7944
7945 glActiveTexture(GL_TEXTURE0);
7946 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7947 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
7948 EXPECT_GL_NO_ERROR();
7949
7950 drawQuad(mProgram, "position", 0.5f);
7951
7952 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7953 }
7954
7955 // Test that CopyTexImage2D does not trigger assertion after CompressedTexImage2D.
7956 // https://crbug.com/1216276
TEST_P(Texture2DTest,CopyAfterCompressed)7957 TEST_P(Texture2DTest, CopyAfterCompressed)
7958 {
7959 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
7960
7961 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7962 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 0, 8, nullptr);
7963 EXPECT_GL_NO_ERROR();
7964
7965 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 0, 0, 4, 4, 0);
7966 EXPECT_GL_NO_ERROR();
7967 }
7968
7969 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7970 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB8UIImplicitAlpha1)7971 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
7972 {
7973 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
7974
7975 glActiveTexture(GL_TEXTURE0);
7976 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7977 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
7978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7979 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7980 EXPECT_GL_NO_ERROR();
7981
7982 drawQuad(mProgram, "position", 0.5f);
7983
7984 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
7985 }
7986
7987 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
7988 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB8IImplicitAlpha1)7989 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
7990 {
7991 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
7992
7993 glActiveTexture(GL_TEXTURE0);
7994 glBindTexture(GL_TEXTURE_2D, mTexture2D);
7995
7996 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
7997 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7998 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7999 EXPECT_GL_NO_ERROR();
8000
8001 drawQuad(mProgram, "position", 0.5f);
8002
8003 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8004 }
8005
8006 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8007 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB16UIImplicitAlpha1)8008 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
8009 {
8010 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8011
8012 glActiveTexture(GL_TEXTURE0);
8013 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8014 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
8015 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8016 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8017 EXPECT_GL_NO_ERROR();
8018
8019 drawQuad(mProgram, "position", 0.5f);
8020
8021 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8022 }
8023
8024 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8025 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB16IImplicitAlpha1)8026 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
8027 {
8028 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8029
8030 glActiveTexture(GL_TEXTURE0);
8031 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8032 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
8033 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8034 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8035 EXPECT_GL_NO_ERROR();
8036
8037 drawQuad(mProgram, "position", 0.5f);
8038
8039 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8040 }
8041
8042 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8043 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB32UIImplicitAlpha1)8044 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
8045 {
8046 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8047
8048 glActiveTexture(GL_TEXTURE0);
8049 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8050 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
8051 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8052 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8053 EXPECT_GL_NO_ERROR();
8054
8055 drawQuad(mProgram, "position", 0.5f);
8056
8057 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8058 }
8059
8060 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8061 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB32IImplicitAlpha1)8062 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
8063 {
8064 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
8065
8066 glActiveTexture(GL_TEXTURE0);
8067 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8068 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
8069 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8070 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8071 EXPECT_GL_NO_ERROR();
8072
8073 drawQuad(mProgram, "position", 0.5f);
8074
8075 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8076 }
8077
8078 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8079 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBSNORMImplicitAlpha1)8080 TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
8081 {
8082 glActiveTexture(GL_TEXTURE0);
8083 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8084 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
8085 EXPECT_GL_NO_ERROR();
8086
8087 drawQuad(mProgram, "position", 0.5f);
8088
8089 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8090 }
8091
8092 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8093 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGB9E5ImplicitAlpha1)8094 TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
8095 {
8096 glActiveTexture(GL_TEXTURE0);
8097 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8098 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
8099 nullptr);
8100 EXPECT_GL_NO_ERROR();
8101
8102 drawQuad(mProgram, "position", 0.5f);
8103
8104 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8105 }
8106
8107 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8108 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)8109 TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
8110 {
8111 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
8112 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
8113
8114 glActiveTexture(GL_TEXTURE0);
8115 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8116 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
8117 EXPECT_GL_NO_ERROR();
8118
8119 drawQuad(mProgram, "position", 0.5f);
8120
8121 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8122 }
8123
8124 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
8125 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)8126 TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
8127 {
8128 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
8129 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
8130
8131 glActiveTexture(GL_TEXTURE0);
8132 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8133 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
8134 EXPECT_GL_NO_ERROR();
8135
8136 drawQuad(mProgram, "position", 0.5f);
8137
8138 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8139 }
8140
8141 // ETC2 punchthrough alpha formats must be initialized to opaque black when emulated
8142 // http://anglebug.com/42265413
TEST_P(Texture2DTestES3RobustInit,TextureCOMPRESSEDRGB8A1ETC2)8143 TEST_P(Texture2DTestES3RobustInit, TextureCOMPRESSEDRGB8A1ETC2)
8144 {
8145 glActiveTexture(GL_TEXTURE0);
8146 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8147 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 1, 1, 0,
8148 8, nullptr);
8149 EXPECT_GL_NO_ERROR();
8150
8151 drawQuad(mProgram, "position", 0.5f);
8152
8153 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8154 }
8155
8156 // ETC2 punchthrough alpha formats must be initialized to opaque black when emulated
8157 // http://anglebug.com/42265413
TEST_P(Texture2DTestES3RobustInit,TextureCOMPRESSEDSRGB8A1ETC2)8158 TEST_P(Texture2DTestES3RobustInit, TextureCOMPRESSEDSRGB8A1ETC2)
8159 {
8160 glActiveTexture(GL_TEXTURE0);
8161 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8162 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 1, 1, 0,
8163 8, nullptr);
8164 EXPECT_GL_NO_ERROR();
8165
8166 drawQuad(mProgram, "position", 0.5f);
8167
8168 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
8169 }
8170
8171 // Test that compressed textures ignore the pixel unpack state.
8172 // (https://crbug.org/1267496)
TEST_P(Texture2DTestES3,PixelUnpackStateTexImage)8173 TEST_P(Texture2DTestES3, PixelUnpackStateTexImage)
8174 {
8175 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
8176 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
8177
8178 glPixelStorei(GL_UNPACK_ROW_LENGTH, 9);
8179 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8180
8181 uint8_t data[64] = {0};
8182 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 8, 8, 0, 64, data);
8183 EXPECT_GL_NO_ERROR();
8184 }
8185
8186 // Test that compressed textures ignore the pixel unpack state.
8187 // (https://crbug.org/1267496)
TEST_P(Texture2DTestES3,PixelUnpackStateTexSubImage)8188 TEST_P(Texture2DTestES3, PixelUnpackStateTexSubImage)
8189 {
8190 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
8191 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
8192
8193 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8194
8195 uint8_t data[64] = {0};
8196 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 8, 8, 0, 64, data);
8197 EXPECT_GL_NO_ERROR();
8198
8199 glPixelStorei(GL_UNPACK_ROW_LENGTH, 9);
8200
8201 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 64,
8202 data);
8203 EXPECT_GL_NO_ERROR();
8204 }
8205
8206 // Test for http://anglebug.com/42265405.
TEST_P(Texture2DTestES3,TextureRGBUpdateWithPBO)8207 TEST_P(Texture2DTestES3, TextureRGBUpdateWithPBO)
8208 {
8209 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
8210
8211 glViewport(0, 0, 16, 16);
8212
8213 GLTexture tex1;
8214 std::vector<GLColor> texDataRed(16u * 16u, GLColor::red);
8215 std::vector<GLColor> texDataGreen(16u * 16u, GLColor::green);
8216
8217 glBindTexture(GL_TEXTURE_2D, tex1);
8218 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
8219 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, texDataRed.data());
8220 ASSERT_GL_NO_ERROR();
8221
8222 GLBuffer pbo;
8223 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
8224 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, texDataGreen.data(), GL_STATIC_DRAW);
8225 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
8226 ASSERT_GL_NO_ERROR();
8227
8228 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8229 ASSERT_GL_NO_ERROR();
8230
8231 glBindTexture(GL_TEXTURE_2D, 0);
8232 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
8233 EXPECT_PIXEL_COLOR_EQ(4, 4, GLColor::green);
8234 }
8235
8236 // Copied from Texture2DTest::TexStorage
8237 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
8238 // default color.
TEST_P(Texture2DTestES31PPO,TexStorage)8239 TEST_P(Texture2DTestES31PPO, TexStorage)
8240 {
8241 ANGLE_SKIP_TEST_IF(!IsVulkan());
8242 ANGLE_SKIP_TEST_IF((getClientMajorVersion() < 3 && getClientMinorVersion() < 1) &&
8243 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
8244
8245 const char *vertexShaderSource = getVertexShaderSource();
8246 const char *fragmentShaderSource = getFragmentShaderSource();
8247
8248 bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
8249 mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
8250
8251 int width = getWindowWidth();
8252 int height = getWindowHeight();
8253
8254 GLTexture tex2D;
8255 glActiveTexture(GL_TEXTURE0);
8256 glBindTexture(GL_TEXTURE_2D, tex2D);
8257
8258 // Fill with red
8259 std::vector<GLubyte> pixels(3 * 16 * 16);
8260 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
8261 {
8262 pixels[pixelId * 3 + 0] = 255;
8263 pixels[pixelId * 3 + 1] = 0;
8264 pixels[pixelId * 3 + 2] = 0;
8265 }
8266
8267 // ANGLE internally uses RGBA as the internal format for RGB images, therefore glTexStorage2DEXT
8268 // initializes the image to a default color to get a consistent alpha color. The data is kept in
8269 // a CPU-side image and the image is marked as dirty.
8270 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
8271
8272 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
8273 // glTexSubImage2D should take into account that the image is dirty.
8274 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
8275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8277
8278 glActiveShaderProgram(mPipeline, mFragProg);
8279 glUniform1i(mTexture2DUniformLocation, 0);
8280
8281 std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
8282 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8283
8284 EXPECT_GL_NO_ERROR();
8285 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
8286
8287 // Validate that the region of the texture without data has an alpha of 1.0
8288 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
8289 EXPECT_EQ(255, pixel.A);
8290 }
8291
8292 // Copied from Texture2DTestES3::SingleTextureMultipleSamplers
8293 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES31PPO,SingleTextureMultipleSamplers)8294 TEST_P(Texture2DTestES31PPO, SingleTextureMultipleSamplers)
8295 {
8296 ANGLE_SKIP_TEST_IF(!IsVulkan());
8297
8298 const char *vertexShaderSource = getVertexShaderSource();
8299 const char *fragmentShaderSource = getFragmentShaderSource();
8300
8301 bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
8302 mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
8303
8304 GLint maxTextureUnits = 0;
8305 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
8306 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
8307
8308 constexpr int kSize = 16;
8309 std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
8310
8311 // Make a single-level texture, fill it with red.
8312 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
8313 GLTexture tex;
8314 glBindTexture(GL_TEXTURE_2D, tex);
8315 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8316 redColors.data());
8317 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8318 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8319
8320 // Simple confidence check.
8321 bind2DTexturedQuadProgramPipeline();
8322 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8323 ASSERT_GL_NO_ERROR();
8324 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
8325
8326 // Bind texture to unit 1 with a sampler object making it incomplete.
8327 GLSampler sampler;
8328 glBindSampler(0, sampler);
8329 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8330 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8331
8332 // Make a mipmap texture, fill it with blue.
8333 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
8334 GLTexture mipmapTex;
8335 glBindTexture(GL_TEXTURE_2D, mipmapTex);
8336 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8337 blueColors.data());
8338 glGenerateMipmap(GL_TEXTURE_2D);
8339
8340 // Draw with the sampler, expect blue.
8341 draw2DTexturedQuad(0.5f, 1.0f, true);
8342 ASSERT_GL_NO_ERROR();
8343 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
8344
8345 // Simple multitexturing program.
8346 constexpr char kVS[] =
8347 "#version 310 es\n"
8348 "precision mediump float;\n"
8349 "in vec2 position;\n"
8350 "out vec2 texCoord;\n"
8351 "void main()\n"
8352 "{\n"
8353 " gl_Position = vec4(position, 0, 1);\n"
8354 " texCoord = position * 0.5 + vec2(0.5);\n"
8355 "}";
8356
8357 constexpr char kFS[] =
8358 "#version 310 es\n"
8359 "precision mediump float;\n"
8360 "in vec2 texCoord;\n"
8361 "uniform sampler2D tex1;\n"
8362 "uniform sampler2D tex2;\n"
8363 "uniform sampler2D tex3;\n"
8364 "uniform sampler2D tex4;\n"
8365 "out vec4 color;\n"
8366 "void main()\n"
8367 "{\n"
8368 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
8369 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
8370 "}";
8371
8372 bindProgramPipeline(kVS, kFS);
8373
8374 std::array<GLint, 4> texLocations = {
8375 {glGetUniformLocation(mFragProg, "tex1"), glGetUniformLocation(mFragProg, "tex2"),
8376 glGetUniformLocation(mFragProg, "tex3"), glGetUniformLocation(mFragProg, "tex4")}};
8377 for (GLint location : texLocations)
8378 {
8379 ASSERT_NE(-1, location);
8380 }
8381
8382 // Init the uniform data.
8383 glActiveShaderProgram(mPipeline, mFragProg);
8384 for (GLint location = 0; location < 4; ++location)
8385 {
8386 glUniform1i(texLocations[location], location);
8387 }
8388
8389 // Initialize four samplers
8390 GLSampler samplers[4];
8391
8392 // 0: non-mipped.
8393 glBindSampler(0, samplers[0]);
8394 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8395 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8396
8397 // 1: mipped.
8398 glBindSampler(1, samplers[1]);
8399 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8400 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8401
8402 // 2: non-mipped.
8403 glBindSampler(2, samplers[2]);
8404 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8405 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8406
8407 // 3: mipped.
8408 glBindSampler(3, samplers[3]);
8409 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8410 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8411
8412 // Bind two blue mipped textures and two single layer textures, should all draw.
8413 glActiveTexture(GL_TEXTURE0);
8414 glBindTexture(GL_TEXTURE_2D, tex);
8415
8416 glActiveTexture(GL_TEXTURE1);
8417 glBindTexture(GL_TEXTURE_2D, mipmapTex);
8418
8419 glActiveTexture(GL_TEXTURE2);
8420 glBindTexture(GL_TEXTURE_2D, tex);
8421
8422 glActiveTexture(GL_TEXTURE3);
8423 glBindTexture(GL_TEXTURE_2D, mipmapTex);
8424
8425 ASSERT_GL_NO_ERROR();
8426
8427 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8428 ASSERT_GL_NO_ERROR();
8429 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
8430
8431 // Bind four single layer textures, two should be incomplete.
8432 glActiveTexture(GL_TEXTURE1);
8433 glBindTexture(GL_TEXTURE_2D, tex);
8434
8435 glActiveTexture(GL_TEXTURE3);
8436 glBindTexture(GL_TEXTURE_2D, tex);
8437
8438 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
8439 ASSERT_GL_NO_ERROR();
8440 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
8441 }
8442
8443 // Use a sampler in a uniform struct.
TEST_P(SamplerInStructTest,SamplerInStruct)8444 TEST_P(SamplerInStructTest, SamplerInStruct)
8445 {
8446 runSamplerInStructTest();
8447 }
8448
8449 // Use a sampler in a uniform struct that's passed as a function parameter.
TEST_P(SamplerInStructAsFunctionParameterTest,SamplerInStructAsFunctionParameter)8450 TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
8451 {
8452 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/42260422
8453 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
8454
8455 runSamplerInStructTest();
8456 }
8457
8458 // Use a sampler in a uniform struct array with a struct from the array passed as a function
8459 // parameter.
TEST_P(SamplerInStructArrayAsFunctionParameterTest,SamplerInStructArrayAsFunctionParameter)8460 TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
8461 {
8462 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/42260422
8463 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
8464
8465 runSamplerInStructTest();
8466 }
8467
8468 // Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
8469 // parameter.
TEST_P(SamplerInNestedStructAsFunctionParameterTest,SamplerInNestedStructAsFunctionParameter)8470 TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
8471 {
8472 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/42260422
8473 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
8474
8475 runSamplerInStructTest();
8476 }
8477
8478 // Make sure that there isn't a name conflict between sampler extracted from a struct and a
8479 // similarly named uniform.
TEST_P(SamplerInStructAndOtherVariableTest,SamplerInStructAndOtherVariable)8480 TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
8481 {
8482 runSamplerInStructTest();
8483 }
8484
8485 // GL_EXT_texture_filter_anisotropic
8486 class TextureAnisotropyTest : public Texture2DTest
8487 {
8488 protected:
uploadTexture()8489 void uploadTexture()
8490 {
8491 glActiveTexture(GL_TEXTURE0);
8492 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8493 GLColor texDataRed[1] = {GLColor::red};
8494 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
8495 EXPECT_GL_NO_ERROR();
8496 }
8497 };
8498
8499 // Tests that setting anisotropic filtering doesn't cause failures at draw time.
TEST_P(TextureAnisotropyTest,AnisotropyFunctional)8500 TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
8501 {
8502 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
8503
8504 setUpProgram();
8505
8506 uploadTexture();
8507
8508 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8509 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8510 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
8511 EXPECT_GL_NO_ERROR();
8512
8513 drawQuad(mProgram, "position", 0.5f);
8514
8515 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8516 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
8517 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
8518 }
8519
8520 // GL_OES_texture_border_clamp
8521 class TextureBorderClampTest : public Texture2DTest
8522 {
8523 protected:
TextureBorderClampTest()8524 TextureBorderClampTest() : Texture2DTest() {}
8525
getVertexShaderSource()8526 const char *getVertexShaderSource() override
8527 {
8528 return
8529 R"(precision highp float;
8530 attribute vec4 position;
8531 varying vec2 texcoord;
8532
8533 void main()
8534 {
8535 gl_Position = vec4(position.xy, 0.0, 1.0);
8536 // texcoords in [-0.5, 1.5]
8537 texcoord = (position.xy) + 0.5;
8538 })";
8539 }
8540
uploadTexture()8541 void uploadTexture()
8542 {
8543 glActiveTexture(GL_TEXTURE0);
8544 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8545 std::vector<GLColor> texDataRed(1, GLColor::red);
8546 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8547 texDataRed.data());
8548 EXPECT_GL_NO_ERROR();
8549 }
8550
testFormat(GLenum format,GLenum type,GLColor32F borderColor)8551 void testFormat(GLenum format, GLenum type, GLColor32F borderColor)
8552 {
8553 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8554 glActiveTexture(GL_TEXTURE0);
8555 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor.R);
8556 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8557 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8558 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8559 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8560 glTexImage2D(GL_TEXTURE_2D, 0, format, 2, 2, 0, format, type, nullptr);
8561 drawQuad(mProgram, "position", 0.5f);
8562 }
8563
testCompressedFormat(GLenum format,GLsizei size,GLColor32F borderColor)8564 void testCompressedFormat(GLenum format, GLsizei size, GLColor32F borderColor)
8565 {
8566 setUpProgram();
8567 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8568 glActiveTexture(GL_TEXTURE0);
8569 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor.R);
8570 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8572 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8573 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8574 glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, 4, 4, 0, size, nullptr);
8575 drawQuad(mProgram, "position", 0.5f);
8576 }
8577 };
8578
8579 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
8580 // GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional)8581 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
8582 {
8583 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8584
8585 setUpProgram();
8586
8587 uploadTexture();
8588
8589 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8590 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8591 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8592 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8593 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8594 EXPECT_GL_NO_ERROR();
8595
8596 drawQuad(mProgram, "position", 0.5f);
8597
8598 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8599 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8600 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
8601 }
8602
8603 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional2)8604 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
8605 {
8606 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8607
8608 glActiveTexture(GL_TEXTURE0);
8609 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8610
8611 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8612
8613 GLint colorFixedPoint[4] = {0};
8614 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
8615 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
8616 std::numeric_limits<GLint>::max()};
8617 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
8618 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
8619 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
8620 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
8621
8622 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
8623 std::numeric_limits<GLint>::max()};
8624 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
8625
8626 GLfloat color[4] = {0.0f};
8627 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
8628 EXPECT_EQ(color[0], kFloatBlue.R);
8629 EXPECT_EQ(color[1], kFloatBlue.G);
8630 EXPECT_EQ(color[2], kFloatBlue.B);
8631 EXPECT_EQ(color[3], kFloatBlue.A);
8632 }
8633
8634 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampValidation)8635 TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
8636 {
8637 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8638
8639 glActiveTexture(GL_TEXTURE0);
8640 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8641
8642 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
8643 EXPECT_GL_ERROR(GL_INVALID_ENUM);
8644
8645 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
8646 EXPECT_GL_ERROR(GL_INVALID_ENUM);
8647
8648 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8649 EXPECT_GL_ERROR(GL_INVALID_ENUM);
8650
8651 GLint colorInt[4] = {0};
8652 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
8653 EXPECT_GL_ERROR(GL_INVALID_ENUM);
8654
8655 if (getClientMajorVersion() < 3)
8656 {
8657 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
8658 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8659 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
8660 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8661
8662 GLuint colorUInt[4] = {0};
8663 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
8664 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8665 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
8666 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8667
8668 GLSampler sampler;
8669 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
8670 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8671 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
8672 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8673
8674 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
8675 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8676 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
8677 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8678 }
8679 }
8680
8681 // Test GL_TEXTURE_BORDER_COLOR parameter with unorm formats.
TEST_P(TextureBorderClampTest,TextureBorderClampUnorm8)8682 TEST_P(TextureBorderClampTest, TextureBorderClampUnorm8)
8683 {
8684 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8685
8686 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8687
8688 setUpProgram();
8689
8690 testFormat(GL_ALPHA, GL_UNSIGNED_BYTE, kBorder);
8691 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8692
8693 testFormat(GL_RGB, GL_UNSIGNED_BYTE, kBorder);
8694 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8695
8696 testFormat(GL_RGBA, GL_UNSIGNED_BYTE, kBorder);
8697 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8698
8699 testFormat(GL_LUMINANCE, GL_UNSIGNED_BYTE, kBorder);
8700 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 255), 1);
8701
8702 testFormat(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, kBorder);
8703 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8704 }
8705
8706 // Test GL_TEXTURE_BORDER_COLOR parameter with sRGB formats.
TEST_P(TextureBorderClampTest,TextureBorderClampSrgb)8707 TEST_P(TextureBorderClampTest, TextureBorderClampSrgb)
8708 {
8709 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8710 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB"));
8711
8712 // AMD D3D9 drivers always sample sRGB formats with (0, 0, 0, 0) border color, won't fix.
8713 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
8714
8715 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8716
8717 setUpProgram();
8718
8719 testFormat(GL_SRGB_EXT, GL_UNSIGNED_BYTE, kBorder);
8720 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8721
8722 testFormat(GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, kBorder);
8723 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8724 }
8725
8726 // Test GL_TEXTURE_BORDER_COLOR parameter with half-float formats.
TEST_P(TextureBorderClampTest,TextureBorderClampFloat16)8727 TEST_P(TextureBorderClampTest, TextureBorderClampFloat16)
8728 {
8729 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8730 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
8731
8732 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8733
8734 setUpProgram();
8735
8736 testFormat(GL_ALPHA, GL_HALF_FLOAT_OES, kBorder);
8737 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8738
8739 testFormat(GL_RGB, GL_HALF_FLOAT_OES, kBorder);
8740 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8741
8742 testFormat(GL_RGBA, GL_HALF_FLOAT_OES, kBorder);
8743 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8744
8745 testFormat(GL_LUMINANCE, GL_HALF_FLOAT_OES, kBorder);
8746 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 255), 1);
8747
8748 testFormat(GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, kBorder);
8749 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8750 }
8751
8752 // Test GL_TEXTURE_BORDER_COLOR parameter with float formats.
TEST_P(TextureBorderClampTest,TextureBorderClampFloat32)8753 TEST_P(TextureBorderClampTest, TextureBorderClampFloat32)
8754 {
8755 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8756 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
8757
8758 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8759
8760 setUpProgram();
8761
8762 testFormat(GL_ALPHA, GL_FLOAT, kBorder);
8763 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8764
8765 testFormat(GL_RGB, GL_FLOAT, kBorder);
8766 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8767
8768 testFormat(GL_RGBA, GL_FLOAT, kBorder);
8769 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8770
8771 testFormat(GL_LUMINANCE, GL_FLOAT, kBorder);
8772 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 255), 1);
8773
8774 testFormat(GL_LUMINANCE_ALPHA, GL_FLOAT, kBorder);
8775 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8776 }
8777
8778 // Test GL_TEXTURE_BORDER_COLOR parameter with red and red-green formats.
TEST_P(TextureBorderClampTest,TextureBorderClampRG)8779 TEST_P(TextureBorderClampTest, TextureBorderClampRG)
8780 {
8781 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8782 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
8783
8784 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8785
8786 setUpProgram();
8787
8788 testFormat(GL_RED_EXT, GL_UNSIGNED_BYTE, kBorder);
8789 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
8790
8791 testFormat(GL_RG_EXT, GL_UNSIGNED_BYTE, kBorder);
8792 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 0, 255), 1);
8793
8794 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
8795 {
8796 testFormat(GL_RED_EXT, GL_HALF_FLOAT_OES, kBorder);
8797 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
8798
8799 testFormat(GL_RG_EXT, GL_HALF_FLOAT_OES, kBorder);
8800 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 0, 255), 1);
8801 }
8802
8803 if (IsGLExtensionEnabled("GL_OES_texture_float"))
8804 {
8805 testFormat(GL_RED_EXT, GL_FLOAT, kBorder);
8806 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 0, 0, 255), 1);
8807
8808 testFormat(GL_RG_EXT, GL_FLOAT, kBorder);
8809 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 0, 255), 1);
8810 }
8811 }
8812
8813 // Test GL_TEXTURE_BORDER_COLOR parameter with DXT1 formats.
TEST_P(TextureBorderClampTest,TextureBorderClampDXT1)8814 TEST_P(TextureBorderClampTest, TextureBorderClampDXT1)
8815 {
8816 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8817 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
8818
8819 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8820
8821 setUpProgram();
8822
8823 testCompressedFormat(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, kBorder);
8824 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8825
8826 testCompressedFormat(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, kBorder);
8827 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8828 }
8829
8830 // Test GL_TEXTURE_BORDER_COLOR parameter with DXT1 sRGB formats.
TEST_P(TextureBorderClampTest,TextureBorderClampDXT1Srgb)8831 TEST_P(TextureBorderClampTest, TextureBorderClampDXT1Srgb)
8832 {
8833 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8834 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc_srgb"));
8835
8836 // AMD D3D9 drivers always sample sRGB formats with (0, 0, 0, 0) border color, won't fix.
8837 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
8838
8839 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8840
8841 setUpProgram();
8842
8843 testCompressedFormat(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 8, kBorder);
8844 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 255), 1);
8845
8846 testCompressedFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 8, kBorder);
8847 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8848 }
8849
8850 // Test GL_TEXTURE_BORDER_COLOR parameter with texture redefinition.
TEST_P(TextureBorderClampTest,Redefinition)8851 TEST_P(TextureBorderClampTest, Redefinition)
8852 {
8853 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8854
8855 GLColor32F kBorder = {0.5f, 0.25f, 0.125f, 0.0625f};
8856
8857 setUpProgram();
8858
8859 testFormat(GL_ALPHA, GL_UNSIGNED_BYTE, kBorder);
8860 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 16), 1);
8861
8862 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 2, 2, 0, GL_LUMINANCE_ALPHA,
8863 GL_UNSIGNED_BYTE, nullptr);
8864 drawQuad(mProgram, "position", 0.5f);
8865 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 128, 128, 16), 1);
8866
8867 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8868 drawQuad(mProgram, "position", 0.5f);
8869 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(128, 64, 32, 16), 1);
8870 }
8871
8872 class TextureBorderClampTestES3 : public TextureBorderClampTest
8873 {
8874 protected:
TextureBorderClampTestES3()8875 TextureBorderClampTestES3() : TextureBorderClampTest() {}
8876 };
8877
8878 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
8879 // GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional)8880 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
8881 {
8882 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8883
8884 setUpProgram();
8885
8886 uploadTexture();
8887
8888 GLSampler sampler;
8889 glBindSampler(0, sampler);
8890 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8891 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
8892 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8893 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8894 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8895 EXPECT_GL_NO_ERROR();
8896
8897 drawQuad(mProgram, "position", 0.5f);
8898
8899 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
8900 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8901 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
8902 }
8903
8904 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional2)8905 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
8906 {
8907 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8908
8909 glActiveTexture(GL_TEXTURE0);
8910
8911 GLSampler sampler;
8912 glBindSampler(0, sampler);
8913
8914 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
8915
8916 GLint colorFixedPoint[4] = {0};
8917 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
8918 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
8919 std::numeric_limits<GLint>::max()};
8920 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
8921 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
8922 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
8923 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
8924
8925 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
8926 std::numeric_limits<GLint>::max()};
8927 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
8928
8929 GLfloat color[4] = {0.0f};
8930 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
8931 EXPECT_EQ(color[0], kFloatBlue.R);
8932 EXPECT_EQ(color[1], kFloatBlue.G);
8933 EXPECT_EQ(color[2], kFloatBlue.B);
8934 EXPECT_EQ(color[3], kFloatBlue.A);
8935
8936 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
8937 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
8938 GLint colorInt[4] = {0};
8939 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
8940 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
8941 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
8942 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
8943 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
8944
8945 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
8946 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
8947 GLuint colorUInt[4] = {0};
8948 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
8949 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
8950 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
8951 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
8952 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
8953
8954 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8955
8956 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
8957 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
8958 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
8959 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
8960 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
8961 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
8962 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
8963
8964 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
8965 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
8966 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
8967 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
8968 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
8969 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
8970 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
8971 }
8972
8973 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Validation)8974 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
8975 {
8976 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8977
8978 glActiveTexture(GL_TEXTURE0);
8979
8980 GLSampler sampler;
8981 glBindSampler(0, sampler);
8982
8983 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
8984 EXPECT_GL_ERROR(GL_INVALID_ENUM);
8985
8986 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
8987 EXPECT_GL_ERROR(GL_INVALID_ENUM);
8988 }
8989
8990 // Test that format-specific adjustments are applied
8991 // when the border color type does not match the texture type.
TEST_P(TextureBorderClampTestES3,TextureBorderTypeMismatch)8992 TEST_P(TextureBorderClampTestES3, TextureBorderTypeMismatch)
8993 {
8994 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
8995
8996 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8997 glActiveTexture(GL_TEXTURE0);
8998 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
8999 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9000 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9001 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9002
9003 GLColor32UI kBorder = {1, 2, 3, 0};
9004 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kBorder.R);
9005 ASSERT_GL_NO_ERROR();
9006
9007 setUpProgram();
9008
9009 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
9010 drawQuad(mProgram, "position", 0.5f);
9011 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
9012 }
9013
9014 class TextureBorderClampIntegerTestES3 : public Texture2DTest
9015 {
9016 protected:
TextureBorderClampIntegerTestES3()9017 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
9018
getVertexShaderSource()9019 const char *getVertexShaderSource() override
9020 {
9021 return
9022 R"(#version 300 es
9023 out vec2 texcoord;
9024 in vec4 position;
9025
9026 void main()
9027 {
9028 gl_Position = vec4(position.xy, 0.0, 1.0);
9029 // texcoords in [-0.5, 1.5]
9030 texcoord = (position.xy) + 0.5;
9031 })";
9032 }
9033
getFragmentShaderSource()9034 const char *getFragmentShaderSource() override
9035 {
9036 if (isUnsignedIntTest)
9037 {
9038 return "#version 300 es\n"
9039 "precision highp float;\n"
9040 "uniform highp usampler2D tex;\n"
9041 "in vec2 texcoord;\n"
9042 "out vec4 fragColor;\n"
9043
9044 "void main()\n"
9045 "{\n"
9046 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
9047 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
9048 "fragColor = (texture(tex, texcoord).r == 150u)"
9049 " ? green : red;\n"
9050 "}\n";
9051 }
9052 else
9053 {
9054 return "#version 300 es\n"
9055 "precision highp float;\n"
9056 "uniform highp isampler2D tex;\n"
9057 "in vec2 texcoord;\n"
9058 "out vec4 fragColor;\n"
9059
9060 "void main()\n"
9061 "{\n"
9062 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
9063 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
9064 "fragColor = (texture(tex, texcoord).r == -50)"
9065 " ? green : red;\n"
9066 "}\n";
9067 }
9068 }
9069
uploadTexture()9070 void uploadTexture()
9071 {
9072 glActiveTexture(GL_TEXTURE0);
9073 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9074 if (isUnsignedIntTest)
9075 {
9076 std::vector<GLubyte> texData(4, 100);
9077 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
9078 texData.data());
9079 }
9080 else
9081 {
9082 std::vector<GLbyte> texData(4, 100);
9083 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
9084 texData.data());
9085 }
9086 EXPECT_GL_NO_ERROR();
9087 }
9088
9089 bool isUnsignedIntTest;
9090 };
9091
9092 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
9093 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger)9094 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
9095 {
9096 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/40096617
9097 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
9098
9099 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9100
9101 setUpProgram();
9102
9103 uploadTexture();
9104
9105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9109
9110 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
9111 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
9112
9113 EXPECT_GL_NO_ERROR();
9114
9115 drawQuad(mProgram, "position", 0.5f);
9116
9117 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9118 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9119 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9120 }
9121
9122 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
9123 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger2)9124 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
9125 {
9126 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/40096617
9127 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
9128
9129 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9130
9131 setUpProgram();
9132
9133 uploadTexture();
9134
9135 GLSampler sampler;
9136 glBindSampler(0, sampler);
9137 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9138 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9139 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9140 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9141
9142 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
9143 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
9144
9145 EXPECT_GL_NO_ERROR();
9146
9147 drawQuad(mProgram, "position", 0.5f);
9148
9149 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9150 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9151 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9152 }
9153
9154 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
9155 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned)9156 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
9157 {
9158 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9159
9160 isUnsignedIntTest = true;
9161
9162 setUpProgram();
9163
9164 uploadTexture();
9165
9166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9170
9171 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
9172 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
9173
9174 EXPECT_GL_NO_ERROR();
9175
9176 drawQuad(mProgram, "position", 0.5f);
9177
9178 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9179 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9180 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9181 }
9182
9183 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
9184 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
9185 // glSamplerParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned2)9186 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
9187 {
9188 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
9189
9190 isUnsignedIntTest = true;
9191
9192 setUpProgram();
9193
9194 uploadTexture();
9195
9196 GLSampler sampler;
9197 glBindSampler(0, sampler);
9198 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
9199 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
9200 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9201 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9202
9203 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
9204 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
9205
9206 EXPECT_GL_NO_ERROR();
9207
9208 drawQuad(mProgram, "position", 0.5f);
9209
9210 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9211 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9212 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
9213 }
9214
9215 // ~GL_OES_texture_border_clamp
9216
9217 // GL_EXT_texture_mirror_clamp_to_edge
9218 class TextureMirrorClampToEdgeTest : public Texture2DTest
9219 {
9220 protected:
TextureMirrorClampToEdgeTest()9221 TextureMirrorClampToEdgeTest() : Texture2DTest() {}
9222
getVertexShaderSource()9223 const char *getVertexShaderSource() override
9224 {
9225 return R"(precision highp float;
9226 attribute vec4 position;
9227 varying vec2 texcoord;
9228
9229 void main()
9230 {
9231 gl_Position = vec4(position.xy, 0.0, 1.0);
9232 texcoord = position.xy * 2.0;
9233 })";
9234 }
9235
uploadTexture(bool isInteger,bool isSigned,GLuint sampler)9236 void uploadTexture(bool isInteger, bool isSigned, GLuint sampler)
9237 {
9238 glActiveTexture(GL_TEXTURE0);
9239 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9240 if (isInteger && isSigned)
9241 {
9242 const int8_t data[] = {0, 0, 0, -1, -1, 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, -1};
9243 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 2, 2, 0, GL_RGBA_INTEGER, GL_BYTE, data);
9244 }
9245 else if (isInteger)
9246 {
9247 const uint8_t data[] = {0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1};
9248 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 2, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
9249 data);
9250 }
9251 else
9252 {
9253 const uint8_t data[] = {0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255};
9254 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
9255 }
9256
9257 if (sampler != 0)
9258 {
9259 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9260 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9261 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9262 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9263 }
9264 else
9265 {
9266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRROR_CLAMP_TO_EDGE_EXT);
9268 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9270 }
9271 ASSERT_GL_NO_ERROR();
9272 }
9273
checkTextureSampling()9274 void checkTextureSampling()
9275 {
9276 auto screenX = [&](float x) { return getWindowWidth() * (x * 0.25 + 0.5); };
9277 auto screenY = [&](float y) { return getWindowHeight() * (y * 0.25 + 0.5); };
9278
9279 // +S, +T
9280 EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(0.25), GLColor::black);
9281 EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(0.25), GLColor::red);
9282 EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(0.25), GLColor::red);
9283 EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(0.75), GLColor::green);
9284 EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(1.50), GLColor::green);
9285 EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(0.75), GLColor::blue);
9286 EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(0.75), GLColor::blue);
9287 EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(1.50), GLColor::blue);
9288 EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(1.50), GLColor::blue);
9289
9290 // -S, +T
9291 EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(0.25), GLColor::black);
9292 EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(0.25), GLColor::red);
9293 EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(0.25), GLColor::red);
9294 EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(0.75), GLColor::green);
9295 EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(1.50), GLColor::green);
9296 EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(0.75), GLColor::blue);
9297 EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(0.75), GLColor::blue);
9298 EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(1.50), GLColor::blue);
9299 EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(1.50), GLColor::blue);
9300
9301 // +S, -T
9302 EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(-0.25), GLColor::black);
9303 EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(-0.25), GLColor::red);
9304 EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(-0.25), GLColor::red);
9305 EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(-0.75), GLColor::green);
9306 EXPECT_PIXEL_COLOR_EQ(screenX(0.25), screenY(-1.50), GLColor::green);
9307 EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(-0.75), GLColor::blue);
9308 EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(-0.75), GLColor::blue);
9309 EXPECT_PIXEL_COLOR_EQ(screenX(0.75), screenY(-1.50), GLColor::blue);
9310 EXPECT_PIXEL_COLOR_EQ(screenX(1.50), screenY(-1.50), GLColor::blue);
9311
9312 // -S, -T
9313 EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(-0.25), GLColor::black);
9314 EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(-0.25), GLColor::red);
9315 EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(-0.25), GLColor::red);
9316 EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(-0.75), GLColor::green);
9317 EXPECT_PIXEL_COLOR_EQ(screenX(-0.25), screenY(-1.50), GLColor::green);
9318 EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(-0.75), GLColor::blue);
9319 EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(-0.75), GLColor::blue);
9320 EXPECT_PIXEL_COLOR_EQ(screenX(-0.75), screenY(-1.50), GLColor::blue);
9321 EXPECT_PIXEL_COLOR_EQ(screenX(-1.50), screenY(-1.50), GLColor::blue);
9322 }
9323 };
9324
9325 // Test that the texture is correctly mirrored in negative directions
9326 // and clamped to edge pixels outside of the normalized range.
TEST_P(TextureMirrorClampToEdgeTest,TexParameter)9327 TEST_P(TextureMirrorClampToEdgeTest, TexParameter)
9328 {
9329 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9330
9331 setUpProgram();
9332 uploadTexture(false, false, 0);
9333 drawQuad(mProgram, "position", 0.5f);
9334 ASSERT_GL_NO_ERROR();
9335
9336 checkTextureSampling();
9337 }
9338
9339 class TextureMirrorClampToEdgeTestES3 : public TextureMirrorClampToEdgeTest
9340 {
9341 protected:
TextureMirrorClampToEdgeTestES3()9342 TextureMirrorClampToEdgeTestES3() : TextureMirrorClampToEdgeTest() {}
9343 };
9344
9345 // Test that the texture is correctly mirrored in negative directions and clamped
9346 // to edge pixels outside of the normalized range with mode set via glSamplerParameter.
TEST_P(TextureMirrorClampToEdgeTestES3,SamplerParameter)9347 TEST_P(TextureMirrorClampToEdgeTestES3, SamplerParameter)
9348 {
9349 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9350
9351 GLSampler sampler;
9352 glBindSampler(0, sampler);
9353
9354 setUpProgram();
9355 uploadTexture(false, false, sampler);
9356 drawQuad(mProgram, "position", 0.5f);
9357 ASSERT_GL_NO_ERROR();
9358
9359 checkTextureSampling();
9360 }
9361
9362 class TextureMirrorClampToEdgeIntegerTestES3 : public TextureMirrorClampToEdgeTestES3
9363 {
9364 protected:
TextureMirrorClampToEdgeIntegerTestES3()9365 TextureMirrorClampToEdgeIntegerTestES3() : TextureMirrorClampToEdgeTestES3() {}
9366
getVertexShaderSource()9367 const char *getVertexShaderSource() override
9368 {
9369 return R"(#version 300 es
9370 precision highp float;
9371 in vec4 position;
9372 out vec2 texcoord;
9373
9374 void main()
9375 {
9376 gl_Position = vec4(position.xy, 0.0, 1.0);
9377 texcoord = position.xy * 2.0;
9378 })";
9379 }
9380
getFragmentShaderSource()9381 const char *getFragmentShaderSource() override
9382 {
9383 if (mIsSigned)
9384 {
9385 return R"(#version 300 es
9386 precision highp float;
9387 uniform highp isampler2D tex;
9388 in vec2 texcoord;
9389 out vec4 fragColor;
9390 void main() { fragColor = vec4(-texture(tex, texcoord)); })";
9391 }
9392 else
9393 {
9394 return R"(#version 300 es
9395 precision highp float;
9396 uniform highp usampler2D tex;
9397 in vec2 texcoord;
9398 out vec4 fragColor;
9399 void main() { fragColor = vec4(texture(tex, texcoord)); })";
9400 }
9401 }
9402
9403 bool mIsSigned = false;
9404 };
9405
9406 // Test that the texture is correctly mirrored in negative directions and clamped
9407 // to edge pixels outside of the normalized range with mode set with glTexParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,TexParameterSigned)9408 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, TexParameterSigned)
9409 {
9410 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9411
9412 mIsSigned = true;
9413 setUpProgram();
9414 uploadTexture(true, true, 0);
9415 drawQuad(mProgram, "position", 0.5f);
9416 ASSERT_GL_NO_ERROR();
9417
9418 checkTextureSampling();
9419 }
9420
9421 // Test that the texture is correctly mirrored in negative directions and clamped
9422 // to edge pixels outside of the normalized range with mode set with glSamplerParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,SamplerParameterSigned)9423 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, SamplerParameterSigned)
9424 {
9425 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9426
9427 GLSampler sampler;
9428 glBindSampler(0, sampler);
9429
9430 mIsSigned = true;
9431 setUpProgram();
9432 uploadTexture(true, true, sampler);
9433 drawQuad(mProgram, "position", 0.5f);
9434 ASSERT_GL_NO_ERROR();
9435
9436 checkTextureSampling();
9437 }
9438
9439 // Test that the unsigned integer texture is correctly mirrored in negative directions and clamped
9440 // to edge pixels outside of the normalized range with mode set with glTexParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,TexParameterUnsigned)9441 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, TexParameterUnsigned)
9442 {
9443 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9444
9445 setUpProgram();
9446 uploadTexture(true, false, 0);
9447 drawQuad(mProgram, "position", 0.5f);
9448 ASSERT_GL_NO_ERROR();
9449
9450 checkTextureSampling();
9451 }
9452
9453 // Test that the unsigned integer texture is correctly mirrored in negative directions and clamped
9454 // to edge pixels outside of the normalized range with mode set with glSamplerParameter.
TEST_P(TextureMirrorClampToEdgeIntegerTestES3,SamplerParameterUnsigned)9455 TEST_P(TextureMirrorClampToEdgeIntegerTestES3, SamplerParameterUnsigned)
9456 {
9457 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_mirror_clamp_to_edge"));
9458
9459 GLSampler sampler;
9460 glBindSampler(0, sampler);
9461
9462 setUpProgram();
9463 uploadTexture(true, false, sampler);
9464 drawQuad(mProgram, "position", 0.5f);
9465 ASSERT_GL_NO_ERROR();
9466
9467 checkTextureSampling();
9468 }
9469 // ~GL_EXT_texture_mirror_clamp_to_edge
9470
9471 class TextureLimitsTest : public ANGLETest<>
9472 {
9473 protected:
9474 struct RGBA8
9475 {
9476 uint8_t R, G, B, A;
9477 };
9478
TextureLimitsTest()9479 TextureLimitsTest()
9480 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
9481 {
9482 setWindowWidth(128);
9483 setWindowHeight(128);
9484 setConfigRedBits(8);
9485 setConfigGreenBits(8);
9486 setConfigBlueBits(8);
9487 setConfigAlphaBits(8);
9488 }
9489
testSetUp()9490 void testSetUp() override
9491 {
9492 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
9493 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
9494 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
9495
9496 ASSERT_GL_NO_ERROR();
9497 }
9498
testTearDown()9499 void testTearDown() override
9500 {
9501 if (mProgram != 0)
9502 {
9503 glDeleteProgram(mProgram);
9504 mProgram = 0;
9505
9506 if (!mTextures.empty())
9507 {
9508 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
9509 }
9510 }
9511 }
9512
compileProgramWithTextureCounts(const std::string & vertexPrefix,GLint vertexTextureCount,GLint vertexActiveTextureCount,const std::string & fragPrefix,GLint fragmentTextureCount,GLint fragmentActiveTextureCount)9513 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
9514 GLint vertexTextureCount,
9515 GLint vertexActiveTextureCount,
9516 const std::string &fragPrefix,
9517 GLint fragmentTextureCount,
9518 GLint fragmentActiveTextureCount)
9519 {
9520 std::stringstream vertexShaderStr;
9521 vertexShaderStr << "attribute vec2 position;\n"
9522 << "varying vec4 color;\n"
9523 << "varying vec2 texCoord;\n";
9524
9525 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
9526 {
9527 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
9528 }
9529
9530 vertexShaderStr << "void main() {\n"
9531 << " gl_Position = vec4(position, 0, 1);\n"
9532 << " texCoord = (position * 0.5) + 0.5;\n"
9533 << " color = vec4(0);\n";
9534
9535 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
9536 {
9537 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
9538 << ", texCoord);\n";
9539 }
9540
9541 vertexShaderStr << "}";
9542
9543 std::stringstream fragmentShaderStr;
9544 fragmentShaderStr << "varying mediump vec4 color;\n" << "varying mediump vec2 texCoord;\n";
9545
9546 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
9547 {
9548 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
9549 }
9550
9551 fragmentShaderStr << "void main() {\n" << " gl_FragColor = color;\n";
9552
9553 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
9554 {
9555 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
9556 << ", texCoord);\n";
9557 }
9558
9559 fragmentShaderStr << "}";
9560
9561 const std::string &vertexShaderSource = vertexShaderStr.str();
9562 const std::string &fragmentShaderSource = fragmentShaderStr.str();
9563
9564 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
9565 }
9566
getPixel(GLint texIndex)9567 RGBA8 getPixel(GLint texIndex)
9568 {
9569 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
9570 0, 255u};
9571 return pixel;
9572 }
9573
initTextures(GLint tex2DCount,GLint texCubeCount)9574 void initTextures(GLint tex2DCount, GLint texCubeCount)
9575 {
9576 GLint totalCount = tex2DCount + texCubeCount;
9577 mTextures.assign(totalCount, 0);
9578 glGenTextures(totalCount, &mTextures[0]);
9579 ASSERT_GL_NO_ERROR();
9580
9581 std::vector<RGBA8> texData(16 * 16);
9582
9583 GLint texIndex = 0;
9584 for (; texIndex < tex2DCount; ++texIndex)
9585 {
9586 texData.assign(texData.size(), getPixel(texIndex));
9587 glActiveTexture(GL_TEXTURE0 + texIndex);
9588 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
9589 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
9590 &texData[0]);
9591 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9592 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9593 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9594 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9595 }
9596
9597 ASSERT_GL_NO_ERROR();
9598
9599 for (; texIndex < texCubeCount; ++texIndex)
9600 {
9601 texData.assign(texData.size(), getPixel(texIndex));
9602 glActiveTexture(GL_TEXTURE0 + texIndex);
9603 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
9604 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9605 GL_UNSIGNED_BYTE, &texData[0]);
9606 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9607 GL_UNSIGNED_BYTE, &texData[0]);
9608 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9609 GL_UNSIGNED_BYTE, &texData[0]);
9610 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9611 GL_UNSIGNED_BYTE, &texData[0]);
9612 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9613 GL_UNSIGNED_BYTE, &texData[0]);
9614 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
9615 GL_UNSIGNED_BYTE, &texData[0]);
9616 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9617 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9618 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9619 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9620 }
9621
9622 ASSERT_GL_NO_ERROR();
9623 }
9624
testWithTextures(GLint vertexTextureCount,const std::string & vertexTexturePrefix,GLint fragmentTextureCount,const std::string & fragmentTexturePrefix)9625 void testWithTextures(GLint vertexTextureCount,
9626 const std::string &vertexTexturePrefix,
9627 GLint fragmentTextureCount,
9628 const std::string &fragmentTexturePrefix)
9629 {
9630 // Generate textures
9631 initTextures(vertexTextureCount + fragmentTextureCount, 0);
9632
9633 glUseProgram(mProgram);
9634 RGBA8 expectedSum = {0};
9635 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
9636 {
9637 std::stringstream uniformNameStr;
9638 uniformNameStr << vertexTexturePrefix << texIndex;
9639 const std::string &uniformName = uniformNameStr.str();
9640 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
9641 ASSERT_NE(-1, location);
9642
9643 glUniform1i(location, texIndex);
9644 RGBA8 contribution = getPixel(texIndex);
9645 expectedSum.R += contribution.R;
9646 expectedSum.G += contribution.G;
9647 }
9648
9649 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
9650 {
9651 std::stringstream uniformNameStr;
9652 uniformNameStr << fragmentTexturePrefix << texIndex;
9653 const std::string &uniformName = uniformNameStr.str();
9654 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
9655 ASSERT_NE(-1, location);
9656
9657 glUniform1i(location, texIndex + vertexTextureCount);
9658 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
9659 expectedSum.R += contribution.R;
9660 expectedSum.G += contribution.G;
9661 }
9662
9663 ASSERT_GE(256u, expectedSum.G);
9664
9665 drawQuad(mProgram, "position", 0.5f);
9666 ASSERT_GL_NO_ERROR();
9667 EXPECT_PIXEL_NEAR(0, 0, expectedSum.R, expectedSum.G, 0, 255, 1);
9668 }
9669
9670 GLuint mProgram;
9671 std::vector<GLuint> mTextures;
9672 GLint mMaxVertexTextures;
9673 GLint mMaxFragmentTextures;
9674 GLint mMaxCombinedTextures;
9675 };
9676
9677 // Test rendering with the maximum vertex texture units.
TEST_P(TextureLimitsTest,MaxVertexTextures)9678 TEST_P(TextureLimitsTest, MaxVertexTextures)
9679 {
9680 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
9681 ASSERT_NE(0u, mProgram);
9682 ASSERT_GL_NO_ERROR();
9683
9684 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
9685 }
9686
9687 // Test rendering with the maximum fragment texture units.
TEST_P(TextureLimitsTest,MaxFragmentTextures)9688 TEST_P(TextureLimitsTest, MaxFragmentTextures)
9689 {
9690 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
9691 ASSERT_NE(0u, mProgram);
9692 ASSERT_GL_NO_ERROR();
9693
9694 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
9695 }
9696
9697 // Test rendering with maximum combined texture units.
TEST_P(TextureLimitsTest,MaxCombinedTextures)9698 TEST_P(TextureLimitsTest, MaxCombinedTextures)
9699 {
9700 GLint vertexTextures = mMaxVertexTextures;
9701
9702 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
9703 {
9704 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
9705 }
9706
9707 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
9708 mMaxFragmentTextures, mMaxFragmentTextures);
9709 ASSERT_NE(0u, mProgram);
9710 ASSERT_GL_NO_ERROR();
9711
9712 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
9713 }
9714
9715 // Negative test for exceeding the number of vertex textures
TEST_P(TextureLimitsTest,ExcessiveVertexTextures)9716 TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
9717 {
9718 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
9719 0);
9720 ASSERT_EQ(0u, mProgram);
9721 }
9722
9723 // Negative test for exceeding the number of fragment textures
TEST_P(TextureLimitsTest,ExcessiveFragmentTextures)9724 TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
9725 {
9726 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
9727 mMaxFragmentTextures + 1);
9728 ASSERT_EQ(0u, mProgram);
9729 }
9730
9731 // Test active vertex textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveVertexTextures)9732 TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
9733 {
9734 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
9735 ASSERT_NE(0u, mProgram);
9736 ASSERT_GL_NO_ERROR();
9737
9738 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
9739 }
9740
9741 // Test active fragment textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveFragmentTextures)9742 TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
9743 {
9744 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
9745 mMaxFragmentTextures);
9746 ASSERT_NE(0u, mProgram);
9747 ASSERT_GL_NO_ERROR();
9748
9749 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
9750 }
9751
9752 // Negative test for pointing two sampler uniforms of different types to the same texture.
9753 // GLES 2.0.25 section 2.10.4 page 39.
TEST_P(TextureLimitsTest,TextureTypeConflict)9754 TEST_P(TextureLimitsTest, TextureTypeConflict)
9755 {
9756 constexpr char kVS[] =
9757 "attribute vec2 position;\n"
9758 "varying float color;\n"
9759 "uniform sampler2D tex2D;\n"
9760 "uniform samplerCube texCube;\n"
9761 "void main() {\n"
9762 " gl_Position = vec4(position, 0, 1);\n"
9763 " vec2 texCoord = (position * 0.5) + 0.5;\n"
9764 " color = texture2D(tex2D, texCoord).x;\n"
9765 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
9766 "}";
9767 constexpr char kFS[] =
9768 "varying mediump float color;\n"
9769 "void main() {\n"
9770 " gl_FragColor = vec4(color, 0, 0, 1);\n"
9771 "}";
9772
9773 mProgram = CompileProgram(kVS, kFS);
9774 ASSERT_NE(0u, mProgram);
9775
9776 initTextures(1, 0);
9777
9778 glUseProgram(mProgram);
9779 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
9780 ASSERT_NE(-1, tex2DLocation);
9781 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
9782 ASSERT_NE(-1, texCubeLocation);
9783
9784 glUniform1i(tex2DLocation, 0);
9785 glUniform1i(texCubeLocation, 0);
9786 ASSERT_GL_NO_ERROR();
9787
9788 drawQuad(mProgram, "position", 0.5f);
9789 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
9790 }
9791
9792 class Texture2DNorm16TestES3 : public Texture2DTestES3
9793 {
9794 protected:
Texture2DNorm16TestES3()9795 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
9796
testSetUp()9797 void testSetUp() override
9798 {
9799 Texture2DTestES3::testSetUp();
9800
9801 glActiveTexture(GL_TEXTURE0);
9802 glGenTextures(3, mTextures);
9803 glGenFramebuffers(1, &mFBO);
9804 glGenRenderbuffers(1, &mRenderbuffer);
9805
9806 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
9807 {
9808 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
9809 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9810 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9811 }
9812
9813 glBindTexture(GL_TEXTURE_2D, 0);
9814
9815 ASSERT_GL_NO_ERROR();
9816 }
9817
testTearDown()9818 void testTearDown() override
9819 {
9820 glDeleteTextures(3, mTextures);
9821 glDeleteFramebuffers(1, &mFBO);
9822 glDeleteRenderbuffers(1, &mRenderbuffer);
9823
9824 Texture2DTestES3::testTearDown();
9825 }
9826
testNorm16Texture(GLint internalformat,GLenum format,GLenum type)9827 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
9828 {
9829 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
9830
9831 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
9832 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
9833
9834 setUpProgram();
9835
9836 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
9837 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
9838 0);
9839
9840 for (int i = 0; i < 2; ++i)
9841 {
9842 bool isSubImage = i == 1;
9843 SCOPED_TRACE("is subimage:" + std::to_string(isSubImage));
9844 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
9845 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
9846
9847 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
9848 if (isSubImage)
9849 {
9850 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, nullptr);
9851 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, format, type, imageData);
9852 }
9853 else
9854 {
9855 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
9856 }
9857 EXPECT_GL_NO_ERROR();
9858
9859 drawQuad(mProgram, "position", 0.5f);
9860
9861 GLubyte expectedValue =
9862 (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
9863
9864 EXPECT_PIXEL_COLOR_EQ(0, 0,
9865 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
9866 expectedValue, expectedValue)));
9867 }
9868 glBindFramebuffer(GL_FRAMEBUFFER, 0);
9869
9870 ASSERT_GL_NO_ERROR();
9871 }
9872
testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,GLuint y,GLuint width,GLuint height,GLint packRowLength,GLint packAlignment,GLint packSkipPixels,GLint packSkipRows,GLenum type,GLColor16 color)9873 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
9874 GLuint y,
9875 GLuint width,
9876 GLuint height,
9877 GLint packRowLength,
9878 GLint packAlignment,
9879 GLint packSkipPixels,
9880 GLint packSkipRows,
9881 GLenum type,
9882 GLColor16 color)
9883 {
9884 // PACK modes debugging
9885 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
9886 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
9887
9888 GLuint l = packRowLength == 0 ? width : packRowLength;
9889 const GLint &a = packAlignment;
9890
9891 // According to
9892 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
9893 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
9894 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
9895 if (static_cast<GLuint>(packRowLength) < width)
9896 {
9897 componentCount += width * n * s - k;
9898 }
9899
9900 // Populate the pixels array with random dirty value
9901 constexpr GLushort kDirtyValue = 0x1234;
9902 std::vector<GLushort> pixels(componentCount, kDirtyValue);
9903 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
9904
9905 EXPECT_GL_NO_ERROR();
9906
9907 GLushort *pixelRowStart = pixels.data();
9908 pixelRowStart += n * packSkipPixels + k * packSkipRows;
9909
9910 std::vector<bool> modifiedPixels(componentCount, false);
9911
9912 char errorInfo[200];
9913
9914 for (GLuint row = 0; row < height; ++row)
9915 {
9916 GLushort *curPixel = pixelRowStart;
9917 for (GLuint col = 0, len = (row == height - 1) ? width : std::min(l, width); col < len;
9918 ++col)
9919 {
9920 snprintf(errorInfo, sizeof(errorInfo),
9921 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
9922 "skipPixels: %d, skipRows: %d\n",
9923 width, height, col, row, packRowLength, packAlignment, packSkipPixels,
9924 packSkipRows);
9925 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
9926 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
9927 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
9928 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
9929
9930 std::ptrdiff_t diff = curPixel - pixels.data();
9931 modifiedPixels[diff + 0] = true;
9932 modifiedPixels[diff + 1] = true;
9933 modifiedPixels[diff + 2] = true;
9934 modifiedPixels[diff + 3] = true;
9935
9936 curPixel += n;
9937 }
9938 pixelRowStart += k;
9939 }
9940
9941 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
9942 {
9943 if (!modifiedPixels[i])
9944 {
9945 EXPECT_EQ(pixels[i], kDirtyValue);
9946 }
9947 }
9948 }
9949
testNorm16RenderAndReadPixels(GLint internalformat,GLenum format,GLenum type)9950 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
9951 {
9952 // TODO(http://anglebug.com/40096653) Fails on Win Intel OpenGL driver
9953 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
9954 // TODO(http://anglebug.com/42262873) Fails on Win AMD OpenGL driver
9955 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
9956 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
9957
9958 GLushort pixelValue = 0x6A35;
9959 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
9960 GLColor16 color =
9961 SliceFormatColor16(format, GLColor16(pixelValue, pixelValue, pixelValue, pixelValue));
9962 // Size of drawing viewport
9963 constexpr GLint width = 8, height = 8;
9964
9965 setUpProgram();
9966
9967 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
9968 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
9969
9970 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
9971 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
9972 0);
9973
9974 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
9975 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
9976 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9977 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9978
9979 EXPECT_GL_NO_ERROR();
9980
9981 drawQuad(mProgram, "position", 0.5f);
9982
9983 // ReadPixels against different width, height, pixel pack mode combinations to test
9984 // workaround of pixels rearrangement
9985
9986 // {x, y, width, height}
9987 std::vector<std::array<GLint, 4>> areas = {
9988 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
9989 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
9990
9991 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
9992
9993 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
9994 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
9995 };
9996
9997 // Put default settings at the last
9998 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
9999 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
10000 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
10001 {3, 1}, {20, 20}, {0, 0}};
10002
10003 // Restore pixel pack modes later
10004 GLint restorePackAlignment;
10005 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
10006 GLint restorePackRowLength;
10007 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
10008 GLint restorePackSkipPixels;
10009 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
10010 GLint restorePackSkipRows;
10011 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
10012
10013 // Variable symbols are based on:
10014 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
10015 for (const auto &skipped : paramsPackSkipPixelsAndRows)
10016 {
10017 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
10018 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
10019 for (GLint a : paramsPackAlignment)
10020 {
10021 glPixelStorei(GL_PACK_ALIGNMENT, a);
10022 for (GLint l : paramsPackRowLength)
10023 {
10024 glPixelStorei(GL_PACK_ROW_LENGTH, l);
10025
10026 for (const auto &area : areas)
10027 {
10028 ASSERT(area[0] + area[2] <= width);
10029 ASSERT(area[1] + area[3] <= height);
10030 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
10031 area[3], l, a, skipped[0],
10032 skipped[1], type, color);
10033 }
10034 }
10035 }
10036 }
10037
10038 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
10039 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
10040 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
10041 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
10042
10043 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
10044 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
10045 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10046 mRenderbuffer);
10047 glBindRenderbuffer(GL_RENDERBUFFER, 0);
10048 EXPECT_GL_NO_ERROR();
10049
10050 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
10051 glClear(GL_COLOR_BUFFER_BIT);
10052
10053 EXPECT_PIXEL_COLOR16_NEAR(
10054 0, 0, SliceFormatColor16(format, GLColor16(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)), 0);
10055
10056 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
10057 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
10058
10059 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
10060 0);
10061 EXPECT_PIXEL_COLOR16_NEAR(
10062 0, 0, SliceFormatColor16(format, GLColor16(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)), 0);
10063
10064 ASSERT_GL_NO_ERROR();
10065
10066 glBindFramebuffer(GL_FRAMEBUFFER, 0);
10067 }
10068
10069 GLuint mTextures[3];
10070 GLuint mFBO;
10071 GLuint mRenderbuffer;
10072 };
10073
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16TextureTest)10074 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
10075 {
10076 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
10077 }
10078
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16SNORMTextureTest)10079 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
10080 {
10081 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
10082 }
10083
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16TextureTest)10084 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
10085 {
10086 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
10087 }
10088
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16SNORMTextureTest)10089 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
10090 {
10091 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
10092 }
10093
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16TextureTest)10094 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
10095 {
10096 // (http://anglebug.com/40096662) Driver bug on some Qualcomm Adreno gpu
10097 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
10098
10099 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
10100 }
10101
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16SNORMTextureTest)10102 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
10103 {
10104 // (http://anglebug.com/40096662) Driver bug on some Qualcomm Adreno gpu
10105 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
10106
10107 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
10108 }
10109
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16TextureTest)10110 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
10111 {
10112 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
10113 }
10114
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16SNORMTextureTest)10115 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
10116 {
10117 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
10118 }
10119
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16RenderTest)10120 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
10121 {
10122 // http://anglebug.com/42263714
10123 ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL() && IsNVIDIA());
10124
10125 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
10126 }
10127
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16RenderTest)10128 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
10129 {
10130 // http://anglebug.com/42263714
10131 ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL() && IsNVIDIA());
10132
10133 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
10134 }
10135
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16RenderTest)10136 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
10137 {
10138 // http://anglebug.com/42263714
10139 ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL() && IsNVIDIA());
10140
10141 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
10142 }
10143
10144 class Texture2DRGTest : public Texture2DTest
10145 {
10146 protected:
Texture2DRGTest()10147 Texture2DRGTest()
10148 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
10149 {}
10150
testSetUp()10151 void testSetUp() override
10152 {
10153 Texture2DTest::testSetUp();
10154
10155 glActiveTexture(GL_TEXTURE0);
10156 glGenTextures(1, &mRenderableTexture);
10157 glGenTextures(1, &mTestTexture);
10158 glGenFramebuffers(1, &mFBO);
10159 glGenRenderbuffers(1, &mRenderbuffer);
10160
10161 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
10162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10164 glBindTexture(GL_TEXTURE_2D, mTestTexture);
10165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10167
10168 glBindTexture(GL_TEXTURE_2D, 0);
10169
10170 setUpProgram();
10171 glUseProgram(mProgram);
10172 glUniform1i(mTexture2DUniformLocation, 0);
10173
10174 ASSERT_GL_NO_ERROR();
10175 }
10176
testTearDown()10177 void testTearDown() override
10178 {
10179 glDeleteTextures(1, &mRenderableTexture);
10180 glDeleteTextures(1, &mTestTexture);
10181 glDeleteFramebuffers(1, &mFBO);
10182 glDeleteRenderbuffers(1, &mRenderbuffer);
10183
10184 Texture2DTest::testTearDown();
10185 }
10186
setupFormatTextures(GLenum internalformat,GLenum format,GLenum type,GLvoid * imageData)10187 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
10188 {
10189 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
10190 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
10191
10192 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10193 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
10194 mRenderableTexture, 0);
10195
10196 glBindTexture(GL_TEXTURE_2D, mTestTexture);
10197 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
10198
10199 EXPECT_GL_NO_ERROR();
10200 }
10201
testRGTexture(GLColor expectedColor)10202 void testRGTexture(GLColor expectedColor)
10203 {
10204 drawQuad(mProgram, "position", 0.5f);
10205
10206 EXPECT_GL_NO_ERROR();
10207 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
10208 }
10209
testRGRender(GLenum internalformat,GLenum format)10210 void testRGRender(GLenum internalformat, GLenum format)
10211 {
10212 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
10213 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
10214 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10215 mRenderbuffer);
10216 glBindRenderbuffer(GL_RENDERBUFFER, 0);
10217 EXPECT_GL_NO_ERROR();
10218
10219 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
10220 glClear(GL_COLOR_BUFFER_BIT);
10221
10222 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
10223
10224 ASSERT_GL_NO_ERROR();
10225 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
10226 }
10227
10228 GLuint mRenderableTexture;
10229 GLuint mTestTexture;
10230 GLuint mFBO;
10231 GLuint mRenderbuffer;
10232 };
10233
10234 // Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGUNormTest)10235 TEST_P(Texture2DRGTest, TextureRGUNormTest)
10236 {
10237 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
10238 // This workaround causes a GL error on Windows AMD, which is likely a driver bug.
10239 // The workaround is not intended to be enabled in this configuration so skip it.
10240 ANGLE_SKIP_TEST_IF(
10241 getEGLWindow()->isFeatureEnabled(Feature::EmulateCopyTexImage2DFromRenderbuffers) &&
10242 IsWindows() && IsAMD());
10243
10244 GLubyte pixelValue = 0xab;
10245 GLubyte imageData[] = {pixelValue, pixelValue};
10246
10247 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
10248 testRGTexture(
10249 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
10250 testRGRender(GL_R8_EXT, GL_RED_EXT);
10251
10252 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
10253 testRGTexture(
10254 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
10255 testRGRender(GL_RG8_EXT, GL_RG_EXT);
10256 }
10257
10258 // Test float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGFloatTest)10259 TEST_P(Texture2DRGTest, TextureRGFloatTest)
10260 {
10261 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
10262 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10263
10264 GLfloat pixelValue = 0.54321;
10265 GLfloat imageData[] = {pixelValue, pixelValue};
10266
10267 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
10268 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
10269
10270 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
10271 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
10272
10273 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
10274 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
10275 }
10276
10277 // Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGHalfFloatTest)10278 TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
10279 {
10280 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
10281 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10282
10283 GLfloat pixelValueFloat = 0.543f;
10284 GLhalf pixelValue = 0x3858;
10285 GLhalf imageData[] = {pixelValue, pixelValue};
10286
10287 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
10288 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
10289
10290 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
10291 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
10292
10293 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
10294 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
10295 }
10296
10297 class Texture2DFloatTest : public Texture2DTest
10298 {
10299 protected:
Texture2DFloatTest()10300 Texture2DFloatTest()
10301 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
10302 {}
10303
testSetUp()10304 void testSetUp() override
10305 {
10306 Texture2DTest::testSetUp();
10307
10308 glActiveTexture(GL_TEXTURE0);
10309 glGenTextures(1, &mRenderableTexture);
10310 glGenTextures(1, &mTestTexture);
10311 glGenFramebuffers(1, &mFBO);
10312 glGenRenderbuffers(1, &mRenderbuffer);
10313
10314 setUpProgram();
10315 glUseProgram(mProgram);
10316 glUniform1i(mTexture2DUniformLocation, 0);
10317
10318 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
10319 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
10320
10321 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10322 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
10323 mRenderableTexture, 0);
10324
10325 ASSERT_GL_NO_ERROR();
10326 }
10327
testTearDown()10328 void testTearDown() override
10329 {
10330 glDeleteTextures(1, &mRenderableTexture);
10331 glDeleteTextures(1, &mTestTexture);
10332 glDeleteFramebuffers(1, &mFBO);
10333 glDeleteRenderbuffers(1, &mRenderbuffer);
10334
10335 Texture2DTest::testTearDown();
10336 }
10337
testFloatTextureSample(GLenum internalFormat,GLenum format,GLenum type)10338 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
10339 {
10340 constexpr GLfloat imageDataFloat[] = {
10341 0.2f,
10342 0.3f,
10343 0.4f,
10344 0.5f,
10345 };
10346 constexpr GLhalf imageDataHalf[] = {
10347 0x3266,
10348 0x34CD,
10349 0x3666,
10350 0x3800,
10351 };
10352 GLColor expectedValue;
10353 for (int i = 0; i < 4; i++)
10354 {
10355 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
10356 }
10357
10358 const GLvoid *imageData;
10359 switch (type)
10360 {
10361 case GL_FLOAT:
10362 imageData = imageDataFloat;
10363 break;
10364 case GL_HALF_FLOAT:
10365 case GL_HALF_FLOAT_OES:
10366 imageData = imageDataHalf;
10367 break;
10368 default:
10369 imageData = nullptr;
10370 }
10371 ASSERT(imageData != nullptr);
10372
10373 glBindTexture(GL_TEXTURE_2D, mTestTexture);
10374 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
10375
10376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10378
10379 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10380 drawQuad(mProgram, "position", 0.5f);
10381
10382 EXPECT_GL_NO_ERROR();
10383 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
10384 }
10385
testFloatTextureLinear(GLenum internalFormat,GLenum format,GLenum type)10386 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
10387 {
10388 int numComponents;
10389 switch (format)
10390 {
10391 case GL_RGBA:
10392 numComponents = 4;
10393 break;
10394 case GL_RGB:
10395 numComponents = 3;
10396 break;
10397 case GL_LUMINANCE_ALPHA:
10398 numComponents = 2;
10399 break;
10400 case GL_LUMINANCE:
10401 case GL_ALPHA:
10402 numComponents = 1;
10403 break;
10404 default:
10405 numComponents = 0;
10406 }
10407 ASSERT(numComponents > 0);
10408
10409 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
10410 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
10411
10412 GLfloat imageDataFloat[16];
10413 GLhalf imageDataHalf[16];
10414 for (int i = 0; i < 4; i++)
10415 {
10416 for (int c = 0; c < numComponents; c++)
10417 {
10418 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
10419 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
10420 }
10421 }
10422
10423 const GLvoid *imageData;
10424 switch (type)
10425 {
10426 case GL_FLOAT:
10427 imageData = imageDataFloat;
10428 break;
10429 case GL_HALF_FLOAT:
10430 case GL_HALF_FLOAT_OES:
10431 imageData = imageDataHalf;
10432 break;
10433 default:
10434 imageData = nullptr;
10435 }
10436 ASSERT(imageData != nullptr);
10437
10438 glBindTexture(GL_TEXTURE_2D, mTestTexture);
10439 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
10440
10441 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10442 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10443
10444 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10445 drawQuad(mProgram, "position", 0.5f);
10446
10447 EXPECT_GL_NO_ERROR();
10448 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
10449 // should expect the final value to be gray (halfway in-between)
10450 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
10451 kPixelTolerance);
10452 }
10453
performFloatTextureRender(GLenum internalFormat,GLenum renderBufferFormat,GLenum format,GLenum type)10454 bool performFloatTextureRender(GLenum internalFormat,
10455 GLenum renderBufferFormat,
10456 GLenum format,
10457 GLenum type)
10458 {
10459 glBindTexture(GL_TEXTURE_2D, mTestTexture);
10460 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
10461 glBindTexture(GL_TEXTURE_2D, 0);
10462
10463 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
10464 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
10465 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10466 mRenderbuffer);
10467 glBindRenderbuffer(GL_RENDERBUFFER, 0);
10468 EXPECT_GL_NO_ERROR();
10469
10470 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
10471 {
10472 return false;
10473 }
10474
10475 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
10476
10477 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
10478 glClear(GL_COLOR_BUFFER_BIT);
10479
10480 EXPECT_GL_NO_ERROR();
10481 return true;
10482 }
10483
10484 GLuint mRenderableTexture;
10485 GLuint mTestTexture;
10486 GLuint mFBO;
10487 GLuint mRenderbuffer;
10488 };
10489
10490 class Texture2DFloatTestES3 : public Texture2DFloatTest
10491 {
10492 protected:
testFloatTextureRender(GLenum internalFormat,GLenum format,GLenum type)10493 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
10494 {
10495 bool framebufferComplete =
10496 performFloatTextureRender(internalFormat, internalFormat, format, type);
10497 EXPECT_TRUE(framebufferComplete);
10498 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
10499 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
10500 kPixelTolerance32F);
10501 }
10502 };
10503
10504 class Texture2DFloatTestES2 : public Texture2DFloatTest
10505 {
10506 protected:
checkFloatTextureRender(GLenum renderBufferFormat,GLenum format,GLenum type)10507 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
10508 {
10509 bool framebufferComplete =
10510 performFloatTextureRender(format, renderBufferFormat, format, type);
10511
10512 if (!framebufferComplete)
10513 {
10514 return false;
10515 }
10516
10517 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
10518 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
10519 kPixelTolerance32F);
10520 return true;
10521 }
10522 };
10523
10524 // Test texture sampling for ES3 float texture formats
TEST_P(Texture2DFloatTestES3,TextureFloatSampleBasicTest)10525 TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
10526 {
10527 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
10528 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
10529 }
10530
10531 // Test texture sampling for ES2 float texture formats
TEST_P(Texture2DFloatTestES2,TextureFloatSampleBasicTest)10532 TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
10533 {
10534 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10535 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
10536 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
10537 }
10538
10539 // Test texture sampling for ES3 half float texture formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleBasicTest)10540 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
10541 {
10542 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
10543 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
10544 }
10545
10546 // Test texture sampling for ES2 half float texture formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleBasicTest)10547 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
10548 {
10549 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10550 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
10551 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
10552 }
10553
10554 // Test texture sampling for legacy GLES 2.0 float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatSampleLegacyTest)10555 TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
10556 {
10557 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10558
10559 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10560 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10561 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10562
10563 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10564 {
10565 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
10566 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
10567 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
10568 }
10569 }
10570
10571 // Test texture sampling for legacy GLES 2.0 float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatSampleLegacyTest)10572 TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
10573 {
10574 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10575
10576 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10577 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10578 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10579 }
10580
10581 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleLegacyTest)10582 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
10583 {
10584 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10585
10586 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10587 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10588 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10589
10590 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10591 {
10592 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
10593 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
10594 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
10595 }
10596 }
10597 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleLegacyTest)10598 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
10599 {
10600 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10601
10602 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10603 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10604 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10605 }
10606
10607 // Test linear sampling for ES3 32F formats
TEST_P(Texture2DFloatTestES3,TextureFloatLinearTest)10608 TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
10609 {
10610 // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10611 ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10612
10613 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10614
10615 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
10616 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
10617 }
10618 // Test linear sampling for ES2 32F formats
TEST_P(Texture2DFloatTestES2,TextureFloatLinearTest)10619 TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
10620 {
10621 // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10622 ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10623
10624 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10625
10626 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10627
10628 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
10629 }
10630
10631 // Test linear sampling for ES3 16F formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearTest)10632 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
10633 {
10634 // Half float formats must be linearly filterable in GLES 3.0 core
10635 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
10636 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
10637 }
10638 // Test linear sampling for ES2 16F formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearTest)10639 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
10640 {
10641 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
10642 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
10643 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
10644 }
10645
10646 // Test linear sampling for legacy GLES 2.0 32F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatLinearLegacyTest)10647 TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
10648 {
10649 // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10650 ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10651
10652 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10653 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10654
10655 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10656 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10657 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10658
10659 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10660 {
10661 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
10662 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
10663 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
10664 }
10665 }
10666 // Test linear sampling for legacy GLES 2.0 32F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatLinearLegacyTest)10667 TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
10668 {
10669 // TODO(anglebug.com/40096747): Failing on ARM-based Apple DTKs.
10670 ANGLE_SKIP_TEST_IF(IsMac() && IsARM64() && (IsDesktopOpenGL()));
10671
10672 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
10673 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
10674
10675 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
10676 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
10677 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
10678 }
10679
10680 // Test linear sampling for legacy GLES 2.0 16F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearLegacyTest)10681 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
10682 {
10683 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10684 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
10685
10686 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10687 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10688 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10689
10690 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
10691 {
10692 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
10693 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
10694 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
10695 }
10696 }
10697 // Test linear sampling for legacy GLES 2.0 16F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearLegacyTest)10698 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
10699 {
10700 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
10701 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
10702
10703 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
10704 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
10705 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
10706 }
10707
10708 // Test color-renderability for ES3 float and half float textures
TEST_P(Texture2DFloatTestES3,TextureFloatRenderTest)10709 TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
10710 {
10711 // http://anglebug.com/40096654
10712 ANGLE_SKIP_TEST_IF(IsD3D9());
10713 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
10714 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
10715
10716 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
10717 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
10718 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
10719
10720 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
10721 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
10722 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
10723
10724 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
10725 }
10726
10727 // Test color-renderability for ES2 half float textures
TEST_P(Texture2DFloatTestES2,TextureFloatRenderTest)10728 TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
10729 {
10730 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
10731 // require a specific one
10732 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
10733 // https://crbug.com/1003971
10734 ANGLE_SKIP_TEST_IF(IsOzone());
10735 // http://anglebug.com/40096654
10736 ANGLE_SKIP_TEST_IF(IsD3D9());
10737
10738 bool atLeastOneSupported = false;
10739
10740 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
10741 IsGLExtensionEnabled("GL_OES_texture_half_float"))
10742 {
10743 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
10744 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
10745 }
10746 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
10747 {
10748 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
10749
10750 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
10751 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
10752 EXPECT_TRUE(rgbaSupported);
10753 atLeastOneSupported |= rgbaSupported;
10754 }
10755
10756 EXPECT_TRUE(atLeastOneSupported);
10757 }
10758
10759 // Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
10760 // GLES 3.0.4 section 3.8.3.
TEST_P(Texture2DTestES3,UnpackSkipImages2D)10761 TEST_P(Texture2DTestES3, UnpackSkipImages2D)
10762 {
10763 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/42260424
10764 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
10765
10766 glBindTexture(GL_TEXTURE_2D, mTexture2D);
10767 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10768 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10769 ASSERT_GL_NO_ERROR();
10770
10771 // SKIP_IMAGES should not have an effect on uploading 2D textures
10772 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
10773 ASSERT_GL_NO_ERROR();
10774
10775 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
10776
10777 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
10778 pixelsGreen.data());
10779 ASSERT_GL_NO_ERROR();
10780
10781 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
10782 pixelsGreen.data());
10783 ASSERT_GL_NO_ERROR();
10784
10785 glUseProgram(mProgram);
10786 drawQuad(mProgram, "position", 0.5f);
10787 ASSERT_GL_NO_ERROR();
10788
10789 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
10790 }
10791
10792 // Test that skip defined in unpack parameters is taken into account when determining whether
10793 // unpacking source extends outside unpack buffer bounds.
TEST_P(Texture2DTestES3,UnpackSkipPixelsOutOfBounds)10794 TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
10795 {
10796 glBindTexture(GL_TEXTURE_2D, mTexture2D);
10797 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10798 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10799 ASSERT_GL_NO_ERROR();
10800
10801 GLBuffer buf;
10802 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
10803 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
10804 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
10805 GL_DYNAMIC_COPY);
10806 ASSERT_GL_NO_ERROR();
10807
10808 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10809 ASSERT_GL_NO_ERROR();
10810
10811 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
10812 ASSERT_GL_NO_ERROR();
10813
10814 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10815 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
10816
10817 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
10818 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
10819 ASSERT_GL_NO_ERROR();
10820
10821 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10822 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
10823 }
10824
10825 // Test unpacking to texture from a buffer with a compatible format but different type.
10826 // Compatible formats can be found in "Table 8.2: Valid combinations of format, type, and sized
10827 // internal format." of the OpenGL ES 3.2 spec.
TEST_P(Texture2DTestES3,UnpackCompatibleFormatButDifferentType)10828 TEST_P(Texture2DTestES3, UnpackCompatibleFormatButDifferentType)
10829 {
10830 glBindTexture(GL_TEXTURE_2D, mTexture2D);
10831 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10832 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10833 ASSERT_GL_NO_ERROR();
10834
10835 // Create texture with GL_RGBA4 format and fill with red
10836 std::vector<GLColor> pixelsRed(128u * 128u, GLColor::red);
10837 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
10838 pixelsRed.data());
10839 ASSERT_GL_NO_ERROR();
10840
10841 // Call glTexSubImage2D with incompatible format and expect an error
10842 std::array<GLubyte, 2> rgColor = {255, 255};
10843 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RG, GL_UNSIGNED_BYTE, rgColor.data());
10844 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
10845
10846 glUseProgram(mProgram);
10847 drawQuad(mProgram, "position", 0.5f);
10848 ASSERT_GL_NO_ERROR();
10849 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
10850
10851 // Create unpack buffer with GL_RGBA8
10852 GLBuffer buf;
10853 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
10854 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
10855 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
10856 GL_DYNAMIC_COPY);
10857 ASSERT_GL_NO_ERROR();
10858
10859 // Unpack GL_RGBA8 buffer data to GL_RGBA4 texture
10860 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10861 ASSERT_GL_NO_ERROR();
10862
10863 // Validate that the data was unpacked correctly
10864 glUseProgram(mProgram);
10865 drawQuad(mProgram, "position", 0.5f);
10866 ASSERT_GL_NO_ERROR();
10867
10868 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
10869 }
10870
10871 // Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
TEST_P(Texture2DTestES3,UnpackOverlappingRowsFromUnpackBuffer)10872 TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
10873 {
10874 ANGLE_SKIP_TEST_IF(IsD3D11());
10875
10876 // Incorrect rendering results seen on OSX AMD.
10877 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac() && IsAMD());
10878
10879 const GLuint width = 8u;
10880 const GLuint height = 8u;
10881 const GLuint unpackRowLength = 5u;
10882 const GLuint unpackSkipPixels = 1u;
10883
10884 setWindowWidth(width);
10885 setWindowHeight(height);
10886
10887 glBindTexture(GL_TEXTURE_2D, mTexture2D);
10888 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10889 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10890 ASSERT_GL_NO_ERROR();
10891
10892 GLBuffer buf;
10893 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
10894 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
10895 GLColor::green);
10896
10897 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
10898 {
10899 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
10900 }
10901
10902 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
10903 GL_DYNAMIC_COPY);
10904 ASSERT_GL_NO_ERROR();
10905
10906 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
10907 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
10908 ASSERT_GL_NO_ERROR();
10909
10910 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
10911 ASSERT_GL_NO_ERROR();
10912
10913 glUseProgram(mProgram);
10914 drawQuad(mProgram, "position", 0.5f);
10915 ASSERT_GL_NO_ERROR();
10916
10917 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
10918 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
10919 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
10920 actual.data());
10921 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
10922 EXPECT_EQ(expected, actual);
10923 }
10924
10925 template <typename T>
UNorm(double value)10926 T UNorm(double value)
10927 {
10928 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
10929 }
10930
10931 // Test rendering a depth texture with mipmaps.
TEST_P(Texture2DTestES3,DepthTexturesWithMipmaps)10932 TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
10933 {
10934 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
10935 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
10936 // http://anglebug.com/42260646
10937 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
10938
10939 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/40096577
10940 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
10941
10942 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/42262590
10943 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
10944
10945 const int size = getWindowWidth();
10946
10947 auto dim = [size](int level) { return size >> level; };
10948 int levels = gl::log2(size);
10949
10950 glActiveTexture(GL_TEXTURE0);
10951 glBindTexture(GL_TEXTURE_2D, mTexture2D);
10952 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
10953 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
10954 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10955 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
10956 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
10957 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
10958 ASSERT_GL_NO_ERROR();
10959
10960 glUseProgram(mProgram);
10961 glUniform1i(mTexture2DUniformLocation, 0);
10962
10963 std::vector<unsigned char> expected;
10964
10965 for (int level = 0; level < levels; ++level)
10966 {
10967 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
10968 expected.push_back(UNorm<unsigned char>(value));
10969
10970 int levelDim = dim(level);
10971
10972 ASSERT_GT(levelDim, 0);
10973
10974 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
10975 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
10976 GL_UNSIGNED_INT, initData.data());
10977 }
10978 ASSERT_GL_NO_ERROR();
10979
10980 for (int level = 0; level < levels; ++level)
10981 {
10982 glViewport(0, 0, dim(level), dim(level));
10983 drawQuad(mProgram, "position", 0.5f);
10984 GLColor actual = ReadColor(0, 0);
10985 EXPECT_NEAR(expected[level], actual.R, 10u);
10986 }
10987
10988 ASSERT_GL_NO_ERROR();
10989 }
10990
10991 class Texture2DDepthTest : public Texture2DTest
10992 {
10993 protected:
Texture2DDepthTest()10994 Texture2DDepthTest() : Texture2DTest() {}
10995
getVertexShaderSource()10996 const char *getVertexShaderSource() override
10997 {
10998 return "attribute vec4 vPosition;\n"
10999 "void main() {\n"
11000 " gl_Position = vPosition;\n"
11001 "}\n";
11002 }
11003
getFragmentShaderSource()11004 const char *getFragmentShaderSource() override
11005 {
11006 return "precision mediump float;\n"
11007 "uniform sampler2D ShadowMap;"
11008 "void main() {\n"
11009 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
11010 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
11011 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
11012 " } else {"
11013 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
11014 " }"
11015 "}\n";
11016 }
11017
checkTexImageFormatSupport(GLenum format,GLenum internalformat,GLenum type)11018 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
11019 {
11020 EXPECT_GL_NO_ERROR();
11021
11022 GLTexture tex;
11023 glBindTexture(GL_TEXTURE_2D, tex);
11024 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
11025
11026 return (glGetError() == GL_NO_ERROR);
11027 }
11028
testBehavior(bool useSizedComponent)11029 void testBehavior(bool useSizedComponent)
11030 {
11031 int w = getWindowWidth();
11032 int h = getWindowHeight();
11033 GLuint format = GL_DEPTH_COMPONENT;
11034 GLuint internalFormat = GL_DEPTH_COMPONENT;
11035
11036 if (useSizedComponent)
11037 {
11038 internalFormat = GL_DEPTH_COMPONENT24;
11039 }
11040
11041 GLFramebuffer fbo;
11042 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
11043 ASSERT_GL_NO_ERROR();
11044
11045 GLTexture depthTexture;
11046 glBindTexture(GL_TEXTURE_2D, depthTexture);
11047 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11048 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11049 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
11050 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
11051
11052 TexCoordDrawTest::setUpProgram();
11053 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
11054 ASSERT_NE(-1, shadowMapLocation);
11055
11056 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
11057 ASSERT_NE(-1, positionLocation);
11058
11059 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
11060 glBindTexture(GL_TEXTURE_2D, depthTexture);
11061 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
11062 ASSERT_GL_NO_ERROR();
11063
11064 // try adding a color buffer.
11065 GLTexture colorTex;
11066 glBindTexture(GL_TEXTURE_2D, colorTex);
11067 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
11068 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
11069 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
11070 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
11071 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11072 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
11073 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
11074 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
11075 ASSERT_GL_NO_ERROR();
11076
11077 glViewport(0, 0, w, h);
11078 // Fill depthTexture with 0.75
11079 glClearDepthf(0.75);
11080 glClear(GL_DEPTH_BUFFER_BIT);
11081
11082 // Revert to normal framebuffer to test depth shader
11083 glBindFramebuffer(GL_FRAMEBUFFER, 0);
11084 glViewport(0, 0, w, h);
11085 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
11086 glClearDepthf(0.0f);
11087 ASSERT_GL_NO_ERROR();
11088
11089 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
11090 ASSERT_GL_NO_ERROR();
11091
11092 glActiveTexture(GL_TEXTURE0);
11093 glBindTexture(GL_TEXTURE_2D, depthTexture);
11094
11095 glUseProgram(mProgram);
11096 ASSERT_GL_NO_ERROR();
11097
11098 glUniform1i(shadowMapLocation, 0);
11099
11100 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
11101
11102 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
11103 ASSERT_GL_NO_ERROR();
11104 glEnableVertexAttribArray(positionLocation);
11105 ASSERT_GL_NO_ERROR();
11106 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
11107 ASSERT_GL_NO_ERROR();
11108
11109 GLuint pixels[1];
11110 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
11111 ASSERT_GL_NO_ERROR();
11112
11113 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
11114 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
11115 // is in all the color components. Multiple implementations implement a workaround that
11116 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
11117 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
11118 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
11119 // depending on if it sees the texture sample in only the RED component.
11120 if (useSizedComponent)
11121 {
11122 ASSERT_NE(pixels[0], 0xff0000ff);
11123 }
11124 else
11125 {
11126 ASSERT_EQ(pixels[0], 0xff0000ff);
11127 }
11128
11129 glBindFramebuffer(GL_FRAMEBUFFER, 0);
11130 glDeleteProgram(mProgram);
11131 }
11132 };
11133
11134 // Test depth texture compatibility with OES_depth_texture. Uses unsized internal format.
TEST_P(Texture2DDepthTest,DepthTextureES2Compatibility)11135 TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
11136 {
11137 ANGLE_SKIP_TEST_IF(IsD3D11());
11138 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
11139 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
11140 !IsGLExtensionEnabled("GL_OES_depth_texture"));
11141 // http://anglebug.com/40096654
11142 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
11143 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
11144
11145 // When the depth texture is specified with unsized internalformat implementations follow
11146 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
11147 testBehavior(false);
11148 }
11149
11150 // Test depth texture compatibility with GLES3 using sized internalformat.
TEST_P(Texture2DDepthTest,DepthTextureES3Compatibility)11151 TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
11152 {
11153 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
11154
11155 // http://anglebug.com/42263796
11156 ANGLE_SKIP_TEST_IF(IsMetal() && !IsMetalTextureSwizzleAvailable());
11157
11158 testBehavior(true);
11159 }
11160
11161 // Tests unpacking into the unsized GL_ALPHA format.
TEST_P(Texture2DTestES3,UnsizedAlphaUnpackBuffer)11162 TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
11163 {
11164 // Initialize the texure.
11165 glBindTexture(GL_TEXTURE_2D, mTexture2D);
11166 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
11167 GL_UNSIGNED_BYTE, nullptr);
11168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11170
11171 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
11172
11173 // Pull in the color data from the unpack buffer.
11174 GLBuffer unpackBuffer;
11175 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
11176 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
11177 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
11178 GL_STATIC_DRAW);
11179
11180 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
11181 GL_UNSIGNED_BYTE, nullptr);
11182
11183 // Clear to a weird color to make sure we're drawing something.
11184 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
11185 glClear(GL_COLOR_BUFFER_BIT);
11186
11187 // Draw with the alpha texture and verify.
11188 drawQuad(mProgram, "position", 0.5f);
11189
11190 ASSERT_GL_NO_ERROR();
11191 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
11192 }
11193
11194 // Ensure stale unpack data doesn't propagate in D3D11.
TEST_P(Texture2DTestES3,StaleUnpackData)11195 TEST_P(Texture2DTestES3, StaleUnpackData)
11196 {
11197 // Init unpack buffer.
11198 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
11199 std::vector<GLColor> pixels(pixelCount, GLColor::red);
11200
11201 GLBuffer unpackBuffer;
11202 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
11203 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
11204 GLsizei bufferSize = pixelCount * sizeof(GLColor);
11205 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
11206
11207 // Create from unpack buffer.
11208 glBindTexture(GL_TEXTURE_2D, mTexture2D);
11209 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
11210 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11211 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11213
11214 drawQuad(mProgram, "position", 0.5f);
11215
11216 ASSERT_GL_NO_ERROR();
11217 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
11218
11219 // Fill unpack with green, recreating buffer.
11220 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
11221 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
11222 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
11223
11224 // Reinit texture with green.
11225 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
11226 GL_UNSIGNED_BYTE, nullptr);
11227
11228 drawQuad(mProgram, "position", 0.5f);
11229
11230 ASSERT_GL_NO_ERROR();
11231 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
11232 }
11233
11234 // Ensure that texture parameters passed as floats that are converted to ints are rounded before
11235 // validating they are less than 0.
TEST_P(Texture2DTestES3,TextureBaseMaxLevelRoundingValidation)11236 TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
11237 {
11238 GLTexture texture;
11239 glBindTexture(GL_TEXTURE_2D, texture);
11240
11241 // Use a negative number that will round to zero when converted to an integer
11242 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
11243 // "Validation of values performed by state-setting commands is performed after conversion,
11244 // unless specified otherwise for a specific command."
11245 GLfloat param = -7.30157126e-07f;
11246 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
11247 EXPECT_GL_NO_ERROR();
11248
11249 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
11250 EXPECT_GL_NO_ERROR();
11251 }
11252
11253 // This test covers a D3D format redefinition bug for 3D textures. The base level format was not
11254 // being properly checked, and the texture storage of the previous texture format was persisting.
11255 // This would result in an ASSERT in debug and incorrect rendering in release.
11256 // See http://anglebug.com/42260575 and WebGL 2 test conformance2/misc/views-with-offsets.html.
TEST_P(Texture3DTestES3,FormatRedefinitionBug)11257 TEST_P(Texture3DTestES3, FormatRedefinitionBug)
11258 {
11259 GLTexture tex;
11260 glBindTexture(GL_TEXTURE_3D, tex);
11261 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11262
11263 GLFramebuffer framebuffer;
11264 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
11265 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
11266
11267 glCheckFramebufferStatus(GL_FRAMEBUFFER);
11268
11269 std::vector<uint8_t> pixelData(100, 0);
11270
11271 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
11272 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
11273 pixelData.data());
11274
11275 ASSERT_GL_NO_ERROR();
11276 }
11277
11278 // Test glTexSubImage using PBO to 3D texture that expose the regression bug
11279 // https://issuetracker.google.com/170657065
TEST_P(Texture3DTestES3,TexSubImageWithPBO)11280 TEST_P(Texture3DTestES3, TexSubImageWithPBO)
11281 {
11282 GLTexture tex;
11283
11284 GLuint pbo;
11285 glGenBuffers(1, &pbo);
11286 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
11287 std::vector<uint8_t> pixelData(128 * 128 * 8 * 4, 0x1f);
11288 glBufferData(GL_PIXEL_UNPACK_BUFFER, 128 * 128 * 8 * 4, pixelData.data(), GL_STATIC_DRAW);
11289
11290 glBindTexture(GL_TEXTURE_3D, tex);
11291 glTexStorage3D(GL_TEXTURE_3D, 8, GL_RGBA8, 128, 128, 8);
11292 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
11293 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
11294 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11295 glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11296 glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11297 glTexSubImage3D(GL_TEXTURE_3D, 3, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11298 glTexSubImage3D(GL_TEXTURE_3D, 4, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11299 glTexSubImage3D(GL_TEXTURE_3D, 5, 0, 0, 0, 4, 4, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11300 glTexSubImage3D(GL_TEXTURE_3D, 6, 0, 0, 0, 2, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11301 glTexSubImage3D(GL_TEXTURE_3D, 7, 0, 0, 0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11302
11303 drawQuad(mProgram, "position", 0.5f);
11304 ASSERT_GL_NO_ERROR();
11305
11306 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11307 glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11308 glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11309 ASSERT_GL_NO_ERROR();
11310
11311 drawQuad(mProgram, "position", 0.5f);
11312 ASSERT_GL_NO_ERROR();
11313 }
11314
11315 // Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
TEST_P(Texture3DTestES3,BasicUnpackBufferOOB)11316 TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
11317 {
11318 // 2D tests
11319 {
11320 GLTexture tex;
11321 glBindTexture(GL_TEXTURE_2D, tex);
11322
11323 GLBuffer pbo;
11324 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
11325
11326 // Test OOB
11327 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
11328 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11329 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
11330
11331 // Test OOB
11332 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
11333 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11334 ASSERT_GL_NO_ERROR();
11335 }
11336
11337 // 3D tests
11338 {
11339 GLTexture tex;
11340 glBindTexture(GL_TEXTURE_3D, tex);
11341
11342 GLBuffer pbo;
11343 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
11344
11345 // Test OOB
11346 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
11347 GL_STATIC_DRAW);
11348 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11349 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
11350
11351 // Test OOB
11352 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
11353 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
11354 ASSERT_GL_NO_ERROR();
11355 }
11356 }
11357
11358 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES3,SingleTextureMultipleSamplers)11359 TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
11360 {
11361 GLint maxTextureUnits = 0;
11362 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
11363 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
11364
11365 constexpr int kSize = 16;
11366
11367 // Make a single-level texture, fill it with red.
11368 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
11369 GLTexture tex;
11370 glBindTexture(GL_TEXTURE_2D, tex);
11371 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11372 redColors.data());
11373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11375
11376 // Simple confidence check.
11377 draw2DTexturedQuad(0.5f, 1.0f, true);
11378 ASSERT_GL_NO_ERROR();
11379 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
11380
11381 // Bind texture to unit 1 with a sampler object making it incomplete.
11382 GLSampler sampler;
11383 glBindSampler(0, sampler);
11384 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11385 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11386
11387 // Make a mipmap texture, fill it with blue.
11388 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
11389 GLTexture mipmapTex;
11390 glBindTexture(GL_TEXTURE_2D, mipmapTex);
11391 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11392 blueColors.data());
11393 glGenerateMipmap(GL_TEXTURE_2D);
11394
11395 // Draw with the sampler, expect blue.
11396 draw2DTexturedQuad(0.5f, 1.0f, true);
11397 ASSERT_GL_NO_ERROR();
11398 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
11399
11400 // Simple multitexturing program.
11401 constexpr char kVS[] =
11402 "#version 300 es\n"
11403 "in vec2 position;\n"
11404 "out vec2 texCoord;\n"
11405 "void main()\n"
11406 "{\n"
11407 " gl_Position = vec4(position, 0, 1);\n"
11408 " texCoord = position * 0.5 + vec2(0.5);\n"
11409 "}";
11410
11411 constexpr char kFS[] =
11412 "#version 300 es\n"
11413 "precision mediump float;\n"
11414 "in vec2 texCoord;\n"
11415 "uniform sampler2D tex1;\n"
11416 "uniform sampler2D tex2;\n"
11417 "uniform sampler2D tex3;\n"
11418 "uniform sampler2D tex4;\n"
11419 "out vec4 color;\n"
11420 "void main()\n"
11421 "{\n"
11422 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
11423 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
11424 "}";
11425
11426 ANGLE_GL_PROGRAM(program, kVS, kFS);
11427
11428 std::array<GLint, 4> texLocations = {
11429 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
11430 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
11431 for (GLint location : texLocations)
11432 {
11433 ASSERT_NE(-1, location);
11434 }
11435
11436 // Init the uniform data.
11437 glUseProgram(program);
11438 for (GLint location = 0; location < 4; ++location)
11439 {
11440 glUniform1i(texLocations[location], location);
11441 }
11442
11443 // Initialize four samplers
11444 GLSampler samplers[4];
11445
11446 // 0: non-mipped.
11447 glBindSampler(0, samplers[0]);
11448 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11449 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11450
11451 // 1: mipped.
11452 glBindSampler(1, samplers[1]);
11453 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11454 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11455
11456 // 2: non-mipped.
11457 glBindSampler(2, samplers[2]);
11458 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11459 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11460
11461 // 3: mipped.
11462 glBindSampler(3, samplers[3]);
11463 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11464 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11465
11466 // Bind two blue mipped textures and two single layer textures, should all draw.
11467 glActiveTexture(GL_TEXTURE0);
11468 glBindTexture(GL_TEXTURE_2D, tex);
11469
11470 glActiveTexture(GL_TEXTURE1);
11471 glBindTexture(GL_TEXTURE_2D, mipmapTex);
11472
11473 glActiveTexture(GL_TEXTURE2);
11474 glBindTexture(GL_TEXTURE_2D, tex);
11475
11476 glActiveTexture(GL_TEXTURE3);
11477 glBindTexture(GL_TEXTURE_2D, mipmapTex);
11478
11479 ASSERT_GL_NO_ERROR();
11480
11481 drawQuad(program, "position", 0.5f);
11482 ASSERT_GL_NO_ERROR();
11483 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
11484
11485 // Bind four single layer textures, two should be incomplete.
11486 glActiveTexture(GL_TEXTURE1);
11487 glBindTexture(GL_TEXTURE_2D, tex);
11488
11489 glActiveTexture(GL_TEXTURE3);
11490 glBindTexture(GL_TEXTURE_2D, tex);
11491
11492 drawQuad(program, "position", 0.5f);
11493 ASSERT_GL_NO_ERROR();
11494 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
11495 }
11496
11497 // The test is added to cover http://anglebug.com/42260889. Cubemap completeness checks used to
11498 // start always at level 0 instead of the base level resulting in an incomplete texture if the faces
11499 // at level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
11500 // level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
11501 // samples the cubemap using a direction vector (1,1,1).
TEST_P(TextureCubeTestES3,SpecifyAndSampleFromBaseLevel1)11502 TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
11503 {
11504 // Check http://anglebug.com/42260891.
11505 ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA());
11506
11507 constexpr char kVS[] =
11508 R"(#version 300 es
11509 precision mediump float;
11510 in vec3 pos;
11511 void main() {
11512 gl_Position = vec4(pos, 1.0);
11513 })";
11514
11515 constexpr char kFS[] =
11516 R"(#version 300 es
11517 precision mediump float;
11518 out vec4 color;
11519 uniform samplerCube uTex;
11520 void main(){
11521 color = texture(uTex, vec3(1.0));
11522 })";
11523
11524 ANGLE_GL_PROGRAM(program, kVS, kFS);
11525 glUseProgram(program);
11526
11527 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
11528 glActiveTexture(GL_TEXTURE0);
11529
11530 GLTexture cubeTex;
11531 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
11532
11533 const int kFaceWidth = 1;
11534 const int kFaceHeight = 1;
11535 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
11536 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11537 GL_UNSIGNED_BYTE, texData.data());
11538 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11539 GL_UNSIGNED_BYTE, texData.data());
11540 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11541 GL_UNSIGNED_BYTE, texData.data());
11542 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11543 GL_UNSIGNED_BYTE, texData.data());
11544 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11545 GL_UNSIGNED_BYTE, texData.data());
11546 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
11547 GL_UNSIGNED_BYTE, texData.data());
11548 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11549 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11550 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
11551 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
11552 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
11553 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
11554
11555 drawQuad(program, "pos", 0.5f, 1.0f, true);
11556 ASSERT_GL_NO_ERROR();
11557
11558 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
11559 }
11560
11561 // Test GL_PIXEL_UNPACK_BUFFER with GL_TEXTURE_CUBE_MAP.
TEST_P(TextureCubeTestES3,CubeMapPixelUnpackBuffer)11562 TEST_P(TextureCubeTestES3, CubeMapPixelUnpackBuffer)
11563 {
11564 // Check http://anglebug.com/42260891.
11565 ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA());
11566
11567 constexpr char kVS[] =
11568 R"(#version 300 es
11569 precision mediump float;
11570 in vec3 pos;
11571 void main() {
11572 gl_Position = vec4(pos, 1.0);
11573 })";
11574
11575 constexpr char kFS[] =
11576 R"(#version 300 es
11577 precision mediump float;
11578 out vec4 color;
11579 uniform samplerCube uTex;
11580 void main(){
11581 color = texture(uTex, vec3(1.0));
11582 })";
11583
11584 ANGLE_GL_PROGRAM(program, kVS, kFS);
11585 glUseProgram(program);
11586
11587 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
11588 glActiveTexture(GL_TEXTURE0);
11589
11590 GLTexture cubeTex;
11591 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
11592
11593 const int kFaceWidth = 4;
11594 const int kFaceHeight = 4;
11595
11596 uint16_t kHalfFloatOne = 0x3C00;
11597 uint16_t kHalfFloatZero = 0;
11598
11599 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA16F, kFaceWidth, kFaceHeight);
11600 struct RGBA16F
11601 {
11602 uint16_t R, G, B, A;
11603 };
11604 RGBA16F redColor = {kHalfFloatOne, kHalfFloatZero, kHalfFloatZero, kHalfFloatOne};
11605
11606 std::vector<RGBA16F> pixels(kFaceWidth * kFaceHeight, redColor);
11607 GLBuffer buffer;
11608 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
11609 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(RGBA16F), pixels.data(),
11610 GL_DYNAMIC_DRAW);
11611 EXPECT_GL_NO_ERROR();
11612 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
11613
11614 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
11615 {
11616 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, 0, 0, 0, kFaceWidth,
11617 kFaceHeight, GL_RGBA, GL_HALF_FLOAT, 0);
11618 EXPECT_GL_NO_ERROR();
11619 }
11620 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
11621
11622 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
11623 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
11624 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
11625 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
11626 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
11627
11628 drawQuad(program, "pos", 0.5f, 1.0f, true);
11629 ASSERT_GL_NO_ERROR();
11630
11631 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::red);
11632 }
11633
11634 // Test creating a mutable cubemap, committing it, and then incomaptibly redefining one layer, while
11635 // compatibly redefining another layer.
TEST_P(TextureCubeTestES3,IncompatibleLayerAThenCompatibleLayerB)11636 TEST_P(TextureCubeTestES3, IncompatibleLayerAThenCompatibleLayerB)
11637 {
11638 GLTexture tex;
11639 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11640
11641 std::vector<uint32_t> data(32 * 32 * 4, 0xC00FFC00);
11642
11643 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11644 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11645 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11646 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11647 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11648 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11649 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11650 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11651 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11652 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11653 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11654 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11655 glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11656 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11657 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11658 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11659 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11660 EXPECT_GL_NO_ERROR();
11661 }
11662
11663 // Test creating a mutable cubemap, committing it, and then comaptibly redefining one layer, while
11664 // incompatibly redefining another layer.
TEST_P(TextureCubeTestES3,CompatibleLayerAThenIncompatibleLayerB)11665 TEST_P(TextureCubeTestES3, CompatibleLayerAThenIncompatibleLayerB)
11666 {
11667 GLTexture tex;
11668 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11669
11670 std::vector<uint32_t> data(32 * 32 * 4, 0xC00FFC00);
11671
11672 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11673 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11674 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11675 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11676 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11677 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11678 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11679 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11680 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11681 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11682 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11683 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11684 glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11685 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11686 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11687 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11688 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11689 EXPECT_GL_NO_ERROR();
11690 }
11691
11692 // Test creating a mutable cubemap, committing it, and then incomaptibly redefining two layers,
11693 // while compatibly redefining another layer.
TEST_P(TextureCubeTestES3,IncompatibleLayerABThenCompatibleLayerC)11694 TEST_P(TextureCubeTestES3, IncompatibleLayerABThenCompatibleLayerC)
11695 {
11696 GLTexture tex;
11697 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11698
11699 std::vector<uint32_t> data(32 * 32 * 4, 0xC00FFC00);
11700
11701 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11702 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11703 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11704 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11705 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11706 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11707 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11708 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11709 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11710 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11711 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11712 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11713 glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11714 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11715 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11716 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, 32, 32, 0, GL_RGBA,
11717 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11718 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, 16, 16, 0, GL_RGBA,
11719 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11720 EXPECT_GL_NO_ERROR();
11721 }
11722
11723 // Test creating a mutable cubemap, committing it, and then incomaptibly redefining two layers and
11724 // compatibly redefining them again.
TEST_P(TextureCubeTestES3,IncompatibleLayerABThenCompatibleLayerAB)11725 TEST_P(TextureCubeTestES3, IncompatibleLayerABThenCompatibleLayerAB)
11726 {
11727 GLTexture tex;
11728 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11729
11730 constexpr uint32_t kSize = 64;
11731
11732 std::vector<uint32_t> data(kSize * kSize * 4 * 4, 0xC00FFC00);
11733 std::vector<uint32_t> data2(kSize * kSize * 4 * 4, 0xC00003FF);
11734
11735 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11736 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11737 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11738 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11739 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11740 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11741 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11742 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11743 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11744 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11745 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11746 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11747 glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
11748 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11749 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11750 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11751 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11752 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11753 GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11754 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11755 GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11756
11757 glActiveTexture(GL_TEXTURE0);
11758 glBindTexture(GL_TEXTURE_2D, 0);
11759 glActiveTexture(GL_TEXTURE1);
11760 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11761
11762 glUseProgram(mProgram);
11763 glUniform1i(mTexture2DUniformLocation, 0);
11764 glUniform1i(mTextureCubeUniformLocation, 1);
11765
11766 const int w = getWindowWidth();
11767 const int h = getWindowHeight();
11768
11769 for (uint32_t i = 0; i < 6; ++i)
11770 {
11771 glUniform1i(mTextureCubeFaceUniformLocation, i);
11772 glClear(GL_COLOR_BUFFER_BIT);
11773 drawQuad(mProgram, "position", 0.5f);
11774
11775 const bool expectRed = i == 2 || i == 5;
11776 const GLColor expect = expectRed ? GLColor::red : GLColor::green;
11777 EXPECT_PIXEL_RECT_EQ(2, 2, w - 4, h - 4, expect);
11778 EXPECT_GL_NO_ERROR();
11779 }
11780 }
11781
11782 // Similar to IncompatibleLayerABThenCompatibleLayerAB, but with a single-level texture
TEST_P(TextureCubeTestES3,IncompatibleLayerABThenCompatibleLayerABSingleLevel)11783 TEST_P(TextureCubeTestES3, IncompatibleLayerABThenCompatibleLayerABSingleLevel)
11784 {
11785 GLTexture tex;
11786 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11787
11788 constexpr uint32_t kSize = 64;
11789
11790 std::vector<uint32_t> data(kSize * kSize * 4 * 4, 0xC00FFC00);
11791 std::vector<uint32_t> data2(kSize * kSize * 4 * 4, 0xC00003FF);
11792
11793 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11794 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11795 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11796 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11797 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11798 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11799 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11800 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11801 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11802 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11803 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11804 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11805
11806 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
11807 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11808
11809 glActiveTexture(GL_TEXTURE0);
11810 glBindTexture(GL_TEXTURE_2D, 0);
11811 glActiveTexture(GL_TEXTURE1);
11812 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
11813
11814 glUseProgram(mProgram);
11815 glUniform1i(mTexture2DUniformLocation, 0);
11816 glUniform1i(mTextureCubeUniformLocation, 1);
11817
11818 const int w = getWindowWidth();
11819 const int h = getWindowHeight();
11820
11821 for (uint32_t i = 0; i < 6; ++i)
11822 {
11823 glUniform1i(mTextureCubeFaceUniformLocation, i);
11824 glClear(GL_COLOR_BUFFER_BIT);
11825 drawQuad(mProgram, "position", 0.5f);
11826
11827 EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::green);
11828 EXPECT_GL_NO_ERROR();
11829 }
11830
11831 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11832 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11833 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize * 2, kSize * 2, 0, GL_RGBA,
11834 GL_UNSIGNED_INT_2_10_10_10_REV, data.data());
11835 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11836 GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11837 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB10_A2, kSize, kSize, 0, GL_RGBA,
11838 GL_UNSIGNED_INT_2_10_10_10_REV, data2.data());
11839
11840 for (uint32_t i = 0; i < 6; ++i)
11841 {
11842 glUniform1i(mTextureCubeFaceUniformLocation, i);
11843 glClear(GL_COLOR_BUFFER_BIT);
11844 drawQuad(mProgram, "position", 0.5f);
11845
11846 const bool expectRed = i == 2 || i == 5;
11847 const GLColor expect = expectRed ? GLColor::red : GLColor::green;
11848 EXPECT_PIXEL_RECT_EQ(2, 2, w - 4, h - 4, expect);
11849 EXPECT_GL_NO_ERROR();
11850 }
11851 }
11852
11853 // Test that the maximum texture layer can allocate enough memory.
TEST_P(TextureCubeTestES32,MaxArrayTextureLayersVerify)11854 TEST_P(TextureCubeTestES32, MaxArrayTextureLayersVerify)
11855 {
11856 GLint maxTextureLayers = 0;
11857 GLTexture texture;
11858
11859 glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
11860 ASSERT_GL_NO_ERROR();
11861
11862 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
11863 ASSERT_GL_NO_ERROR();
11864
11865 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 256, 256, maxTextureLayers, 0, GL_RGBA,
11866 GL_UNSIGNED_BYTE, nullptr);
11867 ASSERT_GL_NO_ERROR();
11868
11869 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 256, 256, maxTextureLayers + 1, 0, GL_RGBA,
11870 GL_UNSIGNED_BYTE, nullptr);
11871 EXPECT_GL_ERROR(GL_INVALID_VALUE);
11872
11873 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 256, 256, maxTextureLayers);
11874 ASSERT_GL_NO_ERROR();
11875
11876 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 256, 256, maxTextureLayers + 1);
11877 EXPECT_GL_ERROR(GL_INVALID_VALUE);
11878 }
11879
11880 // Tests defining a cube map array texture using glTexImage3D().
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexImage)11881 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexImage)
11882 {
11883 GLTexture cubeMapArrayTexture;
11884 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11885
11886 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11887 nullptr);
11888 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, 128, 128, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11889 nullptr);
11890 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, GL_RGBA, 64, 64, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11891 nullptr);
11892 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 3, GL_RGBA, 32, 32, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11893 nullptr);
11894 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 4, GL_RGBA, 16, 16, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11895 nullptr);
11896 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 5, GL_RGBA, 8, 8, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11897 nullptr);
11898 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 6, GL_RGBA, 4, 4, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11899 nullptr);
11900 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 7, GL_RGBA, 2, 2, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11901 nullptr);
11902 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 8, GL_RGBA, 1, 1, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11903 nullptr);
11904 EXPECT_GL_NO_ERROR();
11905 }
11906
11907 // Tests defining a cube map array texture using glTexStorage3D() and filling all levels using
11908 // glTexSubImage3D().
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexStorage)11909 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexStorage)
11910 {
11911 GLTexture cubeMapArrayTexture;
11912 std::vector<GLColor> cubeMapArrayData(256 * 256 * 24, GLColor::red);
11913 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11914
11915 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 9, GL_RGBA8, 256, 256, 24);
11916 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, 256, 256, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11917 cubeMapArrayData.data());
11918 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, 0, 0, 0, 128, 128, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11919 cubeMapArrayData.data());
11920 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, 0, 0, 0, 64, 64, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11921 cubeMapArrayData.data());
11922 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 3, 0, 0, 0, 32, 32, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11923 cubeMapArrayData.data());
11924 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 4, 0, 0, 0, 16, 16, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11925 cubeMapArrayData.data());
11926 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 5, 0, 0, 0, 8, 8, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11927 cubeMapArrayData.data());
11928 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 6, 0, 0, 0, 4, 4, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11929 cubeMapArrayData.data());
11930 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 7, 0, 0, 0, 2, 2, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11931 cubeMapArrayData.data());
11932 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 8, 0, 0, 0, 1, 1, 24, GL_RGBA, GL_UNSIGNED_BYTE,
11933 cubeMapArrayData.data());
11934 EXPECT_GL_NO_ERROR();
11935 }
11936
11937 // Tests defining a single-level cube map array texture and modifying a part of it with unequal
11938 // width and height and a depth that is not a multiple of 6.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexStorageModifyPartially)11939 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexStorageModifyPartially)
11940 {
11941 GLTexture cubeMapArrayTexture;
11942 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11943
11944 std::vector<GLColor> cubeMapArrayData(256 * 256 * 6, GLColor::red);
11945 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, 6);
11946 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, 256, 100, 1, GL_RGBA, GL_UNSIGNED_BYTE,
11947 cubeMapArrayData.data());
11948 EXPECT_GL_NO_ERROR();
11949 }
11950
11951 // Tests TexSubImage3D with cube map arrays using dims beyond the size limit.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexSubImageGreaterThanSizeLimit)11952 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexSubImageGreaterThanSizeLimit)
11953 {
11954 GLTexture cubeMapArrayTexture;
11955 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11956
11957 GLint max3DTextureSize = -1;
11958 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
11959 EXPECT_GT(max3DTextureSize, 0);
11960
11961 GLint maxCubeTextureSize = -1;
11962 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
11963 EXPECT_GT(maxCubeTextureSize, 0);
11964
11965 GLint maxSizeLimit = std::min(maxCubeTextureSize, max3DTextureSize);
11966 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxSizeLimit, maxSizeLimit, 6, 0, GL_RGBA,
11967 GL_UNSIGNED_BYTE, nullptr);
11968 ASSERT_GL_NO_ERROR();
11969
11970 // TexSubImage3D can take unequal values for width and height for cube map arrays. However, they
11971 // should stay below the size limit.
11972 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, maxSizeLimit + 1, maxSizeLimit, 6,
11973 GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
11974 EXPECT_GL_ERROR(GL_INVALID_VALUE);
11975
11976 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, maxSizeLimit, maxSizeLimit + 1, 6,
11977 GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
11978 EXPECT_GL_ERROR(GL_INVALID_VALUE);
11979 }
11980
11981 // Tests invalid dim/level input for TexImage3D with cube map arrays.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexImageInvalidInputs)11982 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexImageInvalidInputs)
11983 {
11984 GLTexture cubeMapArrayTexture;
11985 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
11986
11987 // Negative level and dimensions are not accepted.
11988 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, -1, GL_RGBA, 256, 256, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11989 nullptr);
11990 EXPECT_GL_ERROR(GL_INVALID_VALUE);
11991
11992 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, -1, 256, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11993 nullptr);
11994 EXPECT_GL_ERROR(GL_INVALID_VALUE);
11995
11996 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, -1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
11997 nullptr);
11998 EXPECT_GL_ERROR(GL_INVALID_VALUE);
11999
12000 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, -6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12001 nullptr);
12002 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12003
12004 // As the number of layer-faces, depth should be a multiple of 6, unless it is partially being
12005 // modified (via TexSubImage).
12006 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12007 nullptr);
12008 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12009
12010 // Width and height should be equal, unless it is partially being modified (via TexSubImage).
12011 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 100, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12012 nullptr);
12013 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12014
12015 // Width and height should not exceed the maximum cube map texture size for that mip level.
12016 GLint maxCubeTextureSize = -1;
12017 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
12018 EXPECT_GT(maxCubeTextureSize, 0);
12019
12020 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxCubeTextureSize + 1, maxCubeTextureSize,
12021 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12022 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12023
12024 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxCubeTextureSize, maxCubeTextureSize + 1,
12025 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12026 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12027
12028 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, maxCubeTextureSize + 1,
12029 maxCubeTextureSize + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12030 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12031
12032 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, maxCubeTextureSize / 2 + 1,
12033 maxCubeTextureSize / 2 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12034 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12035
12036 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, GL_RGBA, maxCubeTextureSize / 4 + 1,
12037 maxCubeTextureSize / 4 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12038 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12039
12040 // Width and height and depth should not exceed the maximum 3D texture size.
12041 GLint max3DTextureSize = -1;
12042 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
12043 EXPECT_GT(max3DTextureSize, 0);
12044
12045 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 256, 256, max3DTextureSize + 1, 0, GL_RGBA,
12046 GL_UNSIGNED_BYTE, nullptr);
12047 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12048
12049 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, max3DTextureSize + 1, max3DTextureSize + 1,
12050 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12051 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12052
12053 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, max3DTextureSize / 2 + 1,
12054 max3DTextureSize / 2 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12055 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12056
12057 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 2, GL_RGBA, max3DTextureSize / 4 + 1,
12058 max3DTextureSize / 4 + 1, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
12059 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12060 }
12061
12062 // Tests invalid dim/level input for TexStorage3D with cube map arrays.
TEST_P(TextureCubeTestES32,ValidateCubeMapArrayTexStorageInvalidInputs)12063 TEST_P(TextureCubeTestES32, ValidateCubeMapArrayTexStorageInvalidInputs)
12064 {
12065 GLTexture cubeMapArrayTexture;
12066 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, cubeMapArrayTexture);
12067
12068 // Negative level and dimensions are not accepted.
12069 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, -1, GL_RGBA8, 256, 256, 6);
12070 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12071
12072 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, -1, 256, 6);
12073 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12074
12075 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, -1, 6);
12076 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12077
12078 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, -6);
12079 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12080
12081 // As the number of layer-faces, depth should be a multiple of 6.
12082 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, 1);
12083 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12084
12085 // Width and height should be equal.
12086 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 100, 6);
12087 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12088
12089 // Width and height should not exceed the maximum cube map texture size.
12090 GLint maxCubeTextureSize = -1;
12091 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
12092 EXPECT_GT(maxCubeTextureSize, 0);
12093
12094 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, maxCubeTextureSize + 1,
12095 maxCubeTextureSize + 1, 6);
12096 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12097
12098 // Width and height and depth should not exceed the maximum 3D texture size.
12099 GLint max3DTextureSize = -1;
12100 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
12101 EXPECT_GT(max3DTextureSize, 0);
12102
12103 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, max3DTextureSize + 1,
12104 max3DTextureSize + 1, 6);
12105 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12106
12107 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 256, 256, max3DTextureSize + 1);
12108 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12109
12110 // Level count must not exceed log2(max(width, height)) + 1.
12111 GLint maxLevelCount256 = 1 + static_cast<GLint>(std::log2(256));
12112 glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, maxLevelCount256 + 1, GL_RGBA8, 256, 256, 6);
12113 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12114 }
12115
12116 // Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
TEST_P(Texture2DTestES3,NegativeTextureBaseLevelAndMaxLevel)12117 TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
12118 {
12119 GLuint texture = create2DTexture();
12120
12121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
12122 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12123
12124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
12125 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12126
12127 glDeleteTextures(1, &texture);
12128 EXPECT_GL_NO_ERROR();
12129 }
12130
12131 // Test setting base level after calling generateMipmap on a LUMA texture.
12132 // Covers http://anglebug.com/42261204
TEST_P(Texture2DTestES3,GenerateMipmapAndBaseLevelLUMA)12133 TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
12134 {
12135 glActiveTexture(GL_TEXTURE0);
12136 glBindTexture(GL_TEXTURE_2D, mTexture2D);
12137
12138 constexpr const GLsizei kWidth = 8;
12139 constexpr const GLsizei kHeight = 8;
12140 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
12141 whiteData.fill(255u);
12142
12143 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
12144 GL_UNSIGNED_BYTE, whiteData.data());
12145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
12146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
12147 glGenerateMipmap(GL_TEXTURE_2D);
12148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
12149 EXPECT_GL_NO_ERROR();
12150
12151 drawQuad(mProgram, "position", 0.5f);
12152 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
12153 }
12154
12155 // Incompatible levels with non-mipmap filtering should work.
TEST_P(Texture2DTestES3,IncompatibleMipsButNoMipmapFiltering)12156 TEST_P(Texture2DTestES3, IncompatibleMipsButNoMipmapFiltering)
12157 {
12158 // http://anglebug.com/42263372
12159 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsWindows() && (IsAMD() || IsIntel()));
12160
12161 // http://anglebug.com/40096708
12162 ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsNVIDIAShield());
12163
12164 glActiveTexture(GL_TEXTURE0);
12165 glBindTexture(GL_TEXTURE_2D, mTexture2D);
12166
12167 constexpr const GLsizei kSize = 8;
12168 const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
12169 const std::vector<GLColor> kLevel1Data(kSize * kSize, GLColor::red);
12170
12171 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12172 kLevel0Data.data());
12173 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12174 kLevel1Data.data());
12175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
12176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
12177 EXPECT_GL_NO_ERROR();
12178
12179 // Draw with base level 0. The GL_LINEAR filtering ensures the texture's image is not created
12180 // with mipmap.
12181 drawQuad(mProgram, "position", 0.5f);
12182 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
12183
12184 // Verify draw with level 1.
12185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
12186 drawQuad(mProgram, "position", 0.5f);
12187 EXPECT_GL_NO_ERROR();
12188 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel1Data[0]);
12189
12190 // Verify draw with level 0 again
12191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
12192 drawQuad(mProgram, "position", 0.5f);
12193 EXPECT_GL_NO_ERROR();
12194 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
12195 }
12196
12197 // A collection of negative tests for QCOM foveated rendering extensions
TEST_P(Texture2DTestES3Foveation,NegativeTests)12198 TEST_P(Texture2DTestES3Foveation, NegativeTests)
12199 {
12200 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated") ||
12201 !IsGLExtensionEnabled("GL_QCOM_texture_foveated"));
12202
12203 // Switch to foveated framebuffer
12204 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12205
12206 // QCOM framebuffer foveated tests
12207 GLuint providedFeatures = 0;
12208
12209 // Test invalid numLayers
12210 glFramebufferFoveationConfigQCOM(mFramebuffer, std::numeric_limits<uint32_t>::max(), 1,
12211 GL_FOVEATION_ENABLE_BIT_QCOM, &providedFeatures);
12212 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12213
12214 // Test invalid focal points
12215 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, std::numeric_limits<uint32_t>::max(),
12216 GL_FOVEATION_ENABLE_BIT_QCOM, &providedFeatures);
12217 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12218
12219 // Test setting foveation parameters on a framebuffer that is not configured
12220 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12221 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12222
12223 // Configure framebuffer correctly
12224 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12225 &providedFeatures);
12226 EXPECT_GL_NO_ERROR();
12227 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12228
12229 // Try to configure it again
12230 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12231 &providedFeatures);
12232 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12233
12234 // Set foveation parameters
12235 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12236 EXPECT_GL_NO_ERROR();
12237
12238 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12239
12240 GLTexture texture;
12241 glActiveTexture(GL_TEXTURE0);
12242 glBindTexture(GL_TEXTURE_2D, texture);
12243 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
12244 GL_UNSIGNED_BYTE, nullptr);
12245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12246 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12247 EXPECT_GL_NO_ERROR();
12248
12249 // Change attachments and try to perform a clear and draw
12250 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
12251 ASSERT_GL_NO_ERROR();
12252
12253 glUseProgram(mProgram);
12254
12255 // Clear
12256 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
12257 glClear(GL_COLOR_BUFFER_BIT);
12258 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12259
12260 // Draw
12261 drawQuad(mProgram, "position", 0.5f);
12262 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12263
12264 // QCOM texture foveated tests
12265 glBindTexture(GL_TEXTURE_2D, texture);
12266 // Test invalid feature bit
12267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12268 GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM);
12269 EXPECT_GL_ERROR(GL_INVALID_ENUM);
12270
12271 // Test setting foveation parameters on a framebuffer that is not configured
12272 glTextureFoveationParametersQCOM(texture, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12273 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
12274
12275 // Configure texture
12276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12277 GL_FOVEATION_ENABLE_BIT_QCOM);
12278 EXPECT_GL_NO_ERROR();
12279
12280 // Test invalid focal points
12281 GLint supportedNumFocalPoints = 0;
12282 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM,
12283 &supportedNumFocalPoints);
12284 EXPECT_GL_NO_ERROR();
12285
12286 glTextureFoveationParametersQCOM(texture, 0, supportedNumFocalPoints + 1, 0.0f, 0.0f, 8.0f,
12287 8.0f, 0.0f);
12288 EXPECT_GL_ERROR(GL_INVALID_VALUE);
12289
12290 // Attach foveated texture while framebuffer is also fovated and check framebuffer completeness
12291 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
12292 ASSERT_GL_NO_ERROR();
12293 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM,
12294 glCheckFramebufferStatus(GL_FRAMEBUFFER));
12295
12296 // Attach multiple foveated textures to an un-foveated framebuffer and check completeness
12297 GLFramebuffer fbo;
12298 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
12299 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
12300 ASSERT_GL_NO_ERROR();
12301 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12302
12303 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
12304 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
12305 GL_UNSIGNED_BYTE, nullptr);
12306 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12307 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12308 EXPECT_GL_NO_ERROR();
12309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12310 GL_FOVEATION_ENABLE_BIT_QCOM);
12311 EXPECT_GL_NO_ERROR();
12312
12313 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
12314 mFramebufferColorTexture, 0);
12315 ASSERT_GL_NO_ERROR();
12316 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM,
12317 glCheckFramebufferStatus(GL_FRAMEBUFFER));
12318 }
12319
12320 // QCOM framebuffer foveated rendering + clear
TEST_P(Texture2DTestES3Foveation,Clear)12321 TEST_P(Texture2DTestES3Foveation, Clear)
12322 {
12323 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12324
12325 // Switch to foveated framebuffer
12326 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12327
12328 // Just need 1 focal point
12329 GLuint providedFeatures = 0;
12330 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12331 &providedFeatures);
12332 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12333 // Set foveation parameters
12334 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12335 EXPECT_GL_NO_ERROR();
12336
12337 // Clear
12338 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12339 glClear(GL_COLOR_BUFFER_BIT);
12340 EXPECT_GL_NO_ERROR();
12341
12342 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12343 }
12344
12345 // QCOM framebuffer foveated rendering + clear then draw
TEST_P(Texture2DTestES3Foveation,ClearThenDraw)12346 TEST_P(Texture2DTestES3Foveation, ClearThenDraw)
12347 {
12348 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12349
12350 // Switch to foveated framebuffer
12351 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12352
12353 // Just need 1 focal point
12354 GLuint providedFeatures = 0;
12355 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12356 &providedFeatures);
12357 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12358 // Set foveation parameters
12359 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12360 EXPECT_GL_NO_ERROR();
12361
12362 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12363 glUseProgram(program);
12364
12365 // Clear
12366 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12367 glClear(GL_COLOR_BUFFER_BIT);
12368 EXPECT_GL_NO_ERROR();
12369
12370 // Draw
12371 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12372 EXPECT_GL_NO_ERROR();
12373
12374 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12375 }
12376
12377 // QCOM framebuffer foveated rendering with rendebuffer attachment + clear then draw
TEST_P(Texture2DTestES3Foveation,RenderbufferAttachmentClearThenDraw)12378 TEST_P(Texture2DTestES3Foveation, RenderbufferAttachmentClearThenDraw)
12379 {
12380 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12381
12382 // Switch to foveated framebuffer and attach a renderbuffer
12383 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12384 GLRenderbuffer renderbuffer;
12385 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
12386 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
12387 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
12388 EXPECT_GL_NO_ERROR();
12389
12390 // Just need 1 focal point
12391 GLuint providedFeatures = 0;
12392 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12393 &providedFeatures);
12394 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12395 // Set foveation parameters
12396 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12397 EXPECT_GL_NO_ERROR();
12398
12399 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12400 glUseProgram(program);
12401
12402 // Clear
12403 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12404 glClear(GL_COLOR_BUFFER_BIT);
12405 EXPECT_GL_NO_ERROR();
12406
12407 // Draw
12408 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12409 EXPECT_GL_NO_ERROR();
12410
12411 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12412 }
12413
12414 // QCOM framebuffer foveated rendering + draw, clear then draw
TEST_P(Texture2DTestES3Foveation,DrawClearDraw)12415 TEST_P(Texture2DTestES3Foveation, DrawClearDraw)
12416 {
12417 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12418
12419 // Switch to foveated framebuffer
12420 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12421
12422 // Just need 1 focal point
12423 GLuint providedFeatures = 0;
12424 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12425 &providedFeatures);
12426 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12427 // Set foveation parameters
12428 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12429 EXPECT_GL_NO_ERROR();
12430
12431 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12432 glUseProgram(greenProgram);
12433
12434 // Draw
12435 drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12436 EXPECT_GL_NO_ERROR();
12437
12438 // Clear
12439 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
12440 glClear(GL_COLOR_BUFFER_BIT);
12441 EXPECT_GL_NO_ERROR();
12442
12443 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12444 glUseProgram(blueProgram);
12445
12446 // Draw
12447 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12448 EXPECT_GL_NO_ERROR();
12449
12450 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12451 }
12452
12453 // QCOM framebuffer foveated rendering - draw before and after enabling foveation
TEST_P(Texture2DTestES3Foveation,DrawThenEnableFoveationAndDraw)12454 TEST_P(Texture2DTestES3Foveation, DrawThenEnableFoveationAndDraw)
12455 {
12456 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12457
12458 // Switch to foveated framebuffer
12459 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12460
12461 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12462
12463 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12464 glUseProgram(program);
12465
12466 // Clear
12467 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12468 glClear(GL_COLOR_BUFFER_BIT);
12469 EXPECT_GL_NO_ERROR();
12470
12471 // Draw
12472 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12473 EXPECT_GL_NO_ERROR();
12474
12475 // Configure foveated rendering for framebuffer
12476 // Just need 1 focal point
12477 GLuint providedFeatures = 0;
12478 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12479 &providedFeatures);
12480 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12481 // Set foveation parameters
12482 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12483 EXPECT_GL_NO_ERROR();
12484
12485 // Draw
12486 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12487 EXPECT_GL_NO_ERROR();
12488
12489 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12490 }
12491
12492 // QCOM framebuffer foveated rendering + draw, change foveation parameters and then draw
TEST_P(Texture2DTestES3Foveation,DrawChangeFoveationParametersThenDraw)12493 TEST_P(Texture2DTestES3Foveation, DrawChangeFoveationParametersThenDraw)
12494 {
12495 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12496
12497 // Switch to foveated framebuffer
12498 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12499
12500 // Just need 1 focal point
12501 GLuint providedFeatures = 0;
12502 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12503 &providedFeatures);
12504 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12505 // Set foveation parameters
12506 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12507 EXPECT_GL_NO_ERROR();
12508
12509 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12510 glUseProgram(greenProgram);
12511
12512 // Draw
12513 drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12514 EXPECT_GL_NO_ERROR();
12515
12516 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12517
12518 // Change foveation parameters
12519 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.5f, 0.5f, 3.0f, 3.0f, 3.0f);
12520 EXPECT_GL_NO_ERROR();
12521
12522 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12523 glUseProgram(blueProgram);
12524
12525 // Draw
12526 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12527 EXPECT_GL_NO_ERROR();
12528
12529 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12530 }
12531
12532 // QCOM framebuffer foveated rendering + draw and use as blit source
TEST_P(Texture2DTestES3Foveation,DrawThenUseAsBlitSource)12533 TEST_P(Texture2DTestES3Foveation, DrawThenUseAsBlitSource)
12534 {
12535 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12536
12537 // Switch to foveated framebuffer
12538 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12539
12540 glActiveTexture(GL_TEXTURE0);
12541 glBindTexture(GL_TEXTURE_2D, mTexture2D);
12542
12543 const GLsizei kSizeW = getWindowWidth();
12544 const GLsizei kSizeH = getWindowHeight();
12545 std::vector<GLColor> data(kSizeW * kSizeH, GLColor::blue);
12546 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSizeW, kSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12547 data.data());
12548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12550 EXPECT_GL_NO_ERROR();
12551
12552 // Just need 1 focal point
12553 GLuint providedFeatures = 0;
12554 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12555 &providedFeatures);
12556 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12557 // Set foveation parameters
12558 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12559 EXPECT_GL_NO_ERROR();
12560
12561 glUseProgram(mProgram);
12562
12563 // Verify
12564 drawQuad(mProgram, "position", 0.5f);
12565 EXPECT_GL_NO_ERROR();
12566
12567 // Blit data from foveated framebuffer into default framebuffer
12568 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
12569 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
12570 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
12571 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
12572
12573 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12574 }
12575
12576 // QCOM framebuffer foveated rendering + draw and use as blit target
TEST_P(Texture2DTestES3Foveation,DrawThenUseAsBlitTarget)12577 TEST_P(Texture2DTestES3Foveation, DrawThenUseAsBlitTarget)
12578 {
12579 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12580
12581 // Switch to foveated framebuffer
12582 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12583
12584 // Just need 1 focal point
12585 GLuint providedFeatures = 0;
12586 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12587 &providedFeatures);
12588 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12589 // Set foveation parameters
12590 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12591 EXPECT_GL_NO_ERROR();
12592
12593 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12594 glUseProgram(greenProgram);
12595
12596 // Draw
12597 drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12598 EXPECT_GL_NO_ERROR();
12599 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12600
12601 // Switch to default framebuffer and clear to blue
12602 glBindFramebuffer(GL_FRAMEBUFFER, 0);
12603 EXPECT_GL_NO_ERROR();
12604 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12605 glClear(GL_COLOR_BUFFER_BIT);
12606 EXPECT_GL_NO_ERROR();
12607
12608 // Blit data from default framebuffer into foveated framebuffer
12609 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
12610 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
12611 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
12612 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
12613
12614 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12615 }
12616
12617 // QCOM framebuffer foveated rendering, reuse texture between 2 foveated framebuffers
TEST_P(Texture2DTestES3Foveation,ReuseTextureForFoveatedDraw)12618 TEST_P(Texture2DTestES3Foveation, ReuseTextureForFoveatedDraw)
12619 {
12620 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12621
12622 // Switch to foveated framebuffer
12623 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12624
12625 // Just need 1 focal point
12626 GLuint providedFeatures = 0;
12627 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12628 &providedFeatures);
12629 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12630 // Set foveation parameters
12631 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12632 EXPECT_GL_NO_ERROR();
12633
12634 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12635 glUseProgram(greenProgram);
12636
12637 // Draw
12638 drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12639 EXPECT_GL_NO_ERROR();
12640
12641 // Create another framebuffer
12642 GLFramebuffer framebuffer;
12643 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
12644
12645 // Resuse texture from mFramebuffer
12646 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12647 mFramebufferColorTexture, 0);
12648
12649 // Configure foveation parameters of the new framebuffer
12650 // Just need 1 focal point
12651 providedFeatures = 0;
12652 glFramebufferFoveationConfigQCOM(framebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12653 &providedFeatures);
12654 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12655 // Set foveation parameters
12656 glFramebufferFoveationParametersQCOM(framebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12657 EXPECT_GL_NO_ERROR();
12658
12659 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12660 glUseProgram(blueProgram);
12661
12662 // Draw
12663 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12664 EXPECT_GL_NO_ERROR();
12665
12666 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12667 }
12668
12669 // QCOM framebuffer foveated rendering with MSAA framebuffer
TEST_P(Texture2DTestES3Foveation,DrawWithMsaaFramebuffer)12670 TEST_P(Texture2DTestES3Foveation, DrawWithMsaaFramebuffer)
12671 {
12672 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12673 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
12674
12675 // Create a new MSAA framebuffer
12676 GLFramebuffer msaaFramebuffer;
12677 glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
12678 GLTexture texture;
12679 glActiveTexture(GL_TEXTURE0);
12680 glBindTexture(GL_TEXTURE_2D, texture);
12681 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
12682 GL_UNSIGNED_BYTE, nullptr);
12683 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12684 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12685 EXPECT_GL_NO_ERROR();
12686
12687 glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12688 texture, 0, 4);
12689 ASSERT_GL_NO_ERROR();
12690 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12691
12692 // Just need 1 focal point
12693 GLuint providedFeatures = 0;
12694 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12695 &providedFeatures);
12696 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12697 // Set foveation parameters
12698 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12699 EXPECT_GL_NO_ERROR();
12700
12701 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12702 glUseProgram(program);
12703
12704 // Clear
12705 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12706 glClear(GL_COLOR_BUFFER_BIT);
12707 EXPECT_GL_NO_ERROR();
12708
12709 // Draw
12710 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12711 EXPECT_GL_NO_ERROR();
12712
12713 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12714 }
12715
12716 // QCOM framebuffer foveated rendering with multiple attachments
TEST_P(Texture2DTestES3Foveation,DrawWithMultipleAttachments)12717 TEST_P(Texture2DTestES3Foveation, DrawWithMultipleAttachments)
12718 {
12719 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_framebuffer_foveated"));
12720
12721 const GLsizei kSizeW = getWindowWidth();
12722 const GLsizei kSizeH = getWindowHeight();
12723
12724 // Setup sampling texture
12725 glBindTexture(GL_TEXTURE_2D, mTexture2D);
12726
12727 std::vector<GLColor> data(kSizeW * kSizeH);
12728 // Generate red / blue checkered pattern
12729 for (int i = 0; i < kSizeH; i++)
12730 {
12731 for (int j = 0; j < kSizeW; j++)
12732 {
12733 data[(i * kSizeW) + j] = ((i + j) % 2 == 0) ? GLColor::red : GLColor::blue;
12734 }
12735 }
12736
12737 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSizeW, kSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12738 data.data());
12739 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12740 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12741 EXPECT_GL_NO_ERROR();
12742
12743 // Draw without foveation
12744 glActiveTexture(GL_TEXTURE0);
12745 glBindTexture(GL_TEXTURE_2D, mTexture2D);
12746
12747 glBindFramebuffer(GL_FRAMEBUFFER, 0);
12748 glUseProgram(mProgram);
12749 drawQuad(mProgram, "position", 0.5f);
12750 EXPECT_GL_NO_ERROR();
12751
12752 // Record original data
12753 std::vector<GLColor> originalData(kSizeW * kSizeH, {0, 0, 0, 0});
12754 glReadPixels(0, 0, kSizeW, kSizeH, GL_RGBA, GL_UNSIGNED_BYTE, originalData.data());
12755
12756 // Switch to foveated framebuffer
12757 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
12758
12759 // Setup mutliple color attachments
12760 std::array<GLTexture, 3> colorAttachments;
12761 GLenum attachmentBase = GL_COLOR_ATTACHMENT0;
12762 GLuint attachmentIndex = 0;
12763 for (GLTexture &attachment : colorAttachments)
12764 {
12765 glBindTexture(GL_TEXTURE_2D, attachment);
12766 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSizeW, kSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12767 nullptr);
12768 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12770 EXPECT_GL_NO_ERROR();
12771
12772 glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentBase + attachmentIndex, GL_TEXTURE_2D,
12773 attachment, 0);
12774 ASSERT_GL_NO_ERROR();
12775 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12776
12777 glBindTexture(GL_TEXTURE_2D, 0);
12778
12779 attachmentIndex++;
12780 }
12781
12782 // Setup foveation parameters, just need 1 focal point
12783 GLuint providedFeatures = 0;
12784 glFramebufferFoveationConfigQCOM(mFramebuffer, 1, 1, GL_FOVEATION_ENABLE_BIT_QCOM,
12785 &providedFeatures);
12786 ASSERT_NE(providedFeatures & GL_FOVEATION_ENABLE_BIT_QCOM, 0u);
12787
12788 glFramebufferFoveationParametersQCOM(mFramebuffer, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12789 EXPECT_GL_NO_ERROR();
12790
12791 constexpr char kFS[] = R"(#version 300 es
12792 precision highp float;
12793
12794 in vec2 texcoord;
12795 uniform sampler2D tex;
12796
12797 layout(location = 0) out vec4 color0;
12798 layout(location = 1) out vec4 color1;
12799 layout(location = 2) out vec4 color2;
12800
12801 void main()
12802 {
12803 vec4 fragColor = texture(tex, texcoord);
12804 color0 = fragColor;
12805 color1 = fragColor;
12806 color2 = fragColor;
12807 })";
12808
12809 ANGLE_GL_PROGRAM(program, getVertexShaderSource(), kFS);
12810 glUseProgram(program);
12811
12812 std::array<GLenum, 3> drawBuffers = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
12813 GL_COLOR_ATTACHMENT2};
12814 glDrawBuffers(3, drawBuffers.data());
12815
12816 // Draw with foveation into multiple attachments
12817 glActiveTexture(GL_TEXTURE0);
12818 glBindTexture(GL_TEXTURE_2D, mTexture2D);
12819 drawQuad(program, "position", 0.5f);
12820 EXPECT_GL_NO_ERROR();
12821
12822 // Verify
12823 GLFramebuffer readFBO;
12824 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
12825
12826 // Use colorAttachments[0]'s content as reference data
12827 std::vector<GLColor> referenceData(kSizeW * kSizeH, {0, 0, 0, 0});
12828 std::vector<GLColor> result(kSizeW * kSizeH, {0, 0, 0, 0});
12829 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12830 colorAttachments[0], 0);
12831 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
12832 glReadPixels(0, 0, kSizeW, kSizeH, GL_RGBA, GL_UNSIGNED_BYTE, referenceData.data());
12833
12834 // Foveated rendering should produce content that differs from original data
12835 ASSERT(originalData != referenceData);
12836
12837 // Verify rest of the attachments
12838 for (size_t index = 1; index < colorAttachments.size(); index++)
12839 {
12840 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12841 colorAttachments[index], 0);
12842 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
12843
12844 result.assign(result.size(), {0, 0, 0, 0});
12845 glReadPixels(0, 0, kSizeW, kSizeH, GL_RGBA, GL_UNSIGNED_BYTE, result.data());
12846
12847 ASSERT(referenceData == result);
12848 }
12849 }
12850
12851 // QCOM texture foveated rendering, basic draw
TEST_P(Texture2DTestES3Foveation,FoveatedTextureDraw)12852 TEST_P(Texture2DTestES3Foveation, FoveatedTextureDraw)
12853 {
12854 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_texture_foveated"));
12855
12856 // Create non-foveated framebuffer
12857 GLFramebuffer framebuffer;
12858 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
12859 glActiveTexture(GL_TEXTURE0);
12860 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
12861 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
12862 mFramebufferColorTexture, 0);
12863 ASSERT_GL_NO_ERROR();
12864 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12865
12866 // Render before configuring foveation on the texture
12867 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12868 glUseProgram(greenProgram);
12869
12870 // Clear
12871 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12872 glClear(GL_COLOR_BUFFER_BIT);
12873 EXPECT_GL_NO_ERROR();
12874
12875 // Draw
12876 drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
12877 EXPECT_GL_NO_ERROR();
12878
12879 // Configure foveation for the texture
12880 GLint supportedFoveationFeatures = 0;
12881 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM,
12882 &supportedFoveationFeatures);
12883 ASSERT_EQ(supportedFoveationFeatures & GL_FOVEATION_ENABLE_BIT_QCOM,
12884 GL_FOVEATION_ENABLE_BIT_QCOM);
12885 GLint supportedNumFocalPoints = 0;
12886 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM,
12887 &supportedNumFocalPoints);
12888 ASSERT_GE(supportedNumFocalPoints, 1);
12889 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12890 GL_FOVEATION_ENABLE_BIT_QCOM);
12891 EXPECT_GL_NO_ERROR();
12892
12893 // Set foveation parameters
12894 glTextureFoveationParametersQCOM(mFramebufferColorTexture, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12895 EXPECT_GL_NO_ERROR();
12896
12897 // Render and verify after configuring foveation on the texture
12898 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
12899 glUseProgram(blueProgram);
12900
12901 // Clear
12902 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
12903 glClear(GL_COLOR_BUFFER_BIT);
12904 EXPECT_GL_NO_ERROR();
12905
12906 // Draw
12907 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
12908 EXPECT_GL_NO_ERROR();
12909
12910 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::blue);
12911 }
12912
12913 // QCOM texture foveated rendering to MSAA texture followed by a blit
TEST_P(Texture2DTestES31Foveation,MsaaTextureDrawThenUseAsBlitSource)12914 TEST_P(Texture2DTestES31Foveation, MsaaTextureDrawThenUseAsBlitSource)
12915 {
12916 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_texture_foveated"));
12917
12918 // Create a non-foveated framebuffer
12919 GLFramebuffer framebuffer;
12920 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
12921
12922 // Create an msaa texture and bind to framebuffer
12923 GLTexture textureMS;
12924 glActiveTexture(GL_TEXTURE0);
12925 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS);
12926 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, getWindowWidth(),
12927 getWindowHeight(), GL_TRUE);
12928 EXPECT_GL_NO_ERROR();
12929
12930 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
12931 textureMS, 0);
12932 ASSERT_GL_NO_ERROR();
12933 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
12934
12935 // Just need 1 focal point
12936 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
12937 GL_FOVEATION_ENABLE_BIT_QCOM);
12938 EXPECT_GL_NO_ERROR();
12939
12940 // Set foveation parameters
12941 glTextureFoveationParametersQCOM(textureMS, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
12942 EXPECT_GL_NO_ERROR();
12943
12944 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
12945 glUseProgram(program);
12946
12947 // Clear
12948 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
12949 glClear(GL_COLOR_BUFFER_BIT);
12950 EXPECT_GL_NO_ERROR();
12951
12952 // Draw
12953 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
12954 EXPECT_GL_NO_ERROR();
12955
12956 // Blit data from framebuffer with foveated texture into default framebuffer
12957 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
12958 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
12959 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
12960 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
12961
12962 glBindFramebuffer(GL_FRAMEBUFFER, 0);
12963 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::green);
12964 }
12965
12966 // Enabling mipmap filtering after previously having used the texture without it should work.
TEST_P(Texture2DTestES3,NoMipmapDrawThenMipmapDraw)12967 TEST_P(Texture2DTestES3, NoMipmapDrawThenMipmapDraw)
12968 {
12969 glActiveTexture(GL_TEXTURE0);
12970 glBindTexture(GL_TEXTURE_2D, mTexture2D);
12971
12972 constexpr const GLsizei kSize = 8;
12973 const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
12974 const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
12975
12976 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12977 kLevel0Data.data());
12978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12979 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
12980 EXPECT_GL_NO_ERROR();
12981
12982 // Draw so the texture's image is allocated.
12983 drawQuad(mProgram, "position", 0.5f);
12984 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
12985
12986 // Specify the rest of the image
12987 for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
12988 {
12989 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
12990 GL_UNSIGNED_BYTE, kLevelOtherData.data());
12991 }
12992 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
12993
12994 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
12995 glUseProgram(program);
12996 GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
12997 GLint lodLoc = glGetUniformLocation(program, essl3_shaders::LodUniform());
12998 ASSERT_NE(-1, textureLoc);
12999 ASSERT_NE(-1, lodLoc);
13000 glUniform1i(textureLoc, 0);
13001
13002 // Verify the mips
13003 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13004 {
13005 glUniform1f(lodLoc, mip);
13006 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13007 EXPECT_GL_NO_ERROR();
13008 EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
13009 }
13010 }
13011
13012 // Disabling mipmap filtering after previously having used the texture with it should work.
TEST_P(Texture2DTestES3,MipmapDrawThenNoMipmapDraw)13013 TEST_P(Texture2DTestES3, MipmapDrawThenNoMipmapDraw)
13014 {
13015 glActiveTexture(GL_TEXTURE0);
13016 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13017
13018 constexpr const GLsizei kSize = 8;
13019 const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
13020 const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
13021
13022 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13023 kLevel0Data.data());
13024 for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
13025 {
13026 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
13027 GL_UNSIGNED_BYTE, kLevelOtherData.data());
13028 }
13029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
13030 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13031 EXPECT_GL_NO_ERROR();
13032
13033 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
13034 glUseProgram(program);
13035 GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
13036 GLint lodLoc = glGetUniformLocation(program, essl3_shaders::LodUniform());
13037 ASSERT_NE(-1, textureLoc);
13038 ASSERT_NE(-1, lodLoc);
13039 glUniform1i(textureLoc, 0);
13040
13041 // Verify the mips.
13042 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13043 {
13044 glUniform1f(lodLoc, mip);
13045 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13046 EXPECT_GL_NO_ERROR();
13047 EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
13048 }
13049
13050 // Disable mipmapping and verify mips again.
13051 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13052
13053 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13054 {
13055 glUniform1f(lodLoc, mip);
13056 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13057 EXPECT_GL_NO_ERROR();
13058 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
13059 }
13060 }
13061
13062 // Respecify texture with more mips.
TEST_P(Texture2DTestES3,RespecifyWithMoreMips)13063 TEST_P(Texture2DTestES3, RespecifyWithMoreMips)
13064 {
13065 glActiveTexture(GL_TEXTURE0);
13066 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13067
13068 constexpr const GLsizei kSize = 8;
13069 const std::vector<GLColor> kLevelEvenData(kSize * kSize, GLColor::blue);
13070 const std::vector<GLColor> kLevelOddData(kSize * kSize * 4, GLColor::red);
13071
13072 auto getLevelData = [&](GLint mip) {
13073 return mip % 2 == 0 ? kLevelEvenData.data() : kLevelOddData.data();
13074 };
13075
13076 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13077 {
13078 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
13079 GL_UNSIGNED_BYTE, getLevelData(mip));
13080 }
13081 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
13082 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13083 EXPECT_GL_NO_ERROR();
13084
13085 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
13086 glUseProgram(program);
13087 GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
13088 GLint lodLoc = glGetUniformLocation(program, essl3_shaders::LodUniform());
13089 ASSERT_NE(-1, textureLoc);
13090 ASSERT_NE(-1, lodLoc);
13091 glUniform1i(textureLoc, 0);
13092
13093 // Verify the mips.
13094 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13095 {
13096 glUniform1f(lodLoc, mip);
13097 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13098 EXPECT_GL_NO_ERROR();
13099 EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip)[0]);
13100 }
13101
13102 // Respecify the texture with more mips, without changing any parameters.
13103 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13104 kLevelOddData.data());
13105 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
13106 {
13107 glTexImage2D(GL_TEXTURE_2D, mip + 1, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
13108 GL_UNSIGNED_BYTE, getLevelData(mip));
13109 }
13110
13111 // Verify the mips.
13112 for (GLint mip = 0; ((kSize * 2) >> mip) >= 1; ++mip)
13113 {
13114 glUniform1f(lodLoc, mip);
13115 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
13116 EXPECT_GL_NO_ERROR();
13117 EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip - 1)[0]);
13118 }
13119 }
13120
13121 // Covers a bug in the D3D11 backend: http://anglebug.com/42261476
13122 // When using a sampler the texture was created as if it has mipmaps,
13123 // regardless what you specified in GL_TEXTURE_MIN_FILTER via
13124 // glSamplerParameteri() -- mistakenly the default value
13125 // GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
13126 // evaluated.
13127 // If you didn't provide mipmaps and didn't let the driver generate them
13128 // this led to not sampling your texture data when minification occurred.
TEST_P(Texture2DTestES3,MinificationWithSamplerNoMipmapping)13129 TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
13130 {
13131 constexpr char kVS[] =
13132 "#version 300 es\n"
13133 "out vec2 texcoord;\n"
13134 "in vec4 position;\n"
13135 "void main()\n"
13136 "{\n"
13137 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
13138 " texcoord = (position.xy * 0.5) + 0.5;\n"
13139 "}\n";
13140
13141 constexpr char kFS[] =
13142 "#version 300 es\n"
13143 "precision highp float;\n"
13144 "uniform highp sampler2D tex;\n"
13145 "in vec2 texcoord;\n"
13146 "out vec4 fragColor;\n"
13147 "void main()\n"
13148 "{\n"
13149 " fragColor = texture(tex, texcoord);\n"
13150 "}\n";
13151
13152 ANGLE_GL_PROGRAM(program, kVS, kFS);
13153
13154 GLSampler sampler;
13155 glBindSampler(0, sampler);
13156 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13157 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13158
13159 glActiveTexture(GL_TEXTURE0);
13160 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13161
13162 const GLsizei texWidth = getWindowWidth();
13163 const GLsizei texHeight = getWindowHeight();
13164 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
13165
13166 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13167 whiteData.data());
13168 EXPECT_GL_NO_ERROR();
13169
13170 drawQuad(program, "position", 0.5f);
13171 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
13172 }
13173
testUploadThenUseInDifferentStages(const std::vector<UploadThenUseStageParam> & uses)13174 void Texture2DTest::testUploadThenUseInDifferentStages(
13175 const std::vector<UploadThenUseStageParam> &uses)
13176 {
13177 constexpr char kVSSampleVS[] = R"(attribute vec4 a_position;
13178 uniform sampler2D u_tex2D;
13179 varying vec4 v_color;
13180
13181 void main()
13182 {
13183 gl_Position = vec4(a_position.xy, 0.0, 1.0);
13184 v_color = texture2D(u_tex2D, a_position.xy * 0.5 + vec2(0.5));
13185 })";
13186
13187 constexpr char kVSSampleFS[] = R"(precision mediump float;
13188 varying vec4 v_color;
13189
13190 void main()
13191 {
13192 gl_FragColor = v_color;
13193 })";
13194
13195 ANGLE_GL_PROGRAM(sampleInVS, kVSSampleVS, kVSSampleFS);
13196 ANGLE_GL_PROGRAM(sampleInFS, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
13197
13198 GLFramebuffer fbo[2];
13199 GLTexture color[2];
13200 for (uint32_t i = 0; i < 2; ++i)
13201 {
13202 glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
13203 glBindTexture(GL_TEXTURE_2D, color[i]);
13204 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
13205 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color[i], 0);
13206 }
13207
13208 const GLColor kImageColor(63, 31, 0, 255);
13209
13210 GLTexture tex;
13211 glBindTexture(GL_TEXTURE_2D, tex);
13212 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kImageColor);
13213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13215 glActiveTexture(GL_TEXTURE0);
13216 ASSERT_GL_NO_ERROR();
13217
13218 glEnable(GL_BLEND);
13219 glBlendFunc(GL_ONE, GL_ONE);
13220
13221 glClearColor(0, 0, 0, 1);
13222
13223 glBindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
13224 glClear(GL_COLOR_BUFFER_BIT);
13225 glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
13226 glClear(GL_COLOR_BUFFER_BIT);
13227
13228 uint32_t curFboIndex = 0;
13229 uint32_t fboDrawCount[2] = {};
13230
13231 for (const UploadThenUseStageParam &use : uses)
13232 {
13233 const GLProgram &program = use.useStage == GL_VERTEX_SHADER ? sampleInVS : sampleInFS;
13234 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
13235 ASSERT_GL_NO_ERROR();
13236
13237 ++fboDrawCount[curFboIndex];
13238
13239 if (use.closeRenderPassAfterUse)
13240 {
13241 // Close the render pass without accidentally incurring additional barriers.
13242 curFboIndex = 1 - curFboIndex;
13243 glBindFramebuffer(GL_FRAMEBUFFER, fbo[curFboIndex]);
13244 }
13245 }
13246
13247 // Make sure the transfer operations below aren't reordered with the rendering above and thus
13248 // introduce additional synchronization.
13249 glFinish();
13250
13251 for (uint32_t i = 0; i < 2; ++i)
13252 {
13253 const GLColor kExpectedColor(63 * std::min(4u, fboDrawCount[i]),
13254 31 * std::min(8u, fboDrawCount[i]), 0, 255);
13255
13256 glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
13257 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor);
13258 }
13259 }
13260
13261 // Test synchronization when a texture is used in different shader stages after data upload.
13262 //
13263 // - Use in VS
13264 // - Use in FS
TEST_P(Texture2DTest,UploadThenVSThenFS)13265 TEST_P(Texture2DTest, UploadThenVSThenFS)
13266 {
13267 testUploadThenUseInDifferentStages({
13268 {GL_VERTEX_SHADER, false},
13269 {GL_FRAGMENT_SHADER, false},
13270 });
13271 }
13272
13273 // Test synchronization when a texture is used in different shader stages after data upload.
13274 //
13275 // - Use in VS
13276 // - Break render pass
13277 // - Use in FS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFS)13278 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFS)
13279 {
13280 testUploadThenUseInDifferentStages({
13281 {GL_VERTEX_SHADER, true},
13282 {GL_FRAGMENT_SHADER, false},
13283 });
13284 }
13285
13286 // Test synchronization when a texture is used in different shader stages after data upload.
13287 //
13288 // - Use in FS
13289 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenVS)13290 TEST_P(Texture2DTest, UploadThenFSThenVS)
13291 {
13292 testUploadThenUseInDifferentStages({
13293 {GL_FRAGMENT_SHADER, false},
13294 {GL_VERTEX_SHADER, false},
13295 });
13296 }
13297
13298 // Test synchronization when a texture is used in different shader stages after data upload.
13299 //
13300 // - Use in FS
13301 // - Break render pass
13302 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenVS)13303 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenVS)
13304 {
13305 testUploadThenUseInDifferentStages({
13306 {GL_FRAGMENT_SHADER, true},
13307 {GL_VERTEX_SHADER, false},
13308 });
13309 }
13310
13311 // Test synchronization when a texture is used in different shader stages after data upload.
13312 //
13313 // - Use in VS
13314 // - Use in FS
13315 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenFSThenVS)13316 TEST_P(Texture2DTest, UploadThenVSThenFSThenVS)
13317 {
13318 testUploadThenUseInDifferentStages({
13319 {GL_VERTEX_SHADER, false},
13320 {GL_FRAGMENT_SHADER, false},
13321 {GL_VERTEX_SHADER, false},
13322 });
13323 }
13324
13325 // Test synchronization when a texture is used in different shader stages after data upload.
13326 //
13327 // - Use in VS
13328 // - Break render pass
13329 // - Use in FS
13330 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFSThenVS)13331 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFSThenVS)
13332 {
13333 testUploadThenUseInDifferentStages({
13334 {GL_VERTEX_SHADER, true},
13335 {GL_FRAGMENT_SHADER, false},
13336 {GL_VERTEX_SHADER, false},
13337 });
13338 }
13339
13340 // Test synchronization when a texture is used in different shader stages after data upload.
13341 //
13342 // - Use in VS
13343 // - Break render pass
13344 // - Use in FS
13345 // - Break render pass
13346 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFSThenNewRPThenVS)13347 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFSThenNewRPThenVS)
13348 {
13349 testUploadThenUseInDifferentStages({
13350 {GL_VERTEX_SHADER, true},
13351 {GL_FRAGMENT_SHADER, true},
13352 {GL_VERTEX_SHADER, false},
13353 });
13354 }
13355
13356 // Test synchronization when a texture is used in different shader stages after data upload.
13357 //
13358 // - Use in FS
13359 // - Use in VS
13360 // - Break render pass
13361 // - Use in FS
TEST_P(Texture2DTest,UploadThenFSThenVSThenNewRPThenFS)13362 TEST_P(Texture2DTest, UploadThenFSThenVSThenNewRPThenFS)
13363 {
13364 testUploadThenUseInDifferentStages({
13365 {GL_FRAGMENT_SHADER, false},
13366 {GL_VERTEX_SHADER, true},
13367 {GL_FRAGMENT_SHADER, false},
13368 });
13369 }
13370
13371 // Test synchronization when a texture is used in different shader stages after data upload.
13372 //
13373 // - Use in FS
13374 // - Break render pass
13375 // - Use in VS
13376 // - Use in FS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenVSThenFS)13377 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenVSThenFS)
13378 {
13379 testUploadThenUseInDifferentStages({
13380 {GL_FRAGMENT_SHADER, true},
13381 {GL_VERTEX_SHADER, false},
13382 {GL_FRAGMENT_SHADER, false},
13383 });
13384 }
13385
13386 // Test synchronization when a texture is used in different shader stages after data upload.
13387 //
13388 // - Use in FS
13389 // - Break render pass
13390 // - Use in FS
13391 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenFSThenVS)13392 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenFSThenVS)
13393 {
13394 testUploadThenUseInDifferentStages({
13395 {GL_FRAGMENT_SHADER, true},
13396 {GL_FRAGMENT_SHADER, false},
13397 {GL_VERTEX_SHADER, false},
13398 });
13399 }
13400
13401 // Test that interleaved updates and draw calls many times work
TEST_P(Texture2DTest,DrawThenUpdateMultipleTimes)13402 TEST_P(Texture2DTest, DrawThenUpdateMultipleTimes)
13403 {
13404 constexpr uint32_t kTexWidth = 16;
13405 constexpr uint32_t kTexHeight = 16;
13406 constexpr uint32_t kBpp = 4;
13407
13408 // Create the texture
13409 glActiveTexture(GL_TEXTURE0);
13410 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13411 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13412 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13413 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
13414 nullptr);
13415 EXPECT_GL_ERROR(GL_NO_ERROR);
13416
13417 constexpr GLubyte kInitialColor = 16;
13418 GLubyte expectedFinalColorValue = kInitialColor;
13419 glEnable(GL_BLEND);
13420 glBlendFunc(GL_ONE, GL_ONE);
13421 glClearColor(0, 0, 0, 0);
13422 glClear(GL_COLOR_BUFFER_BIT);
13423
13424 // First draw the screen with initial color
13425 {
13426 ANGLE_GL_PROGRAM(colorProgram, angle::essl1_shaders::vs::Simple(),
13427 angle::essl1_shaders::fs::UniformColor());
13428 glUseProgram(colorProgram);
13429 GLint colorUniformLocation =
13430 glGetUniformLocation(colorProgram, angle::essl1_shaders::ColorUniform());
13431 ASSERT_NE(colorUniformLocation, -1);
13432 glUniform4f(colorUniformLocation, kInitialColor / 256.f, kInitialColor / 256.f,
13433 kInitialColor / 256.f, kInitialColor / 256.f);
13434 drawQuad(colorProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
13435 }
13436
13437 // Then update the texture then draw it multiple times
13438 constexpr GLubyte kColorsToUpdate[] = {16, 64, 64};
13439 setUpProgram();
13440 glUseProgram(mProgram);
13441 glUniform1i(mTexture2DUniformLocation, 0);
13442
13443 for (auto color : kColorsToUpdate)
13444 {
13445 expectedFinalColorValue += color;
13446 std::vector<GLubyte> fullTextureData(kTexWidth * kTexHeight * kBpp, color);
13447 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, GL_UNSIGNED_BYTE,
13448 fullTextureData.data());
13449
13450 drawQuad(mProgram, "position", 0.5f);
13451 }
13452
13453 // The final color should be sum of all updated colors.
13454 const GLColor expectedFinalColor(expectedFinalColorValue, expectedFinalColorValue,
13455 expectedFinalColorValue, expectedFinalColorValue);
13456 EXPECT_GL_NO_ERROR();
13457 EXPECT_PIXEL_COLOR_EQ(1 * getWindowWidth() / 4, getWindowHeight() / 2, expectedFinalColor);
13458 }
13459
13460 // Test that clears due to emulated formats are to the correct level given non-zero base level.
TEST_P(Texture2DTestES3,NonZeroBaseEmulatedClear)13461 TEST_P(Texture2DTestES3, NonZeroBaseEmulatedClear)
13462 {
13463 // Tests behavior of the Vulkan backend with emulated formats.
13464 ANGLE_SKIP_TEST_IF(!IsVulkan());
13465
13466 // TODO(http://anglebug.com/42266496): Skip when using VMA image suballocation on Linux/Intel.
13467 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() &&
13468 getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
13469
13470 // This test assumes GL_RGB is always emulated, which overrides the
13471 // Feature::AllocateNonZeroMemory memory feature, clearing the memory to zero. However, if the
13472 // format is *not* emulated and the feature Feature::AllocateNonZeroMemory is enabled, the
13473 // texture memory will contain non-zero memory, which means the color is not black (causing the
13474 // test to fail).
13475 ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::AllocateNonZeroMemory));
13476
13477 setUpProgram();
13478
13479 glActiveTexture(GL_TEXTURE0);
13480 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13481 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13482 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13483 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13484 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13485 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
13486 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
13487 EXPECT_GL_NO_ERROR();
13488
13489 drawQuad(mProgram, "position", 0.5f);
13490
13491 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
13492 }
13493
13494 // Test that uploading data to buffer that's in use then using it as PBO to update a texture works.
TEST_P(Texture2DTestES3,UseAsUBOThenUpdateThenAsPBO)13495 TEST_P(Texture2DTestES3, UseAsUBOThenUpdateThenAsPBO)
13496 {
13497 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
13498 GLColor::red};
13499 const std::array<GLColor, 4> kUpdateData = {GLColor::blue, GLColor::blue, GLColor::blue,
13500 GLColor::blue};
13501
13502 GLBuffer buffer;
13503 glBindBuffer(GL_UNIFORM_BUFFER, buffer);
13504 glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_COPY);
13505 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
13506 EXPECT_GL_NO_ERROR();
13507
13508 constexpr char kVerifyUBO[] = R"(#version 300 es
13509 precision mediump float;
13510 uniform block {
13511 uvec4 data;
13512 } ubo;
13513 out vec4 colorOut;
13514 void main()
13515 {
13516 if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
13517 colorOut = vec4(0, 1.0, 0, 1.0);
13518 else
13519 colorOut = vec4(1.0, 0, 0, 1.0);
13520 })";
13521
13522 ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
13523 drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
13524 EXPECT_GL_NO_ERROR();
13525
13526 // Update buffer data
13527 glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
13528 EXPECT_GL_NO_ERROR();
13529
13530 // Bind as PBO
13531 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
13532 EXPECT_GL_NO_ERROR();
13533
13534 // Upload from PBO to texture
13535 GLTexture tex;
13536 glBindTexture(GL_TEXTURE_2D, tex);
13537 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
13538 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
13539 EXPECT_GL_NO_ERROR();
13540
13541 // Make sure uniform data is correct.
13542 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
13543
13544 // Make sure the texture data is correct.
13545 GLFramebuffer fbo;
13546 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
13547 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
13548 EXPECT_GL_NO_ERROR();
13549 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
13550
13551 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
13552 }
13553
13554 // Test if the RenderTargetCache is updated when the TextureStorage object is freed
TEST_P(Texture2DTestES3,UpdateRenderTargetCacheOnDestroyTexStorage)13555 TEST_P(Texture2DTestES3, UpdateRenderTargetCacheOnDestroyTexStorage)
13556 {
13557 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
13558 const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
13559
13560 GLTexture tex;
13561 GLFramebuffer fb;
13562 glBindTexture(GL_TEXTURE_2D, tex);
13563 glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 100, 1);
13564 glBindFramebuffer(GL_FRAMEBUFFER, fb);
13565 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
13566 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments);
13567 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
13568 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 1.0f);
13569 EXPECT_GL_NO_ERROR();
13570
13571 EXPECT_PIXEL_RECT_EQ(0, 0, 100, 1, GLColor::red);
13572 }
13573
13574 // Test that we can allocate at least 4096 images, which is the maximum allocation count on some
13575 // platforms. Image suballocation should enable us to allocate more than this limit.
TEST_P(Texture2DTestES3,AllocateMoreThan4096Textures)13576 TEST_P(Texture2DTestES3, AllocateMoreThan4096Textures)
13577 {
13578 ANGLE_SKIP_TEST_IF(!getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
13579
13580 // The test is skipped when AllocateNonZeroMemory is enabled due to risk of timeout.
13581 ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::AllocateNonZeroMemory));
13582
13583 constexpr size_t kTextureCount = 8000;
13584 std::vector<GLTexture> textures(kTextureCount);
13585 for (auto &texture : textures)
13586 {
13587 glBindTexture(GL_TEXTURE_2D, texture);
13588 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
13589 }
13590 EXPECT_GL_NO_ERROR();
13591 }
13592
13593 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
13594 // texture is output.
TEST_P(Texture2DIntegerTestES3,IntegerTextureNonZeroBaseLevel)13595 TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
13596 {
13597 // http://anglebug.com/40644690
13598 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
13599
13600 glActiveTexture(GL_TEXTURE0);
13601 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13602 int width = getWindowWidth();
13603 int height = getWindowHeight();
13604 GLColor color = GLColor::green;
13605 std::vector<GLColor> pixels(width * height, color);
13606 GLint baseLevel = 1;
13607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
13608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13610 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
13611 GL_UNSIGNED_BYTE, pixels.data());
13612
13613 setUpProgram();
13614 glUseProgram(mProgram);
13615 glUniform1i(mTexture2DUniformLocation, 0);
13616 drawQuad(mProgram, "position", 0.5f);
13617
13618 EXPECT_GL_NO_ERROR();
13619 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13620 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13621 }
13622
13623 // Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
13624 // the texture is output.
TEST_P(TextureCubeIntegerTestES3,IntegerCubeTextureNonZeroBaseLevel)13625 TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
13626 {
13627 // All output checks returned black, rather than the texture color.
13628 ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL());
13629
13630 glActiveTexture(GL_TEXTURE0);
13631
13632 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
13633 GLint baseLevel = 1;
13634 int width = getWindowWidth();
13635 int height = getWindowHeight();
13636 GLColor color = GLColor::green;
13637 std::vector<GLColor> pixels(width * height, color);
13638 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
13639 {
13640 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
13641 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
13642 EXPECT_GL_NO_ERROR();
13643 }
13644 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
13645 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13646 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13647
13648 glUseProgram(mProgram);
13649 glUniform1i(mTextureCubeUniformLocation, 0);
13650 drawQuad(mProgram, "position", 0.5f);
13651
13652 EXPECT_GL_NO_ERROR();
13653 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13654 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
13655 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
13656 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13657 }
13658
13659 // This test sets up a cube map with four distincly colored MIP levels.
13660 // The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
13661 // the corners of the screen.
TEST_P(TextureCubeIntegerEdgeTestES3,IntegerCubeTextureCorner)13662 TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
13663 {
13664 glActiveTexture(GL_TEXTURE0);
13665
13666 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
13667 int width = getWindowWidth();
13668 int height = getWindowHeight();
13669 ASSERT_EQ(width, height);
13670 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
13671 for (GLint level = 0; level < 4; level++)
13672 {
13673 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
13674 {
13675 int levelWidth = (2 * width) >> level;
13676 int levelHeight = (2 * height) >> level;
13677 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
13678 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
13679 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
13680 EXPECT_GL_NO_ERROR();
13681 }
13682 }
13683 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
13684 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13685 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
13686
13687 glUseProgram(mProgram);
13688 glUniform1i(mTextureCubeUniformLocation, 0);
13689 drawQuad(mProgram, "position", 0.5f);
13690
13691 ASSERT_GL_NO_ERROR();
13692 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
13693 EXPECT_EQ(ReadColor(0, 0).R, 0);
13694 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
13695 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
13696 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
13697 }
13698
13699 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
13700 // texture is output.
TEST_P(Texture2DIntegerProjectiveOffsetTestES3,NonZeroBaseLevel)13701 TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
13702 {
13703 // Fails on AMD: http://crbug.com/967796
13704 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
13705
13706 glActiveTexture(GL_TEXTURE0);
13707 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13708 int width = getWindowWidth();
13709 int height = getWindowHeight();
13710 GLColor color = GLColor::green;
13711 std::vector<GLColor> pixels(width * height, color);
13712 GLint baseLevel = 1;
13713 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
13714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13716 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
13717 GL_UNSIGNED_BYTE, pixels.data());
13718
13719 setUpProgram();
13720 glUseProgram(mProgram);
13721 glUniform1i(mTexture2DUniformLocation, 0);
13722 drawQuad(mProgram, "position", 0.5f);
13723
13724 EXPECT_GL_NO_ERROR();
13725 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13726 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13727 }
13728
13729 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
13730 // texture is output.
TEST_P(Texture2DArrayIntegerTestES3,NonZeroBaseLevel)13731 TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
13732 {
13733 // Test fail: http://anglebug.com/42264492
13734 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
13735
13736 glActiveTexture(GL_TEXTURE0);
13737 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
13738 int width = getWindowWidth();
13739 int height = getWindowHeight();
13740 int depth = 2;
13741 GLColor color = GLColor::green;
13742 std::vector<GLColor> pixels(width * height * depth, color);
13743 GLint baseLevel = 1;
13744 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
13745 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
13746 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
13747 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13748 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13749
13750 drawQuad(mProgram, "position", 0.5f);
13751
13752 EXPECT_GL_NO_ERROR();
13753 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13754 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13755 }
13756
13757 // Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
13758 // texture is output.
TEST_P(Texture3DIntegerTestES3,NonZeroBaseLevel)13759 TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
13760 {
13761 glActiveTexture(GL_TEXTURE0);
13762 glBindTexture(GL_TEXTURE_3D, mTexture3D);
13763 int width = getWindowWidth();
13764 int height = getWindowHeight();
13765 int depth = 2;
13766 GLColor color = GLColor::green;
13767 std::vector<GLColor> pixels(width * height * depth, color);
13768 GLint baseLevel = 1;
13769 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
13770 GL_UNSIGNED_BYTE, pixels.data());
13771 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
13772 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13773 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13774
13775 drawQuad(mProgram, "position", 0.5f);
13776
13777 EXPECT_GL_NO_ERROR();
13778 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
13779 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
13780 }
13781
runCompressedSubImage()13782 void PBOCompressedTextureTest::runCompressedSubImage()
13783 {
13784 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
13785 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
13786 // http://anglebug.com/42262750
13787 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
13788 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
13789
13790 if (getClientMajorVersion() < 3)
13791 {
13792 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
13793 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
13794 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
13795 }
13796
13797 const GLuint width = 4u;
13798 const GLuint height = 4u;
13799
13800 setWindowWidth(width);
13801 setWindowHeight(height);
13802
13803 // Setup primary Texture
13804 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13805 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13806 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13807
13808 if (getClientMajorVersion() < 3)
13809 {
13810 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
13811 }
13812 else
13813 {
13814 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
13815 }
13816 ASSERT_GL_NO_ERROR();
13817
13818 // Setup PBO and fill it with a red
13819 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
13820 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
13821 ASSERT_GL_NO_ERROR();
13822
13823 // Write PBO to mTexture
13824 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
13825 width * height / 2u, nullptr);
13826 ASSERT_GL_NO_ERROR();
13827
13828 setUpProgram();
13829 // Draw using PBO updated texture
13830 glUseProgram(mProgram);
13831 glUniform1i(mTexture2DUniformLocation, 0);
13832 glBindTexture(GL_TEXTURE_2D, mTexture2D);
13833 drawQuad(mProgram, "position", 0.5f);
13834 ASSERT_GL_NO_ERROR();
13835
13836 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
13837 ASSERT_GL_NO_ERROR();
13838 }
13839
13840 // Test that uses glCompressedTexSubImage2D combined with a PBO
TEST_P(PBOCompressedTextureTest,PBOCompressedSubImage)13841 TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
13842 {
13843 runCompressedSubImage();
13844 }
13845
13846 // Verify the row length state is ignored when using compressed tex image calls.
TEST_P(PBOCompressedTextureTest,PBOCompressedSubImageWithUnpackRowLength)13847 TEST_P(PBOCompressedTextureTest, PBOCompressedSubImageWithUnpackRowLength)
13848 {
13849 // ROW_LENGTH requires ES3 or an extension.
13850 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
13851 !IsGLExtensionEnabled("GL_EXT_unpack_subimage"));
13852
13853 glPixelStorei(GL_UNPACK_ROW_LENGTH, 1);
13854 runCompressedSubImage();
13855 }
13856
13857 class PBOCompressedTexture3DTest : public ANGLETest<>
13858 {
13859 protected:
PBOCompressedTexture3DTest()13860 PBOCompressedTexture3DTest() {}
13861 };
13862
13863 // Test that uses glCompressedTexSubImage3D combined with a PBO
13864 TEST_P(PBOCompressedTexture3DTest, 2DArray)
13865 {
13866 // We use GetTexImage to determine if the internal texture format is emulated
13867 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_get_image"));
13868
13869 const GLuint width = 4u;
13870 const GLuint height = 4u;
13871 const GLuint depth = 1u;
13872
13873 setWindowWidth(width);
13874 setWindowHeight(height);
13875
13876 // Setup primary texture as a 2DArray holding ETC2 data
13877 GLTexture texture2DArray;
13878 glBindTexture(GL_TEXTURE_2D_ARRAY, texture2DArray);
13879 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13880 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13881 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_COMPRESSED_RGB8_ETC2, width, height, depth);
13882
13883 // If the format emulated, we can't transfer it from a PBO
13884 ANGLE_SKIP_TEST_IF(IsFormatEmulated(GL_TEXTURE_2D_ARRAY));
13885
13886 // Set up a VS that simply passes through position and texcord
13887 const char kVS[] = R"(#version 300 es
13888 in vec4 position;
13889 out vec3 texCoord;
13890
13891 void main()
13892 {
13893 gl_Position = vec4(position.xy, 0.0, 1.0);
13894 texCoord = vec3(position.xy * 0.5 + vec2(0.5), 0.0);
13895 })";
13896
13897 // and FS that pulls from the 2DArray, writing out color
13898 const char kFS[] = R"(#version 300 es
13899 precision mediump float;
13900 uniform highp sampler2DArray tex2DArray;
13901 in vec3 texCoord;
13902 out vec4 fragColor;
13903
13904 void main()
13905 {
13906 fragColor = texture(tex2DArray, texCoord);
13907 })";
13908
13909 // Compile the shaders and create the program
13910 ANGLE_GL_PROGRAM(program, kVS, kFS);
13911 ASSERT_GL_NO_ERROR();
13912
13913 // Setup PBO and fill it with a red
13914 GLBuffer pbo;
13915 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
13916 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height * depth / 2u, kCompressedImageETC2,
13917 GL_STATIC_DRAW);
13918 ASSERT_GL_NO_ERROR();
13919
13920 // Write PBO to texture2DArray
13921 glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, depth,
13922 GL_COMPRESSED_RGB8_ETC2, width * height * depth / 2u, nullptr);
13923
13924 ASSERT_GL_NO_ERROR();
13925
13926 // Draw using PBO updated texture
13927 glUseProgram(program);
13928 glUniform1i(glGetUniformLocation(program, "tex2DArray"), 0);
13929 glBindTexture(GL_TEXTURE_2D_ARRAY, texture2DArray);
13930 drawQuad(program, "position", 0.5f);
13931 ASSERT_GL_NO_ERROR();
13932
13933 // Verify the texture now contains data from the PBO
13934 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
13935 ASSERT_GL_NO_ERROR();
13936 }
13937
13938 // Test using ETC1_RGB8 with subimage updates
TEST_P(ETC1CompressedTextureTest,ETC1CompressedSubImage)13939 TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
13940 {
13941 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
13942 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
13943
13944 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
13945 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
13946 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
13947
13948 const GLuint width = 4u;
13949 const GLuint height = 4u;
13950
13951 setWindowWidth(width);
13952 setWindowHeight(height);
13953
13954 // Setup primary Texture
13955 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
13956 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
13957
13958 if (getClientMajorVersion() < 3)
13959 {
13960 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
13961 }
13962 else
13963 {
13964 glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
13965 }
13966 ASSERT_GL_NO_ERROR();
13967
13968 // Populate a subimage of the texture
13969 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
13970 width * height / 2u, kCompressedImageETC2);
13971 ASSERT_GL_NO_ERROR();
13972
13973 // Render and ensure we get red
13974 glUseProgram(mProgram);
13975 drawQuad(mProgram, "position", 0.5f);
13976 ASSERT_GL_NO_ERROR();
13977
13978 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
13979 ASSERT_GL_NO_ERROR();
13980 }
13981
13982 // Fully-define a NPOT compressed texture and draw; set MAX_LEVEL and draw; then increase
13983 // MAX_LEVEL and draw. This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageNPOT)13984 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageNPOT)
13985 {
13986 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
13987 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
13988
13989 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
13990 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
13991
13992 const GLuint width = 5u;
13993 const GLuint height = 5u;
13994 // round up to the nearest block size
13995 const GLsizei imageSize = 8 * 8 / 2;
13996 // smallest block size
13997 const GLsizei minImageSize = 4 * 4 / 2;
13998
13999 uint8_t data[imageSize] = {0};
14000
14001 setWindowWidth(width);
14002 setWindowHeight(height);
14003
14004 // Setup primary Texture
14005 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
14006 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
14007 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
14008 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
14009
14010 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
14011 ASSERT_GL_NO_ERROR();
14012
14013 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width / 2, height / 2, 0,
14014 minImageSize, data);
14015 ASSERT_GL_NO_ERROR();
14016
14017 glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_ETC1_RGB8_OES, width / 4, height / 4, 0,
14018 minImageSize, data);
14019 ASSERT_GL_NO_ERROR();
14020
14021 glUseProgram(mProgram);
14022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14024 drawQuad(mProgram, "position", 0.5f);
14025 ASSERT_GL_NO_ERROR();
14026
14027 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
14028 drawQuad(mProgram, "position", 0.5f);
14029 ASSERT_GL_NO_ERROR();
14030 }
14031
14032 // Define two NPOT compressed textures, set MAX_LEVEL, draw, and swap buffers
14033 // with the two textures. This used to cause release of staging buffers
14034 // that have not been flushed.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageDraws)14035 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageDraws)
14036 {
14037 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
14038 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
14039
14040 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
14041 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
14042
14043 const GLuint width = 384u;
14044 const GLuint height = 384u;
14045 // round up to the nearest block size
14046 const GLsizei imageSize = width * height / 2;
14047
14048 uint8_t data[imageSize] = {0};
14049
14050 setWindowWidth(width);
14051 setWindowHeight(height);
14052
14053 const GLuint smallerWidth = 384u;
14054 const GLuint smallerHeight = 320u;
14055 // round up to the nearest block size
14056 const GLsizei smallerImageSize = smallerWidth * smallerHeight / 2;
14057
14058 // Setup primary Texture
14059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
14060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
14061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
14062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
14063
14064 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, smallerWidth, smallerHeight, 0,
14065 smallerImageSize, data);
14066 ASSERT_GL_NO_ERROR();
14067
14068 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 160, 0, 15360, data);
14069 ASSERT_GL_NO_ERROR();
14070
14071 GLTexture largerTexture;
14072 glBindTexture(GL_TEXTURE_2D, largerTexture);
14073
14074 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
14075 ASSERT_GL_NO_ERROR();
14076
14077 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 192, 0, 18432, data);
14078 ASSERT_GL_NO_ERROR();
14079
14080 glBindTexture(GL_TEXTURE_2D, mTexture2D);
14081
14082 glUseProgram(mProgram);
14083 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14084 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14085 drawQuad(mProgram, "position", 0.5f);
14086 ASSERT_GL_NO_ERROR();
14087 swapBuffers();
14088 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
14089 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
14090 drawQuad(mProgram, "position", 0.5f);
14091 ASSERT_GL_NO_ERROR();
14092 swapBuffers();
14093
14094 glBindTexture(GL_TEXTURE_2D, largerTexture);
14095
14096 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14097 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14098 drawQuad(mProgram, "position", 0.5f);
14099 ASSERT_GL_NO_ERROR();
14100 swapBuffers();
14101
14102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
14103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
14104 drawQuad(mProgram, "position", 0.5f);
14105 ASSERT_GL_NO_ERROR();
14106 swapBuffers();
14107
14108 glBindTexture(GL_TEXTURE_2D, mTexture2D);
14109
14110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
14111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14112 drawQuad(mProgram, "position", 0.5f);
14113 swapBuffers();
14114 ASSERT_GL_NO_ERROR();
14115 }
14116
14117 // Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
14118 // MAX_LEVEL and draw. This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1ShrinkThenGrowMaxLevels)14119 TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
14120 {
14121 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/42262497
14122 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
14123
14124 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
14125 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
14126
14127 const GLuint width = 4u;
14128 const GLuint height = 4u;
14129
14130 setWindowWidth(width);
14131 setWindowHeight(height);
14132
14133 // Setup primary Texture
14134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
14135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
14136
14137 if (getClientMajorVersion() < 3)
14138 {
14139 glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
14140 }
14141 else
14142 {
14143 glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
14144 }
14145 ASSERT_GL_NO_ERROR();
14146
14147 // Populate a subimage of the texture
14148 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
14149 width * height / 2u, kCompressedImageETC2);
14150 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
14151 width * height / 2u, kCompressedImageETC2);
14152 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
14153 width * height / 2u, kCompressedImageETC2);
14154 ASSERT_GL_NO_ERROR();
14155
14156 // Set MAX_LEVEL to 2 (the highest level)
14157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
14158
14159 // Render and ensure we get red
14160 glUseProgram(mProgram);
14161 drawQuad(mProgram, "position", 0.5f);
14162 ASSERT_GL_NO_ERROR();
14163 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
14164 ASSERT_GL_NO_ERROR();
14165
14166 // Decrease MAX_LEVEL to 0, render, and ensure we still get red
14167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14168 drawQuad(mProgram, "position", 0.5f);
14169 ASSERT_GL_NO_ERROR();
14170 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
14171 ASSERT_GL_NO_ERROR();
14172
14173 // Increase MAX_LEVEL back to 2, render, and ensure we still get red
14174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
14175 drawQuad(mProgram, "position", 0.5f);
14176 ASSERT_GL_NO_ERROR();
14177 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
14178 ASSERT_GL_NO_ERROR();
14179 }
14180
14181 class TextureBufferTestBase : public ANGLETest<>
14182 {
14183 protected:
TextureBufferTestBase()14184 TextureBufferTestBase() {}
14185
14186 void callTexBufferAPI(const APIExtensionVersion usedExtension,
14187 GLenum target,
14188 GLenum internalFormat,
14189 GLuint buffer);
14190 void testTexBuffer(const APIExtensionVersion usedExtension,
14191 GLenum internalFormat,
14192 const size_t inputTextureDataSize,
14193 const void *inputTextureData,
14194 const GLColor expectedOutputColor);
14195 };
14196
14197 class TextureBufferTestES31 : public TextureBufferTestBase
14198 {
14199 protected:
TextureBufferTestES31()14200 TextureBufferTestES31() {}
14201
14202 void drawWithIncompleteOrZeroTexture(bool useCompleteTexture, bool useNonZeroTexture);
14203 };
14204
14205 class TextureBufferTestES32 : public TextureBufferTestBase
14206 {
14207 protected:
TextureBufferTestES32()14208 TextureBufferTestES32() {}
14209 };
14210
callTexBufferAPI(const APIExtensionVersion usedExtension,GLenum target,GLenum internalFormat,GLuint buffer)14211 void TextureBufferTestBase::callTexBufferAPI(const APIExtensionVersion usedExtension,
14212 GLenum target,
14213 GLenum internalFormat,
14214 GLuint buffer)
14215 {
14216 ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES ||
14217 usedExtension == APIExtensionVersion::Core);
14218 if (usedExtension == APIExtensionVersion::EXT)
14219 {
14220 glTexBufferEXT(target, internalFormat, buffer);
14221 }
14222 else if (usedExtension == APIExtensionVersion::OES)
14223 {
14224 glTexBufferOES(target, internalFormat, buffer);
14225 }
14226 else
14227 {
14228 glTexBuffer(target, internalFormat, buffer);
14229 }
14230 }
14231
testTexBuffer(const APIExtensionVersion usedExtension,GLenum internalFormat,const size_t inputTextureDataSize,const void * inputTextureData,const GLColor expectedOutputColor)14232 void TextureBufferTestBase::testTexBuffer(const APIExtensionVersion usedExtension,
14233 GLenum internalFormat,
14234 const size_t inputTextureDataSize,
14235 const void *inputTextureData,
14236 const GLColor expectedOutputColor)
14237 {
14238 ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES ||
14239 usedExtension == APIExtensionVersion::Core);
14240
14241 // TODO(http://anglebug.com/42264369): Claims to support GL_OES_texture_buffer, but fails
14242 // compilation of shader because "extension 'GL_OES_texture_buffer' is not supported".
14243 ANGLE_SKIP_TEST_IF(usedExtension == APIExtensionVersion::OES && IsQualcomm() && IsOpenGLES());
14244
14245 GLBuffer buffer;
14246 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14247 glBufferData(GL_TEXTURE_BUFFER, inputTextureDataSize, inputTextureData, GL_DYNAMIC_DRAW);
14248 EXPECT_GL_NO_ERROR();
14249
14250 // Shaders
14251 std::string simpleVS;
14252 std::string samplerBufferFS;
14253
14254 constexpr char kGLSLVersion31[] = R"(#version 310 es
14255 )";
14256 constexpr char kGLSLVersion32[] = R"(#version 320 es
14257 )";
14258 constexpr char kTexBufEXT[] = R"(#extension GL_EXT_texture_buffer : require
14259 )";
14260 constexpr char kTexBufOES[] = R"(#extension GL_OES_texture_buffer : require
14261 )";
14262
14263 if (usedExtension == APIExtensionVersion::EXT)
14264 {
14265 simpleVS.append(kGLSLVersion31);
14266 samplerBufferFS.append(kGLSLVersion31);
14267 samplerBufferFS.append(kTexBufEXT);
14268 }
14269 else if (usedExtension == APIExtensionVersion::OES)
14270 {
14271 simpleVS.append(kGLSLVersion31);
14272 samplerBufferFS.append(kGLSLVersion31);
14273 samplerBufferFS.append(kTexBufOES);
14274 }
14275 else
14276 {
14277 simpleVS.append(kGLSLVersion32);
14278 samplerBufferFS.append(kGLSLVersion32);
14279 }
14280
14281 constexpr char kVSBody[] = R"(
14282 in vec4 a_position;
14283 void main()
14284 {
14285 gl_Position = a_position;
14286 })";
14287 simpleVS.append(kVSBody);
14288
14289 constexpr char kFSBody[] = R"(
14290 precision mediump float;
14291 uniform highp samplerBuffer s;
14292 out vec4 colorOut;
14293 void main()
14294 {
14295 colorOut = texelFetch(s, 0);
14296 })";
14297 samplerBufferFS.append(kFSBody);
14298
14299 ANGLE_GL_PROGRAM(program, simpleVS.c_str(), samplerBufferFS.c_str());
14300 ASSERT_GL_NO_ERROR();
14301
14302 // Draw
14303 callTexBufferAPI(usedExtension, GL_TEXTURE_BUFFER, internalFormat, buffer);
14304 ASSERT_GL_NO_ERROR();
14305
14306 drawQuad(program, "a_position", 0.5);
14307 ASSERT_GL_NO_ERROR();
14308
14309 EXPECT_PIXEL_COLOR_EQ(0, 0, expectedOutputColor);
14310 }
14311
drawWithIncompleteOrZeroTexture(bool useCompleteTexture,bool useNonZeroTexture)14312 void TextureBufferTestES31::drawWithIncompleteOrZeroTexture(bool useCompleteTexture,
14313 bool useNonZeroTexture)
14314 {
14315 constexpr char kSamplerBuffer[] = R"(#version 310 es
14316 #extension GL_OES_texture_buffer : require
14317 precision mediump float;
14318 uniform highp samplerBuffer s;
14319 out vec4 colorOut;
14320 void main()
14321 {
14322 colorOut = texelFetch(s, 0);
14323 })";
14324
14325 ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kSamplerBuffer);
14326 glUseProgram(program);
14327 EXPECT_GL_NO_ERROR();
14328
14329 // Bind as texture buffer
14330 GLTexture texture;
14331 glActiveTexture(GL_TEXTURE0);
14332 glBindTexture(GL_TEXTURE_BUFFER, useNonZeroTexture ? texture.get() : 0u);
14333 EXPECT_GL_NO_ERROR();
14334
14335 if (useCompleteTexture)
14336 {
14337 const std::array<GLColor, 4> kData = {GLColor::blue, GLColor::blue, GLColor::blue,
14338 GLColor::blue};
14339
14340 // Create buffer and initialize with data
14341 GLBuffer buffer;
14342 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14343 glBufferData(GL_TEXTURE_BUFFER, sizeof(kData), kData.data(), GL_DYNAMIC_DRAW);
14344 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14345 EXPECT_GL_NO_ERROR();
14346 }
14347
14348 // Draw texture buffer
14349 drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14350 EXPECT_GL_NO_ERROR();
14351
14352 if (useCompleteTexture)
14353 {
14354 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
14355 }
14356 }
14357
14358 // Test that mutating a buffer attached to a texture returns correct results in query.
TEST_P(TextureBufferTestES31,QueryWidthAfterBufferResize)14359 TEST_P(TextureBufferTestES31, QueryWidthAfterBufferResize)
14360 {
14361 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14362
14363 constexpr GLint kInitialSize = 128;
14364 constexpr std::array<GLint, 4> kModifiedSizes = {96, 192, 32, 256};
14365
14366 GLTexture texture;
14367 glBindTexture(GL_TEXTURE_BUFFER, texture);
14368
14369 GLBuffer buffer;
14370 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14371 glBufferData(GL_TEXTURE_BUFFER, kInitialSize, nullptr, GL_STATIC_DRAW);
14372
14373 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14374 ASSERT_GL_NO_ERROR();
14375
14376 GLint queryResult = 0;
14377 glGetTexLevelParameteriv(GL_TEXTURE_BUFFER, 0, GL_TEXTURE_WIDTH, &queryResult);
14378 ASSERT_GL_NO_ERROR();
14379 EXPECT_EQ(queryResult, kInitialSize / 4);
14380
14381 for (GLint modifiedSize : kModifiedSizes)
14382 {
14383 glBufferData(GL_TEXTURE_BUFFER, modifiedSize, nullptr, GL_STATIC_DRAW);
14384 glGetTexLevelParameteriv(GL_TEXTURE_BUFFER, 0, GL_TEXTURE_WIDTH, &queryResult);
14385 ASSERT_GL_NO_ERROR();
14386 EXPECT_EQ(queryResult, modifiedSize / 4);
14387 }
14388 }
14389
14390 // Test that glTexBufferEXT can be used in two draw calls.
14391 // Covers a bug where TextureVk::setBuffer releases buffer views and doesn't init them.
TEST_P(TextureBufferTestES31,TexBufferDrawTwice)14392 TEST_P(TextureBufferTestES31, TexBufferDrawTwice)
14393 {
14394 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14395
14396 // TODO(http://anglebug.com/42264369): Claims to support GL_OES_texture_buffer, but fails
14397 // compilation of shader because "extension 'GL_OES_texture_buffer' is not supported".
14398 ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
14399
14400 const std::array<GLColor, 1> kTexData = {GLColor::red};
14401
14402 GLBuffer buffer;
14403 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14404 glBufferData(GL_TEXTURE_BUFFER, sizeof(kTexData), kTexData.data(), GL_DYNAMIC_DRAW);
14405 EXPECT_GL_NO_ERROR();
14406
14407 constexpr char kSamplerBuffer[] = R"(#version 310 es
14408 #extension GL_OES_texture_buffer : require
14409 precision mediump float;
14410 uniform highp samplerBuffer s;
14411 out vec4 colorOut;
14412 void main()
14413 {
14414 colorOut = texelFetch(s, 0);
14415 })";
14416
14417 ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kSamplerBuffer);
14418
14419 // Draw once
14420 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14421 drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14422 EXPECT_GL_NO_ERROR();
14423
14424 // Draw twice
14425 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14426 drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14427 EXPECT_GL_NO_ERROR();
14428
14429 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
14430 }
14431
14432 // Test that glTexBufferEXT can be used in a draw call for R8 normalized values.
TEST_P(TextureBufferTestES31,RNorm8EXT)14433 TEST_P(TextureBufferTestES31, RNorm8EXT)
14434 {
14435 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14436
14437 const std::array<uint8_t, 1> kTexData = {0xFF};
14438 testTexBuffer(APIExtensionVersion::EXT, GL_R8, sizeof(kTexData), kTexData.data(), GLColor::red);
14439 }
14440
14441 // Test that glTexBufferEXT can be used in a draw call for RG8 normalized values.
TEST_P(TextureBufferTestES31,RGNorm8EXT)14442 TEST_P(TextureBufferTestES31, RGNorm8EXT)
14443 {
14444 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14445
14446 const std::array<uint8_t, 2> kTexData = {0xFF, 0xFF};
14447 testTexBuffer(APIExtensionVersion::EXT, GL_RG8, sizeof(kTexData), kTexData.data(),
14448 GLColor::yellow);
14449 }
14450
14451 // Test that glTexBufferEXT can be used in a draw call for RGBA8 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm8EXT)14452 TEST_P(TextureBufferTestES31, RGBANorm8EXT)
14453 {
14454 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14455
14456 const std::array<uint8_t, 4> kTexData = {0xFF, 0, 0xFF, 0xFF};
14457 testTexBuffer(APIExtensionVersion::EXT, GL_RGBA8, sizeof(kTexData), kTexData.data(),
14458 GLColor::magenta);
14459 }
14460
14461 // Test that glTexBufferEXT can be used in a draw call for R16 normalized values.
TEST_P(TextureBufferTestES31,RNorm16EXT)14462 TEST_P(TextureBufferTestES31, RNorm16EXT)
14463 {
14464 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14465 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14466
14467 const std::array<uint16_t, 1> kTexData = {0xFFFF};
14468 testTexBuffer(APIExtensionVersion::EXT, GL_R16_EXT, sizeof(kTexData), kTexData.data(),
14469 GLColor::red);
14470 }
14471
14472 // Test that glTexBufferEXT can be used in a draw call for RG16 normalized values.
TEST_P(TextureBufferTestES31,RGNorm16EXT)14473 TEST_P(TextureBufferTestES31, RGNorm16EXT)
14474 {
14475 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14476 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14477
14478 const std::array<uint16_t, 2> kTexData = {0xFFFF, 0xFFFF};
14479 testTexBuffer(APIExtensionVersion::EXT, GL_RG16_EXT, sizeof(kTexData), kTexData.data(),
14480 GLColor::yellow);
14481 }
14482
14483 // Test that glTexBufferEXT can be used in a draw call for RGBA16 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm16EXT)14484 TEST_P(TextureBufferTestES31, RGBANorm16EXT)
14485 {
14486 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14487 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14488
14489 const std::array<uint16_t, 4> kTexData = {0xFFFF, 0, 0xFFFF, 0xFFFF};
14490 testTexBuffer(APIExtensionVersion::EXT, GL_RGBA16_EXT, sizeof(kTexData), kTexData.data(),
14491 GLColor::magenta);
14492 }
14493
14494 // Test that glTexBufferOES can be used in a draw call for R8 normalized values.
TEST_P(TextureBufferTestES31,RNorm8OES)14495 TEST_P(TextureBufferTestES31, RNorm8OES)
14496 {
14497 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14498
14499 const std::array<uint8_t, 1> kTexData = {0xFF};
14500 testTexBuffer(APIExtensionVersion::OES, GL_R8, sizeof(kTexData), kTexData.data(), GLColor::red);
14501 }
14502
14503 // Test that glTexBufferOES can be used in a draw call for RG8 normalized values.
TEST_P(TextureBufferTestES31,RGNorm8OES)14504 TEST_P(TextureBufferTestES31, RGNorm8OES)
14505 {
14506 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14507
14508 const std::array<uint8_t, 2> kTexData = {0xFF, 0xFF};
14509 testTexBuffer(APIExtensionVersion::OES, GL_RG8, sizeof(kTexData), kTexData.data(),
14510 GLColor::yellow);
14511 }
14512
14513 // Test that glTexBufferOES can be used in a draw call for RGBA8 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm8OES)14514 TEST_P(TextureBufferTestES31, RGBANorm8OES)
14515 {
14516 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14517
14518 const std::array<uint8_t, 4> kTexData = {0xFF, 0, 0xFF, 0xFF};
14519 testTexBuffer(APIExtensionVersion::OES, GL_RGBA8, sizeof(kTexData), kTexData.data(),
14520 GLColor::magenta);
14521 }
14522
14523 // Test that glTexBufferOES can be used in a draw call for R16 normalized values.
TEST_P(TextureBufferTestES31,RNorm16OES)14524 TEST_P(TextureBufferTestES31, RNorm16OES)
14525 {
14526 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14527 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14528
14529 const std::array<uint16_t, 1> kTexData = {0xFFFF};
14530 testTexBuffer(APIExtensionVersion::OES, GL_R16_EXT, sizeof(kTexData), kTexData.data(),
14531 GLColor::red);
14532 }
14533
14534 // Test that glTexBufferOES can be used in a draw call for RG16 normalized values.
TEST_P(TextureBufferTestES31,RGNorm16OES)14535 TEST_P(TextureBufferTestES31, RGNorm16OES)
14536 {
14537 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14538 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14539
14540 const std::array<uint16_t, 2> kTexData = {0xFFFF, 0xFFFF};
14541 testTexBuffer(APIExtensionVersion::OES, GL_RG16_EXT, sizeof(kTexData), kTexData.data(),
14542 GLColor::yellow);
14543 }
14544
14545 // Test that glTexBufferOES can be used in a draw call for RGBA16 normalized values.
TEST_P(TextureBufferTestES31,RGBANorm16OES)14546 TEST_P(TextureBufferTestES31, RGBANorm16OES)
14547 {
14548 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14549 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14550
14551 const std::array<uint16_t, 4> kTexData = {0xFFFF, 0, 0xFFFF, 0xFFFF};
14552 testTexBuffer(APIExtensionVersion::OES, GL_RGBA16_EXT, sizeof(kTexData), kTexData.data(),
14553 GLColor::magenta);
14554 }
14555
14556 // Test that glTexBuffer can be used in a draw call for R8 normalized values.
TEST_P(TextureBufferTestES32,RNorm8)14557 TEST_P(TextureBufferTestES32, RNorm8)
14558 {
14559 const std::array<uint8_t, 1> kTexData = {0xFF};
14560 testTexBuffer(APIExtensionVersion::Core, GL_R8, sizeof(kTexData), kTexData.data(),
14561 GLColor::red);
14562 }
14563
14564 // Test that glTexBuffer can be used in a draw call for RG8 normalized values.
TEST_P(TextureBufferTestES32,RGNorm8)14565 TEST_P(TextureBufferTestES32, RGNorm8)
14566 {
14567 const std::array<uint8_t, 2> kTexData = {0xFF, 0xFF};
14568 testTexBuffer(APIExtensionVersion::Core, GL_RG8, sizeof(kTexData), kTexData.data(),
14569 GLColor::yellow);
14570 }
14571
14572 // Test that glTexBuffer can be used in a draw call for RGBA8 normalized values.
TEST_P(TextureBufferTestES32,RGBANorm8)14573 TEST_P(TextureBufferTestES32, RGBANorm8)
14574 {
14575 const std::array<uint8_t, 4> kTexData = {0xFF, 0, 0xFF, 0xFF};
14576 testTexBuffer(APIExtensionVersion::Core, GL_RGBA8, sizeof(kTexData), kTexData.data(),
14577 GLColor::magenta);
14578 }
14579
14580 // Test that glTexBuffer can be used in a draw call for R16 normalized values.
TEST_P(TextureBufferTestES32,RNorm16)14581 TEST_P(TextureBufferTestES32, RNorm16)
14582 {
14583 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14584
14585 const std::array<uint16_t, 1> kTexData = {0xFFFF};
14586 testTexBuffer(APIExtensionVersion::Core, GL_R16_EXT, sizeof(kTexData), kTexData.data(),
14587 GLColor::red);
14588 }
14589
14590 // Test that glTexBuffer can be used in a draw call for RG16 normalized values.
TEST_P(TextureBufferTestES32,RGNorm16)14591 TEST_P(TextureBufferTestES32, RGNorm16)
14592 {
14593 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14594
14595 const std::array<uint16_t, 2> kTexData = {0xFFFF, 0xFFFF};
14596 testTexBuffer(APIExtensionVersion::Core, GL_RG16_EXT, sizeof(kTexData), kTexData.data(),
14597 GLColor::yellow);
14598 }
14599
14600 // Test that glTexBuffer can be used in a draw call for RGBA16 normalized values.
TEST_P(TextureBufferTestES32,RGBANorm16)14601 TEST_P(TextureBufferTestES32, RGBANorm16)
14602 {
14603 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
14604
14605 const std::array<uint16_t, 4> kTexData = {0xFFFF, 0, 0xFFFF, 0xFFFF};
14606 testTexBuffer(APIExtensionVersion::Core, GL_RGBA16_EXT, sizeof(kTexData), kTexData.data(),
14607 GLColor::magenta);
14608 }
14609
14610 // Test that uploading data to buffer that's in use then using it as texture buffer works.
TEST_P(TextureBufferTestES31,UseAsUBOThenUpdateThenAsTextureBuffer)14611 TEST_P(TextureBufferTestES31, UseAsUBOThenUpdateThenAsTextureBuffer)
14612 {
14613 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14614
14615 // Claims to support GL_OES_texture_buffer, but fails compilation of shader because "extension
14616 // 'GL_OES_texture_buffer' is not supported". http://anglebug.com/42264369
14617 ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
14618
14619 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
14620 GLColor::red};
14621 const std::array<GLColor, 4> kUpdateData = {GLColor::blue, GLColor::blue, GLColor::blue,
14622 GLColor::blue};
14623
14624 GLBuffer buffer;
14625 glBindBuffer(GL_UNIFORM_BUFFER, buffer);
14626 glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
14627 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
14628 EXPECT_GL_NO_ERROR();
14629
14630 constexpr char kVerifyUBO[] = R"(#version 310 es
14631 precision mediump float;
14632 layout(binding = 0) uniform block {
14633 uvec4 data;
14634 } ubo;
14635 out vec4 colorOut;
14636 void main()
14637 {
14638 if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
14639 colorOut = vec4(0, 1.0, 0, 1.0);
14640 else
14641 colorOut = vec4(1.0, 0, 0, 1.0);
14642 })";
14643
14644 ANGLE_GL_PROGRAM(verifyUbo, essl31_shaders::vs::Simple(), kVerifyUBO);
14645 drawQuad(verifyUbo, essl31_shaders::PositionAttrib(), 0.5);
14646 EXPECT_GL_NO_ERROR();
14647
14648 // Update buffer data
14649 glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
14650 EXPECT_GL_NO_ERROR();
14651
14652 // Bind as texture buffer
14653 GLTexture texture;
14654 glBindTexture(GL_TEXTURE_BUFFER, texture);
14655 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14656 EXPECT_GL_NO_ERROR();
14657
14658 constexpr char kVerifySamplerBuffer[] = R"(#version 310 es
14659 #extension GL_OES_texture_buffer : require
14660 precision mediump float;
14661 uniform highp samplerBuffer s;
14662 out vec4 colorOut;
14663 void main()
14664 {
14665 colorOut = texelFetch(s, 0);
14666 })";
14667
14668 ANGLE_GL_PROGRAM(verifySamplerBuffer, essl31_shaders::vs::Simple(), kVerifySamplerBuffer);
14669
14670 glEnable(GL_BLEND);
14671 glBlendFunc(GL_ONE, GL_ONE);
14672 drawQuad(verifySamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14673 EXPECT_GL_NO_ERROR();
14674
14675 // Make sure both draw calls succeed
14676 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
14677 }
14678
14679 // Test that mapping a texture buffer with GL_MAP_INVALIDATE_BUFFER_BIT and writing to it works
14680 // correctly.
TEST_P(TextureBufferTestES31,MapTextureBufferInvalidateThenWrite)14681 TEST_P(TextureBufferTestES31, MapTextureBufferInvalidateThenWrite)
14682 {
14683 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14684
14685 // TODO(http://anglebug.com/42264369): Claims to support GL_OES_texture_buffer, but fails
14686 // compilation of shader because "extension 'GL_OES_texture_buffer' is not supported".
14687 ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
14688 // TODO(http://anglebug.com/42264910): The OpenGL backend doesn't correctly handle texture
14689 // buffers being invalidated when mapped.
14690 ANGLE_SKIP_TEST_IF(IsOpenGL());
14691
14692 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
14693 GLColor::red};
14694 const std::array<GLColor, 4> kUpdateData = {GLColor::blue, GLColor::blue, GLColor::blue,
14695 GLColor::blue};
14696
14697 GLBuffer buffer;
14698 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14699 glBufferData(GL_TEXTURE_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
14700 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
14701 EXPECT_GL_NO_ERROR();
14702
14703 // Bind as texture buffer
14704 GLTexture texture;
14705 glBindTexture(GL_TEXTURE_BUFFER, texture);
14706 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14707 EXPECT_GL_NO_ERROR();
14708
14709 constexpr char kSamplerBuffer[] = R"(#version 310 es
14710 #extension GL_OES_texture_buffer : require
14711 precision mediump float;
14712 uniform highp samplerBuffer s;
14713 out vec4 colorOut;
14714 void main()
14715 {
14716 colorOut = texelFetch(s, 0);
14717 })";
14718
14719 ANGLE_GL_PROGRAM(initialSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14720 drawQuad(initialSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14721 EXPECT_GL_NO_ERROR();
14722
14723 // Don't read back, so we don't break the render pass.
14724
14725 // Map the buffer and update it.
14726 void *mappedBuffer = glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(kInitialData),
14727 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
14728 memcpy(mappedBuffer, kUpdateData.data(), sizeof(kInitialData));
14729
14730 glUnmapBuffer(GL_TEXTURE_BUFFER);
14731
14732 // Draw with the updated buffer data.
14733 ANGLE_GL_PROGRAM(updateSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14734 drawQuad(updateSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14735 EXPECT_GL_NO_ERROR();
14736
14737 // Make sure both draw calls succeed
14738 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
14739 }
14740
14741 // Test that calling glBufferData on a buffer that is used as texture buffer still works correctly.
TEST_P(TextureBufferTestES31,TextureBufferThenBufferData)14742 TEST_P(TextureBufferTestES31, TextureBufferThenBufferData)
14743 {
14744 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14745
14746 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
14747 GLColor::red};
14748 const std::array<GLColor, 4> kUpdateData = {GLColor::blue, GLColor::blue, GLColor::blue,
14749 GLColor::blue};
14750 // Create buffer and initialize with data
14751 GLBuffer buffer;
14752 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14753 glBufferData(GL_TEXTURE_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
14754
14755 // Bind as texture buffer
14756 GLTexture texture;
14757 glBindTexture(GL_TEXTURE_BUFFER, texture);
14758 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
14759 EXPECT_GL_NO_ERROR();
14760
14761 constexpr char kSamplerBuffer[] = R"(#version 310 es
14762 #extension GL_OES_texture_buffer : require
14763 precision mediump float;
14764 uniform highp samplerBuffer s;
14765 out vec4 colorOut;
14766 void main()
14767 {
14768 colorOut = texelFetch(s, 0);
14769 })";
14770
14771 ANGLE_GL_PROGRAM(initialSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14772 drawQuad(initialSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14773
14774 // Don't read back, so we keep the original buffer busy. Issue a glBufferData call with same
14775 // size and nullptr so that the old buffer storage gets orphaned.
14776 glBufferData(GL_TEXTURE_BUFFER, sizeof(kUpdateData), nullptr, GL_DYNAMIC_DRAW);
14777 glBufferSubData(GL_TEXTURE_BUFFER, 0, sizeof(kUpdateData), kUpdateData.data());
14778
14779 // Draw with the updated buffer data.
14780 ANGLE_GL_PROGRAM(updateSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
14781 drawQuad(updateSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
14782 EXPECT_GL_NO_ERROR();
14783 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
14784 }
14785
14786 // Test that drawing with a texture buffer after changing its content using transform feedback.
TEST_P(TextureBufferTestES31,UseAsXFBThenAsTextureBuffer)14787 TEST_P(TextureBufferTestES31, UseAsXFBThenAsTextureBuffer)
14788 {
14789 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14790
14791 // Issue a draw call with xfb, set buffer to red
14792 constexpr char kXFBVS[] = R"(#version 310 es
14793 uniform vec4 colorIn;
14794 flat out highp vec4 colorOut;
14795 void main()
14796 {
14797 gl_Position = vec4(0, 0, 0, 1);
14798 colorOut = colorIn;
14799 })";
14800
14801 // Capture the varying "v".
14802 const std::vector<std::string> tfVaryings = {"colorOut"};
14803 ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(programXFB, kXFBVS, essl31_shaders::fs::Green(), tfVaryings,
14804 GL_INTERLEAVED_ATTRIBS);
14805 EXPECT_GL_NO_ERROR();
14806 glUseProgram(programXFB);
14807 const GLint colorLoc = glGetUniformLocation(programXFB, "colorIn");
14808 ASSERT_NE(-1, colorLoc);
14809 glUniform4f(colorLoc, 1, 0, 0, 1);
14810 EXPECT_GL_NO_ERROR();
14811
14812 GLTransformFeedback tf;
14813 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf);
14814 // Initializing the buffer with 0. After the transform feedback writes to it, the data will
14815 // change.
14816 const std::array<GLfloat, 4> data = {0.0, 0.0, 0.0, 0.0};
14817 GLBuffer buffer;
14818 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
14819 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, data.size() * sizeof(data[0]), data.data(),
14820 GL_DYNAMIC_DRAW);
14821 // Fill the buffer using transform feedback.
14822 glBeginTransformFeedback(GL_POINTS);
14823 glDrawArrays(GL_POINTS, 0, 1);
14824 glEndTransformFeedback();
14825
14826 // Issue a draw call with samplerBuffer, sample from buffer and write to color attachment
14827 constexpr char kTextureBufferFS[] = R"(#version 310 es
14828 #extension GL_EXT_texture_buffer : require
14829 precision mediump float;
14830 uniform highp samplerBuffer sampler_buffer;
14831 out vec4 colorOut;
14832 void main()
14833 {
14834 colorOut = texelFetch(sampler_buffer, 0);
14835 })";
14836 ANGLE_GL_PROGRAM(programTextureBuffer, essl31_shaders::vs::Simple(), kTextureBufferFS);
14837 glUseProgram(programTextureBuffer);
14838
14839 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14840 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, buffer);
14841
14842 drawQuad(programTextureBuffer, essl31_shaders::PositionAttrib(), 0.5);
14843 EXPECT_GL_NO_ERROR();
14844
14845 // Issue a draw call with xfb, set buffer to green
14846 glUseProgram(programXFB);
14847 glUniform4f(colorLoc, 0, 1, 0, 1);
14848 EXPECT_GL_NO_ERROR();
14849 glBeginTransformFeedback(GL_POINTS);
14850 glDrawArrays(GL_POINTS, 0, 1);
14851 glEndTransformFeedback();
14852
14853 // Enable blend, with glBlendFunc(GL_ONE, GL_ONE)
14854 glEnable(GL_BLEND);
14855 glBlendFunc(GL_ONE, GL_ONE);
14856
14857 // Issue a draw call with samplerBuffer
14858 glUseProgram(programTextureBuffer);
14859 drawQuad(programTextureBuffer, essl31_shaders::PositionAttrib(), 0.5);
14860 EXPECT_GL_NO_ERROR();
14861 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(255, 255, 0, 255));
14862 }
14863
14864 // Test workaround in Vulkan backend for mismatched texture buffer and sampler formats
TEST_P(TextureBufferTestES31,TexBufferFormatMismatch)14865 TEST_P(TextureBufferTestES31, TexBufferFormatMismatch)
14866 {
14867 ANGLE_SKIP_TEST_IF(!IsVulkan());
14868 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
14869
14870 auto runTestCase = [&](auto texData, GLenum format, const char *samplerType) {
14871 std::stringstream fsStream;
14872 fsStream << R"(#version 310 es
14873 #extension GL_EXT_texture_buffer : require
14874 precision mediump float;
14875 uniform highp )"
14876 << samplerType << R"( s;
14877 out vec4 colorOut;
14878 void main()
14879 {
14880 colorOut = vec4(texelFetch(s, 0).r, 0, 0, 1);
14881 })";
14882 ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), fsStream.str().c_str());
14883
14884 GLBuffer buffer;
14885 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
14886
14887 glBufferData(GL_TEXTURE_BUFFER, sizeof(texData), texData.data(), GL_DYNAMIC_DRAW);
14888 glTexBufferEXT(GL_TEXTURE_BUFFER, format, buffer);
14889
14890 drawQuad(program, essl31_shaders::PositionAttrib(), 0.5);
14891 EXPECT_GL_NO_ERROR();
14892 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
14893 };
14894
14895 const std::array<uint8_t, 4> kTexData8n{255}; // 8-bit normalized {1,0,0,0}
14896 const std::array<uint8_t, 4> kTexData8i{1}; // 8-bit (u)int {1,0,0,0}
14897
14898 // Test all 8-bit formats from EXT_texture_buffer.txt Table texbo.1
14899 for (auto format :
14900 {GL_R8, GL_R8I, GL_R8UI, GL_RG8, GL_RG8I, GL_RG8UI, GL_RGBA8, GL_RGBA8I, GL_RGBA8UI})
14901 {
14902 // float sampler
14903 runTestCase(kTexData8n, format, "samplerBuffer");
14904 // integer samplers
14905 runTestCase(kTexData8i, format, "isamplerBuffer");
14906 runTestCase(kTexData8i, format, "usamplerBuffer");
14907 }
14908
14909 const uint16_t kHalfFloatOne = 0x3C00;
14910 const std::array<uint16_t, 4> kTexData16f{kHalfFloatOne}; // 16-bit float {1,0,0,0}
14911 const std::array<uint16_t, 4> kTexData16i{1}; // 16-bit (u)int {1,0,0,0}
14912
14913 // Test all 16-bit formats from EXT_texture_buffer.txt Table texbo.1
14914 for (auto format : {GL_R16F, GL_R16I, GL_R16UI, GL_RG16F, GL_RG16I, GL_RG16UI, GL_RGBA16F,
14915 GL_RGBA16I, GL_RGBA16UI})
14916 {
14917 // float sampler
14918 runTestCase(kTexData16f, format, "samplerBuffer");
14919 // integer samplers
14920 runTestCase(kTexData16i, format, "isamplerBuffer");
14921 runTestCase(kTexData16i, format, "usamplerBuffer");
14922 }
14923
14924 const std::array<GLfloat, 4> kTexData32f{1.0f}; // 32-bit float {1,0,0,0}
14925 const std::array<uint32_t, 4> kTexData32i{1}; // 32-bit (u)int {1,0,0,0}
14926
14927 // Test all 32-bit formats from EXT_texture_buffer.txt Table texbo.1
14928 for (auto format : {GL_R32F, GL_R32I, GL_R32UI, GL_RG32F, GL_RG32I, GL_RG32UI, GL_RGB32F,
14929 GL_RGB32I, GL_RGB32UI, GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI})
14930 {
14931 // float sampler
14932 runTestCase(kTexData32f, format, "samplerBuffer");
14933 // integer samplers
14934 runTestCase(kTexData32i, format, "isamplerBuffer");
14935 runTestCase(kTexData32i, format, "usamplerBuffer");
14936 }
14937 }
14938
14939 // Create an integer format texture but specify a FLOAT sampler. OpenGL
14940 // tolerates this but it causes a Vulkan validation error.
TEST_P(Texture2DTestES3,TexImageFormatMismatch)14941 TEST_P(Texture2DTestES3, TexImageFormatMismatch)
14942 {
14943 GLint textureUnit = 2;
14944 GLuint genericBuffer;
14945 GLubyte genericBufferMemory[1024];
14946 GLuint texture;
14947 GLuint sampler;
14948 GLuint vertexArray;
14949
14950 glGenBuffers(1, &genericBuffer);
14951 glBindBuffer(GL_ARRAY_BUFFER, genericBuffer);
14952 glBufferData(GL_ARRAY_BUFFER, 1024, &genericBufferMemory, GL_STATIC_DRAW);
14953
14954 glGenTextures(1, &texture);
14955 glBindTexture(GL_TEXTURE_2D, texture);
14956 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
14957 glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 8, 8, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT,
14958 &genericBufferMemory);
14959
14960 const char *vertexShaderSource = getVertexShaderSource();
14961 const char *fragmentShaderSource = getFragmentShaderSource();
14962 ANGLE_GL_PROGRAM(testProgram, vertexShaderSource, fragmentShaderSource);
14963
14964 GLint texLocation = glGetUniformLocation(testProgram, "tex");
14965 glUseProgram(testProgram);
14966
14967 glUniform1iv(texLocation, 1, &textureUnit);
14968
14969 glGenSamplers(1, &sampler);
14970 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
14971 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
14972
14973 glBindBuffer(GL_UNIFORM_BUFFER, genericBuffer);
14974
14975 glActiveTexture(GL_TEXTURE0 + textureUnit);
14976 glBindTexture(GL_TEXTURE_2D, texture);
14977 glBindSampler(textureUnit, sampler);
14978
14979 glGenVertexArrays(1, &vertexArray);
14980 glBindVertexArray(vertexArray);
14981 glBindBuffer(GL_ARRAY_BUFFER, genericBuffer);
14982
14983 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, genericBuffer);
14984 glBindVertexArray(vertexArray);
14985 glDrawElementsInstanced(GL_TRIANGLES, 4, GL_UNSIGNED_SHORT, 0, 1);
14986 }
14987
14988 // Checks that drawing incomplete zero texture buffer does not crash.
TEST_P(TextureBufferTestES31,DrawIncompleteZeroTexture)14989 TEST_P(TextureBufferTestES31, DrawIncompleteZeroTexture)
14990 {
14991 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
14992
14993 drawWithIncompleteOrZeroTexture(false, false);
14994 }
14995
14996 // Checks that drawing incomplete non-zero texture buffer does not crash.
TEST_P(TextureBufferTestES31,DrawIncompleteNonZeroTexture)14997 TEST_P(TextureBufferTestES31, DrawIncompleteNonZeroTexture)
14998 {
14999 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
15000
15001 drawWithIncompleteOrZeroTexture(false, true);
15002 }
15003
15004 // Checks that drawing complete zero texture buffer produces expected results.
TEST_P(TextureBufferTestES31,DrawCompleteZeroTexture)15005 TEST_P(TextureBufferTestES31, DrawCompleteZeroTexture)
15006 {
15007 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
15008
15009 drawWithIncompleteOrZeroTexture(true, false);
15010 }
15011
15012 // Checks that drawing complete non-zero texture buffer produces expected results.
TEST_P(TextureBufferTestES31,DrawCompleteNonZeroTexture)15013 TEST_P(TextureBufferTestES31, DrawCompleteNonZeroTexture)
15014 {
15015 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
15016
15017 drawWithIncompleteOrZeroTexture(true, true);
15018 }
15019
15020 // Test that the correct error is generated if texture buffer support used anyway when not enabled.
TEST_P(TextureBufferTestES31,TestErrorWhenNotEnabled)15021 TEST_P(TextureBufferTestES31, TestErrorWhenNotEnabled)
15022 {
15023 ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15024
15025 GLTexture texture;
15026 glBindTexture(GL_TEXTURE_BUFFER, texture);
15027 ASSERT_GL_ERROR(GL_INVALID_ENUM);
15028 }
15029
15030 class CopyImageTestES31 : public ANGLETest<>
15031 {
15032 protected:
CopyImageTestES31()15033 CopyImageTestES31()
15034 {
15035 setConfigRedBits(8);
15036 setConfigGreenBits(8);
15037 setConfigBlueBits(8);
15038 setConfigAlphaBits(8);
15039 }
15040 };
15041
15042 // Test that copies between RGB formats doesn't affect the emulated alpha channel, if any.
TEST_P(CopyImageTestES31,PreserveEmulatedAlpha)15043 TEST_P(CopyImageTestES31, PreserveEmulatedAlpha)
15044 {
15045 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15046
15047 constexpr GLsizei kSize = 1;
15048
15049 GLTexture src, dst;
15050
15051 // Set up the textures
15052 glBindTexture(GL_TEXTURE_2D, src);
15053 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, kSize, kSize);
15054
15055 const GLColor kInitColor(50, 100, 150, 200);
15056 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGB, GL_UNSIGNED_BYTE, &kInitColor);
15057
15058 glBindTexture(GL_TEXTURE_2D, dst);
15059 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8UI, kSize, kSize);
15060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
15061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
15062
15063 // Copy from src to dst
15064 glCopyImageSubDataEXT(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
15065 kSize, 1);
15066
15067 // Bind dst as image
15068 glBindImageTexture(0, dst, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI);
15069
15070 // Create a buffer for output
15071 constexpr GLsizei kBufferSize = kSize * kSize * sizeof(uint32_t) * 4;
15072 GLBuffer buffer;
15073 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
15074 glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
15075 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, buffer);
15076
15077 constexpr char kCS[] = R"(#version 310 es
15078 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
15079 layout(rgba8ui, binding = 0) readonly uniform highp uimage2D imageIn;
15080 layout(std140, binding = 1) buffer dataOut {
15081 uvec4 data[];
15082 };
15083 void main()
15084 {
15085 uvec4 color = imageLoad(imageIn, ivec2(0));
15086 data[0] = color;
15087 })";
15088
15089 ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
15090 glUseProgram(program);
15091 glDispatchCompute(1, 1, 1);
15092 EXPECT_GL_NO_ERROR();
15093
15094 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
15095
15096 const uint32_t *ptr = reinterpret_cast<uint32_t *>(
15097 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
15098
15099 EXPECT_EQ(ptr[0], kInitColor.R);
15100 EXPECT_EQ(ptr[1], kInitColor.G);
15101 EXPECT_EQ(ptr[2], kInitColor.B);
15102
15103 // Expect alpha to be 1, even if the RGB format is emulated with RGBA.
15104 EXPECT_EQ(ptr[3], 1u);
15105
15106 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
15107 }
15108
15109 // Verify a common pattern used by the Unreal Engine that trips up the tracer
TEST_P(CopyImageTestES31,CubeMapCopyImageSubData)15110 TEST_P(CopyImageTestES31, CubeMapCopyImageSubData)
15111 {
15112 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15113
15114 constexpr char kVS[] =
15115 R"(#version 300 es
15116 precision mediump float;
15117 in vec3 pos;
15118 void main() {
15119 gl_Position = vec4(pos, 1.0);
15120 })";
15121
15122 constexpr char kFS[] =
15123 R"(#version 300 es
15124 precision mediump float;
15125 out vec4 color;
15126 uniform samplerCube uTex;
15127 void main(){
15128 // sample from lod 1.0
15129 color = textureLod(uTex, vec3(1.0), 1.0);
15130 })";
15131
15132 ANGLE_GL_PROGRAM(program, kVS, kFS);
15133 glUseProgram(program);
15134
15135 // Set up two cube maps, then verify we can copy between them
15136 constexpr size_t kSize = 2;
15137 constexpr int levels = 2;
15138 std::vector<GLColor> pixelsGreen(kSize * kSize, GLColor::green);
15139 std::vector<GLColor> pixelsRed(kSize * kSize, GLColor::red);
15140
15141 // Initialize src to green
15142 GLTexture texCubeSrc;
15143 glBindTexture(GL_TEXTURE_CUBE_MAP, texCubeSrc);
15144 for (int i = 0; i < levels; i++)
15145 {
15146 for (GLenum face = 0; face < 6; face++)
15147 {
15148 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, GL_RGBA, kSize >> i, kSize >> i,
15149 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsGreen.data());
15150 }
15151 }
15152 ASSERT_GL_NO_ERROR();
15153
15154 // Initialize dst to red
15155 GLTexture texCubeDst;
15156 glBindTexture(GL_TEXTURE_CUBE_MAP, texCubeDst);
15157 for (int i = 0; i < levels; i++)
15158 {
15159 for (GLenum face = 0; face < 6; face++)
15160 {
15161 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, GL_RGBA, kSize >> i, kSize >> i,
15162 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
15163 }
15164 }
15165 ASSERT_GL_NO_ERROR();
15166
15167 // Clear to blue
15168 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
15169 glClear(GL_COLOR_BUFFER_BIT);
15170 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
15171
15172 // Sample from the dst texture to ensure it has the right color
15173 GLint textureLoc = glGetUniformLocation(program, "uTex");
15174 ASSERT_NE(-1, textureLoc);
15175 glUniform1i(textureLoc, 0);
15176
15177 // Draw once and sample from level 1, which is red
15178 drawQuad(program, "pos", 0.5f);
15179 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
15180
15181 // Swap to trigger MEC
15182 swapBuffers();
15183
15184 // Copy level 1 from src to dst
15185 glCopyImageSubDataEXT(texCubeSrc, GL_TEXTURE_CUBE_MAP, 1, 0, 0, 0, texCubeDst,
15186 GL_TEXTURE_CUBE_MAP, 1, 0, 0, 0, kSize >> 1, kSize >> 1, 6);
15187 ASSERT_GL_NO_ERROR();
15188
15189 // Draw again and verify we get green
15190 drawQuad(program, "pos", 0.5f);
15191 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
15192
15193 // Swap again to end the capture
15194 swapBuffers();
15195
15196 ASSERT_GL_NO_ERROR();
15197 }
15198
15199 // Verify that copies between texture layers works, including when there is a read after write in a
15200 // level/layer.
TEST_P(CopyImageTestES31,ArraySelfCopyImageSubDataWithReadAfterWrite)15201 TEST_P(CopyImageTestES31, ArraySelfCopyImageSubDataWithReadAfterWrite)
15202 {
15203 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15204
15205 // Set up a texture with multiple layers, then verify we can copy between them
15206 constexpr uint32_t kWidth = 13;
15207 constexpr uint32_t kHeight = 57;
15208 constexpr uint32_t kLayers = 5;
15209 constexpr uint32_t kLevels = 2;
15210 std::vector<GLColor> pixelsRed(kWidth * kHeight, GLColor::red);
15211 std::vector<GLColor> pixelsGreen(kWidth * kHeight, GLColor::green);
15212 std::vector<GLColor> pixelsBlue(kWidth * kHeight, GLColor::blue);
15213
15214 const GLColor *colors[3] = {
15215 pixelsRed.data(),
15216 pixelsGreen.data(),
15217 pixelsBlue.data(),
15218 };
15219
15220 GLTexture tex;
15221 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
15222 glTexStorage3D(GL_TEXTURE_2D_ARRAY, kLevels, GL_RGBA8, kWidth, kHeight, kLayers);
15223 for (uint32_t level = 0; level < kLevels; ++level)
15224 {
15225 for (uint32_t layer = 0; layer < kLayers; ++layer)
15226 {
15227 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, layer, kWidth >> level,
15228 kHeight >> level, 1, GL_RGBA, GL_UNSIGNED_BYTE,
15229 colors[(level + layer) % 3]);
15230 }
15231 }
15232 ASSERT_GL_NO_ERROR();
15233
15234 // The texture has the following colors:
15235 // Layer 0 Layer 1 Layer 2 Layer 3 Layer 4
15236 // Level 0 Red Green Blue Red Green
15237 // Level 1 Green Blue Red Green Blue
15238
15239 // Copy level 0, layer 0 to level 0, layer 2
15240 glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15241 2, kWidth, kHeight, 1);
15242
15243 // Copy level 1, layers 3, 4 to level 1, layers 1, 2
15244 glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 1, 0, 0, 3, tex, GL_TEXTURE_2D_ARRAY, 1, 0, 0,
15245 1, kWidth >> 1, kHeight >> 1, 2);
15246
15247 // Partially copy level 1, layer 1 to level 0, layer 3
15248 // Level 1/layer 1 will be read from after being written to
15249 glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 1, kWidth / 8, kHeight / 8, 1, tex,
15250 GL_TEXTURE_2D_ARRAY, 0, kWidth / 4, kHeight / 4, 3, kWidth / 4,
15251 kHeight / 4, 1);
15252 ASSERT_GL_NO_ERROR();
15253
15254 // Verify colors
15255 GLFramebuffer FBO;
15256 glBindFramebuffer(GL_FRAMEBUFFER, FBO);
15257 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
15258 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15259
15260 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
15261 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15262
15263 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
15264 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15265
15266 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 3);
15267 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight / 4, GLColor::red);
15268 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 4, kHeight, GLColor::red);
15269 EXPECT_PIXEL_RECT_EQ(0, kHeight / 4 + kHeight / 4, kWidth,
15270 kHeight - (kHeight / 4 + kHeight / 4), GLColor::red);
15271 EXPECT_PIXEL_RECT_EQ(kWidth / 4 + kWidth / 4, 0, kWidth - (kWidth / 4 + kWidth / 4), kHeight,
15272 GLColor::red);
15273 EXPECT_PIXEL_RECT_EQ(kWidth / 4, kHeight / 4, kWidth / 4, kHeight / 4, GLColor::green);
15274
15275 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 4);
15276 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15277
15278 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 0);
15279 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15280
15281 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 1);
15282 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15283
15284 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 2);
15285 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15286
15287 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 3);
15288 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15289
15290 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 4);
15291 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15292 ASSERT_GL_NO_ERROR();
15293 }
15294
15295 // Verify that copies between texture layers works, including when there is a write after read in a
15296 // level/layer.
TEST_P(CopyImageTestES31,ArraySelfCopyImageSubDataWithWriteAfterRead)15297 TEST_P(CopyImageTestES31, ArraySelfCopyImageSubDataWithWriteAfterRead)
15298 {
15299 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15300
15301 // Set up a texture with multiple layers, then verify we can copy between them
15302 constexpr uint32_t kWidth = 13;
15303 constexpr uint32_t kHeight = 57;
15304 constexpr uint32_t kLayers = 5;
15305 constexpr uint32_t kLevels = 2;
15306 std::vector<GLColor> pixelsRed(kWidth * kHeight, GLColor::red);
15307 std::vector<GLColor> pixelsGreen(kWidth * kHeight, GLColor::green);
15308 std::vector<GLColor> pixelsBlue(kWidth * kHeight, GLColor::blue);
15309
15310 const GLColor *colors[3] = {
15311 pixelsRed.data(),
15312 pixelsGreen.data(),
15313 pixelsBlue.data(),
15314 };
15315
15316 GLTexture tex;
15317 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
15318 glTexStorage3D(GL_TEXTURE_2D_ARRAY, kLevels, GL_RGBA8, kWidth, kHeight, kLayers);
15319 for (uint32_t level = 0; level < kLevels; ++level)
15320 {
15321 for (uint32_t layer = 0; layer < kLayers; ++layer)
15322 {
15323 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, layer, kWidth >> level,
15324 kHeight >> level, 1, GL_RGBA, GL_UNSIGNED_BYTE,
15325 colors[(level + layer) % 3]);
15326 }
15327 }
15328 ASSERT_GL_NO_ERROR();
15329
15330 // The texture has the following colors:
15331 // Layer 0 Layer 1 Layer 2 Layer 3 Layer 4
15332 // Level 0 Red Green Blue Red Green
15333 // Level 1 Green Blue Red Green Blue
15334
15335 // Copy level 0, layer 0 to level 0, layer 2
15336 glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15337 2, kWidth, kHeight, 1);
15338 ASSERT_GL_NO_ERROR();
15339
15340 // Copy level 0, layer 1 to level 0, layer 3
15341 glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15342 3, kWidth, kHeight, 1);
15343 ASSERT_GL_NO_ERROR();
15344
15345 // Copy level 0, layer 0 to level 0, layer 1
15346 // Level 0/layer 1 will be written to from after being read from
15347 glCopyImageSubDataEXT(tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, tex, GL_TEXTURE_2D_ARRAY, 0, 0, 0,
15348 1, kWidth, kHeight, 1);
15349 ASSERT_GL_NO_ERROR();
15350
15351 // Verify colors
15352 GLFramebuffer FBO;
15353 glBindFramebuffer(GL_FRAMEBUFFER, FBO);
15354 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
15355 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15356
15357 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
15358 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15359
15360 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
15361 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15362
15363 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 3);
15364 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15365
15366 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 4);
15367 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15368
15369 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 0);
15370 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15371
15372 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 1);
15373 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15374
15375 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 2);
15376 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::red);
15377
15378 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 3);
15379 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::green);
15380
15381 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 4);
15382 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15383 ASSERT_GL_NO_ERROR();
15384 }
15385
15386 // Verify that copies between 3D texture slices work
TEST_P(CopyImageTestES31,Texture3DSelfCopyImageSubData)15387 TEST_P(CopyImageTestES31, Texture3DSelfCopyImageSubData)
15388 {
15389 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15390
15391 // Set up a texture with multiple layers, then verify we can copy between them
15392 constexpr uint32_t kWidth = 23;
15393 constexpr uint32_t kHeight = 47;
15394 constexpr uint32_t kDepth = 5;
15395 constexpr uint32_t kLevels = 2;
15396 std::vector<GLColor> pixelsRed(kWidth * kHeight, GLColor::red);
15397 std::vector<GLColor> pixelsGreen(kWidth * kHeight, GLColor::green);
15398 std::vector<GLColor> pixelsBlue(kWidth * kHeight, GLColor::blue);
15399
15400 const GLColor *colors[3] = {
15401 pixelsRed.data(),
15402 pixelsGreen.data(),
15403 pixelsBlue.data(),
15404 };
15405
15406 GLTexture tex;
15407 glBindTexture(GL_TEXTURE_3D, tex);
15408 glTexStorage3D(GL_TEXTURE_3D, kLevels, GL_RGBA8, kWidth, kHeight, kDepth);
15409 for (uint32_t level = 0; level < kLevels; ++level)
15410 {
15411 for (uint32_t depth = 0; depth < kDepth >> level; ++depth)
15412 {
15413 glTexSubImage3D(GL_TEXTURE_3D, level, 0, 0, depth, kWidth >> level, kHeight >> level, 1,
15414 GL_RGBA, GL_UNSIGNED_BYTE, colors[(level + depth) % 3]);
15415 }
15416 }
15417 ASSERT_GL_NO_ERROR();
15418
15419 // The texture has the following colors:
15420 // Slice 0 Slice 1 Slice 2 Slice 3 Slice 4
15421 // Level 0 Red Green Blue Red Green
15422 // Level 1 Green Blue
15423
15424 // Copy level 1, slice 1 to level 1, slice 0
15425 glCopyImageSubDataEXT(tex, GL_TEXTURE_3D, 1, 0, 0, 1, tex, GL_TEXTURE_3D, 1, 0, 0, 0,
15426 kWidth >> 1, kHeight >> 1, 1);
15427 ASSERT_GL_NO_ERROR();
15428
15429 // Copy level 0, slice 3, 4 to level 0, slice 1, 2
15430 glCopyImageSubDataEXT(tex, GL_TEXTURE_3D, 0, 0, 0, 3, tex, GL_TEXTURE_3D, 0, 0, 0, 1, kWidth,
15431 kHeight, 2);
15432 ASSERT_GL_NO_ERROR();
15433
15434 // Partially copy level 1, slice 1 to level 0, slice 3
15435 glCopyImageSubDataEXT(tex, GL_TEXTURE_3D, 1, kWidth / 8, kHeight / 8, 1, tex, GL_TEXTURE_3D, 0,
15436 kWidth / 4, kHeight / 4, 3, kWidth / 4, kHeight / 4, 1);
15437 ASSERT_GL_NO_ERROR();
15438
15439 // Verify colors
15440 GLFramebuffer FBO;
15441 glBindFramebuffer(GL_FRAMEBUFFER, FBO);
15442 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
15443 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15444
15445 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
15446 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15447
15448 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
15449 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15450
15451 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 3);
15452 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight / 4, GLColor::red);
15453 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 4, kHeight, GLColor::red);
15454 EXPECT_PIXEL_RECT_EQ(0, kHeight / 4 + kHeight / 4, kWidth,
15455 kHeight - (kHeight / 4 + kHeight / 4), GLColor::red);
15456 EXPECT_PIXEL_RECT_EQ(kWidth / 4 + kWidth / 4, 0, kWidth - (kWidth / 4 + kWidth / 4), kHeight,
15457 GLColor::red);
15458 EXPECT_PIXEL_RECT_EQ(kWidth / 4, kHeight / 4, kWidth / 4, kHeight / 4, GLColor::blue);
15459
15460 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 4);
15461 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
15462
15463 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 0);
15464 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15465
15466 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 1, 1);
15467 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth >> 1, kHeight >> 1, GLColor::blue);
15468 ASSERT_GL_NO_ERROR();
15469 }
15470
15471 // Verify that copying between multisample renderbuffer work
TEST_P(CopyImageTestES31,MultisampleRenderbufferCopyImageSubData)15472 TEST_P(CopyImageTestES31, MultisampleRenderbufferCopyImageSubData)
15473 {
15474 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
15475
15476 constexpr uint32_t kWidth = 16;
15477 constexpr uint32_t kHeight = 16;
15478
15479 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
15480
15481 GLint maxSample = 0;
15482 glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &maxSample);
15483 ASSERT_GL_NO_ERROR();
15484
15485 GLFramebuffer fboRenderbuffer;
15486 GLRenderbuffer srcRenderbuffer;
15487 glBindFramebuffer(GL_FRAMEBUFFER, fboRenderbuffer);
15488 glBindRenderbuffer(GL_RENDERBUFFER, srcRenderbuffer);
15489 glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSample, GL_RGBA8, kWidth, kHeight);
15490 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
15491 srcRenderbuffer);
15492 ASSERT_GL_NO_ERROR();
15493 glCheckFramebufferStatus(GL_FRAMEBUFFER);
15494 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
15495
15496 /* Draw red into the source renderbuffer */
15497 glViewport(0, 0, kWidth, kHeight);
15498 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
15499
15500 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
15501 ASSERT_GL_NO_ERROR();
15502
15503 /* Copy source renderbuffer to destination renderbuffer*/
15504 GLRenderbuffer dstRenderbuffer;
15505 glBindRenderbuffer(GL_RENDERBUFFER, dstRenderbuffer);
15506 glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSample, GL_RGBA8, kWidth, kHeight);
15507 glCopyImageSubDataEXT(srcRenderbuffer, GL_RENDERBUFFER, 0, 0, 0, 0, dstRenderbuffer,
15508 GL_RENDERBUFFER, 0, 0, 0, 0, kWidth, kHeight, 1);
15509 ASSERT_GL_NO_ERROR();
15510
15511 /* Resolve the dstRenderbuffer */
15512 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
15513 glBindFramebuffer(GL_READ_FRAMEBUFFER, fboRenderbuffer);
15514 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
15515 dstRenderbuffer);
15516 ASSERT_GL_NO_ERROR();
15517 glCheckFramebufferStatus(GL_FRAMEBUFFER);
15518 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
15519
15520 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
15521 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
15522 ASSERT_GL_NO_ERROR();
15523
15524 glBindFramebuffer(GL_FRAMEBUFFER, 0);
15525 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
15526 }
15527
15528 class TextureChangeStorageUploadTest : public ANGLETest<>
15529 {
15530 protected:
TextureChangeStorageUploadTest()15531 TextureChangeStorageUploadTest()
15532 {
15533 setWindowWidth(256);
15534 setWindowHeight(256);
15535 setConfigRedBits(8);
15536 setConfigGreenBits(8);
15537 setConfigBlueBits(8);
15538 setConfigAlphaBits(8);
15539 }
15540
testSetUp()15541 void testSetUp() override
15542 {
15543 mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
15544 if (mProgram == 0)
15545 {
15546 FAIL() << "shader compilation failed.";
15547 }
15548
15549 glUseProgram(mProgram);
15550
15551 glClearColor(0, 0, 0, 0);
15552 glClearDepthf(0.0);
15553 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
15554
15555 glEnable(GL_BLEND);
15556 glDisable(GL_DEPTH_TEST);
15557
15558 glGenTextures(1, &mTexture);
15559 ASSERT_GL_NO_ERROR();
15560 }
15561
testTearDown()15562 void testTearDown() override
15563 {
15564 glDeleteTextures(1, &mTexture);
15565 glDeleteProgram(mProgram);
15566 }
15567
15568 GLuint mProgram;
15569 GLint mColorLocation;
15570 GLuint mTexture;
15571 };
15572
15573 // Verify that respecifying storage and re-uploading doesn't crash.
TEST_P(TextureChangeStorageUploadTest,Basic)15574 TEST_P(TextureChangeStorageUploadTest, Basic)
15575 {
15576 constexpr int kImageSize = 8; // 4 doesn't trip ASAN
15577 constexpr int kSmallerImageSize = kImageSize / 2;
15578 EXPECT_GT(kImageSize, kSmallerImageSize);
15579 EXPECT_GT(kSmallerImageSize / 2, 0);
15580
15581 std::array<GLColor, kImageSize * kImageSize> kColor;
15582
15583 glBindTexture(GL_TEXTURE_2D, mTexture);
15584 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
15585 kColor.data());
15586 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSmallerImageSize, kSmallerImageSize);
15587 // need partial update to sidestep optimizations that remove the full upload
15588 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSmallerImageSize / 2, kSmallerImageSize / 2, GL_RGBA,
15589 GL_UNSIGNED_BYTE, kColor.data());
15590 EXPECT_GL_NO_ERROR();
15591 }
15592
15593 class ExtraSamplerCubeShadowUseTest : public ANGLETest<>
15594 {
15595 protected:
ExtraSamplerCubeShadowUseTest()15596 ExtraSamplerCubeShadowUseTest() : ANGLETest() {}
15597
getVertexShaderSource()15598 const char *getVertexShaderSource() { return "#version 300 es\nvoid main() {}"; }
15599
getFragmentShaderSource()15600 const char *getFragmentShaderSource()
15601 {
15602 return R"(#version 300 es
15603 precision mediump float;
15604
15605 uniform mediump samplerCube var_0002; // this has to be there
15606 uniform highp samplerCubeShadow var_0004; // this has to be a cube shadow sampler
15607 out vec4 color;
15608 void main() {
15609
15610 vec4 var_0031 = texture(var_0002, vec3(1,1,1));
15611 ivec2 size = textureSize(var_0004, 0) ;
15612 var_0031.x += float(size.y);
15613
15614 color = var_0031;
15615 })";
15616 }
15617
testSetUp()15618 void testSetUp() override
15619 {
15620 mProgram = CompileProgram(getVertexShaderSource(), getFragmentShaderSource());
15621 if (mProgram == 0)
15622 {
15623 FAIL() << "shader compilation failed.";
15624 }
15625 glUseProgram(mProgram);
15626 ASSERT_GL_NO_ERROR();
15627 }
15628
testTearDown()15629 void testTearDown() override { glDeleteProgram(mProgram); }
15630
15631 GLuint mProgram;
15632 };
15633
TEST_P(ExtraSamplerCubeShadowUseTest,Basic)15634 TEST_P(ExtraSamplerCubeShadowUseTest, Basic)
15635 {
15636 glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
15637 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
15638 }
15639
15640 // Tests covering RBG->RGBA emulation path
15641 class RGBTextureBufferTestES31 : public ANGLETest<>
15642 {
15643 protected:
RGBTextureBufferTestES31()15644 RGBTextureBufferTestES31()
15645 {
15646 setWindowWidth(128);
15647 setWindowHeight(128);
15648 setConfigRedBits(8);
15649 setConfigGreenBits(8);
15650 setConfigBlueBits(8);
15651 setConfigAlphaBits(8);
15652 }
15653 void TestInt(GLuint format);
15654 };
15655
SetupTextureBufferDrawProgram(GLProgram & program,GLuint format)15656 void SetupTextureBufferDrawProgram(GLProgram &program, GLuint format)
15657 {
15658 constexpr char kVS[] = R"(#version 310 es
15659 precision highp float;
15660 in vec4 inputAttribute;
15661
15662 void main()
15663 {
15664 gl_Position = inputAttribute;
15665 })";
15666
15667 if (format == GL_RGB32UI)
15668 {
15669 constexpr char kFS[] = R"(#version 310 es
15670 #extension GL_EXT_texture_buffer : require
15671 precision mediump float;
15672 uniform highp usamplerBuffer tex;
15673 layout(location = 0) out mediump vec4 color;
15674
15675 void main()
15676 {
15677 uvec4 v = texelFetch(tex, 1);
15678 color = vec4(float(v.r)/255.0, float(v.g)/255.0, float(v.b)/255.0, v.a);
15679 })";
15680 program.makeRaster(kVS, kFS);
15681 }
15682 if (format == GL_RGB32I)
15683 {
15684 constexpr char kFS[] = R"(#version 310 es
15685 #extension GL_EXT_texture_buffer : require
15686 precision mediump float;
15687 uniform highp isamplerBuffer tex;
15688 layout(location = 0) out mediump vec4 color;
15689
15690 void main()
15691 {
15692 ivec4 v = texelFetch(tex, 1);
15693 color = vec4(float(v.r)/255.0, float(v.g)/255.0, float(v.b)/255.0, v.a);
15694 })";
15695 program.makeRaster(kVS, kFS);
15696 }
15697 if (format == GL_RGB32F)
15698 {
15699 constexpr char kFS[] = R"(#version 310 es
15700 #extension GL_EXT_texture_buffer : require
15701 precision mediump float;
15702 uniform highp samplerBuffer tex;
15703 layout(location = 0) out mediump vec4 color;
15704
15705 void main()
15706 {
15707 vec4 v = texelFetch(tex, 1);
15708 color = vec4(float(v.r)/255.0, float(v.g)/255.0, float(v.b)/255.0, v.a);
15709 })";
15710 program.makeRaster(kVS, kFS);
15711 }
15712 ASSERT_TRUE(program.valid());
15713 }
15714
TestInt(GLuint format)15715 void RGBTextureBufferTestES31::TestInt(GLuint format)
15716 {
15717 const GLint pixelSize = sizeof(GLuint) * 3;
15718
15719 // Offset must be aligned to GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT (16, 64, ...)
15720 GLint offsetAlignment = 0;
15721 glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment);
15722 ASSERT(offsetAlignment % sizeof(GLuint) == 0);
15723 GLint byteOffset = ((pixelSize * 2) / offsetAlignment + 1) * offsetAlignment;
15724
15725 GLint intOffset = byteOffset / sizeof(GLuint);
15726
15727 std::vector<GLuint> texData(intOffset + 3 * 2);
15728
15729 // first texel(1) col
15730 GLColor col = MakeGLColor(11, 22, 33, 255);
15731 texData[3] = col.R;
15732 texData[4] = col.G;
15733 texData[5] = col.B;
15734
15735 // second texel(1) col2
15736 GLColor col2 = MakeGLColor(44, 55, 66, 255);
15737 texData[intOffset + 3] = col2.R;
15738 texData[intOffset + 4] = col2.G;
15739 texData[intOffset + 5] = col2.B;
15740
15741 GLTexture texture;
15742 glBindTexture(GL_TEXTURE_BUFFER, texture);
15743
15744 GLBuffer buffer;
15745 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
15746 glBufferData(GL_TEXTURE_BUFFER, sizeof(GLuint) * texData.size(), texData.data(),
15747 GL_STATIC_DRAW);
15748 ASSERT_GL_NO_ERROR();
15749
15750 GLProgram program;
15751 SetupTextureBufferDrawProgram(program, format);
15752
15753 glTexBufferEXT(GL_TEXTURE_BUFFER, format, buffer);
15754
15755 drawQuad(program, "inputAttribute", 0.5f);
15756 ASSERT_GL_NO_ERROR();
15757 EXPECT_PIXEL_COLOR_NEAR(0, 0, col, 1);
15758
15759 glTexBufferRangeEXT(GL_TEXTURE_BUFFER, format, buffer, byteOffset, pixelSize * 2);
15760 ASSERT_GL_NO_ERROR();
15761 drawQuad(program, "inputAttribute", 0.5f);
15762 EXPECT_PIXEL_COLOR_NEAR(0, 0, col2, 1);
15763
15764 // Now update the buffer to check the converted data also gets updated.
15765 GLColor colUpd = MakeGLColor(77, 88, 99, 255);
15766 GLuint texDataUpd[] = {0, 0, 0, colUpd.R, colUpd.G, colUpd.B}; // second texel(1) colUpd
15767 glBufferSubData(GL_TEXTURE_BUFFER, byteOffset, sizeof(texDataUpd), texDataUpd);
15768 ASSERT_GL_NO_ERROR();
15769 drawQuad(program, "inputAttribute", 0.5f);
15770 EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd, 1);
15771
15772 // Update with glMapBuffer (hits a different code path...)
15773 GLColor colUpd2 = MakeGLColor(111, 122, 133, 255);
15774 GLuint texDataUpd2[] = {0, 0, 0, colUpd2.R, colUpd2.G, colUpd2.B}; // second texel(1) colUpd2
15775 void *mappedBuffer =
15776 glMapBufferRange(GL_TEXTURE_BUFFER, byteOffset, sizeof(texDataUpd2), GL_MAP_WRITE_BIT);
15777 memcpy(mappedBuffer, texDataUpd2, sizeof(texDataUpd2));
15778 glUnmapBuffer(GL_TEXTURE_BUFFER);
15779 ASSERT_GL_NO_ERROR();
15780 drawQuad(program, "inputAttribute", 0.5f);
15781 EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd2, 1);
15782 }
15783
15784 // Tests GL_RGB32UI texture buffer
TEST_P(RGBTextureBufferTestES31,Uint)15785 TEST_P(RGBTextureBufferTestES31, Uint)
15786 {
15787 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15788
15789 TestInt(GL_RGB32UI);
15790 }
15791
15792 // Tests GL_RGB32I texture buffer
TEST_P(RGBTextureBufferTestES31,Sint)15793 TEST_P(RGBTextureBufferTestES31, Sint)
15794 {
15795 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15796
15797 TestInt(GL_RGB32I);
15798 }
15799
15800 // Tests GL_RGB32F texture buffer
TEST_P(RGBTextureBufferTestES31,Float)15801 TEST_P(RGBTextureBufferTestES31, Float)
15802 {
15803 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
15804
15805 // first texel(1) col
15806 GLColor col = MakeGLColor(11, 22, 33, 255);
15807 GLfloat texData[6]{};
15808 texData[3] = col.R;
15809 texData[4] = col.G;
15810 texData[5] = col.B;
15811
15812 GLTexture texture;
15813 glBindTexture(GL_TEXTURE_BUFFER, texture);
15814
15815 GLBuffer buffer;
15816 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
15817 glBufferData(GL_TEXTURE_BUFFER, sizeof(texData), texData, GL_STATIC_DRAW);
15818 ASSERT_GL_NO_ERROR();
15819
15820 GLProgram program;
15821 SetupTextureBufferDrawProgram(program, GL_RGB32F);
15822
15823 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGB32F, buffer);
15824
15825 drawQuad(program, "inputAttribute", 0.5f);
15826 ASSERT_GL_NO_ERROR();
15827 EXPECT_PIXEL_COLOR_NEAR(0, 0, col, 1);
15828
15829 // Now update the buffer to check the converted data also gets updated.
15830 GLColor colUpd = MakeGLColor(77, 88, 99, 255);
15831 GLfloat texDataUpd[6]{};
15832 texDataUpd[3] = colUpd.R;
15833 texDataUpd[4] = colUpd.G;
15834 texDataUpd[5] = colUpd.B;
15835 glBufferSubData(GL_TEXTURE_BUFFER, 0, sizeof(texDataUpd), texDataUpd);
15836 ASSERT_GL_NO_ERROR();
15837 drawQuad(program, "inputAttribute", 0.5f);
15838 EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd, 1);
15839
15840 // Update with glMapBuffer (hits a different code path...)
15841 GLColor colUpd2 = MakeGLColor(111, 122, 133, 255);
15842 GLfloat texDataUpd2[6]{};
15843 texDataUpd2[3] = colUpd2.R;
15844 texDataUpd2[4] = colUpd2.G;
15845 texDataUpd2[5] = colUpd2.B;
15846 void *mappedBuffer =
15847 glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(texDataUpd2), GL_MAP_WRITE_BIT);
15848 memcpy(mappedBuffer, texDataUpd2, sizeof(texDataUpd2));
15849 glUnmapBuffer(GL_TEXTURE_BUFFER);
15850 ASSERT_GL_NO_ERROR();
15851 drawQuad(program, "inputAttribute", 0.5f);
15852 EXPECT_PIXEL_COLOR_NEAR(0, 0, colUpd2, 1);
15853 }
15854
SetupSSBOProgram(GLProgram & program)15855 void SetupSSBOProgram(GLProgram &program)
15856 {
15857 constexpr char kVS[] = R"(#version 310 es
15858 precision highp float;
15859 in vec4 inputAttribute;
15860
15861 void main()
15862 {
15863 gl_Position = inputAttribute;
15864 })";
15865
15866 constexpr char kFS[] = R"(#version 310 es
15867 layout(location = 0) out mediump vec4 color;
15868 layout(std140, binding = 0) buffer outBlock {
15869 uvec4 data[2]; // uvec4 to avoid padding
15870 };
15871 void main (void)
15872 {
15873 data[0] = uvec4(11u, 22u, 33u, 44u);
15874 data[1] = uvec4(55u, 66u, 0u, 0u);
15875 color = vec4(0);
15876 })";
15877
15878 program.makeRaster(kVS, kFS);
15879 ASSERT_TRUE(program.valid());
15880 }
15881
15882 // Tests RGB32 texture buffer with a SSBO write
TEST_P(RGBTextureBufferTestES31,SSBOWrite)15883 TEST_P(RGBTextureBufferTestES31, SSBOWrite)
15884 {
15885 GLProgram programSSBO;
15886 SetupSSBOProgram(programSSBO);
15887
15888 GLProgram programBufferDraw;
15889 SetupTextureBufferDrawProgram(programBufferDraw, GL_RGB32UI);
15890
15891 constexpr GLint kBufferSize = 2 * 4 * sizeof(GLuint);
15892 GLBuffer buffer;
15893 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
15894 glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
15895 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kBufferSize);
15896
15897 drawQuad(programSSBO, "inputAttribute", 0.5f);
15898 ASSERT_GL_NO_ERROR();
15899
15900 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
15901
15902 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGB32UI, buffer);
15903 drawQuad(programBufferDraw, "inputAttribute", 0.5f);
15904 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(44, 55, 66, 255), 1);
15905 }
15906
15907 class TextureTestES31 : public ANGLETest<>
15908 {
15909 protected:
TextureTestES31()15910 TextureTestES31()
15911 {
15912 setWindowWidth(128);
15913 setWindowHeight(128);
15914 setConfigRedBits(8);
15915 setConfigGreenBits(8);
15916 setConfigBlueBits(8);
15917 setConfigAlphaBits(8);
15918 }
15919 };
15920
15921 // Verify that image uniforms can link in separable programs
TEST_P(TextureTestES31,LinkedImageUniforms)15922 TEST_P(TextureTestES31, LinkedImageUniforms)
15923 {
15924 ANGLE_SKIP_TEST_IF(!IsVulkan());
15925
15926 GLint maxVertexImageUniforms;
15927 glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &maxVertexImageUniforms);
15928 ANGLE_SKIP_TEST_IF(maxVertexImageUniforms == 0);
15929
15930 constexpr char kVS[] = R"(#version 310 es
15931 precision highp float;
15932 precision highp image2D;
15933 layout(binding = 0, r32f) uniform image2D img;
15934
15935 void main()
15936 {
15937 vec2 position = -imageLoad(img, ivec2(0, 0)).rr;
15938 if (gl_VertexID == 1)
15939 position = vec2(3, -1);
15940 else if (gl_VertexID == 2)
15941 position = vec2(-1, 3);
15942
15943 gl_Position = vec4(position, 0, 1);
15944 })";
15945
15946 constexpr char kFS[] = R"(#version 310 es
15947 precision highp float;
15948 precision highp image2D;
15949 layout(binding = 0, r32f) uniform image2D img;
15950 layout(location = 0) out vec4 color;
15951
15952 void main()
15953 {
15954 color = imageLoad(img, ivec2(0, 0));
15955 })";
15956
15957 ANGLE_GL_PROGRAM(program, kVS, kFS);
15958
15959 GLTexture texture;
15960 GLfloat value = 1.0;
15961
15962 glBindTexture(GL_TEXTURE_2D, texture);
15963 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
15964 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, &value);
15965 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
15966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
15967
15968 glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
15969
15970 glUseProgram(program);
15971 glDrawArrays(GL_TRIANGLES, 0, 3);
15972
15973 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
15974 ASSERT_GL_NO_ERROR();
15975 }
15976
15977 // Test that layer-related parameters are ignored when binding a 2D texture
TEST_P(TextureTestES31,Texture2DLayered)15978 TEST_P(TextureTestES31, Texture2DLayered)
15979 {
15980 constexpr char kFS[] = R"(#version 310 es
15981 precision highp float;
15982 precision highp image2D;
15983 layout(binding = 0, r32f) uniform image2D img;
15984 layout(location = 0) out vec4 color;
15985
15986 void main()
15987 {
15988 color = imageLoad(img, ivec2(0, 0));
15989 })";
15990
15991 ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
15992
15993 GLTexture texture;
15994 GLfloat value = 1.0;
15995
15996 glBindTexture(GL_TEXTURE_2D, texture);
15997 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
15998 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, &value);
15999 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16000 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16001
16002 glClearColor(0.0, 1.0, 0.0, 1.0);
16003 for (const bool layered : {true, false})
16004 {
16005 for (const GLint layer : {0, 1})
16006 {
16007 glClear(GL_COLOR_BUFFER_BIT);
16008 glBindImageTexture(0, texture, 0, layered, layer, GL_READ_ONLY, GL_R32F);
16009 ASSERT_GL_NO_ERROR();
16010
16011 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16012 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red)
16013 << "Layered: " << (layered ? "true" : "false") << ", Layer: " << layer;
16014 }
16015 }
16016 }
16017
16018 // Test that rebinding the shader image level without changing the program works
TEST_P(TextureTestES31,Texture2DChangeLevel)16019 TEST_P(TextureTestES31, Texture2DChangeLevel)
16020 {
16021 constexpr char kFS[] = R"(#version 310 es
16022 precision highp float;
16023 precision highp image2D;
16024 layout(binding = 0, r32f) uniform image2D img;
16025 layout(location = 0) out vec4 color;
16026
16027 void main()
16028 {
16029 color = imageLoad(img, ivec2(0, 0));
16030 })";
16031 ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
16032
16033 // Must be active before calling drawQuad to avoid program switches
16034 glUseProgram(program);
16035
16036 GLTexture texture;
16037 const GLfloat level0[4] = {0.5, 0.5, 0.5, 0.5};
16038 const GLfloat level1[1] = {1.0};
16039
16040 glBindTexture(GL_TEXTURE_2D, texture);
16041 glTexStorage2D(GL_TEXTURE_2D, 2, GL_R32F, 2, 2);
16042 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RED, GL_FLOAT, level0);
16043 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1, GL_RED, GL_FLOAT, level1);
16044 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16045 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16046
16047 glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16048 ASSERT_GL_NO_ERROR();
16049 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16050 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16051
16052 glBindImageTexture(0, texture, 1, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16053 ASSERT_GL_NO_ERROR();
16054 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16055 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
16056 }
16057
16058 // Test that rebinding the shader image layer/level without changing the program works
TEST_P(TextureTestES31,Texture2DArrayChangeLayerLevel)16059 TEST_P(TextureTestES31, Texture2DArrayChangeLayerLevel)
16060 {
16061 constexpr char kFS[] = R"(#version 310 es
16062 precision highp float;
16063 precision highp image2D;
16064 layout(binding = 0, r32f) uniform image2D img;
16065 layout(location = 0) out vec4 color;
16066
16067 void main()
16068 {
16069 color = imageLoad(img, ivec2(0, 0));
16070 })";
16071 ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
16072
16073 // Must be active before calling drawQuad to avoid program switches
16074 glUseProgram(program);
16075
16076 GLTexture texture;
16077 const GLfloat level0layer0[4] = {0.25, 0.25, 0.25, 0.25};
16078 const GLfloat level0layer1[4] = {0.50, 0.50, 0.50, 0.50};
16079 const GLfloat level1layer0[1] = {0.75};
16080 const GLfloat level1layer1[1] = {1.00};
16081
16082 glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
16083 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 2, GL_R32F, 2, 2, 2);
16084 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 2, 2, 1, GL_RED, GL_FLOAT, level0layer0);
16085 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 2, 2, 1, GL_RED, GL_FLOAT, level0layer1);
16086 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 0, 1, 1, 1, GL_RED, GL_FLOAT, level1layer0);
16087 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 1, 1, 1, 1, GL_RED, GL_FLOAT, level1layer1);
16088 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16089 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16090
16091 // Level 0, layer 0
16092 glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16093 ASSERT_GL_NO_ERROR();
16094 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16095 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(63, 0, 0, 255), 1);
16096
16097 // Level 0, layer 1
16098 glBindImageTexture(0, texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
16099 ASSERT_GL_NO_ERROR();
16100 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16101 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16102
16103 // Level 1, layer 0
16104 glBindImageTexture(0, texture, 1, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16105 ASSERT_GL_NO_ERROR();
16106 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16107 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(191, 0, 0, 255), 1);
16108
16109 // Level 1, layer 1
16110 glBindImageTexture(0, texture, 1, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
16111 ASSERT_GL_NO_ERROR();
16112 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16113 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 0, 0, 255), 1);
16114 }
16115
16116 // Test that switching between a 2D texture and a layer of a 2D array texture works
TEST_P(TextureTestES31,Texture2DTo2DArraySwitch)16117 TEST_P(TextureTestES31, Texture2DTo2DArraySwitch)
16118 {
16119 constexpr char kFS[] = R"(#version 310 es
16120 precision highp float;
16121 precision highp image2D;
16122 layout(binding = 0, r32f) uniform image2D img;
16123 layout(location = 0) out vec4 color;
16124
16125 void main()
16126 {
16127 color = imageLoad(img, ivec2(0, 0));
16128 })";
16129 ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
16130
16131 // Must be active before calling drawQuad to avoid program switches
16132 glUseProgram(program);
16133
16134 GLTexture texture2D;
16135 GLTexture texture2DArray;
16136 const GLfloat data2D[1] = {0.50};
16137 const GLfloat data2DArray0[1] = {0.25};
16138 const GLfloat data2DArray1[1] = {0.75};
16139
16140 glBindTexture(GL_TEXTURE_2D, texture2D);
16141 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
16142 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, data2D);
16143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16145
16146 glBindTexture(GL_TEXTURE_2D_ARRAY, texture2DArray);
16147 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, 1, 1, 2);
16148 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 1, 1, 1, GL_RED, GL_FLOAT, data2DArray0);
16149 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 1, 1, 1, GL_RED, GL_FLOAT, data2DArray1);
16150 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16151 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
16152
16153 // Texture2D
16154 glBindImageTexture(0, texture2D, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16155 ASSERT_GL_NO_ERROR();
16156 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16157 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16158
16159 // Texture2D array, layer 0
16160 glBindImageTexture(0, texture2DArray, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16161 ASSERT_GL_NO_ERROR();
16162 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16163 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(63, 0, 0, 255), 1);
16164
16165 // Texture2D again
16166 glBindImageTexture(0, texture2D, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
16167 ASSERT_GL_NO_ERROR();
16168 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16169 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 0, 0, 255), 1);
16170
16171 // Texture2D array, layer 1
16172 glBindImageTexture(0, texture2DArray, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
16173 ASSERT_GL_NO_ERROR();
16174 drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
16175 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(191, 0, 0, 255), 1);
16176 }
16177
16178 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
16179 // tests should be run against.
16180 #define ES2_EMULATE_COPY_TEX_IMAGE_VIA_SUB() \
16181 ES2_OPENGL().enable(Feature::EmulateCopyTexImage2D), \
16182 ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2D)
16183 #define ES3_EMULATE_COPY_TEX_IMAGE_VIA_SUB() \
16184 ES3_OPENGL().enable(Feature::EmulateCopyTexImage2D), \
16185 ES3_OPENGLES().enable(Feature::EmulateCopyTexImage2D)
16186 #define ES2_EMULATE_COPY_TEX_IMAGE() \
16187 ES2_OPENGL().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers), \
16188 ES2_OPENGLES().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers)
16189 #define ES3_EMULATE_COPY_TEX_IMAGE() \
16190 ES3_OPENGL().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers), \
16191 ES3_OPENGLES().enable(Feature::EmulateCopyTexImage2DFromRenderbuffers)
16192 ANGLE_INSTANTIATE_TEST(Texture2DTest,
16193 ANGLE_ALL_TEST_PLATFORMS_ES2,
16194 ES2_EMULATE_COPY_TEX_IMAGE_VIA_SUB(),
16195 ES2_EMULATE_COPY_TEX_IMAGE(),
16196 ES2_WEBGPU());
16197 ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
16198 ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
16199 ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
16200 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
16201 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
16202
16203 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3);
16204 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DTestES3,
16205 ES3_VULKAN().enable(Feature::AllocateNonZeroMemory),
16206 ES3_VULKAN().enable(Feature::ForceFallbackFormat));
16207
16208 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DMemoryTestES3);
16209 ANGLE_INSTANTIATE_TEST_ES3(Texture2DMemoryTestES3);
16210
16211 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3YUV);
16212 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DTestES3YUV,
16213 ES3_VULKAN().enable(Feature::PreferLinearFilterForYUV),
16214 ES3_VULKAN().enable(Feature::DisableProgramCaching));
16215
16216 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3RobustInit);
16217 ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3RobustInit);
16218
16219 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3Foveation);
16220 ANGLE_INSTANTIATE_TEST_ES3_AND(
16221 Texture2DTestES3Foveation,
16222 ES3_VULKAN().enable(Feature::GenerateFragmentShadingRateAttchementWithCpu));
16223
16224 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES31Foveation);
16225 ANGLE_INSTANTIATE_TEST_ES31_AND(
16226 Texture2DTestES31Foveation,
16227 ES31_VULKAN().enable(Feature::GenerateFragmentShadingRateAttchementWithCpu));
16228
16229 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES31PPO);
16230 ANGLE_INSTANTIATE_TEST_ES31(Texture2DTestES31PPO);
16231
16232 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DBaseMaxTestES3);
16233 ANGLE_INSTANTIATE_TEST_ES3(Texture2DBaseMaxTestES3);
16234
16235 ANGLE_INSTANTIATE_TEST_ES2(Texture3DTestES2);
16236
16237 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DTestES3);
16238 ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
16239
16240 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerAlpha1TestES3);
16241 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
16242
16243 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DUnsignedIntegerAlpha1TestES3);
16244 ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
16245
16246 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShadowSamplerPlusSampler3DTestES3);
16247 ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
16248
16249 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplerTypeMixTestES3);
16250 ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
16251
16252 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayTestES3);
16253 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
16254
16255 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureSizeTextureArrayTest);
16256 ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
16257
16258 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
16259 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
16260 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
16261 ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
16262 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
16263 ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
16264 ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
16265
16266 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBorderClampTestES3);
16267 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
16268
16269 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBorderClampIntegerTestES3);
16270 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
16271
16272 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(TextureMirrorClampToEdgeTest);
16273
16274 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureMirrorClampToEdgeTestES3);
16275 ANGLE_INSTANTIATE_TEST_ES3(TextureMirrorClampToEdgeTestES3);
16276
16277 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureMirrorClampToEdgeIntegerTestES3);
16278 ANGLE_INSTANTIATE_TEST_ES3(TextureMirrorClampToEdgeIntegerTestES3);
16279
16280 ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
16281
16282 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DNorm16TestES3);
16283 ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
16284
16285 ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
16286 ANGLE_ALL_TEST_PLATFORMS_ES2,
16287 ANGLE_ALL_TEST_PLATFORMS_ES3,
16288 ES2_EMULATE_COPY_TEX_IMAGE_VIA_SUB(),
16289 ES3_EMULATE_COPY_TEX_IMAGE_VIA_SUB(),
16290 ES2_EMULATE_COPY_TEX_IMAGE(),
16291 ES3_EMULATE_COPY_TEX_IMAGE());
16292
16293 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DFloatTestES3);
16294 ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
16295
16296 ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
16297
16298 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeTestES3);
16299 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
16300
16301 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeTestES32);
16302 ANGLE_INSTANTIATE_TEST_ES32(TextureCubeTestES32);
16303
16304 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerTestES3);
16305 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
16306
16307 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeIntegerTestES3);
16308 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
16309
16310 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeIntegerEdgeTestES3);
16311 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
16312
16313 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerProjectiveOffsetTestES3);
16314 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
16315
16316 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayIntegerTestES3);
16317 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
16318
16319 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DIntegerTestES3);
16320 ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
16321
16322 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
16323 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
16324 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
16325 ANGLE_INSTANTIATE_TEST_ES3(PBOCompressedTexture3DTest);
16326
16327 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES31);
16328 ANGLE_INSTANTIATE_TEST_ES31(TextureBufferTestES31);
16329
16330 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES32);
16331 ANGLE_INSTANTIATE_TEST_ES32(TextureBufferTestES32);
16332
16333 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureTestES31);
16334 ANGLE_INSTANTIATE_TEST_ES31(TextureTestES31);
16335
16336 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyImageTestES31);
16337 ANGLE_INSTANTIATE_TEST_ES31(CopyImageTestES31);
16338
16339 ANGLE_INSTANTIATE_TEST_ES3(TextureChangeStorageUploadTest);
16340
16341 ANGLE_INSTANTIATE_TEST_ES3(ExtraSamplerCubeShadowUseTest);
16342
16343 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DDepthStencilTestES3);
16344 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DDepthStencilTestES3,
16345 ES3_VULKAN().enable(Feature::ForceFallbackFormat));
16346
16347 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RGBTextureBufferTestES31);
16348 ANGLE_INSTANTIATE_TEST_ES31(RGBTextureBufferTestES31);
16349
16350 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultisampleTexture2DTestES31);
16351 ANGLE_INSTANTIATE_TEST_ES31(MultisampleTexture2DTestES31);
16352
16353 } // anonymous namespace
16354