blob: 22dfac3f433bbcd30845b16777906c82f968a71a [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
271 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
272 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 Etuaho1a679902016-01-14 12:21:47 +0200783class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
784{
785 protected:
786 ShadowSamplerPlusSampler3DTestES3()
787 : TexCoordDrawTest(),
788 mTextureShadow(0),
789 mTexture3D(0),
790 mTextureShadowUniformLocation(-1),
791 mTexture3DUniformLocation(-1),
792 mDepthRefUniformLocation(-1)
793 {
794 }
795
796 std::string getVertexShaderSource() override
797 {
798 return std::string(
799 "#version 300 es\n"
800 "out vec2 texcoord;\n"
801 "in vec4 position;\n"
802 "void main()\n"
803 "{\n"
804 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
805 " texcoord = (position.xy * 0.5) + 0.5;\n"
806 "}\n");
807 }
808
809 std::string getFragmentShaderSource() override
810 {
811 return std::string(
812 "#version 300 es\n"
813 "precision highp float;\n"
814 "uniform highp sampler2DShadow tex2DShadow;\n"
815 "uniform highp sampler3D tex3D;\n"
816 "in vec2 texcoord;\n"
817 "uniform float depthRef;\n"
818 "out vec4 fragColor;\n"
819 "void main()\n"
820 "{\n"
821 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
822 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
823 "}\n");
824 }
825
826 void SetUp() override
827 {
828 TexCoordDrawTest::SetUp();
829
830 glGenTextures(1, &mTexture3D);
831
832 glGenTextures(1, &mTextureShadow);
833 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
834 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
835
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300836 setUpProgram();
837
Olli Etuaho1a679902016-01-14 12:21:47 +0200838 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
839 ASSERT_NE(-1, mTextureShadowUniformLocation);
840 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
841 ASSERT_NE(-1, mTexture3DUniformLocation);
842 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
843 ASSERT_NE(-1, mDepthRefUniformLocation);
844 }
845
846 void TearDown() override
847 {
848 glDeleteTextures(1, &mTextureShadow);
849 glDeleteTextures(1, &mTexture3D);
850 TexCoordDrawTest::TearDown();
851 }
852
853 GLuint mTextureShadow;
854 GLuint mTexture3D;
855 GLint mTextureShadowUniformLocation;
856 GLint mTexture3DUniformLocation;
857 GLint mDepthRefUniformLocation;
858};
859
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200860class SamplerTypeMixTestES3 : public TexCoordDrawTest
861{
862 protected:
863 SamplerTypeMixTestES3()
864 : TexCoordDrawTest(),
865 mTexture2D(0),
866 mTextureCube(0),
867 mTexture2DShadow(0),
868 mTextureCubeShadow(0),
869 mTexture2DUniformLocation(-1),
870 mTextureCubeUniformLocation(-1),
871 mTexture2DShadowUniformLocation(-1),
872 mTextureCubeShadowUniformLocation(-1),
873 mDepthRefUniformLocation(-1)
874 {
875 }
876
877 std::string getVertexShaderSource() override
878 {
879 return std::string(
880 "#version 300 es\n"
881 "out vec2 texcoord;\n"
882 "in vec4 position;\n"
883 "void main()\n"
884 "{\n"
885 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
886 " texcoord = (position.xy * 0.5) + 0.5;\n"
887 "}\n");
888 }
889
890 std::string getFragmentShaderSource() override
891 {
892 return std::string(
893 "#version 300 es\n"
894 "precision highp float;\n"
895 "uniform highp sampler2D tex2D;\n"
896 "uniform highp samplerCube texCube;\n"
897 "uniform highp sampler2DShadow tex2DShadow;\n"
898 "uniform highp samplerCubeShadow texCubeShadow;\n"
899 "in vec2 texcoord;\n"
900 "uniform float depthRef;\n"
901 "out vec4 fragColor;\n"
902 "void main()\n"
903 "{\n"
904 " fragColor = texture(tex2D, texcoord);\n"
905 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
906 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
907 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
908 "0.125);\n"
909 "}\n");
910 }
911
912 void SetUp() override
913 {
914 TexCoordDrawTest::SetUp();
915
916 glGenTextures(1, &mTexture2D);
917 glGenTextures(1, &mTextureCube);
918
919 glGenTextures(1, &mTexture2DShadow);
920 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
921 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
922
923 glGenTextures(1, &mTextureCubeShadow);
924 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
925 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
926
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300927 setUpProgram();
928
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200929 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
930 ASSERT_NE(-1, mTexture2DUniformLocation);
931 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
932 ASSERT_NE(-1, mTextureCubeUniformLocation);
933 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
934 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
935 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
936 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
937 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
938 ASSERT_NE(-1, mDepthRefUniformLocation);
939
940 ASSERT_GL_NO_ERROR();
941 }
942
943 void TearDown() override
944 {
945 glDeleteTextures(1, &mTexture2D);
946 glDeleteTextures(1, &mTextureCube);
947 glDeleteTextures(1, &mTexture2DShadow);
948 glDeleteTextures(1, &mTextureCubeShadow);
949 TexCoordDrawTest::TearDown();
950 }
951
952 GLuint mTexture2D;
953 GLuint mTextureCube;
954 GLuint mTexture2DShadow;
955 GLuint mTextureCubeShadow;
956 GLint mTexture2DUniformLocation;
957 GLint mTextureCubeUniformLocation;
958 GLint mTexture2DShadowUniformLocation;
959 GLint mTextureCubeShadowUniformLocation;
960 GLint mDepthRefUniformLocation;
961};
962
Olli Etuaho96963162016-03-21 11:54:33 +0200963class SamplerInStructTest : public Texture2DTest
964{
965 protected:
966 SamplerInStructTest() : Texture2DTest() {}
967
968 const char *getTextureUniformName() override { return "us.tex"; }
969
970 std::string getFragmentShaderSource() override
971 {
972 return std::string(
973 "precision highp float;\n"
974 "struct S\n"
975 "{\n"
976 " vec4 a;\n"
977 " highp sampler2D tex;\n"
978 "};\n"
979 "uniform S us;\n"
980 "varying vec2 texcoord;\n"
981 "void main()\n"
982 "{\n"
983 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
984 "}\n");
985 }
986
987 void runSamplerInStructTest()
988 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300989 setUpProgram();
990
Olli Etuaho96963162016-03-21 11:54:33 +0200991 glActiveTexture(GL_TEXTURE0);
992 glBindTexture(GL_TEXTURE_2D, mTexture2D);
993 GLubyte texDataGreen[1u * 1u * 4u];
994 FillWithRGBA<GLubyte>(1u * 1u, 0u, 255u, 0u, 255u, texDataGreen);
995 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
996 drawQuad(mProgram, "position", 0.5f);
997 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
998 }
999};
1000
1001class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1002{
1003 protected:
1004 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1005
1006 std::string getFragmentShaderSource() override
1007 {
1008 return std::string(
1009 "precision highp float;\n"
1010 "struct S\n"
1011 "{\n"
1012 " vec4 a;\n"
1013 " highp sampler2D tex;\n"
1014 "};\n"
1015 "uniform S us;\n"
1016 "varying vec2 texcoord;\n"
1017 "vec4 sampleFrom(S s) {\n"
1018 " return texture2D(s.tex, texcoord + s.a.x);\n"
1019 "}\n"
1020 "void main()\n"
1021 "{\n"
1022 " gl_FragColor = sampleFrom(us);\n"
1023 "}\n");
1024 }
1025};
1026
1027class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1028{
1029 protected:
1030 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1031
1032 const char *getTextureUniformName() override { return "us[0].tex"; }
1033
1034 std::string getFragmentShaderSource() override
1035 {
1036 return std::string(
1037 "precision highp float;\n"
1038 "struct S\n"
1039 "{\n"
1040 " vec4 a;\n"
1041 " highp sampler2D tex;\n"
1042 "};\n"
1043 "uniform S us[1];\n"
1044 "varying vec2 texcoord;\n"
1045 "vec4 sampleFrom(S s) {\n"
1046 " return texture2D(s.tex, texcoord + s.a.x);\n"
1047 "}\n"
1048 "void main()\n"
1049 "{\n"
1050 " gl_FragColor = sampleFrom(us[0]);\n"
1051 "}\n");
1052 }
1053};
1054
1055class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1056{
1057 protected:
1058 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1059
1060 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1061
1062 std::string getFragmentShaderSource() override
1063 {
1064 return std::string(
1065 "precision highp float;\n"
1066 "struct SUB\n"
1067 "{\n"
1068 " vec4 a;\n"
1069 " highp sampler2D tex;\n"
1070 "};\n"
1071 "struct S\n"
1072 "{\n"
1073 " SUB sub;\n"
1074 "};\n"
1075 "uniform S us[1];\n"
1076 "varying vec2 texcoord;\n"
1077 "vec4 sampleFrom(SUB s) {\n"
1078 " return texture2D(s.tex, texcoord + s.a.x);\n"
1079 "}\n"
1080 "void main()\n"
1081 "{\n"
1082 " gl_FragColor = sampleFrom(us[0].sub);\n"
1083 "}\n");
1084 }
1085};
1086
1087class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1088{
1089 protected:
1090 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1091
1092 std::string getFragmentShaderSource() override
1093 {
1094 return std::string(
1095 "precision highp float;\n"
1096 "struct S\n"
1097 "{\n"
1098 " vec4 a;\n"
1099 " highp sampler2D tex;\n"
1100 "};\n"
1101 "uniform S us;\n"
1102 "uniform float us_tex;\n"
1103 "varying vec2 texcoord;\n"
1104 "void main()\n"
1105 "{\n"
1106 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1107 "}\n");
1108 }
1109};
1110
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001111TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001112{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001113 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001114 EXPECT_GL_ERROR(GL_NO_ERROR);
1115
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001116 setUpProgram();
1117
Jamie Madillf67115c2014-04-22 13:14:05 -04001118 const GLubyte *pixels[20] = { 0 };
1119 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1120 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1121}
Geoff Langc41e42d2014-04-28 10:58:16 -04001122
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001123TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001124{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001125 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001126 EXPECT_GL_ERROR(GL_NO_ERROR);
1127
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001128 setUpProgram();
1129
Geoff Langc41e42d2014-04-28 10:58:16 -04001130 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001131 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001132 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001133 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001134
1135 const GLubyte *pixel[4] = { 0 };
1136
1137 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1138 EXPECT_GL_NO_ERROR();
1139
1140 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1141 EXPECT_GL_NO_ERROR();
1142
1143 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1144 EXPECT_GL_NO_ERROR();
1145}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001146
1147// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001148TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001149{
1150 glActiveTexture(GL_TEXTURE0);
1151 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1152 glActiveTexture(GL_TEXTURE1);
1153 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1154 EXPECT_GL_ERROR(GL_NO_ERROR);
1155
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001156 glUseProgram(mProgram);
1157 glUniform1i(mTexture2DUniformLocation, 0);
1158 glUniform1i(mTextureCubeUniformLocation, 1);
1159 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001160 EXPECT_GL_NO_ERROR();
1161}
Jamie Madill9aca0592014-10-06 16:26:59 -04001162
Olli Etuaho53a2da12016-01-11 15:43:32 +02001163// Test drawing with two texture types accessed from the same shader and check that the result of
1164// drawing is correct.
1165TEST_P(TextureCubeTest, CubeMapDraw)
1166{
1167 GLubyte texData[4];
1168 texData[0] = 0;
1169 texData[1] = 60;
1170 texData[2] = 0;
1171 texData[3] = 255;
1172
1173 glActiveTexture(GL_TEXTURE0);
1174 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1175 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1176
1177 glActiveTexture(GL_TEXTURE1);
1178 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1179 texData[1] = 120;
1180 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1181 texData);
1182 EXPECT_GL_ERROR(GL_NO_ERROR);
1183
1184 glUseProgram(mProgram);
1185 glUniform1i(mTexture2DUniformLocation, 0);
1186 glUniform1i(mTextureCubeUniformLocation, 1);
1187 drawQuad(mProgram, "position", 0.5f);
1188 EXPECT_GL_NO_ERROR();
1189
1190 int px = getWindowWidth() - 1;
1191 int py = 0;
1192 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1193}
1194
Olli Etuaho4644a202016-01-12 15:12:53 +02001195TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1196{
1197 glActiveTexture(GL_TEXTURE0);
1198 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1199 GLubyte texData[4];
1200 texData[0] = 0;
1201 texData[1] = 128;
1202 texData[2] = 0;
1203 texData[3] = 255;
1204 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1205 glUseProgram(mProgram);
1206 glUniform1i(mTexture2DUniformLocation, 0);
1207 drawQuad(mProgram, "position", 0.5f);
1208 EXPECT_GL_NO_ERROR();
1209
1210 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1211}
1212
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001213// Test drawing with two textures passed to the shader in a sampler array.
1214TEST_P(SamplerArrayTest, SamplerArrayDraw)
1215{
1216 testSamplerArrayDraw();
1217}
1218
1219// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1220// user-defined function in the shader.
1221TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1222{
1223 testSamplerArrayDraw();
1224}
1225
Jamie Madill9aca0592014-10-06 16:26:59 -04001226// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001227TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001228{
1229 int px = getWindowWidth() / 2;
1230 int py = getWindowHeight() / 2;
1231
1232 glActiveTexture(GL_TEXTURE0);
1233 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1234
1235 // Fill with red
1236 std::vector<GLubyte> pixels(4 * 16 * 16);
Olli Etuaho356f5162016-03-18 14:19:41 +02001237 FillWithRGBA<GLubyte>(16u * 16u, 255u, 0u, 0u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001238
1239 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1242 glGenerateMipmap(GL_TEXTURE_2D);
1243
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001244 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001245 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001246 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1247 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001248 EXPECT_GL_NO_ERROR();
1249 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
1250
1251 // Fill with blue
Olli Etuaho356f5162016-03-18 14:19:41 +02001252 FillWithRGBA<GLubyte>(16u * 16u, 0u, 0u, 255u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001253
1254 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1255 glGenerateMipmap(GL_TEXTURE_2D);
1256
1257 // Fill with green
Olli Etuaho356f5162016-03-18 14:19:41 +02001258 FillWithRGBA<GLubyte>(16u * 16u, 0u, 255u, 0u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001259
1260 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1261 glGenerateMipmap(GL_TEXTURE_2D);
1262
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001263 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001264
1265 EXPECT_GL_NO_ERROR();
1266 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
1267}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001268
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001269// Test creating a FBO with a cube map render target, to test an ANGLE bug
1270// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001271TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001272{
1273 GLuint fbo;
1274 glGenFramebuffers(1, &fbo);
1275 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1276
1277 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1278 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1279
Corentin Wallez322653b2015-06-17 18:33:56 +02001280 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001281
1282 glDeleteFramebuffers(1, &fbo);
1283
1284 EXPECT_GL_NO_ERROR();
1285}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001286
1287// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001288TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001289{
1290 int width = getWindowWidth();
1291 int height = getWindowHeight();
1292
1293 GLuint tex2D;
1294 glGenTextures(1, &tex2D);
1295 glActiveTexture(GL_TEXTURE0);
1296 glBindTexture(GL_TEXTURE_2D, tex2D);
1297
1298 // Fill with red
1299 std::vector<GLubyte> pixels(3 * 16 * 16);
1300 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1301 {
1302 pixels[pixelId * 3 + 0] = 255;
1303 pixels[pixelId * 3 + 1] = 0;
1304 pixels[pixelId * 3 + 2] = 0;
1305 }
1306
1307 // ANGLE internally uses RGBA as the DirectX format for RGB images
1308 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1309 // The data is kept in a CPU-side image and the image is marked as dirty.
1310 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1311
1312 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1313 // glTexSubImage2D should take into account that the image is dirty.
1314 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1317
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001318 setUpProgram();
1319
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001320 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001321 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001322 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001323 glDeleteTextures(1, &tex2D);
1324 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001325 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001326
1327 // Validate that the region of the texture without data has an alpha of 1.0
1328 GLubyte pixel[4];
1329 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1330 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001331}
1332
1333// 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 +02001334TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001335{
1336 if (extensionEnabled("NV_pixel_buffer_object"))
1337 {
1338 int width = getWindowWidth();
1339 int height = getWindowHeight();
1340
1341 GLuint tex2D;
1342 glGenTextures(1, &tex2D);
1343 glActiveTexture(GL_TEXTURE0);
1344 glBindTexture(GL_TEXTURE_2D, tex2D);
1345
1346 // Fill with red
1347 std::vector<GLubyte> pixels(3 * 16 * 16);
1348 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1349 {
1350 pixels[pixelId * 3 + 0] = 255;
1351 pixels[pixelId * 3 + 1] = 0;
1352 pixels[pixelId * 3 + 2] = 0;
1353 }
1354
1355 // Read 16x16 region from red backbuffer to PBO
1356 GLuint pbo;
1357 glGenBuffers(1, &pbo);
1358 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1359 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1360
1361 // ANGLE internally uses RGBA as the DirectX format for RGB images
1362 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1363 // The data is kept in a CPU-side image and the image is marked as dirty.
1364 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1365
1366 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1367 // glTexSubImage2D should take into account that the image is dirty.
1368 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1369 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1371
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001372 setUpProgram();
1373
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001374 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001375 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001376 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001377 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001378 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001379 EXPECT_GL_NO_ERROR();
1380 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1381 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1382 }
1383}
Jamie Madillbc393df2015-01-29 13:46:07 -05001384
1385// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001386TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001387{
1388 testFloatCopySubImage(1, 1);
1389}
1390
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001391TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001392{
1393 testFloatCopySubImage(2, 1);
1394}
1395
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001396TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001397{
1398 testFloatCopySubImage(2, 2);
1399}
1400
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001401TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001402{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001403 if (IsIntel() && IsLinux())
1404 {
1405 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1406 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1407 return;
1408 }
1409
Jamie Madillbc393df2015-01-29 13:46:07 -05001410 testFloatCopySubImage(3, 1);
1411}
1412
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001413TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001414{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001415 if (IsIntel() && IsLinux())
1416 {
1417 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1418 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1419 return;
1420 }
1421
Jamie Madillbc393df2015-01-29 13:46:07 -05001422 testFloatCopySubImage(3, 2);
1423}
1424
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001425TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001426{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001427 if (IsIntel() && IsLinux())
1428 {
1429 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1430 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1431 return;
1432 }
1433
Austin Kinrossd544cc92016-01-11 15:26:42 -08001434 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001435 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001436 {
1437 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1438 return;
1439 }
1440
Jamie Madillbc393df2015-01-29 13:46:07 -05001441 testFloatCopySubImage(3, 3);
1442}
1443
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001444TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001445{
1446 testFloatCopySubImage(4, 1);
1447}
1448
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001449TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001450{
1451 testFloatCopySubImage(4, 2);
1452}
1453
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001454TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001455{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001456 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001457 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001458 {
1459 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1460 return;
1461 }
1462
Jamie Madillbc393df2015-01-29 13:46:07 -05001463 testFloatCopySubImage(4, 3);
1464}
1465
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001466TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001467{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001468 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001469 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001470 {
1471 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1472 return;
1473 }
1474
Jamie Madillbc393df2015-01-29 13:46:07 -05001475 testFloatCopySubImage(4, 4);
1476}
Austin Kinross07285142015-03-26 11:36:16 -07001477
1478// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1479// 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 +02001480TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001481{
1482 const int npotTexSize = 5;
1483 const int potTexSize = 4; // Should be less than npotTexSize
1484 GLuint tex2D;
1485
1486 if (extensionEnabled("GL_OES_texture_npot"))
1487 {
1488 // This test isn't applicable if texture_npot is enabled
1489 return;
1490 }
1491
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001492 setUpProgram();
1493
Austin Kinross07285142015-03-26 11:36:16 -07001494 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1495
Austin Kinross5faa15b2016-01-11 13:32:48 -08001496 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1497 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1498
Austin Kinross07285142015-03-26 11:36:16 -07001499 glActiveTexture(GL_TEXTURE0);
1500 glGenTextures(1, &tex2D);
1501 glBindTexture(GL_TEXTURE_2D, tex2D);
1502
1503 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1504 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1505 {
1506 pixels[pixelId] = 64;
1507 }
1508
1509 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1510 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1511
1512 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1513 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1514 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1515
1516 // Check that an NPOT texture on level 0 succeeds
1517 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1518 EXPECT_GL_NO_ERROR();
1519
1520 // Check that generateMipmap fails on NPOT
1521 glGenerateMipmap(GL_TEXTURE_2D);
1522 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1523
1524 // Check that nothing is drawn if filtering is not correct for NPOT
1525 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1526 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1527 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1528 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1529 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001530 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001531 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1532
1533 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1534 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1535 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1536 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1537 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001538 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001539 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1540
1541 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1542 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1543 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001544 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001545 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1546
1547 // Check that glTexImage2D for POT texture succeeds
1548 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1549 EXPECT_GL_NO_ERROR();
1550
1551 // Check that generateMipmap for an POT texture succeeds
1552 glGenerateMipmap(GL_TEXTURE_2D);
1553 EXPECT_GL_NO_ERROR();
1554
1555 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1556 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1557 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1558 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1559 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1560 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001561 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001562 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1563 EXPECT_GL_NO_ERROR();
1564}
Jamie Madillfa05f602015-05-07 13:47:11 -04001565
Austin Kinross08528e12015-10-07 16:24:40 -07001566// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1567// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001568TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001569{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001570 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1571 // 1278)
1572 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1573 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1574 {
1575 std::cout << "Test disabled on OpenGL." << std::endl;
1576 return;
1577 }
1578
Austin Kinross08528e12015-10-07 16:24:40 -07001579 glActiveTexture(GL_TEXTURE0);
1580 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1581
1582 // Create an 8x8 (i.e. power-of-two) texture.
1583 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1586 glGenerateMipmap(GL_TEXTURE_2D);
1587
1588 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1589 // This should always work, even if GL_OES_texture_npot isn't active.
1590 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1591
1592 EXPECT_GL_NO_ERROR();
1593}
1594
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001595// Test to check that texture completeness is determined correctly when the texture base level is
1596// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1597TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1598{
1599 glActiveTexture(GL_TEXTURE0);
1600 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1601 GLubyte texDataRed[4u * 4u * 4u];
Olli Etuaho356f5162016-03-18 14:19:41 +02001602 FillWithRGBA<GLubyte>(4u * 4u, 255u, 0u, 0u, 255u, texDataRed);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001603 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
1604 GLubyte texDataGreen[2u * 2u * 4u];
Olli Etuaho356f5162016-03-18 14:19:41 +02001605 FillWithRGBA<GLubyte>(2u * 2u, 0u, 255u, 0u, 255u, texDataGreen);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001606 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1607 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1611
1612 EXPECT_GL_NO_ERROR();
1613
1614 drawQuad(mProgram, "position", 0.5f);
1615
1616 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1617}
1618
Jamie Madill2453dbc2015-07-14 11:35:42 -04001619// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
1620// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
1621// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001622TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04001623{
1624 std::vector<GLubyte> pixelData;
1625 for (size_t count = 0; count < 5000; count++)
1626 {
1627 pixelData.push_back(0u);
1628 pixelData.push_back(255u);
1629 pixelData.push_back(0u);
1630 }
1631
1632 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001633 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001634 glUniform1i(mTextureArrayLocation, 0);
1635
1636 // The first draw worked correctly.
1637 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
1638
1639 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1640 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1641 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1642 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001643 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001644 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1645
1646 // The dimension of the respecification must match the original exactly to trigger the bug.
1647 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 +02001648 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001649 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1650
1651 ASSERT_GL_NO_ERROR();
1652}
1653
Olli Etuaho1a679902016-01-14 12:21:47 +02001654// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
1655// This test is needed especially to confirm that sampler registers get assigned correctly on
1656// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
1657TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
1658{
1659 glActiveTexture(GL_TEXTURE0);
1660 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1661 GLubyte texData[4];
1662 texData[0] = 0;
1663 texData[1] = 60;
1664 texData[2] = 0;
1665 texData[3] = 255;
1666 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1667
1668 glActiveTexture(GL_TEXTURE1);
1669 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1670 GLfloat depthTexData[1];
1671 depthTexData[0] = 0.5f;
1672 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1673 depthTexData);
1674
1675 glUseProgram(mProgram);
1676 glUniform1f(mDepthRefUniformLocation, 0.3f);
1677 glUniform1i(mTexture3DUniformLocation, 0);
1678 glUniform1i(mTextureShadowUniformLocation, 1);
1679
1680 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1681 drawQuad(mProgram, "position", 0.5f);
1682 EXPECT_GL_NO_ERROR();
1683 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
1684 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
1685
1686 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
1687 drawQuad(mProgram, "position", 0.5f);
1688 EXPECT_GL_NO_ERROR();
1689 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
1690 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
1691}
1692
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001693// Test multiple different sampler types in the same shader.
1694// This test makes sure that even if sampler / texture registers get grouped together based on type
1695// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
1696// still has the right register index information for each ESSL sampler.
1697// The tested ESSL samplers have the following types in D3D11 HLSL:
1698// sampler2D: Texture2D + SamplerState
1699// samplerCube: TextureCube + SamplerState
1700// sampler2DShadow: Texture2D + SamplerComparisonState
1701// samplerCubeShadow: TextureCube + SamplerComparisonState
1702TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
1703{
1704 glActiveTexture(GL_TEXTURE0);
1705 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1706 GLubyte texData[4];
1707 texData[0] = 0;
1708 texData[1] = 0;
1709 texData[2] = 120;
1710 texData[3] = 255;
1711 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1712
1713 glActiveTexture(GL_TEXTURE1);
1714 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1715 texData[0] = 0;
1716 texData[1] = 90;
1717 texData[2] = 0;
1718 texData[3] = 255;
1719 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
1720 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1721 texData);
1722
1723 glActiveTexture(GL_TEXTURE2);
1724 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1725 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1726 GLfloat depthTexData[1];
1727 depthTexData[0] = 0.5f;
1728 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1729 depthTexData);
1730
1731 glActiveTexture(GL_TEXTURE3);
1732 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1733 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1734 depthTexData[0] = 0.2f;
1735 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1736 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
1737 depthTexData);
1738
1739 EXPECT_GL_NO_ERROR();
1740
1741 glUseProgram(mProgram);
1742 glUniform1f(mDepthRefUniformLocation, 0.3f);
1743 glUniform1i(mTexture2DUniformLocation, 0);
1744 glUniform1i(mTextureCubeUniformLocation, 1);
1745 glUniform1i(mTexture2DShadowUniformLocation, 2);
1746 glUniform1i(mTextureCubeShadowUniformLocation, 3);
1747
1748 drawQuad(mProgram, "position", 0.5f);
1749 EXPECT_GL_NO_ERROR();
1750 // The shader writes:
1751 // <texture 2d color> +
1752 // <cube map color> +
1753 // 0.25 * <comparison result (1.0)> +
1754 // 0.125 * <comparison result (0.0)>
1755 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
1756}
1757
Olli Etuahobce743a2016-01-15 17:18:28 +02001758// Test different base levels on textures accessed through the same sampler array.
1759// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
1760TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
1761{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001762 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02001763 {
1764 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
1765 return;
1766 }
1767 glActiveTexture(GL_TEXTURE0);
1768 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
1769 GLsizei size = 64;
1770 for (GLint level = 0; level < 7; ++level)
1771 {
1772 ASSERT_LT(0, size);
1773 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1774 nullptr);
1775 size = size / 2;
1776 }
1777 ASSERT_EQ(0, size);
1778 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1779
1780 glActiveTexture(GL_TEXTURE1);
1781 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
1782 size = 128;
1783 for (GLint level = 0; level < 8; ++level)
1784 {
1785 ASSERT_LT(0, size);
1786 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1787 nullptr);
1788 size = size / 2;
1789 }
1790 ASSERT_EQ(0, size);
1791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
1792 EXPECT_GL_NO_ERROR();
1793
1794 glUseProgram(mProgram);
1795 glUniform1i(mTexture0Location, 0);
1796 glUniform1i(mTexture1Location, 1);
1797
1798 drawQuad(mProgram, "position", 0.5f);
1799 EXPECT_GL_NO_ERROR();
1800 // Red channel: width of level 1 of texture A: 32.
1801 // Green channel: width of level 3 of texture B: 16.
1802 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
1803}
1804
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001805// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1806// ES 3.0.4 table 3.24
1807TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
1808{
1809 glActiveTexture(GL_TEXTURE0);
1810 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1811 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1812 EXPECT_GL_NO_ERROR();
1813
1814 drawQuad(mProgram, "position", 0.5f);
1815
1816 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1817}
1818
1819// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1820// ES 3.0.4 table 3.24
1821TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
1822{
1823 glActiveTexture(GL_TEXTURE0);
1824 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1825 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1826 EXPECT_GL_NO_ERROR();
1827
1828 drawQuad(mProgram, "position", 0.5f);
1829
1830 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1831}
1832
1833// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1834// ES 3.0.4 table 3.24
1835TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
1836{
1837 if (extensionEnabled("GL_OES_texture_float"))
1838 {
1839 glActiveTexture(GL_TEXTURE0);
1840 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1841 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
1842 EXPECT_GL_NO_ERROR();
1843
1844 drawQuad(mProgram, "position", 0.5f);
1845
1846 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1847 }
1848}
1849
1850// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1851// ES 3.0.4 table 3.24
1852TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
1853{
1854 if (extensionEnabled("GL_OES_texture_half_float"))
1855 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001856 if (IsNVIDIA() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001857 {
1858 std::cout << "Test skipped on NVIDIA" << std::endl;
1859 return;
1860 }
1861 glActiveTexture(GL_TEXTURE0);
1862 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1863 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
1864 nullptr);
1865 EXPECT_GL_NO_ERROR();
1866
1867 drawQuad(mProgram, "position", 0.5f);
1868
1869 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1870 }
1871}
1872
1873// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1874// ES 3.0.4 table 3.24
1875TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
1876{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001877 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001878 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001879 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001880 return;
1881 }
1882 glActiveTexture(GL_TEXTURE0);
1883 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1884 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
1885 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1886 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1887 EXPECT_GL_NO_ERROR();
1888
1889 drawQuad(mProgram, "position", 0.5f);
1890
1891 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1892}
1893
1894// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1895// ES 3.0.4 table 3.24
1896TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
1897{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001898 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001899 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001900 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001901 return;
1902 }
1903 glActiveTexture(GL_TEXTURE0);
1904 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1905
1906 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
1907 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1908 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1909 EXPECT_GL_NO_ERROR();
1910
1911 drawQuad(mProgram, "position", 0.5f);
1912
1913 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1914}
1915
1916// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1917// ES 3.0.4 table 3.24
1918TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
1919{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001920 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001921 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001922 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001923 return;
1924 }
1925 glActiveTexture(GL_TEXTURE0);
1926 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1927 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
1928 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1929 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1930 EXPECT_GL_NO_ERROR();
1931
1932 drawQuad(mProgram, "position", 0.5f);
1933
1934 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1935}
1936
1937// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1938// ES 3.0.4 table 3.24
1939TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
1940{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001941 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001942 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001943 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001944 return;
1945 }
1946 glActiveTexture(GL_TEXTURE0);
1947 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1948 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
1949 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1950 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1951 EXPECT_GL_NO_ERROR();
1952
1953 drawQuad(mProgram, "position", 0.5f);
1954
1955 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1956}
1957
1958// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1959// ES 3.0.4 table 3.24
1960TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
1961{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001962 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001963 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001964 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001965 return;
1966 }
1967 glActiveTexture(GL_TEXTURE0);
1968 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1969 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
1970 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1971 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1972 EXPECT_GL_NO_ERROR();
1973
1974 drawQuad(mProgram, "position", 0.5f);
1975
1976 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1977}
1978
1979// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1980// ES 3.0.4 table 3.24
1981TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
1982{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001983 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001984 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001985 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001986 return;
1987 }
1988 glActiveTexture(GL_TEXTURE0);
1989 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1990 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
1991 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1992 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1993 EXPECT_GL_NO_ERROR();
1994
1995 drawQuad(mProgram, "position", 0.5f);
1996
1997 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1998}
1999
2000// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2001// ES 3.0.4 table 3.24
2002TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
2003{
2004 glActiveTexture(GL_TEXTURE0);
2005 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2006 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
2007 EXPECT_GL_NO_ERROR();
2008
2009 drawQuad(mProgram, "position", 0.5f);
2010
2011 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2012}
2013
2014// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2015// ES 3.0.4 table 3.24
2016TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
2017{
2018 glActiveTexture(GL_TEXTURE0);
2019 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2020 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
2021 nullptr);
2022 EXPECT_GL_NO_ERROR();
2023
2024 drawQuad(mProgram, "position", 0.5f);
2025
2026 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2027}
2028
2029// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2030// ES 3.0.4 table 3.24
2031TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
2032{
2033 glActiveTexture(GL_TEXTURE0);
2034 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2035 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
2036 EXPECT_GL_NO_ERROR();
2037
2038 drawQuad(mProgram, "position", 0.5f);
2039
2040 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2041}
2042
2043// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2044// ES 3.0.4 table 3.24
2045TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
2046{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002047 if (IsIntel() && IsLinux())
2048 {
2049 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2050 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2051 return;
2052 }
2053
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002054 glActiveTexture(GL_TEXTURE0);
2055 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2056 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2057 EXPECT_GL_NO_ERROR();
2058
2059 drawQuad(mProgram, "position", 0.5f);
2060
2061 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2062}
2063
Olli Etuaho96963162016-03-21 11:54:33 +02002064// Use a sampler in a uniform struct.
2065TEST_P(SamplerInStructTest, SamplerInStruct)
2066{
2067 runSamplerInStructTest();
2068}
2069
2070// Use a sampler in a uniform struct that's passed as a function parameter.
2071TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2072{
2073 runSamplerInStructTest();
2074}
2075
2076// Use a sampler in a uniform struct array with a struct from the array passed as a function
2077// parameter.
2078TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2079{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002080 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2081 {
2082 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2083 return;
2084 }
Olli Etuaho96963162016-03-21 11:54:33 +02002085 runSamplerInStructTest();
2086}
2087
2088// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2089// parameter.
2090TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2091{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002092 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2093 {
2094 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2095 return;
2096 }
Olli Etuaho96963162016-03-21 11:54:33 +02002097 runSamplerInStructTest();
2098}
2099
2100// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2101// similarly named uniform.
2102TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2103{
2104 runSamplerInStructTest();
2105}
2106
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002107class TextureLimitsTest : public ANGLETest
2108{
2109 protected:
2110 struct RGBA8
2111 {
2112 uint8_t R, G, B, A;
2113 };
2114
2115 TextureLimitsTest()
2116 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2117 {
2118 setWindowWidth(128);
2119 setWindowHeight(128);
2120 setConfigRedBits(8);
2121 setConfigGreenBits(8);
2122 setConfigBlueBits(8);
2123 setConfigAlphaBits(8);
2124 }
2125
2126 ~TextureLimitsTest()
2127 {
2128 if (mProgram != 0)
2129 {
2130 glDeleteProgram(mProgram);
2131 mProgram = 0;
2132
2133 if (!mTextures.empty())
2134 {
2135 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2136 }
2137 }
2138 }
2139
2140 void SetUp() override
2141 {
2142 ANGLETest::SetUp();
2143
2144 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2145 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2146 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2147
2148 ASSERT_GL_NO_ERROR();
2149 }
2150
2151 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2152 GLint vertexTextureCount,
2153 GLint vertexActiveTextureCount,
2154 const std::string &fragPrefix,
2155 GLint fragmentTextureCount,
2156 GLint fragmentActiveTextureCount)
2157 {
2158 std::stringstream vertexShaderStr;
2159 vertexShaderStr << "attribute vec2 position;\n"
2160 << "varying vec4 color;\n"
2161 << "varying vec2 texCoord;\n";
2162
2163 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2164 {
2165 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2166 }
2167
2168 vertexShaderStr << "void main() {\n"
2169 << " gl_Position = vec4(position, 0, 1);\n"
2170 << " texCoord = (position * 0.5) + 0.5;\n"
2171 << " color = vec4(0);\n";
2172
2173 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2174 {
2175 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2176 << ", texCoord);\n";
2177 }
2178
2179 vertexShaderStr << "}";
2180
2181 std::stringstream fragmentShaderStr;
2182 fragmentShaderStr << "varying mediump vec4 color;\n"
2183 << "varying mediump vec2 texCoord;\n";
2184
2185 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2186 {
2187 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2188 }
2189
2190 fragmentShaderStr << "void main() {\n"
2191 << " gl_FragColor = color;\n";
2192
2193 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2194 {
2195 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2196 << ", texCoord);\n";
2197 }
2198
2199 fragmentShaderStr << "}";
2200
2201 const std::string &vertexShaderSource = vertexShaderStr.str();
2202 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2203
2204 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2205 }
2206
2207 RGBA8 getPixel(GLint texIndex)
2208 {
2209 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2210 0, 255u};
2211 return pixel;
2212 }
2213
2214 void initTextures(GLint tex2DCount, GLint texCubeCount)
2215 {
2216 GLint totalCount = tex2DCount + texCubeCount;
2217 mTextures.assign(totalCount, 0);
2218 glGenTextures(totalCount, &mTextures[0]);
2219 ASSERT_GL_NO_ERROR();
2220
2221 std::vector<RGBA8> texData(16 * 16);
2222
2223 GLint texIndex = 0;
2224 for (; texIndex < tex2DCount; ++texIndex)
2225 {
2226 texData.assign(texData.size(), getPixel(texIndex));
2227 glActiveTexture(GL_TEXTURE0 + texIndex);
2228 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2229 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2230 &texData[0]);
2231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2235 }
2236
2237 ASSERT_GL_NO_ERROR();
2238
2239 for (; texIndex < texCubeCount; ++texIndex)
2240 {
2241 texData.assign(texData.size(), getPixel(texIndex));
2242 glActiveTexture(GL_TEXTURE0 + texIndex);
2243 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2244 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2245 GL_UNSIGNED_BYTE, &texData[0]);
2246 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2247 GL_UNSIGNED_BYTE, &texData[0]);
2248 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2249 GL_UNSIGNED_BYTE, &texData[0]);
2250 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2251 GL_UNSIGNED_BYTE, &texData[0]);
2252 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2253 GL_UNSIGNED_BYTE, &texData[0]);
2254 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2255 GL_UNSIGNED_BYTE, &texData[0]);
2256 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2257 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2258 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2259 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2260 }
2261
2262 ASSERT_GL_NO_ERROR();
2263 }
2264
2265 void testWithTextures(GLint vertexTextureCount,
2266 const std::string &vertexTexturePrefix,
2267 GLint fragmentTextureCount,
2268 const std::string &fragmentTexturePrefix)
2269 {
2270 // Generate textures
2271 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2272
2273 glUseProgram(mProgram);
2274 RGBA8 expectedSum = {0};
2275 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2276 {
2277 std::stringstream uniformNameStr;
2278 uniformNameStr << vertexTexturePrefix << texIndex;
2279 const std::string &uniformName = uniformNameStr.str();
2280 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2281 ASSERT_NE(-1, location);
2282
2283 glUniform1i(location, texIndex);
2284 RGBA8 contribution = getPixel(texIndex);
2285 expectedSum.R += contribution.R;
2286 expectedSum.G += contribution.G;
2287 }
2288
2289 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2290 {
2291 std::stringstream uniformNameStr;
2292 uniformNameStr << fragmentTexturePrefix << texIndex;
2293 const std::string &uniformName = uniformNameStr.str();
2294 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2295 ASSERT_NE(-1, location);
2296
2297 glUniform1i(location, texIndex + vertexTextureCount);
2298 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
2299 expectedSum.R += contribution.R;
2300 expectedSum.G += contribution.G;
2301 }
2302
2303 ASSERT_GE(256u, expectedSum.G);
2304
2305 drawQuad(mProgram, "position", 0.5f);
2306 ASSERT_GL_NO_ERROR();
2307 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
2308 }
2309
2310 GLuint mProgram;
2311 std::vector<GLuint> mTextures;
2312 GLint mMaxVertexTextures;
2313 GLint mMaxFragmentTextures;
2314 GLint mMaxCombinedTextures;
2315};
2316
2317// Test rendering with the maximum vertex texture units.
2318TEST_P(TextureLimitsTest, MaxVertexTextures)
2319{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002320 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002321 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002322 {
2323 std::cout << "Test skipped on Intel." << std::endl;
2324 return;
2325 }
2326
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002327 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
2328 ASSERT_NE(0u, mProgram);
2329 ASSERT_GL_NO_ERROR();
2330
2331 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2332}
2333
2334// Test rendering with the maximum fragment texture units.
2335TEST_P(TextureLimitsTest, MaxFragmentTextures)
2336{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002337 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002338 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002339 {
2340 std::cout << "Test skipped on Intel." << std::endl;
2341 return;
2342 }
2343
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002344 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
2345 ASSERT_NE(0u, mProgram);
2346 ASSERT_GL_NO_ERROR();
2347
2348 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
2349}
2350
2351// Test rendering with maximum combined texture units.
2352TEST_P(TextureLimitsTest, MaxCombinedTextures)
2353{
Jamie Madill412f17d2015-09-25 08:43:54 -04002354 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002355 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04002356 {
2357 std::cout << "Test skipped on Intel." << std::endl;
2358 return;
2359 }
2360
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002361 GLint vertexTextures = mMaxVertexTextures;
2362
2363 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
2364 {
2365 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
2366 }
2367
2368 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
2369 mMaxFragmentTextures, mMaxFragmentTextures);
2370 ASSERT_NE(0u, mProgram);
2371 ASSERT_GL_NO_ERROR();
2372
2373 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
2374}
2375
2376// Negative test for exceeding the number of vertex textures
2377TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
2378{
2379 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
2380 0);
2381 ASSERT_EQ(0u, mProgram);
2382}
2383
2384// Negative test for exceeding the number of fragment textures
2385TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
2386{
2387 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
2388 mMaxFragmentTextures + 1);
2389 ASSERT_EQ(0u, mProgram);
2390}
2391
2392// Test active vertex textures under the limit, but excessive textures specified.
2393TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
2394{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002395 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002396 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002397 {
2398 std::cout << "Test skipped on Intel." << std::endl;
2399 return;
2400 }
2401
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002402 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
2403 ASSERT_NE(0u, mProgram);
2404 ASSERT_GL_NO_ERROR();
2405
2406 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2407}
2408
2409// Test active fragment textures under the limit, but excessive textures specified.
2410TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
2411{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002412 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002413 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002414 {
2415 std::cout << "Test skipped on Intel." << std::endl;
2416 return;
2417 }
2418
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002419 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
2420 mMaxFragmentTextures);
2421 ASSERT_NE(0u, mProgram);
2422 ASSERT_GL_NO_ERROR();
2423
2424 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
2425}
2426
2427// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002428// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002429TEST_P(TextureLimitsTest, TextureTypeConflict)
2430{
2431 const std::string &vertexShader =
2432 "attribute vec2 position;\n"
2433 "varying float color;\n"
2434 "uniform sampler2D tex2D;\n"
2435 "uniform samplerCube texCube;\n"
2436 "void main() {\n"
2437 " gl_Position = vec4(position, 0, 1);\n"
2438 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2439 " color = texture2D(tex2D, texCoord).x;\n"
2440 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
2441 "}";
2442 const std::string &fragmentShader =
2443 "varying mediump float color;\n"
2444 "void main() {\n"
2445 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2446 "}";
2447
2448 mProgram = CompileProgram(vertexShader, fragmentShader);
2449 ASSERT_NE(0u, mProgram);
2450
2451 initTextures(1, 0);
2452
2453 glUseProgram(mProgram);
2454 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2455 ASSERT_NE(-1, tex2DLocation);
2456 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
2457 ASSERT_NE(-1, texCubeLocation);
2458
2459 glUniform1i(tex2DLocation, 0);
2460 glUniform1i(texCubeLocation, 0);
2461 ASSERT_GL_NO_ERROR();
2462
2463 drawQuad(mProgram, "position", 0.5f);
2464 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2465}
2466
2467// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002468// TODO(jmadill): Possibly adjust the test according to the spec:
2469// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
2470// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002471TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
2472{
2473 const std::string &vertexShader =
2474 "attribute vec2 position;\n"
2475 "varying float color;\n"
2476 "uniform sampler2D tex2D;\n"
2477 "void main() {\n"
2478 " gl_Position = vec4(position, 0, 1);\n"
2479 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2480 " color = texture2D(tex2D, texCoord).x;\n"
2481 "}";
2482 const std::string &fragmentShader =
2483 "varying mediump float color;\n"
2484 "void main() {\n"
2485 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2486 "}";
2487
2488 mProgram = CompileProgram(vertexShader, fragmentShader);
2489 ASSERT_NE(0u, mProgram);
2490
2491 glUseProgram(mProgram);
2492 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2493 ASSERT_NE(-1, tex2DLocation);
2494
2495 glUniform1i(tex2DLocation, mMaxCombinedTextures);
2496 ASSERT_GL_NO_ERROR();
2497
2498 drawQuad(mProgram, "position", 0.5f);
2499 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2500}
2501
Jamie Madillfa05f602015-05-07 13:47:11 -04002502// 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 +02002503// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05002504ANGLE_INSTANTIATE_TEST(Texture2DTest,
2505 ES2_D3D9(),
2506 ES2_D3D11(),
2507 ES2_D3D11_FL9_3(),
2508 ES2_OPENGL(),
2509 ES2_OPENGLES());
2510ANGLE_INSTANTIATE_TEST(TextureCubeTest,
2511 ES2_D3D9(),
2512 ES2_D3D11(),
2513 ES2_D3D11_FL9_3(),
2514 ES2_OPENGL(),
2515 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002516ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
2517 ES2_D3D9(),
2518 ES2_D3D11(),
2519 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002520 ES2_OPENGL(),
2521 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002522ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
2523 ES2_D3D9(),
2524 ES2_D3D11(),
2525 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002526 ES2_OPENGL(),
2527 ES2_OPENGLES());
2528ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
2529 ES2_D3D9(),
2530 ES2_D3D11(),
2531 ES2_D3D11_FL9_3(),
2532 ES2_OPENGL(),
2533 ES2_OPENGLES());
2534ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
2535 ES2_D3D9(),
2536 ES2_D3D11(),
2537 ES2_D3D11_FL9_3(),
2538 ES2_OPENGL(),
2539 ES2_OPENGLES());
2540ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002541ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2542ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
2543 ES3_D3D11(),
2544 ES3_OPENGL(),
2545 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002546ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
2547 ES3_D3D11(),
2548 ES3_OPENGL(),
2549 ES3_OPENGLES());
2550ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2551ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02002552ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02002553ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
2554 ES2_D3D11(),
2555 ES2_D3D11_FL9_3(),
2556 ES2_D3D9(),
2557 ES2_OPENGL(),
2558 ES2_OPENGLES());
2559ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
2560 ES2_D3D11(),
2561 ES2_D3D11_FL9_3(),
2562 ES2_D3D9(),
2563 ES2_OPENGL(),
2564 ES2_OPENGLES());
2565ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
2566 ES2_D3D11(),
2567 ES2_D3D11_FL9_3(),
2568 ES2_D3D9(),
2569 ES2_OPENGL(),
2570 ES2_OPENGLES());
2571ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
2572 ES2_D3D11(),
2573 ES2_D3D11_FL9_3(),
2574 ES2_D3D9(),
2575 ES2_OPENGL(),
2576 ES2_OPENGLES());
2577ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
2578 ES2_D3D11(),
2579 ES2_D3D11_FL9_3(),
2580 ES2_D3D9(),
2581 ES2_OPENGL(),
2582 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002583ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04002584
2585} // namespace