blob: 40f21622b92e75cc52ef1b5ea92dc04f4180d981 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
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
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Jamie Madillf67115c2014-04-22 13:14:05 -04008
Jamie Madillfa05f602015-05-07 13:47:11 -04009using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070010
Jamie Madillfa05f602015-05-07 13:47:11 -040011namespace
12{
13
Olli Etuaho4a8329f2016-01-11 17:12:57 +020014class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -040015{
Jamie Madillbc393df2015-01-29 13:46:07 -050016 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020017 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -040018 {
19 setWindowWidth(128);
20 setWindowHeight(128);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 }
26
Olli Etuaho4a8329f2016-01-11 17:12:57 +020027 virtual std::string getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -040028 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020029 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040030 (
31 precision highp float;
32 attribute vec4 position;
33 varying vec2 texcoord;
34
35 void main()
36 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020037 gl_Position = vec4(position.xy, 0.0, 1.0);
Geoff Langc41e42d2014-04-28 10:58:16 -040038 texcoord = (position.xy * 0.5) + 0.5;
39 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +020040 )
Geoff Langc41e42d2014-04-28 10:58:16 -040041 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +020042 }
Geoff Langc41e42d2014-04-28 10:58:16 -040043
Olli Etuaho4a8329f2016-01-11 17:12:57 +020044 virtual std::string getFragmentShaderSource() = 0;
45
Olli Etuahoa1c917f2016-04-06 13:50:03 +030046 virtual void setUpProgram()
Olli Etuaho4a8329f2016-01-11 17:12:57 +020047 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020048 const std::string vertexShaderSource = getVertexShaderSource();
49 const std::string fragmentShaderSource = getFragmentShaderSource();
50
51 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
52 ASSERT_NE(0u, mProgram);
53 ASSERT_GL_NO_ERROR();
Olli Etuahoa1c917f2016-04-06 13:50:03 +030054 }
55
56 void SetUp() override
57 {
58 ANGLETest::SetUp();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020059
60 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020061 }
62
63 void TearDown() override
64 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020065 glBindFramebuffer(GL_FRAMEBUFFER, 0);
66 glDeleteFramebuffers(1, &mFramebuffer);
67 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020068 glDeleteProgram(mProgram);
69 ANGLETest::TearDown();
70 }
71
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020072 void setUpFramebuffer()
73 {
74 // We use an FBO to work around an issue where the default framebuffer applies SRGB
75 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
76 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
77 // section 4.4 says that the format of the default framebuffer is entirely up to the window
78 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
79 // SRGB conversion like desktop GL does.
80 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
81 glGenFramebuffers(1, &mFramebuffer);
82 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
83
84 glGenTextures(1, &mFramebufferColorTexture);
85 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
86 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
87 GL_UNSIGNED_BYTE, nullptr);
88 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
89 mFramebufferColorTexture, 0);
90 ASSERT_GL_NO_ERROR();
91 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
92 glBindTexture(GL_TEXTURE_2D, 0);
93 }
94
Olli Etuaho4a8329f2016-01-11 17:12:57 +020095 // Returns the created texture ID.
96 GLuint create2DTexture()
97 {
98 GLuint texture2D;
99 glGenTextures(1, &texture2D);
100 glBindTexture(GL_TEXTURE_2D, texture2D);
101 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
102 EXPECT_GL_NO_ERROR();
103 return texture2D;
104 }
105
106 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200107 GLuint mFramebuffer;
108
109 private:
110 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200111};
112
113class Texture2DTest : public TexCoordDrawTest
114{
115 protected:
116 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
117
118 std::string getFragmentShaderSource() override
119 {
120 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400121 (
122 precision highp float;
123 uniform sampler2D tex;
124 varying vec2 texcoord;
125
126 void main()
127 {
128 gl_FragColor = texture2D(tex, texcoord);
129 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200130 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400131 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200132 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400133
Olli Etuaho96963162016-03-21 11:54:33 +0200134 virtual const char *getTextureUniformName() { return "tex"; }
135
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300136 void setUpProgram() override
137 {
138 TexCoordDrawTest::setUpProgram();
139 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
140 ASSERT_NE(-1, mTexture2DUniformLocation);
141 }
142
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200143 void SetUp() override
144 {
145 TexCoordDrawTest::SetUp();
146 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400147
Jamie Madill9aca0592014-10-06 16:26:59 -0400148 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -0400149 }
150
Jamie Madillfa05f602015-05-07 13:47:11 -0400151 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400152 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400153 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200154 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400155 }
156
Jamie Madillbc393df2015-01-29 13:46:07 -0500157 // Tests CopyTexSubImage with floating point textures of various formats.
158 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
159 {
Geoff Langbde666a2015-04-07 17:17:08 -0400160 // TODO(jmadill): Figure out why this is broken on Intel D3D11
Jamie Madill518b9fa2016-03-02 11:26:02 -0500161 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Geoff Langbde666a2015-04-07 17:17:08 -0400162 {
163 std::cout << "Test skipped on Intel D3D11." << std::endl;
164 return;
165 }
166
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300167 setUpProgram();
168
Geoff Langfbfa47c2015-03-31 11:26:00 -0400169 if (getClientVersion() < 3)
170 {
171 if (!extensionEnabled("GL_OES_texture_float"))
172 {
173 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
174 return;
175 }
176
177 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
178 {
179 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
180 return;
181 }
182 }
183
Jamie Madillbc393df2015-01-29 13:46:07 -0500184 GLfloat sourceImageData[4][16] =
185 {
186 { // R
187 1.0f,
188 0.0f,
189 0.0f,
190 1.0f
191 },
192 { // RG
193 1.0f, 0.0f,
194 0.0f, 1.0f,
195 0.0f, 0.0f,
196 1.0f, 1.0f
197 },
198 { // RGB
199 1.0f, 0.0f, 0.0f,
200 0.0f, 1.0f, 0.0f,
201 0.0f, 0.0f, 1.0f,
202 1.0f, 1.0f, 0.0f
203 },
204 { // RGBA
205 1.0f, 0.0f, 0.0f, 1.0f,
206 0.0f, 1.0f, 0.0f, 1.0f,
207 0.0f, 0.0f, 1.0f, 1.0f,
208 1.0f, 1.0f, 0.0f, 1.0f
209 },
210 };
211
212 GLenum imageFormats[] =
213 {
214 GL_R32F,
215 GL_RG32F,
216 GL_RGB32F,
217 GL_RGBA32F,
218 };
219
220 GLenum sourceUnsizedFormats[] =
221 {
222 GL_RED,
223 GL_RG,
224 GL_RGB,
225 GL_RGBA,
226 };
227
228 GLuint textures[2];
229
230 glGenTextures(2, textures);
231
232 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
233 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
234 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
235 GLenum destImageFormat = imageFormats[destImageChannels - 1];
236
237 glBindTexture(GL_TEXTURE_2D, textures[0]);
238 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
241 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
242
hendrikwb27f79a2015-03-04 11:26:46 -0800243 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500244 {
245 // This is not supported
246 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
247 }
248 else
249 {
250 ASSERT_GL_NO_ERROR();
251 }
252
253 GLuint fbo;
254 glGenFramebuffers(1, &fbo);
255 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
256 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
257
258 glBindTexture(GL_TEXTURE_2D, textures[1]);
259 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
262
263 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
264 ASSERT_GL_NO_ERROR();
265
266 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200267 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500268
269 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
270
Olli Etuahoa314b612016-03-10 16:43:00 +0200271 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Jamie Madillbc393df2015-01-29 13:46:07 -0500272 if (testImageChannels > 1)
273 {
274 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
275 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
276 if (testImageChannels > 2)
277 {
278 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
279 }
280 }
281
282 glDeleteFramebuffers(1, &fbo);
283 glDeleteTextures(2, textures);
284
285 ASSERT_GL_NO_ERROR();
286 }
287
Jamie Madilld4cfa572014-07-08 10:00:32 -0400288 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400289 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400290};
291
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200292class Texture2DTestES3 : public Texture2DTest
293{
294 protected:
295 Texture2DTestES3() : Texture2DTest() {}
296
297 std::string getVertexShaderSource() override
298 {
299 return std::string(
300 "#version 300 es\n"
301 "out vec2 texcoord;\n"
302 "in vec4 position;\n"
303 "void main()\n"
304 "{\n"
305 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
306 " texcoord = (position.xy * 0.5) + 0.5;\n"
307 "}\n");
308 }
309
310 std::string getFragmentShaderSource() override
311 {
312 return std::string(
313 "#version 300 es\n"
314 "precision highp float;\n"
315 "uniform highp sampler2D tex;\n"
316 "in vec2 texcoord;\n"
317 "out vec4 fragColor;\n"
318 "void main()\n"
319 "{\n"
320 " fragColor = texture(tex, texcoord);\n"
321 "}\n");
322 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300323
324 void SetUp() override
325 {
326 Texture2DTest::SetUp();
327 setUpProgram();
328 }
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200329};
330
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200331class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
332{
333 protected:
334 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
335
336 std::string getVertexShaderSource() override
337 {
338 return std::string(
339 "#version 300 es\n"
340 "out vec2 texcoord;\n"
341 "in vec4 position;\n"
342 "void main()\n"
343 "{\n"
344 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
345 " texcoord = (position.xy * 0.5) + 0.5;\n"
346 "}\n");
347 }
348
349 std::string getFragmentShaderSource() override
350 {
351 return std::string(
352 "#version 300 es\n"
353 "precision highp float;\n"
354 "uniform highp isampler2D tex;\n"
355 "in vec2 texcoord;\n"
356 "out vec4 fragColor;\n"
357 "void main()\n"
358 "{\n"
359 " vec4 green = vec4(0, 1, 0, 1);\n"
360 " vec4 black = vec4(0, 0, 0, 0);\n"
361 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
362 "}\n");
363 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300364
365 void SetUp() override
366 {
367 Texture2DTest::SetUp();
368 setUpProgram();
369 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200370};
371
372class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
373{
374 protected:
375 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
376
377 std::string getVertexShaderSource() override
378 {
379 return std::string(
380 "#version 300 es\n"
381 "out vec2 texcoord;\n"
382 "in vec4 position;\n"
383 "void main()\n"
384 "{\n"
385 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
386 " texcoord = (position.xy * 0.5) + 0.5;\n"
387 "}\n");
388 }
389
390 std::string getFragmentShaderSource() override
391 {
392 return std::string(
393 "#version 300 es\n"
394 "precision highp float;\n"
395 "uniform highp usampler2D tex;\n"
396 "in vec2 texcoord;\n"
397 "out vec4 fragColor;\n"
398 "void main()\n"
399 "{\n"
400 " vec4 green = vec4(0, 1, 0, 1);\n"
401 " vec4 black = vec4(0, 0, 0, 0);\n"
402 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
403 "}\n");
404 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300405
406 void SetUp() override
407 {
408 Texture2DTest::SetUp();
409 setUpProgram();
410 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200411};
412
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200413class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400414{
415 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200416 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
417
418 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400419 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200420 return std::string(SHADER_SOURCE
421 (
422 precision highp float;
423 attribute vec4 position;
424 varying vec2 texcoord;
425
426 uniform vec2 drawScale;
427
428 void main()
429 {
430 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
431 texcoord = (position.xy * 0.5) + 0.5;
432 }
433 )
434 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400435 }
436
437 void SetUp() override
438 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200439 Texture2DTest::SetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300440
441 setUpProgram();
442
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200443 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
444 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400445
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200446 glUseProgram(mProgram);
447 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
448 glUseProgram(0);
449 ASSERT_GL_NO_ERROR();
450 }
451
452 GLint mDrawScaleUniformLocation;
453};
454
Olli Etuaho4644a202016-01-12 15:12:53 +0200455class Sampler2DAsFunctionParameterTest : public Texture2DTest
456{
457 protected:
458 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
459
460 std::string getFragmentShaderSource() override
461 {
462 return std::string(SHADER_SOURCE
463 (
464 precision highp float;
465 uniform sampler2D tex;
466 varying vec2 texcoord;
467
468 vec4 computeFragColor(sampler2D aTex)
469 {
470 return texture2D(aTex, texcoord);
471 }
472
473 void main()
474 {
475 gl_FragColor = computeFragColor(tex);
476 }
477 )
478 );
479 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300480
481 void SetUp() override
482 {
483 Texture2DTest::SetUp();
484 setUpProgram();
485 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200486};
487
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200488class TextureCubeTest : public TexCoordDrawTest
489{
490 protected:
491 TextureCubeTest()
492 : TexCoordDrawTest(),
493 mTexture2D(0),
494 mTextureCube(0),
495 mTexture2DUniformLocation(-1),
496 mTextureCubeUniformLocation(-1)
497 {
498 }
499
500 std::string getFragmentShaderSource() override
501 {
502 return std::string(SHADER_SOURCE
503 (
504 precision highp float;
505 uniform sampler2D tex2D;
506 uniform samplerCube texCube;
507 varying vec2 texcoord;
508
509 void main()
510 {
511 gl_FragColor = texture2D(tex2D, texcoord);
512 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
513 }
514 )
515 );
516 }
517
518 void SetUp() override
519 {
520 TexCoordDrawTest::SetUp();
521
522 glGenTextures(1, &mTextureCube);
523 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
524 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
525 EXPECT_GL_NO_ERROR();
526
527 mTexture2D = create2DTexture();
528
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300529 setUpProgram();
530
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200531 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
532 ASSERT_NE(-1, mTexture2DUniformLocation);
533 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
534 ASSERT_NE(-1, mTextureCubeUniformLocation);
535 }
536
537 void TearDown() override
538 {
539 glDeleteTextures(1, &mTextureCube);
540 TexCoordDrawTest::TearDown();
541 }
542
543 GLuint mTexture2D;
544 GLuint mTextureCube;
545 GLint mTexture2DUniformLocation;
546 GLint mTextureCubeUniformLocation;
547};
548
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200549class SamplerArrayTest : public TexCoordDrawTest
550{
551 protected:
552 SamplerArrayTest()
553 : TexCoordDrawTest(),
554 mTexture2DA(0),
555 mTexture2DB(0),
556 mTexture0UniformLocation(-1),
557 mTexture1UniformLocation(-1)
558 {
559 }
560
561 std::string getFragmentShaderSource() override
562 {
563 return std::string(SHADER_SOURCE
564 (
565 precision mediump float;
566 uniform highp sampler2D tex2DArray[2];
567 varying vec2 texcoord;
568 void main()
569 {
570 gl_FragColor = texture2D(tex2DArray[0], texcoord);
571 gl_FragColor += texture2D(tex2DArray[1], texcoord);
572 }
573 )
574 );
575 }
576
577 void SetUp() override
578 {
579 TexCoordDrawTest::SetUp();
580
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300581 setUpProgram();
582
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200583 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
584 ASSERT_NE(-1, mTexture0UniformLocation);
585 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
586 ASSERT_NE(-1, mTexture1UniformLocation);
587
588 mTexture2DA = create2DTexture();
589 mTexture2DB = create2DTexture();
590 ASSERT_GL_NO_ERROR();
591 }
592
593 void TearDown() override
594 {
595 glDeleteTextures(1, &mTexture2DA);
596 glDeleteTextures(1, &mTexture2DB);
597 TexCoordDrawTest::TearDown();
598 }
599
600 void testSamplerArrayDraw()
601 {
602 GLubyte texData[4];
603 texData[0] = 0;
604 texData[1] = 60;
605 texData[2] = 0;
606 texData[3] = 255;
607
608 glActiveTexture(GL_TEXTURE0);
609 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
610 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
611
612 texData[1] = 120;
613 glActiveTexture(GL_TEXTURE1);
614 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
615 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
616 EXPECT_GL_ERROR(GL_NO_ERROR);
617
618 glUseProgram(mProgram);
619 glUniform1i(mTexture0UniformLocation, 0);
620 glUniform1i(mTexture1UniformLocation, 1);
621 drawQuad(mProgram, "position", 0.5f);
622 EXPECT_GL_NO_ERROR();
623
624 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
625 }
626
627 GLuint mTexture2DA;
628 GLuint mTexture2DB;
629 GLint mTexture0UniformLocation;
630 GLint mTexture1UniformLocation;
631};
632
633
634class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
635{
636 protected:
637 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
638
639 std::string getFragmentShaderSource() override
640 {
641 return std::string(SHADER_SOURCE
642 (
643 precision mediump float;
644 uniform highp sampler2D tex2DArray[2];
645 varying vec2 texcoord;
646
647 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
648 {
649 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
650 }
651
652 void main()
653 {
654 gl_FragColor = computeFragColor(tex2DArray);
655 }
656 )
657 );
658 }
659};
660
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200661class Texture2DArrayTestES3 : public TexCoordDrawTest
662{
663 protected:
664 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
665
666 std::string getVertexShaderSource() override
667 {
668 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400669 "#version 300 es\n"
670 "out vec2 texcoord;\n"
671 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200672 "void main()\n"
673 "{\n"
674 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
675 " texcoord = (position.xy * 0.5) + 0.5;\n"
676 "}\n");
677 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400678
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200679 std::string getFragmentShaderSource() override
680 {
681 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400682 "#version 300 es\n"
683 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200684 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400685 "in vec2 texcoord;\n"
686 "out vec4 fragColor;\n"
687 "void main()\n"
688 "{\n"
689 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200690 "}\n");
691 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400692
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200693 void SetUp() override
694 {
695 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400696
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300697 setUpProgram();
698
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200699 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400700 ASSERT_NE(-1, mTextureArrayLocation);
701
702 glGenTextures(1, &m2DArrayTexture);
703 ASSERT_GL_NO_ERROR();
704 }
705
706 void TearDown() override
707 {
708 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200709 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400710 }
711
712 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400713 GLint mTextureArrayLocation;
714};
715
Olli Etuahobce743a2016-01-15 17:18:28 +0200716class TextureSizeTextureArrayTest : public TexCoordDrawTest
717{
718 protected:
719 TextureSizeTextureArrayTest()
720 : TexCoordDrawTest(),
721 mTexture2DA(0),
722 mTexture2DB(0),
723 mTexture0Location(-1),
724 mTexture1Location(-1)
725 {
726 }
727
728 std::string getVertexShaderSource() override
729 {
730 return std::string(
731 "#version 300 es\n"
732 "in vec4 position;\n"
733 "void main()\n"
734 "{\n"
735 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
736 "}\n");
737 }
738
739 std::string getFragmentShaderSource() override
740 {
741 return std::string(
742 "#version 300 es\n"
743 "precision highp float;\n"
744 "uniform highp sampler2D tex2DArray[2];\n"
745 "out vec4 fragColor;\n"
746 "void main()\n"
747 "{\n"
748 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
749 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
750 " fragColor = vec4(red, green, 0.0, 1.0);\n"
751 "}\n");
752 }
753
754 void SetUp() override
755 {
756 TexCoordDrawTest::SetUp();
757
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300758 setUpProgram();
759
Olli Etuahobce743a2016-01-15 17:18:28 +0200760 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
761 ASSERT_NE(-1, mTexture0Location);
762 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
763 ASSERT_NE(-1, mTexture1Location);
764
765 mTexture2DA = create2DTexture();
766 mTexture2DB = create2DTexture();
767 ASSERT_GL_NO_ERROR();
768 }
769
770 void TearDown() override
771 {
772 glDeleteTextures(1, &mTexture2DA);
773 glDeleteTextures(1, &mTexture2DB);
774 TexCoordDrawTest::TearDown();
775 }
776
777 GLuint mTexture2DA;
778 GLuint mTexture2DB;
779 GLint mTexture0Location;
780 GLint mTexture1Location;
781};
782
Olli Etuahoa314b612016-03-10 16:43:00 +0200783class Texture3DTestES3 : public TexCoordDrawTest
784{
785 protected:
786 Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
787
788 std::string getVertexShaderSource() override
789 {
790 return std::string(
791 "#version 300 es\n"
792 "out vec2 texcoord;\n"
793 "in vec4 position;\n"
794 "void main()\n"
795 "{\n"
796 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
797 " texcoord = (position.xy * 0.5) + 0.5;\n"
798 "}\n");
799 }
800
801 std::string getFragmentShaderSource() override
802 {
803 return std::string(
804 "#version 300 es\n"
805 "precision highp float;\n"
806 "uniform highp sampler3D tex3D;\n"
807 "in vec2 texcoord;\n"
808 "out vec4 fragColor;\n"
809 "void main()\n"
810 "{\n"
811 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
812 "}\n");
813 }
814
815 void SetUp() override
816 {
817 TexCoordDrawTest::SetUp();
818
819 glGenTextures(1, &mTexture3D);
820
821 setUpProgram();
822
823 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
824 ASSERT_NE(-1, mTexture3DUniformLocation);
825 }
826
827 void TearDown() override
828 {
829 glDeleteTextures(1, &mTexture3D);
830 TexCoordDrawTest::TearDown();
831 }
832
833 GLuint mTexture3D;
834 GLint mTexture3DUniformLocation;
835};
836
Olli Etuaho1a679902016-01-14 12:21:47 +0200837class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
838{
839 protected:
840 ShadowSamplerPlusSampler3DTestES3()
841 : TexCoordDrawTest(),
842 mTextureShadow(0),
843 mTexture3D(0),
844 mTextureShadowUniformLocation(-1),
845 mTexture3DUniformLocation(-1),
846 mDepthRefUniformLocation(-1)
847 {
848 }
849
850 std::string getVertexShaderSource() override
851 {
852 return std::string(
853 "#version 300 es\n"
854 "out vec2 texcoord;\n"
855 "in vec4 position;\n"
856 "void main()\n"
857 "{\n"
858 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
859 " texcoord = (position.xy * 0.5) + 0.5;\n"
860 "}\n");
861 }
862
863 std::string getFragmentShaderSource() override
864 {
865 return std::string(
866 "#version 300 es\n"
867 "precision highp float;\n"
868 "uniform highp sampler2DShadow tex2DShadow;\n"
869 "uniform highp sampler3D tex3D;\n"
870 "in vec2 texcoord;\n"
871 "uniform float depthRef;\n"
872 "out vec4 fragColor;\n"
873 "void main()\n"
874 "{\n"
875 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
876 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
877 "}\n");
878 }
879
880 void SetUp() override
881 {
882 TexCoordDrawTest::SetUp();
883
884 glGenTextures(1, &mTexture3D);
885
886 glGenTextures(1, &mTextureShadow);
887 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
888 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
889
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300890 setUpProgram();
891
Olli Etuaho1a679902016-01-14 12:21:47 +0200892 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
893 ASSERT_NE(-1, mTextureShadowUniformLocation);
894 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
895 ASSERT_NE(-1, mTexture3DUniformLocation);
896 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
897 ASSERT_NE(-1, mDepthRefUniformLocation);
898 }
899
900 void TearDown() override
901 {
902 glDeleteTextures(1, &mTextureShadow);
903 glDeleteTextures(1, &mTexture3D);
904 TexCoordDrawTest::TearDown();
905 }
906
907 GLuint mTextureShadow;
908 GLuint mTexture3D;
909 GLint mTextureShadowUniformLocation;
910 GLint mTexture3DUniformLocation;
911 GLint mDepthRefUniformLocation;
912};
913
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200914class SamplerTypeMixTestES3 : public TexCoordDrawTest
915{
916 protected:
917 SamplerTypeMixTestES3()
918 : TexCoordDrawTest(),
919 mTexture2D(0),
920 mTextureCube(0),
921 mTexture2DShadow(0),
922 mTextureCubeShadow(0),
923 mTexture2DUniformLocation(-1),
924 mTextureCubeUniformLocation(-1),
925 mTexture2DShadowUniformLocation(-1),
926 mTextureCubeShadowUniformLocation(-1),
927 mDepthRefUniformLocation(-1)
928 {
929 }
930
931 std::string getVertexShaderSource() override
932 {
933 return std::string(
934 "#version 300 es\n"
935 "out vec2 texcoord;\n"
936 "in vec4 position;\n"
937 "void main()\n"
938 "{\n"
939 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
940 " texcoord = (position.xy * 0.5) + 0.5;\n"
941 "}\n");
942 }
943
944 std::string getFragmentShaderSource() override
945 {
946 return std::string(
947 "#version 300 es\n"
948 "precision highp float;\n"
949 "uniform highp sampler2D tex2D;\n"
950 "uniform highp samplerCube texCube;\n"
951 "uniform highp sampler2DShadow tex2DShadow;\n"
952 "uniform highp samplerCubeShadow texCubeShadow;\n"
953 "in vec2 texcoord;\n"
954 "uniform float depthRef;\n"
955 "out vec4 fragColor;\n"
956 "void main()\n"
957 "{\n"
958 " fragColor = texture(tex2D, texcoord);\n"
959 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
960 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
961 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
962 "0.125);\n"
963 "}\n");
964 }
965
966 void SetUp() override
967 {
968 TexCoordDrawTest::SetUp();
969
970 glGenTextures(1, &mTexture2D);
971 glGenTextures(1, &mTextureCube);
972
973 glGenTextures(1, &mTexture2DShadow);
974 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
975 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
976
977 glGenTextures(1, &mTextureCubeShadow);
978 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
979 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
980
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300981 setUpProgram();
982
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200983 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
984 ASSERT_NE(-1, mTexture2DUniformLocation);
985 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
986 ASSERT_NE(-1, mTextureCubeUniformLocation);
987 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
988 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
989 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
990 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
991 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
992 ASSERT_NE(-1, mDepthRefUniformLocation);
993
994 ASSERT_GL_NO_ERROR();
995 }
996
997 void TearDown() override
998 {
999 glDeleteTextures(1, &mTexture2D);
1000 glDeleteTextures(1, &mTextureCube);
1001 glDeleteTextures(1, &mTexture2DShadow);
1002 glDeleteTextures(1, &mTextureCubeShadow);
1003 TexCoordDrawTest::TearDown();
1004 }
1005
1006 GLuint mTexture2D;
1007 GLuint mTextureCube;
1008 GLuint mTexture2DShadow;
1009 GLuint mTextureCubeShadow;
1010 GLint mTexture2DUniformLocation;
1011 GLint mTextureCubeUniformLocation;
1012 GLint mTexture2DShadowUniformLocation;
1013 GLint mTextureCubeShadowUniformLocation;
1014 GLint mDepthRefUniformLocation;
1015};
1016
Olli Etuaho96963162016-03-21 11:54:33 +02001017class SamplerInStructTest : public Texture2DTest
1018{
1019 protected:
1020 SamplerInStructTest() : Texture2DTest() {}
1021
1022 const char *getTextureUniformName() override { return "us.tex"; }
1023
1024 std::string getFragmentShaderSource() override
1025 {
1026 return std::string(
1027 "precision highp float;\n"
1028 "struct S\n"
1029 "{\n"
1030 " vec4 a;\n"
1031 " highp sampler2D tex;\n"
1032 "};\n"
1033 "uniform S us;\n"
1034 "varying vec2 texcoord;\n"
1035 "void main()\n"
1036 "{\n"
1037 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1038 "}\n");
1039 }
1040
1041 void runSamplerInStructTest()
1042 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001043 setUpProgram();
1044
Olli Etuaho96963162016-03-21 11:54:33 +02001045 glActiveTexture(GL_TEXTURE0);
1046 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001047 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1048 &GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001049 drawQuad(mProgram, "position", 0.5f);
Olli Etuahoa314b612016-03-10 16:43:00 +02001050 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001051 }
1052};
1053
1054class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1055{
1056 protected:
1057 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1058
1059 std::string getFragmentShaderSource() override
1060 {
1061 return std::string(
1062 "precision highp float;\n"
1063 "struct S\n"
1064 "{\n"
1065 " vec4 a;\n"
1066 " highp sampler2D tex;\n"
1067 "};\n"
1068 "uniform S us;\n"
1069 "varying vec2 texcoord;\n"
1070 "vec4 sampleFrom(S s) {\n"
1071 " return texture2D(s.tex, texcoord + s.a.x);\n"
1072 "}\n"
1073 "void main()\n"
1074 "{\n"
1075 " gl_FragColor = sampleFrom(us);\n"
1076 "}\n");
1077 }
1078};
1079
1080class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1081{
1082 protected:
1083 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1084
1085 const char *getTextureUniformName() override { return "us[0].tex"; }
1086
1087 std::string getFragmentShaderSource() override
1088 {
1089 return std::string(
1090 "precision highp float;\n"
1091 "struct S\n"
1092 "{\n"
1093 " vec4 a;\n"
1094 " highp sampler2D tex;\n"
1095 "};\n"
1096 "uniform S us[1];\n"
1097 "varying vec2 texcoord;\n"
1098 "vec4 sampleFrom(S s) {\n"
1099 " return texture2D(s.tex, texcoord + s.a.x);\n"
1100 "}\n"
1101 "void main()\n"
1102 "{\n"
1103 " gl_FragColor = sampleFrom(us[0]);\n"
1104 "}\n");
1105 }
1106};
1107
1108class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1109{
1110 protected:
1111 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1112
1113 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1114
1115 std::string getFragmentShaderSource() override
1116 {
1117 return std::string(
1118 "precision highp float;\n"
1119 "struct SUB\n"
1120 "{\n"
1121 " vec4 a;\n"
1122 " highp sampler2D tex;\n"
1123 "};\n"
1124 "struct S\n"
1125 "{\n"
1126 " SUB sub;\n"
1127 "};\n"
1128 "uniform S us[1];\n"
1129 "varying vec2 texcoord;\n"
1130 "vec4 sampleFrom(SUB s) {\n"
1131 " return texture2D(s.tex, texcoord + s.a.x);\n"
1132 "}\n"
1133 "void main()\n"
1134 "{\n"
1135 " gl_FragColor = sampleFrom(us[0].sub);\n"
1136 "}\n");
1137 }
1138};
1139
1140class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1141{
1142 protected:
1143 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1144
1145 std::string getFragmentShaderSource() override
1146 {
1147 return std::string(
1148 "precision highp float;\n"
1149 "struct S\n"
1150 "{\n"
1151 " vec4 a;\n"
1152 " highp sampler2D tex;\n"
1153 "};\n"
1154 "uniform S us;\n"
1155 "uniform float us_tex;\n"
1156 "varying vec2 texcoord;\n"
1157 "void main()\n"
1158 "{\n"
1159 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1160 "}\n");
1161 }
1162};
1163
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001164TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001165{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001166 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001167 EXPECT_GL_ERROR(GL_NO_ERROR);
1168
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001169 setUpProgram();
1170
Jamie Madillf67115c2014-04-22 13:14:05 -04001171 const GLubyte *pixels[20] = { 0 };
1172 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1173 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1174}
Geoff Langc41e42d2014-04-28 10:58:16 -04001175
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001176TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001177{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001178 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001179 EXPECT_GL_ERROR(GL_NO_ERROR);
1180
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001181 setUpProgram();
1182
Geoff Langc41e42d2014-04-28 10:58:16 -04001183 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001184 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001185 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001186 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001187
1188 const GLubyte *pixel[4] = { 0 };
1189
1190 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1191 EXPECT_GL_NO_ERROR();
1192
1193 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1194 EXPECT_GL_NO_ERROR();
1195
1196 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1197 EXPECT_GL_NO_ERROR();
1198}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001199
1200// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001201TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001202{
1203 glActiveTexture(GL_TEXTURE0);
1204 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1205 glActiveTexture(GL_TEXTURE1);
1206 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1207 EXPECT_GL_ERROR(GL_NO_ERROR);
1208
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001209 glUseProgram(mProgram);
1210 glUniform1i(mTexture2DUniformLocation, 0);
1211 glUniform1i(mTextureCubeUniformLocation, 1);
1212 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001213 EXPECT_GL_NO_ERROR();
1214}
Jamie Madill9aca0592014-10-06 16:26:59 -04001215
Olli Etuaho53a2da12016-01-11 15:43:32 +02001216// Test drawing with two texture types accessed from the same shader and check that the result of
1217// drawing is correct.
1218TEST_P(TextureCubeTest, CubeMapDraw)
1219{
1220 GLubyte texData[4];
1221 texData[0] = 0;
1222 texData[1] = 60;
1223 texData[2] = 0;
1224 texData[3] = 255;
1225
1226 glActiveTexture(GL_TEXTURE0);
1227 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1228 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1229
1230 glActiveTexture(GL_TEXTURE1);
1231 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1232 texData[1] = 120;
1233 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1234 texData);
1235 EXPECT_GL_ERROR(GL_NO_ERROR);
1236
1237 glUseProgram(mProgram);
1238 glUniform1i(mTexture2DUniformLocation, 0);
1239 glUniform1i(mTextureCubeUniformLocation, 1);
1240 drawQuad(mProgram, "position", 0.5f);
1241 EXPECT_GL_NO_ERROR();
1242
1243 int px = getWindowWidth() - 1;
1244 int py = 0;
1245 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1246}
1247
Olli Etuaho4644a202016-01-12 15:12:53 +02001248TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1249{
1250 glActiveTexture(GL_TEXTURE0);
1251 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1252 GLubyte texData[4];
1253 texData[0] = 0;
1254 texData[1] = 128;
1255 texData[2] = 0;
1256 texData[3] = 255;
1257 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1258 glUseProgram(mProgram);
1259 glUniform1i(mTexture2DUniformLocation, 0);
1260 drawQuad(mProgram, "position", 0.5f);
1261 EXPECT_GL_NO_ERROR();
1262
1263 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1264}
1265
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001266// Test drawing with two textures passed to the shader in a sampler array.
1267TEST_P(SamplerArrayTest, SamplerArrayDraw)
1268{
1269 testSamplerArrayDraw();
1270}
1271
1272// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1273// user-defined function in the shader.
1274TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1275{
1276 testSamplerArrayDraw();
1277}
1278
Jamie Madill9aca0592014-10-06 16:26:59 -04001279// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001280TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001281{
1282 int px = getWindowWidth() / 2;
1283 int py = getWindowHeight() / 2;
1284
1285 glActiveTexture(GL_TEXTURE0);
1286 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1287
Olli Etuahoa314b612016-03-10 16:43:00 +02001288 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001289
Olli Etuahoa314b612016-03-10 16:43:00 +02001290 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001291 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1292 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1293 glGenerateMipmap(GL_TEXTURE_2D);
1294
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001295 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001296 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001297 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1298 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001299 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001300 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001301
Olli Etuahoa314b612016-03-10 16:43:00 +02001302 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001303
Olli Etuahoa314b612016-03-10 16:43:00 +02001304 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1305 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001306 glGenerateMipmap(GL_TEXTURE_2D);
1307
Olli Etuahoa314b612016-03-10 16:43:00 +02001308 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001309
Olli Etuahoa314b612016-03-10 16:43:00 +02001310 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1311 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001312 glGenerateMipmap(GL_TEXTURE_2D);
1313
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001314 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001315
1316 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001317 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001318}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001319
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001320// Test creating a FBO with a cube map render target, to test an ANGLE bug
1321// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001322TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001323{
1324 GLuint fbo;
1325 glGenFramebuffers(1, &fbo);
1326 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1327
1328 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1329 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1330
Corentin Wallez322653b2015-06-17 18:33:56 +02001331 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001332
1333 glDeleteFramebuffers(1, &fbo);
1334
1335 EXPECT_GL_NO_ERROR();
1336}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001337
1338// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001339TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001340{
1341 int width = getWindowWidth();
1342 int height = getWindowHeight();
1343
1344 GLuint tex2D;
1345 glGenTextures(1, &tex2D);
1346 glActiveTexture(GL_TEXTURE0);
1347 glBindTexture(GL_TEXTURE_2D, tex2D);
1348
1349 // Fill with red
1350 std::vector<GLubyte> pixels(3 * 16 * 16);
1351 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1352 {
1353 pixels[pixelId * 3 + 0] = 255;
1354 pixels[pixelId * 3 + 1] = 0;
1355 pixels[pixelId * 3 + 2] = 0;
1356 }
1357
1358 // ANGLE internally uses RGBA as the DirectX format for RGB images
1359 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1360 // The data is kept in a CPU-side image and the image is marked as dirty.
1361 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1362
1363 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1364 // glTexSubImage2D should take into account that the image is dirty.
1365 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1368
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001369 setUpProgram();
1370
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001371 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001372 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001373 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001374 glDeleteTextures(1, &tex2D);
1375 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001376 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001377
1378 // Validate that the region of the texture without data has an alpha of 1.0
1379 GLubyte pixel[4];
1380 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1381 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001382}
1383
1384// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001385TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001386{
1387 if (extensionEnabled("NV_pixel_buffer_object"))
1388 {
1389 int width = getWindowWidth();
1390 int height = getWindowHeight();
1391
1392 GLuint tex2D;
1393 glGenTextures(1, &tex2D);
1394 glActiveTexture(GL_TEXTURE0);
1395 glBindTexture(GL_TEXTURE_2D, tex2D);
1396
1397 // Fill with red
1398 std::vector<GLubyte> pixels(3 * 16 * 16);
1399 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1400 {
1401 pixels[pixelId * 3 + 0] = 255;
1402 pixels[pixelId * 3 + 1] = 0;
1403 pixels[pixelId * 3 + 2] = 0;
1404 }
1405
1406 // Read 16x16 region from red backbuffer to PBO
1407 GLuint pbo;
1408 glGenBuffers(1, &pbo);
1409 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1410 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1411
1412 // ANGLE internally uses RGBA as the DirectX format for RGB images
1413 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1414 // The data is kept in a CPU-side image and the image is marked as dirty.
1415 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1416
1417 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1418 // glTexSubImage2D should take into account that the image is dirty.
1419 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1420 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1421 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1422
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001423 setUpProgram();
1424
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001425 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001426 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001427 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001428 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001429 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001430 EXPECT_GL_NO_ERROR();
1431 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1432 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1433 }
1434}
Jamie Madillbc393df2015-01-29 13:46:07 -05001435
1436// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001437TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001438{
1439 testFloatCopySubImage(1, 1);
1440}
1441
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001442TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001443{
1444 testFloatCopySubImage(2, 1);
1445}
1446
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001447TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001448{
1449 testFloatCopySubImage(2, 2);
1450}
1451
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001452TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001453{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001454 if (IsIntel() && IsLinux())
1455 {
1456 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1457 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1458 return;
1459 }
1460
Jamie Madillbc393df2015-01-29 13:46:07 -05001461 testFloatCopySubImage(3, 1);
1462}
1463
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001464TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001465{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001466 if (IsIntel() && IsLinux())
1467 {
1468 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1469 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1470 return;
1471 }
1472
Jamie Madillbc393df2015-01-29 13:46:07 -05001473 testFloatCopySubImage(3, 2);
1474}
1475
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001476TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001477{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001478 if (IsIntel() && IsLinux())
1479 {
1480 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1481 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1482 return;
1483 }
1484
Austin Kinrossd544cc92016-01-11 15:26:42 -08001485 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001486 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001487 {
1488 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1489 return;
1490 }
1491
Jamie Madillbc393df2015-01-29 13:46:07 -05001492 testFloatCopySubImage(3, 3);
1493}
1494
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001495TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001496{
1497 testFloatCopySubImage(4, 1);
1498}
1499
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001500TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001501{
1502 testFloatCopySubImage(4, 2);
1503}
1504
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001505TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001506{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001507 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001508 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001509 {
1510 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1511 return;
1512 }
1513
Jamie Madillbc393df2015-01-29 13:46:07 -05001514 testFloatCopySubImage(4, 3);
1515}
1516
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001517TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001518{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001519 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001520 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001521 {
1522 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1523 return;
1524 }
1525
Jamie Madillbc393df2015-01-29 13:46:07 -05001526 testFloatCopySubImage(4, 4);
1527}
Austin Kinross07285142015-03-26 11:36:16 -07001528
1529// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1530// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001531TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001532{
1533 const int npotTexSize = 5;
1534 const int potTexSize = 4; // Should be less than npotTexSize
1535 GLuint tex2D;
1536
1537 if (extensionEnabled("GL_OES_texture_npot"))
1538 {
1539 // This test isn't applicable if texture_npot is enabled
1540 return;
1541 }
1542
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001543 setUpProgram();
1544
Austin Kinross07285142015-03-26 11:36:16 -07001545 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1546
Austin Kinross5faa15b2016-01-11 13:32:48 -08001547 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1548 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1549
Austin Kinross07285142015-03-26 11:36:16 -07001550 glActiveTexture(GL_TEXTURE0);
1551 glGenTextures(1, &tex2D);
1552 glBindTexture(GL_TEXTURE_2D, tex2D);
1553
1554 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1555 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1556 {
1557 pixels[pixelId] = 64;
1558 }
1559
1560 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1562
1563 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1564 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1565 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1566
1567 // Check that an NPOT texture on level 0 succeeds
1568 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1569 EXPECT_GL_NO_ERROR();
1570
1571 // Check that generateMipmap fails on NPOT
1572 glGenerateMipmap(GL_TEXTURE_2D);
1573 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1574
1575 // Check that nothing is drawn if filtering is not correct for NPOT
1576 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1577 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1578 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1579 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1580 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001581 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001582 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1583
1584 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1586 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1587 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1588 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001589 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001590 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1591
1592 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1593 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1594 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001595 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001596 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1597
1598 // Check that glTexImage2D for POT texture succeeds
1599 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1600 EXPECT_GL_NO_ERROR();
1601
1602 // Check that generateMipmap for an POT texture succeeds
1603 glGenerateMipmap(GL_TEXTURE_2D);
1604 EXPECT_GL_NO_ERROR();
1605
1606 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1611 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001612 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001613 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1614 EXPECT_GL_NO_ERROR();
1615}
Jamie Madillfa05f602015-05-07 13:47:11 -04001616
Austin Kinross08528e12015-10-07 16:24:40 -07001617// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1618// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001619TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001620{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001621 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1622 // 1278)
1623 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1624 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1625 {
1626 std::cout << "Test disabled on OpenGL." << std::endl;
1627 return;
1628 }
1629
Austin Kinross08528e12015-10-07 16:24:40 -07001630 glActiveTexture(GL_TEXTURE0);
1631 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1632
1633 // Create an 8x8 (i.e. power-of-two) texture.
1634 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1635 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1636 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1637 glGenerateMipmap(GL_TEXTURE_2D);
1638
1639 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1640 // This should always work, even if GL_OES_texture_npot isn't active.
1641 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1642
1643 EXPECT_GL_NO_ERROR();
1644}
1645
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001646// Test to check that texture completeness is determined correctly when the texture base level is
1647// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1648TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1649{
1650 glActiveTexture(GL_TEXTURE0);
1651 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001652
1653 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
1654 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1655 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1656 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1657 texDataGreen.data());
1658 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1659 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001660 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1661 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1662 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1663
1664 EXPECT_GL_NO_ERROR();
1665
1666 drawQuad(mProgram, "position", 0.5f);
1667
Olli Etuahoa314b612016-03-10 16:43:00 +02001668 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1669}
1670
1671// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1672// have images defined.
1673TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
1674{
1675 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1676 {
1677 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
1678 std::cout << "Test skipped on AMD OpenGL." << std::endl;
1679 return;
1680 }
1681 if (IsOSX())
1682 {
1683 // Observed incorrect rendering on OSX.
1684 std::cout << "Test skipped on OSX." << std::endl;
1685 return;
1686 }
1687 glActiveTexture(GL_TEXTURE0);
1688 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1689 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1690 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1691 texDataGreen.data());
1692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1693 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1694 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1695 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1696
1697 EXPECT_GL_NO_ERROR();
1698
1699 drawQuad(mProgram, "position", 0.5f);
1700
1701 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1702}
1703
1704// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1705// dimensions that don't fit the images inside the range.
1706// GLES 3.0.4 section 3.8.13 Texture completeness
1707TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1708{
1709 if (IsOSX())
1710 {
1711 // Observed incorrect rendering on OSX.
1712 std::cout << "Test skipped on OSX." << std::endl;
1713 return;
1714 }
1715 glActiveTexture(GL_TEXTURE0);
1716 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1717 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
1718 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1719 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
1720
1721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1722 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1723
1724 // Two levels that are initially unused.
1725 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1726 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1727 texDataCyan.data());
1728
1729 // One level that is used - only this level should affect completeness.
1730 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1731 texDataGreen.data());
1732
1733 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1734 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1735
1736 EXPECT_GL_NO_ERROR();
1737
1738 drawQuad(mProgram, "position", 0.5f);
1739
1740 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1741
1742 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1743 {
1744 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1745 // level was changed.
1746 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1747 return;
1748 }
1749
1750 // Switch the level that is being used to the cyan level 2.
1751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
1752 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1753
1754 EXPECT_GL_NO_ERROR();
1755
1756 drawQuad(mProgram, "position", 0.5f);
1757
1758 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1759}
1760
1761// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1762// have images defined.
1763TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
1764{
1765 if (IsOSX())
1766 {
1767 // Observed incorrect rendering on OSX.
1768 std::cout << "Test skipped on OSX." << std::endl;
1769 return;
1770 }
1771 glActiveTexture(GL_TEXTURE0);
1772 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1773 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1774 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1775 texDataGreen.data());
1776 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1777 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1778 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1779 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1780
1781 EXPECT_GL_NO_ERROR();
1782
1783 drawQuad(mProgram, "position", 0.5f);
1784
1785 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1786}
1787
1788// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1789// dimensions that don't fit the images inside the range.
1790// GLES 3.0.4 section 3.8.13 Texture completeness
1791TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1792{
1793 if (IsOSX())
1794 {
1795 // Observed incorrect rendering on OSX.
1796 std::cout << "Test skipped on OSX." << std::endl;
1797 return;
1798 }
1799 glActiveTexture(GL_TEXTURE0);
1800 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1801 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1802 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1803 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1804
1805 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1806 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1807
1808 // Two levels that are initially unused.
1809 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1810 texDataRed.data());
1811 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1812 texDataCyan.data());
1813
1814 // One level that is used - only this level should affect completeness.
1815 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1816 texDataGreen.data());
1817
1818 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1819 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1820
1821 EXPECT_GL_NO_ERROR();
1822
1823 drawQuad(mProgram, "position", 0.5f);
1824
1825 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1826
1827 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1828 {
1829 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1830 // level was changed.
1831 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1832 return;
1833 }
1834
1835 // Switch the level that is being used to the cyan level 2.
1836 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
1837 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
1838
1839 EXPECT_GL_NO_ERROR();
1840
1841 drawQuad(mProgram, "position", 0.5f);
1842
1843 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1844}
1845
1846// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1847// have images defined.
1848TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
1849{
1850 if (IsOSX())
1851 {
1852 // Observed incorrect rendering on OSX.
1853 std::cout << "Test skipped on OSX." << std::endl;
1854 return;
1855 }
1856 glActiveTexture(GL_TEXTURE0);
1857 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
1858 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1859 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1860 texDataGreen.data());
1861 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1862 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1863 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1864 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1865
1866 EXPECT_GL_NO_ERROR();
1867
1868 drawQuad(mProgram, "position", 0.5f);
1869
1870 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1871}
1872
1873// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1874// dimensions that don't fit the images inside the range.
1875// GLES 3.0.4 section 3.8.13 Texture completeness
1876TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1877{
1878 if (IsOSX())
1879 {
1880 // Observed incorrect rendering on OSX.
1881 std::cout << "Test skipped on OSX." << std::endl;
1882 return;
1883 }
1884 glActiveTexture(GL_TEXTURE0);
1885 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
1886 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1887 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1888 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1889
1890 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1891 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1892
1893 // Two levels that are initially unused.
1894 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1895 texDataRed.data());
1896 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1897 texDataCyan.data());
1898
1899 // One level that is used - only this level should affect completeness.
1900 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1901 texDataGreen.data());
1902
1903 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1904 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1905
1906 EXPECT_GL_NO_ERROR();
1907
1908 drawQuad(mProgram, "position", 0.5f);
1909
1910 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1911
1912 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1913 {
1914 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1915 // level was changed.
1916 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1917 return;
1918 }
1919 if (IsNVIDIA() && (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1920 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE))
1921 {
1922 // NVIDIA was observed drawing color 0,0,0,0 instead of the texture color after the base
1923 // level was changed.
1924 std::cout << "Test partially skipped on NVIDIA OpenGL." << std::endl;
1925 return;
1926 }
1927
1928 // Switch the level that is being used to the cyan level 2.
1929 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
1930 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
1931
1932 EXPECT_GL_NO_ERROR();
1933
1934 drawQuad(mProgram, "position", 0.5f);
1935
1936 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1937}
1938
1939// Test that texture completeness is updated if texture max level changes.
1940// GLES 3.0.4 section 3.8.13 Texture completeness
1941TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
1942{
1943 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1944 {
1945 // Intel was observed having wrong behavior after the texture is made incomplete by changing
1946 // the base level.
1947 std::cout << "Test skipped on Intel OpenGL." << std::endl;
1948 return;
1949 }
1950 if (IsOSX())
1951 {
1952 // Observed incorrect rendering on OSX.
1953 std::cout << "Test skipped on OSX." << std::endl;
1954 return;
1955 }
1956
1957 glActiveTexture(GL_TEXTURE0);
1958 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1959 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
1960
1961 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1962 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1963
1964 // A level that is initially unused.
1965 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1966 texDataGreen.data());
1967
1968 // One level that is initially used - only this level should affect completeness.
1969 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1970 texDataGreen.data());
1971
1972 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
1973 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
1974
1975 EXPECT_GL_NO_ERROR();
1976
1977 drawQuad(mProgram, "position", 0.5f);
1978
1979 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1980
1981 // Switch the max level to level 1. The levels within the used range now have inconsistent
1982 // dimensions and the texture should be incomplete.
1983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1984
1985 EXPECT_GL_NO_ERROR();
1986
1987 drawQuad(mProgram, "position", 0.5f);
1988
1989 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
1990}
1991
1992// Test that 3D texture completeness is updated if texture max level changes.
1993// GLES 3.0.4 section 3.8.13 Texture completeness
1994TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
1995{
1996 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1997 {
1998 // Intel was observed having wrong behavior after the texture is made incomplete by changing
1999 // the base level.
2000 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2001 return;
2002 }
2003 if (IsOSX())
2004 {
2005 // Observed incorrect rendering on OSX.
2006 std::cout << "Test skipped on OSX." << std::endl;
2007 return;
2008 }
2009
2010 glActiveTexture(GL_TEXTURE0);
2011 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2012 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2013
2014 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2015 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2016
2017 // A level that is initially unused.
2018 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2019 texDataGreen.data());
2020
2021 // One level that is initially used - only this level should affect completeness.
2022 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2023 texDataGreen.data());
2024
2025 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2026 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2027
2028 EXPECT_GL_NO_ERROR();
2029
2030 drawQuad(mProgram, "position", 0.5f);
2031
2032 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2033
2034 // Switch the max level to level 1. The levels within the used range now have inconsistent
2035 // dimensions and the texture should be incomplete.
2036 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2037
2038 EXPECT_GL_NO_ERROR();
2039
2040 drawQuad(mProgram, "position", 0.5f);
2041
2042 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2043}
2044
2045// Test that texture completeness is updated if texture base level changes.
2046// GLES 3.0.4 section 3.8.13 Texture completeness
2047TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2048{
2049 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2050 {
2051 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2052 // the base level.
2053 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2054 return;
2055 }
2056
2057 glActiveTexture(GL_TEXTURE0);
2058 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2059 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2060
2061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2063
2064 // Two levels that are initially unused.
2065 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2066 texDataGreen.data());
2067 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2068 texDataGreen.data());
2069
2070 // One level that is initially used - only this level should affect completeness.
2071 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2072 texDataGreen.data());
2073
2074 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2075 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2076
2077 EXPECT_GL_NO_ERROR();
2078
2079 drawQuad(mProgram, "position", 0.5f);
2080
2081 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2082
2083 // Switch the base level to level 1. The levels within the used range now have inconsistent
2084 // dimensions and the texture should be incomplete.
2085 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2086
2087 EXPECT_GL_NO_ERROR();
2088
2089 drawQuad(mProgram, "position", 0.5f);
2090
2091 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2092}
2093
2094// Test that texture is not complete if base level is greater than max level.
2095// GLES 3.0.4 section 3.8.13 Texture completeness
2096TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2097{
2098 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2099 {
2100 // Intel Windows OpenGL driver crashes if the base level of a non-immutable texture is out
2101 // of range.
2102 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2103 return;
2104 }
2105
2106 glActiveTexture(GL_TEXTURE0);
2107 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2108
2109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2111
2112 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2113
2114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2116
2117 EXPECT_GL_NO_ERROR();
2118
2119 drawQuad(mProgram, "position", 0.5f);
2120
2121 // Texture should be incomplete.
2122 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2123}
2124
2125// Test that immutable texture base level and max level are clamped.
2126// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2127TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2128{
2129 if (IsOSX())
2130 {
2131 // Observed incorrect rendering on OSX.
2132 std::cout << "Test skipped on OSX." << std::endl;
2133 return;
2134 }
2135 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2136 {
2137 // Observed incorrect rendering on AMD OpenGL.
2138 std::cout << "Test skipped on AMD OpenGL." << std::endl;
2139 return;
2140 }
2141
2142 glActiveTexture(GL_TEXTURE0);
2143 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2144
2145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2147
2148 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2149
2150 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2151
2152 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2153 // should be clamped to [base_level, levels - 1].
2154 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2155 // In the case of this test, those rules make the effective base level and max level 0.
2156 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2158
2159 EXPECT_GL_NO_ERROR();
2160
2161 drawQuad(mProgram, "position", 0.5f);
2162
2163 // Texture should be complete.
2164 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2165}
2166
2167// Test that setting a texture image works when base level is out of range.
2168TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2169{
2170 glActiveTexture(GL_TEXTURE0);
2171 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2172
2173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2175
2176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2178
2179 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2180
2181 EXPECT_GL_NO_ERROR();
2182
2183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2184
2185 drawQuad(mProgram, "position", 0.5f);
2186
2187 // Texture should be complete.
2188 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002189}
2190
Jamie Madill2453dbc2015-07-14 11:35:42 -04002191// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
2192// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
2193// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002194TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002195{
2196 std::vector<GLubyte> pixelData;
2197 for (size_t count = 0; count < 5000; count++)
2198 {
2199 pixelData.push_back(0u);
2200 pixelData.push_back(255u);
2201 pixelData.push_back(0u);
2202 }
2203
2204 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002205 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002206 glUniform1i(mTextureArrayLocation, 0);
2207
2208 // The first draw worked correctly.
2209 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
2210
2211 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2212 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2213 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2214 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002215 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002216 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002217
2218 // The dimension of the respecification must match the original exactly to trigger the bug.
2219 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002220 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002221 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002222
2223 ASSERT_GL_NO_ERROR();
2224}
2225
Olli Etuaho1a679902016-01-14 12:21:47 +02002226// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2227// This test is needed especially to confirm that sampler registers get assigned correctly on
2228// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2229TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2230{
2231 glActiveTexture(GL_TEXTURE0);
2232 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2233 GLubyte texData[4];
2234 texData[0] = 0;
2235 texData[1] = 60;
2236 texData[2] = 0;
2237 texData[3] = 255;
2238 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2239
2240 glActiveTexture(GL_TEXTURE1);
2241 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2242 GLfloat depthTexData[1];
2243 depthTexData[0] = 0.5f;
2244 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2245 depthTexData);
2246
2247 glUseProgram(mProgram);
2248 glUniform1f(mDepthRefUniformLocation, 0.3f);
2249 glUniform1i(mTexture3DUniformLocation, 0);
2250 glUniform1i(mTextureShadowUniformLocation, 1);
2251
2252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2253 drawQuad(mProgram, "position", 0.5f);
2254 EXPECT_GL_NO_ERROR();
2255 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2256 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2257
2258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2259 drawQuad(mProgram, "position", 0.5f);
2260 EXPECT_GL_NO_ERROR();
2261 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2262 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2263}
2264
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002265// Test multiple different sampler types in the same shader.
2266// This test makes sure that even if sampler / texture registers get grouped together based on type
2267// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2268// still has the right register index information for each ESSL sampler.
2269// The tested ESSL samplers have the following types in D3D11 HLSL:
2270// sampler2D: Texture2D + SamplerState
2271// samplerCube: TextureCube + SamplerState
2272// sampler2DShadow: Texture2D + SamplerComparisonState
2273// samplerCubeShadow: TextureCube + SamplerComparisonState
2274TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2275{
2276 glActiveTexture(GL_TEXTURE0);
2277 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2278 GLubyte texData[4];
2279 texData[0] = 0;
2280 texData[1] = 0;
2281 texData[2] = 120;
2282 texData[3] = 255;
2283 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2284
2285 glActiveTexture(GL_TEXTURE1);
2286 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2287 texData[0] = 0;
2288 texData[1] = 90;
2289 texData[2] = 0;
2290 texData[3] = 255;
2291 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2292 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2293 texData);
2294
2295 glActiveTexture(GL_TEXTURE2);
2296 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2297 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2298 GLfloat depthTexData[1];
2299 depthTexData[0] = 0.5f;
2300 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2301 depthTexData);
2302
2303 glActiveTexture(GL_TEXTURE3);
2304 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2305 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2306 depthTexData[0] = 0.2f;
2307 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2308 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2309 depthTexData);
2310
2311 EXPECT_GL_NO_ERROR();
2312
2313 glUseProgram(mProgram);
2314 glUniform1f(mDepthRefUniformLocation, 0.3f);
2315 glUniform1i(mTexture2DUniformLocation, 0);
2316 glUniform1i(mTextureCubeUniformLocation, 1);
2317 glUniform1i(mTexture2DShadowUniformLocation, 2);
2318 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2319
2320 drawQuad(mProgram, "position", 0.5f);
2321 EXPECT_GL_NO_ERROR();
2322 // The shader writes:
2323 // <texture 2d color> +
2324 // <cube map color> +
2325 // 0.25 * <comparison result (1.0)> +
2326 // 0.125 * <comparison result (0.0)>
2327 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2328}
2329
Olli Etuahobce743a2016-01-15 17:18:28 +02002330// Test different base levels on textures accessed through the same sampler array.
2331// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2332TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2333{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002334 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02002335 {
2336 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
2337 return;
2338 }
2339 glActiveTexture(GL_TEXTURE0);
2340 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2341 GLsizei size = 64;
2342 for (GLint level = 0; level < 7; ++level)
2343 {
2344 ASSERT_LT(0, size);
2345 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2346 nullptr);
2347 size = size / 2;
2348 }
2349 ASSERT_EQ(0, size);
2350 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2351
2352 glActiveTexture(GL_TEXTURE1);
2353 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2354 size = 128;
2355 for (GLint level = 0; level < 8; ++level)
2356 {
2357 ASSERT_LT(0, size);
2358 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2359 nullptr);
2360 size = size / 2;
2361 }
2362 ASSERT_EQ(0, size);
2363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2364 EXPECT_GL_NO_ERROR();
2365
2366 glUseProgram(mProgram);
2367 glUniform1i(mTexture0Location, 0);
2368 glUniform1i(mTexture1Location, 1);
2369
2370 drawQuad(mProgram, "position", 0.5f);
2371 EXPECT_GL_NO_ERROR();
2372 // Red channel: width of level 1 of texture A: 32.
2373 // Green channel: width of level 3 of texture B: 16.
2374 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2375}
2376
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002377// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2378// ES 3.0.4 table 3.24
2379TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2380{
2381 glActiveTexture(GL_TEXTURE0);
2382 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2383 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2384 EXPECT_GL_NO_ERROR();
2385
2386 drawQuad(mProgram, "position", 0.5f);
2387
2388 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2389}
2390
2391// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2392// ES 3.0.4 table 3.24
2393TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
2394{
2395 glActiveTexture(GL_TEXTURE0);
2396 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2397 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2398 EXPECT_GL_NO_ERROR();
2399
2400 drawQuad(mProgram, "position", 0.5f);
2401
2402 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2403}
2404
2405// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2406// ES 3.0.4 table 3.24
2407TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
2408{
2409 if (extensionEnabled("GL_OES_texture_float"))
2410 {
2411 glActiveTexture(GL_TEXTURE0);
2412 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2413 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
2414 EXPECT_GL_NO_ERROR();
2415
2416 drawQuad(mProgram, "position", 0.5f);
2417
2418 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2419 }
2420}
2421
2422// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2423// ES 3.0.4 table 3.24
2424TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
2425{
2426 if (extensionEnabled("GL_OES_texture_half_float"))
2427 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002428 if (IsNVIDIA() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002429 {
2430 std::cout << "Test skipped on NVIDIA" << std::endl;
2431 return;
2432 }
2433 glActiveTexture(GL_TEXTURE0);
2434 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2435 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
2436 nullptr);
2437 EXPECT_GL_NO_ERROR();
2438
2439 drawQuad(mProgram, "position", 0.5f);
2440
2441 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2442 }
2443}
2444
2445// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2446// ES 3.0.4 table 3.24
2447TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
2448{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002449 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002450 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002451 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002452 return;
2453 }
2454 glActiveTexture(GL_TEXTURE0);
2455 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2456 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
2457 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2458 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2459 EXPECT_GL_NO_ERROR();
2460
2461 drawQuad(mProgram, "position", 0.5f);
2462
2463 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2464}
2465
2466// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2467// ES 3.0.4 table 3.24
2468TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
2469{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002470 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002471 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002472 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002473 return;
2474 }
2475 glActiveTexture(GL_TEXTURE0);
2476 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2477
2478 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
2479 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2480 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2481 EXPECT_GL_NO_ERROR();
2482
2483 drawQuad(mProgram, "position", 0.5f);
2484
2485 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2486}
2487
2488// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2489// ES 3.0.4 table 3.24
2490TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
2491{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002492 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002493 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002494 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002495 return;
2496 }
2497 glActiveTexture(GL_TEXTURE0);
2498 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2499 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
2500 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2501 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2502 EXPECT_GL_NO_ERROR();
2503
2504 drawQuad(mProgram, "position", 0.5f);
2505
2506 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2507}
2508
2509// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2510// ES 3.0.4 table 3.24
2511TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
2512{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002513 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002514 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002515 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002516 return;
2517 }
2518 glActiveTexture(GL_TEXTURE0);
2519 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2520 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
2521 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2522 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2523 EXPECT_GL_NO_ERROR();
2524
2525 drawQuad(mProgram, "position", 0.5f);
2526
2527 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2528}
2529
2530// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2531// ES 3.0.4 table 3.24
2532TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
2533{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002534 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002535 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002536 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002537 return;
2538 }
2539 glActiveTexture(GL_TEXTURE0);
2540 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2541 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
2542 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2543 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2544 EXPECT_GL_NO_ERROR();
2545
2546 drawQuad(mProgram, "position", 0.5f);
2547
2548 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2549}
2550
2551// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2552// ES 3.0.4 table 3.24
2553TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
2554{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002555 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002556 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002557 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002558 return;
2559 }
2560 glActiveTexture(GL_TEXTURE0);
2561 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2562 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
2563 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2564 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2565 EXPECT_GL_NO_ERROR();
2566
2567 drawQuad(mProgram, "position", 0.5f);
2568
2569 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2570}
2571
2572// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2573// ES 3.0.4 table 3.24
2574TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
2575{
2576 glActiveTexture(GL_TEXTURE0);
2577 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2578 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
2579 EXPECT_GL_NO_ERROR();
2580
2581 drawQuad(mProgram, "position", 0.5f);
2582
2583 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2584}
2585
2586// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2587// ES 3.0.4 table 3.24
2588TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
2589{
2590 glActiveTexture(GL_TEXTURE0);
2591 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2592 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
2593 nullptr);
2594 EXPECT_GL_NO_ERROR();
2595
2596 drawQuad(mProgram, "position", 0.5f);
2597
2598 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2599}
2600
2601// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2602// ES 3.0.4 table 3.24
2603TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
2604{
2605 glActiveTexture(GL_TEXTURE0);
2606 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2607 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
2608 EXPECT_GL_NO_ERROR();
2609
2610 drawQuad(mProgram, "position", 0.5f);
2611
2612 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2613}
2614
2615// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2616// ES 3.0.4 table 3.24
2617TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
2618{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002619 if (IsIntel() && IsLinux())
2620 {
2621 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2622 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2623 return;
2624 }
2625
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002626 glActiveTexture(GL_TEXTURE0);
2627 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2628 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2629 EXPECT_GL_NO_ERROR();
2630
2631 drawQuad(mProgram, "position", 0.5f);
2632
2633 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2634}
2635
Olli Etuaho96963162016-03-21 11:54:33 +02002636// Use a sampler in a uniform struct.
2637TEST_P(SamplerInStructTest, SamplerInStruct)
2638{
2639 runSamplerInStructTest();
2640}
2641
2642// Use a sampler in a uniform struct that's passed as a function parameter.
2643TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2644{
2645 runSamplerInStructTest();
2646}
2647
2648// Use a sampler in a uniform struct array with a struct from the array passed as a function
2649// parameter.
2650TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2651{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002652 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2653 {
2654 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2655 return;
2656 }
Olli Etuaho96963162016-03-21 11:54:33 +02002657 runSamplerInStructTest();
2658}
2659
2660// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2661// parameter.
2662TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2663{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002664 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2665 {
2666 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2667 return;
2668 }
Olli Etuaho96963162016-03-21 11:54:33 +02002669 runSamplerInStructTest();
2670}
2671
2672// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2673// similarly named uniform.
2674TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2675{
2676 runSamplerInStructTest();
2677}
2678
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002679class TextureLimitsTest : public ANGLETest
2680{
2681 protected:
2682 struct RGBA8
2683 {
2684 uint8_t R, G, B, A;
2685 };
2686
2687 TextureLimitsTest()
2688 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2689 {
2690 setWindowWidth(128);
2691 setWindowHeight(128);
2692 setConfigRedBits(8);
2693 setConfigGreenBits(8);
2694 setConfigBlueBits(8);
2695 setConfigAlphaBits(8);
2696 }
2697
2698 ~TextureLimitsTest()
2699 {
2700 if (mProgram != 0)
2701 {
2702 glDeleteProgram(mProgram);
2703 mProgram = 0;
2704
2705 if (!mTextures.empty())
2706 {
2707 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2708 }
2709 }
2710 }
2711
2712 void SetUp() override
2713 {
2714 ANGLETest::SetUp();
2715
2716 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2717 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2718 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2719
2720 ASSERT_GL_NO_ERROR();
2721 }
2722
2723 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2724 GLint vertexTextureCount,
2725 GLint vertexActiveTextureCount,
2726 const std::string &fragPrefix,
2727 GLint fragmentTextureCount,
2728 GLint fragmentActiveTextureCount)
2729 {
2730 std::stringstream vertexShaderStr;
2731 vertexShaderStr << "attribute vec2 position;\n"
2732 << "varying vec4 color;\n"
2733 << "varying vec2 texCoord;\n";
2734
2735 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2736 {
2737 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2738 }
2739
2740 vertexShaderStr << "void main() {\n"
2741 << " gl_Position = vec4(position, 0, 1);\n"
2742 << " texCoord = (position * 0.5) + 0.5;\n"
2743 << " color = vec4(0);\n";
2744
2745 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2746 {
2747 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2748 << ", texCoord);\n";
2749 }
2750
2751 vertexShaderStr << "}";
2752
2753 std::stringstream fragmentShaderStr;
2754 fragmentShaderStr << "varying mediump vec4 color;\n"
2755 << "varying mediump vec2 texCoord;\n";
2756
2757 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2758 {
2759 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2760 }
2761
2762 fragmentShaderStr << "void main() {\n"
2763 << " gl_FragColor = color;\n";
2764
2765 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2766 {
2767 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2768 << ", texCoord);\n";
2769 }
2770
2771 fragmentShaderStr << "}";
2772
2773 const std::string &vertexShaderSource = vertexShaderStr.str();
2774 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2775
2776 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2777 }
2778
2779 RGBA8 getPixel(GLint texIndex)
2780 {
2781 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2782 0, 255u};
2783 return pixel;
2784 }
2785
2786 void initTextures(GLint tex2DCount, GLint texCubeCount)
2787 {
2788 GLint totalCount = tex2DCount + texCubeCount;
2789 mTextures.assign(totalCount, 0);
2790 glGenTextures(totalCount, &mTextures[0]);
2791 ASSERT_GL_NO_ERROR();
2792
2793 std::vector<RGBA8> texData(16 * 16);
2794
2795 GLint texIndex = 0;
2796 for (; texIndex < tex2DCount; ++texIndex)
2797 {
2798 texData.assign(texData.size(), getPixel(texIndex));
2799 glActiveTexture(GL_TEXTURE0 + texIndex);
2800 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2801 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2802 &texData[0]);
2803 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2804 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2805 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2806 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2807 }
2808
2809 ASSERT_GL_NO_ERROR();
2810
2811 for (; texIndex < texCubeCount; ++texIndex)
2812 {
2813 texData.assign(texData.size(), getPixel(texIndex));
2814 glActiveTexture(GL_TEXTURE0 + texIndex);
2815 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2816 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2817 GL_UNSIGNED_BYTE, &texData[0]);
2818 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2819 GL_UNSIGNED_BYTE, &texData[0]);
2820 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2821 GL_UNSIGNED_BYTE, &texData[0]);
2822 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2823 GL_UNSIGNED_BYTE, &texData[0]);
2824 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2825 GL_UNSIGNED_BYTE, &texData[0]);
2826 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2827 GL_UNSIGNED_BYTE, &texData[0]);
2828 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2829 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2830 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2831 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2832 }
2833
2834 ASSERT_GL_NO_ERROR();
2835 }
2836
2837 void testWithTextures(GLint vertexTextureCount,
2838 const std::string &vertexTexturePrefix,
2839 GLint fragmentTextureCount,
2840 const std::string &fragmentTexturePrefix)
2841 {
2842 // Generate textures
2843 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2844
2845 glUseProgram(mProgram);
2846 RGBA8 expectedSum = {0};
2847 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2848 {
2849 std::stringstream uniformNameStr;
2850 uniformNameStr << vertexTexturePrefix << texIndex;
2851 const std::string &uniformName = uniformNameStr.str();
2852 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2853 ASSERT_NE(-1, location);
2854
2855 glUniform1i(location, texIndex);
2856 RGBA8 contribution = getPixel(texIndex);
2857 expectedSum.R += contribution.R;
2858 expectedSum.G += contribution.G;
2859 }
2860
2861 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2862 {
2863 std::stringstream uniformNameStr;
2864 uniformNameStr << fragmentTexturePrefix << texIndex;
2865 const std::string &uniformName = uniformNameStr.str();
2866 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2867 ASSERT_NE(-1, location);
2868
2869 glUniform1i(location, texIndex + vertexTextureCount);
2870 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
2871 expectedSum.R += contribution.R;
2872 expectedSum.G += contribution.G;
2873 }
2874
2875 ASSERT_GE(256u, expectedSum.G);
2876
2877 drawQuad(mProgram, "position", 0.5f);
2878 ASSERT_GL_NO_ERROR();
2879 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
2880 }
2881
2882 GLuint mProgram;
2883 std::vector<GLuint> mTextures;
2884 GLint mMaxVertexTextures;
2885 GLint mMaxFragmentTextures;
2886 GLint mMaxCombinedTextures;
2887};
2888
2889// Test rendering with the maximum vertex texture units.
2890TEST_P(TextureLimitsTest, MaxVertexTextures)
2891{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002892 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002893 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002894 {
2895 std::cout << "Test skipped on Intel." << std::endl;
2896 return;
2897 }
2898
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002899 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
2900 ASSERT_NE(0u, mProgram);
2901 ASSERT_GL_NO_ERROR();
2902
2903 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2904}
2905
2906// Test rendering with the maximum fragment texture units.
2907TEST_P(TextureLimitsTest, MaxFragmentTextures)
2908{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002909 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002910 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002911 {
2912 std::cout << "Test skipped on Intel." << std::endl;
2913 return;
2914 }
2915
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002916 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
2917 ASSERT_NE(0u, mProgram);
2918 ASSERT_GL_NO_ERROR();
2919
2920 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
2921}
2922
2923// Test rendering with maximum combined texture units.
2924TEST_P(TextureLimitsTest, MaxCombinedTextures)
2925{
Jamie Madill412f17d2015-09-25 08:43:54 -04002926 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002927 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04002928 {
2929 std::cout << "Test skipped on Intel." << std::endl;
2930 return;
2931 }
2932
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002933 GLint vertexTextures = mMaxVertexTextures;
2934
2935 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
2936 {
2937 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
2938 }
2939
2940 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
2941 mMaxFragmentTextures, mMaxFragmentTextures);
2942 ASSERT_NE(0u, mProgram);
2943 ASSERT_GL_NO_ERROR();
2944
2945 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
2946}
2947
2948// Negative test for exceeding the number of vertex textures
2949TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
2950{
2951 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
2952 0);
2953 ASSERT_EQ(0u, mProgram);
2954}
2955
2956// Negative test for exceeding the number of fragment textures
2957TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
2958{
2959 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
2960 mMaxFragmentTextures + 1);
2961 ASSERT_EQ(0u, mProgram);
2962}
2963
2964// Test active vertex textures under the limit, but excessive textures specified.
2965TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
2966{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002967 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002968 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002969 {
2970 std::cout << "Test skipped on Intel." << std::endl;
2971 return;
2972 }
2973
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002974 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
2975 ASSERT_NE(0u, mProgram);
2976 ASSERT_GL_NO_ERROR();
2977
2978 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2979}
2980
2981// Test active fragment textures under the limit, but excessive textures specified.
2982TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
2983{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002984 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002985 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002986 {
2987 std::cout << "Test skipped on Intel." << std::endl;
2988 return;
2989 }
2990
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002991 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
2992 mMaxFragmentTextures);
2993 ASSERT_NE(0u, mProgram);
2994 ASSERT_GL_NO_ERROR();
2995
2996 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
2997}
2998
2999// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003000// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003001TEST_P(TextureLimitsTest, TextureTypeConflict)
3002{
3003 const std::string &vertexShader =
3004 "attribute vec2 position;\n"
3005 "varying float color;\n"
3006 "uniform sampler2D tex2D;\n"
3007 "uniform samplerCube texCube;\n"
3008 "void main() {\n"
3009 " gl_Position = vec4(position, 0, 1);\n"
3010 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3011 " color = texture2D(tex2D, texCoord).x;\n"
3012 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
3013 "}";
3014 const std::string &fragmentShader =
3015 "varying mediump float color;\n"
3016 "void main() {\n"
3017 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3018 "}";
3019
3020 mProgram = CompileProgram(vertexShader, fragmentShader);
3021 ASSERT_NE(0u, mProgram);
3022
3023 initTextures(1, 0);
3024
3025 glUseProgram(mProgram);
3026 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3027 ASSERT_NE(-1, tex2DLocation);
3028 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
3029 ASSERT_NE(-1, texCubeLocation);
3030
3031 glUniform1i(tex2DLocation, 0);
3032 glUniform1i(texCubeLocation, 0);
3033 ASSERT_GL_NO_ERROR();
3034
3035 drawQuad(mProgram, "position", 0.5f);
3036 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3037}
3038
3039// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003040// TODO(jmadill): Possibly adjust the test according to the spec:
3041// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
3042// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003043TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
3044{
3045 const std::string &vertexShader =
3046 "attribute vec2 position;\n"
3047 "varying float color;\n"
3048 "uniform sampler2D tex2D;\n"
3049 "void main() {\n"
3050 " gl_Position = vec4(position, 0, 1);\n"
3051 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3052 " color = texture2D(tex2D, texCoord).x;\n"
3053 "}";
3054 const std::string &fragmentShader =
3055 "varying mediump float color;\n"
3056 "void main() {\n"
3057 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3058 "}";
3059
3060 mProgram = CompileProgram(vertexShader, fragmentShader);
3061 ASSERT_NE(0u, mProgram);
3062
3063 glUseProgram(mProgram);
3064 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3065 ASSERT_NE(-1, tex2DLocation);
3066
3067 glUniform1i(tex2DLocation, mMaxCombinedTextures);
3068 ASSERT_GL_NO_ERROR();
3069
3070 drawQuad(mProgram, "position", 0.5f);
3071 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3072}
3073
Jamie Madillfa05f602015-05-07 13:47:11 -04003074// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003075// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05003076ANGLE_INSTANTIATE_TEST(Texture2DTest,
3077 ES2_D3D9(),
3078 ES2_D3D11(),
3079 ES2_D3D11_FL9_3(),
3080 ES2_OPENGL(),
3081 ES2_OPENGLES());
3082ANGLE_INSTANTIATE_TEST(TextureCubeTest,
3083 ES2_D3D9(),
3084 ES2_D3D11(),
3085 ES2_D3D11_FL9_3(),
3086 ES2_OPENGL(),
3087 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003088ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
3089 ES2_D3D9(),
3090 ES2_D3D11(),
3091 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003092 ES2_OPENGL(),
3093 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003094ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
3095 ES2_D3D9(),
3096 ES2_D3D11(),
3097 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003098 ES2_OPENGL(),
3099 ES2_OPENGLES());
3100ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
3101 ES2_D3D9(),
3102 ES2_D3D11(),
3103 ES2_D3D11_FL9_3(),
3104 ES2_OPENGL(),
3105 ES2_OPENGLES());
3106ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
3107 ES2_D3D9(),
3108 ES2_D3D11(),
3109 ES2_D3D11_FL9_3(),
3110 ES2_OPENGL(),
3111 ES2_OPENGLES());
3112ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahoa314b612016-03-10 16:43:00 +02003113ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003114ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3115ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
3116 ES3_D3D11(),
3117 ES3_OPENGL(),
3118 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003119ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
3120 ES3_D3D11(),
3121 ES3_OPENGL(),
3122 ES3_OPENGLES());
3123ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3124ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02003125ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02003126ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
3127 ES2_D3D11(),
3128 ES2_D3D11_FL9_3(),
3129 ES2_D3D9(),
3130 ES2_OPENGL(),
3131 ES2_OPENGLES());
3132ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
3133 ES2_D3D11(),
3134 ES2_D3D11_FL9_3(),
3135 ES2_D3D9(),
3136 ES2_OPENGL(),
3137 ES2_OPENGLES());
3138ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
3139 ES2_D3D11(),
3140 ES2_D3D11_FL9_3(),
3141 ES2_D3D9(),
3142 ES2_OPENGL(),
3143 ES2_OPENGLES());
3144ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
3145 ES2_D3D11(),
3146 ES2_D3D11_FL9_3(),
3147 ES2_D3D9(),
3148 ES2_OPENGL(),
3149 ES2_OPENGLES());
3150ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
3151 ES2_D3D11(),
3152 ES2_D3D11_FL9_3(),
3153 ES2_D3D9(),
3154 ES2_OPENGL(),
3155 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003156ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04003157
3158} // namespace