blob: 742ffbd05159ab54550fcb59ebcc7440c290ad2a [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{
Olli Etuahoa314b612016-03-10 16:43:00 +02002129 glActiveTexture(GL_TEXTURE0);
2130 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2131
2132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2134
2135 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2136
2137 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2138
2139 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2140 // should be clamped to [base_level, levels - 1].
2141 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2142 // In the case of this test, those rules make the effective base level and max level 0.
2143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2145
2146 EXPECT_GL_NO_ERROR();
2147
2148 drawQuad(mProgram, "position", 0.5f);
2149
2150 // Texture should be complete.
2151 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2152}
2153
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002154// Test that changing base level works when it affects the format of the texture.
2155TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2156{
2157 if (IsNVIDIA() && (isOpenGL() || isGLES()))
2158 {
2159 // Observed rendering corruption on NVIDIA OpenGL.
2160 std::cout << "Test skipped on NVIDIA OpenGL." << std::endl;
2161 return;
2162 }
2163 if (IsIntel() && isOpenGL())
2164 {
2165 // Observed incorrect rendering on Intel OpenGL.
2166 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2167 return;
2168 }
2169 if (IsAMD() && isOpenGL())
2170 {
2171 // Observed incorrect rendering on AMD OpenGL.
2172 std::cout << "Test skipped on AMD OpenGL." << std::endl;
2173 return;
2174 }
2175
2176 glActiveTexture(GL_TEXTURE0);
2177 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2178 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2179 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2180
2181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2183
2184 // RGBA8 level that's initially unused.
2185 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2186 texDataCyan.data());
2187
2188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2190
2191 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2192 // format. It reads green channel data from the green and alpha channels of texDataGreen
2193 // (this is a bit hacky but works).
2194 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2195
2196 EXPECT_GL_NO_ERROR();
2197
2198 drawQuad(mProgram, "position", 0.5f);
2199
2200 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2201
2202 // Switch the texture to use the cyan level 0 with the RGBA format.
2203 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2205
2206 EXPECT_GL_NO_ERROR();
2207
2208 drawQuad(mProgram, "position", 0.5f);
2209
2210 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2211}
2212
Olli Etuahoa314b612016-03-10 16:43:00 +02002213// Test that setting a texture image works when base level is out of range.
2214TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2215{
2216 glActiveTexture(GL_TEXTURE0);
2217 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2218
2219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2221
2222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2224
2225 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2226
2227 EXPECT_GL_NO_ERROR();
2228
2229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2230
2231 drawQuad(mProgram, "position", 0.5f);
2232
2233 // Texture should be complete.
2234 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002235}
2236
Jamie Madill2453dbc2015-07-14 11:35:42 -04002237// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
2238// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
2239// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002240TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002241{
2242 std::vector<GLubyte> pixelData;
2243 for (size_t count = 0; count < 5000; count++)
2244 {
2245 pixelData.push_back(0u);
2246 pixelData.push_back(255u);
2247 pixelData.push_back(0u);
2248 }
2249
2250 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002251 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002252 glUniform1i(mTextureArrayLocation, 0);
2253
2254 // The first draw worked correctly.
2255 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
2256
2257 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2258 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2259 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2260 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002261 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002262 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002263
2264 // The dimension of the respecification must match the original exactly to trigger the bug.
2265 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 +02002266 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002267 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002268
2269 ASSERT_GL_NO_ERROR();
2270}
2271
Olli Etuaho1a679902016-01-14 12:21:47 +02002272// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2273// This test is needed especially to confirm that sampler registers get assigned correctly on
2274// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2275TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2276{
2277 glActiveTexture(GL_TEXTURE0);
2278 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2279 GLubyte texData[4];
2280 texData[0] = 0;
2281 texData[1] = 60;
2282 texData[2] = 0;
2283 texData[3] = 255;
2284 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2285
2286 glActiveTexture(GL_TEXTURE1);
2287 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2288 GLfloat depthTexData[1];
2289 depthTexData[0] = 0.5f;
2290 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2291 depthTexData);
2292
2293 glUseProgram(mProgram);
2294 glUniform1f(mDepthRefUniformLocation, 0.3f);
2295 glUniform1i(mTexture3DUniformLocation, 0);
2296 glUniform1i(mTextureShadowUniformLocation, 1);
2297
2298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2299 drawQuad(mProgram, "position", 0.5f);
2300 EXPECT_GL_NO_ERROR();
2301 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2302 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2303
2304 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2305 drawQuad(mProgram, "position", 0.5f);
2306 EXPECT_GL_NO_ERROR();
2307 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2308 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2309}
2310
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002311// Test multiple different sampler types in the same shader.
2312// This test makes sure that even if sampler / texture registers get grouped together based on type
2313// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2314// still has the right register index information for each ESSL sampler.
2315// The tested ESSL samplers have the following types in D3D11 HLSL:
2316// sampler2D: Texture2D + SamplerState
2317// samplerCube: TextureCube + SamplerState
2318// sampler2DShadow: Texture2D + SamplerComparisonState
2319// samplerCubeShadow: TextureCube + SamplerComparisonState
2320TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2321{
2322 glActiveTexture(GL_TEXTURE0);
2323 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2324 GLubyte texData[4];
2325 texData[0] = 0;
2326 texData[1] = 0;
2327 texData[2] = 120;
2328 texData[3] = 255;
2329 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2330
2331 glActiveTexture(GL_TEXTURE1);
2332 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2333 texData[0] = 0;
2334 texData[1] = 90;
2335 texData[2] = 0;
2336 texData[3] = 255;
2337 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2338 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2339 texData);
2340
2341 glActiveTexture(GL_TEXTURE2);
2342 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2343 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2344 GLfloat depthTexData[1];
2345 depthTexData[0] = 0.5f;
2346 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2347 depthTexData);
2348
2349 glActiveTexture(GL_TEXTURE3);
2350 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2351 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2352 depthTexData[0] = 0.2f;
2353 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2354 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2355 depthTexData);
2356
2357 EXPECT_GL_NO_ERROR();
2358
2359 glUseProgram(mProgram);
2360 glUniform1f(mDepthRefUniformLocation, 0.3f);
2361 glUniform1i(mTexture2DUniformLocation, 0);
2362 glUniform1i(mTextureCubeUniformLocation, 1);
2363 glUniform1i(mTexture2DShadowUniformLocation, 2);
2364 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2365
2366 drawQuad(mProgram, "position", 0.5f);
2367 EXPECT_GL_NO_ERROR();
2368 // The shader writes:
2369 // <texture 2d color> +
2370 // <cube map color> +
2371 // 0.25 * <comparison result (1.0)> +
2372 // 0.125 * <comparison result (0.0)>
2373 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2374}
2375
Olli Etuahobce743a2016-01-15 17:18:28 +02002376// Test different base levels on textures accessed through the same sampler array.
2377// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2378TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2379{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002380 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02002381 {
2382 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
2383 return;
2384 }
2385 glActiveTexture(GL_TEXTURE0);
2386 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2387 GLsizei size = 64;
2388 for (GLint level = 0; level < 7; ++level)
2389 {
2390 ASSERT_LT(0, size);
2391 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2392 nullptr);
2393 size = size / 2;
2394 }
2395 ASSERT_EQ(0, size);
2396 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2397
2398 glActiveTexture(GL_TEXTURE1);
2399 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2400 size = 128;
2401 for (GLint level = 0; level < 8; ++level)
2402 {
2403 ASSERT_LT(0, size);
2404 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2405 nullptr);
2406 size = size / 2;
2407 }
2408 ASSERT_EQ(0, size);
2409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2410 EXPECT_GL_NO_ERROR();
2411
2412 glUseProgram(mProgram);
2413 glUniform1i(mTexture0Location, 0);
2414 glUniform1i(mTexture1Location, 1);
2415
2416 drawQuad(mProgram, "position", 0.5f);
2417 EXPECT_GL_NO_ERROR();
2418 // Red channel: width of level 1 of texture A: 32.
2419 // Green channel: width of level 3 of texture B: 16.
2420 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2421}
2422
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002423// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2424// ES 3.0.4 table 3.24
2425TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2426{
2427 glActiveTexture(GL_TEXTURE0);
2428 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2429 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2430 EXPECT_GL_NO_ERROR();
2431
2432 drawQuad(mProgram, "position", 0.5f);
2433
2434 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2435}
2436
2437// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2438// ES 3.0.4 table 3.24
2439TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
2440{
2441 glActiveTexture(GL_TEXTURE0);
2442 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2443 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2444 EXPECT_GL_NO_ERROR();
2445
2446 drawQuad(mProgram, "position", 0.5f);
2447
2448 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2449}
2450
2451// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2452// ES 3.0.4 table 3.24
2453TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
2454{
2455 if (extensionEnabled("GL_OES_texture_float"))
2456 {
2457 glActiveTexture(GL_TEXTURE0);
2458 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2459 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
2460 EXPECT_GL_NO_ERROR();
2461
2462 drawQuad(mProgram, "position", 0.5f);
2463
2464 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2465 }
2466}
2467
2468// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2469// ES 3.0.4 table 3.24
2470TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
2471{
2472 if (extensionEnabled("GL_OES_texture_half_float"))
2473 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002474 if (IsNVIDIA() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002475 {
2476 std::cout << "Test skipped on NVIDIA" << std::endl;
2477 return;
2478 }
2479 glActiveTexture(GL_TEXTURE0);
2480 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2481 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
2482 nullptr);
2483 EXPECT_GL_NO_ERROR();
2484
2485 drawQuad(mProgram, "position", 0.5f);
2486
2487 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2488 }
2489}
2490
2491// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2492// ES 3.0.4 table 3.24
2493TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
2494{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002495 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002496 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002497 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002498 return;
2499 }
2500 glActiveTexture(GL_TEXTURE0);
2501 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2502 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
2503 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2504 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2505 EXPECT_GL_NO_ERROR();
2506
2507 drawQuad(mProgram, "position", 0.5f);
2508
2509 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2510}
2511
2512// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2513// ES 3.0.4 table 3.24
2514TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
2515{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002516 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002517 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002518 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002519 return;
2520 }
2521 glActiveTexture(GL_TEXTURE0);
2522 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2523
2524 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
2525 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2526 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2527 EXPECT_GL_NO_ERROR();
2528
2529 drawQuad(mProgram, "position", 0.5f);
2530
2531 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2532}
2533
2534// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2535// ES 3.0.4 table 3.24
2536TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
2537{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002538 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002539 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002540 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002541 return;
2542 }
2543 glActiveTexture(GL_TEXTURE0);
2544 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2545 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
2546 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2548 EXPECT_GL_NO_ERROR();
2549
2550 drawQuad(mProgram, "position", 0.5f);
2551
2552 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2553}
2554
2555// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2556// ES 3.0.4 table 3.24
2557TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
2558{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002559 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002560 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002561 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002562 return;
2563 }
2564 glActiveTexture(GL_TEXTURE0);
2565 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2566 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
2567 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2568 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2569 EXPECT_GL_NO_ERROR();
2570
2571 drawQuad(mProgram, "position", 0.5f);
2572
2573 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2574}
2575
2576// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2577// ES 3.0.4 table 3.24
2578TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
2579{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002580 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002581 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002582 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002583 return;
2584 }
2585 glActiveTexture(GL_TEXTURE0);
2586 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2587 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
2588 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2589 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2590 EXPECT_GL_NO_ERROR();
2591
2592 drawQuad(mProgram, "position", 0.5f);
2593
2594 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2595}
2596
2597// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2598// ES 3.0.4 table 3.24
2599TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
2600{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002601 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002602 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002603 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002604 return;
2605 }
2606 glActiveTexture(GL_TEXTURE0);
2607 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2608 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
2609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2611 EXPECT_GL_NO_ERROR();
2612
2613 drawQuad(mProgram, "position", 0.5f);
2614
2615 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2616}
2617
2618// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2619// ES 3.0.4 table 3.24
2620TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
2621{
2622 glActiveTexture(GL_TEXTURE0);
2623 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2624 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
2625 EXPECT_GL_NO_ERROR();
2626
2627 drawQuad(mProgram, "position", 0.5f);
2628
2629 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2630}
2631
2632// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2633// ES 3.0.4 table 3.24
2634TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
2635{
2636 glActiveTexture(GL_TEXTURE0);
2637 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2638 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
2639 nullptr);
2640 EXPECT_GL_NO_ERROR();
2641
2642 drawQuad(mProgram, "position", 0.5f);
2643
2644 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2645}
2646
2647// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2648// ES 3.0.4 table 3.24
2649TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
2650{
2651 glActiveTexture(GL_TEXTURE0);
2652 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2653 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
2654 EXPECT_GL_NO_ERROR();
2655
2656 drawQuad(mProgram, "position", 0.5f);
2657
2658 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2659}
2660
2661// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2662// ES 3.0.4 table 3.24
2663TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
2664{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002665 if (IsIntel() && IsLinux())
2666 {
2667 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2668 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2669 return;
2670 }
2671
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002672 glActiveTexture(GL_TEXTURE0);
2673 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2674 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2675 EXPECT_GL_NO_ERROR();
2676
2677 drawQuad(mProgram, "position", 0.5f);
2678
2679 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2680}
2681
Olli Etuaho96963162016-03-21 11:54:33 +02002682// Use a sampler in a uniform struct.
2683TEST_P(SamplerInStructTest, SamplerInStruct)
2684{
2685 runSamplerInStructTest();
2686}
2687
2688// Use a sampler in a uniform struct that's passed as a function parameter.
2689TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2690{
2691 runSamplerInStructTest();
2692}
2693
2694// Use a sampler in a uniform struct array with a struct from the array passed as a function
2695// parameter.
2696TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2697{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002698 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2699 {
2700 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2701 return;
2702 }
Olli Etuaho96963162016-03-21 11:54:33 +02002703 runSamplerInStructTest();
2704}
2705
2706// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2707// parameter.
2708TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2709{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002710 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2711 {
2712 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2713 return;
2714 }
Olli Etuaho96963162016-03-21 11:54:33 +02002715 runSamplerInStructTest();
2716}
2717
2718// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2719// similarly named uniform.
2720TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2721{
2722 runSamplerInStructTest();
2723}
2724
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002725class TextureLimitsTest : public ANGLETest
2726{
2727 protected:
2728 struct RGBA8
2729 {
2730 uint8_t R, G, B, A;
2731 };
2732
2733 TextureLimitsTest()
2734 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2735 {
2736 setWindowWidth(128);
2737 setWindowHeight(128);
2738 setConfigRedBits(8);
2739 setConfigGreenBits(8);
2740 setConfigBlueBits(8);
2741 setConfigAlphaBits(8);
2742 }
2743
2744 ~TextureLimitsTest()
2745 {
2746 if (mProgram != 0)
2747 {
2748 glDeleteProgram(mProgram);
2749 mProgram = 0;
2750
2751 if (!mTextures.empty())
2752 {
2753 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2754 }
2755 }
2756 }
2757
2758 void SetUp() override
2759 {
2760 ANGLETest::SetUp();
2761
2762 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2763 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2764 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2765
2766 ASSERT_GL_NO_ERROR();
2767 }
2768
2769 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2770 GLint vertexTextureCount,
2771 GLint vertexActiveTextureCount,
2772 const std::string &fragPrefix,
2773 GLint fragmentTextureCount,
2774 GLint fragmentActiveTextureCount)
2775 {
2776 std::stringstream vertexShaderStr;
2777 vertexShaderStr << "attribute vec2 position;\n"
2778 << "varying vec4 color;\n"
2779 << "varying vec2 texCoord;\n";
2780
2781 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2782 {
2783 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2784 }
2785
2786 vertexShaderStr << "void main() {\n"
2787 << " gl_Position = vec4(position, 0, 1);\n"
2788 << " texCoord = (position * 0.5) + 0.5;\n"
2789 << " color = vec4(0);\n";
2790
2791 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2792 {
2793 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2794 << ", texCoord);\n";
2795 }
2796
2797 vertexShaderStr << "}";
2798
2799 std::stringstream fragmentShaderStr;
2800 fragmentShaderStr << "varying mediump vec4 color;\n"
2801 << "varying mediump vec2 texCoord;\n";
2802
2803 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2804 {
2805 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2806 }
2807
2808 fragmentShaderStr << "void main() {\n"
2809 << " gl_FragColor = color;\n";
2810
2811 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2812 {
2813 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2814 << ", texCoord);\n";
2815 }
2816
2817 fragmentShaderStr << "}";
2818
2819 const std::string &vertexShaderSource = vertexShaderStr.str();
2820 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2821
2822 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2823 }
2824
2825 RGBA8 getPixel(GLint texIndex)
2826 {
2827 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2828 0, 255u};
2829 return pixel;
2830 }
2831
2832 void initTextures(GLint tex2DCount, GLint texCubeCount)
2833 {
2834 GLint totalCount = tex2DCount + texCubeCount;
2835 mTextures.assign(totalCount, 0);
2836 glGenTextures(totalCount, &mTextures[0]);
2837 ASSERT_GL_NO_ERROR();
2838
2839 std::vector<RGBA8> texData(16 * 16);
2840
2841 GLint texIndex = 0;
2842 for (; texIndex < tex2DCount; ++texIndex)
2843 {
2844 texData.assign(texData.size(), getPixel(texIndex));
2845 glActiveTexture(GL_TEXTURE0 + texIndex);
2846 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2847 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2848 &texData[0]);
2849 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2850 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2851 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2852 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2853 }
2854
2855 ASSERT_GL_NO_ERROR();
2856
2857 for (; texIndex < texCubeCount; ++texIndex)
2858 {
2859 texData.assign(texData.size(), getPixel(texIndex));
2860 glActiveTexture(GL_TEXTURE0 + texIndex);
2861 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2862 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2863 GL_UNSIGNED_BYTE, &texData[0]);
2864 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2865 GL_UNSIGNED_BYTE, &texData[0]);
2866 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2867 GL_UNSIGNED_BYTE, &texData[0]);
2868 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2869 GL_UNSIGNED_BYTE, &texData[0]);
2870 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2871 GL_UNSIGNED_BYTE, &texData[0]);
2872 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2873 GL_UNSIGNED_BYTE, &texData[0]);
2874 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2875 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2876 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2877 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2878 }
2879
2880 ASSERT_GL_NO_ERROR();
2881 }
2882
2883 void testWithTextures(GLint vertexTextureCount,
2884 const std::string &vertexTexturePrefix,
2885 GLint fragmentTextureCount,
2886 const std::string &fragmentTexturePrefix)
2887 {
2888 // Generate textures
2889 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2890
2891 glUseProgram(mProgram);
2892 RGBA8 expectedSum = {0};
2893 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2894 {
2895 std::stringstream uniformNameStr;
2896 uniformNameStr << vertexTexturePrefix << texIndex;
2897 const std::string &uniformName = uniformNameStr.str();
2898 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2899 ASSERT_NE(-1, location);
2900
2901 glUniform1i(location, texIndex);
2902 RGBA8 contribution = getPixel(texIndex);
2903 expectedSum.R += contribution.R;
2904 expectedSum.G += contribution.G;
2905 }
2906
2907 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2908 {
2909 std::stringstream uniformNameStr;
2910 uniformNameStr << fragmentTexturePrefix << texIndex;
2911 const std::string &uniformName = uniformNameStr.str();
2912 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2913 ASSERT_NE(-1, location);
2914
2915 glUniform1i(location, texIndex + vertexTextureCount);
2916 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
2917 expectedSum.R += contribution.R;
2918 expectedSum.G += contribution.G;
2919 }
2920
2921 ASSERT_GE(256u, expectedSum.G);
2922
2923 drawQuad(mProgram, "position", 0.5f);
2924 ASSERT_GL_NO_ERROR();
2925 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
2926 }
2927
2928 GLuint mProgram;
2929 std::vector<GLuint> mTextures;
2930 GLint mMaxVertexTextures;
2931 GLint mMaxFragmentTextures;
2932 GLint mMaxCombinedTextures;
2933};
2934
2935// Test rendering with the maximum vertex texture units.
2936TEST_P(TextureLimitsTest, MaxVertexTextures)
2937{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002938 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002939 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002940 {
2941 std::cout << "Test skipped on Intel." << std::endl;
2942 return;
2943 }
2944
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002945 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
2946 ASSERT_NE(0u, mProgram);
2947 ASSERT_GL_NO_ERROR();
2948
2949 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2950}
2951
2952// Test rendering with the maximum fragment texture units.
2953TEST_P(TextureLimitsTest, MaxFragmentTextures)
2954{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002955 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002956 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002957 {
2958 std::cout << "Test skipped on Intel." << std::endl;
2959 return;
2960 }
2961
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002962 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
2963 ASSERT_NE(0u, mProgram);
2964 ASSERT_GL_NO_ERROR();
2965
2966 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
2967}
2968
2969// Test rendering with maximum combined texture units.
2970TEST_P(TextureLimitsTest, MaxCombinedTextures)
2971{
Jamie Madill412f17d2015-09-25 08:43:54 -04002972 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002973 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04002974 {
2975 std::cout << "Test skipped on Intel." << std::endl;
2976 return;
2977 }
2978
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002979 GLint vertexTextures = mMaxVertexTextures;
2980
2981 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
2982 {
2983 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
2984 }
2985
2986 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
2987 mMaxFragmentTextures, mMaxFragmentTextures);
2988 ASSERT_NE(0u, mProgram);
2989 ASSERT_GL_NO_ERROR();
2990
2991 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
2992}
2993
2994// Negative test for exceeding the number of vertex textures
2995TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
2996{
2997 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
2998 0);
2999 ASSERT_EQ(0u, mProgram);
3000}
3001
3002// Negative test for exceeding the number of fragment textures
3003TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
3004{
3005 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
3006 mMaxFragmentTextures + 1);
3007 ASSERT_EQ(0u, mProgram);
3008}
3009
3010// Test active vertex textures under the limit, but excessive textures specified.
3011TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
3012{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003013 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003014 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003015 {
3016 std::cout << "Test skipped on Intel." << std::endl;
3017 return;
3018 }
3019
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003020 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
3021 ASSERT_NE(0u, mProgram);
3022 ASSERT_GL_NO_ERROR();
3023
3024 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3025}
3026
3027// Test active fragment textures under the limit, but excessive textures specified.
3028TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
3029{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003030 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003031 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003032 {
3033 std::cout << "Test skipped on Intel." << std::endl;
3034 return;
3035 }
3036
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003037 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
3038 mMaxFragmentTextures);
3039 ASSERT_NE(0u, mProgram);
3040 ASSERT_GL_NO_ERROR();
3041
3042 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
3043}
3044
3045// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003046// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003047TEST_P(TextureLimitsTest, TextureTypeConflict)
3048{
3049 const std::string &vertexShader =
3050 "attribute vec2 position;\n"
3051 "varying float color;\n"
3052 "uniform sampler2D tex2D;\n"
3053 "uniform samplerCube texCube;\n"
3054 "void main() {\n"
3055 " gl_Position = vec4(position, 0, 1);\n"
3056 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3057 " color = texture2D(tex2D, texCoord).x;\n"
3058 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
3059 "}";
3060 const std::string &fragmentShader =
3061 "varying mediump float color;\n"
3062 "void main() {\n"
3063 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3064 "}";
3065
3066 mProgram = CompileProgram(vertexShader, fragmentShader);
3067 ASSERT_NE(0u, mProgram);
3068
3069 initTextures(1, 0);
3070
3071 glUseProgram(mProgram);
3072 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3073 ASSERT_NE(-1, tex2DLocation);
3074 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
3075 ASSERT_NE(-1, texCubeLocation);
3076
3077 glUniform1i(tex2DLocation, 0);
3078 glUniform1i(texCubeLocation, 0);
3079 ASSERT_GL_NO_ERROR();
3080
3081 drawQuad(mProgram, "position", 0.5f);
3082 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3083}
3084
3085// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003086// TODO(jmadill): Possibly adjust the test according to the spec:
3087// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
3088// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003089TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
3090{
3091 const std::string &vertexShader =
3092 "attribute vec2 position;\n"
3093 "varying float color;\n"
3094 "uniform sampler2D tex2D;\n"
3095 "void main() {\n"
3096 " gl_Position = vec4(position, 0, 1);\n"
3097 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3098 " color = texture2D(tex2D, texCoord).x;\n"
3099 "}";
3100 const std::string &fragmentShader =
3101 "varying mediump float color;\n"
3102 "void main() {\n"
3103 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3104 "}";
3105
3106 mProgram = CompileProgram(vertexShader, fragmentShader);
3107 ASSERT_NE(0u, mProgram);
3108
3109 glUseProgram(mProgram);
3110 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3111 ASSERT_NE(-1, tex2DLocation);
3112
3113 glUniform1i(tex2DLocation, mMaxCombinedTextures);
3114 ASSERT_GL_NO_ERROR();
3115
3116 drawQuad(mProgram, "position", 0.5f);
3117 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3118}
3119
Jamie Madillfa05f602015-05-07 13:47:11 -04003120// 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 +02003121// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05003122ANGLE_INSTANTIATE_TEST(Texture2DTest,
3123 ES2_D3D9(),
3124 ES2_D3D11(),
3125 ES2_D3D11_FL9_3(),
3126 ES2_OPENGL(),
3127 ES2_OPENGLES());
3128ANGLE_INSTANTIATE_TEST(TextureCubeTest,
3129 ES2_D3D9(),
3130 ES2_D3D11(),
3131 ES2_D3D11_FL9_3(),
3132 ES2_OPENGL(),
3133 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003134ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
3135 ES2_D3D9(),
3136 ES2_D3D11(),
3137 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003138 ES2_OPENGL(),
3139 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003140ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
3141 ES2_D3D9(),
3142 ES2_D3D11(),
3143 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003144 ES2_OPENGL(),
3145 ES2_OPENGLES());
3146ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
3147 ES2_D3D9(),
3148 ES2_D3D11(),
3149 ES2_D3D11_FL9_3(),
3150 ES2_OPENGL(),
3151 ES2_OPENGLES());
3152ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
3153 ES2_D3D9(),
3154 ES2_D3D11(),
3155 ES2_D3D11_FL9_3(),
3156 ES2_OPENGL(),
3157 ES2_OPENGLES());
3158ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahoa314b612016-03-10 16:43:00 +02003159ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003160ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3161ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
3162 ES3_D3D11(),
3163 ES3_OPENGL(),
3164 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003165ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
3166 ES3_D3D11(),
3167 ES3_OPENGL(),
3168 ES3_OPENGLES());
3169ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3170ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02003171ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02003172ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
3173 ES2_D3D11(),
3174 ES2_D3D11_FL9_3(),
3175 ES2_D3D9(),
3176 ES2_OPENGL(),
3177 ES2_OPENGLES());
3178ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
3179 ES2_D3D11(),
3180 ES2_D3D11_FL9_3(),
3181 ES2_D3D9(),
3182 ES2_OPENGL(),
3183 ES2_OPENGLES());
3184ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
3185 ES2_D3D11(),
3186 ES2_D3D11_FL9_3(),
3187 ES2_D3D9(),
3188 ES2_OPENGL(),
3189 ES2_OPENGLES());
3190ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
3191 ES2_D3D11(),
3192 ES2_D3D11_FL9_3(),
3193 ES2_D3D9(),
3194 ES2_OPENGL(),
3195 ES2_OPENGLES());
3196ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
3197 ES2_D3D11(),
3198 ES2_D3D11_FL9_3(),
3199 ES2_D3D9(),
3200 ES2_OPENGL(),
3201 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003202ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04003203
3204} // namespace