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 using namespace angle;
12
13 namespace
14 {
15
16 constexpr GLuint kPixelTolerance = 1u;
17 constexpr GLfloat kPixelTolerance32F = 0.01f;
18
19 // Single compressed ETC2 block of source pixels all set red
20 constexpr uint8_t kCompressedImageETC2[] = {0x7E, 0x80, 0x04, 0x7F, 0x00, 0x07, 0xE0, 0x00};
21
22 // Take a pixel, and reset the components not covered by the format to default
23 // values. In particular, the default value for the alpha component is 255
24 // (1.0 as unsigned normalized fixed point value).
25 // For legacy formats, the components may be reordered to match the color that
26 // would be created if a pixel of that format was initialized from the given color
SliceFormatColor(GLenum format,GLColor full)27 GLColor SliceFormatColor(GLenum format, GLColor full)
28 {
29 switch (format)
30 {
31 case GL_RED:
32 return GLColor(full.R, 0, 0, 255u);
33 case GL_RG:
34 return GLColor(full.R, full.G, 0, 255u);
35 case GL_RGB:
36 return GLColor(full.R, full.G, full.B, 255u);
37 case GL_RGBA:
38 return full;
39 case GL_LUMINANCE:
40 return GLColor(full.R, full.R, full.R, 255u);
41 case GL_ALPHA:
42 return GLColor(0, 0, 0, full.R);
43 case GL_LUMINANCE_ALPHA:
44 return GLColor(full.R, full.R, full.R, full.G);
45 default:
46 EXPECT_TRUE(false);
47 return GLColor::white;
48 }
49 }
50
SliceFormatColor16UI(GLenum format,GLColor16UI full)51 GLColor16UI SliceFormatColor16UI(GLenum format, GLColor16UI full)
52 {
53 switch (format)
54 {
55 case GL_RED:
56 return GLColor16UI(full.R, 0, 0, 0xFFFF);
57 case GL_RG:
58 return GLColor16UI(full.R, full.G, 0, 0xFFFF);
59 case GL_RGB:
60 return GLColor16UI(full.R, full.G, full.B, 0xFFFF);
61 case GL_RGBA:
62 return full;
63 case GL_LUMINANCE:
64 return GLColor16UI(full.R, full.R, full.R, 0xFFFF);
65 case GL_ALPHA:
66 return GLColor16UI(0, 0, 0, full.R);
67 case GL_LUMINANCE_ALPHA:
68 return GLColor16UI(full.R, full.R, full.R, full.G);
69 default:
70 EXPECT_TRUE(false);
71 return GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
72 }
73 }
74
75 // As above, for 32F colors
SliceFormatColor32F(GLenum format,GLColor32F full)76 GLColor32F SliceFormatColor32F(GLenum format, GLColor32F full)
77 {
78 switch (format)
79 {
80 case GL_RED:
81 return GLColor32F(full.R, 0.0f, 0.0f, 1.0f);
82 case GL_RG:
83 return GLColor32F(full.R, full.G, 0.0f, 1.0f);
84 case GL_RGB:
85 return GLColor32F(full.R, full.G, full.B, 1.0f);
86 case GL_RGBA:
87 return full;
88 case GL_LUMINANCE:
89 return GLColor32F(full.R, full.R, full.R, 1.0f);
90 case GL_ALPHA:
91 return GLColor32F(0.0f, 0.0f, 0.0f, full.R);
92 case GL_LUMINANCE_ALPHA:
93 return GLColor32F(full.R, full.R, full.R, full.G);
94 default:
95 EXPECT_TRUE(false);
96 return GLColor32F(1.0f, 1.0f, 1.0f, 1.0f);
97 }
98 }
99
100 class TexCoordDrawTest : public ANGLETest
101 {
102 protected:
TexCoordDrawTest()103 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
104 {
105 setWindowWidth(128);
106 setWindowHeight(128);
107 setConfigRedBits(8);
108 setConfigGreenBits(8);
109 setConfigBlueBits(8);
110 setConfigAlphaBits(8);
111 }
112
getVertexShaderSource()113 virtual const char *getVertexShaderSource()
114 {
115 return R"(precision highp float;
116 attribute vec4 position;
117 varying vec2 texcoord;
118
119 void main()
120 {
121 gl_Position = vec4(position.xy, 0.0, 1.0);
122 texcoord = (position.xy * 0.5) + 0.5;
123 })";
124 }
125
126 virtual const char *getFragmentShaderSource() = 0;
127
setUpProgram()128 virtual void setUpProgram()
129 {
130 const char *vertexShaderSource = getVertexShaderSource();
131 const char *fragmentShaderSource = getFragmentShaderSource();
132
133 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
134 ASSERT_NE(0u, mProgram);
135 ASSERT_GL_NO_ERROR();
136 }
137
testSetUp()138 void testSetUp() override { setUpFramebuffer(); }
139
testTearDown()140 void testTearDown() override
141 {
142 glBindFramebuffer(GL_FRAMEBUFFER, 0);
143 glDeleteFramebuffers(1, &mFramebuffer);
144 glDeleteTextures(1, &mFramebufferColorTexture);
145 glDeleteProgram(mProgram);
146 }
147
setUpFramebuffer()148 void setUpFramebuffer()
149 {
150 // We use an FBO to work around an issue where the default framebuffer applies SRGB
151 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
152 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
153 // section 4.4 says that the format of the default framebuffer is entirely up to the window
154 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
155 // SRGB conversion like desktop GL does.
156 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
157 glGenFramebuffers(1, &mFramebuffer);
158 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
159
160 glGenTextures(1, &mFramebufferColorTexture);
161 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
162 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
163 GL_UNSIGNED_BYTE, nullptr);
164 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
165 mFramebufferColorTexture, 0);
166 ASSERT_GL_NO_ERROR();
167 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
168 glBindTexture(GL_TEXTURE_2D, 0);
169 }
170
171 // Returns the created texture ID.
create2DTexture()172 GLuint create2DTexture()
173 {
174 GLuint texture2D;
175 glGenTextures(1, &texture2D);
176 glBindTexture(GL_TEXTURE_2D, texture2D);
177 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
178 EXPECT_GL_NO_ERROR();
179 return texture2D;
180 }
181
182 GLuint mProgram;
183 GLuint mFramebuffer;
184
185 private:
186 GLuint mFramebufferColorTexture;
187 };
188
189 class Texture2DTest : public TexCoordDrawTest
190 {
191 protected:
Texture2DTest()192 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
193
getFragmentShaderSource()194 const char *getFragmentShaderSource() override
195 {
196 return R"(precision highp float;
197 uniform sampler2D tex;
198 varying vec2 texcoord;
199
200 void main()
201 {
202 gl_FragColor = texture2D(tex, texcoord);
203 })";
204 }
205
getTextureUniformName()206 virtual const char *getTextureUniformName() { return "tex"; }
207
setUpProgram()208 void setUpProgram() override
209 {
210 TexCoordDrawTest::setUpProgram();
211 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
212 ASSERT_NE(-1, mTexture2DUniformLocation);
213 }
214
testSetUp()215 void testSetUp() override
216 {
217 TexCoordDrawTest::testSetUp();
218 mTexture2D = create2DTexture();
219
220 ASSERT_GL_NO_ERROR();
221 }
222
testTearDown()223 void testTearDown() override
224 {
225 glDeleteTextures(1, &mTexture2D);
226 TexCoordDrawTest::testTearDown();
227 }
228
229 // Tests CopyTexSubImage with floating point textures of various formats.
testFloatCopySubImage(int sourceImageChannels,int destImageChannels)230 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
231 {
232 setUpProgram();
233
234 if (getClientMajorVersion() < 3)
235 {
236 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
237 !IsGLExtensionEnabled("GL_OES_texture_float"));
238
239 ANGLE_SKIP_TEST_IF((sourceImageChannels < 3 || destImageChannels < 3) &&
240 !IsGLExtensionEnabled("GL_EXT_texture_rg"));
241
242 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
243 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
244
245 ANGLE_SKIP_TEST_IF(destImageChannels == 4 &&
246 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"));
247
248 ANGLE_SKIP_TEST_IF(destImageChannels <= 2);
249 }
250 else
251 {
252 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_color_buffer_float"));
253
254 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
255 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
256 }
257
258 // clang-format off
259 GLfloat sourceImageData[4][16] =
260 {
261 { // R
262 1.0f,
263 0.0f,
264 0.0f,
265 1.0f
266 },
267 { // RG
268 1.0f, 0.0f,
269 0.0f, 1.0f,
270 0.0f, 0.0f,
271 1.0f, 1.0f
272 },
273 { // RGB
274 1.0f, 0.0f, 0.0f,
275 0.0f, 1.0f, 0.0f,
276 0.0f, 0.0f, 1.0f,
277 1.0f, 1.0f, 0.0f
278 },
279 { // RGBA
280 1.0f, 0.0f, 0.0f, 1.0f,
281 0.0f, 1.0f, 0.0f, 1.0f,
282 0.0f, 0.0f, 1.0f, 1.0f,
283 1.0f, 1.0f, 0.0f, 1.0f
284 },
285 };
286 // clang-format on
287
288 GLenum imageFormats[] = {
289 GL_R32F,
290 GL_RG32F,
291 GL_RGB32F,
292 GL_RGBA32F,
293 };
294
295 GLenum sourceUnsizedFormats[] = {
296 GL_RED,
297 GL_RG,
298 GL_RGB,
299 GL_RGBA,
300 };
301
302 GLuint textures[2];
303
304 glGenTextures(2, textures);
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 glDeleteTextures(2, textures);
372
373 ASSERT_GL_NO_ERROR();
374 }
375
376 void testTextureSize(int testCaseIndex);
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
471 class Texture2DBaseMaxTestES3 : public ANGLETest
472 {
473 protected:
474 static constexpr size_t kMip0Size = 13;
475 static constexpr uint32_t kMipCount = 4;
476
Texture2DBaseMaxTestES3()477 Texture2DBaseMaxTestES3() : ANGLETest(), mTextureLocation(0), mLodLocation(0)
478 {
479 setWindowWidth(128);
480 setWindowHeight(128);
481 setConfigRedBits(8);
482 setConfigGreenBits(8);
483 setConfigBlueBits(8);
484 setConfigAlphaBits(8);
485 }
486
getMipDataSize(size_t mip0Size,size_t mip)487 static constexpr size_t getMipDataSize(size_t mip0Size, size_t mip)
488 {
489 size_t mipSize = std::max<size_t>(1u, mip0Size >> mip);
490 return mipSize * mipSize;
491 }
492
getTotalMipDataSize(size_t mip0Size)493 static constexpr size_t getTotalMipDataSize(size_t mip0Size)
494 {
495 size_t totalCount = 0;
496 for (size_t mip = 0; mip < kMipCount; ++mip)
497 {
498 totalCount += getMipDataSize(mip0Size, mip);
499 }
500 return totalCount;
501 }
502
getMipDataOffset(size_t mip0Size,size_t mip)503 static constexpr size_t getMipDataOffset(size_t mip0Size, size_t mip)
504 {
505 // This calculates:
506 //
507 // mip == 0: 0
508 // o.w.: sum(0, mip-1) getMipDataSize(i)
509 //
510 // The above can be calculated simply as:
511 //
512 // (mip0 >> (kMipCount-1))^2 * (0x55555555 & ((1 << (2*mip)) - 1))
513 // \__________ ___________/ \_______________ ________________/
514 // \/ \/
515 // last mip size sum(0, mip-1) (4^i)
516 //
517 // But let's loop explicitly for clarity.
518 size_t offset = 0;
519 for (size_t m = 0; m < mip; ++m)
520 {
521 offset += getMipDataSize(mip0Size, m);
522 }
523 return offset;
524 }
525
526 template <typename colorType = GLColor>
fillMipData(colorType * data,size_t mip0Size,const colorType mipColors[kMipCount])527 void fillMipData(colorType *data, size_t mip0Size, const colorType mipColors[kMipCount])
528 {
529 for (size_t mip = 0; mip < kMipCount; ++mip)
530 {
531 size_t offset = getMipDataOffset(mip0Size, mip);
532 size_t size = getMipDataSize(mip0Size, mip);
533 std::fill(data + offset, data + offset + size, mipColors[mip]);
534 }
535 }
536
initTest(bool immutable)537 void initTest(bool immutable)
538 {
539 // Set up program to sample from specific lod level.
540 mProgram.makeRaster(essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
541 ASSERT(mProgram.valid());
542
543 glUseProgram(mProgram);
544
545 mTextureLocation = glGetUniformLocation(mProgram, essl3_shaders::Texture2DUniform());
546 ASSERT_NE(-1, mTextureLocation);
547
548 mLodLocation = glGetUniformLocation(mProgram, essl3_shaders::LodUniform());
549 ASSERT_NE(-1, mLodLocation);
550
551 // Set up texture with a handful of lods.
552 glActiveTexture(GL_TEXTURE0);
553 glBindTexture(GL_TEXTURE_2D, mTexture);
554
555 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
556 fillMipData(mipData.data(), kMip0Size, kMipColors);
557
558 if (immutable)
559 {
560 glTexStorage2D(GL_TEXTURE_2D, kMipCount, GL_RGBA8, kMip0Size, kMip0Size);
561 for (size_t mip = 0; mip < kMipCount; ++mip)
562 {
563 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip,
564 GL_RGBA, GL_UNSIGNED_BYTE,
565 mipData.data() + getMipDataOffset(kMip0Size, mip));
566 }
567 }
568 else
569 {
570 for (size_t mip = 0; mip < kMipCount; ++mip)
571 {
572 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0,
573 GL_RGBA, GL_UNSIGNED_BYTE,
574 mipData.data() + getMipDataOffset(kMip0Size, mip));
575 }
576 }
577
578 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
579 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
580
581 EXPECT_GL_NO_ERROR();
582 }
583
setLodUniform(uint32_t lod)584 void setLodUniform(uint32_t lod) { glUniform1f(mLodLocation, lod); }
585
586 void testPingPongBaseLevel(bool immutable);
587 void testGenerateMipmapAfterRebase(bool immutable);
588
589 GLProgram mProgram;
590 GLTexture mTexture;
591 GLint mTextureLocation;
592 GLint mLodLocation;
593
594 const GLColor kMipColors[kMipCount] = {
595 GLColor::red,
596 GLColor::green,
597 GLColor::blue,
598 GLColor::magenta,
599 };
600 };
601
602 class TextureES31PPO
603 {
604 protected:
TextureES31PPO()605 TextureES31PPO() : mVertProg(0), mFragProg(0), mPipeline(0) {}
606
get2DTexturedVertexShaderSource()607 const char *get2DTexturedVertexShaderSource()
608 {
609 return "#version 310 es\n"
610 "precision mediump float;\n"
611 "in vec2 position;\n"
612 "out vec2 texCoord;\n"
613 "void main()\n"
614 "{\n"
615 " gl_Position = vec4(position, 0, 1);\n"
616 " texCoord = position * 0.5 + vec2(0.5);\n"
617 "}";
618 }
619
get2DTexturedFragmentShaderSource()620 const char *get2DTexturedFragmentShaderSource()
621 {
622 return "#version 310 es\n"
623 "precision mediump float;\n"
624 "in vec2 texCoord;\n"
625 "uniform sampler2D tex1;\n"
626 "uniform sampler2D tex2;\n"
627 "uniform sampler2D tex3;\n"
628 "uniform sampler2D tex4;\n"
629 "out vec4 color;\n"
630 "void main()\n"
631 "{\n"
632 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
633 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
634 "}";
635 }
636
bindProgramPipeline(const GLchar * vertString,const GLchar * fragString)637 void bindProgramPipeline(const GLchar *vertString, const GLchar *fragString)
638 {
639 mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
640 ASSERT_NE(mVertProg, 0u);
641 mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
642 ASSERT_NE(mFragProg, 0u);
643
644 // Generate a program pipeline and attach the programs to their respective stages
645 glGenProgramPipelines(1, &mPipeline);
646 EXPECT_GL_NO_ERROR();
647 glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
648 EXPECT_GL_NO_ERROR();
649 glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
650 EXPECT_GL_NO_ERROR();
651 glBindProgramPipeline(mPipeline);
652 EXPECT_GL_NO_ERROR();
653 }
654
bind2DTexturedQuadProgramPipeline()655 void bind2DTexturedQuadProgramPipeline()
656 {
657 const char *vertexShaderSource = get2DTexturedVertexShaderSource();
658 const char *fragmentShaderSource = get2DTexturedFragmentShaderSource();
659
660 m2DTexturedQuadVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertexShaderSource);
661 ASSERT_NE(m2DTexturedQuadVertProg, 0u);
662 m2DTexturedQuadFragProg =
663 glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentShaderSource);
664 ASSERT_NE(m2DTexturedQuadFragProg, 0u);
665
666 // Generate a program pipeline and attach the programs to their respective stages
667 glGenProgramPipelines(1, &m2DTexturedQuadPipeline);
668 EXPECT_GL_NO_ERROR();
669 glUseProgramStages(m2DTexturedQuadPipeline, GL_VERTEX_SHADER_BIT, m2DTexturedQuadVertProg);
670 EXPECT_GL_NO_ERROR();
671 glUseProgramStages(m2DTexturedQuadPipeline, GL_FRAGMENT_SHADER_BIT,
672 m2DTexturedQuadFragProg);
673 EXPECT_GL_NO_ERROR();
674 glBindProgramPipeline(m2DTexturedQuadPipeline);
675 EXPECT_GL_NO_ERROR();
676 }
677
ppoDrawQuad(std::array<Vector3,6> & quadVertices,const std::string & positionAttribName,const GLfloat positionAttribZ,const GLfloat positionAttribXYScale)678 void ppoDrawQuad(std::array<Vector3, 6> &quadVertices,
679 const std::string &positionAttribName,
680 const GLfloat positionAttribZ,
681 const GLfloat positionAttribXYScale)
682 {
683 glUseProgram(0);
684
685 for (Vector3 &vertex : quadVertices)
686 {
687 vertex.x() *= positionAttribXYScale;
688 vertex.y() *= positionAttribXYScale;
689 vertex.z() = positionAttribZ;
690 }
691
692 GLint positionLocation = glGetAttribLocation(mVertProg, positionAttribName.c_str());
693
694 glBindBuffer(GL_ARRAY_BUFFER, 0);
695 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
696 glEnableVertexAttribArray(positionLocation);
697
698 glDrawArrays(GL_TRIANGLES, 0, 6);
699
700 glDisableVertexAttribArray(positionLocation);
701 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
702 }
703
704 GLuint mVertProg;
705 GLuint mFragProg;
706 GLuint mPipeline;
707 GLuint m2DTexturedQuadVertProg;
708 GLuint m2DTexturedQuadFragProg;
709 GLuint m2DTexturedQuadPipeline;
710 };
711
712 class Texture2DTestES31PPO : public TextureES31PPO, public Texture2DTest
713 {
714 protected:
Texture2DTestES31PPO()715 Texture2DTestES31PPO() : TextureES31PPO(), Texture2DTest() {}
716
testSetUp()717 void testSetUp() override { Texture2DTest::testSetUp(); }
718 };
719
720 class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
721 {
722 protected:
Texture2DIntegerAlpha1TestES3()723 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
724
getVertexShaderSource()725 const char *getVertexShaderSource() override
726 {
727 return "#version 300 es\n"
728 "out vec2 texcoord;\n"
729 "in vec4 position;\n"
730 "void main()\n"
731 "{\n"
732 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
733 " texcoord = (position.xy * 0.5) + 0.5;\n"
734 "}\n";
735 }
736
getFragmentShaderSource()737 const char *getFragmentShaderSource() override
738 {
739 return "#version 300 es\n"
740 "precision highp float;\n"
741 "uniform highp isampler2D tex;\n"
742 "in vec2 texcoord;\n"
743 "out vec4 fragColor;\n"
744 "void main()\n"
745 "{\n"
746 " vec4 green = vec4(0, 1, 0, 1);\n"
747 " vec4 black = vec4(0, 0, 0, 0);\n"
748 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
749 "}\n";
750 }
751
testSetUp()752 void testSetUp() override
753 {
754 Texture2DTest::testSetUp();
755 setUpProgram();
756 }
757 };
758
759 class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
760 {
761 protected:
Texture2DUnsignedIntegerAlpha1TestES3()762 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
763
getVertexShaderSource()764 const char *getVertexShaderSource() override
765 {
766 return "#version 300 es\n"
767 "out vec2 texcoord;\n"
768 "in vec4 position;\n"
769 "void main()\n"
770 "{\n"
771 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
772 " texcoord = (position.xy * 0.5) + 0.5;\n"
773 "}\n";
774 }
775
getFragmentShaderSource()776 const char *getFragmentShaderSource() override
777 {
778 return "#version 300 es\n"
779 "precision highp float;\n"
780 "uniform highp usampler2D tex;\n"
781 "in vec2 texcoord;\n"
782 "out vec4 fragColor;\n"
783 "void main()\n"
784 "{\n"
785 " vec4 green = vec4(0, 1, 0, 1);\n"
786 " vec4 black = vec4(0, 0, 0, 0);\n"
787 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
788 "}\n";
789 }
790
testSetUp()791 void testSetUp() override
792 {
793 Texture2DTest::testSetUp();
794 setUpProgram();
795 }
796 };
797
798 class Texture2DTestWithDrawScale : public Texture2DTest
799 {
800 protected:
Texture2DTestWithDrawScale()801 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
802
getVertexShaderSource()803 const char *getVertexShaderSource() override
804 {
805 return
806 R"(precision highp float;
807 attribute vec4 position;
808 varying vec2 texcoord;
809
810 uniform vec2 drawScale;
811
812 void main()
813 {
814 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
815 texcoord = (position.xy * 0.5) + 0.5;
816 })";
817 }
818
testSetUp()819 void testSetUp() override
820 {
821 Texture2DTest::testSetUp();
822
823 setUpProgram();
824
825 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
826 ASSERT_NE(-1, mDrawScaleUniformLocation);
827
828 glUseProgram(mProgram);
829 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
830 glUseProgram(0);
831 ASSERT_GL_NO_ERROR();
832 }
833
834 GLint mDrawScaleUniformLocation;
835 };
836
837 class Sampler2DAsFunctionParameterTest : public Texture2DTest
838 {
839 protected:
Sampler2DAsFunctionParameterTest()840 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
841
getFragmentShaderSource()842 const char *getFragmentShaderSource() override
843 {
844 return
845 R"(precision highp float;
846 uniform sampler2D tex;
847 varying vec2 texcoord;
848
849 vec4 computeFragColor(sampler2D aTex)
850 {
851 return texture2D(aTex, texcoord);
852 }
853
854 void main()
855 {
856 gl_FragColor = computeFragColor(tex);
857 })";
858 }
859
testSetUp()860 void testSetUp() override
861 {
862 Texture2DTest::testSetUp();
863 setUpProgram();
864 }
865 };
866
867 class TextureCubeTest : public TexCoordDrawTest
868 {
869 protected:
TextureCubeTest()870 TextureCubeTest()
871 : TexCoordDrawTest(),
872 mTexture2D(0),
873 mTextureCube(0),
874 mTexture2DUniformLocation(-1),
875 mTextureCubeUniformLocation(-1)
876 {}
877
getFragmentShaderSource()878 const char *getFragmentShaderSource() override
879 {
880 return
881 R"(precision highp float;
882 uniform sampler2D tex2D;
883 uniform samplerCube texCube;
884 varying vec2 texcoord;
885
886 void main()
887 {
888 gl_FragColor = texture2D(tex2D, texcoord);
889 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
890 })";
891 }
892
testSetUp()893 void testSetUp() override
894 {
895 TexCoordDrawTest::testSetUp();
896
897 glGenTextures(1, &mTextureCube);
898 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
899 for (GLenum face = 0; face < 6; face++)
900 {
901 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
902 GL_UNSIGNED_BYTE, nullptr);
903 }
904 EXPECT_GL_NO_ERROR();
905
906 mTexture2D = create2DTexture();
907
908 setUpProgram();
909
910 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
911 ASSERT_NE(-1, mTexture2DUniformLocation);
912 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
913 ASSERT_NE(-1, mTextureCubeUniformLocation);
914 }
915
testTearDown()916 void testTearDown() override
917 {
918 glDeleteTextures(1, &mTextureCube);
919 TexCoordDrawTest::testTearDown();
920 }
921
922 GLuint mTexture2D;
923 GLuint mTextureCube;
924 GLint mTexture2DUniformLocation;
925 GLint mTextureCubeUniformLocation;
926 };
927
928 class TextureCubeTestES3 : public ANGLETest
929 {
930 protected:
TextureCubeTestES3()931 TextureCubeTestES3() {}
932 };
933
934 class SamplerArrayTest : public TexCoordDrawTest
935 {
936 protected:
SamplerArrayTest()937 SamplerArrayTest()
938 : TexCoordDrawTest(),
939 mTexture2DA(0),
940 mTexture2DB(0),
941 mTexture0UniformLocation(-1),
942 mTexture1UniformLocation(-1)
943 {}
944
getFragmentShaderSource()945 const char *getFragmentShaderSource() override
946 {
947 return
948 R"(precision mediump float;
949 uniform highp sampler2D tex2DArray[2];
950 varying vec2 texcoord;
951 void main()
952 {
953 gl_FragColor = texture2D(tex2DArray[0], texcoord);
954 gl_FragColor += texture2D(tex2DArray[1], texcoord);
955 })";
956 }
957
testSetUp()958 void testSetUp() override
959 {
960 TexCoordDrawTest::testSetUp();
961
962 setUpProgram();
963
964 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
965 ASSERT_NE(-1, mTexture0UniformLocation);
966 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
967 ASSERT_NE(-1, mTexture1UniformLocation);
968
969 mTexture2DA = create2DTexture();
970 mTexture2DB = create2DTexture();
971 ASSERT_GL_NO_ERROR();
972 }
973
testTearDown()974 void testTearDown() override
975 {
976 glDeleteTextures(1, &mTexture2DA);
977 glDeleteTextures(1, &mTexture2DB);
978 TexCoordDrawTest::testTearDown();
979 }
980
testSamplerArrayDraw()981 void testSamplerArrayDraw()
982 {
983 GLubyte texData[4];
984 texData[0] = 0;
985 texData[1] = 60;
986 texData[2] = 0;
987 texData[3] = 255;
988
989 glActiveTexture(GL_TEXTURE0);
990 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
991 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
992
993 texData[1] = 120;
994 glActiveTexture(GL_TEXTURE1);
995 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
996 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
997 EXPECT_GL_ERROR(GL_NO_ERROR);
998
999 glUseProgram(mProgram);
1000 glUniform1i(mTexture0UniformLocation, 0);
1001 glUniform1i(mTexture1UniformLocation, 1);
1002 drawQuad(mProgram, "position", 0.5f);
1003 EXPECT_GL_NO_ERROR();
1004
1005 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
1006 }
1007
1008 GLuint mTexture2DA;
1009 GLuint mTexture2DB;
1010 GLint mTexture0UniformLocation;
1011 GLint mTexture1UniformLocation;
1012 };
1013
1014 class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
1015 {
1016 protected:
SamplerArrayAsFunctionParameterTest()1017 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
1018
getFragmentShaderSource()1019 const char *getFragmentShaderSource() override
1020 {
1021 return
1022 R"(precision mediump float;
1023 uniform highp sampler2D tex2DArray[2];
1024 varying vec2 texcoord;
1025
1026 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
1027 {
1028 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
1029 }
1030
1031 void main()
1032 {
1033 gl_FragColor = computeFragColor(tex2DArray);
1034 })";
1035 }
1036 };
1037
1038 class Texture2DArrayTestES3 : public TexCoordDrawTest
1039 {
1040 protected:
Texture2DArrayTestES3()1041 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
1042
getVertexShaderSource()1043 const char *getVertexShaderSource() override
1044 {
1045 return "#version 300 es\n"
1046 "out vec2 texcoord;\n"
1047 "in vec4 position;\n"
1048 "void main()\n"
1049 "{\n"
1050 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1051 " texcoord = (position.xy * 0.5) + 0.5;\n"
1052 "}\n";
1053 }
1054
getFragmentShaderSource()1055 const char *getFragmentShaderSource() override
1056 {
1057 return "#version 300 es\n"
1058 "precision highp float;\n"
1059 "uniform highp sampler2DArray tex2DArray;\n"
1060 "in vec2 texcoord;\n"
1061 "out vec4 fragColor;\n"
1062 "void main()\n"
1063 "{\n"
1064 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
1065 "}\n";
1066 }
1067
testSetUp()1068 void testSetUp() override
1069 {
1070 TexCoordDrawTest::testSetUp();
1071
1072 setUpProgram();
1073
1074 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
1075 ASSERT_NE(-1, mTextureArrayLocation);
1076
1077 glGenTextures(1, &m2DArrayTexture);
1078 ASSERT_GL_NO_ERROR();
1079 }
1080
testTearDown()1081 void testTearDown() override
1082 {
1083 glDeleteTextures(1, &m2DArrayTexture);
1084 TexCoordDrawTest::testTearDown();
1085 }
1086
1087 GLuint m2DArrayTexture;
1088 GLint mTextureArrayLocation;
1089 };
1090
1091 class TextureSizeTextureArrayTest : public TexCoordDrawTest
1092 {
1093 protected:
TextureSizeTextureArrayTest()1094 TextureSizeTextureArrayTest()
1095 : TexCoordDrawTest(),
1096 mTexture2DA(0),
1097 mTexture2DB(0),
1098 mTexture0Location(-1),
1099 mTexture1Location(-1)
1100 {}
1101
getVertexShaderSource()1102 const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
1103
getFragmentShaderSource()1104 const char *getFragmentShaderSource() override
1105 {
1106 return "#version 300 es\n"
1107 "precision highp float;\n"
1108 "uniform highp sampler2D tex2DArray[2];\n"
1109 "out vec4 fragColor;\n"
1110 "void main()\n"
1111 "{\n"
1112 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
1113 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
1114 " fragColor = vec4(red, green, 0.0, 1.0);\n"
1115 "}\n";
1116 }
1117
testSetUp()1118 void testSetUp() override
1119 {
1120 TexCoordDrawTest::testSetUp();
1121
1122 setUpProgram();
1123
1124 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
1125 ASSERT_NE(-1, mTexture0Location);
1126 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
1127 ASSERT_NE(-1, mTexture1Location);
1128
1129 mTexture2DA = create2DTexture();
1130 mTexture2DB = create2DTexture();
1131 ASSERT_GL_NO_ERROR();
1132 }
1133
testTearDown()1134 void testTearDown() override
1135 {
1136 glDeleteTextures(1, &mTexture2DA);
1137 glDeleteTextures(1, &mTexture2DB);
1138 TexCoordDrawTest::testTearDown();
1139 }
1140
1141 GLuint mTexture2DA;
1142 GLuint mTexture2DB;
1143 GLint mTexture0Location;
1144 GLint mTexture1Location;
1145 };
1146
1147 // Test for GL_OES_texture_3D extension
1148 class Texture3DTestES2 : public TexCoordDrawTest
1149 {
1150 protected:
Texture3DTestES2()1151 Texture3DTestES2() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
1152
getVertexShaderSource()1153 const char *getVertexShaderSource() override
1154 {
1155 return "#version 100\n"
1156 "varying vec2 texcoord;\n"
1157 "attribute vec4 position;\n"
1158 "void main()\n"
1159 "{\n"
1160 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1161 " texcoord = (position.xy * 0.5) + 0.5;\n"
1162 "}\n";
1163 }
1164
getFragmentShaderSource()1165 const char *getFragmentShaderSource() override
1166 {
1167 if (!hasTexture3DExt())
1168 {
1169 return "#version 100\n"
1170 "precision highp float;\n"
1171 "varying vec2 texcoord;\n"
1172 "void main()\n"
1173 "{\n"
1174 " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1175 "}\n";
1176 }
1177 return "#version 100\n"
1178 "#extension GL_OES_texture_3D : enable\n"
1179 "precision highp float;\n"
1180 "uniform highp sampler3D tex3D;\n"
1181 "uniform highp float level;\n"
1182 "varying vec2 texcoord;\n"
1183 "void main()\n"
1184 "{\n"
1185 " gl_FragColor = texture3DLod(tex3D, vec3(texcoord, 0.0), level);\n"
1186 "}\n";
1187 }
1188
testSetUp()1189 void testSetUp() override
1190 {
1191 // http://anglebug.com/5728
1192 ANGLE_SKIP_TEST_IF(IsOzone());
1193
1194 TexCoordDrawTest::testSetUp();
1195
1196 glGenTextures(1, &mTexture3D);
1197
1198 setUpProgram();
1199
1200 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1201 if (hasTexture3DExt())
1202 {
1203 ASSERT_NE(-1, mTexture3DUniformLocation);
1204 }
1205 }
1206
testTearDown()1207 void testTearDown() override
1208 {
1209 glDeleteTextures(1, &mTexture3D);
1210 TexCoordDrawTest::testTearDown();
1211 }
1212
hasTexture3DExt() const1213 bool hasTexture3DExt() const
1214 {
1215 // http://anglebug.com/4927
1216 if ((IsPixel2() || IsNexus5X()) && IsOpenGLES())
1217 {
1218 return false;
1219 }
1220 return IsGLExtensionEnabled("GL_OES_texture_3D");
1221 }
1222
1223 GLuint mTexture3D;
1224 GLint mTexture3DUniformLocation;
1225 };
1226
1227 class Texture3DTestES3 : public Texture3DTestES2
1228 {
1229 protected:
Texture3DTestES3()1230 Texture3DTestES3() : Texture3DTestES2() {}
1231
getVertexShaderSource()1232 const char *getVertexShaderSource() override
1233 {
1234 return "#version 300 es\n"
1235 "out vec2 texcoord;\n"
1236 "in vec4 position;\n"
1237 "void main()\n"
1238 "{\n"
1239 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1240 " texcoord = (position.xy * 0.5) + 0.5;\n"
1241 "}\n";
1242 }
1243
getFragmentShaderSource()1244 const char *getFragmentShaderSource() override
1245 {
1246 return "#version 300 es\n"
1247 "precision highp float;\n"
1248 "uniform highp sampler3D tex3D;\n"
1249 "in vec2 texcoord;\n"
1250 "out vec4 fragColor;\n"
1251 "void main()\n"
1252 "{\n"
1253 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
1254 "}\n";
1255 }
1256 };
1257
1258 class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
1259 {
1260 protected:
ShadowSamplerPlusSampler3DTestES3()1261 ShadowSamplerPlusSampler3DTestES3()
1262 : TexCoordDrawTest(),
1263 mTextureShadow(0),
1264 mTexture3D(0),
1265 mTextureShadowUniformLocation(-1),
1266 mTexture3DUniformLocation(-1),
1267 mDepthRefUniformLocation(-1)
1268 {}
1269
getVertexShaderSource()1270 const char *getVertexShaderSource() override
1271 {
1272 return "#version 300 es\n"
1273 "out vec2 texcoord;\n"
1274 "in vec4 position;\n"
1275 "void main()\n"
1276 "{\n"
1277 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1278 " texcoord = (position.xy * 0.5) + 0.5;\n"
1279 "}\n";
1280 }
1281
getFragmentShaderSource()1282 const char *getFragmentShaderSource() override
1283 {
1284 return "#version 300 es\n"
1285 "precision highp float;\n"
1286 "uniform highp sampler2DShadow tex2DShadow;\n"
1287 "uniform highp sampler3D tex3D;\n"
1288 "in vec2 texcoord;\n"
1289 "uniform float depthRef;\n"
1290 "out vec4 fragColor;\n"
1291 "void main()\n"
1292 "{\n"
1293 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
1294 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
1295 "}\n";
1296 }
1297
testSetUp()1298 void testSetUp() override
1299 {
1300 TexCoordDrawTest::testSetUp();
1301
1302 glGenTextures(1, &mTexture3D);
1303
1304 glGenTextures(1, &mTextureShadow);
1305 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1306 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1307
1308 setUpProgram();
1309
1310 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1311 ASSERT_NE(-1, mTextureShadowUniformLocation);
1312 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1313 ASSERT_NE(-1, mTexture3DUniformLocation);
1314 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1315 ASSERT_NE(-1, mDepthRefUniformLocation);
1316 }
1317
testTearDown()1318 void testTearDown() override
1319 {
1320 glDeleteTextures(1, &mTextureShadow);
1321 glDeleteTextures(1, &mTexture3D);
1322 TexCoordDrawTest::testTearDown();
1323 }
1324
1325 GLuint mTextureShadow;
1326 GLuint mTexture3D;
1327 GLint mTextureShadowUniformLocation;
1328 GLint mTexture3DUniformLocation;
1329 GLint mDepthRefUniformLocation;
1330 };
1331
1332 class SamplerTypeMixTestES3 : public TexCoordDrawTest
1333 {
1334 protected:
SamplerTypeMixTestES3()1335 SamplerTypeMixTestES3()
1336 : TexCoordDrawTest(),
1337 mTexture2D(0),
1338 mTextureCube(0),
1339 mTexture2DShadow(0),
1340 mTextureCubeShadow(0),
1341 mTexture2DUniformLocation(-1),
1342 mTextureCubeUniformLocation(-1),
1343 mTexture2DShadowUniformLocation(-1),
1344 mTextureCubeShadowUniformLocation(-1),
1345 mDepthRefUniformLocation(-1)
1346 {}
1347
getVertexShaderSource()1348 const char *getVertexShaderSource() override
1349 {
1350 return "#version 300 es\n"
1351 "out vec2 texcoord;\n"
1352 "in vec4 position;\n"
1353 "void main()\n"
1354 "{\n"
1355 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1356 " texcoord = (position.xy * 0.5) + 0.5;\n"
1357 "}\n";
1358 }
1359
getFragmentShaderSource()1360 const char *getFragmentShaderSource() override
1361 {
1362 return "#version 300 es\n"
1363 "precision highp float;\n"
1364 "uniform highp sampler2D tex2D;\n"
1365 "uniform highp samplerCube texCube;\n"
1366 "uniform highp sampler2DShadow tex2DShadow;\n"
1367 "uniform highp samplerCubeShadow texCubeShadow;\n"
1368 "in vec2 texcoord;\n"
1369 "uniform float depthRef;\n"
1370 "out vec4 fragColor;\n"
1371 "void main()\n"
1372 "{\n"
1373 " fragColor = texture(tex2D, texcoord);\n"
1374 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1375 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1376 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1377 "0.125);\n"
1378 "}\n";
1379 }
1380
testSetUp()1381 void testSetUp() override
1382 {
1383 TexCoordDrawTest::testSetUp();
1384
1385 glGenTextures(1, &mTexture2D);
1386 glGenTextures(1, &mTextureCube);
1387
1388 glGenTextures(1, &mTexture2DShadow);
1389 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1391
1392 glGenTextures(1, &mTextureCubeShadow);
1393 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1394 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1395
1396 setUpProgram();
1397
1398 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1399 ASSERT_NE(-1, mTexture2DUniformLocation);
1400 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1401 ASSERT_NE(-1, mTextureCubeUniformLocation);
1402 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1403 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1404 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1405 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1406 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1407 ASSERT_NE(-1, mDepthRefUniformLocation);
1408
1409 ASSERT_GL_NO_ERROR();
1410 }
1411
testTearDown()1412 void testTearDown() override
1413 {
1414 glDeleteTextures(1, &mTexture2D);
1415 glDeleteTextures(1, &mTextureCube);
1416 glDeleteTextures(1, &mTexture2DShadow);
1417 glDeleteTextures(1, &mTextureCubeShadow);
1418 TexCoordDrawTest::testTearDown();
1419 }
1420
1421 GLuint mTexture2D;
1422 GLuint mTextureCube;
1423 GLuint mTexture2DShadow;
1424 GLuint mTextureCubeShadow;
1425 GLint mTexture2DUniformLocation;
1426 GLint mTextureCubeUniformLocation;
1427 GLint mTexture2DShadowUniformLocation;
1428 GLint mTextureCubeShadowUniformLocation;
1429 GLint mDepthRefUniformLocation;
1430 };
1431
1432 class SamplerInStructTest : public Texture2DTest
1433 {
1434 protected:
SamplerInStructTest()1435 SamplerInStructTest() : Texture2DTest() {}
1436
getTextureUniformName()1437 const char *getTextureUniformName() override { return "us.tex"; }
1438
getFragmentShaderSource()1439 const char *getFragmentShaderSource() override
1440 {
1441 return "precision highp float;\n"
1442 "struct S\n"
1443 "{\n"
1444 " vec4 a;\n"
1445 " highp sampler2D tex;\n"
1446 "};\n"
1447 "uniform S us;\n"
1448 "varying vec2 texcoord;\n"
1449 "void main()\n"
1450 "{\n"
1451 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1452 "}\n";
1453 }
1454
runSamplerInStructTest()1455 void runSamplerInStructTest()
1456 {
1457 setUpProgram();
1458
1459 glActiveTexture(GL_TEXTURE0);
1460 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1461 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1462 &GLColor::green);
1463 drawQuad(mProgram, "position", 0.5f);
1464 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1465 }
1466 };
1467
1468 class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1469 {
1470 protected:
SamplerInStructAsFunctionParameterTest()1471 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1472
getFragmentShaderSource()1473 const char *getFragmentShaderSource() override
1474 {
1475 return "precision highp float;\n"
1476 "struct S\n"
1477 "{\n"
1478 " vec4 a;\n"
1479 " highp sampler2D tex;\n"
1480 "};\n"
1481 "uniform S us;\n"
1482 "varying vec2 texcoord;\n"
1483 "vec4 sampleFrom(S s) {\n"
1484 " return texture2D(s.tex, texcoord + s.a.x);\n"
1485 "}\n"
1486 "void main()\n"
1487 "{\n"
1488 " gl_FragColor = sampleFrom(us);\n"
1489 "}\n";
1490 }
1491 };
1492
1493 class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1494 {
1495 protected:
SamplerInStructArrayAsFunctionParameterTest()1496 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1497
getTextureUniformName()1498 const char *getTextureUniformName() override { return "us[0].tex"; }
1499
getFragmentShaderSource()1500 const char *getFragmentShaderSource() override
1501 {
1502 return "precision highp float;\n"
1503 "struct S\n"
1504 "{\n"
1505 " vec4 a;\n"
1506 " highp sampler2D tex;\n"
1507 "};\n"
1508 "uniform S us[1];\n"
1509 "varying vec2 texcoord;\n"
1510 "vec4 sampleFrom(S s) {\n"
1511 " return texture2D(s.tex, texcoord + s.a.x);\n"
1512 "}\n"
1513 "void main()\n"
1514 "{\n"
1515 " gl_FragColor = sampleFrom(us[0]);\n"
1516 "}\n";
1517 }
1518 };
1519
1520 class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1521 {
1522 protected:
SamplerInNestedStructAsFunctionParameterTest()1523 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1524
getTextureUniformName()1525 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1526
getFragmentShaderSource()1527 const char *getFragmentShaderSource() override
1528 {
1529 return "precision highp float;\n"
1530 "struct SUB\n"
1531 "{\n"
1532 " vec4 a;\n"
1533 " highp sampler2D tex;\n"
1534 "};\n"
1535 "struct S\n"
1536 "{\n"
1537 " SUB sub;\n"
1538 "};\n"
1539 "uniform S us[1];\n"
1540 "varying vec2 texcoord;\n"
1541 "vec4 sampleFrom(SUB s) {\n"
1542 " return texture2D(s.tex, texcoord + s.a.x);\n"
1543 "}\n"
1544 "void main()\n"
1545 "{\n"
1546 " gl_FragColor = sampleFrom(us[0].sub);\n"
1547 "}\n";
1548 }
1549 };
1550
1551 class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1552 {
1553 protected:
SamplerInStructAndOtherVariableTest()1554 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1555
getFragmentShaderSource()1556 const char *getFragmentShaderSource() override
1557 {
1558 return "precision highp float;\n"
1559 "struct S\n"
1560 "{\n"
1561 " vec4 a;\n"
1562 " highp sampler2D tex;\n"
1563 "};\n"
1564 "uniform S us;\n"
1565 "uniform float us_tex;\n"
1566 "varying vec2 texcoord;\n"
1567 "void main()\n"
1568 "{\n"
1569 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1570 "}\n";
1571 }
1572 };
1573
1574 class Texture2DIntegerTestES3 : public Texture2DTest
1575 {
1576 protected:
Texture2DIntegerTestES3()1577 Texture2DIntegerTestES3() : Texture2DTest() {}
1578
getVertexShaderSource()1579 const char *getVertexShaderSource() override
1580 {
1581 return "#version 300 es\n"
1582 "out vec2 texcoord;\n"
1583 "in vec4 position;\n"
1584 "void main()\n"
1585 "{\n"
1586 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1587 " texcoord = (position.xy * 0.5) + 0.5;\n"
1588 "}\n";
1589 }
1590
getFragmentShaderSource()1591 const char *getFragmentShaderSource() override
1592 {
1593 return "#version 300 es\n"
1594 "precision highp float;\n"
1595 "precision highp usampler2D;\n"
1596 "uniform usampler2D tex;\n"
1597 "in vec2 texcoord;\n"
1598 "out vec4 fragColor;\n"
1599 "void main()\n"
1600 "{\n"
1601 " fragColor = vec4(texture(tex, texcoord))/255.0;\n"
1602 "}\n";
1603 }
1604 };
1605
1606 class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1607 {
1608 protected:
TextureCubeIntegerTestES3()1609 TextureCubeIntegerTestES3()
1610 : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1611 {}
1612
getVertexShaderSource()1613 const char *getVertexShaderSource() override
1614 {
1615 return "#version 300 es\n"
1616 "out vec2 texcoord;\n"
1617 "in vec4 position;\n"
1618 "void main()\n"
1619 "{\n"
1620 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1621 " texcoord = 0.5*position.xy;\n"
1622 "}\n";
1623 }
1624
getFragmentShaderSource()1625 const char *getFragmentShaderSource() override
1626 {
1627 return "#version 300 es\n"
1628 "precision highp float;\n"
1629 "precision highp usamplerCube;\n"
1630 "uniform usamplerCube texCube;\n"
1631 "in vec2 texcoord;\n"
1632 "out vec4 fragColor;\n"
1633 "void main()\n"
1634 "{\n"
1635 " fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1636 "}\n";
1637 }
1638
testSetUp()1639 void testSetUp() override
1640 {
1641 TexCoordDrawTest::testSetUp();
1642 glGenTextures(1, &mTextureCube);
1643 setUpProgram();
1644
1645 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1646 ASSERT_NE(-1, mTextureCubeUniformLocation);
1647 }
1648
testTearDown()1649 void testTearDown() override
1650 {
1651 glDeleteTextures(1, &mTextureCube);
1652 TexCoordDrawTest::testTearDown();
1653 }
1654
1655 GLuint mTextureCube;
1656 GLint mTextureCubeUniformLocation;
1657 };
1658
1659 class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1660 {
1661 protected:
TextureCubeIntegerEdgeTestES3()1662 TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1663
getVertexShaderSource()1664 const char *getVertexShaderSource() override
1665 {
1666 return "#version 300 es\n"
1667 "out vec2 texcoord;\n"
1668 "in vec4 position;\n"
1669 "void main()\n"
1670 "{\n"
1671 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1672 " texcoord = position.xy;\n"
1673 "}\n";
1674 }
1675
getFragmentShaderSource()1676 const char *getFragmentShaderSource() override
1677 {
1678 return "#version 300 es\n"
1679 "precision highp float;\n"
1680 "precision highp usamplerCube;\n"
1681 "uniform usamplerCube texCube;\n"
1682 "in vec2 texcoord;\n"
1683 "out vec4 fragColor;\n"
1684 "void main()\n"
1685 "{\n"
1686 " fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1687 "}\n";
1688 }
1689 };
1690
1691 class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1692 {
1693 protected:
Texture2DIntegerProjectiveOffsetTestES3()1694 Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1695
getVertexShaderSource()1696 const char *getVertexShaderSource() override
1697 {
1698 return "#version 300 es\n"
1699 "out vec2 texcoord;\n"
1700 "in vec4 position;\n"
1701 "void main()\n"
1702 "{\n"
1703 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1704 " texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1705 "}\n";
1706 }
1707
getFragmentShaderSource()1708 const char *getFragmentShaderSource() override
1709 {
1710 return "#version 300 es\n"
1711 "precision highp float;\n"
1712 "precision highp usampler2D;\n"
1713 "uniform usampler2D tex;\n"
1714 "in vec2 texcoord;\n"
1715 "out vec4 fragColor;\n"
1716 "void main()\n"
1717 "{\n"
1718 " fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1719 "0.0))/255.0;\n"
1720 "}\n";
1721 }
1722 };
1723
1724 class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1725 {
1726 protected:
Texture2DArrayIntegerTestES3()1727 Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1728
getVertexShaderSource()1729 const char *getVertexShaderSource() override
1730 {
1731 return "#version 300 es\n"
1732 "out vec2 texcoord;\n"
1733 "in vec4 position;\n"
1734 "void main()\n"
1735 "{\n"
1736 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1737 " texcoord = (position.xy * 0.5) + 0.5;\n"
1738 "}\n";
1739 }
1740
getFragmentShaderSource()1741 const char *getFragmentShaderSource() override
1742 {
1743 return "#version 300 es\n"
1744 "precision highp float;\n"
1745 "uniform highp usampler2DArray tex2DArray;\n"
1746 "in vec2 texcoord;\n"
1747 "out vec4 fragColor;\n"
1748 "void main()\n"
1749 "{\n"
1750 " fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
1751 "0.0)))/255.0;\n"
1752 "}\n";
1753 }
1754 };
1755
1756 class Texture3DIntegerTestES3 : public Texture3DTestES3
1757 {
1758 protected:
Texture3DIntegerTestES3()1759 Texture3DIntegerTestES3() : Texture3DTestES3() {}
1760
getVertexShaderSource()1761 const char *getVertexShaderSource() override
1762 {
1763 return "#version 300 es\n"
1764 "out vec2 texcoord;\n"
1765 "in vec4 position;\n"
1766 "void main()\n"
1767 "{\n"
1768 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1769 " texcoord = (position.xy * 0.5) + 0.5;\n"
1770 "}\n";
1771 }
1772
getFragmentShaderSource()1773 const char *getFragmentShaderSource() override
1774 {
1775 return "#version 300 es\n"
1776 "precision highp float;\n"
1777 "uniform highp usampler3D tex3D;\n"
1778 "in vec2 texcoord;\n"
1779 "out vec4 fragColor;\n"
1780 "void main()\n"
1781 "{\n"
1782 " fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1783 "}\n";
1784 }
1785 };
1786
1787 class PBOCompressedTextureTest : public Texture2DTest
1788 {
1789 protected:
PBOCompressedTextureTest()1790 PBOCompressedTextureTest() : Texture2DTest() {}
1791
testSetUp()1792 void testSetUp() override
1793 {
1794 TexCoordDrawTest::testSetUp();
1795 glGenTextures(1, &mTexture2D);
1796 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1797 EXPECT_GL_NO_ERROR();
1798
1799 setUpProgram();
1800
1801 glGenBuffers(1, &mPBO);
1802 }
1803
testTearDown()1804 void testTearDown() override
1805 {
1806 glDeleteBuffers(1, &mPBO);
1807 Texture2DTest::testTearDown();
1808 }
1809
1810 void runCompressedSubImage();
1811
1812 GLuint mPBO;
1813 };
1814
1815 class ETC1CompressedTextureTest : public Texture2DTest
1816 {
1817 protected:
ETC1CompressedTextureTest()1818 ETC1CompressedTextureTest() : Texture2DTest() {}
1819
testSetUp()1820 void testSetUp() override
1821 {
1822 TexCoordDrawTest::testSetUp();
1823 glGenTextures(1, &mTexture2D);
1824 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1825 EXPECT_GL_NO_ERROR();
1826
1827 setUpProgram();
1828 }
1829
testTearDown()1830 void testTearDown() override { Texture2DTest::testTearDown(); }
1831 };
1832
TEST_P(Texture2DTest,NegativeAPISubImage)1833 TEST_P(Texture2DTest, NegativeAPISubImage)
1834 {
1835 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1836 EXPECT_GL_ERROR(GL_NO_ERROR);
1837
1838 setUpProgram();
1839
1840 const GLubyte *pixels[20] = {0};
1841 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1842 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1843
1844 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
1845 {
1846 // Create a 1-level immutable texture.
1847 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1848
1849 // Try calling sub image on the second level.
1850 glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1851 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1852 }
1853 }
1854
1855 // Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
TEST_P(Texture2DTest,QueryBinding)1856 TEST_P(Texture2DTest, QueryBinding)
1857 {
1858 glBindTexture(GL_TEXTURE_2D, 0);
1859 EXPECT_GL_ERROR(GL_NO_ERROR);
1860
1861 GLint textureBinding;
1862 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1863 EXPECT_GL_NO_ERROR();
1864 EXPECT_EQ(0, textureBinding);
1865
1866 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
1867 if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1868 IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
1869 {
1870 EXPECT_GL_NO_ERROR();
1871 EXPECT_EQ(0, textureBinding);
1872 }
1873 else
1874 {
1875 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1876 }
1877 }
1878
TEST_P(Texture2DTest,ZeroSizedUploads)1879 TEST_P(Texture2DTest, ZeroSizedUploads)
1880 {
1881 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1882 EXPECT_GL_ERROR(GL_NO_ERROR);
1883
1884 setUpProgram();
1885
1886 // Use the texture first to make sure it's in video memory
1887 glUseProgram(mProgram);
1888 glUniform1i(mTexture2DUniformLocation, 0);
1889 drawQuad(mProgram, "position", 0.5f);
1890
1891 const GLubyte *pixel[4] = {0};
1892
1893 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1894 EXPECT_GL_NO_ERROR();
1895
1896 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1897 EXPECT_GL_NO_ERROR();
1898
1899 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1900 EXPECT_GL_NO_ERROR();
1901 }
1902
TEST_P(Texture2DTest,DefineMultipleLevelsWithoutMipmapping)1903 TEST_P(Texture2DTest, DefineMultipleLevelsWithoutMipmapping)
1904 {
1905 setUpProgram();
1906
1907 constexpr size_t kImageSize = 256;
1908 std::array<GLColor, kImageSize * kImageSize> kMipColors[2];
1909
1910 std::fill(kMipColors[0].begin(), kMipColors[0].end(), GLColor::red);
1911 std::fill(kMipColors[1].begin(), kMipColors[1].end(), GLColor::green);
1912
1913 glActiveTexture(GL_TEXTURE0);
1914 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1915 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1916 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1917
1918 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1919 kMipColors[0].data());
1920 EXPECT_GL_NO_ERROR();
1921
1922 // Draw so the image is created.
1923 glUseProgram(mProgram);
1924 glUniform1i(mTexture2DUniformLocation, 0);
1925 drawQuad(mProgram, "position", 0.5f);
1926
1927 // Define level 1 of the texture.
1928 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1929 kMipColors[1].data());
1930 EXPECT_GL_NO_ERROR();
1931
1932 // Draw again.
1933 drawQuad(mProgram, "position", 0.5f);
1934 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0][0]);
1935 }
1936
1937 // Test drawing with two texture types, to trigger an ANGLE bug in validation
TEST_P(TextureCubeTest,CubeMapBug)1938 TEST_P(TextureCubeTest, CubeMapBug)
1939 {
1940 glActiveTexture(GL_TEXTURE0);
1941 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1942 glActiveTexture(GL_TEXTURE1);
1943 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1944 EXPECT_GL_ERROR(GL_NO_ERROR);
1945
1946 glUseProgram(mProgram);
1947 glUniform1i(mTexture2DUniformLocation, 0);
1948 glUniform1i(mTextureCubeUniformLocation, 1);
1949 drawQuad(mProgram, "position", 0.5f);
1950 EXPECT_GL_NO_ERROR();
1951 }
1952
1953 // Test drawing with two texture types accessed from the same shader and check that the result of
1954 // drawing is correct.
TEST_P(TextureCubeTest,CubeMapDraw)1955 TEST_P(TextureCubeTest, CubeMapDraw)
1956 {
1957 GLubyte texData[4];
1958 texData[0] = 0;
1959 texData[1] = 60;
1960 texData[2] = 0;
1961 texData[3] = 255;
1962
1963 glActiveTexture(GL_TEXTURE0);
1964 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1965 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1966
1967 glActiveTexture(GL_TEXTURE1);
1968 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1969 texData[1] = 120;
1970 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1971 texData);
1972 EXPECT_GL_ERROR(GL_NO_ERROR);
1973
1974 glUseProgram(mProgram);
1975 glUniform1i(mTexture2DUniformLocation, 0);
1976 glUniform1i(mTextureCubeUniformLocation, 1);
1977 drawQuad(mProgram, "position", 0.5f);
1978 EXPECT_GL_NO_ERROR();
1979
1980 int px = getWindowWidth() - 1;
1981 int py = 0;
1982 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1983 }
1984
TEST_P(Sampler2DAsFunctionParameterTest,Sampler2DAsFunctionParameter)1985 TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1986 {
1987 glActiveTexture(GL_TEXTURE0);
1988 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1989 GLubyte texData[4];
1990 texData[0] = 0;
1991 texData[1] = 128;
1992 texData[2] = 0;
1993 texData[3] = 255;
1994 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1995 glUseProgram(mProgram);
1996 glUniform1i(mTexture2DUniformLocation, 0);
1997 drawQuad(mProgram, "position", 0.5f);
1998 EXPECT_GL_NO_ERROR();
1999
2000 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
2001 }
2002
2003 // Test drawing with two textures passed to the shader in a sampler array.
TEST_P(SamplerArrayTest,SamplerArrayDraw)2004 TEST_P(SamplerArrayTest, SamplerArrayDraw)
2005 {
2006 testSamplerArrayDraw();
2007 }
2008
2009 // Test drawing with two textures passed to the shader in a sampler array which is passed to a
2010 // user-defined function in the shader.
TEST_P(SamplerArrayAsFunctionParameterTest,SamplerArrayAsFunctionParameter)2011 TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
2012 {
2013 // TODO: Diagnose and fix. http://anglebug.com/2955
2014 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
2015
2016 testSamplerArrayDraw();
2017 }
2018
2019 // Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
TEST_P(Texture2DTestWithDrawScale,MipmapsTwice)2020 TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
2021 {
2022 int px = getWindowWidth() / 2;
2023 int py = getWindowHeight() / 2;
2024
2025 glActiveTexture(GL_TEXTURE0);
2026 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2027
2028 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
2029
2030 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
2031 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2032 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2033 glGenerateMipmap(GL_TEXTURE_2D);
2034
2035 glUseProgram(mProgram);
2036 glUniform1i(mTexture2DUniformLocation, 0);
2037 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
2038 drawQuad(mProgram, "position", 0.5f);
2039 EXPECT_GL_NO_ERROR();
2040 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
2041
2042 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
2043
2044 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2045 pixelsBlue.data());
2046 glGenerateMipmap(GL_TEXTURE_2D);
2047
2048 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
2049
2050 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2051 pixelsGreen.data());
2052 glGenerateMipmap(GL_TEXTURE_2D);
2053
2054 drawQuad(mProgram, "position", 0.5f);
2055
2056 EXPECT_GL_NO_ERROR();
2057 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
2058 }
2059
2060 // Test creating a FBO with a cube map render target, to test an ANGLE bug
2061 // https://code.google.com/p/angleproject/issues/detail?id=849
TEST_P(TextureCubeTest,CubeMapFBO)2062 TEST_P(TextureCubeTest, CubeMapFBO)
2063 {
2064 // http://anglebug.com/3145
2065 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
2066
2067 GLFramebuffer fbo;
2068 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2069
2070 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2071 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2072 mTextureCube, 0);
2073
2074 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2075 EXPECT_GL_NO_ERROR();
2076
2077 // Test clearing the six mip faces individually.
2078 std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
2079 GLColor::yellow, GLColor::cyan, GLColor::magenta}};
2080
2081 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2082 {
2083 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2084 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2085
2086 Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
2087 glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
2088 glClear(GL_COLOR_BUFFER_BIT);
2089
2090 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
2091 }
2092
2093 // Iterate the faces again to make sure the colors haven't changed.
2094 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
2095 {
2096 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2097 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
2098 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
2099 << "face color " << faceIndex << " shouldn't change";
2100 }
2101 }
2102
2103 // Tests clearing a cube map with a scissor enabled.
TEST_P(TextureCubeTest,CubeMapFBOScissoredClear)2104 TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
2105 {
2106 // http://anglebug.com/3145
2107 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
2108
2109 constexpr size_t kSize = 16;
2110
2111 GLFramebuffer fbo;
2112 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2113 glViewport(0, 0, kSize, kSize);
2114
2115 GLTexture texcube;
2116 glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
2117 for (GLenum face = 0; face < 6; face++)
2118 {
2119 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
2120 GL_UNSIGNED_BYTE, nullptr);
2121 }
2122 ASSERT_GL_NO_ERROR();
2123
2124 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
2125 texcube, 0);
2126
2127 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2128 ASSERT_GL_NO_ERROR();
2129
2130 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2131 glClear(GL_COLOR_BUFFER_BIT);
2132 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2133
2134 glEnable(GL_SCISSOR_TEST);
2135 glScissor(kSize / 2, 0, kSize / 2, kSize);
2136 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2137 glClear(GL_COLOR_BUFFER_BIT);
2138
2139 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2140 EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
2141
2142 ASSERT_GL_NO_ERROR();
2143 }
2144
2145 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
2146 // default color.
TEST_P(Texture2DTest,TexStorage)2147 TEST_P(Texture2DTest, TexStorage)
2148 {
2149 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
2150 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
2151
2152 int width = getWindowWidth();
2153 int height = getWindowHeight();
2154
2155 GLuint tex2D;
2156 glGenTextures(1, &tex2D);
2157 glActiveTexture(GL_TEXTURE0);
2158 glBindTexture(GL_TEXTURE_2D, tex2D);
2159
2160 // Fill with red
2161 std::vector<GLubyte> pixels(3 * 16 * 16);
2162 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2163 {
2164 pixels[pixelId * 3 + 0] = 255;
2165 pixels[pixelId * 3 + 1] = 0;
2166 pixels[pixelId * 3 + 2] = 0;
2167 }
2168
2169 // ANGLE internally uses RGBA as the DirectX format for RGB images
2170 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2171 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2172 if (getClientMajorVersion() >= 3)
2173 {
2174 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2175 }
2176 else
2177 {
2178 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2179 }
2180
2181 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2182 // glTexSubImage2D should take into account that the image is dirty.
2183 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2186
2187 setUpProgram();
2188
2189 glUseProgram(mProgram);
2190 glUniform1i(mTexture2DUniformLocation, 0);
2191 drawQuad(mProgram, "position", 0.5f);
2192 glDeleteTextures(1, &tex2D);
2193 EXPECT_GL_NO_ERROR();
2194 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2195
2196 // Validate that the region of the texture without data has an alpha of 1.0
2197 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
2198 EXPECT_EQ(255, pixel.A);
2199 }
2200
2201 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2202 // initialized the image with a default color.
TEST_P(Texture2DTest,TexStorageWithPBO)2203 TEST_P(Texture2DTest, TexStorageWithPBO)
2204 {
2205 // http://anglebug.com/4126
2206 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
2207
2208 // http://anglebug.com/5081
2209 ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsOpenGL());
2210
2211 // http://anglebug.com/5651
2212 ANGLE_SKIP_TEST_IF(IsLinux() && IsNVIDIA() && IsOpenGL());
2213
2214 // http://anglebug.com/5097
2215 ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsTSan());
2216
2217 if (getClientMajorVersion() < 3)
2218 {
2219 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2220 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2221 }
2222
2223 const int width = getWindowWidth();
2224 const int height = getWindowHeight();
2225 const size_t pixelCount = width * height;
2226 const int componentCount = 3;
2227
2228 GLuint tex2D;
2229 glGenTextures(1, &tex2D);
2230 glActiveTexture(GL_TEXTURE0);
2231 glBindTexture(GL_TEXTURE_2D, tex2D);
2232
2233 // Fill with red
2234 std::vector<GLubyte> pixels(componentCount * pixelCount);
2235 for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
2236 {
2237 pixels[pixelId * componentCount + 0] = 255;
2238 pixels[pixelId * componentCount + 1] = 0;
2239 pixels[pixelId * componentCount + 2] = 0;
2240 }
2241
2242 // Read 16x16 region from red backbuffer to PBO
2243 GLuint pbo;
2244 glGenBuffers(1, &pbo);
2245 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2246 glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
2247 GL_STATIC_DRAW);
2248
2249 // ANGLE internally uses RGBA as the DirectX format for RGB images
2250 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
2251 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
2252 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
2253
2254 // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
2255 // untouched. glTexSubImage2D should take into account that the image is dirty.
2256 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
2257 nullptr);
2258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2259 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2260
2261 setUpProgram();
2262
2263 glUseProgram(mProgram);
2264 glUniform1i(mTexture2DUniformLocation, 0);
2265 drawQuad(mProgram, "position", 0.5f);
2266 glDeleteTextures(1, &tex2D);
2267 glDeleteBuffers(1, &pbo);
2268 EXPECT_GL_NO_ERROR();
2269 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
2270 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2271 }
2272
2273 // Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
2274 // and drawing with the texture
2275 // Pseudo code for the follow test:
2276 // 1. Upload PBO to mTexture2D
2277 // 2. Delete PBO
2278 // 3. Draw with otherTexture (x5)
2279 // 4. Draw with mTexture2D
2280 // 5. Validate color output
TEST_P(Texture2DTest,PBOWithMultipleDraws)2281 TEST_P(Texture2DTest, PBOWithMultipleDraws)
2282 {
2283 if (getClientMajorVersion() < 3)
2284 {
2285 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2286 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2287 }
2288
2289 const GLuint width = getWindowWidth();
2290 const GLuint height = getWindowHeight();
2291 const GLuint windowPixelCount = width * height;
2292 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
2293 std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
2294
2295 // Create secondary draw that does not use mTexture
2296 const char *vertexShaderSource = getVertexShaderSource();
2297 const char *fragmentShaderSource = getFragmentShaderSource();
2298 ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
2299
2300 GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
2301 ASSERT_NE(-1, uniformLoc);
2302 glUseProgram(0);
2303
2304 // Create secondary Texture to draw with
2305 GLTexture otherTexture;
2306 glActiveTexture(GL_TEXTURE0);
2307 glBindTexture(GL_TEXTURE_2D, otherTexture);
2308 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2309 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
2310 pixelsRed.data());
2311 ASSERT_GL_NO_ERROR();
2312
2313 // Setup primary Texture
2314 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2317 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2318 ASSERT_GL_NO_ERROR();
2319
2320 // Setup PBO
2321 GLuint pbo = 0;
2322 glGenBuffers(1, &pbo);
2323 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2324 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
2325 GL_STATIC_DRAW);
2326 ASSERT_GL_NO_ERROR();
2327
2328 // Write PBO to mTexture
2329 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2330 ASSERT_GL_NO_ERROR();
2331 // Delete PBO as ANGLE should be properly handling refcount of this buffer
2332 glDeleteBuffers(1, &pbo);
2333 pixelsGreen.clear();
2334
2335 // Do 5 draws not involving primary texture that the PBO updated
2336 glUseProgram(otherProgram);
2337 glUniform1i(uniformLoc, 0);
2338 glBindTexture(GL_TEXTURE_2D, otherTexture);
2339 drawQuad(otherProgram, "position", 0.5f);
2340 glBindTexture(GL_TEXTURE_2D, 0);
2341 glUseProgram(0);
2342
2343 glUseProgram(otherProgram);
2344 glUniform1i(uniformLoc, 0);
2345 glBindTexture(GL_TEXTURE_2D, otherTexture);
2346 drawQuad(otherProgram, "position", 0.5f);
2347 glBindTexture(GL_TEXTURE_2D, 0);
2348 glUseProgram(0);
2349
2350 glUseProgram(otherProgram);
2351 glUniform1i(uniformLoc, 0);
2352 glBindTexture(GL_TEXTURE_2D, otherTexture);
2353 drawQuad(otherProgram, "position", 0.5f);
2354 glBindTexture(GL_TEXTURE_2D, 0);
2355 glUseProgram(0);
2356
2357 glUseProgram(otherProgram);
2358 glUniform1i(uniformLoc, 0);
2359 glBindTexture(GL_TEXTURE_2D, otherTexture);
2360 drawQuad(otherProgram, "position", 0.5f);
2361 glBindTexture(GL_TEXTURE_2D, 0);
2362 glUseProgram(0);
2363 ASSERT_GL_NO_ERROR();
2364
2365 std::vector<GLColor> output(windowPixelCount, GLColor::black);
2366 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2367 output.data());
2368 EXPECT_EQ(pixelsRed, output);
2369
2370 setUpProgram();
2371 // Draw using PBO updated texture
2372 glUseProgram(mProgram);
2373 glUniform1i(mTexture2DUniformLocation, 0);
2374 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2375 drawQuad(mProgram, "position", 0.5f);
2376 ASSERT_GL_NO_ERROR();
2377
2378 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
2379 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2380 actual.data());
2381 // Value should be green as it was updated during PBO transfer to mTexture
2382 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
2383 EXPECT_EQ(expected, actual);
2384 }
2385
2386 // Test that glTexSubImage2D combined with a PBO works properly. PBO has all pixels as red
2387 // except the middle one being green.
TEST_P(Texture2DTest,TexStorageWithPBOMiddlePixelDifferent)2388 TEST_P(Texture2DTest, TexStorageWithPBOMiddlePixelDifferent)
2389 {
2390 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2391 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2392
2393 int width = getWindowWidth();
2394 int height = getWindowHeight();
2395
2396 GLuint tex2D;
2397 glGenTextures(1, &tex2D);
2398 glActiveTexture(GL_TEXTURE0);
2399 glBindTexture(GL_TEXTURE_2D, tex2D);
2400
2401 std::vector<GLubyte> pixels(3 * 16 * 16);
2402
2403 // Initialize texture with default black color.
2404 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
2405 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
2406
2407 // Fill PBO's data with red, with middle one as green
2408 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2409 {
2410 if (pixelId == 8 * 7 + 7)
2411 {
2412 pixels[pixelId * 3 + 0] = 0;
2413 pixels[pixelId * 3 + 1] = 255;
2414 pixels[pixelId * 3 + 2] = 0;
2415 }
2416 else
2417 {
2418 pixels[pixelId * 3 + 0] = 255;
2419 pixels[pixelId * 3 + 1] = 0;
2420 pixels[pixelId * 3 + 2] = 0;
2421 }
2422 }
2423
2424 GLuint pbo;
2425 glGenBuffers(1, &pbo);
2426 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2427 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2428
2429 // Update the color of the texture's upper-left 8x8 pixels, leaves the other pixels untouched.
2430 // glTexSubImage2D should take into account that the image is dirty.
2431 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2432 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2433 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2434
2435 setUpProgram();
2436
2437 glUseProgram(mProgram);
2438 glUniform1i(mTexture2DUniformLocation, 0);
2439 drawQuad(mProgram, "position", 0.5f);
2440 glDeleteTextures(1, &tex2D);
2441 glDeleteBuffers(1, &pbo);
2442 EXPECT_GL_NO_ERROR();
2443 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
2444 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2445 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2446 }
2447
2448 // Test that glTexSubImage2D combined with a PBO works properly when glTexImage2D has
2449 // initialized the image with a luminance color
TEST_P(Texture2DTest,TexImageWithLuminancePBO)2450 TEST_P(Texture2DTest, TexImageWithLuminancePBO)
2451 {
2452 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2453
2454 int width = getWindowWidth();
2455 int height = getWindowHeight();
2456
2457 GLuint tex2D;
2458 glGenTextures(1, &tex2D);
2459 glActiveTexture(GL_TEXTURE0);
2460 glBindTexture(GL_TEXTURE_2D, tex2D);
2461
2462 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
2463 nullptr);
2464
2465 // Fill PBO with white, with middle one as grey
2466 std::vector<GLubyte> pixels(16 * 16);
2467 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2468 {
2469 if (pixelId == 8 * 7 + 7)
2470 {
2471 pixels[pixelId] = 128;
2472 }
2473 else
2474 {
2475 pixels[pixelId] = 255;
2476 }
2477 }
2478
2479 GLuint pbo;
2480 glGenBuffers(1, &pbo);
2481 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2482 glBufferData(GL_PIXEL_UNPACK_BUFFER, 16 * 16, pixels.data(), GL_STATIC_DRAW);
2483
2484 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2485 // glTexSubImage2D should take into account that the image is dirty.
2486 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2487 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2488 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2489
2490 setUpProgram();
2491
2492 glUseProgram(mProgram);
2493 glUniform1i(mTexture2DUniformLocation, 0);
2494 drawQuad(mProgram, "position", 0.5f);
2495 glDeleteTextures(1, &tex2D);
2496 glDeleteBuffers(1, &pbo);
2497 EXPECT_GL_NO_ERROR();
2498 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 255, 255, 255);
2499 EXPECT_PIXEL_NEAR(width / 2 - 1, height / 2 - 1, 128, 128, 128, 255, 1);
2500 }
2501
2502 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2503 // initialized the image with a RGB656 color
TEST_P(Texture2DTest,TexImageWithRGB565PBO)2504 TEST_P(Texture2DTest, TexImageWithRGB565PBO)
2505 {
2506 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2507 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2508
2509 int width = getWindowWidth();
2510 int height = getWindowHeight();
2511
2512 GLuint tex2D;
2513 glGenTextures(1, &tex2D);
2514 glActiveTexture(GL_TEXTURE0);
2515 glBindTexture(GL_TEXTURE_2D, tex2D);
2516
2517 // Fill PBO with red, with middle one as green
2518 std::vector<GLushort> pixels(16 * 16);
2519 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2520 {
2521 if (pixelId == 8 * 7 + 8)
2522 {
2523 pixels[pixelId] = 0x7E0;
2524 }
2525 else
2526 {
2527 pixels[pixelId] = 0xF800;
2528 }
2529 }
2530
2531 GLuint pbo;
2532 glGenBuffers(1, &pbo);
2533 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2534 glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2535
2536 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB565, 16, 16);
2537
2538 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2539 // glTexSubImage2D should take into account that the image is dirty.
2540 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
2541 reinterpret_cast<void *>(2));
2542 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2543 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2544
2545 setUpProgram();
2546
2547 glUseProgram(mProgram);
2548 glUniform1i(mTexture2DUniformLocation, 0);
2549 drawQuad(mProgram, "position", 0.5f);
2550 glDeleteTextures(1, &tex2D);
2551 glDeleteBuffers(1, &pbo);
2552 EXPECT_GL_NO_ERROR();
2553 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2554 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2555 }
2556
2557 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2558 // initialized the image with a RGBA4444 color
TEST_P(Texture2DTest,TexImageWithRGBA4444PBO)2559 TEST_P(Texture2DTest, TexImageWithRGBA4444PBO)
2560 {
2561 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2562 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2563
2564 int width = getWindowWidth();
2565 int height = getWindowHeight();
2566
2567 GLuint tex2D;
2568 glGenTextures(1, &tex2D);
2569 glActiveTexture(GL_TEXTURE0);
2570 glBindTexture(GL_TEXTURE_2D, tex2D);
2571
2572 // Fill PBO with red, with middle one as green
2573 std::vector<GLushort> pixels(16 * 16);
2574 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2575 {
2576 if (pixelId == 8 * 7 + 8)
2577 {
2578 pixels[pixelId] = 0xF0F;
2579 }
2580 else
2581 {
2582 pixels[pixelId] = 0xF00F;
2583 }
2584 }
2585
2586 GLuint pbo;
2587 glGenBuffers(1, &pbo);
2588 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2589 glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2590
2591 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA4, 16, 16);
2592
2593 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2594 // glTexSubImage2D should take into account that the image is dirty.
2595 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
2596 reinterpret_cast<void *>(2));
2597 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2598 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2599
2600 setUpProgram();
2601
2602 glUseProgram(mProgram);
2603 glUniform1i(mTexture2DUniformLocation, 0);
2604 drawQuad(mProgram, "position", 0.5f);
2605 glDeleteTextures(1, &tex2D);
2606 glDeleteBuffers(1, &pbo);
2607 EXPECT_GL_NO_ERROR();
2608 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2609 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2610 }
2611
2612 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
2613 // initialized the image with a RGBA5551 color
TEST_P(Texture2DTest,TexImageWithRGBA5551PBO)2614 TEST_P(Texture2DTest, TexImageWithRGBA5551PBO)
2615 {
2616 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2617 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2618
2619 int width = getWindowWidth();
2620 int height = getWindowHeight();
2621
2622 GLuint tex2D;
2623 glGenTextures(1, &tex2D);
2624 glActiveTexture(GL_TEXTURE0);
2625 glBindTexture(GL_TEXTURE_2D, tex2D);
2626
2627 // Fill PBO with red, with middle one as green
2628 std::vector<GLushort> pixels(16 * 16);
2629 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
2630 {
2631 if (pixelId == 8 * 7 + 7)
2632 {
2633 pixels[pixelId] = 0x7C1;
2634 }
2635 else
2636 {
2637 pixels[pixelId] = 0xF801;
2638 }
2639 }
2640
2641 GLuint pbo;
2642 glGenBuffers(1, &pbo);
2643 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2644 glBufferData(GL_PIXEL_UNPACK_BUFFER, 2 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
2645
2646 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB5_A1, 16, 16);
2647
2648 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
2649 // glTexSubImage2D should take into account that the image is dirty.
2650 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr);
2651 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2652 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2653
2654 setUpProgram();
2655
2656 glUseProgram(mProgram);
2657 glUniform1i(mTexture2DUniformLocation, 0);
2658 drawQuad(mProgram, "position", 0.5f);
2659 glDeleteTextures(1, &tex2D);
2660 glDeleteBuffers(1, &pbo);
2661 EXPECT_GL_NO_ERROR();
2662 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2663 EXPECT_PIXEL_EQ(width / 2 - 1, height / 2 - 1, 0, 255, 0, 255);
2664 }
2665
2666 // Test if the KHR debug label is set and passed to D3D correctly using glCopyTexImage2D.
TEST_P(Texture2DTest,TextureKHRDebugLabelWithCopyTexImage2D)2667 TEST_P(Texture2DTest, TextureKHRDebugLabelWithCopyTexImage2D)
2668 {
2669 GLTexture texture2D;
2670 glBindTexture(GL_TEXTURE_2D, texture2D);
2671
2672 // Create a texture and copy into, to initialize storage object.
2673 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 32, 32, 0);
2674
2675 // Set KHR Debug Label.
2676 std::string label = "TestKHR.DebugLabel";
2677 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
2678
2679 std::vector<char> labelBuf(label.length() + 1);
2680 GLsizei labelLengthBuf = 0;
2681
2682 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
2683 &labelLengthBuf, labelBuf.data());
2684
2685 EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
2686 EXPECT_STREQ(label.c_str(), labelBuf.data());
2687
2688 // Delete the texture.
2689 texture2D.reset();
2690 EXPECT_GL_NO_ERROR();
2691
2692 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
2693 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2694
2695 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
2696 &labelLengthBuf, labelBuf.data());
2697 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2698 }
2699
2700 // Test to call labeling API before the storage texture is created.
TEST_P(Texture2DTest,CallKHRDebugLabelBeforeTexStorageCreation)2701 TEST_P(Texture2DTest, CallKHRDebugLabelBeforeTexStorageCreation)
2702 {
2703 GLTexture texture2D;
2704 glBindTexture(GL_TEXTURE_2D, texture2D);
2705
2706 // Set label before texture storage creation.
2707 std::string label = "TestKHR.DebugLabel";
2708 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
2709
2710 // Create a texture and copy into, to initialize storage object.
2711 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 32, 32, 0);
2712
2713 std::vector<char> labelBuf(label.length() + 1);
2714 GLsizei labelLengthBuf = 0;
2715
2716 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
2717 &labelLengthBuf, labelBuf.data());
2718
2719 EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
2720 EXPECT_STREQ(label.c_str(), labelBuf.data());
2721
2722 // Delete the texture.
2723 texture2D.reset();
2724 EXPECT_GL_NO_ERROR();
2725
2726 glObjectLabelKHR(GL_TEXTURE, texture2D, -1, label.c_str());
2727 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2728
2729 glGetObjectLabelKHR(GL_TEXTURE, texture2D, static_cast<GLsizei>(labelBuf.size()),
2730 &labelLengthBuf, labelBuf.data());
2731 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2732 }
2733
2734 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
2735 // initialized the image with a depth-only format.
TEST_P(Texture2DTestES3,TexImageWithDepthPBO)2736 TEST_P(Texture2DTestES3, TexImageWithDepthPBO)
2737 {
2738 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2739 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2740
2741 // http://anglebug.com/5315
2742 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());
2743
2744 constexpr GLsizei kSize = 4;
2745
2746 // Set up the framebuffer.
2747 GLTexture colorTexture;
2748 glBindTexture(GL_TEXTURE_2D, colorTexture);
2749 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2750 ASSERT_GL_NO_ERROR();
2751
2752 GLTexture depthTexture;
2753 glBindTexture(GL_TEXTURE_2D, depthTexture);
2754 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, kSize, kSize);
2755 ASSERT_GL_NO_ERROR();
2756
2757 GLFramebuffer fbo;
2758 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2759 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2760 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
2761 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2762 ASSERT_GL_NO_ERROR();
2763
2764 // Clear depth to 0, ensuring the texture's image is allocated.
2765 glClearDepthf(0);
2766 glClearColor(0, 0, 0, 1);
2767 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2768 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2769
2770 // Fill depth with 1.0f.
2771 std::vector<GLushort> pixels(kSize * kSize);
2772 for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
2773 {
2774 pixels[pixelId] = 0xFFFF;
2775 }
2776
2777 GLuint pbo;
2778 glGenBuffers(1, &pbo);
2779 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2780 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
2781 GL_STATIC_DRAW);
2782 ASSERT_GL_NO_ERROR();
2783
2784 // Upload PBO data.
2785 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
2786 nullptr);
2787
2788 // If depth is not set to 1, rendering would fail.
2789 glEnable(GL_DEPTH_TEST);
2790 glDepthFunc(GL_LESS);
2791
2792 // Draw red
2793 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2794 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
2795 ASSERT_GL_NO_ERROR();
2796
2797 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2798 }
2799
2800 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
2801 // initialized the image with a stencil-only format.
TEST_P(Texture2DTestES3,TexImageWithStencilPBO)2802 TEST_P(Texture2DTestES3, TexImageWithStencilPBO)
2803 {
2804 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2805 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2806
2807 // http://anglebug.com/5315
2808 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());
2809
2810 // http://anglebug.com/5317
2811 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D());
2812
2813 constexpr GLsizei kSize = 4;
2814
2815 // Set up the framebuffer.
2816 GLTexture colorTexture;
2817 glBindTexture(GL_TEXTURE_2D, colorTexture);
2818 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2819 ASSERT_GL_NO_ERROR();
2820
2821 GLTexture stencilTexture;
2822 glBindTexture(GL_TEXTURE_2D, stencilTexture);
2823 glTexStorage2D(GL_TEXTURE_2D, 1, GL_STENCIL_INDEX8, kSize, kSize);
2824 ASSERT_GL_NO_ERROR();
2825
2826 GLFramebuffer fbo;
2827 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2828 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2829 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 0);
2830 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2831 ASSERT_GL_NO_ERROR();
2832
2833 // Clear stencil to 0, ensuring the texture's image is allocated.
2834 glClearStencil(0);
2835 glClearColor(0, 0, 0, 1);
2836 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2837 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2838
2839 // Fill stencil with 0x4E
2840 std::vector<GLubyte> pixels(kSize * kSize);
2841 for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
2842 {
2843 pixels[pixelId] = 0x4E;
2844 }
2845
2846 GLuint pbo;
2847 glGenBuffers(1, &pbo);
2848 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2849 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
2850 GL_STATIC_DRAW);
2851 ASSERT_GL_NO_ERROR();
2852
2853 // Upload PBO data.
2854 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
2855 nullptr);
2856 ASSERT_GL_NO_ERROR();
2857
2858 // If stencil is not set to 0x4E, rendering would fail.
2859 glEnable(GL_STENCIL_TEST);
2860 glStencilFunc(GL_EQUAL, 0x4E, 0xFF);
2861 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2862 glStencilMask(0xFF);
2863
2864 // Draw red
2865 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2866 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
2867 ASSERT_GL_NO_ERROR();
2868
2869 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2870 }
2871
2872 // Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2D has
2873 // initialized the image with a depth/stencil format.
TEST_P(Texture2DTestES3,TexImageWithDepthStencilPBO)2874 TEST_P(Texture2DTestES3, TexImageWithDepthStencilPBO)
2875 {
2876 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2877 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2878
2879 // http://anglebug.com/5313
2880 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
2881
2882 // http://anglebug.com/5315
2883 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());
2884
2885 // http://anglebug.com/5317
2886 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D());
2887
2888 constexpr GLsizei kSize = 4;
2889
2890 // Set up the framebuffer.
2891 GLTexture colorTexture;
2892 glBindTexture(GL_TEXTURE_2D, colorTexture);
2893 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2894 ASSERT_GL_NO_ERROR();
2895
2896 GLTexture depthStencilTexture;
2897 glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
2898 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
2899 ASSERT_GL_NO_ERROR();
2900
2901 GLFramebuffer fbo;
2902 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2903 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2904 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
2905 depthStencilTexture, 0);
2906 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2907 ASSERT_GL_NO_ERROR();
2908
2909 // Clear depth and stencil to 0, ensuring the texture's image is allocated.
2910 glClearDepthf(0);
2911 glClearStencil(0);
2912 glClearColor(0, 0, 0, 1);
2913 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2914 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2915
2916 // Fill depth with 1.0f and stencil with 0xD5
2917 std::vector<GLuint> pixels(kSize * kSize);
2918 for (size_t pixelId = 0; pixelId < pixels.size(); ++pixelId)
2919 {
2920 pixels[pixelId] = 0xFFFFFFD5;
2921 }
2922
2923 GLuint pbo;
2924 glGenBuffers(1, &pbo);
2925 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2926 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixels.size() * sizeof(pixels[0]), pixels.data(),
2927 GL_STATIC_DRAW);
2928 ASSERT_GL_NO_ERROR();
2929
2930 // Upload PBO data.
2931 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
2932 nullptr);
2933
2934 // If depth is not set to 1, rendering would fail.
2935 glEnable(GL_DEPTH_TEST);
2936 glDepthFunc(GL_LESS);
2937
2938 // If stencil is not set to 0xD5, rendering would fail.
2939 glEnable(GL_STENCIL_TEST);
2940 glStencilFunc(GL_EQUAL, 0xD5, 0xFF);
2941 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2942 glStencilMask(0xFF);
2943
2944 // Draw red
2945 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2946 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f);
2947 ASSERT_GL_NO_ERROR();
2948
2949 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
2950 }
2951
2952 // Test functionality of GL_ANGLE_yuv_internal_format while cycling through RGB and YUV sources
TEST_P(Texture2DTestES3,TexStorage2DCycleThroughYuvAndRgbSources)2953 TEST_P(Texture2DTestES3, TexStorage2DCycleThroughYuvAndRgbSources)
2954 {
2955 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
2956
2957 // Create YUV texture
2958 GLTexture yuvTexture;
2959 GLubyte yuvColor[6] = {40, 40, 40, 40, 240, 109};
2960 GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
2961 createImmutableTexture2D(yuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
2962 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, yuvColor);
2963
2964 // Create RGBA texture
2965 GLTexture rgbaTexture;
2966 GLubyte rgbaColor[4] = {0, 0, 255, 255};
2967 createImmutableTexture2D(rgbaTexture, 1, 1, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, 1, rgbaColor);
2968
2969 // Cycle through source textures
2970 // RGBA source
2971 verifyResults2D(rgbaTexture, rgbaColor);
2972 ASSERT_GL_NO_ERROR();
2973
2974 // YUV source
2975 verifyResults2D(yuvTexture, expectedRgbColor);
2976 ASSERT_GL_NO_ERROR();
2977
2978 // RGBA source
2979 verifyResults2D(rgbaTexture, rgbaColor);
2980 ASSERT_GL_NO_ERROR();
2981 }
2982
2983 // Test functionality of GL_ANGLE_yuv_internal_format with large number of YUV sources
TEST_P(Texture2DTestES3,TexStorage2DLargeYuvTextureCount)2984 TEST_P(Texture2DTestES3, TexStorage2DLargeYuvTextureCount)
2985 {
2986 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
2987
2988 constexpr uint32_t kTextureCount = 16;
2989
2990 // Create YUV texture
2991 GLTexture yuvTexture[kTextureCount];
2992 for (uint32_t i = 0; i < kTextureCount; i++)
2993 {
2994 // Create 2 plane YCbCr 420 texture
2995 createImmutableTexture2D(yuvTexture[i], 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
2996 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
2997 }
2998
2999 // Cycle through YUV source textures
3000 glUseProgram(mProgram);
3001 glUniform1i(mTexture2DUniformLocation, 0);
3002
3003 for (uint32_t i = 0; i < kTextureCount; i++)
3004 {
3005 glBindTexture(GL_TEXTURE_2D, yuvTexture[i]);
3006 drawQuad(mProgram, "position", 0.5f);
3007 ASSERT_GL_NO_ERROR();
3008 }
3009 }
3010
3011 // Test functionality of GL_ANGLE_yuv_internal_format with simultaneous use of multiple YUV sources
TEST_P(Texture2DTestES3,TexStorage2DSimultaneousUseOfMultipleYuvSourcesNoData)3012 TEST_P(Texture2DTestES3, TexStorage2DSimultaneousUseOfMultipleYuvSourcesNoData)
3013 {
3014 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3015
3016 // Create YUV texture
3017 // Create 2 plane YCbCr 420 texture
3018 GLTexture twoPlaneYuvTexture;
3019 createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3020 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
3021
3022 // Create 3 plane YCbCr 420 texture
3023 GLTexture threePlaneYuvTexture;
3024 createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
3025 GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
3026
3027 // Cycle through YUV source textures
3028 // Create program with 2 samplers
3029 const char *vertexShaderSource = getVertexShaderSource();
3030 const char *fragmentShaderSource = R"(#version 300 es
3031 precision highp float;
3032 uniform sampler2D tex0;
3033 uniform sampler2D tex1;
3034 in vec2 texcoord;
3035 out vec4 fragColor;
3036
3037 void main()
3038 {
3039 vec4 color0 = texture(tex0, texcoord);
3040 vec4 color1 = texture(tex1, texcoord);
3041 fragColor = color0 + color1;
3042 })";
3043
3044 ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
3045 glUseProgram(twoSamplersProgram);
3046 GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
3047 ASSERT_NE(-1, tex0Location);
3048 GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
3049 ASSERT_NE(-1, tex1Location);
3050
3051 glUniform1i(tex0Location, 0);
3052 glUniform1i(tex1Location, 1);
3053
3054 // Bind 2 plane YUV source
3055 glActiveTexture(GL_TEXTURE0);
3056 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
3057 ASSERT_GL_NO_ERROR();
3058
3059 // Bind 3 plane YUV source
3060 glActiveTexture(GL_TEXTURE1);
3061 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
3062 ASSERT_GL_NO_ERROR();
3063
3064 drawQuad(twoSamplersProgram, "position", 0.5f);
3065 ASSERT_GL_NO_ERROR();
3066
3067 // Switch active texture index and draw again
3068 // Bind 2 plane YUV source
3069 glActiveTexture(GL_TEXTURE1);
3070 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
3071 ASSERT_GL_NO_ERROR();
3072
3073 // Bind 3 plane YUV source
3074 glActiveTexture(GL_TEXTURE0);
3075 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
3076 ASSERT_GL_NO_ERROR();
3077
3078 drawQuad(twoSamplersProgram, "position", 0.5f);
3079 ASSERT_GL_NO_ERROR();
3080 }
3081
3082 // Test functional of GL_ANGLE_yuv_internal_format while cycling through YUV sources
TEST_P(Texture2DTestES3,TexStorage2DCycleThroughYuvSourcesNoData)3083 TEST_P(Texture2DTestES3, TexStorage2DCycleThroughYuvSourcesNoData)
3084 {
3085 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_yuv_internal_format"));
3086
3087 // Create YUV texture
3088 // Create 2 plane YCbCr 420 texture
3089 GLTexture twoPlaneYuvTexture;
3090 createImmutableTexture2D(twoPlaneYuvTexture, 2, 2, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
3091 GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
3092
3093 // Create 3 plane YCbCr 420 texture
3094 GLTexture threePlaneYuvTexture;
3095 createImmutableTexture2D(threePlaneYuvTexture, 2, 2, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
3096 GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, 1, nullptr);
3097
3098 // Cycle through YUV source textures
3099 glUseProgram(mProgram);
3100 glUniform1i(mTexture2DUniformLocation, 0);
3101
3102 // 2 plane YUV source
3103 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
3104 drawQuad(mProgram, "position", 0.5f);
3105 ASSERT_GL_NO_ERROR();
3106
3107 // 3 plane YUV source
3108 glBindTexture(GL_TEXTURE_2D, threePlaneYuvTexture);
3109 drawQuad(mProgram, "position", 0.5f);
3110 ASSERT_GL_NO_ERROR();
3111
3112 // 2 plane YUV source
3113 glBindTexture(GL_TEXTURE_2D, twoPlaneYuvTexture);
3114 drawQuad(mProgram, "position", 0.5f);
3115 ASSERT_GL_NO_ERROR();
3116 }
3117
3118 // Tests CopySubImage for float formats
TEST_P(Texture2DTest,CopySubImageFloat_R_R)3119 TEST_P(Texture2DTest, CopySubImageFloat_R_R)
3120 {
3121 testFloatCopySubImage(1, 1);
3122 }
3123
TEST_P(Texture2DTest,CopySubImageFloat_RG_R)3124 TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
3125 {
3126 testFloatCopySubImage(2, 1);
3127 }
3128
TEST_P(Texture2DTest,CopySubImageFloat_RG_RG)3129 TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
3130 {
3131 testFloatCopySubImage(2, 2);
3132 }
3133
TEST_P(Texture2DTest,CopySubImageFloat_RGB_R)3134 TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
3135 {
3136 testFloatCopySubImage(3, 1);
3137 }
3138
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RG)3139 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
3140 {
3141 testFloatCopySubImage(3, 2);
3142 }
3143
TEST_P(Texture2DTest,CopySubImageFloat_RGB_RGB)3144 TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
3145 {
3146 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
3147 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
3148
3149 testFloatCopySubImage(3, 3);
3150 }
3151
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_R)3152 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
3153 {
3154 testFloatCopySubImage(4, 1);
3155 }
3156
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RG)3157 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
3158 {
3159 testFloatCopySubImage(4, 2);
3160 }
3161
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGB)3162 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
3163 {
3164 testFloatCopySubImage(4, 3);
3165 }
3166
TEST_P(Texture2DTest,CopySubImageFloat_RGBA_RGBA)3167 TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
3168 {
3169 testFloatCopySubImage(4, 4);
3170 }
3171
3172 // Port of
3173 // https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
3174 // Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
3175 // handles GL_ALPHA
TEST_P(Texture2DTest,TextureNPOT_GL_ALPHA_UBYTE)3176 TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
3177 {
3178 const int npotTexSize = 5;
3179 const int potTexSize = 4; // Should be less than npotTexSize
3180 GLuint tex2D;
3181
3182 if (IsGLExtensionEnabled("GL_OES_texture_npot"))
3183 {
3184 // This test isn't applicable if texture_npot is enabled
3185 return;
3186 }
3187
3188 setUpProgram();
3189
3190 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
3191
3192 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
3193 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3194
3195 glActiveTexture(GL_TEXTURE0);
3196 glGenTextures(1, &tex2D);
3197 glBindTexture(GL_TEXTURE_2D, tex2D);
3198
3199 const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
3200
3201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3203
3204 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
3205 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
3206 GL_UNSIGNED_BYTE, pixels.data());
3207 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3208
3209 // Check that an NPOT texture on level 0 succeeds
3210 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
3211 GL_UNSIGNED_BYTE, pixels.data());
3212 EXPECT_GL_NO_ERROR();
3213
3214 // Check that generateMipmap fails on NPOT
3215 glGenerateMipmap(GL_TEXTURE_2D);
3216 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3217
3218 // Check that nothing is drawn if filtering is not correct for NPOT
3219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3223 glClear(GL_COLOR_BUFFER_BIT);
3224 drawQuad(mProgram, "position", 1.0f);
3225 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
3226
3227 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
3228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
3231 glClear(GL_COLOR_BUFFER_BIT);
3232 drawQuad(mProgram, "position", 1.0f);
3233 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
3234
3235 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
3236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3237 glClear(GL_COLOR_BUFFER_BIT);
3238 drawQuad(mProgram, "position", 1.0f);
3239 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
3240
3241 // Check that glTexImage2D for POT texture succeeds
3242 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
3243 pixels.data());
3244 EXPECT_GL_NO_ERROR();
3245
3246 // Check that generateMipmap for an POT texture succeeds
3247 glGenerateMipmap(GL_TEXTURE_2D);
3248 EXPECT_GL_NO_ERROR();
3249
3250 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
3251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3255 glClear(GL_COLOR_BUFFER_BIT);
3256 drawQuad(mProgram, "position", 1.0f);
3257 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
3258 EXPECT_GL_NO_ERROR();
3259 }
3260
3261 // Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
3262 // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
TEST_P(Texture2DTest,NPOTSubImageParameters)3263 TEST_P(Texture2DTest, NPOTSubImageParameters)
3264 {
3265 glActiveTexture(GL_TEXTURE0);
3266 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3267
3268 // Create an 8x8 (i.e. power-of-two) texture.
3269 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3272 glGenerateMipmap(GL_TEXTURE_2D);
3273
3274 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
3275 // This should always work, even if GL_OES_texture_npot isn't active.
3276 std::array<GLColor, 3 * 3> data;
3277 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
3278
3279 EXPECT_GL_NO_ERROR();
3280 }
3281
3282 // Regression test for https://crbug.com/1222516 to prevent integer overflow during validation.
TEST_P(Texture2DTest,SubImageValidationOverflow)3283 TEST_P(Texture2DTest, SubImageValidationOverflow)
3284 {
3285 glActiveTexture(GL_TEXTURE0);
3286 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3287
3288 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3289 EXPECT_GL_NO_ERROR();
3290
3291 glTexSubImage2D(GL_TEXTURE_2D, 0, -4, 0, 2147483647, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3292 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3293
3294 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, -4, 1, 2147483647, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3295 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3296 }
3297
3298 // Test to ensure that glTexStorage3D accepts ASTC sliced 3D. https://crbug.com/1060012
TEST_P(Texture3DTestES3,ImmutableASTCSliced3D)3299 TEST_P(Texture3DTestES3, ImmutableASTCSliced3D)
3300 {
3301 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_texture_compression_astc_sliced_3d"));
3302
3303 glBindTexture(GL_TEXTURE_3D, mTexture3D);
3304 glTexStorage3D(GL_TEXTURE_3D, 1, GL_COMPRESSED_RGBA_ASTC_4x4, 4, 4, 1);
3305 EXPECT_GL_NO_ERROR();
3306 }
3307
FillLevel(GLint level,GLuint width,GLuint height,const GLColor & color,bool cubemap,bool subTex)3308 void FillLevel(GLint level,
3309 GLuint width,
3310 GLuint height,
3311 const GLColor &color,
3312 bool cubemap,
3313 bool subTex)
3314 {
3315 std::vector<GLColor> pixels(width * height, color);
3316 std::vector<GLenum> targets;
3317 if (cubemap)
3318 {
3319 targets = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
3320 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
3321 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
3322 }
3323 else
3324 {
3325 targets = {GL_TEXTURE_2D};
3326 }
3327
3328 for (GLenum target : targets)
3329 {
3330 if (subTex)
3331 {
3332 glTexSubImage2D(target, level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
3333 pixels.data());
3334 }
3335 else
3336 {
3337 glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3338 pixels.data());
3339 }
3340 }
3341 }
3342
3343 // This is part of tests that webgl_conformance_vulkan_passthrough_tests
3344 // conformance/textures/misc/texture-size.html does
testTextureSize(int testCaseIndex)3345 void Texture2DTest::testTextureSize(int testCaseIndex)
3346 {
3347 std::array<GLColor, 6> kNewMipColors = {
3348 GLColor::green, GLColor::red, GLColor::blue,
3349 GLColor::yellow, GLColor::magenta, GLColor::cyan,
3350 };
3351 GLuint colorCount = 0;
3352
3353 setUpProgram();
3354
3355 constexpr char kVS[] =
3356 R"(precision highp float;
3357 attribute vec4 position;
3358 varying vec3 texcoord;
3359 void main()
3360 {
3361 gl_Position = position;
3362 texcoord = (position.xyz * 0.5) + 0.5;
3363 }
3364 )";
3365 constexpr char kFS[] =
3366 R"(precision mediump float;
3367 uniform samplerCube tex;
3368 varying vec3 texcoord;
3369 void main()
3370 {
3371 gl_FragColor = textureCube(tex, texcoord);
3372 })";
3373 ANGLE_GL_PROGRAM(programCubeMap, kVS, kFS);
3374 GLint textureCubeUniformLocation = glGetUniformLocation(programCubeMap, "tex");
3375 ASSERT_NE(-1, textureCubeUniformLocation);
3376 ASSERT_GL_NO_ERROR();
3377
3378 GLint max2DSize = 0;
3379 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
3380 GLint maxCubeMapSize = 0;
3381 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapSize);
3382 // Assuming 2048x2048xRGBA (22 mb with mips) will run on all WebGL platforms
3383 GLint max2DSquareSize = std::min(max2DSize, 2048);
3384 // I'd prefer this to be 2048 but that's 16 mb x 6 faces or 128 mb (with mips)
3385 // 1024 is 33.5 mb (with mips)
3386 maxCubeMapSize = std::min(maxCubeMapSize, 1024);
3387 ASSERT_GL_NO_ERROR();
3388
3389 for (GLint size = 1; size <= max2DSize; size *= 2)
3390 {
3391 bool cubeMap = testCaseIndex == 3;
3392 GLenum texTarget = cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
3393 GLuint program = cubeMap ? programCubeMap : mProgram;
3394 GLint texWidth = 0, texHeight = 0;
3395
3396 switch (testCaseIndex)
3397 {
3398 case 0:
3399 texWidth = size;
3400 texHeight = 1;
3401 break;
3402 case 1:
3403 texWidth = 1;
3404 texHeight = size;
3405 break;
3406 case 2:
3407 case 3:
3408 texWidth = size;
3409 texHeight = size;
3410 break;
3411 }
3412
3413 if (texWidth == texHeight && size > max2DSquareSize)
3414 {
3415 return;
3416 }
3417
3418 if (cubeMap && size > maxCubeMapSize)
3419 {
3420 return;
3421 }
3422
3423 GLTexture texture;
3424 glActiveTexture(GL_TEXTURE0);
3425 glBindTexture(texTarget, texture);
3426 FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
3427 glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3428 glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3429 glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3430 glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3431 ASSERT_GL_NO_ERROR();
3432
3433 glClear(GL_COLOR_BUFFER_BIT);
3434 ASSERT_GL_NO_ERROR();
3435
3436 glUseProgram(program);
3437 if (cubeMap)
3438 {
3439 glUniform1i(textureCubeUniformLocation, 0);
3440 }
3441 else
3442 {
3443 glUniform1i(mTexture2DUniformLocation, 0);
3444 }
3445
3446 drawQuad(program, "position", 1.0f);
3447 ASSERT_GL_NO_ERROR();
3448 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
3449
3450 colorCount = (colorCount + 1) % kNewMipColors.size();
3451 FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
3452 glGenerateMipmap(texTarget);
3453 ASSERT_GL_NO_ERROR();
3454
3455 glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3456 glClear(GL_COLOR_BUFFER_BIT);
3457 drawQuad(program, "position", 1.0f);
3458 ASSERT_GL_NO_ERROR();
3459 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
3460
3461 colorCount = (colorCount + 1) % kNewMipColors.size();
3462 FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, true);
3463 glGenerateMipmap(texTarget);
3464
3465 glClear(GL_COLOR_BUFFER_BIT);
3466 drawQuad(program, "position", 1.0f);
3467 ASSERT_GL_NO_ERROR();
3468 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
3469 }
3470 }
3471
3472 // Permutation 0 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase0)3473 TEST_P(Texture2DTest, TextureSizeCase0)
3474 {
3475 testTextureSize(0);
3476 }
3477
3478 // Permutation 1 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase1)3479 TEST_P(Texture2DTest, TextureSizeCase1)
3480 {
3481 testTextureSize(1);
3482 }
3483
3484 // Permutation 2 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase2)3485 TEST_P(Texture2DTest, TextureSizeCase2)
3486 {
3487 testTextureSize(2);
3488 }
3489
3490 // Permutation 3 of testTextureSize.
TEST_P(Texture2DTest,TextureSizeCase3)3491 TEST_P(Texture2DTest, TextureSizeCase3)
3492 {
3493 testTextureSize(3);
3494 }
3495
3496 // Test that drawing works correctly RGBA 3D texture
TEST_P(Texture3DTestES2,RGBA)3497 TEST_P(Texture3DTestES2, RGBA)
3498 {
3499 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3500
3501 // http://anglebug.com/5728
3502 ANGLE_SKIP_TEST_IF(IsOzone());
3503
3504 glActiveTexture(GL_TEXTURE0);
3505 glBindTexture(GL_TEXTURE_3D, mTexture3D);
3506 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
3507 std::vector<GLColor> texDataRed(1u * 1u * 1u, GLColor::red);
3508 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3509 texDataGreen.data());
3510 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3511 texDataRed.data());
3512 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3513 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3514
3515 EXPECT_GL_NO_ERROR();
3516
3517 drawQuad(mProgram, "position", 0.5f);
3518
3519 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3520 }
3521
3522 // Test that drawing works correctly Luminance 3D texture
TEST_P(Texture3DTestES2,Luminance)3523 TEST_P(Texture3DTestES2, Luminance)
3524 {
3525 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3526
3527 // http://anglebug.com/5728
3528 ANGLE_SKIP_TEST_IF(IsOzone());
3529
3530 glActiveTexture(GL_TEXTURE0);
3531 glBindTexture(GL_TEXTURE_3D, mTexture3D);
3532 std::vector<GLubyte> texData(2u * 2u * 2u, 125);
3533 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3534 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3535 texData.data());
3536 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3537 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3538
3539 EXPECT_GL_NO_ERROR();
3540
3541 drawQuad(mProgram, "position", 0.5f);
3542
3543 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(125, 125, 125, 255));
3544 }
3545
3546 // Test that drawing works correctly with glCopyTexSubImage3D
TEST_P(Texture3DTestES2,CopySubImageRGBA)3547 TEST_P(Texture3DTestES2, CopySubImageRGBA)
3548 {
3549 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3550
3551 // http://anglebug.com/5728
3552 ANGLE_SKIP_TEST_IF(IsOzone());
3553
3554 glClearColor(0, 0, 1, 1);
3555 glClear(GL_COLOR_BUFFER_BIT);
3556
3557 glActiveTexture(GL_TEXTURE0);
3558 glBindTexture(GL_TEXTURE_3D, mTexture3D);
3559 std::vector<GLColor> texDataRed(4u * 4u * 4u, GLColor::red);
3560 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3561 texDataRed.data());
3562 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3563 texDataRed.data());
3564 glTexImage3DOES(GL_TEXTURE_3D, 2, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3565 texDataRed.data());
3566 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
3567 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
3568 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3569 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3570
3571 EXPECT_GL_NO_ERROR();
3572
3573 glClearColor(0, 1, 0, 1);
3574 glClear(GL_COLOR_BUFFER_BIT);
3575 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3576
3577 glUseProgram(mProgram);
3578 glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
3579 drawQuad(mProgram, "position", 0.5f);
3580
3581 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3582 }
3583
TEST_P(Texture3DTestES2,CopySubImageLuminance)3584 TEST_P(Texture3DTestES2, CopySubImageLuminance)
3585 {
3586 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3587
3588 // http://anglebug.com/5728
3589 ANGLE_SKIP_TEST_IF(IsOzone());
3590
3591 glClearColor(1, 0, 0, 1);
3592 glClear(GL_COLOR_BUFFER_BIT);
3593
3594 glActiveTexture(GL_TEXTURE0);
3595 glBindTexture(GL_TEXTURE_3D, mTexture3D);
3596 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_LUMINANCE, 4, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3597 nullptr);
3598 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_LUMINANCE, 2, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3599 nullptr);
3600 glTexImage3DOES(GL_TEXTURE_3D, 2, GL_LUMINANCE, 1, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
3601 nullptr);
3602 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
3603 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
3604 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3605 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3606
3607 EXPECT_GL_NO_ERROR();
3608
3609 glClearColor(0, 1, 0, 1);
3610 glClear(GL_COLOR_BUFFER_BIT);
3611 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3612
3613 glUseProgram(mProgram);
3614 glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
3615 drawQuad(mProgram, "position", 0.5f);
3616
3617 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
3618 }
3619
TEST_P(Texture3DTestES2,CopySubImageAlpha)3620 TEST_P(Texture3DTestES2, CopySubImageAlpha)
3621 {
3622 ANGLE_SKIP_TEST_IF(!hasTexture3DExt());
3623
3624 // http://anglebug.com/5728
3625 ANGLE_SKIP_TEST_IF(IsOzone());
3626
3627 glClearColor(1, 0, 0, 0.5);
3628 glClear(GL_COLOR_BUFFER_BIT);
3629
3630 glActiveTexture(GL_TEXTURE0);
3631 glBindTexture(GL_TEXTURE_3D, mTexture3D);
3632 glTexImage3DOES(GL_TEXTURE_3D, 0, GL_ALPHA, 4, 4, 4, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
3633 glTexImage3DOES(GL_TEXTURE_3D, 1, GL_ALPHA, 2, 2, 2, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
3634 glTexImage3DOES(GL_TEXTURE_3D, 2, GL_ALPHA, 1, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
3635 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 0, 0, 0, 2, 2);
3636 glCopyTexSubImage3DOES(GL_TEXTURE_3D, 1, 0, 0, 1, 0, 0, 2, 2);
3637 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3638 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
3639
3640 EXPECT_GL_NO_ERROR();
3641
3642 glClearColor(0, 1, 0, 1);
3643 glClear(GL_COLOR_BUFFER_BIT);
3644 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3645
3646 glUseProgram(mProgram);
3647 glUniform1f(glGetUniformLocation(mProgram, "level"), 1);
3648 drawQuad(mProgram, "position", 0.5f);
3649
3650 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 128), 1.0);
3651 }
3652
3653 // Verify shrinking a texture with glTexStorage2D works correctly
TEST_P(Texture2DTestES3,ChangeTexSizeWithTexStorage)3654 TEST_P(Texture2DTestES3, ChangeTexSizeWithTexStorage)
3655 {
3656 // TODO: http://anglebug.com/5256
3657 ANGLE_SKIP_TEST_IF(IsWindows() && IsOpenGL());
3658
3659 constexpr uint32_t kSizeLarge = 128;
3660 constexpr uint32_t kSizeSmall = 64;
3661
3662 glActiveTexture(GL_TEXTURE0);
3663 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3664 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3665 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3666
3667 // Create the texture with 'large' dimensions
3668 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSizeLarge, kSizeLarge, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3669 nullptr);
3670 ASSERT_GL_NO_ERROR();
3671
3672 GLFramebuffer destFbo;
3673 glBindFramebuffer(GL_FRAMEBUFFER, destFbo);
3674 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
3675 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3676
3677 // Draw with the new texture so it's created in the back end
3678 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3679 glUseProgram(blueProgram);
3680 drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3681 ASSERT_GL_NO_ERROR();
3682 EXPECT_PIXEL_RECT_EQ(0, 0, kSizeLarge, kSizeLarge, GLColor::blue);
3683
3684 // Shrink the texture
3685 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
3686 ASSERT_GL_NO_ERROR();
3687
3688 // Create a source texture/FBO to blit from
3689 GLTexture sourceTex;
3690 glBindTexture(GL_TEXTURE_2D, sourceTex.get());
3691 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSizeSmall, kSizeSmall);
3692 ASSERT_GL_NO_ERROR();
3693 GLFramebuffer sourceFbo;
3694 glBindFramebuffer(GL_FRAMEBUFFER, sourceFbo);
3695 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTex, 0);
3696 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3697 // Fill the source texture with green
3698 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
3699 glUseProgram(greenProgram);
3700 drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3701 ASSERT_GL_NO_ERROR();
3702 EXPECT_PIXEL_RECT_EQ(0, 0, kSizeSmall, kSizeSmall, GLColor::green);
3703
3704 // Blit the source (green) to the destination
3705 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFbo);
3706 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFbo);
3707 glBlitFramebuffer(0, 0, kSizeSmall, kSizeSmall, 0, 0, kSizeSmall, kSizeSmall,
3708 GL_COLOR_BUFFER_BIT, GL_NEAREST);
3709 ASSERT_GL_NO_ERROR();
3710
3711 // Render to the default framebuffer sampling from the blited texture and verify it's green
3712 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3713 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3714 ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
3715 glUseProgram(texProgram);
3716 drawQuad(texProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3717 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
3718 }
3719
3720 // Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
3721 // TextureImpl and the texture is synced before being used in a draw call.
TEST_P(Texture2DTestES3,TextureImplPropogatesDirtyBits)3722 TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
3723 {
3724 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
3725 // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
3726 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
3727 // D3D Debug device reports an error. http://anglebug.com/3501
3728 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
3729 // Support copy from levels outside the image range. http://anglebug.com/4733
3730 ANGLE_SKIP_TEST_IF(IsVulkan());
3731
3732 // The workaround in the GL backend required to trigger this bug generates driver warning
3733 // messages.
3734 ScopedIgnorePlatformMessages ignoreMessages;
3735
3736 setUpProgram();
3737 glUseProgram(mProgram);
3738 glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
3739
3740 GLTexture dest;
3741 glBindTexture(GL_TEXTURE_2D, dest);
3742
3743 GLTexture source;
3744 glBindTexture(GL_TEXTURE_2D, source);
3745
3746 // Put data in mip 0 and 1
3747 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3748 GLColor::red.data());
3749 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3750 GLColor::green.data());
3751
3752 // Disable mipmapping so source is complete
3753 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3754 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3755
3756 // Force the dirty bits to be synchronized in source
3757 drawQuad(mProgram, "position", 1.0f);
3758
3759 // Copy from mip 1 of the source. In the GL backend this internally sets the base level to mip
3760 // 1 and sets a dirty bit.
3761 glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
3762 GL_FALSE, GL_FALSE);
3763
3764 // Draw again, assertions are generated if the texture has internal dirty bits at draw time
3765 drawQuad(mProgram, "position", 1.0f);
3766 }
3767
3768 // This test case changes the base level of a texture that's attached to a framebuffer, clears every
3769 // level to green, and then samples the texture when rendering. Test is taken from
3770 // https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
TEST_P(Texture2DTestES3,FramebufferTextureChangingBaselevel)3771 TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
3772 {
3773 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
3774 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
3775
3776 setUpProgram();
3777
3778 constexpr GLint width = 8;
3779 constexpr GLint height = 4;
3780
3781 GLTexture texture;
3782 glBindTexture(GL_TEXTURE_2D, texture);
3783 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3784 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3785 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3786 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3787
3788 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
3789 GLint level = 0;
3790 GLint levelW = width;
3791 GLint levelH = height;
3792 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3793 nullptr);
3794 while (levelW > 1 || levelH > 1)
3795 {
3796 ++level;
3797 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
3798 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
3799 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3800 nullptr);
3801 }
3802
3803 // Clear each level of the texture using an FBO. Change the base level to match the level used
3804 // for the FBO on each iteration.
3805 GLFramebuffer fbo;
3806 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3807 level = 0;
3808 levelW = width;
3809 levelH = height;
3810 while (levelW > 1 || levelH > 1)
3811 {
3812 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
3813 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
3814
3815 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
3816 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
3817
3818 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3819 EXPECT_GL_NO_ERROR();
3820
3821 glClearColor(0, 1, 0, 1);
3822 glClear(GL_COLOR_BUFFER_BIT);
3823
3824 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3825
3826 ++level;
3827 }
3828
3829 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3830 glViewport(0, 0, 16, 16);
3831 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3832
3833 drawQuad(mProgram, "position", 0.5f);
3834
3835 EXPECT_GL_NO_ERROR();
3836 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3837 }
3838
3839 // Test that changing the base level of a texture after redefining a level outside the mip-chain
3840 // preserves the other mips' data.
TEST_P(Texture2DBaseMaxTestES3,ExtendMipChainAfterRedefine)3841 TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
3842 {
3843 // http://anglebug.com/4699
3844 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
3845
3846 // http://anglebug.com/5153
3847 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && IsOSX());
3848
3849 GLFramebuffer framebuffer;
3850 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3851
3852 GLTexture texture;
3853 glBindTexture(GL_TEXTURE_2D, texture);
3854
3855 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
3856 fillMipData(mipData.data(), kMip0Size, kMipColors);
3857
3858 for (size_t mip = 1; mip < kMipCount; ++mip)
3859 {
3860 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
3861 GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
3862 }
3863
3864 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3865 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
3866 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3867
3868 // Mip 1 is green. Verify this.
3869 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
3870
3871 // http://anglebug.com/4709
3872 ANGLE_SKIP_TEST_IF(IsOpenGL() && (IsIntel() || IsAMD()) && IsWindows());
3873
3874 // Add mip 0 and rebase the mip chain.
3875 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3876 mipData.data() + getMipDataOffset(kMip0Size, 0));
3877 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3878
3879 // Mip 1 should still be green.
3880 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
3881
3882 // Verify the other mips too.
3883 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
3884 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3885 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[2]);
3886
3887 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
3888 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3889 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[3]);
3890
3891 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3892 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3893
3894 // http://anglebug.com/4704
3895 ANGLE_SKIP_TEST_IF(IsVulkan());
3896
3897 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
3898 }
3899
3900 // Test that changing the base level of a texture multiple times preserves the data.
TEST_P(Texture2DBaseMaxTestES3,PingPongBaseLevel)3901 TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevel)
3902 {
3903 testPingPongBaseLevel(false);
3904 }
TEST_P(Texture2DBaseMaxTestES3,PingPongBaseLevelImmutable)3905 TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevelImmutable)
3906 {
3907 testPingPongBaseLevel(true);
3908 }
testPingPongBaseLevel(bool immutable)3909 void Texture2DBaseMaxTestES3::testPingPongBaseLevel(bool immutable)
3910 {
3911 // http://anglebug.com/4710
3912 ANGLE_SKIP_TEST_IF(IsD3D());
3913
3914 // http://anglebug.com/4711
3915 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsAMD() && IsWindows());
3916
3917 // http://anglebug.com/4701
3918 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
3919
3920 initTest(immutable);
3921
3922 // Ping pong a few times.
3923 for (uint32_t tries = 0; tries < 2; ++tries)
3924 {
3925 // Rebase to different mips and verify mips.
3926 for (uint32_t base = 0; base < kMipCount; ++base)
3927 {
3928 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
3929 for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
3930 {
3931 setLodUniform(lod);
3932 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3933 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
3934 }
3935 }
3936
3937 // Rebase backwards and verify mips.
3938 for (uint32_t base = kMipCount - 2; base > 0; --base)
3939 {
3940 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
3941 for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
3942 {
3943 setLodUniform(lod);
3944 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3945 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
3946 }
3947 }
3948 }
3949 }
3950
3951 // Test that glTexSubImage2D after incompatibly redefining a mip level correctly applies the update
3952 // after the redefine data.
TEST_P(Texture2DBaseMaxTestES3,SubImageAfterRedefine)3953 TEST_P(Texture2DBaseMaxTestES3, SubImageAfterRedefine)
3954 {
3955 initTest(false);
3956
3957 // Test that all mips have the expected data initially (this makes sure the texture image is
3958 // created already).
3959 for (uint32_t lod = 0; lod < kMipCount; ++lod)
3960 {
3961 setLodUniform(lod);
3962 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
3963 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
3964 }
3965
3966 // Redefine every level, followed by a glTexSubImage2D
3967 const GLColor kNewMipColors[kMipCount] = {
3968 GLColor::yellow,
3969 GLColor::cyan,
3970 GLColor(127, 0, 0, 255),
3971 GLColor(0, 127, 0, 255),
3972 };
3973 std::array<GLColor, getTotalMipDataSize(kMip0Size * 2)> newMipData;
3974 fillMipData(newMipData.data(), kMip0Size * 2, kNewMipColors);
3975
3976 const GLColor kSubImageMipColors[kMipCount] = {
3977 GLColor(0, 0, 127, 255),
3978 GLColor(127, 127, 0, 255),
3979 GLColor(0, 127, 127, 255),
3980 GLColor(127, 0, 127, 255),
3981 };
3982 std::array<GLColor, getTotalMipDataSize(kMip0Size)> subImageMipData;
3983 fillMipData(subImageMipData.data(), kMip0Size, kSubImageMipColors);
3984
3985 for (size_t mip = 0; mip < kMipCount; ++mip)
3986 {
3987 // Redefine the level.
3988 size_t newMipSize = (kMip0Size * 2) >> mip;
3989 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, newMipSize, newMipSize, 0, GL_RGBA,
3990 GL_UNSIGNED_BYTE, newMipData.data() + getMipDataOffset(kMip0Size * 2, mip));
3991
3992 // Immediately follow that with a subimage update.
3993 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
3994 GL_UNSIGNED_BYTE,
3995 subImageMipData.data() + getMipDataOffset(kMip0Size, mip));
3996 }
3997 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
3998
3999 // Test that the texture looks as expected.
4000 const int w = getWindowWidth() - 1;
4001 const int h = getWindowHeight() - 1;
4002 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4003 {
4004 setLodUniform(lod);
4005 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4006 EXPECT_PIXEL_COLOR_EQ(0, 0, kSubImageMipColors[lod]);
4007 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColors[lod]);
4008 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColors[lod]);
4009 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColors[lod]);
4010 }
4011 }
4012
4013 // Test that incompatibly redefining a level then redefining it back to its original size works.
TEST_P(Texture2DBaseMaxTestES3,IncompatiblyRedefineLevelThenRevert)4014 TEST_P(Texture2DBaseMaxTestES3, IncompatiblyRedefineLevelThenRevert)
4015 {
4016 initTest(false);
4017
4018 // Test that all mips have the expected data initially (this makes sure the texture image is
4019 // created already).
4020 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4021 {
4022 setLodUniform(lod);
4023 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4024 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4025 }
4026
4027 // Redefine Mip 1 to be larger.
4028 constexpr size_t kLargeMip1Size = getMipDataSize(kMip0Size * 2, 1);
4029 std::array<GLColor, kLargeMip1Size> interimMipData;
4030 std::fill(interimMipData.data(), interimMipData.data() + kLargeMip1Size, GLColor::yellow);
4031
4032 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4033 interimMipData.data());
4034
4035 // Redefine Mip 1 back to its original size.
4036 constexpr size_t kNormalMip1Size = getMipDataSize(kMip0Size, 1);
4037 std::array<GLColor, kLargeMip1Size> newMipData;
4038 std::fill(newMipData.data(), newMipData.data() + kNormalMip1Size, GLColor::cyan);
4039
4040 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size / 2, kMip0Size / 2, 0, GL_RGBA,
4041 GL_UNSIGNED_BYTE, newMipData.data());
4042
4043 // Verify texture colors.
4044 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4045 {
4046 setLodUniform(lod);
4047 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4048 EXPECT_PIXEL_COLOR_EQ(0, 0, lod == 1 ? GLColor::cyan : kMipColors[lod]);
4049 }
4050 }
4051
4052 // Test that redefining every level of a texture to another format works. The format uses more
4053 // bits per component, to ensure alignment requirements for the new format are taken into account.
TEST_P(Texture2DBaseMaxTestES3,RedefineEveryLevelToAnotherFormat)4054 TEST_P(Texture2DBaseMaxTestES3, RedefineEveryLevelToAnotherFormat)
4055 {
4056 initTest(false);
4057
4058 // Test that all mips have the expected data initially (this makes sure the texture image is
4059 // created already).
4060 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4061 {
4062 setLodUniform(lod);
4063 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4064 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4065 }
4066
4067 const GLColor32F kNewMipColors[kMipCount] = {
4068 GLColor32F(1.0, 1.0, 0.0, 1.0f),
4069 GLColor32F(1.0, 0.0, 1.0, 1.0f),
4070 GLColor32F(0.0, 1.0, 1.0, 1.0f),
4071 GLColor32F(1.0, 1.0, 1.0, 1.0f),
4072 };
4073
4074 std::array<GLColor32F, getTotalMipDataSize(kMip0Size)> newMipData;
4075 fillMipData(newMipData.data(), kMip0Size, kNewMipColors);
4076
4077 // Redefine every level with the new format.
4078 for (size_t mip = 0; mip < kMipCount; ++mip)
4079 {
4080 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA32F, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
4081 GL_FLOAT, newMipData.data() + getMipDataOffset(kMip0Size, mip));
4082 }
4083
4084 // Verify texture colors.
4085 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4086 {
4087 setLodUniform(lod);
4088 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4089
4090 GLColor32F mipColor32F = kNewMipColors[lod];
4091 GLColor mipColor(static_cast<GLubyte>(std::roundf(mipColor32F.R * 255)),
4092 static_cast<GLubyte>(std::roundf(mipColor32F.G * 255)),
4093 static_cast<GLubyte>(std::roundf(mipColor32F.B * 255)),
4094 static_cast<GLubyte>(std::roundf(mipColor32F.A * 255)));
4095
4096 EXPECT_PIXEL_COLOR_EQ(0, 0, mipColor);
4097 }
4098 }
4099
4100 // Test that generating mipmaps after change base level.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRebase)4101 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRebase)
4102 {
4103 // http://anglebug.com/5880
4104 ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsDesktopOpenGL());
4105
4106 testGenerateMipmapAfterRebase(false);
4107 }
4108
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRebaseImmutable)4109 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRebaseImmutable)
4110 {
4111 // http://anglebug.com/4710
4112 ANGLE_SKIP_TEST_IF(IsD3D());
4113 // http://anglebug.com/5798
4114 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA());
4115 // http://anglebug.com/5880
4116 ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsDesktopOpenGL());
4117
4118 testGenerateMipmapAfterRebase(true);
4119 }
4120
testGenerateMipmapAfterRebase(bool immutable)4121 void Texture2DBaseMaxTestES3::testGenerateMipmapAfterRebase(bool immutable)
4122 {
4123 initTest(immutable);
4124
4125 // Test that all mips have the expected data initially (this makes sure the texture image is
4126 // created already).
4127 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4128 {
4129 setLodUniform(lod);
4130 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4131 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4132 }
4133
4134 // Update level 1 (any level would do other than 0) with new data
4135 const GLColor kNewMipColor = GLColor::yellow;
4136 std::array<GLColor, getMipDataSize(kMip0Size >> 1, 0)> newMipData;
4137 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
4138
4139 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kMip0Size >> 1, kMip0Size >> 1, GL_RGBA,
4140 GL_UNSIGNED_BYTE, newMipData.data());
4141
4142 // Change base level and max level and then generate mipmaps. This should redefine level 1 and 2
4143 // with kNewMipColor and leave levels 0 and 3 unchanged.
4144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 2);
4146 glGenerateMipmap(GL_TEXTURE_2D);
4147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
4149
4150 // Test that the texture looks as expected.
4151 const int w = getWindowWidth() - 1;
4152 const int h = getWindowHeight() - 1;
4153 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4154 {
4155 setLodUniform(lod);
4156 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4157 if (lod == 0)
4158 {
4159 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4160 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]);
4161 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]);
4162 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]);
4163 }
4164 else if (lod == kMipCount - 1)
4165 {
4166 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4167 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]);
4168 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]);
4169 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]);
4170 }
4171 else
4172 {
4173 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
4174 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
4175 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
4176 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
4177 }
4178 }
4179 }
4180
4181 // Test that generating mipmaps after incompatibly redefining a level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefine)4182 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefine)
4183 {
4184 initTest(false);
4185
4186 // Test that all mips have the expected data initially (this makes sure the texture image is
4187 // created already).
4188 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4189 {
4190 setLodUniform(lod);
4191 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4192 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4193 }
4194
4195 // Redefine level 1 (any level would do other than 0) to an incompatible size, say the same size
4196 // as level 0.
4197 const GLColor kNewMipColor = GLColor::yellow;
4198 std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
4199 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
4200
4201 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4202 newMipData.data());
4203
4204 // Generate mipmaps. This should redefine level 1 back to being compatible with level 0.
4205 glGenerateMipmap(GL_TEXTURE_2D);
4206
4207 // Test that the texture looks as expected.
4208 const int w = getWindowWidth() - 1;
4209 const int h = getWindowHeight() - 1;
4210 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4211 {
4212 setLodUniform(lod);
4213 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4214 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
4215 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]);
4216 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]);
4217 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]);
4218 }
4219 }
4220
4221 // Test that generating mipmaps after incompatibly redefining a level while simultaneously changing
4222 // the base level works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefineAndRebase)4223 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefineAndRebase)
4224 {
4225 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
4226
4227 // http://crbug.com/1100613
4228 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
4229
4230 // TODO(anglebug.com/5360): Failing on ARM-based Apple DTKs.
4231 ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsDesktopOpenGL());
4232
4233 initTest(false);
4234
4235 // Test that all mips have the expected data initially (this makes sure the texture image is
4236 // created already).
4237 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4238 {
4239 setLodUniform(lod);
4240 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4241 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]) << lod;
4242 }
4243
4244 // Redefine level 2 to an incompatible size, say the same size as level 0.
4245 const GLColor kNewMipColor = GLColor::yellow;
4246 std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
4247 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
4248
4249 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4250 newMipData.data());
4251
4252 // Set base level of the texture to 1 then generate mipmaps. Level 2 that's redefined should
4253 // go back to being compatibly defined.
4254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4255 glGenerateMipmap(GL_TEXTURE_2D);
4256
4257 // Test that the texture looks as expected.
4258 const int w = getWindowWidth() - 1;
4259 const int h = getWindowHeight() - 1;
4260 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4261 {
4262 setLodUniform(lod);
4263 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4264 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]) << lod;
4265 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[1]) << lod;
4266 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[1]) << lod;
4267 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[1]) << lod;
4268 }
4269
4270 // Redefine level 1 (current base level) to an incompatible size.
4271 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4272 newMipData.data());
4273
4274 // Set base level of the texture back to 0 then generate mipmaps. Level 1 should go back to
4275 // being compatibly defined.
4276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4277 glGenerateMipmap(GL_TEXTURE_2D);
4278
4279 // Test that the texture looks as expected.
4280 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4281 {
4282 setLodUniform(lod);
4283 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4284 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]) << lod;
4285 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[0]) << lod;
4286 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[0]) << lod;
4287 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[0]) << lod;
4288 }
4289 }
4290
4291 // Test that generating mipmaps after incompatibly redefining the base level of the texture works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBase)4292 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBase)
4293 {
4294 initTest(false);
4295
4296 // Test that all mips have the expected data initially (this makes sure the texture image is
4297 // created already).
4298 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4299 {
4300 setLodUniform(lod);
4301 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4302 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4303 }
4304
4305 // Redefine level 0 to an incompatible size.
4306 const GLColor kNewMipColor = GLColor::yellow;
4307 std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
4308 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
4309
4310 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
4311 GL_UNSIGNED_BYTE, newMipData.data());
4312
4313 // Generate mipmaps.
4314 glGenerateMipmap(GL_TEXTURE_2D);
4315
4316 // Test that the texture looks as expected.
4317 const int w = getWindowWidth() - 1;
4318 const int h = getWindowHeight() - 1;
4319 for (uint32_t lod = 0; lod < kMipCount + 1; ++lod)
4320 {
4321 setLodUniform(lod);
4322 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4323 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
4324 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
4325 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
4326 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
4327 }
4328 }
4329
4330 // Test that generating mipmaps after incompatibly redefining the base level while simultaneously
4331 // changing MAX_LEVEL works.
TEST_P(Texture2DBaseMaxTestES3,GenerateMipmapAfterRedefiningBaseAndChangingMax)4332 TEST_P(Texture2DBaseMaxTestES3, GenerateMipmapAfterRedefiningBaseAndChangingMax)
4333 {
4334 initTest(false);
4335
4336 // Test that all mips have the expected data initially (this makes sure the texture image is
4337 // created already).
4338 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4339 {
4340 setLodUniform(lod);
4341 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4342 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4343 }
4344
4345 // Redefine level 0 to an incompatible size.
4346 const GLColor kNewMipColor = GLColor::yellow;
4347 std::array<GLColor, getMipDataSize(kMip0Size * 2, 0)> newMipData;
4348 std::fill(newMipData.begin(), newMipData.end(), kNewMipColor);
4349
4350 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size * 2, kMip0Size * 2, 0, GL_RGBA,
4351 GL_UNSIGNED_BYTE, newMipData.data());
4352
4353 // Set max level of the texture to 2 then generate mipmaps.
4354 constexpr uint32_t kMaxLevel = 2;
4355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMaxLevel);
4356 glGenerateMipmap(GL_TEXTURE_2D);
4357
4358 // Test that the texture looks as expected.
4359 const int w = getWindowWidth() - 1;
4360 const int h = getWindowHeight() - 1;
4361 for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
4362 {
4363 setLodUniform(lod);
4364 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4365 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColor);
4366 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColor);
4367 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColor);
4368 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColor);
4369 }
4370 }
4371
4372 // Test that stage invalid texture levels work.
TEST_P(Texture2DBaseMaxTestES3,StageInvalidLevels)4373 TEST_P(Texture2DBaseMaxTestES3, StageInvalidLevels)
4374 {
4375 constexpr uint32_t kMaxLevel = 2;
4376 const GLColor kMipColor[kMaxLevel + 1] = {GLColor::red, GLColor::green, GLColor::blue};
4377
4378 initTest(false);
4379
4380 GLTexture texture;
4381 glBindTexture(GL_TEXTURE_2D, texture);
4382
4383 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4384 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4385 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
4386 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataCyan.data());
4387 setLodUniform(0);
4388 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4389 EXPECT_GL_NO_ERROR();
4390
4391 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4392 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4393 texDataGreen.data());
4394 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4395 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4396 EXPECT_GL_NO_ERROR();
4397
4398 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
4399 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4400 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4401 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4402
4403 // Test that the texture looks as expected.
4404 const int w = getWindowWidth() - 1;
4405 const int h = getWindowHeight() - 1;
4406 for (uint32_t lod = 0; lod <= kMaxLevel; ++lod)
4407 {
4408 setLodUniform(lod);
4409 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4410 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColor[lod]);
4411 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColor[lod]);
4412 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColor[lod]);
4413 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColor[lod]);
4414 }
4415 }
4416
4417 // Test redefine a mutable texture into an immutable texture.
TEST_P(Texture2DBaseMaxTestES3,RedefineMutableToImmutable)4418 TEST_P(Texture2DBaseMaxTestES3, RedefineMutableToImmutable)
4419 {
4420 // http://anglebug.com/4710
4421 ANGLE_SKIP_TEST_IF(IsD3D());
4422
4423 // http://anglebug.com/4701
4424 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
4425
4426 constexpr uint32_t kBaseLevel = 1;
4427 const GLColor kNewMipColors[kMipCount] = {
4428 GLColor::yellow,
4429 GLColor::cyan,
4430 GLColor::white,
4431 GLColor(127u, 127u, 127u, 255u),
4432 };
4433
4434 initTest(false);
4435
4436 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, kBaseLevel);
4437
4438 // Test that all mips have the expected data
4439 for (uint32_t lod = kBaseLevel; lod < kMipCount; ++lod)
4440 {
4441 setLodUniform(lod - kBaseLevel);
4442 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4443 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4444 }
4445
4446 glTexStorage2D(GL_TEXTURE_2D, kMipCount, GL_RGBA8, kMip0Size, kMip0Size);
4447 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
4448 fillMipData(mipData.data(), kMip0Size, kNewMipColors);
4449 for (size_t mip = 0; mip < kMipCount; ++mip)
4450 {
4451 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
4452 GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
4453 }
4454
4455 // Test that all enabled mips have the expected data
4456 for (uint32_t lod = kBaseLevel; lod < kMipCount; ++lod)
4457 {
4458 setLodUniform(lod - kBaseLevel);
4459 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4460 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[lod]);
4461 }
4462
4463 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4464 for (uint32_t lod = 0; lod < kBaseLevel; ++lod)
4465 {
4466 setLodUniform(lod);
4467 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4468 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[lod]);
4469 }
4470 }
4471
4472 // Test that redefine a level with incompatible size beyond the max level.
TEST_P(Texture2DBaseMaxTestES3,RedefineIncompatibleLevelBeyondMaxLevel)4473 TEST_P(Texture2DBaseMaxTestES3, RedefineIncompatibleLevelBeyondMaxLevel)
4474 {
4475 initTest(false);
4476
4477 // Test that all mips have the expected data initially (this makes sure the texture image is
4478 // created already).
4479 for (uint32_t lod = 0; lod < kMipCount; ++lod)
4480 {
4481 setLodUniform(lod);
4482 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4483 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4484 }
4485
4486 uint32_t maxLevel = 1;
4487 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel);
4488
4489 // Update level 0
4490 const GLColor kNewMipLevle0Color = GLColor::yellow;
4491 std::array<GLColor, getMipDataSize(kMip0Size, 0)> newMipData;
4492 std::fill(newMipData.begin(), newMipData.end(), kNewMipLevle0Color);
4493 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kMip0Size, kMip0Size, GL_RGBA, GL_UNSIGNED_BYTE,
4494 newMipData.data());
4495
4496 // Update level 2 with incompatible data
4497 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4498 newMipData.data());
4499 EXPECT_GL_NO_ERROR();
4500
4501 // Test that the texture looks as expected.
4502 const int w = getWindowWidth() - 1;
4503 const int h = getWindowHeight() - 1;
4504 for (uint32_t lod = 0; lod < maxLevel; ++lod)
4505 {
4506 setLodUniform(lod);
4507 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
4508 if (lod == 0)
4509 {
4510 EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipLevle0Color);
4511 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipLevle0Color);
4512 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipLevle0Color);
4513 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipLevle0Color);
4514 }
4515 else
4516 {
4517 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
4518 EXPECT_PIXEL_COLOR_EQ(w, 0, kMipColors[lod]);
4519 EXPECT_PIXEL_COLOR_EQ(0, h, kMipColors[lod]);
4520 EXPECT_PIXEL_COLOR_EQ(w, h, kMipColors[lod]);
4521 }
4522 }
4523 }
4524
4525 // Port test from web_gl/conformance2/textures/misc/fuzz-545-immutable-tex-render-feedback.html.
4526 // What this tries to do is create a render feedback loop and ensure it is not crashing.
TEST_P(Texture2DBaseMaxTestES3,Fuzz545ImmutableTexRenderFeedback)4527 TEST_P(Texture2DBaseMaxTestES3, Fuzz545ImmutableTexRenderFeedback)
4528 {
4529 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4530
4531 constexpr uint32_t MIPS = 2;
4532 constexpr uint32_t SIZE = 10;
4533
4534 GLTexture immutTex;
4535 glBindTexture(GL_TEXTURE_2D, immutTex);
4536 glTexStorage2D(GL_TEXTURE_2D, MIPS, GL_RGBA8, SIZE, SIZE);
4537
4538 GLTexture mutTex;
4539 glBindTexture(GL_TEXTURE_2D, mutTex);
4540 for (uint32_t mip = 0; mip < MIPS; mip++)
4541 {
4542 const uint32_t size = SIZE >> mip;
4543 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4544 nullptr);
4545 }
4546
4547 constexpr GLenum MAG_FILTERS[] = {GL_LINEAR, GL_NEAREST};
4548 constexpr GLenum MIN_FILTERS[] = {
4549 GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST,
4550 GL_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_NEAREST};
4551
4552 GLFramebuffer fbo;
4553 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4554
4555 const GLuint texs[] = {immutTex, mutTex};
4556 for (const GLuint tex : texs)
4557 {
4558 glBindTexture(GL_TEXTURE_2D, tex);
4559
4560 for (GLuint level_prime_base = 0; level_prime_base < (MIPS + 1); level_prime_base++)
4561 { // `level_base` in GLES
4562 // ES 3.0.6 p150
4563 GLuint _level_base = level_prime_base;
4564 if (tex == immutTex)
4565 {
4566 _level_base = std::min(_level_base, MIPS - 1);
4567 }
4568 const GLuint level_base = _level_base;
4569
4570 for (GLuint _level_prime_max = (level_prime_base - 1); _level_prime_max < (MIPS + 2);
4571 _level_prime_max++)
4572 { // `q` in GLES
4573 if (_level_prime_max < 0)
4574 continue;
4575 if (_level_prime_max == (MIPS + 1))
4576 {
4577 _level_prime_max = 10000; // This is the default, after all!
4578 }
4579 const GLuint level_prime_max = _level_prime_max;
4580
4581 // ES 3.0.6 p150
4582 GLuint _level_max = level_prime_max;
4583 if (tex == immutTex)
4584 {
4585 _level_max = std::min(std::max(level_base, level_prime_max), MIPS - 1);
4586 }
4587 const GLuint level_max = _level_max;
4588
4589 const GLuint p = std::floor((float)std::log2(SIZE)) + level_base;
4590 const GLuint q = std::min(p, level_max);
4591
4592 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level_prime_base);
4593 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level_prime_max);
4594
4595 const bool mipComplete = (q <= MIPS - 1);
4596
4597 for (const GLenum minFilter : MIN_FILTERS)
4598 {
4599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
4600
4601 for (const GLenum magFilter : MAG_FILTERS)
4602 {
4603 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
4604
4605 for (GLuint dstMip = 0; dstMip < (MIPS + 1); dstMip++)
4606 {
4607 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
4608 GL_TEXTURE_2D, tex, dstMip);
4609
4610 // ES3.0 p213-214
4611 bool fbComplete = true;
4612
4613 // * "The width and height of `image` are non-zero"
4614 fbComplete &= (0 <= dstMip && dstMip <= MIPS - 1);
4615
4616 if (tex != immutTex)
4617 { // "...does not name an immutable-format texture..."
4618 // * "...the value of [level] must be in the range `[level_base,
4619 // q]`"
4620 fbComplete &= (level_base <= dstMip && dstMip <= q);
4621
4622 // * "...the value of [level] is not `level_base`, then the texture
4623 // must be mipmap complete"
4624 if (dstMip != level_base)
4625 {
4626 fbComplete &= mipComplete;
4627 }
4628 }
4629
4630 // -
4631 GLenum expectError = 0;
4632 GLenum expectStatus = GL_FRAMEBUFFER_COMPLETE;
4633 if (!fbComplete)
4634 {
4635 expectStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
4636 expectError = GL_INVALID_FRAMEBUFFER_OPERATION;
4637 }
4638
4639 // -
4640 EXPECT_GLENUM_EQ(expectStatus,
4641 glCheckFramebufferStatus(GL_FRAMEBUFFER));
4642
4643 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
4644 EXPECT_EQ(expectError, glGetError());
4645 }
4646 }
4647 }
4648 }
4649 }
4650 }
4651 }
4652
4653 // Test to check that texture completeness is determined correctly when the texture base level is
4654 // greater than 0, and also that level 0 is not sampled when base level is greater than 0.
TEST_P(Texture2DTestES3,DrawWithBaseLevel1)4655 TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
4656 {
4657 glActiveTexture(GL_TEXTURE0);
4658 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4659
4660 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
4661 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4662 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4663 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4664 texDataGreen.data());
4665 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4666 texDataGreen.data());
4667 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4668 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4669 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4670
4671 EXPECT_GL_NO_ERROR();
4672
4673 drawQuad(mProgram, "position", 0.5f);
4674
4675 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4676 }
4677
4678 // Test basic GL_EXT_copy_image copy without any bound textures
TEST_P(Texture2DTestES3,CopyImage)4679 TEST_P(Texture2DTestES3, CopyImage)
4680 {
4681 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
4682
4683 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
4684 GLTexture srcTexture;
4685 GLTexture destTexture;
4686
4687 glActiveTexture(GL_TEXTURE0);
4688 glBindTexture(GL_TEXTURE_2D, destTexture);
4689 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4690 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4691 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4693 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4694
4695 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
4696 glBindTexture(GL_TEXTURE_2D, srcTexture);
4697 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4698 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4699 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4700 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4701 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4702 texDataGreen.data());
4703
4704 glBindTexture(GL_TEXTURE_2D, 0);
4705
4706 // copy
4707 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 2, 2, 0, destTexture, GL_TEXTURE_2D, 0, 2,
4708 2, 0, 2, 2, 1);
4709
4710 glBindTexture(GL_TEXTURE_2D, destTexture);
4711
4712 EXPECT_GL_NO_ERROR();
4713
4714 glViewport(0, 0, 4, 4);
4715 drawQuad(mProgram, "position", 0.5f);
4716 EXPECT_GL_NO_ERROR();
4717
4718 EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
4719 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
4720 EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
4721 }
4722
4723 // Test GL_EXT_copy_image compressed texture copy with mipmaps smaller than the block size
TEST_P(Texture2DTestES3,CopyCompressedImageMipMaps)4724 TEST_P(Texture2DTestES3, CopyCompressedImageMipMaps)
4725 {
4726 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
4727 // TODO(http://anglebug.com/5634): Fix calls to vkCmdCopyBufferToImage() with images smaller
4728 // than the compressed format block size.
4729 ANGLE_SKIP_TEST_IF(isAllocateNonZeroMemoryEnabled());
4730
4731 constexpr uint32_t kSize = 4;
4732 constexpr size_t kNumLevels = 3;
4733 const uint8_t CompressedImageETC1[8] = {0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0};
4734
4735 GLTexture srcTexture;
4736 glBindTexture(GL_TEXTURE_2D, srcTexture);
4737 for (size_t level = 0; level < kNumLevels; ++level)
4738 {
4739 glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
4740 kSize >> level, 0, 8, CompressedImageETC1);
4741 EXPECT_GL_NO_ERROR();
4742 }
4743
4744 GLTexture destTexture;
4745 glBindTexture(GL_TEXTURE_2D, destTexture);
4746 for (size_t level = 0; level < kNumLevels; ++level)
4747 {
4748 glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, kSize >> level,
4749 kSize >> level, 0, 8, nullptr);
4750 EXPECT_GL_NO_ERROR();
4751 }
4752
4753 glBindTexture(GL_TEXTURE_2D, 0);
4754
4755 // copy
4756 for (size_t level = 0; level < kNumLevels; ++level)
4757 {
4758 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, level, 0, 0, 0, destTexture, GL_TEXTURE_2D,
4759 level, 0, 0, 0, kSize >> level, kSize >> level, 1);
4760 EXPECT_GL_NO_ERROR();
4761 }
4762 }
4763
4764 // Test GL_EXT_copy_image copy with a non-zero base level
TEST_P(Texture2DTestES3,CopyImageBaseLevel1)4765 TEST_P(Texture2DTestES3, CopyImageBaseLevel1)
4766 {
4767 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
4768
4769 std::vector<GLColor> texDataBlack(8u * 8u, GLColor::black);
4770 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
4771 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
4772 std::vector<GLColor> texDataBlue(4u * 4u, GLColor::blue);
4773
4774 GLTexture srcTexture;
4775 GLTexture destTexture;
4776
4777 glActiveTexture(GL_TEXTURE0);
4778 glBindTexture(GL_TEXTURE_2D, destTexture);
4779 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4780 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4781 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4782 texDataBlack.data());
4783 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4784 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4785 texDataGreen.data());
4786 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
4787 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4788 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4789
4790 glBindTexture(GL_TEXTURE_2D, srcTexture);
4791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4793 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4794 texDataBlack.data());
4795 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4796 texDataGreen.data());
4797 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataBlue.data());
4798 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4799 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4800 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4801
4802 glBindTexture(GL_TEXTURE_2D, 0);
4803
4804 // copy
4805 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 1, 2, 2, 0, destTexture, GL_TEXTURE_2D, 1, 2,
4806 2, 0, 2, 2, 1);
4807
4808 glBindTexture(GL_TEXTURE_2D, destTexture);
4809
4810 EXPECT_GL_NO_ERROR();
4811
4812 glViewport(0, 0, 4, 4);
4813 drawQuad(mProgram, "position", 0.5f);
4814 EXPECT_GL_NO_ERROR();
4815
4816 EXPECT_PIXEL_RECT_EQ(2, 2, 2, 2, GLColor::green);
4817 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 2, GLColor::red);
4818 EXPECT_PIXEL_RECT_EQ(0, 0, 2, 4, GLColor::red);
4819 }
4820
4821 // Test basic GL_EXT_copy_image copy without any draw calls by attaching the texture
4822 // to a framebuffer and reads from the framebuffer to validate the copy
TEST_P(Texture2DTestES3,CopyImageFB)4823 TEST_P(Texture2DTestES3, CopyImageFB)
4824 {
4825 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
4826
4827 glViewport(0, 0, 4, 4);
4828 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
4829 GLTexture srcTexture;
4830 GLTexture destTexture;
4831
4832 glActiveTexture(GL_TEXTURE0);
4833 glBindTexture(GL_TEXTURE_2D, destTexture);
4834 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4835 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4836 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4837 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4838 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4839
4840 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
4841 glBindTexture(GL_TEXTURE_2D, srcTexture);
4842 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4843 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4844 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4845 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4846 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4847 texDataGreen.data());
4848 glBindTexture(GL_TEXTURE_2D, 0);
4849
4850 // copy
4851 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, destTexture, GL_TEXTURE_2D, 0, 0,
4852 1, 0, 3, 3, 1);
4853
4854 EXPECT_GL_NO_ERROR();
4855
4856 GLFramebuffer fb;
4857 glBindFramebuffer(GL_FRAMEBUFFER, fb);
4858 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
4859 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4860
4861 EXPECT_PIXEL_RECT_EQ(0, 1, 3, 3, GLColor::green);
4862 EXPECT_PIXEL_RECT_EQ(3, 0, 1, 4, GLColor::red);
4863 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 1, GLColor::red);
4864
4865 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4866 }
4867
4868 // Test GL_EXT_copy_image copy to a framebuffer attachment after
4869 // invalidation. Then draw with blending onto the framebuffer.
TEST_P(Texture2DTestES3,CopyImageFBInvalidateThenBlend)4870 TEST_P(Texture2DTestES3, CopyImageFBInvalidateThenBlend)
4871 {
4872 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
4873
4874 ANGLE_GL_PROGRAM(drawBlueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
4875 ANGLE_GL_PROGRAM(drawRedProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
4876
4877 glViewport(0, 0, 4, 4);
4878 GLTexture srcTexture;
4879 GLTexture textureAttachment;
4880
4881 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
4882 glBindTexture(GL_TEXTURE_2D, srcTexture);
4883 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4884 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4885 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4886 texDataGreen.data());
4887 glBindTexture(GL_TEXTURE_2D, 0);
4888
4889 glBindTexture(GL_TEXTURE_2D, textureAttachment);
4890 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4891 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4893 glBindTexture(GL_TEXTURE_2D, 0);
4894
4895 GLFramebuffer fb;
4896 glBindFramebuffer(GL_FRAMEBUFFER, fb);
4897 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureAttachment,
4898 0);
4899 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4900
4901 // Draw something in the texture to make sure it's image is defined.
4902 drawQuad(drawRedProgram, essl1_shaders::PositionAttrib(), 0.0f);
4903
4904 // Invalidate the framebuffer.
4905 const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
4906 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
4907 ASSERT_GL_NO_ERROR();
4908
4909 // Copy into the framebuffer attachment.
4910 glCopyImageSubDataEXT(srcTexture, GL_TEXTURE_2D, 0, 0, 0, 0, textureAttachment, GL_TEXTURE_2D,
4911 0, 0, 0, 0, 4, 4, 1);
4912 EXPECT_GL_NO_ERROR();
4913
4914 // Draw and blend, making sure both the copy and draw happen correctly.
4915 glEnable(GL_BLEND);
4916 glBlendFunc(GL_ONE, GL_ONE);
4917 drawQuad(drawBlueProgram, essl1_shaders::PositionAttrib(), 0.0f);
4918 ASSERT_GL_NO_ERROR();
4919
4920 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::cyan);
4921
4922 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4923 }
4924
4925 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
4926 // have images defined.
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeUndefined)4927 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
4928 {
4929 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
4930 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
4931
4932 glActiveTexture(GL_TEXTURE0);
4933 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4934 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4935 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4936 texDataGreen.data());
4937 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4938 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4939 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4940 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4941
4942 EXPECT_GL_NO_ERROR();
4943
4944 drawQuad(mProgram, "position", 0.5f);
4945
4946 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4947 }
4948
4949 // Test that drawing works correctly when level 0 is undefined and base level is 1.
TEST_P(Texture2DTestES3,DrawWithLevelZeroUndefined)4950 TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
4951 {
4952 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
4953 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
4954
4955 glActiveTexture(GL_TEXTURE0);
4956 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4957 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4958 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4959 texDataGreen.data());
4960 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4961 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4962 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4963 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
4964
4965 EXPECT_GL_NO_ERROR();
4966
4967 // Texture is incomplete.
4968 drawQuad(mProgram, "position", 0.5f);
4969 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
4970
4971 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4972 texDataGreen.data());
4973
4974 // Texture is now complete.
4975 drawQuad(mProgram, "position", 0.5f);
4976 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4977 }
4978
4979 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
4980 // dimensions that don't fit the images inside the range.
4981 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)4982 TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
4983 {
4984 glActiveTexture(GL_TEXTURE0);
4985 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4986 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
4987 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
4988 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
4989
4990 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4991 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
4992
4993 // Two levels that are initially unused.
4994 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
4995 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4996 texDataCyan.data());
4997
4998 // One level that is used - only this level should affect completeness.
4999 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5000 texDataGreen.data());
5001
5002 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5003 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
5004
5005 EXPECT_GL_NO_ERROR();
5006
5007 drawQuad(mProgram, "position", 0.5f);
5008
5009 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5010
5011 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
5012
5013 // Switch the level that is being used to the cyan level 2.
5014 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
5015 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
5016
5017 EXPECT_GL_NO_ERROR();
5018
5019 drawQuad(mProgram, "position", 0.5f);
5020
5021 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5022 }
5023
5024 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
5025 // have images defined.
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeUndefined)5026 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
5027 {
5028 glActiveTexture(GL_TEXTURE0);
5029 glBindTexture(GL_TEXTURE_3D, mTexture3D);
5030 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
5031 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5032 texDataGreen.data());
5033 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5034 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5035 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
5036 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
5037
5038 EXPECT_GL_NO_ERROR();
5039
5040 drawQuad(mProgram, "position", 0.5f);
5041
5042 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5043 }
5044
5045 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
5046 // dimensions that don't fit the images inside the range.
5047 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)5048 TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
5049 {
5050 // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
5051 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
5052
5053 glActiveTexture(GL_TEXTURE0);
5054 glBindTexture(GL_TEXTURE_3D, mTexture3D);
5055 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
5056 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
5057 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
5058
5059 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5060 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5061
5062 // Two levels that are initially unused.
5063 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5064 texDataRed.data());
5065 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5066 texDataCyan.data());
5067
5068 // One level that is used - only this level should affect completeness.
5069 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5070 texDataGreen.data());
5071
5072 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
5073 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
5074
5075 EXPECT_GL_NO_ERROR();
5076
5077 drawQuad(mProgram, "position", 0.5f);
5078
5079 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5080
5081 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
5082
5083 // Switch the level that is being used to the cyan level 2.
5084 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
5085 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
5086
5087 EXPECT_GL_NO_ERROR();
5088
5089 drawQuad(mProgram, "position", 0.5f);
5090
5091 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5092 }
5093
5094 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
5095 // have images defined.
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeUndefined)5096 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
5097 {
5098 glActiveTexture(GL_TEXTURE0);
5099 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
5100 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
5101 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5102 texDataGreen.data());
5103 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5104 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5105 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
5106 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
5107
5108 EXPECT_GL_NO_ERROR();
5109
5110 drawQuad(mProgram, "position", 0.5f);
5111
5112 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5113 }
5114
5115 // Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
5116 // dimensions that don't fit the images inside the range.
5117 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DArrayTestES3,DrawWithLevelsOutsideRangeWithInconsistentDimensions)5118 TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
5119 {
5120 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
5121 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
5122
5123 glActiveTexture(GL_TEXTURE0);
5124 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
5125 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
5126 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
5127 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
5128
5129 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5130 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5131
5132 // Two levels that are initially unused.
5133 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5134 texDataRed.data());
5135 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5136 texDataCyan.data());
5137
5138 // One level that is used - only this level should affect completeness.
5139 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5140 texDataGreen.data());
5141
5142 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
5143 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
5144
5145 EXPECT_GL_NO_ERROR();
5146
5147 drawQuad(mProgram, "position", 0.5f);
5148
5149 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5150
5151 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
5152
5153 // Switch the level that is being used to the cyan level 2.
5154 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
5155 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
5156
5157 EXPECT_GL_NO_ERROR();
5158
5159 drawQuad(mProgram, "position", 0.5f);
5160
5161 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5162 }
5163
5164 // Test that texture completeness is updated if texture max level changes.
5165 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithMaxLevel)5166 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
5167 {
5168 glActiveTexture(GL_TEXTURE0);
5169 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5170 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
5171
5172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5174
5175 // A level that is initially unused.
5176 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5177 texDataGreen.data());
5178
5179 // One level that is initially used - only this level should affect completeness.
5180 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5181 texDataGreen.data());
5182
5183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5185
5186 EXPECT_GL_NO_ERROR();
5187
5188 drawQuad(mProgram, "position", 0.5f);
5189
5190 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5191
5192 // Switch the max level to level 1. The levels within the used range now have inconsistent
5193 // dimensions and the texture should be incomplete.
5194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
5195
5196 EXPECT_GL_NO_ERROR();
5197
5198 drawQuad(mProgram, "position", 0.5f);
5199
5200 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
5201 }
5202
5203 // Test that compressed textures ignore the pixel unpack state.
5204 // (https://crbug.org/1267496)
TEST_P(Texture3DTestES3,PixelUnpackStateTexImage)5205 TEST_P(Texture3DTestES3, PixelUnpackStateTexImage)
5206 {
5207 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
5208 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
5209
5210 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 5);
5211 glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
5212
5213 uint8_t data[64] = {0};
5214 glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 4, 4, 4, 0, 64,
5215 data);
5216 EXPECT_GL_NO_ERROR();
5217 }
5218
5219 // Test that compressed textures ignore the pixel unpack state.
5220 // (https://crbug.org/1267496)
TEST_P(Texture3DTestES3,PixelUnpackStateTexSubImage)5221 TEST_P(Texture3DTestES3, PixelUnpackStateTexSubImage)
5222 {
5223 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
5224 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
5225
5226 glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture3D);
5227
5228 uint8_t data[64] = {0};
5229 glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 4, 4, 4, 0, 64,
5230 data);
5231 EXPECT_GL_NO_ERROR();
5232
5233 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 5);
5234
5235 glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 4, 4, 4,
5236 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 64, data);
5237 EXPECT_GL_NO_ERROR();
5238 }
5239
5240 // Test that 3D texture completeness is updated if texture max level changes.
5241 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture3DTestES3,Texture3DCompletenessChangesWithMaxLevel)5242 TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
5243 {
5244 glActiveTexture(GL_TEXTURE0);
5245 glBindTexture(GL_TEXTURE_3D, mTexture3D);
5246 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
5247
5248 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5249 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5250
5251 // A level that is initially unused.
5252 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5253 texDataGreen.data());
5254
5255 // One level that is initially used - only this level should affect completeness.
5256 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5257 texDataGreen.data());
5258
5259 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
5260 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
5261
5262 EXPECT_GL_NO_ERROR();
5263
5264 drawQuad(mProgram, "position", 0.5f);
5265
5266 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5267
5268 // Switch the max level to level 1. The levels within the used range now have inconsistent
5269 // dimensions and the texture should be incomplete.
5270 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
5271
5272 EXPECT_GL_NO_ERROR();
5273
5274 drawQuad(mProgram, "position", 0.5f);
5275
5276 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
5277 }
5278
5279 // Test that texture completeness is updated if texture base level changes.
5280 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureCompletenessChangesWithBaseLevel)5281 TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
5282 {
5283 glActiveTexture(GL_TEXTURE0);
5284 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5285 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
5286
5287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5288 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5289
5290 // Two levels that are initially unused.
5291 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5292 texDataGreen.data());
5293 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5294 texDataGreen.data());
5295
5296 // One level that is initially used - only this level should affect completeness.
5297 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5298 texDataGreen.data());
5299
5300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
5301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
5302
5303 EXPECT_GL_NO_ERROR();
5304
5305 drawQuad(mProgram, "position", 0.5f);
5306
5307 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5308
5309 // Switch the base level to level 1. The levels within the used range now have inconsistent
5310 // dimensions and the texture should be incomplete.
5311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5312
5313 EXPECT_GL_NO_ERROR();
5314
5315 drawQuad(mProgram, "position", 0.5f);
5316
5317 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
5318 }
5319
5320 // Test that texture is not complete if base level is greater than max level.
5321 // GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3,TextureBaseLevelGreaterThanMaxLevel)5322 TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
5323 {
5324 glActiveTexture(GL_TEXTURE0);
5325 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5326
5327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5328 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5329
5330 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5331
5332 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
5333 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5334
5335 EXPECT_GL_NO_ERROR();
5336
5337 drawQuad(mProgram, "position", 0.5f);
5338
5339 // Texture should be incomplete.
5340 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
5341 }
5342
5343 // Test that immutable texture base level and max level are clamped.
5344 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
TEST_P(Texture2DTestES3,ImmutableTextureBaseLevelOutOfRange)5345 TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
5346 {
5347 glActiveTexture(GL_TEXTURE0);
5348 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5349
5350 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5352
5353 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
5354
5355 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5356
5357 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
5358 // should be clamped to [base_level, levels - 1].
5359 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
5360 // In the case of this test, those rules make the effective base level and max level 0.
5361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
5362 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
5363
5364 EXPECT_GL_NO_ERROR();
5365
5366 drawQuad(mProgram, "position", 0.5f);
5367
5368 // Texture should be complete.
5369 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5370 }
5371
5372 // Test that changing base level works when it affects the format of the texture.
TEST_P(Texture2DTestES3,TextureFormatChangesWithBaseLevel)5373 TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
5374 {
5375 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
5376 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
5377
5378 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
5379
5380 // Observed incorrect rendering on AMD OpenGL.
5381 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
5382
5383 glActiveTexture(GL_TEXTURE0);
5384 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5385 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
5386 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
5387
5388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
5390
5391 // RGBA8 level that's initially unused.
5392 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5393 texDataCyan.data());
5394
5395 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5396 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
5397
5398 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
5399 // format. It reads green channel data from the green and alpha channels of texDataGreen
5400 // (this is a bit hacky but works).
5401 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
5402
5403 EXPECT_GL_NO_ERROR();
5404
5405 drawQuad(mProgram, "position", 0.5f);
5406
5407 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5408
5409 // Switch the texture to use the cyan level 0 with the RGBA format.
5410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5411 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
5412
5413 EXPECT_GL_NO_ERROR();
5414
5415 drawQuad(mProgram, "position", 0.5f);
5416
5417 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
5418 }
5419
5420 // Test that setting a texture image works when base level is out of range.
TEST_P(Texture2DTestES3,SetImageWhenBaseLevelOutOfRange)5421 TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
5422 {
5423 glActiveTexture(GL_TEXTURE0);
5424 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5425
5426 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5427 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5428
5429 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
5430 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
5431
5432 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5433
5434 EXPECT_GL_NO_ERROR();
5435
5436 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
5437
5438 drawQuad(mProgram, "position", 0.5f);
5439
5440 // Texture should be complete.
5441 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5442 }
5443
5444 // In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
5445 // RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
5446 // with these formats does not work as expected.
TEST_P(Texture2DArrayTestES3,RedefineInittableArray)5447 TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
5448 {
5449 std::vector<GLubyte> pixelData;
5450 for (size_t count = 0; count < 5000; count++)
5451 {
5452 pixelData.push_back(0u);
5453 pixelData.push_back(255u);
5454 pixelData.push_back(0u);
5455 }
5456
5457 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
5458 glUseProgram(mProgram);
5459 glUniform1i(mTextureArrayLocation, 0);
5460
5461 // The first draw worked correctly.
5462 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
5463 &pixelData[0]);
5464
5465 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5466 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5467 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
5468 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
5469 drawQuad(mProgram, "position", 1.0f);
5470 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5471
5472 // The dimension of the respecification must match the original exactly to trigger the bug.
5473 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
5474 &pixelData[0]);
5475 drawQuad(mProgram, "position", 1.0f);
5476 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5477
5478 ASSERT_GL_NO_ERROR();
5479 }
5480
5481 // Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
5482 // This test is needed especially to confirm that sampler registers get assigned correctly on
5483 // the HLSL backend even when there's a mix of different HLSL sampler and texture types.
TEST_P(ShadowSamplerPlusSampler3DTestES3,ShadowSamplerPlusSampler3DDraw)5484 TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
5485 {
5486 glActiveTexture(GL_TEXTURE0);
5487 glBindTexture(GL_TEXTURE_3D, mTexture3D);
5488 GLubyte texData[4];
5489 texData[0] = 0;
5490 texData[1] = 60;
5491 texData[2] = 0;
5492 texData[3] = 255;
5493 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
5494
5495 glActiveTexture(GL_TEXTURE1);
5496 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
5497 GLfloat depthTexData[1];
5498 depthTexData[0] = 0.5f;
5499 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
5500 depthTexData);
5501
5502 glUseProgram(mProgram);
5503 glUniform1f(mDepthRefUniformLocation, 0.3f);
5504 glUniform1i(mTexture3DUniformLocation, 0);
5505 glUniform1i(mTextureShadowUniformLocation, 1);
5506
5507 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
5508 drawQuad(mProgram, "position", 0.5f);
5509 EXPECT_GL_NO_ERROR();
5510 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
5511 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
5512
5513 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
5514 drawQuad(mProgram, "position", 0.5f);
5515 EXPECT_GL_NO_ERROR();
5516 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
5517 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
5518 }
5519
5520 // Test multiple different sampler types in the same shader.
5521 // This test makes sure that even if sampler / texture registers get grouped together based on type
5522 // or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
5523 // still has the right register index information for each ESSL sampler.
5524 // The tested ESSL samplers have the following types in D3D11 HLSL:
5525 // sampler2D: Texture2D + SamplerState
5526 // samplerCube: TextureCube + SamplerState
5527 // sampler2DShadow: Texture2D + SamplerComparisonState
5528 // samplerCubeShadow: TextureCube + SamplerComparisonState
TEST_P(SamplerTypeMixTestES3,SamplerTypeMixDraw)5529 TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
5530 {
5531 glActiveTexture(GL_TEXTURE0);
5532 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5533 GLubyte texData[4];
5534 texData[0] = 0;
5535 texData[1] = 0;
5536 texData[2] = 120;
5537 texData[3] = 255;
5538 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
5539
5540 glActiveTexture(GL_TEXTURE1);
5541 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5542 texData[0] = 0;
5543 texData[1] = 90;
5544 texData[2] = 0;
5545 texData[3] = 255;
5546 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
5547 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5548 texData);
5549
5550 glActiveTexture(GL_TEXTURE2);
5551 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
5552 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
5553 GLfloat depthTexData[1];
5554 depthTexData[0] = 0.5f;
5555 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
5556 depthTexData);
5557
5558 glActiveTexture(GL_TEXTURE3);
5559 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
5560 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
5561 depthTexData[0] = 0.2f;
5562 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
5563 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
5564 depthTexData);
5565
5566 // http://anglebug.com/3949: TODO: Add a DS texture case
5567
5568 EXPECT_GL_NO_ERROR();
5569
5570 glUseProgram(mProgram);
5571 glUniform1f(mDepthRefUniformLocation, 0.3f);
5572 glUniform1i(mTexture2DUniformLocation, 0);
5573 glUniform1i(mTextureCubeUniformLocation, 1);
5574 glUniform1i(mTexture2DShadowUniformLocation, 2);
5575 glUniform1i(mTextureCubeShadowUniformLocation, 3);
5576
5577 drawQuad(mProgram, "position", 0.5f);
5578 EXPECT_GL_NO_ERROR();
5579 // The shader writes:
5580 // <texture 2d color> +
5581 // <cube map color> +
5582 // 0.25 * <comparison result (1.0)> +
5583 // 0.125 * <comparison result (0.0)>
5584 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
5585 }
5586
5587 // Test different base levels on textures accessed through the same sampler array.
5588 // Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
TEST_P(TextureSizeTextureArrayTest,BaseLevelVariesInTextureArray)5589 TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
5590 {
5591 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
5592
5593 // http://anglebug.com/4391
5594 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
5595
5596 glActiveTexture(GL_TEXTURE0);
5597 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
5598 GLsizei size = 64;
5599 for (GLint level = 0; level < 7; ++level)
5600 {
5601 ASSERT_LT(0, size);
5602 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5603 nullptr);
5604 size = size / 2;
5605 }
5606 ASSERT_EQ(0, size);
5607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5608
5609 glActiveTexture(GL_TEXTURE1);
5610 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
5611 size = 128;
5612 for (GLint level = 0; level < 8; ++level)
5613 {
5614 ASSERT_LT(0, size);
5615 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5616 nullptr);
5617 size = size / 2;
5618 }
5619 ASSERT_EQ(0, size);
5620 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
5621 EXPECT_GL_NO_ERROR();
5622
5623 glUseProgram(mProgram);
5624 glUniform1i(mTexture0Location, 0);
5625 glUniform1i(mTexture1Location, 1);
5626
5627 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
5628 EXPECT_GL_NO_ERROR();
5629 // Red channel: width of level 1 of texture A: 32.
5630 // Green channel: width of level 3 of texture B: 16.
5631 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
5632 }
5633
5634 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5635 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBImplicitAlpha1)5636 TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
5637 {
5638 glActiveTexture(GL_TEXTURE0);
5639 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5640 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
5641 EXPECT_GL_NO_ERROR();
5642
5643 drawQuad(mProgram, "position", 0.5f);
5644
5645 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5646 }
5647
5648 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5649 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBXImplicitAlpha1)5650 TEST_P(Texture2DTestES3, TextureRGBXImplicitAlpha1)
5651 {
5652 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
5653
5654 GLuint texture2D;
5655 glGenTextures(1, &texture2D);
5656 glBindTexture(GL_TEXTURE_2D, texture2D);
5657 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBX8_ANGLE, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
5658 glActiveTexture(GL_TEXTURE0);
5659 EXPECT_GL_NO_ERROR();
5660
5661 drawQuad(mProgram, "position", 0.5f);
5662
5663 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5664 }
5665
5666 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5667 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminanceImplicitAlpha1)5668 TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
5669 {
5670 setUpProgram();
5671
5672 glActiveTexture(GL_TEXTURE0);
5673 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5674 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
5675 EXPECT_GL_NO_ERROR();
5676
5677 drawQuad(mProgram, "position", 0.5f);
5678
5679 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5680 }
5681
5682 // Validate that every component of the pixel will be equal to the luminance value we've set
5683 // and that the alpha channel will be 1 (or 255 to be exact).
TEST_P(Texture2DTest,TextureLuminanceRGBSame)5684 TEST_P(Texture2DTest, TextureLuminanceRGBSame)
5685 {
5686 setUpProgram();
5687
5688 glActiveTexture(GL_TEXTURE0);
5689 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5690 uint8_t pixel = 50;
5691 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
5692 EXPECT_GL_NO_ERROR();
5693
5694 drawQuad(mProgram, "position", 0.5f);
5695
5696 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
5697 }
5698
5699 // Validate that every component of the pixel will be equal to the luminance value we've set
5700 // and that the alpha channel will be the second component.
TEST_P(Texture2DTest,TextureLuminanceAlphaRGBSame)5701 TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
5702 {
5703 setUpProgram();
5704
5705 glActiveTexture(GL_TEXTURE0);
5706 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5707 uint8_t pixel[] = {50, 25};
5708 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
5709 GL_UNSIGNED_BYTE, pixel);
5710 EXPECT_GL_NO_ERROR();
5711
5712 drawQuad(mProgram, "position", 0.5f);
5713
5714 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
5715 }
5716
5717 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5718 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance32ImplicitAlpha1)5719 TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
5720 {
5721 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5722 ANGLE_SKIP_TEST_IF(IsD3D9());
5723 ANGLE_SKIP_TEST_IF(IsVulkan());
5724
5725 setUpProgram();
5726
5727 glActiveTexture(GL_TEXTURE0);
5728 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5729 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
5730 EXPECT_GL_NO_ERROR();
5731
5732 drawQuad(mProgram, "position", 0.5f);
5733
5734 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5735 }
5736
5737 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5738 // ES 3.0.4 table 3.24
TEST_P(Texture2DTest,TextureLuminance16ImplicitAlpha1)5739 TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
5740 {
5741 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5742 ANGLE_SKIP_TEST_IF(IsD3D9());
5743 ANGLE_SKIP_TEST_IF(IsVulkan());
5744 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
5745 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
5746
5747 setUpProgram();
5748
5749 glActiveTexture(GL_TEXTURE0);
5750 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5751 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
5752 EXPECT_GL_NO_ERROR();
5753
5754 drawQuad(mProgram, "position", 0.5f);
5755
5756 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5757 }
5758
5759 // Test that CopyTexImage2D does not trigger assertion after CompressedTexImage2D.
5760 // https://crbug.com/1216276
TEST_P(Texture2DTest,CopyAfterCompressed)5761 TEST_P(Texture2DTest, CopyAfterCompressed)
5762 {
5763 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
5764
5765 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5766 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 0, 8, nullptr);
5767 EXPECT_GL_NO_ERROR();
5768
5769 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 0, 0, 4, 4, 0);
5770 EXPECT_GL_NO_ERROR();
5771 }
5772
5773 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5774 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB8UIImplicitAlpha1)5775 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
5776 {
5777 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
5778
5779 glActiveTexture(GL_TEXTURE0);
5780 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5781 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
5782 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5783 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5784 EXPECT_GL_NO_ERROR();
5785
5786 drawQuad(mProgram, "position", 0.5f);
5787
5788 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5789 }
5790
5791 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5792 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB8IImplicitAlpha1)5793 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
5794 {
5795 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
5796
5797 glActiveTexture(GL_TEXTURE0);
5798 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5799
5800 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
5801 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5802 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5803 EXPECT_GL_NO_ERROR();
5804
5805 drawQuad(mProgram, "position", 0.5f);
5806
5807 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5808 }
5809
5810 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5811 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB16UIImplicitAlpha1)5812 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
5813 {
5814 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
5815
5816 glActiveTexture(GL_TEXTURE0);
5817 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5818 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
5819 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5820 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5821 EXPECT_GL_NO_ERROR();
5822
5823 drawQuad(mProgram, "position", 0.5f);
5824
5825 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5826 }
5827
5828 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5829 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB16IImplicitAlpha1)5830 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
5831 {
5832 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
5833
5834 glActiveTexture(GL_TEXTURE0);
5835 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5836 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
5837 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5839 EXPECT_GL_NO_ERROR();
5840
5841 drawQuad(mProgram, "position", 0.5f);
5842
5843 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5844 }
5845
5846 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5847 // ES 3.0.4 table 3.24
TEST_P(Texture2DUnsignedIntegerAlpha1TestES3,TextureRGB32UIImplicitAlpha1)5848 TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
5849 {
5850 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
5851
5852 glActiveTexture(GL_TEXTURE0);
5853 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5854 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
5855 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5857 EXPECT_GL_NO_ERROR();
5858
5859 drawQuad(mProgram, "position", 0.5f);
5860
5861 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5862 }
5863
5864 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5865 // ES 3.0.4 table 3.24
TEST_P(Texture2DIntegerAlpha1TestES3,TextureRGB32IImplicitAlpha1)5866 TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
5867 {
5868 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
5869
5870 glActiveTexture(GL_TEXTURE0);
5871 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5872 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
5873 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5874 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5875 EXPECT_GL_NO_ERROR();
5876
5877 drawQuad(mProgram, "position", 0.5f);
5878
5879 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5880 }
5881
5882 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5883 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGBSNORMImplicitAlpha1)5884 TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
5885 {
5886 glActiveTexture(GL_TEXTURE0);
5887 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5888 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
5889 EXPECT_GL_NO_ERROR();
5890
5891 drawQuad(mProgram, "position", 0.5f);
5892
5893 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5894 }
5895
5896 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5897 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureRGB9E5ImplicitAlpha1)5898 TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
5899 {
5900 glActiveTexture(GL_TEXTURE0);
5901 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5902 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
5903 nullptr);
5904 EXPECT_GL_NO_ERROR();
5905
5906 drawQuad(mProgram, "position", 0.5f);
5907
5908 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5909 }
5910
5911 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5912 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)5913 TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
5914 {
5915 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
5916 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
5917
5918 glActiveTexture(GL_TEXTURE0);
5919 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5920 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
5921 EXPECT_GL_NO_ERROR();
5922
5923 drawQuad(mProgram, "position", 0.5f);
5924
5925 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5926 }
5927
5928 // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
5929 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3,TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)5930 TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
5931 {
5932 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
5933 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
5934
5935 glActiveTexture(GL_TEXTURE0);
5936 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5937 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
5938 EXPECT_GL_NO_ERROR();
5939
5940 drawQuad(mProgram, "position", 0.5f);
5941
5942 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
5943 }
5944
5945 // Test that compressed textures ignore the pixel unpack state.
5946 // (https://crbug.org/1267496)
TEST_P(Texture2DTestES3,PixelUnpackStateTexImage)5947 TEST_P(Texture2DTestES3, PixelUnpackStateTexImage)
5948 {
5949 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
5950 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
5951
5952 glPixelStorei(GL_UNPACK_ROW_LENGTH, 9);
5953 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5954
5955 uint8_t data[64] = {0};
5956 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 8, 8, 0, 64, data);
5957 EXPECT_GL_NO_ERROR();
5958 }
5959
5960 // Test that compressed textures ignore the pixel unpack state.
5961 // (https://crbug.org/1267496)
TEST_P(Texture2DTestES3,PixelUnpackStateTexSubImage)5962 TEST_P(Texture2DTestES3, PixelUnpackStateTexSubImage)
5963 {
5964 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc") &&
5965 !IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt3"));
5966
5967 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5968
5969 uint8_t data[64] = {0};
5970 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 8, 8, 0, 64, data);
5971 EXPECT_GL_NO_ERROR();
5972
5973 glPixelStorei(GL_UNPACK_ROW_LENGTH, 9);
5974
5975 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 64,
5976 data);
5977 EXPECT_GL_NO_ERROR();
5978 }
5979
5980 // Copied from Texture2DTest::TexStorage
5981 // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
5982 // default color.
TEST_P(Texture2DTestES31PPO,TexStorage)5983 TEST_P(Texture2DTestES31PPO, TexStorage)
5984 {
5985 ANGLE_SKIP_TEST_IF(!IsVulkan());
5986 ANGLE_SKIP_TEST_IF((getClientMajorVersion() < 3 && getClientMinorVersion() < 1) &&
5987 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
5988
5989 const char *vertexShaderSource = getVertexShaderSource();
5990 const char *fragmentShaderSource = getFragmentShaderSource();
5991
5992 bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
5993 mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
5994
5995 int width = getWindowWidth();
5996 int height = getWindowHeight();
5997
5998 GLuint tex2D;
5999 glGenTextures(1, &tex2D);
6000 glActiveTexture(GL_TEXTURE0);
6001 glBindTexture(GL_TEXTURE_2D, tex2D);
6002
6003 // Fill with red
6004 std::vector<GLubyte> pixels(3 * 16 * 16);
6005 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
6006 {
6007 pixels[pixelId * 3 + 0] = 255;
6008 pixels[pixelId * 3 + 1] = 0;
6009 pixels[pixelId * 3 + 2] = 0;
6010 }
6011
6012 // ANGLE internally uses RGBA as the internal format for RGB images, therefore glTexStorage2DEXT
6013 // initializes the image to a default color to get a consistent alpha color. The data is kept in
6014 // a CPU-side image and the image is marked as dirty.
6015 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
6016
6017 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
6018 // glTexSubImage2D should take into account that the image is dirty.
6019 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
6020 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6021 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6022
6023 glActiveShaderProgram(mPipeline, mFragProg);
6024 glUniform1i(mTexture2DUniformLocation, 0);
6025
6026 std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
6027 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
6028
6029 glDeleteTextures(1, &tex2D);
6030 EXPECT_GL_NO_ERROR();
6031 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
6032
6033 // Validate that the region of the texture without data has an alpha of 1.0
6034 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
6035 EXPECT_EQ(255, pixel.A);
6036 }
6037
6038 // Copied from Texture2DTestES3::SingleTextureMultipleSamplers
6039 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES31PPO,SingleTextureMultipleSamplers)6040 TEST_P(Texture2DTestES31PPO, SingleTextureMultipleSamplers)
6041 {
6042 ANGLE_SKIP_TEST_IF(!IsVulkan());
6043
6044 const char *vertexShaderSource = getVertexShaderSource();
6045 const char *fragmentShaderSource = getFragmentShaderSource();
6046
6047 bindProgramPipeline(vertexShaderSource, fragmentShaderSource);
6048 mTexture2DUniformLocation = glGetUniformLocation(mFragProg, getTextureUniformName());
6049
6050 GLint maxTextureUnits = 0;
6051 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
6052 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
6053
6054 constexpr int kSize = 16;
6055 std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
6056
6057 // Make a single-level texture, fill it with red.
6058 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
6059 GLTexture tex;
6060 glBindTexture(GL_TEXTURE_2D, tex);
6061 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6062 redColors.data());
6063 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6064 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6065
6066 // Simple confidence check.
6067 bind2DTexturedQuadProgramPipeline();
6068 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
6069 ASSERT_GL_NO_ERROR();
6070 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6071
6072 // Bind texture to unit 1 with a sampler object making it incomplete.
6073 GLSampler sampler;
6074 glBindSampler(0, sampler);
6075 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
6076 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6077
6078 // Make a mipmap texture, fill it with blue.
6079 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
6080 GLTexture mipmapTex;
6081 glBindTexture(GL_TEXTURE_2D, mipmapTex);
6082 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6083 blueColors.data());
6084 glGenerateMipmap(GL_TEXTURE_2D);
6085
6086 // Draw with the sampler, expect blue.
6087 draw2DTexturedQuad(0.5f, 1.0f, true);
6088 ASSERT_GL_NO_ERROR();
6089 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
6090
6091 // Simple multitexturing program.
6092 constexpr char kVS[] =
6093 "#version 310 es\n"
6094 "precision mediump float;\n"
6095 "in vec2 position;\n"
6096 "out vec2 texCoord;\n"
6097 "void main()\n"
6098 "{\n"
6099 " gl_Position = vec4(position, 0, 1);\n"
6100 " texCoord = position * 0.5 + vec2(0.5);\n"
6101 "}";
6102
6103 constexpr char kFS[] =
6104 "#version 310 es\n"
6105 "precision mediump float;\n"
6106 "in vec2 texCoord;\n"
6107 "uniform sampler2D tex1;\n"
6108 "uniform sampler2D tex2;\n"
6109 "uniform sampler2D tex3;\n"
6110 "uniform sampler2D tex4;\n"
6111 "out vec4 color;\n"
6112 "void main()\n"
6113 "{\n"
6114 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
6115 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
6116 "}";
6117
6118 bindProgramPipeline(kVS, kFS);
6119
6120 std::array<GLint, 4> texLocations = {
6121 {glGetUniformLocation(mFragProg, "tex1"), glGetUniformLocation(mFragProg, "tex2"),
6122 glGetUniformLocation(mFragProg, "tex3"), glGetUniformLocation(mFragProg, "tex4")}};
6123 for (GLint location : texLocations)
6124 {
6125 ASSERT_NE(-1, location);
6126 }
6127
6128 // Init the uniform data.
6129 glActiveShaderProgram(mPipeline, mFragProg);
6130 for (GLint location = 0; location < 4; ++location)
6131 {
6132 glUniform1i(texLocations[location], location);
6133 }
6134
6135 // Initialize four samplers
6136 GLSampler samplers[4];
6137
6138 // 0: non-mipped.
6139 glBindSampler(0, samplers[0]);
6140 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6141 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6142
6143 // 1: mipped.
6144 glBindSampler(1, samplers[1]);
6145 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
6146 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6147
6148 // 2: non-mipped.
6149 glBindSampler(2, samplers[2]);
6150 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6151 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6152
6153 // 3: mipped.
6154 glBindSampler(3, samplers[3]);
6155 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
6156 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6157
6158 // Bind two blue mipped textures and two single layer textures, should all draw.
6159 glActiveTexture(GL_TEXTURE0);
6160 glBindTexture(GL_TEXTURE_2D, tex);
6161
6162 glActiveTexture(GL_TEXTURE1);
6163 glBindTexture(GL_TEXTURE_2D, mipmapTex);
6164
6165 glActiveTexture(GL_TEXTURE2);
6166 glBindTexture(GL_TEXTURE_2D, tex);
6167
6168 glActiveTexture(GL_TEXTURE3);
6169 glBindTexture(GL_TEXTURE_2D, mipmapTex);
6170
6171 ASSERT_GL_NO_ERROR();
6172
6173 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
6174 ASSERT_GL_NO_ERROR();
6175 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
6176
6177 // Bind four single layer textures, two should be incomplete.
6178 glActiveTexture(GL_TEXTURE1);
6179 glBindTexture(GL_TEXTURE_2D, tex);
6180
6181 glActiveTexture(GL_TEXTURE3);
6182 glBindTexture(GL_TEXTURE_2D, tex);
6183
6184 ppoDrawQuad(quadVertices, "position", 0.5f, 1.0f);
6185 ASSERT_GL_NO_ERROR();
6186 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
6187 }
6188
6189 // Use a sampler in a uniform struct.
TEST_P(SamplerInStructTest,SamplerInStruct)6190 TEST_P(SamplerInStructTest, SamplerInStruct)
6191 {
6192 runSamplerInStructTest();
6193 }
6194
6195 // Use a sampler in a uniform struct that's passed as a function parameter.
TEST_P(SamplerInStructAsFunctionParameterTest,SamplerInStructAsFunctionParameter)6196 TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
6197 {
6198 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
6199 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
6200
6201 runSamplerInStructTest();
6202 }
6203
6204 // Use a sampler in a uniform struct array with a struct from the array passed as a function
6205 // parameter.
TEST_P(SamplerInStructArrayAsFunctionParameterTest,SamplerInStructArrayAsFunctionParameter)6206 TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
6207 {
6208 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
6209 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
6210
6211 runSamplerInStructTest();
6212 }
6213
6214 // Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
6215 // parameter.
TEST_P(SamplerInNestedStructAsFunctionParameterTest,SamplerInNestedStructAsFunctionParameter)6216 TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
6217 {
6218 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
6219 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
6220
6221 runSamplerInStructTest();
6222 }
6223
6224 // Make sure that there isn't a name conflict between sampler extracted from a struct and a
6225 // similarly named uniform.
TEST_P(SamplerInStructAndOtherVariableTest,SamplerInStructAndOtherVariable)6226 TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
6227 {
6228 runSamplerInStructTest();
6229 }
6230
6231 // GL_EXT_texture_filter_anisotropic
6232 class TextureAnisotropyTest : public Texture2DTest
6233 {
6234 protected:
uploadTexture()6235 void uploadTexture()
6236 {
6237 glActiveTexture(GL_TEXTURE0);
6238 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6239 GLColor texDataRed[1] = {GLColor::red};
6240 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
6241 EXPECT_GL_NO_ERROR();
6242 }
6243 };
6244
6245 // Tests that setting anisotropic filtering doesn't cause failures at draw time.
TEST_P(TextureAnisotropyTest,AnisotropyFunctional)6246 TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
6247 {
6248 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
6249
6250 setUpProgram();
6251
6252 uploadTexture();
6253
6254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6255 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6256 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
6257 EXPECT_GL_NO_ERROR();
6258
6259 drawQuad(mProgram, "position", 0.5f);
6260
6261 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6262 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6263 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
6264 }
6265
6266 // GL_OES_texture_border_clamp
6267 class TextureBorderClampTest : public Texture2DTest
6268 {
6269 protected:
TextureBorderClampTest()6270 TextureBorderClampTest() : Texture2DTest() {}
6271
getVertexShaderSource()6272 const char *getVertexShaderSource() override
6273 {
6274 return
6275 R"(precision highp float;
6276 attribute vec4 position;
6277 varying vec2 texcoord;
6278
6279 void main()
6280 {
6281 gl_Position = vec4(position.xy, 0.0, 1.0);
6282 // texcoords in [-0.5, 1.5]
6283 texcoord = (position.xy) + 0.5;
6284 })";
6285 }
6286
uploadTexture()6287 void uploadTexture()
6288 {
6289 glActiveTexture(GL_TEXTURE0);
6290 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6291 std::vector<GLColor> texDataRed(1, GLColor::red);
6292 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6293 texDataRed.data());
6294 EXPECT_GL_NO_ERROR();
6295 }
6296 };
6297
6298 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
6299 // GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional)6300 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
6301 {
6302 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6303
6304 setUpProgram();
6305
6306 uploadTexture();
6307
6308 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
6309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
6310 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6312 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
6313 EXPECT_GL_NO_ERROR();
6314
6315 drawQuad(mProgram, "position", 0.5f);
6316
6317 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6318 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6319 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
6320 }
6321
6322 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampFunctional2)6323 TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
6324 {
6325 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6326
6327 glActiveTexture(GL_TEXTURE0);
6328 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6329
6330 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
6331
6332 GLint colorFixedPoint[4] = {0};
6333 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
6334 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
6335 std::numeric_limits<GLint>::max()};
6336 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
6337 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
6338 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
6339 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
6340
6341 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
6342 std::numeric_limits<GLint>::max()};
6343 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
6344
6345 GLfloat color[4] = {0.0f};
6346 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
6347 EXPECT_EQ(color[0], kFloatBlue.R);
6348 EXPECT_EQ(color[1], kFloatBlue.G);
6349 EXPECT_EQ(color[2], kFloatBlue.B);
6350 EXPECT_EQ(color[3], kFloatBlue.A);
6351 }
6352
6353 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
TEST_P(TextureBorderClampTest,TextureBorderClampValidation)6354 TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
6355 {
6356 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6357
6358 glActiveTexture(GL_TEXTURE0);
6359 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6360
6361 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
6362 EXPECT_GL_ERROR(GL_INVALID_ENUM);
6363
6364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
6365 EXPECT_GL_ERROR(GL_INVALID_ENUM);
6366
6367 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
6368 EXPECT_GL_ERROR(GL_INVALID_ENUM);
6369
6370 GLint colorInt[4] = {0};
6371 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
6372 EXPECT_GL_ERROR(GL_INVALID_ENUM);
6373
6374 if (getClientMajorVersion() < 3)
6375 {
6376 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
6377 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6378 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
6379 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6380
6381 GLuint colorUInt[4] = {0};
6382 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
6383 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6384 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
6385 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6386
6387 GLSampler sampler;
6388 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
6389 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6390 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
6391 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6392
6393 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
6394 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6395 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
6396 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6397 }
6398 }
6399
6400 class TextureBorderClampTestES3 : public TextureBorderClampTest
6401 {
6402 protected:
TextureBorderClampTestES3()6403 TextureBorderClampTestES3() : TextureBorderClampTest() {}
6404 };
6405
6406 // Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
6407 // GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional)6408 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
6409 {
6410 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6411
6412 setUpProgram();
6413
6414 uploadTexture();
6415
6416 GLSampler sampler;
6417 glBindSampler(0, sampler);
6418 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
6419 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
6420 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6421 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6422 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
6423 EXPECT_GL_NO_ERROR();
6424
6425 drawQuad(mProgram, "position", 0.5f);
6426
6427 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6428 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6429 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
6430 }
6431
6432 // Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Functional2)6433 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
6434 {
6435 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6436
6437 glActiveTexture(GL_TEXTURE0);
6438
6439 GLSampler sampler;
6440 glBindSampler(0, sampler);
6441
6442 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
6443
6444 GLint colorFixedPoint[4] = {0};
6445 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
6446 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
6447 std::numeric_limits<GLint>::max()};
6448 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
6449 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
6450 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
6451 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
6452
6453 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
6454 std::numeric_limits<GLint>::max()};
6455 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
6456
6457 GLfloat color[4] = {0.0f};
6458 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
6459 EXPECT_EQ(color[0], kFloatBlue.R);
6460 EXPECT_EQ(color[1], kFloatBlue.G);
6461 EXPECT_EQ(color[2], kFloatBlue.B);
6462 EXPECT_EQ(color[3], kFloatBlue.A);
6463
6464 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
6465 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
6466 GLint colorInt[4] = {0};
6467 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
6468 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
6469 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
6470 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
6471 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
6472
6473 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
6474 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
6475 GLuint colorUInt[4] = {0};
6476 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
6477 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
6478 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
6479 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
6480 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
6481
6482 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6483
6484 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
6485 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
6486 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
6487 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
6488 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
6489 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
6490 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
6491
6492 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
6493 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
6494 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
6495 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
6496 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
6497 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
6498 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
6499 }
6500
6501 // Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
TEST_P(TextureBorderClampTestES3,TextureBorderClampES3Validation)6502 TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
6503 {
6504 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6505
6506 glActiveTexture(GL_TEXTURE0);
6507
6508 GLSampler sampler;
6509 glBindSampler(0, sampler);
6510
6511 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
6512 EXPECT_GL_ERROR(GL_INVALID_ENUM);
6513
6514 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
6515 EXPECT_GL_ERROR(GL_INVALID_ENUM);
6516 }
6517
6518 class TextureBorderClampIntegerTestES3 : public Texture2DTest
6519 {
6520 protected:
TextureBorderClampIntegerTestES3()6521 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
6522
getVertexShaderSource()6523 const char *getVertexShaderSource() override
6524 {
6525 return
6526 R"(#version 300 es
6527 out vec2 texcoord;
6528 in vec4 position;
6529
6530 void main()
6531 {
6532 gl_Position = vec4(position.xy, 0.0, 1.0);
6533 // texcoords in [-0.5, 1.5]
6534 texcoord = (position.xy) + 0.5;
6535 })";
6536 }
6537
getFragmentShaderSource()6538 const char *getFragmentShaderSource() override
6539 {
6540 if (isUnsignedIntTest)
6541 {
6542 return "#version 300 es\n"
6543 "precision highp float;\n"
6544 "uniform highp usampler2D tex;\n"
6545 "in vec2 texcoord;\n"
6546 "out vec4 fragColor;\n"
6547
6548 "void main()\n"
6549 "{\n"
6550 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
6551 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
6552 "fragColor = (texture(tex, texcoord).r == 150u)"
6553 " ? green : red;\n"
6554 "}\n";
6555 }
6556 else
6557 {
6558 return "#version 300 es\n"
6559 "precision highp float;\n"
6560 "uniform highp isampler2D tex;\n"
6561 "in vec2 texcoord;\n"
6562 "out vec4 fragColor;\n"
6563
6564 "void main()\n"
6565 "{\n"
6566 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
6567 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
6568 "fragColor = (texture(tex, texcoord).r == -50)"
6569 " ? green : red;\n"
6570 "}\n";
6571 }
6572 }
6573
uploadTexture()6574 void uploadTexture()
6575 {
6576 glActiveTexture(GL_TEXTURE0);
6577 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6578 if (isUnsignedIntTest)
6579 {
6580 std::vector<GLubyte> texData(4, 100);
6581 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
6582 texData.data());
6583 }
6584 else
6585 {
6586 std::vector<GLbyte> texData(4, 100);
6587 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
6588 texData.data());
6589 }
6590 EXPECT_GL_NO_ERROR();
6591 }
6592
6593 bool isUnsignedIntTest;
6594 };
6595
6596 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
6597 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger)6598 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
6599 {
6600 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
6601 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
6602
6603 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6604
6605 setUpProgram();
6606
6607 uploadTexture();
6608
6609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
6610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
6611 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6612 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6613
6614 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
6615 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
6616
6617 EXPECT_GL_NO_ERROR();
6618
6619 drawQuad(mProgram, "position", 0.5f);
6620
6621 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6622 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6623 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
6624 }
6625
6626 // Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
6627 // integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampInteger2)6628 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
6629 {
6630 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
6631 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
6632
6633 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6634
6635 setUpProgram();
6636
6637 uploadTexture();
6638
6639 GLSampler sampler;
6640 glBindSampler(0, sampler);
6641 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
6642 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
6643 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6644 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6645
6646 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
6647 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
6648
6649 EXPECT_GL_NO_ERROR();
6650
6651 drawQuad(mProgram, "position", 0.5f);
6652
6653 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6654 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6655 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
6656 }
6657
6658 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
6659 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned)6660 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
6661 {
6662 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6663
6664 isUnsignedIntTest = true;
6665
6666 setUpProgram();
6667
6668 uploadTexture();
6669
6670 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
6671 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
6672 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6674
6675 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
6676 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
6677
6678 EXPECT_GL_NO_ERROR();
6679
6680 drawQuad(mProgram, "position", 0.5f);
6681
6682 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6683 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6684 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
6685 }
6686
6687 // Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
6688 // of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
6689 // glSamplerParameterIuivOES).
TEST_P(TextureBorderClampIntegerTestES3,TextureBorderClampIntegerUnsigned2)6690 TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
6691 {
6692 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
6693
6694 isUnsignedIntTest = true;
6695
6696 setUpProgram();
6697
6698 uploadTexture();
6699
6700 GLSampler sampler;
6701 glBindSampler(0, sampler);
6702 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
6703 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
6704 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6705 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6706
6707 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
6708 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
6709
6710 EXPECT_GL_NO_ERROR();
6711
6712 drawQuad(mProgram, "position", 0.5f);
6713
6714 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6715 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6716 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
6717 }
6718
6719 // ~GL_OES_texture_border_clamp
6720
6721 class TextureLimitsTest : public ANGLETest
6722 {
6723 protected:
6724 struct RGBA8
6725 {
6726 uint8_t R, G, B, A;
6727 };
6728
TextureLimitsTest()6729 TextureLimitsTest()
6730 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
6731 {
6732 setWindowWidth(128);
6733 setWindowHeight(128);
6734 setConfigRedBits(8);
6735 setConfigGreenBits(8);
6736 setConfigBlueBits(8);
6737 setConfigAlphaBits(8);
6738 }
6739
testSetUp()6740 void testSetUp() override
6741 {
6742 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
6743 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
6744 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
6745
6746 ASSERT_GL_NO_ERROR();
6747 }
6748
testTearDown()6749 void testTearDown() override
6750 {
6751 if (mProgram != 0)
6752 {
6753 glDeleteProgram(mProgram);
6754 mProgram = 0;
6755
6756 if (!mTextures.empty())
6757 {
6758 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
6759 }
6760 }
6761 }
6762
compileProgramWithTextureCounts(const std::string & vertexPrefix,GLint vertexTextureCount,GLint vertexActiveTextureCount,const std::string & fragPrefix,GLint fragmentTextureCount,GLint fragmentActiveTextureCount)6763 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
6764 GLint vertexTextureCount,
6765 GLint vertexActiveTextureCount,
6766 const std::string &fragPrefix,
6767 GLint fragmentTextureCount,
6768 GLint fragmentActiveTextureCount)
6769 {
6770 std::stringstream vertexShaderStr;
6771 vertexShaderStr << "attribute vec2 position;\n"
6772 << "varying vec4 color;\n"
6773 << "varying vec2 texCoord;\n";
6774
6775 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
6776 {
6777 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
6778 }
6779
6780 vertexShaderStr << "void main() {\n"
6781 << " gl_Position = vec4(position, 0, 1);\n"
6782 << " texCoord = (position * 0.5) + 0.5;\n"
6783 << " color = vec4(0);\n";
6784
6785 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
6786 {
6787 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
6788 << ", texCoord);\n";
6789 }
6790
6791 vertexShaderStr << "}";
6792
6793 std::stringstream fragmentShaderStr;
6794 fragmentShaderStr << "varying mediump vec4 color;\n"
6795 << "varying mediump vec2 texCoord;\n";
6796
6797 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
6798 {
6799 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
6800 }
6801
6802 fragmentShaderStr << "void main() {\n"
6803 << " gl_FragColor = color;\n";
6804
6805 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
6806 {
6807 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
6808 << ", texCoord);\n";
6809 }
6810
6811 fragmentShaderStr << "}";
6812
6813 const std::string &vertexShaderSource = vertexShaderStr.str();
6814 const std::string &fragmentShaderSource = fragmentShaderStr.str();
6815
6816 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
6817 }
6818
getPixel(GLint texIndex)6819 RGBA8 getPixel(GLint texIndex)
6820 {
6821 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
6822 0, 255u};
6823 return pixel;
6824 }
6825
initTextures(GLint tex2DCount,GLint texCubeCount)6826 void initTextures(GLint tex2DCount, GLint texCubeCount)
6827 {
6828 GLint totalCount = tex2DCount + texCubeCount;
6829 mTextures.assign(totalCount, 0);
6830 glGenTextures(totalCount, &mTextures[0]);
6831 ASSERT_GL_NO_ERROR();
6832
6833 std::vector<RGBA8> texData(16 * 16);
6834
6835 GLint texIndex = 0;
6836 for (; texIndex < tex2DCount; ++texIndex)
6837 {
6838 texData.assign(texData.size(), getPixel(texIndex));
6839 glActiveTexture(GL_TEXTURE0 + texIndex);
6840 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
6841 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6842 &texData[0]);
6843 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6844 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6845 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6846 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6847 }
6848
6849 ASSERT_GL_NO_ERROR();
6850
6851 for (; texIndex < texCubeCount; ++texIndex)
6852 {
6853 texData.assign(texData.size(), getPixel(texIndex));
6854 glActiveTexture(GL_TEXTURE0 + texIndex);
6855 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
6856 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
6857 GL_UNSIGNED_BYTE, &texData[0]);
6858 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
6859 GL_UNSIGNED_BYTE, &texData[0]);
6860 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
6861 GL_UNSIGNED_BYTE, &texData[0]);
6862 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
6863 GL_UNSIGNED_BYTE, &texData[0]);
6864 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
6865 GL_UNSIGNED_BYTE, &texData[0]);
6866 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
6867 GL_UNSIGNED_BYTE, &texData[0]);
6868 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6869 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6870 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
6871 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
6872 }
6873
6874 ASSERT_GL_NO_ERROR();
6875 }
6876
testWithTextures(GLint vertexTextureCount,const std::string & vertexTexturePrefix,GLint fragmentTextureCount,const std::string & fragmentTexturePrefix)6877 void testWithTextures(GLint vertexTextureCount,
6878 const std::string &vertexTexturePrefix,
6879 GLint fragmentTextureCount,
6880 const std::string &fragmentTexturePrefix)
6881 {
6882 // Generate textures
6883 initTextures(vertexTextureCount + fragmentTextureCount, 0);
6884
6885 glUseProgram(mProgram);
6886 RGBA8 expectedSum = {0};
6887 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
6888 {
6889 std::stringstream uniformNameStr;
6890 uniformNameStr << vertexTexturePrefix << texIndex;
6891 const std::string &uniformName = uniformNameStr.str();
6892 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
6893 ASSERT_NE(-1, location);
6894
6895 glUniform1i(location, texIndex);
6896 RGBA8 contribution = getPixel(texIndex);
6897 expectedSum.R += contribution.R;
6898 expectedSum.G += contribution.G;
6899 }
6900
6901 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
6902 {
6903 std::stringstream uniformNameStr;
6904 uniformNameStr << fragmentTexturePrefix << texIndex;
6905 const std::string &uniformName = uniformNameStr.str();
6906 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
6907 ASSERT_NE(-1, location);
6908
6909 glUniform1i(location, texIndex + vertexTextureCount);
6910 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
6911 expectedSum.R += contribution.R;
6912 expectedSum.G += contribution.G;
6913 }
6914
6915 ASSERT_GE(256u, expectedSum.G);
6916
6917 drawQuad(mProgram, "position", 0.5f);
6918 ASSERT_GL_NO_ERROR();
6919 EXPECT_PIXEL_NEAR(0, 0, expectedSum.R, expectedSum.G, 0, 255, 1);
6920 }
6921
6922 GLuint mProgram;
6923 std::vector<GLuint> mTextures;
6924 GLint mMaxVertexTextures;
6925 GLint mMaxFragmentTextures;
6926 GLint mMaxCombinedTextures;
6927 };
6928
6929 // Test rendering with the maximum vertex texture units.
TEST_P(TextureLimitsTest,MaxVertexTextures)6930 TEST_P(TextureLimitsTest, MaxVertexTextures)
6931 {
6932 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
6933 ASSERT_NE(0u, mProgram);
6934 ASSERT_GL_NO_ERROR();
6935
6936 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
6937 }
6938
6939 // Test rendering with the maximum fragment texture units.
TEST_P(TextureLimitsTest,MaxFragmentTextures)6940 TEST_P(TextureLimitsTest, MaxFragmentTextures)
6941 {
6942 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
6943 ASSERT_NE(0u, mProgram);
6944 ASSERT_GL_NO_ERROR();
6945
6946 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
6947 }
6948
6949 // Test rendering with maximum combined texture units.
TEST_P(TextureLimitsTest,MaxCombinedTextures)6950 TEST_P(TextureLimitsTest, MaxCombinedTextures)
6951 {
6952 GLint vertexTextures = mMaxVertexTextures;
6953
6954 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
6955 {
6956 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
6957 }
6958
6959 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
6960 mMaxFragmentTextures, mMaxFragmentTextures);
6961 ASSERT_NE(0u, mProgram);
6962 ASSERT_GL_NO_ERROR();
6963
6964 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
6965 }
6966
6967 // Negative test for exceeding the number of vertex textures
TEST_P(TextureLimitsTest,ExcessiveVertexTextures)6968 TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
6969 {
6970 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
6971 0);
6972 ASSERT_EQ(0u, mProgram);
6973 }
6974
6975 // Negative test for exceeding the number of fragment textures
TEST_P(TextureLimitsTest,ExcessiveFragmentTextures)6976 TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
6977 {
6978 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
6979 mMaxFragmentTextures + 1);
6980 ASSERT_EQ(0u, mProgram);
6981 }
6982
6983 // Test active vertex textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveVertexTextures)6984 TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
6985 {
6986 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
6987 ASSERT_NE(0u, mProgram);
6988 ASSERT_GL_NO_ERROR();
6989
6990 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
6991 }
6992
6993 // Test active fragment textures under the limit, but excessive textures specified.
TEST_P(TextureLimitsTest,MaxActiveFragmentTextures)6994 TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
6995 {
6996 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
6997 mMaxFragmentTextures);
6998 ASSERT_NE(0u, mProgram);
6999 ASSERT_GL_NO_ERROR();
7000
7001 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
7002 }
7003
7004 // Negative test for pointing two sampler uniforms of different types to the same texture.
7005 // GLES 2.0.25 section 2.10.4 page 39.
TEST_P(TextureLimitsTest,TextureTypeConflict)7006 TEST_P(TextureLimitsTest, TextureTypeConflict)
7007 {
7008 constexpr char kVS[] =
7009 "attribute vec2 position;\n"
7010 "varying float color;\n"
7011 "uniform sampler2D tex2D;\n"
7012 "uniform samplerCube texCube;\n"
7013 "void main() {\n"
7014 " gl_Position = vec4(position, 0, 1);\n"
7015 " vec2 texCoord = (position * 0.5) + 0.5;\n"
7016 " color = texture2D(tex2D, texCoord).x;\n"
7017 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
7018 "}";
7019 constexpr char kFS[] =
7020 "varying mediump float color;\n"
7021 "void main() {\n"
7022 " gl_FragColor = vec4(color, 0, 0, 1);\n"
7023 "}";
7024
7025 mProgram = CompileProgram(kVS, kFS);
7026 ASSERT_NE(0u, mProgram);
7027
7028 initTextures(1, 0);
7029
7030 glUseProgram(mProgram);
7031 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
7032 ASSERT_NE(-1, tex2DLocation);
7033 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
7034 ASSERT_NE(-1, texCubeLocation);
7035
7036 glUniform1i(tex2DLocation, 0);
7037 glUniform1i(texCubeLocation, 0);
7038 ASSERT_GL_NO_ERROR();
7039
7040 drawQuad(mProgram, "position", 0.5f);
7041 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7042 }
7043
7044 class Texture2DNorm16TestES3 : public Texture2DTestES3
7045 {
7046 protected:
Texture2DNorm16TestES3()7047 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
7048
testSetUp()7049 void testSetUp() override
7050 {
7051 Texture2DTestES3::testSetUp();
7052
7053 glActiveTexture(GL_TEXTURE0);
7054 glGenTextures(3, mTextures);
7055 glGenFramebuffers(1, &mFBO);
7056 glGenRenderbuffers(1, &mRenderbuffer);
7057
7058 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
7059 {
7060 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
7061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7063 }
7064
7065 glBindTexture(GL_TEXTURE_2D, 0);
7066
7067 ASSERT_GL_NO_ERROR();
7068 }
7069
testTearDown()7070 void testTearDown() override
7071 {
7072 glDeleteTextures(3, mTextures);
7073 glDeleteFramebuffers(1, &mFBO);
7074 glDeleteRenderbuffers(1, &mRenderbuffer);
7075
7076 Texture2DTestES3::testTearDown();
7077 }
7078
testNorm16Texture(GLint internalformat,GLenum format,GLenum type)7079 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
7080 {
7081 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
7082 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
7083 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
7084
7085 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
7086 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
7087
7088 setUpProgram();
7089
7090 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
7091 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
7092 0);
7093
7094 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
7095 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
7096
7097 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
7098 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
7099
7100 EXPECT_GL_NO_ERROR();
7101
7102 drawQuad(mProgram, "position", 0.5f);
7103
7104 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
7105
7106 EXPECT_PIXEL_COLOR_EQ(0, 0,
7107 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
7108 expectedValue, expectedValue)));
7109
7110 glBindFramebuffer(GL_FRAMEBUFFER, 0);
7111
7112 ASSERT_GL_NO_ERROR();
7113 }
7114
testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,GLuint y,GLuint width,GLuint height,GLint packRowLength,GLint packAlignment,GLint packSkipPixels,GLint packSkipRows,GLenum type,GLColor16UI color)7115 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
7116 GLuint y,
7117 GLuint width,
7118 GLuint height,
7119 GLint packRowLength,
7120 GLint packAlignment,
7121 GLint packSkipPixels,
7122 GLint packSkipRows,
7123 GLenum type,
7124 GLColor16UI color)
7125 {
7126 // PACK modes debugging
7127 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
7128 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
7129
7130 GLuint l = packRowLength == 0 ? width : packRowLength;
7131 const GLint &a = packAlignment;
7132
7133 // According to
7134 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
7135 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
7136 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
7137 if (static_cast<GLuint>(packRowLength) < width)
7138 {
7139 componentCount += width * n * s - k;
7140 }
7141
7142 // Populate the pixels array with random dirty value
7143 constexpr GLushort kDirtyValue = 0x1234;
7144 std::vector<GLushort> pixels(componentCount, kDirtyValue);
7145 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
7146
7147 EXPECT_GL_NO_ERROR();
7148
7149 GLushort *pixelRowStart = pixels.data();
7150 pixelRowStart += n * packSkipPixels + k * packSkipRows;
7151
7152 std::vector<bool> modifiedPixels(componentCount, false);
7153
7154 char errorInfo[200];
7155
7156 for (GLuint row = 0; row < height; ++row)
7157 {
7158 GLushort *curPixel = pixelRowStart;
7159 for (GLuint col = 0, len = (row == height - 1) ? width : std::min(l, width); col < len;
7160 ++col)
7161 {
7162 snprintf(errorInfo, sizeof(errorInfo),
7163 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
7164 "skipPixels: %d, skipRows: %d\n",
7165 width, height, col, row, packRowLength, packAlignment, packSkipPixels,
7166 packSkipRows);
7167 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
7168 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
7169 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
7170 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
7171
7172 std::ptrdiff_t diff = curPixel - pixels.data();
7173 modifiedPixels[diff + 0] = true;
7174 modifiedPixels[diff + 1] = true;
7175 modifiedPixels[diff + 2] = true;
7176 modifiedPixels[diff + 3] = true;
7177
7178 curPixel += n;
7179 }
7180 pixelRowStart += k;
7181 }
7182
7183 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
7184 {
7185 if (!modifiedPixels[i])
7186 {
7187 EXPECT_EQ(pixels[i], kDirtyValue);
7188 }
7189 }
7190 }
7191
testNorm16RenderAndReadPixels(GLint internalformat,GLenum format,GLenum type)7192 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
7193 {
7194 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
7195 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
7196 // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
7197 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
7198 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
7199
7200 GLushort pixelValue = 0x6A35;
7201 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
7202 GLColor16UI color = SliceFormatColor16UI(
7203 format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
7204 // Size of drawing viewport
7205 constexpr GLint width = 8, height = 8;
7206
7207 setUpProgram();
7208
7209 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
7210 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
7211
7212 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
7213 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
7214 0);
7215
7216 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
7217 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
7218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7220
7221 EXPECT_GL_NO_ERROR();
7222
7223 drawQuad(mProgram, "position", 0.5f);
7224
7225 // ReadPixels against different width, height, pixel pack mode combinations to test
7226 // workaround of pixels rearrangement
7227
7228 // {x, y, width, height}
7229 std::vector<std::array<GLint, 4>> areas = {
7230 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
7231 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
7232
7233 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
7234
7235 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
7236 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
7237 };
7238
7239 // Put default settings at the last
7240 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
7241 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
7242 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
7243 {3, 1}, {20, 20}, {0, 0}};
7244
7245 // Restore pixel pack modes later
7246 GLint restorePackAlignment;
7247 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
7248 GLint restorePackRowLength;
7249 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
7250 GLint restorePackSkipPixels;
7251 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
7252 GLint restorePackSkipRows;
7253 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
7254
7255 // Variable symbols are based on:
7256 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
7257 for (const auto &skipped : paramsPackSkipPixelsAndRows)
7258 {
7259 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
7260 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
7261 for (GLint a : paramsPackAlignment)
7262 {
7263 glPixelStorei(GL_PACK_ALIGNMENT, a);
7264 for (GLint l : paramsPackRowLength)
7265 {
7266 glPixelStorei(GL_PACK_ROW_LENGTH, l);
7267
7268 for (const auto &area : areas)
7269 {
7270 ASSERT(area[0] + area[2] <= width);
7271 ASSERT(area[1] + area[3] <= height);
7272 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
7273 area[3], l, a, skipped[0],
7274 skipped[1], type, color);
7275 }
7276 }
7277 }
7278 }
7279
7280 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
7281 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
7282 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
7283 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
7284
7285 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
7286 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
7287 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
7288 mRenderbuffer);
7289 glBindRenderbuffer(GL_RENDERBUFFER, 0);
7290 EXPECT_GL_NO_ERROR();
7291
7292 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
7293 glClear(GL_COLOR_BUFFER_BIT);
7294
7295 EXPECT_PIXEL_16UI_COLOR(
7296 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
7297
7298 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
7299 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
7300
7301 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
7302 0);
7303 EXPECT_PIXEL_16UI_COLOR(
7304 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
7305
7306 ASSERT_GL_NO_ERROR();
7307
7308 glBindFramebuffer(GL_FRAMEBUFFER, 0);
7309 }
7310
7311 GLuint mTextures[3];
7312 GLuint mFBO;
7313 GLuint mRenderbuffer;
7314 };
7315
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16TextureTest)7316 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
7317 {
7318 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
7319 }
7320
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16SNORMTextureTest)7321 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
7322 {
7323 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
7324 }
7325
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16TextureTest)7326 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
7327 {
7328 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
7329 }
7330
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16SNORMTextureTest)7331 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
7332 {
7333 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
7334 }
7335
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16TextureTest)7336 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
7337 {
7338 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
7339 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
7340
7341 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
7342 }
7343
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGB16SNORMTextureTest)7344 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
7345 {
7346 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
7347 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
7348
7349 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
7350 }
7351
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16TextureTest)7352 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
7353 {
7354 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
7355 }
7356
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16SNORMTextureTest)7357 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
7358 {
7359 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
7360 }
7361
TEST_P(Texture2DNorm16TestES3,TextureNorm16R16RenderTest)7362 TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
7363 {
7364 // http://anglebug.com/5153
7365 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL() && IsNVIDIA());
7366
7367 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
7368 }
7369
TEST_P(Texture2DNorm16TestES3,TextureNorm16RG16RenderTest)7370 TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
7371 {
7372 // http://anglebug.com/5153
7373 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL() && IsNVIDIA());
7374
7375 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
7376 }
7377
TEST_P(Texture2DNorm16TestES3,TextureNorm16RGBA16RenderTest)7378 TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
7379 {
7380 // http://anglebug.com/5153
7381 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL() && IsNVIDIA());
7382
7383 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
7384 }
7385
7386 class Texture2DRGTest : public Texture2DTest
7387 {
7388 protected:
Texture2DRGTest()7389 Texture2DRGTest()
7390 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
7391 {}
7392
testSetUp()7393 void testSetUp() override
7394 {
7395 Texture2DTest::testSetUp();
7396
7397 glActiveTexture(GL_TEXTURE0);
7398 glGenTextures(1, &mRenderableTexture);
7399 glGenTextures(1, &mTestTexture);
7400 glGenFramebuffers(1, &mFBO);
7401 glGenRenderbuffers(1, &mRenderbuffer);
7402
7403 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
7404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7406 glBindTexture(GL_TEXTURE_2D, mTestTexture);
7407 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7409
7410 glBindTexture(GL_TEXTURE_2D, 0);
7411
7412 setUpProgram();
7413 glUseProgram(mProgram);
7414 glUniform1i(mTexture2DUniformLocation, 0);
7415
7416 ASSERT_GL_NO_ERROR();
7417 }
7418
testTearDown()7419 void testTearDown() override
7420 {
7421 glDeleteTextures(1, &mRenderableTexture);
7422 glDeleteTextures(1, &mTestTexture);
7423 glDeleteFramebuffers(1, &mFBO);
7424 glDeleteRenderbuffers(1, &mRenderbuffer);
7425
7426 Texture2DTest::testTearDown();
7427 }
7428
setupFormatTextures(GLenum internalformat,GLenum format,GLenum type,GLvoid * imageData)7429 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
7430 {
7431 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
7432 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7433
7434 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
7435 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
7436 mRenderableTexture, 0);
7437
7438 glBindTexture(GL_TEXTURE_2D, mTestTexture);
7439 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
7440
7441 EXPECT_GL_NO_ERROR();
7442 }
7443
testRGTexture(GLColor expectedColor)7444 void testRGTexture(GLColor expectedColor)
7445 {
7446 drawQuad(mProgram, "position", 0.5f);
7447
7448 EXPECT_GL_NO_ERROR();
7449 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
7450 }
7451
testRGRender(GLenum internalformat,GLenum format)7452 void testRGRender(GLenum internalformat, GLenum format)
7453 {
7454 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
7455 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
7456 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
7457 mRenderbuffer);
7458 glBindRenderbuffer(GL_RENDERBUFFER, 0);
7459 EXPECT_GL_NO_ERROR();
7460
7461 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
7462 glClear(GL_COLOR_BUFFER_BIT);
7463
7464 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
7465
7466 ASSERT_GL_NO_ERROR();
7467 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
7468 }
7469
7470 GLuint mRenderableTexture;
7471 GLuint mTestTexture;
7472 GLuint mFBO;
7473 GLuint mRenderbuffer;
7474 };
7475
7476 // Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGUNormTest)7477 TEST_P(Texture2DRGTest, TextureRGUNormTest)
7478 {
7479 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
7480 // This workaround causes a GL error on Windows AMD, which is likely a driver bug.
7481 // The workaround is not intended to be enabled in this configuration so skip it.
7482 ANGLE_SKIP_TEST_IF(GetParam().eglParameters.emulateCopyTexImage2DFromRenderbuffers &&
7483 IsWindows() && IsAMD());
7484
7485 GLubyte pixelValue = 0xab;
7486 GLubyte imageData[] = {pixelValue, pixelValue};
7487
7488 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
7489 testRGTexture(
7490 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
7491 testRGRender(GL_R8_EXT, GL_RED_EXT);
7492
7493 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
7494 testRGTexture(
7495 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
7496 testRGRender(GL_RG8_EXT, GL_RG_EXT);
7497 }
7498
7499 // Test float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGFloatTest)7500 TEST_P(Texture2DRGTest, TextureRGFloatTest)
7501 {
7502 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
7503 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7504
7505 GLfloat pixelValue = 0.54321;
7506 GLfloat imageData[] = {pixelValue, pixelValue};
7507
7508 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
7509 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
7510
7511 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
7512 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
7513
7514 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
7515 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
7516 }
7517
7518 // Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
TEST_P(Texture2DRGTest,TextureRGHalfFloatTest)7519 TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
7520 {
7521 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
7522 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
7523
7524 GLfloat pixelValueFloat = 0.543f;
7525 GLhalf pixelValue = 0x3858;
7526 GLhalf imageData[] = {pixelValue, pixelValue};
7527
7528 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
7529 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
7530
7531 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
7532 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
7533
7534 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
7535 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
7536 }
7537
7538 class Texture2DFloatTest : public Texture2DTest
7539 {
7540 protected:
Texture2DFloatTest()7541 Texture2DFloatTest()
7542 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
7543 {}
7544
testSetUp()7545 void testSetUp() override
7546 {
7547 Texture2DTest::testSetUp();
7548
7549 glActiveTexture(GL_TEXTURE0);
7550 glGenTextures(1, &mRenderableTexture);
7551 glGenTextures(1, &mTestTexture);
7552 glGenFramebuffers(1, &mFBO);
7553 glGenRenderbuffers(1, &mRenderbuffer);
7554
7555 setUpProgram();
7556 glUseProgram(mProgram);
7557 glUniform1i(mTexture2DUniformLocation, 0);
7558
7559 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
7560 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7561
7562 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
7563 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
7564 mRenderableTexture, 0);
7565
7566 ASSERT_GL_NO_ERROR();
7567 }
7568
testTearDown()7569 void testTearDown() override
7570 {
7571 glDeleteTextures(1, &mRenderableTexture);
7572 glDeleteTextures(1, &mTestTexture);
7573 glDeleteFramebuffers(1, &mFBO);
7574 glDeleteRenderbuffers(1, &mRenderbuffer);
7575
7576 Texture2DTest::testTearDown();
7577 }
7578
testFloatTextureSample(GLenum internalFormat,GLenum format,GLenum type)7579 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
7580 {
7581 constexpr GLfloat imageDataFloat[] = {
7582 0.2f,
7583 0.3f,
7584 0.4f,
7585 0.5f,
7586 };
7587 constexpr GLhalf imageDataHalf[] = {
7588 0x3266,
7589 0x34CD,
7590 0x3666,
7591 0x3800,
7592 };
7593 GLColor expectedValue;
7594 for (int i = 0; i < 4; i++)
7595 {
7596 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
7597 }
7598
7599 const GLvoid *imageData;
7600 switch (type)
7601 {
7602 case GL_FLOAT:
7603 imageData = imageDataFloat;
7604 break;
7605 case GL_HALF_FLOAT:
7606 case GL_HALF_FLOAT_OES:
7607 imageData = imageDataHalf;
7608 break;
7609 default:
7610 imageData = nullptr;
7611 }
7612 ASSERT(imageData != nullptr);
7613
7614 glBindTexture(GL_TEXTURE_2D, mTestTexture);
7615 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
7616
7617 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7618 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7619
7620 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
7621 drawQuad(mProgram, "position", 0.5f);
7622
7623 EXPECT_GL_NO_ERROR();
7624 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
7625 }
7626
testFloatTextureLinear(GLenum internalFormat,GLenum format,GLenum type)7627 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
7628 {
7629 int numComponents;
7630 switch (format)
7631 {
7632 case GL_RGBA:
7633 numComponents = 4;
7634 break;
7635 case GL_RGB:
7636 numComponents = 3;
7637 break;
7638 case GL_LUMINANCE_ALPHA:
7639 numComponents = 2;
7640 break;
7641 case GL_LUMINANCE:
7642 case GL_ALPHA:
7643 numComponents = 1;
7644 break;
7645 default:
7646 numComponents = 0;
7647 }
7648 ASSERT(numComponents > 0);
7649
7650 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
7651 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
7652
7653 GLfloat imageDataFloat[16];
7654 GLhalf imageDataHalf[16];
7655 for (int i = 0; i < 4; i++)
7656 {
7657 for (int c = 0; c < numComponents; c++)
7658 {
7659 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
7660 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
7661 }
7662 }
7663
7664 const GLvoid *imageData;
7665 switch (type)
7666 {
7667 case GL_FLOAT:
7668 imageData = imageDataFloat;
7669 break;
7670 case GL_HALF_FLOAT:
7671 case GL_HALF_FLOAT_OES:
7672 imageData = imageDataHalf;
7673 break;
7674 default:
7675 imageData = nullptr;
7676 }
7677 ASSERT(imageData != nullptr);
7678
7679 glBindTexture(GL_TEXTURE_2D, mTestTexture);
7680 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
7681
7682 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7683 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
7684
7685 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
7686 drawQuad(mProgram, "position", 0.5f);
7687
7688 EXPECT_GL_NO_ERROR();
7689 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
7690 // should expect the final value to be gray (halfway in-between)
7691 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
7692 kPixelTolerance);
7693 }
7694
performFloatTextureRender(GLenum internalFormat,GLenum renderBufferFormat,GLenum format,GLenum type)7695 bool performFloatTextureRender(GLenum internalFormat,
7696 GLenum renderBufferFormat,
7697 GLenum format,
7698 GLenum type)
7699 {
7700 glBindTexture(GL_TEXTURE_2D, mTestTexture);
7701 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
7702 glBindTexture(GL_TEXTURE_2D, 0);
7703
7704 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
7705 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
7706 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
7707 mRenderbuffer);
7708 glBindRenderbuffer(GL_RENDERBUFFER, 0);
7709 EXPECT_GL_NO_ERROR();
7710
7711 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
7712 {
7713 return false;
7714 }
7715
7716 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
7717
7718 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
7719 glClear(GL_COLOR_BUFFER_BIT);
7720
7721 EXPECT_GL_NO_ERROR();
7722 return true;
7723 }
7724
7725 GLuint mRenderableTexture;
7726 GLuint mTestTexture;
7727 GLuint mFBO;
7728 GLuint mRenderbuffer;
7729 };
7730
7731 class Texture2DFloatTestES3 : public Texture2DFloatTest
7732 {
7733 protected:
testFloatTextureRender(GLenum internalFormat,GLenum format,GLenum type)7734 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
7735 {
7736 bool framebufferComplete =
7737 performFloatTextureRender(internalFormat, internalFormat, format, type);
7738 EXPECT_TRUE(framebufferComplete);
7739 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
7740 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
7741 kPixelTolerance32F);
7742 }
7743 };
7744
7745 class Texture2DFloatTestES2 : public Texture2DFloatTest
7746 {
7747 protected:
checkFloatTextureRender(GLenum renderBufferFormat,GLenum format,GLenum type)7748 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
7749 {
7750 bool framebufferComplete =
7751 performFloatTextureRender(format, renderBufferFormat, format, type);
7752
7753 if (!framebufferComplete)
7754 {
7755 return false;
7756 }
7757
7758 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
7759 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
7760 kPixelTolerance32F);
7761 return true;
7762 }
7763 };
7764
7765 // Test texture sampling for ES3 float texture formats
TEST_P(Texture2DFloatTestES3,TextureFloatSampleBasicTest)7766 TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
7767 {
7768 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
7769 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
7770 }
7771
7772 // Test texture sampling for ES2 float texture formats
TEST_P(Texture2DFloatTestES2,TextureFloatSampleBasicTest)7773 TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
7774 {
7775 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7776 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
7777 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
7778 }
7779
7780 // Test texture sampling for ES3 half float texture formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleBasicTest)7781 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
7782 {
7783 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
7784 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
7785 }
7786
7787 // Test texture sampling for ES2 half float texture formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleBasicTest)7788 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
7789 {
7790 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
7791 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
7792 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
7793 }
7794
7795 // Test texture sampling for legacy GLES 2.0 float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatSampleLegacyTest)7796 TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
7797 {
7798 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7799
7800 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
7801 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
7802 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
7803
7804 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
7805 {
7806 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
7807 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
7808 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
7809 }
7810 }
7811
7812 // Test texture sampling for legacy GLES 2.0 float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatSampleLegacyTest)7813 TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
7814 {
7815 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7816
7817 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
7818 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
7819 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
7820 }
7821
7822 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatSampleLegacyTest)7823 TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
7824 {
7825 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
7826
7827 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
7828 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
7829 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
7830
7831 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
7832 {
7833 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
7834 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
7835 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
7836 }
7837 }
7838 // Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatSampleLegacyTest)7839 TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
7840 {
7841 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
7842
7843 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
7844 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
7845 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
7846 }
7847
7848 // Test linear sampling for ES3 32F formats
TEST_P(Texture2DFloatTestES3,TextureFloatLinearTest)7849 TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
7850 {
7851 // TODO(anglebug.com/5360): Failing on ARM-based Apple DTKs.
7852 ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && (IsDesktopOpenGL()));
7853
7854 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
7855
7856 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
7857 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
7858 }
7859 // Test linear sampling for ES2 32F formats
TEST_P(Texture2DFloatTestES2,TextureFloatLinearTest)7860 TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
7861 {
7862 // TODO(anglebug.com/5360): Failing on ARM-based Apple DTKs.
7863 ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && (IsDesktopOpenGL()));
7864
7865 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
7866
7867 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7868
7869 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
7870 }
7871
7872 // Test linear sampling for ES3 16F formats
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearTest)7873 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
7874 {
7875 // Half float formats must be linearly filterable in GLES 3.0 core
7876 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
7877 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
7878 }
7879 // Test linear sampling for ES2 16F formats
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearTest)7880 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
7881 {
7882 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
7883 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
7884 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
7885 }
7886
7887 // Test linear sampling for legacy GLES 2.0 32F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureFloatLinearLegacyTest)7888 TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
7889 {
7890 // TODO(anglebug.com/5360): Failing on ARM-based Apple DTKs.
7891 ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && (IsDesktopOpenGL()));
7892
7893 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7894 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
7895
7896 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
7897 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
7898 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
7899
7900 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
7901 {
7902 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
7903 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
7904 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
7905 }
7906 }
7907 // Test linear sampling for legacy GLES 2.0 32F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureFloatLinearLegacyTest)7908 TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
7909 {
7910 // TODO(anglebug.com/5360): Failing on ARM-based Apple DTKs.
7911 ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && (IsDesktopOpenGL()));
7912
7913 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
7914 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
7915
7916 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
7917 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
7918 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
7919 }
7920
7921 // Test linear sampling for legacy GLES 2.0 16F formats in ES3
TEST_P(Texture2DFloatTestES3,TextureHalfFloatLinearLegacyTest)7922 TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
7923 {
7924 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
7925 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
7926
7927 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
7928 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
7929 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
7930
7931 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
7932 {
7933 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
7934 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
7935 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
7936 }
7937 }
7938 // Test linear sampling for legacy GLES 2.0 16F formats in ES2
TEST_P(Texture2DFloatTestES2,TextureHalfFloatLinearLegacyTest)7939 TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
7940 {
7941 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
7942 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
7943
7944 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
7945 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
7946 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
7947 }
7948
7949 // Test color-renderability for ES3 float and half float textures
TEST_P(Texture2DFloatTestES3,TextureFloatRenderTest)7950 TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
7951 {
7952 // http://anglebug.com/4092
7953 ANGLE_SKIP_TEST_IF(IsD3D9());
7954 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
7955 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
7956
7957 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
7958 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
7959 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
7960
7961 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
7962 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
7963 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
7964
7965 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
7966 }
7967
7968 // Test color-renderability for ES2 half float textures
TEST_P(Texture2DFloatTestES2,TextureFloatRenderTest)7969 TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
7970 {
7971 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
7972 // require a specific one
7973 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
7974 // https://crbug.com/1003971
7975 ANGLE_SKIP_TEST_IF(IsOzone());
7976 // http://anglebug.com/4092
7977 ANGLE_SKIP_TEST_IF(IsD3D9());
7978
7979 bool atLeastOneSupported = false;
7980
7981 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
7982 IsGLExtensionEnabled("GL_OES_texture_half_float"))
7983 {
7984 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
7985 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
7986 }
7987 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
7988 {
7989 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
7990
7991 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
7992 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
7993 EXPECT_TRUE(rgbaSupported);
7994 atLeastOneSupported |= rgbaSupported;
7995 }
7996
7997 EXPECT_TRUE(atLeastOneSupported);
7998 }
7999
8000 // Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
8001 // GLES 3.0.4 section 3.8.3.
TEST_P(Texture2DTestES3,UnpackSkipImages2D)8002 TEST_P(Texture2DTestES3, UnpackSkipImages2D)
8003 {
8004 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
8005 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsOpenGLES());
8006
8007 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8008 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8009 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8010 ASSERT_GL_NO_ERROR();
8011
8012 // SKIP_IMAGES should not have an effect on uploading 2D textures
8013 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
8014 ASSERT_GL_NO_ERROR();
8015
8016 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
8017
8018 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8019 pixelsGreen.data());
8020 ASSERT_GL_NO_ERROR();
8021
8022 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
8023 pixelsGreen.data());
8024 ASSERT_GL_NO_ERROR();
8025
8026 glUseProgram(mProgram);
8027 drawQuad(mProgram, "position", 0.5f);
8028 ASSERT_GL_NO_ERROR();
8029
8030 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8031 }
8032
8033 // Test that skip defined in unpack parameters is taken into account when determining whether
8034 // unpacking source extends outside unpack buffer bounds.
TEST_P(Texture2DTestES3,UnpackSkipPixelsOutOfBounds)8035 TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
8036 {
8037 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8038 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8039 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8040 ASSERT_GL_NO_ERROR();
8041
8042 GLBuffer buf;
8043 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
8044 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
8045 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
8046 GL_DYNAMIC_COPY);
8047 ASSERT_GL_NO_ERROR();
8048
8049 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
8050 ASSERT_GL_NO_ERROR();
8051
8052 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
8053 ASSERT_GL_NO_ERROR();
8054
8055 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
8056 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8057
8058 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
8059 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
8060 ASSERT_GL_NO_ERROR();
8061
8062 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
8063 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
8064 }
8065
8066 // Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
TEST_P(Texture2DTestES3,UnpackOverlappingRowsFromUnpackBuffer)8067 TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
8068 {
8069 ANGLE_SKIP_TEST_IF(IsD3D11());
8070
8071 // Incorrect rendering results seen on OSX AMD.
8072 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX() && IsAMD());
8073
8074 const GLuint width = 8u;
8075 const GLuint height = 8u;
8076 const GLuint unpackRowLength = 5u;
8077 const GLuint unpackSkipPixels = 1u;
8078
8079 setWindowWidth(width);
8080 setWindowHeight(height);
8081
8082 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8083 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8084 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8085 ASSERT_GL_NO_ERROR();
8086
8087 GLBuffer buf;
8088 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
8089 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
8090 GLColor::green);
8091
8092 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
8093 {
8094 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
8095 }
8096
8097 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
8098 GL_DYNAMIC_COPY);
8099 ASSERT_GL_NO_ERROR();
8100
8101 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
8102 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
8103 ASSERT_GL_NO_ERROR();
8104
8105 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
8106 ASSERT_GL_NO_ERROR();
8107
8108 glUseProgram(mProgram);
8109 drawQuad(mProgram, "position", 0.5f);
8110 ASSERT_GL_NO_ERROR();
8111
8112 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
8113 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
8114 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
8115 actual.data());
8116 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
8117 EXPECT_EQ(expected, actual);
8118 }
8119
8120 template <typename T>
UNorm(double value)8121 T UNorm(double value)
8122 {
8123 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
8124 }
8125
8126 // Test rendering a depth texture with mipmaps.
TEST_P(Texture2DTestES3,DepthTexturesWithMipmaps)8127 TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
8128 {
8129 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
8130 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
8131 // http://anglebug.com/1706
8132 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
8133
8134 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
8135 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
8136
8137 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
8138 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
8139
8140 const int size = getWindowWidth();
8141
8142 auto dim = [size](int level) { return size >> level; };
8143 int levels = gl::log2(size);
8144
8145 glActiveTexture(GL_TEXTURE0);
8146 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8147 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
8148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8152 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8153 ASSERT_GL_NO_ERROR();
8154
8155 glUseProgram(mProgram);
8156 glUniform1i(mTexture2DUniformLocation, 0);
8157
8158 std::vector<unsigned char> expected;
8159
8160 for (int level = 0; level < levels; ++level)
8161 {
8162 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
8163 expected.push_back(UNorm<unsigned char>(value));
8164
8165 int levelDim = dim(level);
8166
8167 ASSERT_GT(levelDim, 0);
8168
8169 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
8170 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
8171 GL_UNSIGNED_INT, initData.data());
8172 }
8173 ASSERT_GL_NO_ERROR();
8174
8175 for (int level = 0; level < levels; ++level)
8176 {
8177 glViewport(0, 0, dim(level), dim(level));
8178 drawQuad(mProgram, "position", 0.5f);
8179 GLColor actual = ReadColor(0, 0);
8180 EXPECT_NEAR(expected[level], actual.R, 10u);
8181 }
8182
8183 ASSERT_GL_NO_ERROR();
8184 }
8185
8186 class Texture2DDepthTest : public Texture2DTest
8187 {
8188 protected:
Texture2DDepthTest()8189 Texture2DDepthTest() : Texture2DTest() {}
8190
getVertexShaderSource()8191 const char *getVertexShaderSource() override
8192 {
8193 return "attribute vec4 vPosition;\n"
8194 "void main() {\n"
8195 " gl_Position = vPosition;\n"
8196 "}\n";
8197 }
8198
getFragmentShaderSource()8199 const char *getFragmentShaderSource() override
8200 {
8201 return "precision mediump float;\n"
8202 "uniform sampler2D ShadowMap;"
8203 "void main() {\n"
8204 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
8205 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
8206 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
8207 " } else {"
8208 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
8209 " }"
8210 "}\n";
8211 }
8212
checkTexImageFormatSupport(GLenum format,GLenum internalformat,GLenum type)8213 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
8214 {
8215 EXPECT_GL_NO_ERROR();
8216
8217 GLTexture tex;
8218 glBindTexture(GL_TEXTURE_2D, tex);
8219 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
8220
8221 return (glGetError() == GL_NO_ERROR);
8222 }
8223
testBehavior(bool useSizedComponent)8224 void testBehavior(bool useSizedComponent)
8225 {
8226 int w = getWindowWidth();
8227 int h = getWindowHeight();
8228 GLuint format = GL_DEPTH_COMPONENT;
8229 GLuint internalFormat = GL_DEPTH_COMPONENT;
8230
8231 if (useSizedComponent)
8232 {
8233 internalFormat = GL_DEPTH_COMPONENT24;
8234 }
8235
8236 GLFramebuffer fbo;
8237 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
8238 ASSERT_GL_NO_ERROR();
8239
8240 GLTexture depthTexture;
8241 glBindTexture(GL_TEXTURE_2D, depthTexture);
8242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8243 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8246
8247 TexCoordDrawTest::setUpProgram();
8248 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
8249 ASSERT_NE(-1, shadowMapLocation);
8250
8251 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
8252 ASSERT_NE(-1, positionLocation);
8253
8254 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
8255 glBindTexture(GL_TEXTURE_2D, depthTexture);
8256 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
8257 ASSERT_GL_NO_ERROR();
8258
8259 // try adding a color buffer.
8260 GLuint colorTex = 0;
8261 glGenTextures(1, &colorTex);
8262 glBindTexture(GL_TEXTURE_2D, colorTex);
8263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8267 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8268 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
8269 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
8270 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
8271 ASSERT_GL_NO_ERROR();
8272
8273 glViewport(0, 0, w, h);
8274 // Fill depthTexture with 0.75
8275 glClearDepthf(0.75);
8276 glClear(GL_DEPTH_BUFFER_BIT);
8277
8278 // Revert to normal framebuffer to test depth shader
8279 glBindFramebuffer(GL_FRAMEBUFFER, 0);
8280 glViewport(0, 0, w, h);
8281 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
8282 glClearDepthf(0.0f);
8283 ASSERT_GL_NO_ERROR();
8284
8285 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
8286 ASSERT_GL_NO_ERROR();
8287
8288 glActiveTexture(GL_TEXTURE0);
8289 glBindTexture(GL_TEXTURE_2D, depthTexture);
8290
8291 glUseProgram(mProgram);
8292 ASSERT_GL_NO_ERROR();
8293
8294 glUniform1i(shadowMapLocation, 0);
8295
8296 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
8297
8298 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
8299 ASSERT_GL_NO_ERROR();
8300 glEnableVertexAttribArray(positionLocation);
8301 ASSERT_GL_NO_ERROR();
8302 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8303 ASSERT_GL_NO_ERROR();
8304
8305 GLuint pixels[1];
8306 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
8307 ASSERT_GL_NO_ERROR();
8308
8309 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
8310 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
8311 // is in all the color components. Multiple implementations implement a workaround that
8312 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
8313 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
8314 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
8315 // depending on if it sees the texture sample in only the RED component.
8316 if (useSizedComponent)
8317 {
8318 ASSERT_NE(pixels[0], 0xff0000ff);
8319 }
8320 else
8321 {
8322 ASSERT_EQ(pixels[0], 0xff0000ff);
8323 }
8324
8325 glBindFramebuffer(GL_FRAMEBUFFER, 0);
8326 glDeleteProgram(mProgram);
8327 }
8328 };
8329
8330 // Test depth texture compatibility with OES_depth_texture. Uses unsized internal format.
TEST_P(Texture2DDepthTest,DepthTextureES2Compatibility)8331 TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
8332 {
8333 ANGLE_SKIP_TEST_IF(IsD3D11());
8334 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
8335 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
8336 !IsGLExtensionEnabled("GL_OES_depth_texture"));
8337 // http://anglebug.com/4092
8338 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
8339 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
8340
8341 // When the depth texture is specified with unsized internalformat implementations follow
8342 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
8343 testBehavior(false);
8344 }
8345
8346 // Test depth texture compatibility with GLES3 using sized internalformat.
TEST_P(Texture2DDepthTest,DepthTextureES3Compatibility)8347 TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
8348 {
8349 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
8350
8351 // http://anglebug.com/5243
8352 ANGLE_SKIP_TEST_IF(IsMetal() && !IsMetalTextureSwizzleAvailable());
8353
8354 testBehavior(true);
8355 }
8356
8357 // Tests unpacking into the unsized GL_ALPHA format.
TEST_P(Texture2DTestES3,UnsizedAlphaUnpackBuffer)8358 TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
8359 {
8360 // Initialize the texure.
8361 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8362 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
8363 GL_UNSIGNED_BYTE, nullptr);
8364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8366
8367 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
8368
8369 // Pull in the color data from the unpack buffer.
8370 GLBuffer unpackBuffer;
8371 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8372 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
8373 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
8374 GL_STATIC_DRAW);
8375
8376 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
8377 GL_UNSIGNED_BYTE, nullptr);
8378
8379 // Clear to a weird color to make sure we're drawing something.
8380 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
8381 glClear(GL_COLOR_BUFFER_BIT);
8382
8383 // Draw with the alpha texture and verify.
8384 drawQuad(mProgram, "position", 0.5f);
8385
8386 ASSERT_GL_NO_ERROR();
8387 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
8388 }
8389
8390 // Ensure stale unpack data doesn't propagate in D3D11.
TEST_P(Texture2DTestES3,StaleUnpackData)8391 TEST_P(Texture2DTestES3, StaleUnpackData)
8392 {
8393 // Init unpack buffer.
8394 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
8395 std::vector<GLColor> pixels(pixelCount, GLColor::red);
8396
8397 GLBuffer unpackBuffer;
8398 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8399 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
8400 GLsizei bufferSize = pixelCount * sizeof(GLColor);
8401 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
8402
8403 // Create from unpack buffer.
8404 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8405 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
8406 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8407 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8409
8410 drawQuad(mProgram, "position", 0.5f);
8411
8412 ASSERT_GL_NO_ERROR();
8413 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
8414
8415 // Fill unpack with green, recreating buffer.
8416 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
8417 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
8418 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
8419
8420 // Reinit texture with green.
8421 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
8422 GL_UNSIGNED_BYTE, nullptr);
8423
8424 drawQuad(mProgram, "position", 0.5f);
8425
8426 ASSERT_GL_NO_ERROR();
8427 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8428 }
8429
8430 // Ensure that texture parameters passed as floats that are converted to ints are rounded before
8431 // validating they are less than 0.
TEST_P(Texture2DTestES3,TextureBaseMaxLevelRoundingValidation)8432 TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
8433 {
8434 GLTexture texture;
8435 glBindTexture(GL_TEXTURE_2D, texture);
8436
8437 // Use a negative number that will round to zero when converted to an integer
8438 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
8439 // "Validation of values performed by state-setting commands is performed after conversion,
8440 // unless specified otherwise for a specific command."
8441 GLfloat param = -7.30157126e-07f;
8442 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
8443 EXPECT_GL_NO_ERROR();
8444
8445 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
8446 EXPECT_GL_NO_ERROR();
8447 }
8448
8449 // This test covers a D3D format redefinition bug for 3D textures. The base level format was not
8450 // being properly checked, and the texture storage of the previous texture format was persisting.
8451 // This would result in an ASSERT in debug and incorrect rendering in release.
8452 // See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
TEST_P(Texture3DTestES3,FormatRedefinitionBug)8453 TEST_P(Texture3DTestES3, FormatRedefinitionBug)
8454 {
8455 GLTexture tex;
8456 glBindTexture(GL_TEXTURE_3D, tex.get());
8457 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8458
8459 GLFramebuffer framebuffer;
8460 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
8461 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
8462
8463 glCheckFramebufferStatus(GL_FRAMEBUFFER);
8464
8465 std::vector<uint8_t> pixelData(100, 0);
8466
8467 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
8468 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
8469 pixelData.data());
8470
8471 ASSERT_GL_NO_ERROR();
8472 }
8473
8474 // Test glTexSubImage using PBO to 3D texture that expose the regression bug
8475 // https://issuetracker.google.com/170657065
TEST_P(Texture3DTestES3,TexSubImageWithPBO)8476 TEST_P(Texture3DTestES3, TexSubImageWithPBO)
8477 {
8478 GLTexture tex;
8479
8480 GLuint pbo;
8481 glGenBuffers(1, &pbo);
8482 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
8483 std::vector<uint8_t> pixelData(128 * 128 * 8 * 4, 0x1f);
8484 glBufferData(GL_PIXEL_UNPACK_BUFFER, 128 * 128 * 8 * 4, pixelData.data(), GL_STATIC_DRAW);
8485
8486 glBindTexture(GL_TEXTURE_3D, tex.get());
8487 glTexStorage3D(GL_TEXTURE_3D, 8, GL_RGBA8, 128, 128, 8);
8488 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
8489 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8490 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8491 glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8492 glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8493 glTexSubImage3D(GL_TEXTURE_3D, 3, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8494 glTexSubImage3D(GL_TEXTURE_3D, 4, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8495 glTexSubImage3D(GL_TEXTURE_3D, 5, 0, 0, 0, 4, 4, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8496 glTexSubImage3D(GL_TEXTURE_3D, 6, 0, 0, 0, 2, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8497 glTexSubImage3D(GL_TEXTURE_3D, 7, 0, 0, 0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8498
8499 drawQuad(mProgram, "position", 0.5f);
8500 ASSERT_GL_NO_ERROR();
8501
8502 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 128, 128, 8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8503 glTexSubImage3D(GL_TEXTURE_3D, 1, 0, 0, 0, 64, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8504 glTexSubImage3D(GL_TEXTURE_3D, 2, 0, 0, 0, 32, 32, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8505 ASSERT_GL_NO_ERROR();
8506
8507 drawQuad(mProgram, "position", 0.5f);
8508 ASSERT_GL_NO_ERROR();
8509 }
8510
8511 // Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
TEST_P(Texture3DTestES3,BasicUnpackBufferOOB)8512 TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
8513 {
8514 // 2D tests
8515 {
8516 GLTexture tex;
8517 glBindTexture(GL_TEXTURE_2D, tex.get());
8518
8519 GLBuffer pbo;
8520 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
8521
8522 // Test OOB
8523 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
8524 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8525 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
8526
8527 // Test OOB
8528 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
8529 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8530 ASSERT_GL_NO_ERROR();
8531 }
8532
8533 // 3D tests
8534 {
8535 GLTexture tex;
8536 glBindTexture(GL_TEXTURE_3D, tex.get());
8537
8538 GLBuffer pbo;
8539 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
8540
8541 // Test OOB
8542 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
8543 GL_STATIC_DRAW);
8544 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8545 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
8546
8547 // Test OOB
8548 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
8549 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
8550 ASSERT_GL_NO_ERROR();
8551 }
8552 }
8553
8554 // Tests behaviour with a single texture and multiple sampler objects.
TEST_P(Texture2DTestES3,SingleTextureMultipleSamplers)8555 TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
8556 {
8557 GLint maxTextureUnits = 0;
8558 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
8559 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
8560
8561 constexpr int kSize = 16;
8562
8563 // Make a single-level texture, fill it with red.
8564 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
8565 GLTexture tex;
8566 glBindTexture(GL_TEXTURE_2D, tex);
8567 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8568 redColors.data());
8569 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8570 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8571
8572 // Simple confidence check.
8573 draw2DTexturedQuad(0.5f, 1.0f, true);
8574 ASSERT_GL_NO_ERROR();
8575 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
8576
8577 // Bind texture to unit 1 with a sampler object making it incomplete.
8578 GLSampler sampler;
8579 glBindSampler(0, sampler);
8580 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8581 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8582
8583 // Make a mipmap texture, fill it with blue.
8584 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
8585 GLTexture mipmapTex;
8586 glBindTexture(GL_TEXTURE_2D, mipmapTex);
8587 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8588 blueColors.data());
8589 glGenerateMipmap(GL_TEXTURE_2D);
8590
8591 // Draw with the sampler, expect blue.
8592 draw2DTexturedQuad(0.5f, 1.0f, true);
8593 ASSERT_GL_NO_ERROR();
8594 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
8595
8596 // Simple multitexturing program.
8597 constexpr char kVS[] =
8598 "#version 300 es\n"
8599 "in vec2 position;\n"
8600 "out vec2 texCoord;\n"
8601 "void main()\n"
8602 "{\n"
8603 " gl_Position = vec4(position, 0, 1);\n"
8604 " texCoord = position * 0.5 + vec2(0.5);\n"
8605 "}";
8606
8607 constexpr char kFS[] =
8608 "#version 300 es\n"
8609 "precision mediump float;\n"
8610 "in vec2 texCoord;\n"
8611 "uniform sampler2D tex1;\n"
8612 "uniform sampler2D tex2;\n"
8613 "uniform sampler2D tex3;\n"
8614 "uniform sampler2D tex4;\n"
8615 "out vec4 color;\n"
8616 "void main()\n"
8617 "{\n"
8618 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
8619 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
8620 "}";
8621
8622 ANGLE_GL_PROGRAM(program, kVS, kFS);
8623
8624 std::array<GLint, 4> texLocations = {
8625 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
8626 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
8627 for (GLint location : texLocations)
8628 {
8629 ASSERT_NE(-1, location);
8630 }
8631
8632 // Init the uniform data.
8633 glUseProgram(program);
8634 for (GLint location = 0; location < 4; ++location)
8635 {
8636 glUniform1i(texLocations[location], location);
8637 }
8638
8639 // Initialize four samplers
8640 GLSampler samplers[4];
8641
8642 // 0: non-mipped.
8643 glBindSampler(0, samplers[0]);
8644 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8645 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8646
8647 // 1: mipped.
8648 glBindSampler(1, samplers[1]);
8649 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8650 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8651
8652 // 2: non-mipped.
8653 glBindSampler(2, samplers[2]);
8654 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8655 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8656
8657 // 3: mipped.
8658 glBindSampler(3, samplers[3]);
8659 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8660 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8661
8662 // Bind two blue mipped textures and two single layer textures, should all draw.
8663 glActiveTexture(GL_TEXTURE0);
8664 glBindTexture(GL_TEXTURE_2D, tex);
8665
8666 glActiveTexture(GL_TEXTURE1);
8667 glBindTexture(GL_TEXTURE_2D, mipmapTex);
8668
8669 glActiveTexture(GL_TEXTURE2);
8670 glBindTexture(GL_TEXTURE_2D, tex);
8671
8672 glActiveTexture(GL_TEXTURE3);
8673 glBindTexture(GL_TEXTURE_2D, mipmapTex);
8674
8675 ASSERT_GL_NO_ERROR();
8676
8677 drawQuad(program, "position", 0.5f);
8678 ASSERT_GL_NO_ERROR();
8679 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
8680
8681 // Bind four single layer textures, two should be incomplete.
8682 glActiveTexture(GL_TEXTURE1);
8683 glBindTexture(GL_TEXTURE_2D, tex);
8684
8685 glActiveTexture(GL_TEXTURE3);
8686 glBindTexture(GL_TEXTURE_2D, tex);
8687
8688 drawQuad(program, "position", 0.5f);
8689 ASSERT_GL_NO_ERROR();
8690 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
8691 }
8692
8693 // The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
8694 // always at level 0 instead of the base level resulting in an incomplete texture if the faces at
8695 // level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
8696 // level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
8697 // samples the cubemap using a direction vector (1,1,1).
TEST_P(TextureCubeTestES3,SpecifyAndSampleFromBaseLevel1)8698 TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
8699 {
8700 // Check http://anglebug.com/2155.
8701 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
8702
8703 constexpr char kVS[] =
8704 R"(#version 300 es
8705 precision mediump float;
8706 in vec3 pos;
8707 void main() {
8708 gl_Position = vec4(pos, 1.0);
8709 })";
8710
8711 constexpr char kFS[] =
8712 R"(#version 300 es
8713 precision mediump float;
8714 out vec4 color;
8715 uniform samplerCube uTex;
8716 void main(){
8717 color = texture(uTex, vec3(1.0));
8718 })";
8719
8720 ANGLE_GL_PROGRAM(program, kVS, kFS);
8721 glUseProgram(program);
8722
8723 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
8724 glActiveTexture(GL_TEXTURE0);
8725
8726 GLTexture cubeTex;
8727 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
8728
8729 const int kFaceWidth = 1;
8730 const int kFaceHeight = 1;
8731 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
8732 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
8733 GL_UNSIGNED_BYTE, texData.data());
8734 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
8735 GL_UNSIGNED_BYTE, texData.data());
8736 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
8737 GL_UNSIGNED_BYTE, texData.data());
8738 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
8739 GL_UNSIGNED_BYTE, texData.data());
8740 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
8741 GL_UNSIGNED_BYTE, texData.data());
8742 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
8743 GL_UNSIGNED_BYTE, texData.data());
8744 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8745 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8746 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
8747 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
8748 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
8749 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
8750
8751 drawQuad(program, "pos", 0.5f, 1.0f, true);
8752 ASSERT_GL_NO_ERROR();
8753
8754 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
8755 }
8756
8757 // Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
TEST_P(Texture2DTestES3,NegativeTextureBaseLevelAndMaxLevel)8758 TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
8759 {
8760 GLuint texture = create2DTexture();
8761
8762 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
8763 EXPECT_GL_ERROR(GL_INVALID_VALUE);
8764
8765 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
8766 EXPECT_GL_ERROR(GL_INVALID_VALUE);
8767
8768 glDeleteTextures(1, &texture);
8769 EXPECT_GL_NO_ERROR();
8770 }
8771
8772 // Test setting base level after calling generateMipmap on a LUMA texture.
8773 // Covers http://anglebug.com/2498
TEST_P(Texture2DTestES3,GenerateMipmapAndBaseLevelLUMA)8774 TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
8775 {
8776 glActiveTexture(GL_TEXTURE0);
8777 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8778
8779 constexpr const GLsizei kWidth = 8;
8780 constexpr const GLsizei kHeight = 8;
8781 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
8782 whiteData.fill(255u);
8783
8784 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
8785 GL_UNSIGNED_BYTE, whiteData.data());
8786 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
8787 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8788 glGenerateMipmap(GL_TEXTURE_2D);
8789 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
8790 EXPECT_GL_NO_ERROR();
8791
8792 drawQuad(mProgram, "position", 0.5f);
8793 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
8794 }
8795
8796 // Incompatible levels with non-mipmap filtering should work.
TEST_P(Texture2DTestES3,IncompatibleMipsButNoMipmapFiltering)8797 TEST_P(Texture2DTestES3, IncompatibleMipsButNoMipmapFiltering)
8798 {
8799 // http://anglebug.com/4782
8800 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsWindows() && (IsAMD() || IsIntel()));
8801
8802 // http://anglebug.com/4786
8803 ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsNVIDIAShield());
8804
8805 glActiveTexture(GL_TEXTURE0);
8806 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8807
8808 constexpr const GLsizei kSize = 8;
8809 const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
8810 const std::vector<GLColor> kLevel1Data(kSize * kSize, GLColor::red);
8811
8812 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8813 kLevel0Data.data());
8814 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8815 kLevel1Data.data());
8816 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8817 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8818 EXPECT_GL_NO_ERROR();
8819
8820 // Draw with base level 0. The GL_LINEAR filtering ensures the texture's image is not created
8821 // with mipmap.
8822 drawQuad(mProgram, "position", 0.5f);
8823 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
8824
8825 // Verify draw with level 1.
8826 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
8827 drawQuad(mProgram, "position", 0.5f);
8828 EXPECT_GL_NO_ERROR();
8829 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel1Data[0]);
8830
8831 // Verify draw with level 0 again
8832 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
8833 drawQuad(mProgram, "position", 0.5f);
8834 EXPECT_GL_NO_ERROR();
8835 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
8836 }
8837
8838 // Enabling mipmap filtering after previously having used the texture without it should work.
TEST_P(Texture2DTestES3,NoMipmapDrawThenMipmapDraw)8839 TEST_P(Texture2DTestES3, NoMipmapDrawThenMipmapDraw)
8840 {
8841 glActiveTexture(GL_TEXTURE0);
8842 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8843
8844 constexpr const GLsizei kSize = 8;
8845 const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
8846 const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
8847
8848 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8849 kLevel0Data.data());
8850 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8851 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8852 EXPECT_GL_NO_ERROR();
8853
8854 // Draw so the texture's image is allocated.
8855 drawQuad(mProgram, "position", 0.5f);
8856 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
8857
8858 // Specify the rest of the image
8859 for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
8860 {
8861 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
8862 GL_UNSIGNED_BYTE, kLevelOtherData.data());
8863 }
8864 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8865
8866 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
8867 glUseProgram(program);
8868 GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
8869 GLint lodLoc = glGetUniformLocation(program, essl3_shaders::LodUniform());
8870 ASSERT_NE(-1, textureLoc);
8871 ASSERT_NE(-1, lodLoc);
8872 glUniform1i(textureLoc, 0);
8873
8874 // Verify the mips
8875 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
8876 {
8877 glUniform1f(lodLoc, mip);
8878 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
8879 EXPECT_GL_NO_ERROR();
8880 EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
8881 }
8882 }
8883
8884 // Disabling mipmap filtering after previously having used the texture with it should work.
TEST_P(Texture2DTestES3,MipmapDrawThenNoMipmapDraw)8885 TEST_P(Texture2DTestES3, MipmapDrawThenNoMipmapDraw)
8886 {
8887 glActiveTexture(GL_TEXTURE0);
8888 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8889
8890 constexpr const GLsizei kSize = 8;
8891 const std::vector<GLColor> kLevel0Data(kSize * kSize, GLColor::blue);
8892 const std::vector<GLColor> kLevelOtherData(kSize * kSize, GLColor::red);
8893
8894 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8895 kLevel0Data.data());
8896 for (GLint mip = 1; (kSize >> mip) >= 1; ++mip)
8897 {
8898 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
8899 GL_UNSIGNED_BYTE, kLevelOtherData.data());
8900 }
8901 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8902 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8903 EXPECT_GL_NO_ERROR();
8904
8905 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
8906 glUseProgram(program);
8907 GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
8908 GLint lodLoc = glGetUniformLocation(program, essl3_shaders::LodUniform());
8909 ASSERT_NE(-1, textureLoc);
8910 ASSERT_NE(-1, lodLoc);
8911 glUniform1i(textureLoc, 0);
8912
8913 // Verify the mips.
8914 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
8915 {
8916 glUniform1f(lodLoc, mip);
8917 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
8918 EXPECT_GL_NO_ERROR();
8919 EXPECT_PIXEL_COLOR_EQ(0, 0, (mip == 0 ? kLevel0Data[0] : kLevelOtherData[0]));
8920 }
8921
8922 // Disable mipmapping and verify mips again.
8923 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8924
8925 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
8926 {
8927 glUniform1f(lodLoc, mip);
8928 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
8929 EXPECT_GL_NO_ERROR();
8930 EXPECT_PIXEL_COLOR_EQ(0, 0, kLevel0Data[0]);
8931 }
8932 }
8933
8934 // Respecify texture with more mips.
TEST_P(Texture2DTestES3,RespecifyWithMoreMips)8935 TEST_P(Texture2DTestES3, RespecifyWithMoreMips)
8936 {
8937 glActiveTexture(GL_TEXTURE0);
8938 glBindTexture(GL_TEXTURE_2D, mTexture2D);
8939
8940 constexpr const GLsizei kSize = 8;
8941 const std::vector<GLColor> kLevelEvenData(kSize * kSize, GLColor::blue);
8942 const std::vector<GLColor> kLevelOddData(kSize * kSize * 4, GLColor::red);
8943
8944 auto getLevelData = [&](GLint mip) {
8945 return mip % 2 == 0 ? kLevelEvenData.data() : kLevelOddData.data();
8946 };
8947
8948 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
8949 {
8950 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
8951 GL_UNSIGNED_BYTE, getLevelData(mip));
8952 }
8953 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8954 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8955 EXPECT_GL_NO_ERROR();
8956
8957 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
8958 glUseProgram(program);
8959 GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
8960 GLint lodLoc = glGetUniformLocation(program, essl3_shaders::LodUniform());
8961 ASSERT_NE(-1, textureLoc);
8962 ASSERT_NE(-1, lodLoc);
8963 glUniform1i(textureLoc, 0);
8964
8965 // Verify the mips.
8966 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
8967 {
8968 glUniform1f(lodLoc, mip);
8969 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
8970 EXPECT_GL_NO_ERROR();
8971 EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip)[0]);
8972 }
8973
8974 // Respecify the texture with more mips, without changing any parameters.
8975 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize * 2, kSize * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8976 kLevelOddData.data());
8977 for (GLint mip = 0; (kSize >> mip) >= 1; ++mip)
8978 {
8979 glTexImage2D(GL_TEXTURE_2D, mip + 1, GL_RGBA, kSize >> mip, kSize >> mip, 0, GL_RGBA,
8980 GL_UNSIGNED_BYTE, getLevelData(mip));
8981 }
8982
8983 // Verify the mips.
8984 for (GLint mip = 0; ((kSize * 2) >> mip) >= 1; ++mip)
8985 {
8986 glUniform1f(lodLoc, mip);
8987 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
8988 EXPECT_GL_NO_ERROR();
8989 EXPECT_PIXEL_COLOR_EQ(0, 0, getLevelData(mip - 1)[0]);
8990 }
8991 }
8992
8993 // Covers a bug in the D3D11 backend: http://anglebug.com/2772
8994 // When using a sampler the texture was created as if it has mipmaps,
8995 // regardless what you specified in GL_TEXTURE_MIN_FILTER via
8996 // glSamplerParameteri() -- mistakenly the default value
8997 // GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
8998 // evaluated.
8999 // If you didn't provide mipmaps and didn't let the driver generate them
9000 // this led to not sampling your texture data when minification occurred.
TEST_P(Texture2DTestES3,MinificationWithSamplerNoMipmapping)9001 TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
9002 {
9003 constexpr char kVS[] =
9004 "#version 300 es\n"
9005 "out vec2 texcoord;\n"
9006 "in vec4 position;\n"
9007 "void main()\n"
9008 "{\n"
9009 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
9010 " texcoord = (position.xy * 0.5) + 0.5;\n"
9011 "}\n";
9012
9013 constexpr char kFS[] =
9014 "#version 300 es\n"
9015 "precision highp float;\n"
9016 "uniform highp sampler2D tex;\n"
9017 "in vec2 texcoord;\n"
9018 "out vec4 fragColor;\n"
9019 "void main()\n"
9020 "{\n"
9021 " fragColor = texture(tex, texcoord);\n"
9022 "}\n";
9023
9024 ANGLE_GL_PROGRAM(program, kVS, kFS);
9025
9026 GLSampler sampler;
9027 glBindSampler(0, sampler);
9028 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9029 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9030
9031 glActiveTexture(GL_TEXTURE0);
9032 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9033
9034 const GLsizei texWidth = getWindowWidth();
9035 const GLsizei texHeight = getWindowHeight();
9036 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
9037
9038 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
9039 whiteData.data());
9040 EXPECT_GL_NO_ERROR();
9041
9042 drawQuad(program, "position", 0.5f);
9043 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
9044 }
9045
testUploadThenUseInDifferentStages(const std::vector<UploadThenUseStageParam> & uses)9046 void Texture2DTest::testUploadThenUseInDifferentStages(
9047 const std::vector<UploadThenUseStageParam> &uses)
9048 {
9049 constexpr char kVSSampleVS[] = R"(attribute vec4 a_position;
9050 uniform sampler2D u_tex2D;
9051 varying vec4 v_color;
9052
9053 void main()
9054 {
9055 gl_Position = vec4(a_position.xy, 0.0, 1.0);
9056 v_color = texture2D(u_tex2D, a_position.xy * 0.5 + vec2(0.5));
9057 })";
9058
9059 constexpr char kVSSampleFS[] = R"(precision mediump float;
9060 varying vec4 v_color;
9061
9062 void main()
9063 {
9064 gl_FragColor = v_color;
9065 })";
9066
9067 ANGLE_GL_PROGRAM(sampleInVS, kVSSampleVS, kVSSampleFS);
9068 ANGLE_GL_PROGRAM(sampleInFS, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
9069
9070 GLFramebuffer fbo[2];
9071 GLTexture color[2];
9072 for (uint32_t i = 0; i < 2; ++i)
9073 {
9074 glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
9075 glBindTexture(GL_TEXTURE_2D, color[i]);
9076 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
9077 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color[i], 0);
9078 }
9079
9080 const GLColor kImageColor(63, 31, 0, 255);
9081
9082 GLTexture tex;
9083 glBindTexture(GL_TEXTURE_2D, tex);
9084 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kImageColor);
9085 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9086 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9087 glActiveTexture(GL_TEXTURE0);
9088 ASSERT_GL_NO_ERROR();
9089
9090 glEnable(GL_BLEND);
9091 glBlendFunc(GL_ONE, GL_ONE);
9092
9093 glClearColor(0, 0, 0, 1);
9094
9095 glBindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
9096 glClear(GL_COLOR_BUFFER_BIT);
9097 glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
9098 glClear(GL_COLOR_BUFFER_BIT);
9099
9100 uint32_t curFboIndex = 0;
9101 uint32_t fboDrawCount[2] = {};
9102
9103 for (const UploadThenUseStageParam &use : uses)
9104 {
9105 const GLProgram &program = use.useStage == GL_VERTEX_SHADER ? sampleInVS : sampleInFS;
9106 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
9107 ASSERT_GL_NO_ERROR();
9108
9109 ++fboDrawCount[curFboIndex];
9110
9111 if (use.closeRenderPassAfterUse)
9112 {
9113 // Close the render pass without accidentally incurring additional barriers.
9114 curFboIndex = 1 - curFboIndex;
9115 glBindFramebuffer(GL_FRAMEBUFFER, fbo[curFboIndex]);
9116 }
9117 }
9118
9119 // Make sure the transfer operations below aren't reordered with the rendering above and thus
9120 // introduce additional synchronization.
9121 glFinish();
9122
9123 for (uint32_t i = 0; i < 2; ++i)
9124 {
9125 const GLColor kExpectedColor(63 * std::min(4u, fboDrawCount[i]),
9126 31 * std::min(8u, fboDrawCount[i]), 0, 255);
9127
9128 glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
9129 EXPECT_PIXEL_COLOR_EQ(0, 0, kExpectedColor);
9130 }
9131 }
9132
9133 // Test synchronization when a texture is used in different shader stages after data upload.
9134 //
9135 // - Use in VS
9136 // - Use in FS
TEST_P(Texture2DTest,UploadThenVSThenFS)9137 TEST_P(Texture2DTest, UploadThenVSThenFS)
9138 {
9139 testUploadThenUseInDifferentStages({
9140 {GL_VERTEX_SHADER, false},
9141 {GL_FRAGMENT_SHADER, false},
9142 });
9143 }
9144
9145 // Test synchronization when a texture is used in different shader stages after data upload.
9146 //
9147 // - Use in VS
9148 // - Break render pass
9149 // - Use in FS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFS)9150 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFS)
9151 {
9152 testUploadThenUseInDifferentStages({
9153 {GL_VERTEX_SHADER, true},
9154 {GL_FRAGMENT_SHADER, false},
9155 });
9156 }
9157
9158 // Test synchronization when a texture is used in different shader stages after data upload.
9159 //
9160 // - Use in FS
9161 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenVS)9162 TEST_P(Texture2DTest, UploadThenFSThenVS)
9163 {
9164 testUploadThenUseInDifferentStages({
9165 {GL_FRAGMENT_SHADER, false},
9166 {GL_VERTEX_SHADER, false},
9167 });
9168 }
9169
9170 // Test synchronization when a texture is used in different shader stages after data upload.
9171 //
9172 // - Use in FS
9173 // - Break render pass
9174 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenVS)9175 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenVS)
9176 {
9177 testUploadThenUseInDifferentStages({
9178 {GL_FRAGMENT_SHADER, true},
9179 {GL_VERTEX_SHADER, false},
9180 });
9181 }
9182
9183 // Test synchronization when a texture is used in different shader stages after data upload.
9184 //
9185 // - Use in VS
9186 // - Use in FS
9187 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenFSThenVS)9188 TEST_P(Texture2DTest, UploadThenVSThenFSThenVS)
9189 {
9190 testUploadThenUseInDifferentStages({
9191 {GL_VERTEX_SHADER, false},
9192 {GL_FRAGMENT_SHADER, false},
9193 {GL_VERTEX_SHADER, false},
9194 });
9195 }
9196
9197 // Test synchronization when a texture is used in different shader stages after data upload.
9198 //
9199 // - Use in VS
9200 // - Break render pass
9201 // - Use in FS
9202 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFSThenVS)9203 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFSThenVS)
9204 {
9205 testUploadThenUseInDifferentStages({
9206 {GL_VERTEX_SHADER, true},
9207 {GL_FRAGMENT_SHADER, false},
9208 {GL_VERTEX_SHADER, false},
9209 });
9210 }
9211
9212 // Test synchronization when a texture is used in different shader stages after data upload.
9213 //
9214 // - Use in VS
9215 // - Break render pass
9216 // - Use in FS
9217 // - Break render pass
9218 // - Use in VS
TEST_P(Texture2DTest,UploadThenVSThenNewRPThenFSThenNewRPThenVS)9219 TEST_P(Texture2DTest, UploadThenVSThenNewRPThenFSThenNewRPThenVS)
9220 {
9221 testUploadThenUseInDifferentStages({
9222 {GL_VERTEX_SHADER, true},
9223 {GL_FRAGMENT_SHADER, true},
9224 {GL_VERTEX_SHADER, false},
9225 });
9226 }
9227
9228 // Test synchronization when a texture is used in different shader stages after data upload.
9229 //
9230 // - Use in FS
9231 // - Use in VS
9232 // - Break render pass
9233 // - Use in FS
TEST_P(Texture2DTest,UploadThenFSThenVSThenNewRPThenFS)9234 TEST_P(Texture2DTest, UploadThenFSThenVSThenNewRPThenFS)
9235 {
9236 testUploadThenUseInDifferentStages({
9237 {GL_FRAGMENT_SHADER, false},
9238 {GL_VERTEX_SHADER, true},
9239 {GL_FRAGMENT_SHADER, false},
9240 });
9241 }
9242
9243 // Test synchronization when a texture is used in different shader stages after data upload.
9244 //
9245 // - Use in FS
9246 // - Break render pass
9247 // - Use in VS
9248 // - Use in FS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenVSThenFS)9249 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenVSThenFS)
9250 {
9251 testUploadThenUseInDifferentStages({
9252 {GL_FRAGMENT_SHADER, true},
9253 {GL_VERTEX_SHADER, false},
9254 {GL_FRAGMENT_SHADER, false},
9255 });
9256 }
9257
9258 // Test synchronization when a texture is used in different shader stages after data upload.
9259 //
9260 // - Use in FS
9261 // - Break render pass
9262 // - Use in FS
9263 // - Use in VS
TEST_P(Texture2DTest,UploadThenFSThenNewRPThenFSThenVS)9264 TEST_P(Texture2DTest, UploadThenFSThenNewRPThenFSThenVS)
9265 {
9266 testUploadThenUseInDifferentStages({
9267 {GL_FRAGMENT_SHADER, true},
9268 {GL_FRAGMENT_SHADER, false},
9269 {GL_VERTEX_SHADER, false},
9270 });
9271 }
9272
9273 // Test that clears due to emulated formats are to the correct level given non-zero base level.
TEST_P(Texture2DTestES3,NonZeroBaseEmulatedClear)9274 TEST_P(Texture2DTestES3, NonZeroBaseEmulatedClear)
9275 {
9276 // Tests behavior of the Vulkan backend with emulated formats.
9277 ANGLE_SKIP_TEST_IF(!IsVulkan());
9278
9279 // This test assumes GL_RGB is always emulated, which overrides the WithAllocateNonZeroMemory
9280 // memory feature, clearing the memory to zero. However, if the format is *not* emulated and the
9281 // feature WithAllocateNonZeroMemory is enabled, the texture memory will contain non-zero
9282 // memory, which means the color is not black (causing the test to fail).
9283 ANGLE_SKIP_TEST_IF(isAllocateNonZeroMemoryEnabled());
9284
9285 setUpProgram();
9286
9287 glActiveTexture(GL_TEXTURE0);
9288 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9289 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
9290 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
9291 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
9292 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
9293 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
9294 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
9295 EXPECT_GL_NO_ERROR();
9296
9297 drawQuad(mProgram, "position", 0.5f);
9298
9299 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
9300 }
9301
9302 // Test that uploading data to buffer that's in use then using it as PBO to update a texture works.
TEST_P(Texture2DTestES3,UseAsUBOThenUpdateThenAsPBO)9303 TEST_P(Texture2DTestES3, UseAsUBOThenUpdateThenAsPBO)
9304 {
9305 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
9306 GLColor::red};
9307 const std::array<GLColor, 4> kUpdateData = {GLColor::blue, GLColor::blue, GLColor::blue,
9308 GLColor::blue};
9309
9310 GLBuffer buffer;
9311 glBindBuffer(GL_UNIFORM_BUFFER, buffer);
9312 glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_COPY);
9313 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
9314 EXPECT_GL_NO_ERROR();
9315
9316 constexpr char kVerifyUBO[] = R"(#version 300 es
9317 precision mediump float;
9318 uniform block {
9319 uvec4 data;
9320 } ubo;
9321 out vec4 colorOut;
9322 void main()
9323 {
9324 if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
9325 colorOut = vec4(0, 1.0, 0, 1.0);
9326 else
9327 colorOut = vec4(1.0, 0, 0, 1.0);
9328 })";
9329
9330 ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
9331 drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
9332 EXPECT_GL_NO_ERROR();
9333
9334 // Update buffer data
9335 glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
9336 EXPECT_GL_NO_ERROR();
9337
9338 // Bind as PBO
9339 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
9340 EXPECT_GL_NO_ERROR();
9341
9342 // Upload from PBO to texture
9343 GLTexture tex;
9344 glBindTexture(GL_TEXTURE_2D, tex);
9345 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
9346 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
9347 EXPECT_GL_NO_ERROR();
9348
9349 // Make sure uniform data is correct.
9350 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
9351
9352 // Make sure the texture data is correct.
9353 GLFramebuffer fbo;
9354 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
9355 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
9356 EXPECT_GL_NO_ERROR();
9357 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
9358
9359 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
9360 }
9361
9362 // Test if the RenderTargetCache is updated when the TextureStorage object is freed
TEST_P(Texture2DTestES3,UpdateRenderTargetCacheOnDestroyTexStorage)9363 TEST_P(Texture2DTestES3, UpdateRenderTargetCacheOnDestroyTexStorage)
9364 {
9365 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
9366 const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
9367
9368 GLTexture tex;
9369 GLFramebuffer fb;
9370 glBindTexture(GL_TEXTURE_2D, tex);
9371 glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 100, 1);
9372 glBindFramebuffer(GL_FRAMEBUFFER, fb);
9373 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
9374 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments);
9375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
9376 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 1.0f);
9377 EXPECT_GL_NO_ERROR();
9378
9379 EXPECT_PIXEL_RECT_EQ(0, 0, 100, 1, GLColor::red);
9380 }
9381
9382 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
9383 // texture is output.
TEST_P(Texture2DIntegerTestES3,IntegerTextureNonZeroBaseLevel)9384 TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
9385 {
9386 // http://anglebug.com/3478
9387 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
9388
9389 glActiveTexture(GL_TEXTURE0);
9390 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9391 int width = getWindowWidth();
9392 int height = getWindowHeight();
9393 GLColor color = GLColor::green;
9394 std::vector<GLColor> pixels(width * height, color);
9395 GLint baseLevel = 1;
9396 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
9397 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9398 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9399 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
9400 GL_UNSIGNED_BYTE, pixels.data());
9401
9402 setUpProgram();
9403 glUseProgram(mProgram);
9404 glUniform1i(mTexture2DUniformLocation, 0);
9405 drawQuad(mProgram, "position", 0.5f);
9406
9407 EXPECT_GL_NO_ERROR();
9408 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
9409 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
9410 }
9411
9412 // Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
9413 // the texture is output.
TEST_P(TextureCubeIntegerTestES3,IntegerCubeTextureNonZeroBaseLevel)9414 TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
9415 {
9416 // All output checks returned black, rather than the texture color.
9417 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
9418
9419 glActiveTexture(GL_TEXTURE0);
9420
9421 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
9422 GLint baseLevel = 1;
9423 int width = getWindowWidth();
9424 int height = getWindowHeight();
9425 GLColor color = GLColor::green;
9426 std::vector<GLColor> pixels(width * height, color);
9427 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
9428 {
9429 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
9430 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
9431 EXPECT_GL_NO_ERROR();
9432 }
9433 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
9434 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9435 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9436
9437 glUseProgram(mProgram);
9438 glUniform1i(mTextureCubeUniformLocation, 0);
9439 drawQuad(mProgram, "position", 0.5f);
9440
9441 EXPECT_GL_NO_ERROR();
9442 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
9443 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
9444 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
9445 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
9446 }
9447
9448 // This test sets up a cube map with four distincly colored MIP levels.
9449 // The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
9450 // the corners of the screen.
TEST_P(TextureCubeIntegerEdgeTestES3,IntegerCubeTextureCorner)9451 TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
9452 {
9453 glActiveTexture(GL_TEXTURE0);
9454
9455 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
9456 int width = getWindowWidth();
9457 int height = getWindowHeight();
9458 ASSERT_EQ(width, height);
9459 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
9460 for (GLint level = 0; level < 4; level++)
9461 {
9462 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
9463 {
9464 int levelWidth = (2 * width) >> level;
9465 int levelHeight = (2 * height) >> level;
9466 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
9467 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
9468 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
9469 EXPECT_GL_NO_ERROR();
9470 }
9471 }
9472 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
9473 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9474 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
9475
9476 glUseProgram(mProgram);
9477 glUniform1i(mTextureCubeUniformLocation, 0);
9478 drawQuad(mProgram, "position", 0.5f);
9479
9480 ASSERT_GL_NO_ERROR();
9481 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
9482 EXPECT_EQ(ReadColor(0, 0).R, 0);
9483 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
9484 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
9485 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
9486 }
9487
9488 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
9489 // texture is output.
TEST_P(Texture2DIntegerProjectiveOffsetTestES3,NonZeroBaseLevel)9490 TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
9491 {
9492 // Fails on AMD: http://crbug.com/967796
9493 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
9494
9495 glActiveTexture(GL_TEXTURE0);
9496 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9497 int width = getWindowWidth();
9498 int height = getWindowHeight();
9499 GLColor color = GLColor::green;
9500 std::vector<GLColor> pixels(width * height, color);
9501 GLint baseLevel = 1;
9502 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
9503 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9504 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9505 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
9506 GL_UNSIGNED_BYTE, pixels.data());
9507
9508 setUpProgram();
9509 glUseProgram(mProgram);
9510 glUniform1i(mTexture2DUniformLocation, 0);
9511 drawQuad(mProgram, "position", 0.5f);
9512
9513 EXPECT_GL_NO_ERROR();
9514 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
9515 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
9516 }
9517
9518 // Draw a quad with an integer texture with a non-zero base level, and test that the color of the
9519 // texture is output.
TEST_P(Texture2DArrayIntegerTestES3,NonZeroBaseLevel)9520 TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
9521 {
9522 // Test fail: http://anglebug.com/5959
9523 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX() && IsOpenGL());
9524
9525 glActiveTexture(GL_TEXTURE0);
9526 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
9527 int width = getWindowWidth();
9528 int height = getWindowHeight();
9529 int depth = 2;
9530 GLColor color = GLColor::green;
9531 std::vector<GLColor> pixels(width * height * depth, color);
9532 GLint baseLevel = 1;
9533 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
9534 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
9535 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
9536 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9537 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9538
9539 drawQuad(mProgram, "position", 0.5f);
9540
9541 EXPECT_GL_NO_ERROR();
9542 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
9543 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
9544 }
9545
9546 // Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
9547 // texture is output.
TEST_P(Texture3DIntegerTestES3,NonZeroBaseLevel)9548 TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
9549 {
9550 glActiveTexture(GL_TEXTURE0);
9551 glBindTexture(GL_TEXTURE_3D, mTexture3D);
9552 int width = getWindowWidth();
9553 int height = getWindowHeight();
9554 int depth = 2;
9555 GLColor color = GLColor::green;
9556 std::vector<GLColor> pixels(width * height * depth, color);
9557 GLint baseLevel = 1;
9558 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
9559 GL_UNSIGNED_BYTE, pixels.data());
9560 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
9561 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9562 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9563
9564 drawQuad(mProgram, "position", 0.5f);
9565
9566 EXPECT_GL_NO_ERROR();
9567 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
9568 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
9569 }
9570
runCompressedSubImage()9571 void PBOCompressedTextureTest::runCompressedSubImage()
9572 {
9573 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
9574 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
9575 // http://anglebug.com/4115
9576 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
9577 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
9578
9579 if (getClientMajorVersion() < 3)
9580 {
9581 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
9582 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
9583 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
9584 }
9585
9586 const GLuint width = 4u;
9587 const GLuint height = 4u;
9588
9589 setWindowWidth(width);
9590 setWindowHeight(height);
9591
9592 // Setup primary Texture
9593 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9594 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9595 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9596
9597 if (getClientMajorVersion() < 3)
9598 {
9599 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
9600 }
9601 else
9602 {
9603 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
9604 }
9605 ASSERT_GL_NO_ERROR();
9606
9607 // Setup PBO and fill it with a red
9608 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
9609 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
9610 ASSERT_GL_NO_ERROR();
9611
9612 // Write PBO to mTexture
9613 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
9614 width * height / 2u, nullptr);
9615 ASSERT_GL_NO_ERROR();
9616
9617 setUpProgram();
9618 // Draw using PBO updated texture
9619 glUseProgram(mProgram);
9620 glUniform1i(mTexture2DUniformLocation, 0);
9621 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9622 drawQuad(mProgram, "position", 0.5f);
9623 ASSERT_GL_NO_ERROR();
9624
9625 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9626 ASSERT_GL_NO_ERROR();
9627 }
9628
9629 // Test that uses glCompressedTexSubImage2D combined with a PBO
TEST_P(PBOCompressedTextureTest,PBOCompressedSubImage)9630 TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
9631 {
9632 runCompressedSubImage();
9633 }
9634
9635 // Verify the row length state is ignored when using compressed tex image calls.
TEST_P(PBOCompressedTextureTest,PBOCompressedSubImageWithUnpackRowLength)9636 TEST_P(PBOCompressedTextureTest, PBOCompressedSubImageWithUnpackRowLength)
9637 {
9638 // ROW_LENGTH requires ES3 or an extension.
9639 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
9640 !IsGLExtensionEnabled("GL_EXT_unpack_subimage"));
9641
9642 glPixelStorei(GL_UNPACK_ROW_LENGTH, 1);
9643 runCompressedSubImage();
9644 }
9645
9646 // Test using ETC1_RGB8 with subimage updates
TEST_P(ETC1CompressedTextureTest,ETC1CompressedSubImage)9647 TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
9648 {
9649 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
9650 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
9651
9652 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
9653 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
9654 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
9655
9656 const GLuint width = 4u;
9657 const GLuint height = 4u;
9658
9659 setWindowWidth(width);
9660 setWindowHeight(height);
9661
9662 // Setup primary Texture
9663 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9664 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9665
9666 if (getClientMajorVersion() < 3)
9667 {
9668 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
9669 }
9670 else
9671 {
9672 glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
9673 }
9674 ASSERT_GL_NO_ERROR();
9675
9676 // Populate a subimage of the texture
9677 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
9678 width * height / 2u, kCompressedImageETC2);
9679 ASSERT_GL_NO_ERROR();
9680
9681 // Render and ensure we get red
9682 glUseProgram(mProgram);
9683 drawQuad(mProgram, "position", 0.5f);
9684 ASSERT_GL_NO_ERROR();
9685
9686 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9687 ASSERT_GL_NO_ERROR();
9688 }
9689
9690 // Fully-define a NPOT compressed texture and draw; set MAX_LEVEL and draw; then increase
9691 // MAX_LEVEL and draw. This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageNPOT)9692 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageNPOT)
9693 {
9694 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
9695 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
9696
9697 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
9698 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
9699
9700 const GLuint width = 5u;
9701 const GLuint height = 5u;
9702 // round up to the nearest block size
9703 const GLsizei imageSize = 8 * 8 / 2;
9704 // smallest block size
9705 const GLsizei minImageSize = 4 * 4 / 2;
9706
9707 uint8_t data[imageSize] = {0};
9708
9709 setWindowWidth(width);
9710 setWindowHeight(height);
9711
9712 // Setup primary Texture
9713 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9716 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9717
9718 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
9719 ASSERT_GL_NO_ERROR();
9720
9721 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width / 2, height / 2, 0,
9722 minImageSize, data);
9723 ASSERT_GL_NO_ERROR();
9724
9725 glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_ETC1_RGB8_OES, width / 4, height / 4, 0,
9726 minImageSize, data);
9727 ASSERT_GL_NO_ERROR();
9728
9729 glUseProgram(mProgram);
9730 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
9731 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
9732 drawQuad(mProgram, "position", 0.5f);
9733 ASSERT_GL_NO_ERROR();
9734
9735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
9736 drawQuad(mProgram, "position", 0.5f);
9737 ASSERT_GL_NO_ERROR();
9738 }
9739
9740 // Define two NPOT compressed textures, set MAX_LEVEL, draw, and swap buffers
9741 // with the two textures. This used to cause release of staging buffers
9742 // that have not been flushed.
TEST_P(ETC1CompressedTextureTest,ETC1CompressedImageDraws)9743 TEST_P(ETC1CompressedTextureTest, ETC1CompressedImageDraws)
9744 {
9745 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
9746 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
9747
9748 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
9749 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
9750
9751 const GLuint width = 384u;
9752 const GLuint height = 384u;
9753 // round up to the nearest block size
9754 const GLsizei imageSize = width * height / 2;
9755
9756 uint8_t data[imageSize] = {0};
9757
9758 setWindowWidth(width);
9759 setWindowHeight(height);
9760
9761 const GLuint smallerWidth = 384u;
9762 const GLuint smallerHeight = 320u;
9763 // round up to the nearest block size
9764 const GLsizei smallerImageSize = smallerWidth * smallerHeight / 2;
9765
9766 // Setup primary Texture
9767 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9768 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9771
9772 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, smallerWidth, smallerHeight, 0,
9773 smallerImageSize, data);
9774 ASSERT_GL_NO_ERROR();
9775
9776 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 160, 0, 15360, data);
9777 ASSERT_GL_NO_ERROR();
9778
9779 GLTexture largerTexture;
9780 glBindTexture(GL_TEXTURE_2D, largerTexture);
9781
9782 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, imageSize, data);
9783 ASSERT_GL_NO_ERROR();
9784
9785 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, 192, 192, 0, 18432, data);
9786 ASSERT_GL_NO_ERROR();
9787
9788 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9789
9790 glUseProgram(mProgram);
9791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
9792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
9793 drawQuad(mProgram, "position", 0.5f);
9794 ASSERT_GL_NO_ERROR();
9795 swapBuffers();
9796 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
9797 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
9798 drawQuad(mProgram, "position", 0.5f);
9799 ASSERT_GL_NO_ERROR();
9800 swapBuffers();
9801
9802 glBindTexture(GL_TEXTURE_2D, largerTexture);
9803
9804 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
9805 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
9806 drawQuad(mProgram, "position", 0.5f);
9807 ASSERT_GL_NO_ERROR();
9808 swapBuffers();
9809
9810 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
9811 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
9812 drawQuad(mProgram, "position", 0.5f);
9813 ASSERT_GL_NO_ERROR();
9814 swapBuffers();
9815
9816 glBindTexture(GL_TEXTURE_2D, mTexture2D);
9817
9818 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
9819 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
9820 drawQuad(mProgram, "position", 0.5f);
9821 swapBuffers();
9822 ASSERT_GL_NO_ERROR();
9823 }
9824
9825 // Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
9826 // MAX_LEVEL and draw. This used to cause Vulkan validation errors.
TEST_P(ETC1CompressedTextureTest,ETC1ShrinkThenGrowMaxLevels)9827 TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
9828 {
9829 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
9830 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
9831
9832 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
9833 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
9834
9835 const GLuint width = 4u;
9836 const GLuint height = 4u;
9837
9838 setWindowWidth(width);
9839 setWindowHeight(height);
9840
9841 // Setup primary Texture
9842 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9843 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9844
9845 if (getClientMajorVersion() < 3)
9846 {
9847 glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
9848 }
9849 else
9850 {
9851 glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
9852 }
9853 ASSERT_GL_NO_ERROR();
9854
9855 // Populate a subimage of the texture
9856 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
9857 width * height / 2u, kCompressedImageETC2);
9858 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
9859 width * height / 2u, kCompressedImageETC2);
9860 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
9861 width * height / 2u, kCompressedImageETC2);
9862 ASSERT_GL_NO_ERROR();
9863
9864 // Set MAX_LEVEL to 2 (the highest level)
9865 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
9866
9867 // Render and ensure we get red
9868 glUseProgram(mProgram);
9869 drawQuad(mProgram, "position", 0.5f);
9870 ASSERT_GL_NO_ERROR();
9871 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9872 ASSERT_GL_NO_ERROR();
9873
9874 // Decrease MAX_LEVEL to 0, render, and ensure we still get red
9875 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
9876 drawQuad(mProgram, "position", 0.5f);
9877 ASSERT_GL_NO_ERROR();
9878 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9879 ASSERT_GL_NO_ERROR();
9880
9881 // Increase MAX_LEVEL back to 2, render, and ensure we still get red
9882 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
9883 drawQuad(mProgram, "position", 0.5f);
9884 ASSERT_GL_NO_ERROR();
9885 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
9886 ASSERT_GL_NO_ERROR();
9887 }
9888
9889 class TextureBufferTestES31 : public ANGLETest
9890 {
9891 protected:
TextureBufferTestES31()9892 TextureBufferTestES31() {}
9893 };
9894
9895 // Test that mutating a buffer attached to a texture returns correct results in query.
TEST_P(TextureBufferTestES31,QueryWidthAfterBufferResize)9896 TEST_P(TextureBufferTestES31, QueryWidthAfterBufferResize)
9897 {
9898 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_buffer"));
9899
9900 constexpr GLint kInitialSize = 128;
9901 constexpr std::array<GLint, 4> kModifiedSizes = {96, 192, 32, 256};
9902
9903 GLTexture texture;
9904 glBindTexture(GL_TEXTURE_BUFFER, texture);
9905
9906 GLBuffer buffer;
9907 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
9908 glBufferData(GL_TEXTURE_BUFFER, kInitialSize, nullptr, GL_STATIC_DRAW);
9909
9910 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
9911 ASSERT_GL_NO_ERROR();
9912
9913 GLint queryResult = 0;
9914 glGetTexLevelParameteriv(GL_TEXTURE_BUFFER, 0, GL_TEXTURE_WIDTH, &queryResult);
9915 ASSERT_GL_NO_ERROR();
9916 EXPECT_EQ(queryResult, kInitialSize / 4);
9917
9918 for (GLint modifiedSize : kModifiedSizes)
9919 {
9920 glBufferData(GL_TEXTURE_BUFFER, modifiedSize, nullptr, GL_STATIC_DRAW);
9921 glGetTexLevelParameteriv(GL_TEXTURE_BUFFER, 0, GL_TEXTURE_WIDTH, &queryResult);
9922 ASSERT_GL_NO_ERROR();
9923 EXPECT_EQ(queryResult, modifiedSize / 4);
9924 }
9925 }
9926
9927 // Test that uploading data to buffer that's in use then using it as texture buffer works.
TEST_P(TextureBufferTestES31,UseAsUBOThenUpdateThenAsTextureBuffer)9928 TEST_P(TextureBufferTestES31, UseAsUBOThenUpdateThenAsTextureBuffer)
9929 {
9930 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
9931
9932 // Claims to support GL_OES_texture_buffer, but fails compilation of shader because "extension
9933 // 'GL_OES_texture_buffer' is not supported". http://anglebug.com/5832
9934 ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
9935
9936 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
9937 GLColor::red};
9938 const std::array<GLColor, 4> kUpdateData = {GLColor::blue, GLColor::blue, GLColor::blue,
9939 GLColor::blue};
9940
9941 GLBuffer buffer;
9942 glBindBuffer(GL_UNIFORM_BUFFER, buffer);
9943 glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
9944 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
9945 EXPECT_GL_NO_ERROR();
9946
9947 constexpr char kVerifyUBO[] = R"(#version 310 es
9948 precision mediump float;
9949 layout(binding = 0) uniform block {
9950 uvec4 data;
9951 } ubo;
9952 out vec4 colorOut;
9953 void main()
9954 {
9955 if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
9956 colorOut = vec4(0, 1.0, 0, 1.0);
9957 else
9958 colorOut = vec4(1.0, 0, 0, 1.0);
9959 })";
9960
9961 ANGLE_GL_PROGRAM(verifyUbo, essl31_shaders::vs::Simple(), kVerifyUBO);
9962 drawQuad(verifyUbo, essl31_shaders::PositionAttrib(), 0.5);
9963 EXPECT_GL_NO_ERROR();
9964
9965 // Update buffer data
9966 glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
9967 EXPECT_GL_NO_ERROR();
9968
9969 // Bind as texture buffer
9970 GLTexture texture;
9971 glBindTexture(GL_TEXTURE_BUFFER, texture);
9972 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
9973 EXPECT_GL_NO_ERROR();
9974
9975 constexpr char kVerifySamplerBuffer[] = R"(#version 310 es
9976 #extension GL_OES_texture_buffer : require
9977 precision mediump float;
9978 uniform highp samplerBuffer s;
9979 out vec4 colorOut;
9980 void main()
9981 {
9982 colorOut = texelFetch(s, 0);
9983 })";
9984
9985 ANGLE_GL_PROGRAM(verifySamplerBuffer, essl31_shaders::vs::Simple(), kVerifySamplerBuffer);
9986
9987 glEnable(GL_BLEND);
9988 glBlendFunc(GL_ONE, GL_ONE);
9989 drawQuad(verifySamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
9990 EXPECT_GL_NO_ERROR();
9991
9992 // Make sure both draw calls succeed
9993 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
9994 }
9995
9996 // Test that mapping a texture buffer with GL_MAP_INVALIDATE_BUFFER_BIT and writing to it works
9997 // correctly.
TEST_P(TextureBufferTestES31,MapTextureBufferInvalidateThenWrite)9998 TEST_P(TextureBufferTestES31, MapTextureBufferInvalidateThenWrite)
9999 {
10000 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_buffer"));
10001
10002 // TODO(http://anglebug.com/5832): Claims to support GL_OES_texture_buffer, but fails
10003 // compilation of shader because "extension 'GL_OES_texture_buffer' is not supported".
10004 ANGLE_SKIP_TEST_IF(IsQualcomm() && IsOpenGLES());
10005 // TODO(http://anglebug.com/6396): The OpenGL backend doesn't correctly handle texture buffers
10006 // being invalidated when mapped.
10007 ANGLE_SKIP_TEST_IF(IsOpenGL());
10008
10009 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
10010 GLColor::red};
10011 const std::array<GLColor, 4> kUpdateData = {GLColor::blue, GLColor::blue, GLColor::blue,
10012 GLColor::blue};
10013
10014 GLBuffer buffer;
10015 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
10016 glBufferData(GL_TEXTURE_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
10017 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
10018 EXPECT_GL_NO_ERROR();
10019
10020 // Bind as texture buffer
10021 GLTexture texture;
10022 glBindTexture(GL_TEXTURE_BUFFER, texture);
10023 glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA8, buffer);
10024 EXPECT_GL_NO_ERROR();
10025
10026 constexpr char kSamplerBuffer[] = R"(#version 310 es
10027 #extension GL_OES_texture_buffer : require
10028 precision mediump float;
10029 uniform highp samplerBuffer s;
10030 out vec4 colorOut;
10031 void main()
10032 {
10033 colorOut = texelFetch(s, 0);
10034 })";
10035
10036 ANGLE_GL_PROGRAM(initialSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
10037 drawQuad(initialSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
10038 EXPECT_GL_NO_ERROR();
10039
10040 // Don't read back, so we don't break the render pass.
10041
10042 // Map the buffer and update it.
10043 void *mappedBuffer = glMapBufferRange(GL_TEXTURE_BUFFER, 0, sizeof(kInitialData),
10044 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
10045 memcpy(mappedBuffer, kUpdateData.data(), sizeof(kInitialData));
10046
10047 // Draw with the updated buffer data.
10048 ANGLE_GL_PROGRAM(updateSamplerBuffer, essl31_shaders::vs::Simple(), kSamplerBuffer);
10049 drawQuad(updateSamplerBuffer, essl31_shaders::PositionAttrib(), 0.5);
10050 EXPECT_GL_NO_ERROR();
10051
10052 // Make sure both draw calls succeed
10053 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
10054 }
10055
10056 // Test that the correct error is generated if texture buffer support used anyway when not enabled.
TEST_P(TextureBufferTestES31,TestErrorWhenNotEnabled)10057 TEST_P(TextureBufferTestES31, TestErrorWhenNotEnabled)
10058 {
10059 ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_EXT_texture_buffer"));
10060
10061 GLTexture texture;
10062 glBindTexture(GL_TEXTURE_BUFFER, texture);
10063 ASSERT_GL_ERROR(GL_INVALID_ENUM);
10064 }
10065
10066 class CopyImageTestES31 : public ANGLETest
10067 {
10068 protected:
CopyImageTestES31()10069 CopyImageTestES31() {}
10070 };
10071
10072 // Test that copies between RGB formats doesn't affect the emulated alpha channel, if any.
TEST_P(CopyImageTestES31,PreserveEmulatedAlpha)10073 TEST_P(CopyImageTestES31, PreserveEmulatedAlpha)
10074 {
10075 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));
10076
10077 constexpr GLsizei kSize = 1;
10078
10079 GLTexture src, dst;
10080
10081 // Set up the textures
10082 glBindTexture(GL_TEXTURE_2D, src);
10083 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, kSize, kSize);
10084
10085 const GLColor kInitColor(50, 100, 150, 200);
10086 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGB, GL_UNSIGNED_BYTE, &kInitColor);
10087
10088 glBindTexture(GL_TEXTURE_2D, dst);
10089 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8UI, kSize, kSize);
10090 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10092
10093 // Copy from src to dst
10094 glCopyImageSubDataEXT(src, GL_TEXTURE_2D, 0, 0, 0, 0, dst, GL_TEXTURE_2D, 0, 0, 0, 0, kSize,
10095 kSize, 1);
10096
10097 // Bind dst as image
10098 glBindImageTexture(0, dst, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI);
10099
10100 // Create a buffer for output
10101 constexpr GLsizei kBufferSize = kSize * kSize * sizeof(uint32_t) * 4;
10102 GLBuffer buffer;
10103 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
10104 glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
10105 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, buffer);
10106
10107 constexpr char kCS[] = R"(#version 310 es
10108 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
10109 layout(rgba8ui, binding = 0) readonly uniform highp uimage2D imageIn;
10110 layout(std140, binding = 1) buffer dataOut {
10111 uvec4 data[];
10112 };
10113 void main()
10114 {
10115 uvec4 color = imageLoad(imageIn, ivec2(0));
10116 data[0] = color;
10117 })";
10118
10119 ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
10120 glUseProgram(program);
10121 glDispatchCompute(1, 1, 1);
10122 EXPECT_GL_NO_ERROR();
10123
10124 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
10125
10126 const uint32_t *ptr = reinterpret_cast<uint32_t *>(
10127 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
10128
10129 EXPECT_EQ(ptr[0], kInitColor.R);
10130 EXPECT_EQ(ptr[1], kInitColor.G);
10131 EXPECT_EQ(ptr[2], kInitColor.B);
10132
10133 // Expect alpha to be 1, even if the RGB format is emulated with RGBA.
10134 EXPECT_EQ(ptr[3], 1u);
10135
10136 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
10137 }
10138
10139 class TextureChangeStorageUploadTest : public ANGLETest
10140 {
10141 protected:
TextureChangeStorageUploadTest()10142 TextureChangeStorageUploadTest()
10143 {
10144 setWindowWidth(256);
10145 setWindowHeight(256);
10146 setConfigRedBits(8);
10147 setConfigGreenBits(8);
10148 setConfigBlueBits(8);
10149 setConfigAlphaBits(8);
10150 }
10151
testSetUp()10152 void testSetUp() override
10153 {
10154 mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
10155 if (mProgram == 0)
10156 {
10157 FAIL() << "shader compilation failed.";
10158 }
10159
10160 glUseProgram(mProgram);
10161
10162 glClearColor(0, 0, 0, 0);
10163 glClearDepthf(0.0);
10164 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
10165
10166 glEnable(GL_BLEND);
10167 glDisable(GL_DEPTH_TEST);
10168
10169 glGenTextures(1, &mTexture);
10170 ASSERT_GL_NO_ERROR();
10171 }
10172
testTearDown()10173 void testTearDown() override
10174 {
10175 glDeleteTextures(1, &mTexture);
10176 glDeleteProgram(mProgram);
10177 }
10178
10179 GLuint mProgram;
10180 GLint mColorLocation;
10181 GLuint mTexture;
10182 };
10183
10184 // Verify that respecifying storage and re-uploading doesn't crash.
TEST_P(TextureChangeStorageUploadTest,Basic)10185 TEST_P(TextureChangeStorageUploadTest, Basic)
10186 {
10187 constexpr int kImageSize = 8; // 4 doesn't trip ASAN
10188 constexpr int kSmallerImageSize = kImageSize / 2;
10189 EXPECT_GT(kImageSize, kSmallerImageSize);
10190 EXPECT_GT(kSmallerImageSize / 2, 0);
10191
10192 std::array<GLColor, kImageSize * kImageSize> kColor;
10193
10194 glBindTexture(GL_TEXTURE_2D, mTexture);
10195 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kImageSize, kImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
10196 kColor.data());
10197 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSmallerImageSize, kSmallerImageSize);
10198 // need partial update to sidestep optimizations that remove the full upload
10199 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSmallerImageSize / 2, kSmallerImageSize / 2, GL_RGBA,
10200 GL_UNSIGNED_BYTE, kColor.data());
10201 EXPECT_GL_NO_ERROR();
10202 }
10203
10204 class ExtraSamplerCubeShadowUseTest : public ANGLETest
10205 {
10206 protected:
ExtraSamplerCubeShadowUseTest()10207 ExtraSamplerCubeShadowUseTest() : ANGLETest() {}
10208
getVertexShaderSource()10209 const char *getVertexShaderSource() { return "#version 300 es\nvoid main() {}"; }
10210
getFragmentShaderSource()10211 const char *getFragmentShaderSource()
10212 {
10213 return R"(#version 300 es
10214 precision mediump float;
10215
10216 uniform mediump samplerCube var_0002; // this has to be there
10217 uniform highp samplerCubeShadow var_0004; // this has to be a cube shadow sampler
10218 out vec4 color;
10219 void main() {
10220
10221 vec4 var_0031 = texture(var_0002, vec3(1,1,1));
10222 ivec2 size = textureSize(var_0004, 0) ;
10223 var_0031.x += float(size.y);
10224
10225 color = var_0031;
10226 })";
10227 }
10228
testSetUp()10229 void testSetUp() override
10230 {
10231 mProgram = CompileProgram(getVertexShaderSource(), getFragmentShaderSource());
10232 if (mProgram == 0)
10233 {
10234 FAIL() << "shader compilation failed.";
10235 }
10236 glUseProgram(mProgram);
10237 ASSERT_GL_NO_ERROR();
10238 }
10239
testTearDown()10240 void testTearDown() override { glDeleteProgram(mProgram); }
10241
10242 GLuint mProgram;
10243 };
10244
TEST_P(ExtraSamplerCubeShadowUseTest,Basic)10245 TEST_P(ExtraSamplerCubeShadowUseTest, Basic)
10246 {
10247 glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
10248 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
10249 }
10250
10251 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
10252 // tests should be run against.
10253 #define ES2_EMULATE_COPY_TEX_IMAGE() \
10254 WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGL()), \
10255 WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGLES())
10256 #define ES3_EMULATE_COPY_TEX_IMAGE() \
10257 WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()), \
10258 WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES())
10259 ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ES2_EMULATE_COPY_TEX_IMAGE());
10260 ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
10261 ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
10262 ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
10263 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
10264 ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
10265
10266 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES3);
10267 ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DTestES3, WithAllocateNonZeroMemory(ES3_VULKAN()));
10268
10269 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DTestES31PPO);
10270 ANGLE_INSTANTIATE_TEST_ES31(Texture2DTestES31PPO);
10271
10272 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DBaseMaxTestES3);
10273 ANGLE_INSTANTIATE_TEST_ES3(Texture2DBaseMaxTestES3);
10274
10275 ANGLE_INSTANTIATE_TEST_ES2(Texture3DTestES2);
10276
10277 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DTestES3);
10278 ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
10279
10280 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerAlpha1TestES3);
10281 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
10282
10283 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DUnsignedIntegerAlpha1TestES3);
10284 ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
10285
10286 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShadowSamplerPlusSampler3DTestES3);
10287 ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
10288
10289 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplerTypeMixTestES3);
10290 ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
10291
10292 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayTestES3);
10293 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
10294
10295 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureSizeTextureArrayTest);
10296 ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
10297
10298 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
10299 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
10300 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
10301 ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
10302 ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
10303 ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
10304 ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
10305
10306 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBorderClampTestES3);
10307 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
10308
10309 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBorderClampIntegerTestES3);
10310 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
10311
10312 ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
10313
10314 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DNorm16TestES3);
10315 ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
10316
10317 ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
10318 ANGLE_ALL_TEST_PLATFORMS_ES2,
10319 ANGLE_ALL_TEST_PLATFORMS_ES3,
10320 ES2_EMULATE_COPY_TEX_IMAGE(),
10321 ES3_EMULATE_COPY_TEX_IMAGE());
10322
10323 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DFloatTestES3);
10324 ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
10325
10326 ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
10327
10328 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeTestES3);
10329 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
10330
10331 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerTestES3);
10332 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
10333
10334 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeIntegerTestES3);
10335 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
10336
10337 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureCubeIntegerEdgeTestES3);
10338 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
10339
10340 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerProjectiveOffsetTestES3);
10341 ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
10342
10343 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayIntegerTestES3);
10344 ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
10345
10346 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DIntegerTestES3);
10347 ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
10348
10349 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
10350 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
10351 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
10352
10353 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES31);
10354 ANGLE_INSTANTIATE_TEST_ES31(TextureBufferTestES31);
10355
10356 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyImageTestES31);
10357 ANGLE_INSTANTIATE_TEST_ES31(CopyImageTestES31);
10358
10359 ANGLE_INSTANTIATE_TEST_ES3(TextureChangeStorageUploadTest);
10360
10361 ANGLE_INSTANTIATE_TEST_ES3(ExtraSamplerCubeShadowUseTest);
10362
10363 } // anonymous namespace
10364