blob: bed1771419e70a0711f6a7a3549db287f8b87628 [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 Etuaho356f5162016-03-18 14:19:41 +020014template <typename T>
15void FillWithRGBA(size_t pixelCount, T red, T green, T blue, T alpha, T *outArray)
16{
17 for (size_t i = 0u; i < pixelCount; ++i)
18 {
19 outArray[i * 4u] = red;
20 outArray[i * 4u + 1u] = green;
21 outArray[i * 4u + 2u] = blue;
22 outArray[i * 4u + 3u] = alpha;
23 }
24}
25
Olli Etuaho4a8329f2016-01-11 17:12:57 +020026class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -040027{
Jamie Madillbc393df2015-01-29 13:46:07 -050028 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020029 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -040030 {
31 setWindowWidth(128);
32 setWindowHeight(128);
33 setConfigRedBits(8);
34 setConfigGreenBits(8);
35 setConfigBlueBits(8);
36 setConfigAlphaBits(8);
37 }
38
Olli Etuaho4a8329f2016-01-11 17:12:57 +020039 virtual std::string getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -040040 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020041 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040042 (
43 precision highp float;
44 attribute vec4 position;
45 varying vec2 texcoord;
46
47 void main()
48 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020049 gl_Position = vec4(position.xy, 0.0, 1.0);
Geoff Langc41e42d2014-04-28 10:58:16 -040050 texcoord = (position.xy * 0.5) + 0.5;
51 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +020052 )
Geoff Langc41e42d2014-04-28 10:58:16 -040053 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +020054 }
Geoff Langc41e42d2014-04-28 10:58:16 -040055
Olli Etuaho4a8329f2016-01-11 17:12:57 +020056 virtual std::string getFragmentShaderSource() = 0;
57
58 void SetUp() override
59 {
60 ANGLETest::SetUp();
61 const std::string vertexShaderSource = getVertexShaderSource();
62 const std::string fragmentShaderSource = getFragmentShaderSource();
63
64 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
65 ASSERT_NE(0u, mProgram);
66 ASSERT_GL_NO_ERROR();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020067
68 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020069 }
70
71 void TearDown() override
72 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020073 glBindFramebuffer(GL_FRAMEBUFFER, 0);
74 glDeleteFramebuffers(1, &mFramebuffer);
75 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020076 glDeleteProgram(mProgram);
77 ANGLETest::TearDown();
78 }
79
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020080 void setUpFramebuffer()
81 {
82 // We use an FBO to work around an issue where the default framebuffer applies SRGB
83 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
84 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
85 // section 4.4 says that the format of the default framebuffer is entirely up to the window
86 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
87 // SRGB conversion like desktop GL does.
88 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
89 glGenFramebuffers(1, &mFramebuffer);
90 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
91
92 glGenTextures(1, &mFramebufferColorTexture);
93 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
94 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
95 GL_UNSIGNED_BYTE, nullptr);
96 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
97 mFramebufferColorTexture, 0);
98 ASSERT_GL_NO_ERROR();
99 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
100 glBindTexture(GL_TEXTURE_2D, 0);
101 }
102
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200103 // Returns the created texture ID.
104 GLuint create2DTexture()
105 {
106 GLuint texture2D;
107 glGenTextures(1, &texture2D);
108 glBindTexture(GL_TEXTURE_2D, texture2D);
109 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
110 EXPECT_GL_NO_ERROR();
111 return texture2D;
112 }
113
114 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200115 GLuint mFramebuffer;
116
117 private:
118 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200119};
120
121class Texture2DTest : public TexCoordDrawTest
122{
123 protected:
124 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
125
126 std::string getFragmentShaderSource() override
127 {
128 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400129 (
130 precision highp float;
131 uniform sampler2D tex;
132 varying vec2 texcoord;
133
134 void main()
135 {
136 gl_FragColor = texture2D(tex, texcoord);
137 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200138 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400139 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200140 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400141
Olli Etuaho96963162016-03-21 11:54:33 +0200142 virtual const char *getTextureUniformName() { return "tex"; }
143
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200144 void SetUp() override
145 {
146 TexCoordDrawTest::SetUp();
147 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400148
Jamie Madill9aca0592014-10-06 16:26:59 -0400149 ASSERT_GL_NO_ERROR();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200150
Olli Etuaho96963162016-03-21 11:54:33 +0200151 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200152 ASSERT_NE(-1, mTexture2DUniformLocation);
Jamie Madillf67115c2014-04-22 13:14:05 -0400153 }
154
Jamie Madillfa05f602015-05-07 13:47:11 -0400155 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400156 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400157 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200158 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400159 }
160
Jamie Madillbc393df2015-01-29 13:46:07 -0500161 // Tests CopyTexSubImage with floating point textures of various formats.
162 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
163 {
Geoff Langbde666a2015-04-07 17:17:08 -0400164 // TODO(jmadill): Figure out why this is broken on Intel D3D11
Jamie Madill518b9fa2016-03-02 11:26:02 -0500165 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Geoff Langbde666a2015-04-07 17:17:08 -0400166 {
167 std::cout << "Test skipped on Intel D3D11." << std::endl;
168 return;
169 }
170
Geoff Langfbfa47c2015-03-31 11:26:00 -0400171 if (getClientVersion() < 3)
172 {
173 if (!extensionEnabled("GL_OES_texture_float"))
174 {
175 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
176 return;
177 }
178
179 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
180 {
181 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
182 return;
183 }
184 }
185
Jamie Madillbc393df2015-01-29 13:46:07 -0500186 GLfloat sourceImageData[4][16] =
187 {
188 { // R
189 1.0f,
190 0.0f,
191 0.0f,
192 1.0f
193 },
194 { // RG
195 1.0f, 0.0f,
196 0.0f, 1.0f,
197 0.0f, 0.0f,
198 1.0f, 1.0f
199 },
200 { // RGB
201 1.0f, 0.0f, 0.0f,
202 0.0f, 1.0f, 0.0f,
203 0.0f, 0.0f, 1.0f,
204 1.0f, 1.0f, 0.0f
205 },
206 { // RGBA
207 1.0f, 0.0f, 0.0f, 1.0f,
208 0.0f, 1.0f, 0.0f, 1.0f,
209 0.0f, 0.0f, 1.0f, 1.0f,
210 1.0f, 1.0f, 0.0f, 1.0f
211 },
212 };
213
214 GLenum imageFormats[] =
215 {
216 GL_R32F,
217 GL_RG32F,
218 GL_RGB32F,
219 GL_RGBA32F,
220 };
221
222 GLenum sourceUnsizedFormats[] =
223 {
224 GL_RED,
225 GL_RG,
226 GL_RGB,
227 GL_RGBA,
228 };
229
230 GLuint textures[2];
231
232 glGenTextures(2, textures);
233
234 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
235 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
236 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
237 GLenum destImageFormat = imageFormats[destImageChannels - 1];
238
239 glBindTexture(GL_TEXTURE_2D, textures[0]);
240 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
243 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
244
hendrikwb27f79a2015-03-04 11:26:46 -0800245 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500246 {
247 // This is not supported
248 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
249 }
250 else
251 {
252 ASSERT_GL_NO_ERROR();
253 }
254
255 GLuint fbo;
256 glGenFramebuffers(1, &fbo);
257 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
258 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
259
260 glBindTexture(GL_TEXTURE_2D, textures[1]);
261 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
264
265 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
266 ASSERT_GL_NO_ERROR();
267
268 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200269 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500270
271 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
272
273 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
274 if (testImageChannels > 1)
275 {
276 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
277 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
278 if (testImageChannels > 2)
279 {
280 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
281 }
282 }
283
284 glDeleteFramebuffers(1, &fbo);
285 glDeleteTextures(2, textures);
286
287 ASSERT_GL_NO_ERROR();
288 }
289
Jamie Madilld4cfa572014-07-08 10:00:32 -0400290 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400291 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400292};
293
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200294class Texture2DTestES3 : public Texture2DTest
295{
296 protected:
297 Texture2DTestES3() : Texture2DTest() {}
298
299 std::string getVertexShaderSource() override
300 {
301 return std::string(
302 "#version 300 es\n"
303 "out vec2 texcoord;\n"
304 "in vec4 position;\n"
305 "void main()\n"
306 "{\n"
307 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
308 " texcoord = (position.xy * 0.5) + 0.5;\n"
309 "}\n");
310 }
311
312 std::string getFragmentShaderSource() override
313 {
314 return std::string(
315 "#version 300 es\n"
316 "precision highp float;\n"
317 "uniform highp sampler2D tex;\n"
318 "in vec2 texcoord;\n"
319 "out vec4 fragColor;\n"
320 "void main()\n"
321 "{\n"
322 " fragColor = texture(tex, texcoord);\n"
323 "}\n");
324 }
325};
326
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200327class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
328{
329 protected:
330 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
331
332 std::string getVertexShaderSource() override
333 {
334 return std::string(
335 "#version 300 es\n"
336 "out vec2 texcoord;\n"
337 "in vec4 position;\n"
338 "void main()\n"
339 "{\n"
340 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
341 " texcoord = (position.xy * 0.5) + 0.5;\n"
342 "}\n");
343 }
344
345 std::string getFragmentShaderSource() override
346 {
347 return std::string(
348 "#version 300 es\n"
349 "precision highp float;\n"
350 "uniform highp isampler2D tex;\n"
351 "in vec2 texcoord;\n"
352 "out vec4 fragColor;\n"
353 "void main()\n"
354 "{\n"
355 " vec4 green = vec4(0, 1, 0, 1);\n"
356 " vec4 black = vec4(0, 0, 0, 0);\n"
357 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
358 "}\n");
359 }
360};
361
362class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
363{
364 protected:
365 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
366
367 std::string getVertexShaderSource() override
368 {
369 return std::string(
370 "#version 300 es\n"
371 "out vec2 texcoord;\n"
372 "in vec4 position;\n"
373 "void main()\n"
374 "{\n"
375 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
376 " texcoord = (position.xy * 0.5) + 0.5;\n"
377 "}\n");
378 }
379
380 std::string getFragmentShaderSource() override
381 {
382 return std::string(
383 "#version 300 es\n"
384 "precision highp float;\n"
385 "uniform highp usampler2D tex;\n"
386 "in vec2 texcoord;\n"
387 "out vec4 fragColor;\n"
388 "void main()\n"
389 "{\n"
390 " vec4 green = vec4(0, 1, 0, 1);\n"
391 " vec4 black = vec4(0, 0, 0, 0);\n"
392 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
393 "}\n");
394 }
395};
396
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200397class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400398{
399 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200400 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
401
402 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400403 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200404 return std::string(SHADER_SOURCE
405 (
406 precision highp float;
407 attribute vec4 position;
408 varying vec2 texcoord;
409
410 uniform vec2 drawScale;
411
412 void main()
413 {
414 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
415 texcoord = (position.xy * 0.5) + 0.5;
416 }
417 )
418 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400419 }
420
421 void SetUp() override
422 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200423 Texture2DTest::SetUp();
424 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
425 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400426
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200427 glUseProgram(mProgram);
428 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
429 glUseProgram(0);
430 ASSERT_GL_NO_ERROR();
431 }
432
433 GLint mDrawScaleUniformLocation;
434};
435
Olli Etuaho4644a202016-01-12 15:12:53 +0200436class Sampler2DAsFunctionParameterTest : public Texture2DTest
437{
438 protected:
439 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
440
441 std::string getFragmentShaderSource() override
442 {
443 return std::string(SHADER_SOURCE
444 (
445 precision highp float;
446 uniform sampler2D tex;
447 varying vec2 texcoord;
448
449 vec4 computeFragColor(sampler2D aTex)
450 {
451 return texture2D(aTex, texcoord);
452 }
453
454 void main()
455 {
456 gl_FragColor = computeFragColor(tex);
457 }
458 )
459 );
460 }
461};
462
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200463class TextureCubeTest : public TexCoordDrawTest
464{
465 protected:
466 TextureCubeTest()
467 : TexCoordDrawTest(),
468 mTexture2D(0),
469 mTextureCube(0),
470 mTexture2DUniformLocation(-1),
471 mTextureCubeUniformLocation(-1)
472 {
473 }
474
475 std::string getFragmentShaderSource() override
476 {
477 return std::string(SHADER_SOURCE
478 (
479 precision highp float;
480 uniform sampler2D tex2D;
481 uniform samplerCube texCube;
482 varying vec2 texcoord;
483
484 void main()
485 {
486 gl_FragColor = texture2D(tex2D, texcoord);
487 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
488 }
489 )
490 );
491 }
492
493 void SetUp() override
494 {
495 TexCoordDrawTest::SetUp();
496
497 glGenTextures(1, &mTextureCube);
498 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
499 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
500 EXPECT_GL_NO_ERROR();
501
502 mTexture2D = create2DTexture();
503
504 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
505 ASSERT_NE(-1, mTexture2DUniformLocation);
506 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
507 ASSERT_NE(-1, mTextureCubeUniformLocation);
508 }
509
510 void TearDown() override
511 {
512 glDeleteTextures(1, &mTextureCube);
513 TexCoordDrawTest::TearDown();
514 }
515
516 GLuint mTexture2D;
517 GLuint mTextureCube;
518 GLint mTexture2DUniformLocation;
519 GLint mTextureCubeUniformLocation;
520};
521
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200522class SamplerArrayTest : public TexCoordDrawTest
523{
524 protected:
525 SamplerArrayTest()
526 : TexCoordDrawTest(),
527 mTexture2DA(0),
528 mTexture2DB(0),
529 mTexture0UniformLocation(-1),
530 mTexture1UniformLocation(-1)
531 {
532 }
533
534 std::string getFragmentShaderSource() override
535 {
536 return std::string(SHADER_SOURCE
537 (
538 precision mediump float;
539 uniform highp sampler2D tex2DArray[2];
540 varying vec2 texcoord;
541 void main()
542 {
543 gl_FragColor = texture2D(tex2DArray[0], texcoord);
544 gl_FragColor += texture2D(tex2DArray[1], texcoord);
545 }
546 )
547 );
548 }
549
550 void SetUp() override
551 {
552 TexCoordDrawTest::SetUp();
553
554 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
555 ASSERT_NE(-1, mTexture0UniformLocation);
556 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
557 ASSERT_NE(-1, mTexture1UniformLocation);
558
559 mTexture2DA = create2DTexture();
560 mTexture2DB = create2DTexture();
561 ASSERT_GL_NO_ERROR();
562 }
563
564 void TearDown() override
565 {
566 glDeleteTextures(1, &mTexture2DA);
567 glDeleteTextures(1, &mTexture2DB);
568 TexCoordDrawTest::TearDown();
569 }
570
571 void testSamplerArrayDraw()
572 {
573 GLubyte texData[4];
574 texData[0] = 0;
575 texData[1] = 60;
576 texData[2] = 0;
577 texData[3] = 255;
578
579 glActiveTexture(GL_TEXTURE0);
580 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
581 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
582
583 texData[1] = 120;
584 glActiveTexture(GL_TEXTURE1);
585 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
586 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
587 EXPECT_GL_ERROR(GL_NO_ERROR);
588
589 glUseProgram(mProgram);
590 glUniform1i(mTexture0UniformLocation, 0);
591 glUniform1i(mTexture1UniformLocation, 1);
592 drawQuad(mProgram, "position", 0.5f);
593 EXPECT_GL_NO_ERROR();
594
595 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
596 }
597
598 GLuint mTexture2DA;
599 GLuint mTexture2DB;
600 GLint mTexture0UniformLocation;
601 GLint mTexture1UniformLocation;
602};
603
604
605class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
606{
607 protected:
608 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
609
610 std::string getFragmentShaderSource() override
611 {
612 return std::string(SHADER_SOURCE
613 (
614 precision mediump float;
615 uniform highp sampler2D tex2DArray[2];
616 varying vec2 texcoord;
617
618 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
619 {
620 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
621 }
622
623 void main()
624 {
625 gl_FragColor = computeFragColor(tex2DArray);
626 }
627 )
628 );
629 }
630};
631
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200632class Texture2DArrayTestES3 : public TexCoordDrawTest
633{
634 protected:
635 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
636
637 std::string getVertexShaderSource() override
638 {
639 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400640 "#version 300 es\n"
641 "out vec2 texcoord;\n"
642 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200643 "void main()\n"
644 "{\n"
645 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
646 " texcoord = (position.xy * 0.5) + 0.5;\n"
647 "}\n");
648 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400649
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200650 std::string getFragmentShaderSource() override
651 {
652 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400653 "#version 300 es\n"
654 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200655 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400656 "in vec2 texcoord;\n"
657 "out vec4 fragColor;\n"
658 "void main()\n"
659 "{\n"
660 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200661 "}\n");
662 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400663
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200664 void SetUp() override
665 {
666 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400667
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200668 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400669 ASSERT_NE(-1, mTextureArrayLocation);
670
671 glGenTextures(1, &m2DArrayTexture);
672 ASSERT_GL_NO_ERROR();
673 }
674
675 void TearDown() override
676 {
677 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200678 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400679 }
680
681 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400682 GLint mTextureArrayLocation;
683};
684
Olli Etuahobce743a2016-01-15 17:18:28 +0200685class TextureSizeTextureArrayTest : public TexCoordDrawTest
686{
687 protected:
688 TextureSizeTextureArrayTest()
689 : TexCoordDrawTest(),
690 mTexture2DA(0),
691 mTexture2DB(0),
692 mTexture0Location(-1),
693 mTexture1Location(-1)
694 {
695 }
696
697 std::string getVertexShaderSource() override
698 {
699 return std::string(
700 "#version 300 es\n"
701 "in vec4 position;\n"
702 "void main()\n"
703 "{\n"
704 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
705 "}\n");
706 }
707
708 std::string getFragmentShaderSource() override
709 {
710 return std::string(
711 "#version 300 es\n"
712 "precision highp float;\n"
713 "uniform highp sampler2D tex2DArray[2];\n"
714 "out vec4 fragColor;\n"
715 "void main()\n"
716 "{\n"
717 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
718 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
719 " fragColor = vec4(red, green, 0.0, 1.0);\n"
720 "}\n");
721 }
722
723 void SetUp() override
724 {
725 TexCoordDrawTest::SetUp();
726
727 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
728 ASSERT_NE(-1, mTexture0Location);
729 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
730 ASSERT_NE(-1, mTexture1Location);
731
732 mTexture2DA = create2DTexture();
733 mTexture2DB = create2DTexture();
734 ASSERT_GL_NO_ERROR();
735 }
736
737 void TearDown() override
738 {
739 glDeleteTextures(1, &mTexture2DA);
740 glDeleteTextures(1, &mTexture2DB);
741 TexCoordDrawTest::TearDown();
742 }
743
744 GLuint mTexture2DA;
745 GLuint mTexture2DB;
746 GLint mTexture0Location;
747 GLint mTexture1Location;
748};
749
Olli Etuaho1a679902016-01-14 12:21:47 +0200750class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
751{
752 protected:
753 ShadowSamplerPlusSampler3DTestES3()
754 : TexCoordDrawTest(),
755 mTextureShadow(0),
756 mTexture3D(0),
757 mTextureShadowUniformLocation(-1),
758 mTexture3DUniformLocation(-1),
759 mDepthRefUniformLocation(-1)
760 {
761 }
762
763 std::string getVertexShaderSource() override
764 {
765 return std::string(
766 "#version 300 es\n"
767 "out vec2 texcoord;\n"
768 "in vec4 position;\n"
769 "void main()\n"
770 "{\n"
771 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
772 " texcoord = (position.xy * 0.5) + 0.5;\n"
773 "}\n");
774 }
775
776 std::string getFragmentShaderSource() override
777 {
778 return std::string(
779 "#version 300 es\n"
780 "precision highp float;\n"
781 "uniform highp sampler2DShadow tex2DShadow;\n"
782 "uniform highp sampler3D tex3D;\n"
783 "in vec2 texcoord;\n"
784 "uniform float depthRef;\n"
785 "out vec4 fragColor;\n"
786 "void main()\n"
787 "{\n"
788 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
789 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
790 "}\n");
791 }
792
793 void SetUp() override
794 {
795 TexCoordDrawTest::SetUp();
796
797 glGenTextures(1, &mTexture3D);
798
799 glGenTextures(1, &mTextureShadow);
800 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
801 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
802
803 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
804 ASSERT_NE(-1, mTextureShadowUniformLocation);
805 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
806 ASSERT_NE(-1, mTexture3DUniformLocation);
807 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
808 ASSERT_NE(-1, mDepthRefUniformLocation);
809 }
810
811 void TearDown() override
812 {
813 glDeleteTextures(1, &mTextureShadow);
814 glDeleteTextures(1, &mTexture3D);
815 TexCoordDrawTest::TearDown();
816 }
817
818 GLuint mTextureShadow;
819 GLuint mTexture3D;
820 GLint mTextureShadowUniformLocation;
821 GLint mTexture3DUniformLocation;
822 GLint mDepthRefUniformLocation;
823};
824
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200825class SamplerTypeMixTestES3 : public TexCoordDrawTest
826{
827 protected:
828 SamplerTypeMixTestES3()
829 : TexCoordDrawTest(),
830 mTexture2D(0),
831 mTextureCube(0),
832 mTexture2DShadow(0),
833 mTextureCubeShadow(0),
834 mTexture2DUniformLocation(-1),
835 mTextureCubeUniformLocation(-1),
836 mTexture2DShadowUniformLocation(-1),
837 mTextureCubeShadowUniformLocation(-1),
838 mDepthRefUniformLocation(-1)
839 {
840 }
841
842 std::string getVertexShaderSource() override
843 {
844 return std::string(
845 "#version 300 es\n"
846 "out vec2 texcoord;\n"
847 "in vec4 position;\n"
848 "void main()\n"
849 "{\n"
850 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
851 " texcoord = (position.xy * 0.5) + 0.5;\n"
852 "}\n");
853 }
854
855 std::string getFragmentShaderSource() override
856 {
857 return std::string(
858 "#version 300 es\n"
859 "precision highp float;\n"
860 "uniform highp sampler2D tex2D;\n"
861 "uniform highp samplerCube texCube;\n"
862 "uniform highp sampler2DShadow tex2DShadow;\n"
863 "uniform highp samplerCubeShadow texCubeShadow;\n"
864 "in vec2 texcoord;\n"
865 "uniform float depthRef;\n"
866 "out vec4 fragColor;\n"
867 "void main()\n"
868 "{\n"
869 " fragColor = texture(tex2D, texcoord);\n"
870 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
871 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
872 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
873 "0.125);\n"
874 "}\n");
875 }
876
877 void SetUp() override
878 {
879 TexCoordDrawTest::SetUp();
880
881 glGenTextures(1, &mTexture2D);
882 glGenTextures(1, &mTextureCube);
883
884 glGenTextures(1, &mTexture2DShadow);
885 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
886 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
887
888 glGenTextures(1, &mTextureCubeShadow);
889 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
890 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
891
892 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
893 ASSERT_NE(-1, mTexture2DUniformLocation);
894 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
895 ASSERT_NE(-1, mTextureCubeUniformLocation);
896 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
897 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
898 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
899 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
900 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
901 ASSERT_NE(-1, mDepthRefUniformLocation);
902
903 ASSERT_GL_NO_ERROR();
904 }
905
906 void TearDown() override
907 {
908 glDeleteTextures(1, &mTexture2D);
909 glDeleteTextures(1, &mTextureCube);
910 glDeleteTextures(1, &mTexture2DShadow);
911 glDeleteTextures(1, &mTextureCubeShadow);
912 TexCoordDrawTest::TearDown();
913 }
914
915 GLuint mTexture2D;
916 GLuint mTextureCube;
917 GLuint mTexture2DShadow;
918 GLuint mTextureCubeShadow;
919 GLint mTexture2DUniformLocation;
920 GLint mTextureCubeUniformLocation;
921 GLint mTexture2DShadowUniformLocation;
922 GLint mTextureCubeShadowUniformLocation;
923 GLint mDepthRefUniformLocation;
924};
925
Olli Etuaho96963162016-03-21 11:54:33 +0200926class SamplerInStructTest : public Texture2DTest
927{
928 protected:
929 SamplerInStructTest() : Texture2DTest() {}
930
931 const char *getTextureUniformName() override { return "us.tex"; }
932
933 std::string getFragmentShaderSource() override
934 {
935 return std::string(
936 "precision highp float;\n"
937 "struct S\n"
938 "{\n"
939 " vec4 a;\n"
940 " highp sampler2D tex;\n"
941 "};\n"
942 "uniform S us;\n"
943 "varying vec2 texcoord;\n"
944 "void main()\n"
945 "{\n"
946 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
947 "}\n");
948 }
949
950 void runSamplerInStructTest()
951 {
952 glActiveTexture(GL_TEXTURE0);
953 glBindTexture(GL_TEXTURE_2D, mTexture2D);
954 GLubyte texDataGreen[1u * 1u * 4u];
955 FillWithRGBA<GLubyte>(1u * 1u, 0u, 255u, 0u, 255u, texDataGreen);
956 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
957 drawQuad(mProgram, "position", 0.5f);
958 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
959 }
960};
961
962class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
963{
964 protected:
965 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
966
967 std::string getFragmentShaderSource() override
968 {
969 return std::string(
970 "precision highp float;\n"
971 "struct S\n"
972 "{\n"
973 " vec4 a;\n"
974 " highp sampler2D tex;\n"
975 "};\n"
976 "uniform S us;\n"
977 "varying vec2 texcoord;\n"
978 "vec4 sampleFrom(S s) {\n"
979 " return texture2D(s.tex, texcoord + s.a.x);\n"
980 "}\n"
981 "void main()\n"
982 "{\n"
983 " gl_FragColor = sampleFrom(us);\n"
984 "}\n");
985 }
986};
987
988class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
989{
990 protected:
991 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
992
993 const char *getTextureUniformName() override { return "us[0].tex"; }
994
995 std::string getFragmentShaderSource() override
996 {
997 return std::string(
998 "precision highp float;\n"
999 "struct S\n"
1000 "{\n"
1001 " vec4 a;\n"
1002 " highp sampler2D tex;\n"
1003 "};\n"
1004 "uniform S us[1];\n"
1005 "varying vec2 texcoord;\n"
1006 "vec4 sampleFrom(S s) {\n"
1007 " return texture2D(s.tex, texcoord + s.a.x);\n"
1008 "}\n"
1009 "void main()\n"
1010 "{\n"
1011 " gl_FragColor = sampleFrom(us[0]);\n"
1012 "}\n");
1013 }
1014};
1015
1016class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1017{
1018 protected:
1019 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1020
1021 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1022
1023 std::string getFragmentShaderSource() override
1024 {
1025 return std::string(
1026 "precision highp float;\n"
1027 "struct SUB\n"
1028 "{\n"
1029 " vec4 a;\n"
1030 " highp sampler2D tex;\n"
1031 "};\n"
1032 "struct S\n"
1033 "{\n"
1034 " SUB sub;\n"
1035 "};\n"
1036 "uniform S us[1];\n"
1037 "varying vec2 texcoord;\n"
1038 "vec4 sampleFrom(SUB s) {\n"
1039 " return texture2D(s.tex, texcoord + s.a.x);\n"
1040 "}\n"
1041 "void main()\n"
1042 "{\n"
1043 " gl_FragColor = sampleFrom(us[0].sub);\n"
1044 "}\n");
1045 }
1046};
1047
1048class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1049{
1050 protected:
1051 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1052
1053 std::string getFragmentShaderSource() override
1054 {
1055 return std::string(
1056 "precision highp float;\n"
1057 "struct S\n"
1058 "{\n"
1059 " vec4 a;\n"
1060 " highp sampler2D tex;\n"
1061 "};\n"
1062 "uniform S us;\n"
1063 "uniform float us_tex;\n"
1064 "varying vec2 texcoord;\n"
1065 "void main()\n"
1066 "{\n"
1067 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1068 "}\n");
1069 }
1070};
1071
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001072TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001073{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001074 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001075 EXPECT_GL_ERROR(GL_NO_ERROR);
1076
1077 const GLubyte *pixels[20] = { 0 };
1078 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1079 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1080}
Geoff Langc41e42d2014-04-28 10:58:16 -04001081
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001082TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001083{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001084 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001085 EXPECT_GL_ERROR(GL_NO_ERROR);
1086
1087 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001088 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001089 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001090 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001091
1092 const GLubyte *pixel[4] = { 0 };
1093
1094 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1095 EXPECT_GL_NO_ERROR();
1096
1097 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1098 EXPECT_GL_NO_ERROR();
1099
1100 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1101 EXPECT_GL_NO_ERROR();
1102}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001103
1104// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001105TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001106{
1107 glActiveTexture(GL_TEXTURE0);
1108 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1109 glActiveTexture(GL_TEXTURE1);
1110 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1111 EXPECT_GL_ERROR(GL_NO_ERROR);
1112
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001113 glUseProgram(mProgram);
1114 glUniform1i(mTexture2DUniformLocation, 0);
1115 glUniform1i(mTextureCubeUniformLocation, 1);
1116 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001117 EXPECT_GL_NO_ERROR();
1118}
Jamie Madill9aca0592014-10-06 16:26:59 -04001119
Olli Etuaho53a2da12016-01-11 15:43:32 +02001120// Test drawing with two texture types accessed from the same shader and check that the result of
1121// drawing is correct.
1122TEST_P(TextureCubeTest, CubeMapDraw)
1123{
1124 GLubyte texData[4];
1125 texData[0] = 0;
1126 texData[1] = 60;
1127 texData[2] = 0;
1128 texData[3] = 255;
1129
1130 glActiveTexture(GL_TEXTURE0);
1131 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1132 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1133
1134 glActiveTexture(GL_TEXTURE1);
1135 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1136 texData[1] = 120;
1137 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1138 texData);
1139 EXPECT_GL_ERROR(GL_NO_ERROR);
1140
1141 glUseProgram(mProgram);
1142 glUniform1i(mTexture2DUniformLocation, 0);
1143 glUniform1i(mTextureCubeUniformLocation, 1);
1144 drawQuad(mProgram, "position", 0.5f);
1145 EXPECT_GL_NO_ERROR();
1146
1147 int px = getWindowWidth() - 1;
1148 int py = 0;
1149 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1150}
1151
Olli Etuaho4644a202016-01-12 15:12:53 +02001152TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1153{
1154 glActiveTexture(GL_TEXTURE0);
1155 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1156 GLubyte texData[4];
1157 texData[0] = 0;
1158 texData[1] = 128;
1159 texData[2] = 0;
1160 texData[3] = 255;
1161 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1162 glUseProgram(mProgram);
1163 glUniform1i(mTexture2DUniformLocation, 0);
1164 drawQuad(mProgram, "position", 0.5f);
1165 EXPECT_GL_NO_ERROR();
1166
1167 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1168}
1169
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001170// Test drawing with two textures passed to the shader in a sampler array.
1171TEST_P(SamplerArrayTest, SamplerArrayDraw)
1172{
1173 testSamplerArrayDraw();
1174}
1175
1176// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1177// user-defined function in the shader.
1178TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1179{
1180 testSamplerArrayDraw();
1181}
1182
Jamie Madill9aca0592014-10-06 16:26:59 -04001183// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001184TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001185{
1186 int px = getWindowWidth() / 2;
1187 int py = getWindowHeight() / 2;
1188
1189 glActiveTexture(GL_TEXTURE0);
1190 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1191
1192 // Fill with red
1193 std::vector<GLubyte> pixels(4 * 16 * 16);
Olli Etuaho356f5162016-03-18 14:19:41 +02001194 FillWithRGBA<GLubyte>(16u * 16u, 255u, 0u, 0u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001195
1196 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1197 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1199 glGenerateMipmap(GL_TEXTURE_2D);
1200
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001201 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001202 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001203 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1204 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001205 EXPECT_GL_NO_ERROR();
1206 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
1207
1208 // Fill with blue
Olli Etuaho356f5162016-03-18 14:19:41 +02001209 FillWithRGBA<GLubyte>(16u * 16u, 0u, 0u, 255u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001210
1211 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1212 glGenerateMipmap(GL_TEXTURE_2D);
1213
1214 // Fill with green
Olli Etuaho356f5162016-03-18 14:19:41 +02001215 FillWithRGBA<GLubyte>(16u * 16u, 0u, 255u, 0u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001216
1217 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1218 glGenerateMipmap(GL_TEXTURE_2D);
1219
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001220 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001221
1222 EXPECT_GL_NO_ERROR();
1223 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
1224}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001225
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001226// Test creating a FBO with a cube map render target, to test an ANGLE bug
1227// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001228TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001229{
1230 GLuint fbo;
1231 glGenFramebuffers(1, &fbo);
1232 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1233
1234 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1235 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1236
Corentin Wallez322653b2015-06-17 18:33:56 +02001237 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001238
1239 glDeleteFramebuffers(1, &fbo);
1240
1241 EXPECT_GL_NO_ERROR();
1242}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001243
1244// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001245TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001246{
1247 int width = getWindowWidth();
1248 int height = getWindowHeight();
1249
1250 GLuint tex2D;
1251 glGenTextures(1, &tex2D);
1252 glActiveTexture(GL_TEXTURE0);
1253 glBindTexture(GL_TEXTURE_2D, tex2D);
1254
1255 // Fill with red
1256 std::vector<GLubyte> pixels(3 * 16 * 16);
1257 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1258 {
1259 pixels[pixelId * 3 + 0] = 255;
1260 pixels[pixelId * 3 + 1] = 0;
1261 pixels[pixelId * 3 + 2] = 0;
1262 }
1263
1264 // ANGLE internally uses RGBA as the DirectX format for RGB images
1265 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1266 // The data is kept in a CPU-side image and the image is marked as dirty.
1267 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1268
1269 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1270 // glTexSubImage2D should take into account that the image is dirty.
1271 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1274
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001275 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001276 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001277 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001278 glDeleteTextures(1, &tex2D);
1279 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001280 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001281
1282 // Validate that the region of the texture without data has an alpha of 1.0
1283 GLubyte pixel[4];
1284 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1285 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001286}
1287
1288// 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 +02001289TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001290{
1291 if (extensionEnabled("NV_pixel_buffer_object"))
1292 {
1293 int width = getWindowWidth();
1294 int height = getWindowHeight();
1295
1296 GLuint tex2D;
1297 glGenTextures(1, &tex2D);
1298 glActiveTexture(GL_TEXTURE0);
1299 glBindTexture(GL_TEXTURE_2D, tex2D);
1300
1301 // Fill with red
1302 std::vector<GLubyte> pixels(3 * 16 * 16);
1303 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1304 {
1305 pixels[pixelId * 3 + 0] = 255;
1306 pixels[pixelId * 3 + 1] = 0;
1307 pixels[pixelId * 3 + 2] = 0;
1308 }
1309
1310 // Read 16x16 region from red backbuffer to PBO
1311 GLuint pbo;
1312 glGenBuffers(1, &pbo);
1313 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1314 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1315
1316 // ANGLE internally uses RGBA as the DirectX format for RGB images
1317 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1318 // The data is kept in a CPU-side image and the image is marked as dirty.
1319 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1320
1321 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1322 // glTexSubImage2D should take into account that the image is dirty.
1323 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1324 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1325 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1326
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001327 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001328 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001329 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001330 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001331 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001332 EXPECT_GL_NO_ERROR();
1333 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1334 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1335 }
1336}
Jamie Madillbc393df2015-01-29 13:46:07 -05001337
1338// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001339TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001340{
1341 testFloatCopySubImage(1, 1);
1342}
1343
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001344TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001345{
1346 testFloatCopySubImage(2, 1);
1347}
1348
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001349TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001350{
1351 testFloatCopySubImage(2, 2);
1352}
1353
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001354TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001355{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001356 if (IsIntel() && IsLinux())
1357 {
1358 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1359 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1360 return;
1361 }
1362
Jamie Madillbc393df2015-01-29 13:46:07 -05001363 testFloatCopySubImage(3, 1);
1364}
1365
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001366TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001367{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001368 if (IsIntel() && IsLinux())
1369 {
1370 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1371 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1372 return;
1373 }
1374
Jamie Madillbc393df2015-01-29 13:46:07 -05001375 testFloatCopySubImage(3, 2);
1376}
1377
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001378TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001379{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001380 if (IsIntel() && IsLinux())
1381 {
1382 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1383 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1384 return;
1385 }
1386
Austin Kinrossd544cc92016-01-11 15:26:42 -08001387 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001388 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001389 {
1390 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1391 return;
1392 }
1393
Jamie Madillbc393df2015-01-29 13:46:07 -05001394 testFloatCopySubImage(3, 3);
1395}
1396
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001397TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001398{
1399 testFloatCopySubImage(4, 1);
1400}
1401
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001402TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001403{
1404 testFloatCopySubImage(4, 2);
1405}
1406
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001407TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001408{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001409 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001410 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001411 {
1412 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1413 return;
1414 }
1415
Jamie Madillbc393df2015-01-29 13:46:07 -05001416 testFloatCopySubImage(4, 3);
1417}
1418
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001419TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001420{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001421 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001422 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001423 {
1424 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1425 return;
1426 }
1427
Jamie Madillbc393df2015-01-29 13:46:07 -05001428 testFloatCopySubImage(4, 4);
1429}
Austin Kinross07285142015-03-26 11:36:16 -07001430
1431// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1432// 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 +02001433TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001434{
1435 const int npotTexSize = 5;
1436 const int potTexSize = 4; // Should be less than npotTexSize
1437 GLuint tex2D;
1438
1439 if (extensionEnabled("GL_OES_texture_npot"))
1440 {
1441 // This test isn't applicable if texture_npot is enabled
1442 return;
1443 }
1444
1445 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1446
Austin Kinross5faa15b2016-01-11 13:32:48 -08001447 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1448 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1449
Austin Kinross07285142015-03-26 11:36:16 -07001450 glActiveTexture(GL_TEXTURE0);
1451 glGenTextures(1, &tex2D);
1452 glBindTexture(GL_TEXTURE_2D, tex2D);
1453
1454 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1455 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1456 {
1457 pixels[pixelId] = 64;
1458 }
1459
1460 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1461 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1462
1463 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1464 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1465 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1466
1467 // Check that an NPOT texture on level 0 succeeds
1468 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1469 EXPECT_GL_NO_ERROR();
1470
1471 // Check that generateMipmap fails on NPOT
1472 glGenerateMipmap(GL_TEXTURE_2D);
1473 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1474
1475 // Check that nothing is drawn if filtering is not correct for NPOT
1476 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1477 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1478 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1479 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1480 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001481 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001482 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1483
1484 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1485 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1486 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1487 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1488 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001489 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001490 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1491
1492 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1493 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1494 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001495 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001496 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1497
1498 // Check that glTexImage2D for POT texture succeeds
1499 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1500 EXPECT_GL_NO_ERROR();
1501
1502 // Check that generateMipmap for an POT texture succeeds
1503 glGenerateMipmap(GL_TEXTURE_2D);
1504 EXPECT_GL_NO_ERROR();
1505
1506 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1507 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1508 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1509 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1510 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1511 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001512 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001513 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1514 EXPECT_GL_NO_ERROR();
1515}
Jamie Madillfa05f602015-05-07 13:47:11 -04001516
Austin Kinross08528e12015-10-07 16:24:40 -07001517// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1518// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001519TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001520{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001521 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1522 // 1278)
1523 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1524 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1525 {
1526 std::cout << "Test disabled on OpenGL." << std::endl;
1527 return;
1528 }
1529
Austin Kinross08528e12015-10-07 16:24:40 -07001530 glActiveTexture(GL_TEXTURE0);
1531 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1532
1533 // Create an 8x8 (i.e. power-of-two) texture.
1534 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1535 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1536 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1537 glGenerateMipmap(GL_TEXTURE_2D);
1538
1539 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1540 // This should always work, even if GL_OES_texture_npot isn't active.
1541 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1542
1543 EXPECT_GL_NO_ERROR();
1544}
1545
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001546// Test to check that texture completeness is determined correctly when the texture base level is
1547// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1548TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1549{
1550 glActiveTexture(GL_TEXTURE0);
1551 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1552 GLubyte texDataRed[4u * 4u * 4u];
Olli Etuaho356f5162016-03-18 14:19:41 +02001553 FillWithRGBA<GLubyte>(4u * 4u, 255u, 0u, 0u, 255u, texDataRed);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001554 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
1555 GLubyte texDataGreen[2u * 2u * 4u];
Olli Etuaho356f5162016-03-18 14:19:41 +02001556 FillWithRGBA<GLubyte>(2u * 2u, 0u, 255u, 0u, 255u, texDataGreen);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001557 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1558 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1559 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1560 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1562
1563 EXPECT_GL_NO_ERROR();
1564
1565 drawQuad(mProgram, "position", 0.5f);
1566
1567 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1568}
1569
Jamie Madill2453dbc2015-07-14 11:35:42 -04001570// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
1571// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
1572// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001573TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04001574{
1575 std::vector<GLubyte> pixelData;
1576 for (size_t count = 0; count < 5000; count++)
1577 {
1578 pixelData.push_back(0u);
1579 pixelData.push_back(255u);
1580 pixelData.push_back(0u);
1581 }
1582
1583 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001584 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001585 glUniform1i(mTextureArrayLocation, 0);
1586
1587 // The first draw worked correctly.
1588 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
1589
1590 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1591 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1592 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1593 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001594 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001595 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1596
1597 // The dimension of the respecification must match the original exactly to trigger the bug.
1598 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 +02001599 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001600 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1601
1602 ASSERT_GL_NO_ERROR();
1603}
1604
Olli Etuaho1a679902016-01-14 12:21:47 +02001605// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
1606// This test is needed especially to confirm that sampler registers get assigned correctly on
1607// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
1608TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
1609{
1610 glActiveTexture(GL_TEXTURE0);
1611 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1612 GLubyte texData[4];
1613 texData[0] = 0;
1614 texData[1] = 60;
1615 texData[2] = 0;
1616 texData[3] = 255;
1617 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1618
1619 glActiveTexture(GL_TEXTURE1);
1620 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1621 GLfloat depthTexData[1];
1622 depthTexData[0] = 0.5f;
1623 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1624 depthTexData);
1625
1626 glUseProgram(mProgram);
1627 glUniform1f(mDepthRefUniformLocation, 0.3f);
1628 glUniform1i(mTexture3DUniformLocation, 0);
1629 glUniform1i(mTextureShadowUniformLocation, 1);
1630
1631 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1632 drawQuad(mProgram, "position", 0.5f);
1633 EXPECT_GL_NO_ERROR();
1634 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
1635 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
1636
1637 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
1638 drawQuad(mProgram, "position", 0.5f);
1639 EXPECT_GL_NO_ERROR();
1640 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
1641 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
1642}
1643
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001644// Test multiple different sampler types in the same shader.
1645// This test makes sure that even if sampler / texture registers get grouped together based on type
1646// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
1647// still has the right register index information for each ESSL sampler.
1648// The tested ESSL samplers have the following types in D3D11 HLSL:
1649// sampler2D: Texture2D + SamplerState
1650// samplerCube: TextureCube + SamplerState
1651// sampler2DShadow: Texture2D + SamplerComparisonState
1652// samplerCubeShadow: TextureCube + SamplerComparisonState
1653TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
1654{
1655 glActiveTexture(GL_TEXTURE0);
1656 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1657 GLubyte texData[4];
1658 texData[0] = 0;
1659 texData[1] = 0;
1660 texData[2] = 120;
1661 texData[3] = 255;
1662 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1663
1664 glActiveTexture(GL_TEXTURE1);
1665 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1666 texData[0] = 0;
1667 texData[1] = 90;
1668 texData[2] = 0;
1669 texData[3] = 255;
1670 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
1671 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1672 texData);
1673
1674 glActiveTexture(GL_TEXTURE2);
1675 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1677 GLfloat depthTexData[1];
1678 depthTexData[0] = 0.5f;
1679 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1680 depthTexData);
1681
1682 glActiveTexture(GL_TEXTURE3);
1683 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1684 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1685 depthTexData[0] = 0.2f;
1686 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1687 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
1688 depthTexData);
1689
1690 EXPECT_GL_NO_ERROR();
1691
1692 glUseProgram(mProgram);
1693 glUniform1f(mDepthRefUniformLocation, 0.3f);
1694 glUniform1i(mTexture2DUniformLocation, 0);
1695 glUniform1i(mTextureCubeUniformLocation, 1);
1696 glUniform1i(mTexture2DShadowUniformLocation, 2);
1697 glUniform1i(mTextureCubeShadowUniformLocation, 3);
1698
1699 drawQuad(mProgram, "position", 0.5f);
1700 EXPECT_GL_NO_ERROR();
1701 // The shader writes:
1702 // <texture 2d color> +
1703 // <cube map color> +
1704 // 0.25 * <comparison result (1.0)> +
1705 // 0.125 * <comparison result (0.0)>
1706 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
1707}
1708
Olli Etuahobce743a2016-01-15 17:18:28 +02001709// Test different base levels on textures accessed through the same sampler array.
1710// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
1711TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
1712{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001713 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02001714 {
1715 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
1716 return;
1717 }
1718 glActiveTexture(GL_TEXTURE0);
1719 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
1720 GLsizei size = 64;
1721 for (GLint level = 0; level < 7; ++level)
1722 {
1723 ASSERT_LT(0, size);
1724 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1725 nullptr);
1726 size = size / 2;
1727 }
1728 ASSERT_EQ(0, size);
1729 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1730
1731 glActiveTexture(GL_TEXTURE1);
1732 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
1733 size = 128;
1734 for (GLint level = 0; level < 8; ++level)
1735 {
1736 ASSERT_LT(0, size);
1737 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1738 nullptr);
1739 size = size / 2;
1740 }
1741 ASSERT_EQ(0, size);
1742 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
1743 EXPECT_GL_NO_ERROR();
1744
1745 glUseProgram(mProgram);
1746 glUniform1i(mTexture0Location, 0);
1747 glUniform1i(mTexture1Location, 1);
1748
1749 drawQuad(mProgram, "position", 0.5f);
1750 EXPECT_GL_NO_ERROR();
1751 // Red channel: width of level 1 of texture A: 32.
1752 // Green channel: width of level 3 of texture B: 16.
1753 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
1754}
1755
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001756// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1757// ES 3.0.4 table 3.24
1758TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
1759{
1760 glActiveTexture(GL_TEXTURE0);
1761 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1762 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1763 EXPECT_GL_NO_ERROR();
1764
1765 drawQuad(mProgram, "position", 0.5f);
1766
1767 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1768}
1769
1770// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1771// ES 3.0.4 table 3.24
1772TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
1773{
1774 glActiveTexture(GL_TEXTURE0);
1775 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1776 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1777 EXPECT_GL_NO_ERROR();
1778
1779 drawQuad(mProgram, "position", 0.5f);
1780
1781 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1782}
1783
1784// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1785// ES 3.0.4 table 3.24
1786TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
1787{
1788 if (extensionEnabled("GL_OES_texture_float"))
1789 {
1790 glActiveTexture(GL_TEXTURE0);
1791 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1792 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
1793 EXPECT_GL_NO_ERROR();
1794
1795 drawQuad(mProgram, "position", 0.5f);
1796
1797 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1798 }
1799}
1800
1801// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1802// ES 3.0.4 table 3.24
1803TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
1804{
1805 if (extensionEnabled("GL_OES_texture_half_float"))
1806 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001807 if (IsNVIDIA() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001808 {
1809 std::cout << "Test skipped on NVIDIA" << std::endl;
1810 return;
1811 }
1812 glActiveTexture(GL_TEXTURE0);
1813 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1814 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
1815 nullptr);
1816 EXPECT_GL_NO_ERROR();
1817
1818 drawQuad(mProgram, "position", 0.5f);
1819
1820 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1821 }
1822}
1823
1824// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1825// ES 3.0.4 table 3.24
1826TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
1827{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001828 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001829 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001830 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001831 return;
1832 }
1833 glActiveTexture(GL_TEXTURE0);
1834 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1835 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
1836 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1837 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1838 EXPECT_GL_NO_ERROR();
1839
1840 drawQuad(mProgram, "position", 0.5f);
1841
1842 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1843}
1844
1845// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1846// ES 3.0.4 table 3.24
1847TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
1848{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001849 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001850 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001851 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001852 return;
1853 }
1854 glActiveTexture(GL_TEXTURE0);
1855 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1856
1857 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
1858 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1859 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1860 EXPECT_GL_NO_ERROR();
1861
1862 drawQuad(mProgram, "position", 0.5f);
1863
1864 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1865}
1866
1867// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1868// ES 3.0.4 table 3.24
1869TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
1870{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001871 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001872 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001873 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001874 return;
1875 }
1876 glActiveTexture(GL_TEXTURE0);
1877 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1878 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
1879 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1880 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1881 EXPECT_GL_NO_ERROR();
1882
1883 drawQuad(mProgram, "position", 0.5f);
1884
1885 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1886}
1887
1888// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1889// ES 3.0.4 table 3.24
1890TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
1891{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001892 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001893 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001894 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001895 return;
1896 }
1897 glActiveTexture(GL_TEXTURE0);
1898 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1899 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
1900 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1901 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1902 EXPECT_GL_NO_ERROR();
1903
1904 drawQuad(mProgram, "position", 0.5f);
1905
1906 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1907}
1908
1909// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1910// ES 3.0.4 table 3.24
1911TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
1912{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001913 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001914 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001915 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001916 return;
1917 }
1918 glActiveTexture(GL_TEXTURE0);
1919 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1920 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
1921 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1922 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1923 EXPECT_GL_NO_ERROR();
1924
1925 drawQuad(mProgram, "position", 0.5f);
1926
1927 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1928}
1929
1930// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1931// ES 3.0.4 table 3.24
1932TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
1933{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001934 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001935 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001936 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001937 return;
1938 }
1939 glActiveTexture(GL_TEXTURE0);
1940 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1941 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
1942 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1943 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1944 EXPECT_GL_NO_ERROR();
1945
1946 drawQuad(mProgram, "position", 0.5f);
1947
1948 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1949}
1950
1951// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1952// ES 3.0.4 table 3.24
1953TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
1954{
1955 glActiveTexture(GL_TEXTURE0);
1956 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1957 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
1958 EXPECT_GL_NO_ERROR();
1959
1960 drawQuad(mProgram, "position", 0.5f);
1961
1962 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1963}
1964
1965// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1966// ES 3.0.4 table 3.24
1967TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
1968{
1969 glActiveTexture(GL_TEXTURE0);
1970 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1971 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
1972 nullptr);
1973 EXPECT_GL_NO_ERROR();
1974
1975 drawQuad(mProgram, "position", 0.5f);
1976
1977 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1978}
1979
1980// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1981// ES 3.0.4 table 3.24
1982TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
1983{
1984 glActiveTexture(GL_TEXTURE0);
1985 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1986 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
1987 EXPECT_GL_NO_ERROR();
1988
1989 drawQuad(mProgram, "position", 0.5f);
1990
1991 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1992}
1993
1994// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1995// ES 3.0.4 table 3.24
1996TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
1997{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001998 if (IsIntel() && IsLinux())
1999 {
2000 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2001 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2002 return;
2003 }
2004
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002005 glActiveTexture(GL_TEXTURE0);
2006 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2007 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2008 EXPECT_GL_NO_ERROR();
2009
2010 drawQuad(mProgram, "position", 0.5f);
2011
2012 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2013}
2014
Olli Etuaho96963162016-03-21 11:54:33 +02002015// Use a sampler in a uniform struct.
2016TEST_P(SamplerInStructTest, SamplerInStruct)
2017{
2018 runSamplerInStructTest();
2019}
2020
2021// Use a sampler in a uniform struct that's passed as a function parameter.
2022TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2023{
2024 runSamplerInStructTest();
2025}
2026
2027// Use a sampler in a uniform struct array with a struct from the array passed as a function
2028// parameter.
2029TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2030{
2031 runSamplerInStructTest();
2032}
2033
2034// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2035// parameter.
2036TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2037{
2038 runSamplerInStructTest();
2039}
2040
2041// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2042// similarly named uniform.
2043TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2044{
2045 runSamplerInStructTest();
2046}
2047
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002048class TextureLimitsTest : public ANGLETest
2049{
2050 protected:
2051 struct RGBA8
2052 {
2053 uint8_t R, G, B, A;
2054 };
2055
2056 TextureLimitsTest()
2057 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2058 {
2059 setWindowWidth(128);
2060 setWindowHeight(128);
2061 setConfigRedBits(8);
2062 setConfigGreenBits(8);
2063 setConfigBlueBits(8);
2064 setConfigAlphaBits(8);
2065 }
2066
2067 ~TextureLimitsTest()
2068 {
2069 if (mProgram != 0)
2070 {
2071 glDeleteProgram(mProgram);
2072 mProgram = 0;
2073
2074 if (!mTextures.empty())
2075 {
2076 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2077 }
2078 }
2079 }
2080
2081 void SetUp() override
2082 {
2083 ANGLETest::SetUp();
2084
2085 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2086 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2087 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2088
2089 ASSERT_GL_NO_ERROR();
2090 }
2091
2092 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2093 GLint vertexTextureCount,
2094 GLint vertexActiveTextureCount,
2095 const std::string &fragPrefix,
2096 GLint fragmentTextureCount,
2097 GLint fragmentActiveTextureCount)
2098 {
2099 std::stringstream vertexShaderStr;
2100 vertexShaderStr << "attribute vec2 position;\n"
2101 << "varying vec4 color;\n"
2102 << "varying vec2 texCoord;\n";
2103
2104 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2105 {
2106 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2107 }
2108
2109 vertexShaderStr << "void main() {\n"
2110 << " gl_Position = vec4(position, 0, 1);\n"
2111 << " texCoord = (position * 0.5) + 0.5;\n"
2112 << " color = vec4(0);\n";
2113
2114 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2115 {
2116 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2117 << ", texCoord);\n";
2118 }
2119
2120 vertexShaderStr << "}";
2121
2122 std::stringstream fragmentShaderStr;
2123 fragmentShaderStr << "varying mediump vec4 color;\n"
2124 << "varying mediump vec2 texCoord;\n";
2125
2126 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2127 {
2128 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2129 }
2130
2131 fragmentShaderStr << "void main() {\n"
2132 << " gl_FragColor = color;\n";
2133
2134 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2135 {
2136 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2137 << ", texCoord);\n";
2138 }
2139
2140 fragmentShaderStr << "}";
2141
2142 const std::string &vertexShaderSource = vertexShaderStr.str();
2143 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2144
2145 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2146 }
2147
2148 RGBA8 getPixel(GLint texIndex)
2149 {
2150 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2151 0, 255u};
2152 return pixel;
2153 }
2154
2155 void initTextures(GLint tex2DCount, GLint texCubeCount)
2156 {
2157 GLint totalCount = tex2DCount + texCubeCount;
2158 mTextures.assign(totalCount, 0);
2159 glGenTextures(totalCount, &mTextures[0]);
2160 ASSERT_GL_NO_ERROR();
2161
2162 std::vector<RGBA8> texData(16 * 16);
2163
2164 GLint texIndex = 0;
2165 for (; texIndex < tex2DCount; ++texIndex)
2166 {
2167 texData.assign(texData.size(), getPixel(texIndex));
2168 glActiveTexture(GL_TEXTURE0 + texIndex);
2169 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2170 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2171 &texData[0]);
2172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2176 }
2177
2178 ASSERT_GL_NO_ERROR();
2179
2180 for (; texIndex < texCubeCount; ++texIndex)
2181 {
2182 texData.assign(texData.size(), getPixel(texIndex));
2183 glActiveTexture(GL_TEXTURE0 + texIndex);
2184 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2185 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2186 GL_UNSIGNED_BYTE, &texData[0]);
2187 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2188 GL_UNSIGNED_BYTE, &texData[0]);
2189 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2190 GL_UNSIGNED_BYTE, &texData[0]);
2191 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2192 GL_UNSIGNED_BYTE, &texData[0]);
2193 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2194 GL_UNSIGNED_BYTE, &texData[0]);
2195 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2196 GL_UNSIGNED_BYTE, &texData[0]);
2197 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2198 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2199 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2200 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2201 }
2202
2203 ASSERT_GL_NO_ERROR();
2204 }
2205
2206 void testWithTextures(GLint vertexTextureCount,
2207 const std::string &vertexTexturePrefix,
2208 GLint fragmentTextureCount,
2209 const std::string &fragmentTexturePrefix)
2210 {
2211 // Generate textures
2212 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2213
2214 glUseProgram(mProgram);
2215 RGBA8 expectedSum = {0};
2216 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2217 {
2218 std::stringstream uniformNameStr;
2219 uniformNameStr << vertexTexturePrefix << texIndex;
2220 const std::string &uniformName = uniformNameStr.str();
2221 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2222 ASSERT_NE(-1, location);
2223
2224 glUniform1i(location, texIndex);
2225 RGBA8 contribution = getPixel(texIndex);
2226 expectedSum.R += contribution.R;
2227 expectedSum.G += contribution.G;
2228 }
2229
2230 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2231 {
2232 std::stringstream uniformNameStr;
2233 uniformNameStr << fragmentTexturePrefix << texIndex;
2234 const std::string &uniformName = uniformNameStr.str();
2235 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2236 ASSERT_NE(-1, location);
2237
2238 glUniform1i(location, texIndex + vertexTextureCount);
2239 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
2240 expectedSum.R += contribution.R;
2241 expectedSum.G += contribution.G;
2242 }
2243
2244 ASSERT_GE(256u, expectedSum.G);
2245
2246 drawQuad(mProgram, "position", 0.5f);
2247 ASSERT_GL_NO_ERROR();
2248 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
2249 }
2250
2251 GLuint mProgram;
2252 std::vector<GLuint> mTextures;
2253 GLint mMaxVertexTextures;
2254 GLint mMaxFragmentTextures;
2255 GLint mMaxCombinedTextures;
2256};
2257
2258// Test rendering with the maximum vertex texture units.
2259TEST_P(TextureLimitsTest, MaxVertexTextures)
2260{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002261 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002262 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002263 {
2264 std::cout << "Test skipped on Intel." << std::endl;
2265 return;
2266 }
2267
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002268 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
2269 ASSERT_NE(0u, mProgram);
2270 ASSERT_GL_NO_ERROR();
2271
2272 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2273}
2274
2275// Test rendering with the maximum fragment texture units.
2276TEST_P(TextureLimitsTest, MaxFragmentTextures)
2277{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002278 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002279 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002280 {
2281 std::cout << "Test skipped on Intel." << std::endl;
2282 return;
2283 }
2284
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002285 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
2286 ASSERT_NE(0u, mProgram);
2287 ASSERT_GL_NO_ERROR();
2288
2289 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
2290}
2291
2292// Test rendering with maximum combined texture units.
2293TEST_P(TextureLimitsTest, MaxCombinedTextures)
2294{
Jamie Madill412f17d2015-09-25 08:43:54 -04002295 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002296 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04002297 {
2298 std::cout << "Test skipped on Intel." << std::endl;
2299 return;
2300 }
2301
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002302 GLint vertexTextures = mMaxVertexTextures;
2303
2304 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
2305 {
2306 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
2307 }
2308
2309 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
2310 mMaxFragmentTextures, mMaxFragmentTextures);
2311 ASSERT_NE(0u, mProgram);
2312 ASSERT_GL_NO_ERROR();
2313
2314 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
2315}
2316
2317// Negative test for exceeding the number of vertex textures
2318TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
2319{
2320 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
2321 0);
2322 ASSERT_EQ(0u, mProgram);
2323}
2324
2325// Negative test for exceeding the number of fragment textures
2326TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
2327{
2328 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
2329 mMaxFragmentTextures + 1);
2330 ASSERT_EQ(0u, mProgram);
2331}
2332
2333// Test active vertex textures under the limit, but excessive textures specified.
2334TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
2335{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002336 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002337 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002338 {
2339 std::cout << "Test skipped on Intel." << std::endl;
2340 return;
2341 }
2342
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002343 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
2344 ASSERT_NE(0u, mProgram);
2345 ASSERT_GL_NO_ERROR();
2346
2347 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2348}
2349
2350// Test active fragment textures under the limit, but excessive textures specified.
2351TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
2352{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002353 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002354 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002355 {
2356 std::cout << "Test skipped on Intel." << std::endl;
2357 return;
2358 }
2359
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002360 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
2361 mMaxFragmentTextures);
2362 ASSERT_NE(0u, mProgram);
2363 ASSERT_GL_NO_ERROR();
2364
2365 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
2366}
2367
2368// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002369// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002370TEST_P(TextureLimitsTest, TextureTypeConflict)
2371{
2372 const std::string &vertexShader =
2373 "attribute vec2 position;\n"
2374 "varying float color;\n"
2375 "uniform sampler2D tex2D;\n"
2376 "uniform samplerCube texCube;\n"
2377 "void main() {\n"
2378 " gl_Position = vec4(position, 0, 1);\n"
2379 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2380 " color = texture2D(tex2D, texCoord).x;\n"
2381 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
2382 "}";
2383 const std::string &fragmentShader =
2384 "varying mediump float color;\n"
2385 "void main() {\n"
2386 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2387 "}";
2388
2389 mProgram = CompileProgram(vertexShader, fragmentShader);
2390 ASSERT_NE(0u, mProgram);
2391
2392 initTextures(1, 0);
2393
2394 glUseProgram(mProgram);
2395 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2396 ASSERT_NE(-1, tex2DLocation);
2397 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
2398 ASSERT_NE(-1, texCubeLocation);
2399
2400 glUniform1i(tex2DLocation, 0);
2401 glUniform1i(texCubeLocation, 0);
2402 ASSERT_GL_NO_ERROR();
2403
2404 drawQuad(mProgram, "position", 0.5f);
2405 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2406}
2407
2408// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002409// TODO(jmadill): Possibly adjust the test according to the spec:
2410// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
2411// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002412TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
2413{
2414 const std::string &vertexShader =
2415 "attribute vec2 position;\n"
2416 "varying float color;\n"
2417 "uniform sampler2D tex2D;\n"
2418 "void main() {\n"
2419 " gl_Position = vec4(position, 0, 1);\n"
2420 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2421 " color = texture2D(tex2D, texCoord).x;\n"
2422 "}";
2423 const std::string &fragmentShader =
2424 "varying mediump float color;\n"
2425 "void main() {\n"
2426 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2427 "}";
2428
2429 mProgram = CompileProgram(vertexShader, fragmentShader);
2430 ASSERT_NE(0u, mProgram);
2431
2432 glUseProgram(mProgram);
2433 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2434 ASSERT_NE(-1, tex2DLocation);
2435
2436 glUniform1i(tex2DLocation, mMaxCombinedTextures);
2437 ASSERT_GL_NO_ERROR();
2438
2439 drawQuad(mProgram, "position", 0.5f);
2440 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2441}
2442
Jamie Madillfa05f602015-05-07 13:47:11 -04002443// 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 +02002444// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05002445ANGLE_INSTANTIATE_TEST(Texture2DTest,
2446 ES2_D3D9(),
2447 ES2_D3D11(),
2448 ES2_D3D11_FL9_3(),
2449 ES2_OPENGL(),
2450 ES2_OPENGLES());
2451ANGLE_INSTANTIATE_TEST(TextureCubeTest,
2452 ES2_D3D9(),
2453 ES2_D3D11(),
2454 ES2_D3D11_FL9_3(),
2455 ES2_OPENGL(),
2456 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002457ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
2458 ES2_D3D9(),
2459 ES2_D3D11(),
2460 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002461 ES2_OPENGL(),
2462 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002463ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
2464 ES2_D3D9(),
2465 ES2_D3D11(),
2466 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002467 ES2_OPENGL(),
2468 ES2_OPENGLES());
2469ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
2470 ES2_D3D9(),
2471 ES2_D3D11(),
2472 ES2_D3D11_FL9_3(),
2473 ES2_OPENGL(),
2474 ES2_OPENGLES());
2475ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
2476 ES2_D3D9(),
2477 ES2_D3D11(),
2478 ES2_D3D11_FL9_3(),
2479 ES2_OPENGL(),
2480 ES2_OPENGLES());
2481ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002482ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2483ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
2484 ES3_D3D11(),
2485 ES3_OPENGL(),
2486 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002487ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
2488 ES3_D3D11(),
2489 ES3_OPENGL(),
2490 ES3_OPENGLES());
2491ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2492ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02002493ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02002494ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
2495 ES2_D3D11(),
2496 ES2_D3D11_FL9_3(),
2497 ES2_D3D9(),
2498 ES2_OPENGL(),
2499 ES2_OPENGLES());
2500ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
2501 ES2_D3D11(),
2502 ES2_D3D11_FL9_3(),
2503 ES2_D3D9(),
2504 ES2_OPENGL(),
2505 ES2_OPENGLES());
2506ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
2507 ES2_D3D11(),
2508 ES2_D3D11_FL9_3(),
2509 ES2_D3D9(),
2510 ES2_OPENGL(),
2511 ES2_OPENGLES());
2512ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
2513 ES2_D3D11(),
2514 ES2_D3D11_FL9_3(),
2515 ES2_D3D9(),
2516 ES2_OPENGL(),
2517 ES2_OPENGLES());
2518ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
2519 ES2_D3D11(),
2520 ES2_D3D11_FL9_3(),
2521 ES2_D3D9(),
2522 ES2_OPENGL(),
2523 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002524ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04002525
2526} // namespace