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