blob: e74519c079c0e322d4cc8351d04807d6a81fd5e4 [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
Olli Etuahoa1c917f2016-04-06 13:50:03 +030058 virtual void setUpProgram()
Olli Etuaho4a8329f2016-01-11 17:12:57 +020059 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020060 const std::string vertexShaderSource = getVertexShaderSource();
61 const std::string fragmentShaderSource = getFragmentShaderSource();
62
63 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
64 ASSERT_NE(0u, mProgram);
65 ASSERT_GL_NO_ERROR();
Olli Etuahoa1c917f2016-04-06 13:50:03 +030066 }
67
68 void SetUp() override
69 {
70 ANGLETest::SetUp();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020071
72 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020073 }
74
75 void TearDown() override
76 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020077 glBindFramebuffer(GL_FRAMEBUFFER, 0);
78 glDeleteFramebuffers(1, &mFramebuffer);
79 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020080 glDeleteProgram(mProgram);
81 ANGLETest::TearDown();
82 }
83
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020084 void setUpFramebuffer()
85 {
86 // We use an FBO to work around an issue where the default framebuffer applies SRGB
87 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
88 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
89 // section 4.4 says that the format of the default framebuffer is entirely up to the window
90 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
91 // SRGB conversion like desktop GL does.
92 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
93 glGenFramebuffers(1, &mFramebuffer);
94 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
95
96 glGenTextures(1, &mFramebufferColorTexture);
97 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
98 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
99 GL_UNSIGNED_BYTE, nullptr);
100 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
101 mFramebufferColorTexture, 0);
102 ASSERT_GL_NO_ERROR();
103 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
104 glBindTexture(GL_TEXTURE_2D, 0);
105 }
106
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200107 // Returns the created texture ID.
108 GLuint create2DTexture()
109 {
110 GLuint texture2D;
111 glGenTextures(1, &texture2D);
112 glBindTexture(GL_TEXTURE_2D, texture2D);
113 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
114 EXPECT_GL_NO_ERROR();
115 return texture2D;
116 }
117
118 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200119 GLuint mFramebuffer;
120
121 private:
122 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200123};
124
125class Texture2DTest : public TexCoordDrawTest
126{
127 protected:
128 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
129
130 std::string getFragmentShaderSource() override
131 {
132 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400133 (
134 precision highp float;
135 uniform sampler2D tex;
136 varying vec2 texcoord;
137
138 void main()
139 {
140 gl_FragColor = texture2D(tex, texcoord);
141 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200142 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400143 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200144 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400145
Olli Etuaho96963162016-03-21 11:54:33 +0200146 virtual const char *getTextureUniformName() { return "tex"; }
147
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300148 void setUpProgram() override
149 {
150 TexCoordDrawTest::setUpProgram();
151 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
152 ASSERT_NE(-1, mTexture2DUniformLocation);
153 }
154
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200155 void SetUp() override
156 {
157 TexCoordDrawTest::SetUp();
158 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400159
Jamie Madill9aca0592014-10-06 16:26:59 -0400160 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -0400161 }
162
Jamie Madillfa05f602015-05-07 13:47:11 -0400163 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400164 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400165 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200166 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400167 }
168
Jamie Madillbc393df2015-01-29 13:46:07 -0500169 // Tests CopyTexSubImage with floating point textures of various formats.
170 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
171 {
Geoff Langbde666a2015-04-07 17:17:08 -0400172 // TODO(jmadill): Figure out why this is broken on Intel D3D11
Jamie Madill518b9fa2016-03-02 11:26:02 -0500173 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Geoff Langbde666a2015-04-07 17:17:08 -0400174 {
175 std::cout << "Test skipped on Intel D3D11." << std::endl;
176 return;
177 }
178
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300179 setUpProgram();
180
Geoff Langfbfa47c2015-03-31 11:26:00 -0400181 if (getClientVersion() < 3)
182 {
183 if (!extensionEnabled("GL_OES_texture_float"))
184 {
185 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
186 return;
187 }
188
189 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
190 {
191 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
192 return;
193 }
194 }
195
Jamie Madillbc393df2015-01-29 13:46:07 -0500196 GLfloat sourceImageData[4][16] =
197 {
198 { // R
199 1.0f,
200 0.0f,
201 0.0f,
202 1.0f
203 },
204 { // RG
205 1.0f, 0.0f,
206 0.0f, 1.0f,
207 0.0f, 0.0f,
208 1.0f, 1.0f
209 },
210 { // RGB
211 1.0f, 0.0f, 0.0f,
212 0.0f, 1.0f, 0.0f,
213 0.0f, 0.0f, 1.0f,
214 1.0f, 1.0f, 0.0f
215 },
216 { // RGBA
217 1.0f, 0.0f, 0.0f, 1.0f,
218 0.0f, 1.0f, 0.0f, 1.0f,
219 0.0f, 0.0f, 1.0f, 1.0f,
220 1.0f, 1.0f, 0.0f, 1.0f
221 },
222 };
223
224 GLenum imageFormats[] =
225 {
226 GL_R32F,
227 GL_RG32F,
228 GL_RGB32F,
229 GL_RGBA32F,
230 };
231
232 GLenum sourceUnsizedFormats[] =
233 {
234 GL_RED,
235 GL_RG,
236 GL_RGB,
237 GL_RGBA,
238 };
239
240 GLuint textures[2];
241
242 glGenTextures(2, textures);
243
244 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
245 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
246 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
247 GLenum destImageFormat = imageFormats[destImageChannels - 1];
248
249 glBindTexture(GL_TEXTURE_2D, textures[0]);
250 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
253 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
254
hendrikwb27f79a2015-03-04 11:26:46 -0800255 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500256 {
257 // This is not supported
258 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
259 }
260 else
261 {
262 ASSERT_GL_NO_ERROR();
263 }
264
265 GLuint fbo;
266 glGenFramebuffers(1, &fbo);
267 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
268 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
269
270 glBindTexture(GL_TEXTURE_2D, textures[1]);
271 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
274
275 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
276 ASSERT_GL_NO_ERROR();
277
278 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200279 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500280
281 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
282
283 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
284 if (testImageChannels > 1)
285 {
286 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
287 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
288 if (testImageChannels > 2)
289 {
290 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
291 }
292 }
293
294 glDeleteFramebuffers(1, &fbo);
295 glDeleteTextures(2, textures);
296
297 ASSERT_GL_NO_ERROR();
298 }
299
Jamie Madilld4cfa572014-07-08 10:00:32 -0400300 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400301 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400302};
303
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200304class Texture2DTestES3 : public Texture2DTest
305{
306 protected:
307 Texture2DTestES3() : Texture2DTest() {}
308
309 std::string getVertexShaderSource() override
310 {
311 return std::string(
312 "#version 300 es\n"
313 "out vec2 texcoord;\n"
314 "in vec4 position;\n"
315 "void main()\n"
316 "{\n"
317 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
318 " texcoord = (position.xy * 0.5) + 0.5;\n"
319 "}\n");
320 }
321
322 std::string getFragmentShaderSource() override
323 {
324 return std::string(
325 "#version 300 es\n"
326 "precision highp float;\n"
327 "uniform highp sampler2D tex;\n"
328 "in vec2 texcoord;\n"
329 "out vec4 fragColor;\n"
330 "void main()\n"
331 "{\n"
332 " fragColor = texture(tex, texcoord);\n"
333 "}\n");
334 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300335
336 void SetUp() override
337 {
338 Texture2DTest::SetUp();
339 setUpProgram();
340 }
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200341};
342
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200343class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
344{
345 protected:
346 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
347
348 std::string getVertexShaderSource() override
349 {
350 return std::string(
351 "#version 300 es\n"
352 "out vec2 texcoord;\n"
353 "in vec4 position;\n"
354 "void main()\n"
355 "{\n"
356 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
357 " texcoord = (position.xy * 0.5) + 0.5;\n"
358 "}\n");
359 }
360
361 std::string getFragmentShaderSource() override
362 {
363 return std::string(
364 "#version 300 es\n"
365 "precision highp float;\n"
366 "uniform highp isampler2D tex;\n"
367 "in vec2 texcoord;\n"
368 "out vec4 fragColor;\n"
369 "void main()\n"
370 "{\n"
371 " vec4 green = vec4(0, 1, 0, 1);\n"
372 " vec4 black = vec4(0, 0, 0, 0);\n"
373 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
374 "}\n");
375 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300376
377 void SetUp() override
378 {
379 Texture2DTest::SetUp();
380 setUpProgram();
381 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200382};
383
384class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
385{
386 protected:
387 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
388
389 std::string getVertexShaderSource() override
390 {
391 return std::string(
392 "#version 300 es\n"
393 "out vec2 texcoord;\n"
394 "in vec4 position;\n"
395 "void main()\n"
396 "{\n"
397 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
398 " texcoord = (position.xy * 0.5) + 0.5;\n"
399 "}\n");
400 }
401
402 std::string getFragmentShaderSource() override
403 {
404 return std::string(
405 "#version 300 es\n"
406 "precision highp float;\n"
407 "uniform highp usampler2D tex;\n"
408 "in vec2 texcoord;\n"
409 "out vec4 fragColor;\n"
410 "void main()\n"
411 "{\n"
412 " vec4 green = vec4(0, 1, 0, 1);\n"
413 " vec4 black = vec4(0, 0, 0, 0);\n"
414 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
415 "}\n");
416 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300417
418 void SetUp() override
419 {
420 Texture2DTest::SetUp();
421 setUpProgram();
422 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200423};
424
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200425class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400426{
427 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200428 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
429
430 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400431 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200432 return std::string(SHADER_SOURCE
433 (
434 precision highp float;
435 attribute vec4 position;
436 varying vec2 texcoord;
437
438 uniform vec2 drawScale;
439
440 void main()
441 {
442 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
443 texcoord = (position.xy * 0.5) + 0.5;
444 }
445 )
446 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400447 }
448
449 void SetUp() override
450 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200451 Texture2DTest::SetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300452
453 setUpProgram();
454
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200455 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
456 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400457
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200458 glUseProgram(mProgram);
459 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
460 glUseProgram(0);
461 ASSERT_GL_NO_ERROR();
462 }
463
464 GLint mDrawScaleUniformLocation;
465};
466
Olli Etuaho4644a202016-01-12 15:12:53 +0200467class Sampler2DAsFunctionParameterTest : public Texture2DTest
468{
469 protected:
470 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
471
472 std::string getFragmentShaderSource() override
473 {
474 return std::string(SHADER_SOURCE
475 (
476 precision highp float;
477 uniform sampler2D tex;
478 varying vec2 texcoord;
479
480 vec4 computeFragColor(sampler2D aTex)
481 {
482 return texture2D(aTex, texcoord);
483 }
484
485 void main()
486 {
487 gl_FragColor = computeFragColor(tex);
488 }
489 )
490 );
491 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300492
493 void SetUp() override
494 {
495 Texture2DTest::SetUp();
496 setUpProgram();
497 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200498};
499
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200500class TextureCubeTest : public TexCoordDrawTest
501{
502 protected:
503 TextureCubeTest()
504 : TexCoordDrawTest(),
505 mTexture2D(0),
506 mTextureCube(0),
507 mTexture2DUniformLocation(-1),
508 mTextureCubeUniformLocation(-1)
509 {
510 }
511
512 std::string getFragmentShaderSource() override
513 {
514 return std::string(SHADER_SOURCE
515 (
516 precision highp float;
517 uniform sampler2D tex2D;
518 uniform samplerCube texCube;
519 varying vec2 texcoord;
520
521 void main()
522 {
523 gl_FragColor = texture2D(tex2D, texcoord);
524 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
525 }
526 )
527 );
528 }
529
530 void SetUp() override
531 {
532 TexCoordDrawTest::SetUp();
533
534 glGenTextures(1, &mTextureCube);
535 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
536 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
537 EXPECT_GL_NO_ERROR();
538
539 mTexture2D = create2DTexture();
540
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300541 setUpProgram();
542
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200543 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
544 ASSERT_NE(-1, mTexture2DUniformLocation);
545 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
546 ASSERT_NE(-1, mTextureCubeUniformLocation);
547 }
548
549 void TearDown() override
550 {
551 glDeleteTextures(1, &mTextureCube);
552 TexCoordDrawTest::TearDown();
553 }
554
555 GLuint mTexture2D;
556 GLuint mTextureCube;
557 GLint mTexture2DUniformLocation;
558 GLint mTextureCubeUniformLocation;
559};
560
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200561class SamplerArrayTest : public TexCoordDrawTest
562{
563 protected:
564 SamplerArrayTest()
565 : TexCoordDrawTest(),
566 mTexture2DA(0),
567 mTexture2DB(0),
568 mTexture0UniformLocation(-1),
569 mTexture1UniformLocation(-1)
570 {
571 }
572
573 std::string getFragmentShaderSource() override
574 {
575 return std::string(SHADER_SOURCE
576 (
577 precision mediump float;
578 uniform highp sampler2D tex2DArray[2];
579 varying vec2 texcoord;
580 void main()
581 {
582 gl_FragColor = texture2D(tex2DArray[0], texcoord);
583 gl_FragColor += texture2D(tex2DArray[1], texcoord);
584 }
585 )
586 );
587 }
588
589 void SetUp() override
590 {
591 TexCoordDrawTest::SetUp();
592
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300593 setUpProgram();
594
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200595 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
596 ASSERT_NE(-1, mTexture0UniformLocation);
597 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
598 ASSERT_NE(-1, mTexture1UniformLocation);
599
600 mTexture2DA = create2DTexture();
601 mTexture2DB = create2DTexture();
602 ASSERT_GL_NO_ERROR();
603 }
604
605 void TearDown() override
606 {
607 glDeleteTextures(1, &mTexture2DA);
608 glDeleteTextures(1, &mTexture2DB);
609 TexCoordDrawTest::TearDown();
610 }
611
612 void testSamplerArrayDraw()
613 {
614 GLubyte texData[4];
615 texData[0] = 0;
616 texData[1] = 60;
617 texData[2] = 0;
618 texData[3] = 255;
619
620 glActiveTexture(GL_TEXTURE0);
621 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
622 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
623
624 texData[1] = 120;
625 glActiveTexture(GL_TEXTURE1);
626 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
627 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
628 EXPECT_GL_ERROR(GL_NO_ERROR);
629
630 glUseProgram(mProgram);
631 glUniform1i(mTexture0UniformLocation, 0);
632 glUniform1i(mTexture1UniformLocation, 1);
633 drawQuad(mProgram, "position", 0.5f);
634 EXPECT_GL_NO_ERROR();
635
636 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
637 }
638
639 GLuint mTexture2DA;
640 GLuint mTexture2DB;
641 GLint mTexture0UniformLocation;
642 GLint mTexture1UniformLocation;
643};
644
645
646class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
647{
648 protected:
649 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
650
651 std::string getFragmentShaderSource() override
652 {
653 return std::string(SHADER_SOURCE
654 (
655 precision mediump float;
656 uniform highp sampler2D tex2DArray[2];
657 varying vec2 texcoord;
658
659 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
660 {
661 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
662 }
663
664 void main()
665 {
666 gl_FragColor = computeFragColor(tex2DArray);
667 }
668 )
669 );
670 }
671};
672
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200673class Texture2DArrayTestES3 : public TexCoordDrawTest
674{
675 protected:
676 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
677
678 std::string getVertexShaderSource() override
679 {
680 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400681 "#version 300 es\n"
682 "out vec2 texcoord;\n"
683 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200684 "void main()\n"
685 "{\n"
686 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
687 " texcoord = (position.xy * 0.5) + 0.5;\n"
688 "}\n");
689 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400690
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200691 std::string getFragmentShaderSource() override
692 {
693 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400694 "#version 300 es\n"
695 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200696 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400697 "in vec2 texcoord;\n"
698 "out vec4 fragColor;\n"
699 "void main()\n"
700 "{\n"
701 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200702 "}\n");
703 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400704
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200705 void SetUp() override
706 {
707 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400708
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300709 setUpProgram();
710
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200711 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400712 ASSERT_NE(-1, mTextureArrayLocation);
713
714 glGenTextures(1, &m2DArrayTexture);
715 ASSERT_GL_NO_ERROR();
716 }
717
718 void TearDown() override
719 {
720 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200721 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400722 }
723
724 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400725 GLint mTextureArrayLocation;
726};
727
Olli Etuahobce743a2016-01-15 17:18:28 +0200728class TextureSizeTextureArrayTest : public TexCoordDrawTest
729{
730 protected:
731 TextureSizeTextureArrayTest()
732 : TexCoordDrawTest(),
733 mTexture2DA(0),
734 mTexture2DB(0),
735 mTexture0Location(-1),
736 mTexture1Location(-1)
737 {
738 }
739
740 std::string getVertexShaderSource() override
741 {
742 return std::string(
743 "#version 300 es\n"
744 "in vec4 position;\n"
745 "void main()\n"
746 "{\n"
747 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
748 "}\n");
749 }
750
751 std::string getFragmentShaderSource() override
752 {
753 return std::string(
754 "#version 300 es\n"
755 "precision highp float;\n"
756 "uniform highp sampler2D tex2DArray[2];\n"
757 "out vec4 fragColor;\n"
758 "void main()\n"
759 "{\n"
760 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
761 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
762 " fragColor = vec4(red, green, 0.0, 1.0);\n"
763 "}\n");
764 }
765
766 void SetUp() override
767 {
768 TexCoordDrawTest::SetUp();
769
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300770 setUpProgram();
771
Olli Etuahobce743a2016-01-15 17:18:28 +0200772 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
773 ASSERT_NE(-1, mTexture0Location);
774 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
775 ASSERT_NE(-1, mTexture1Location);
776
777 mTexture2DA = create2DTexture();
778 mTexture2DB = create2DTexture();
779 ASSERT_GL_NO_ERROR();
780 }
781
782 void TearDown() override
783 {
784 glDeleteTextures(1, &mTexture2DA);
785 glDeleteTextures(1, &mTexture2DB);
786 TexCoordDrawTest::TearDown();
787 }
788
789 GLuint mTexture2DA;
790 GLuint mTexture2DB;
791 GLint mTexture0Location;
792 GLint mTexture1Location;
793};
794
Olli Etuaho1a679902016-01-14 12:21:47 +0200795class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
796{
797 protected:
798 ShadowSamplerPlusSampler3DTestES3()
799 : TexCoordDrawTest(),
800 mTextureShadow(0),
801 mTexture3D(0),
802 mTextureShadowUniformLocation(-1),
803 mTexture3DUniformLocation(-1),
804 mDepthRefUniformLocation(-1)
805 {
806 }
807
808 std::string getVertexShaderSource() override
809 {
810 return std::string(
811 "#version 300 es\n"
812 "out vec2 texcoord;\n"
813 "in vec4 position;\n"
814 "void main()\n"
815 "{\n"
816 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
817 " texcoord = (position.xy * 0.5) + 0.5;\n"
818 "}\n");
819 }
820
821 std::string getFragmentShaderSource() override
822 {
823 return std::string(
824 "#version 300 es\n"
825 "precision highp float;\n"
826 "uniform highp sampler2DShadow tex2DShadow;\n"
827 "uniform highp sampler3D tex3D;\n"
828 "in vec2 texcoord;\n"
829 "uniform float depthRef;\n"
830 "out vec4 fragColor;\n"
831 "void main()\n"
832 "{\n"
833 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
834 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
835 "}\n");
836 }
837
838 void SetUp() override
839 {
840 TexCoordDrawTest::SetUp();
841
842 glGenTextures(1, &mTexture3D);
843
844 glGenTextures(1, &mTextureShadow);
845 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
846 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
847
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300848 setUpProgram();
849
Olli Etuaho1a679902016-01-14 12:21:47 +0200850 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
851 ASSERT_NE(-1, mTextureShadowUniformLocation);
852 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
853 ASSERT_NE(-1, mTexture3DUniformLocation);
854 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
855 ASSERT_NE(-1, mDepthRefUniformLocation);
856 }
857
858 void TearDown() override
859 {
860 glDeleteTextures(1, &mTextureShadow);
861 glDeleteTextures(1, &mTexture3D);
862 TexCoordDrawTest::TearDown();
863 }
864
865 GLuint mTextureShadow;
866 GLuint mTexture3D;
867 GLint mTextureShadowUniformLocation;
868 GLint mTexture3DUniformLocation;
869 GLint mDepthRefUniformLocation;
870};
871
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200872class SamplerTypeMixTestES3 : public TexCoordDrawTest
873{
874 protected:
875 SamplerTypeMixTestES3()
876 : TexCoordDrawTest(),
877 mTexture2D(0),
878 mTextureCube(0),
879 mTexture2DShadow(0),
880 mTextureCubeShadow(0),
881 mTexture2DUniformLocation(-1),
882 mTextureCubeUniformLocation(-1),
883 mTexture2DShadowUniformLocation(-1),
884 mTextureCubeShadowUniformLocation(-1),
885 mDepthRefUniformLocation(-1)
886 {
887 }
888
889 std::string getVertexShaderSource() override
890 {
891 return std::string(
892 "#version 300 es\n"
893 "out vec2 texcoord;\n"
894 "in vec4 position;\n"
895 "void main()\n"
896 "{\n"
897 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
898 " texcoord = (position.xy * 0.5) + 0.5;\n"
899 "}\n");
900 }
901
902 std::string getFragmentShaderSource() override
903 {
904 return std::string(
905 "#version 300 es\n"
906 "precision highp float;\n"
907 "uniform highp sampler2D tex2D;\n"
908 "uniform highp samplerCube texCube;\n"
909 "uniform highp sampler2DShadow tex2DShadow;\n"
910 "uniform highp samplerCubeShadow texCubeShadow;\n"
911 "in vec2 texcoord;\n"
912 "uniform float depthRef;\n"
913 "out vec4 fragColor;\n"
914 "void main()\n"
915 "{\n"
916 " fragColor = texture(tex2D, texcoord);\n"
917 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
918 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
919 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
920 "0.125);\n"
921 "}\n");
922 }
923
924 void SetUp() override
925 {
926 TexCoordDrawTest::SetUp();
927
928 glGenTextures(1, &mTexture2D);
929 glGenTextures(1, &mTextureCube);
930
931 glGenTextures(1, &mTexture2DShadow);
932 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
933 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
934
935 glGenTextures(1, &mTextureCubeShadow);
936 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
937 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
938
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300939 setUpProgram();
940
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200941 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
942 ASSERT_NE(-1, mTexture2DUniformLocation);
943 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
944 ASSERT_NE(-1, mTextureCubeUniformLocation);
945 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
946 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
947 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
948 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
949 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
950 ASSERT_NE(-1, mDepthRefUniformLocation);
951
952 ASSERT_GL_NO_ERROR();
953 }
954
955 void TearDown() override
956 {
957 glDeleteTextures(1, &mTexture2D);
958 glDeleteTextures(1, &mTextureCube);
959 glDeleteTextures(1, &mTexture2DShadow);
960 glDeleteTextures(1, &mTextureCubeShadow);
961 TexCoordDrawTest::TearDown();
962 }
963
964 GLuint mTexture2D;
965 GLuint mTextureCube;
966 GLuint mTexture2DShadow;
967 GLuint mTextureCubeShadow;
968 GLint mTexture2DUniformLocation;
969 GLint mTextureCubeUniformLocation;
970 GLint mTexture2DShadowUniformLocation;
971 GLint mTextureCubeShadowUniformLocation;
972 GLint mDepthRefUniformLocation;
973};
974
Olli Etuaho96963162016-03-21 11:54:33 +0200975class SamplerInStructTest : public Texture2DTest
976{
977 protected:
978 SamplerInStructTest() : Texture2DTest() {}
979
980 const char *getTextureUniformName() override { return "us.tex"; }
981
982 std::string getFragmentShaderSource() override
983 {
984 return std::string(
985 "precision highp float;\n"
986 "struct S\n"
987 "{\n"
988 " vec4 a;\n"
989 " highp sampler2D tex;\n"
990 "};\n"
991 "uniform S us;\n"
992 "varying vec2 texcoord;\n"
993 "void main()\n"
994 "{\n"
995 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
996 "}\n");
997 }
998
999 void runSamplerInStructTest()
1000 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001001 setUpProgram();
1002
Olli Etuaho96963162016-03-21 11:54:33 +02001003 glActiveTexture(GL_TEXTURE0);
1004 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1005 GLubyte texDataGreen[1u * 1u * 4u];
1006 FillWithRGBA<GLubyte>(1u * 1u, 0u, 255u, 0u, 255u, texDataGreen);
1007 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1008 drawQuad(mProgram, "position", 0.5f);
1009 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1010 }
1011};
1012
1013class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1014{
1015 protected:
1016 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1017
1018 std::string getFragmentShaderSource() override
1019 {
1020 return std::string(
1021 "precision highp float;\n"
1022 "struct S\n"
1023 "{\n"
1024 " vec4 a;\n"
1025 " highp sampler2D tex;\n"
1026 "};\n"
1027 "uniform S us;\n"
1028 "varying vec2 texcoord;\n"
1029 "vec4 sampleFrom(S s) {\n"
1030 " return texture2D(s.tex, texcoord + s.a.x);\n"
1031 "}\n"
1032 "void main()\n"
1033 "{\n"
1034 " gl_FragColor = sampleFrom(us);\n"
1035 "}\n");
1036 }
1037};
1038
1039class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1040{
1041 protected:
1042 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1043
1044 const char *getTextureUniformName() override { return "us[0].tex"; }
1045
1046 std::string getFragmentShaderSource() override
1047 {
1048 return std::string(
1049 "precision highp float;\n"
1050 "struct S\n"
1051 "{\n"
1052 " vec4 a;\n"
1053 " highp sampler2D tex;\n"
1054 "};\n"
1055 "uniform S us[1];\n"
1056 "varying vec2 texcoord;\n"
1057 "vec4 sampleFrom(S s) {\n"
1058 " return texture2D(s.tex, texcoord + s.a.x);\n"
1059 "}\n"
1060 "void main()\n"
1061 "{\n"
1062 " gl_FragColor = sampleFrom(us[0]);\n"
1063 "}\n");
1064 }
1065};
1066
1067class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1068{
1069 protected:
1070 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1071
1072 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1073
1074 std::string getFragmentShaderSource() override
1075 {
1076 return std::string(
1077 "precision highp float;\n"
1078 "struct SUB\n"
1079 "{\n"
1080 " vec4 a;\n"
1081 " highp sampler2D tex;\n"
1082 "};\n"
1083 "struct S\n"
1084 "{\n"
1085 " SUB sub;\n"
1086 "};\n"
1087 "uniform S us[1];\n"
1088 "varying vec2 texcoord;\n"
1089 "vec4 sampleFrom(SUB s) {\n"
1090 " return texture2D(s.tex, texcoord + s.a.x);\n"
1091 "}\n"
1092 "void main()\n"
1093 "{\n"
1094 " gl_FragColor = sampleFrom(us[0].sub);\n"
1095 "}\n");
1096 }
1097};
1098
1099class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1100{
1101 protected:
1102 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1103
1104 std::string getFragmentShaderSource() override
1105 {
1106 return std::string(
1107 "precision highp float;\n"
1108 "struct S\n"
1109 "{\n"
1110 " vec4 a;\n"
1111 " highp sampler2D tex;\n"
1112 "};\n"
1113 "uniform S us;\n"
1114 "uniform float us_tex;\n"
1115 "varying vec2 texcoord;\n"
1116 "void main()\n"
1117 "{\n"
1118 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1119 "}\n");
1120 }
1121};
1122
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001123TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001124{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001125 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001126 EXPECT_GL_ERROR(GL_NO_ERROR);
1127
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001128 setUpProgram();
1129
Jamie Madillf67115c2014-04-22 13:14:05 -04001130 const GLubyte *pixels[20] = { 0 };
1131 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1132 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1133}
Geoff Langc41e42d2014-04-28 10:58:16 -04001134
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001135TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001136{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001137 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001138 EXPECT_GL_ERROR(GL_NO_ERROR);
1139
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001140 setUpProgram();
1141
Geoff Langc41e42d2014-04-28 10:58:16 -04001142 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001143 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001144 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001145 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001146
1147 const GLubyte *pixel[4] = { 0 };
1148
1149 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1150 EXPECT_GL_NO_ERROR();
1151
1152 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1153 EXPECT_GL_NO_ERROR();
1154
1155 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1156 EXPECT_GL_NO_ERROR();
1157}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001158
1159// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001160TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001161{
1162 glActiveTexture(GL_TEXTURE0);
1163 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1164 glActiveTexture(GL_TEXTURE1);
1165 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1166 EXPECT_GL_ERROR(GL_NO_ERROR);
1167
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001168 glUseProgram(mProgram);
1169 glUniform1i(mTexture2DUniformLocation, 0);
1170 glUniform1i(mTextureCubeUniformLocation, 1);
1171 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001172 EXPECT_GL_NO_ERROR();
1173}
Jamie Madill9aca0592014-10-06 16:26:59 -04001174
Olli Etuaho53a2da12016-01-11 15:43:32 +02001175// Test drawing with two texture types accessed from the same shader and check that the result of
1176// drawing is correct.
1177TEST_P(TextureCubeTest, CubeMapDraw)
1178{
1179 GLubyte texData[4];
1180 texData[0] = 0;
1181 texData[1] = 60;
1182 texData[2] = 0;
1183 texData[3] = 255;
1184
1185 glActiveTexture(GL_TEXTURE0);
1186 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1187 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1188
1189 glActiveTexture(GL_TEXTURE1);
1190 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1191 texData[1] = 120;
1192 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1193 texData);
1194 EXPECT_GL_ERROR(GL_NO_ERROR);
1195
1196 glUseProgram(mProgram);
1197 glUniform1i(mTexture2DUniformLocation, 0);
1198 glUniform1i(mTextureCubeUniformLocation, 1);
1199 drawQuad(mProgram, "position", 0.5f);
1200 EXPECT_GL_NO_ERROR();
1201
1202 int px = getWindowWidth() - 1;
1203 int py = 0;
1204 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1205}
1206
Olli Etuaho4644a202016-01-12 15:12:53 +02001207TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1208{
1209 glActiveTexture(GL_TEXTURE0);
1210 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1211 GLubyte texData[4];
1212 texData[0] = 0;
1213 texData[1] = 128;
1214 texData[2] = 0;
1215 texData[3] = 255;
1216 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1217 glUseProgram(mProgram);
1218 glUniform1i(mTexture2DUniformLocation, 0);
1219 drawQuad(mProgram, "position", 0.5f);
1220 EXPECT_GL_NO_ERROR();
1221
1222 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1223}
1224
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001225// Test drawing with two textures passed to the shader in a sampler array.
1226TEST_P(SamplerArrayTest, SamplerArrayDraw)
1227{
1228 testSamplerArrayDraw();
1229}
1230
1231// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1232// user-defined function in the shader.
1233TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1234{
1235 testSamplerArrayDraw();
1236}
1237
Jamie Madill9aca0592014-10-06 16:26:59 -04001238// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001239TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001240{
1241 int px = getWindowWidth() / 2;
1242 int py = getWindowHeight() / 2;
1243
1244 glActiveTexture(GL_TEXTURE0);
1245 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1246
1247 // Fill with red
1248 std::vector<GLubyte> pixels(4 * 16 * 16);
Olli Etuaho356f5162016-03-18 14:19:41 +02001249 FillWithRGBA<GLubyte>(16u * 16u, 255u, 0u, 0u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001250
1251 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1254 glGenerateMipmap(GL_TEXTURE_2D);
1255
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001256 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001257 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001258 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1259 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001260 EXPECT_GL_NO_ERROR();
1261 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
1262
1263 // Fill with blue
Olli Etuaho356f5162016-03-18 14:19:41 +02001264 FillWithRGBA<GLubyte>(16u * 16u, 0u, 0u, 255u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001265
1266 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1267 glGenerateMipmap(GL_TEXTURE_2D);
1268
1269 // Fill with green
Olli Etuaho356f5162016-03-18 14:19:41 +02001270 FillWithRGBA<GLubyte>(16u * 16u, 0u, 255u, 0u, 255u, pixels.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001271
1272 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1273 glGenerateMipmap(GL_TEXTURE_2D);
1274
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001275 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001276
1277 EXPECT_GL_NO_ERROR();
1278 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
1279}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001280
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001281// Test creating a FBO with a cube map render target, to test an ANGLE bug
1282// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001283TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001284{
1285 GLuint fbo;
1286 glGenFramebuffers(1, &fbo);
1287 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1288
1289 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1290 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1291
Corentin Wallez322653b2015-06-17 18:33:56 +02001292 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001293
1294 glDeleteFramebuffers(1, &fbo);
1295
1296 EXPECT_GL_NO_ERROR();
1297}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001298
1299// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001300TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001301{
1302 int width = getWindowWidth();
1303 int height = getWindowHeight();
1304
1305 GLuint tex2D;
1306 glGenTextures(1, &tex2D);
1307 glActiveTexture(GL_TEXTURE0);
1308 glBindTexture(GL_TEXTURE_2D, tex2D);
1309
1310 // Fill with red
1311 std::vector<GLubyte> pixels(3 * 16 * 16);
1312 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1313 {
1314 pixels[pixelId * 3 + 0] = 255;
1315 pixels[pixelId * 3 + 1] = 0;
1316 pixels[pixelId * 3 + 2] = 0;
1317 }
1318
1319 // ANGLE internally uses RGBA as the DirectX format for RGB images
1320 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1321 // The data is kept in a CPU-side image and the image is marked as dirty.
1322 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1323
1324 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1325 // glTexSubImage2D should take into account that the image is dirty.
1326 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1328 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1329
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001330 setUpProgram();
1331
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001332 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001333 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001334 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001335 glDeleteTextures(1, &tex2D);
1336 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001337 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001338
1339 // Validate that the region of the texture without data has an alpha of 1.0
1340 GLubyte pixel[4];
1341 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1342 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001343}
1344
1345// 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 +02001346TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001347{
1348 if (extensionEnabled("NV_pixel_buffer_object"))
1349 {
1350 int width = getWindowWidth();
1351 int height = getWindowHeight();
1352
1353 GLuint tex2D;
1354 glGenTextures(1, &tex2D);
1355 glActiveTexture(GL_TEXTURE0);
1356 glBindTexture(GL_TEXTURE_2D, tex2D);
1357
1358 // Fill with red
1359 std::vector<GLubyte> pixels(3 * 16 * 16);
1360 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1361 {
1362 pixels[pixelId * 3 + 0] = 255;
1363 pixels[pixelId * 3 + 1] = 0;
1364 pixels[pixelId * 3 + 2] = 0;
1365 }
1366
1367 // Read 16x16 region from red backbuffer to PBO
1368 GLuint pbo;
1369 glGenBuffers(1, &pbo);
1370 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1371 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1372
1373 // ANGLE internally uses RGBA as the DirectX format for RGB images
1374 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1375 // The data is kept in a CPU-side image and the image is marked as dirty.
1376 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1377
1378 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1379 // glTexSubImage2D should take into account that the image is dirty.
1380 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1381 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1382 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1383
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001384 setUpProgram();
1385
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001386 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001387 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001388 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001389 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001390 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001391 EXPECT_GL_NO_ERROR();
1392 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1393 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1394 }
1395}
Jamie Madillbc393df2015-01-29 13:46:07 -05001396
1397// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001398TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001399{
1400 testFloatCopySubImage(1, 1);
1401}
1402
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001403TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001404{
1405 testFloatCopySubImage(2, 1);
1406}
1407
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001408TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001409{
1410 testFloatCopySubImage(2, 2);
1411}
1412
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001413TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001414{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001415 if (IsIntel() && IsLinux())
1416 {
1417 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1418 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1419 return;
1420 }
1421
Jamie Madillbc393df2015-01-29 13:46:07 -05001422 testFloatCopySubImage(3, 1);
1423}
1424
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001425TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001426{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001427 if (IsIntel() && IsLinux())
1428 {
1429 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1430 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1431 return;
1432 }
1433
Jamie Madillbc393df2015-01-29 13:46:07 -05001434 testFloatCopySubImage(3, 2);
1435}
1436
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001437TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001438{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001439 if (IsIntel() && IsLinux())
1440 {
1441 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1442 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1443 return;
1444 }
1445
Austin Kinrossd544cc92016-01-11 15:26:42 -08001446 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001447 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001448 {
1449 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1450 return;
1451 }
1452
Jamie Madillbc393df2015-01-29 13:46:07 -05001453 testFloatCopySubImage(3, 3);
1454}
1455
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001456TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001457{
1458 testFloatCopySubImage(4, 1);
1459}
1460
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001461TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001462{
1463 testFloatCopySubImage(4, 2);
1464}
1465
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001466TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001467{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001468 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001469 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001470 {
1471 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1472 return;
1473 }
1474
Jamie Madillbc393df2015-01-29 13:46:07 -05001475 testFloatCopySubImage(4, 3);
1476}
1477
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001478TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001479{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001480 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001481 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001482 {
1483 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1484 return;
1485 }
1486
Jamie Madillbc393df2015-01-29 13:46:07 -05001487 testFloatCopySubImage(4, 4);
1488}
Austin Kinross07285142015-03-26 11:36:16 -07001489
1490// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1491// 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 +02001492TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001493{
1494 const int npotTexSize = 5;
1495 const int potTexSize = 4; // Should be less than npotTexSize
1496 GLuint tex2D;
1497
1498 if (extensionEnabled("GL_OES_texture_npot"))
1499 {
1500 // This test isn't applicable if texture_npot is enabled
1501 return;
1502 }
1503
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001504 setUpProgram();
1505
Austin Kinross07285142015-03-26 11:36:16 -07001506 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1507
Austin Kinross5faa15b2016-01-11 13:32:48 -08001508 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1509 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1510
Austin Kinross07285142015-03-26 11:36:16 -07001511 glActiveTexture(GL_TEXTURE0);
1512 glGenTextures(1, &tex2D);
1513 glBindTexture(GL_TEXTURE_2D, tex2D);
1514
1515 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1516 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1517 {
1518 pixels[pixelId] = 64;
1519 }
1520
1521 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1522 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1523
1524 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1525 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1526 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1527
1528 // Check that an NPOT texture on level 0 succeeds
1529 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1530 EXPECT_GL_NO_ERROR();
1531
1532 // Check that generateMipmap fails on NPOT
1533 glGenerateMipmap(GL_TEXTURE_2D);
1534 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1535
1536 // Check that nothing is drawn if filtering is not correct for NPOT
1537 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1538 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1539 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1540 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1541 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001542 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001543 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1544
1545 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1546 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1549 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001550 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001551 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1552
1553 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1554 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1555 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001556 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001557 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1558
1559 // Check that glTexImage2D for POT texture succeeds
1560 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1561 EXPECT_GL_NO_ERROR();
1562
1563 // Check that generateMipmap for an POT texture succeeds
1564 glGenerateMipmap(GL_TEXTURE_2D);
1565 EXPECT_GL_NO_ERROR();
1566
1567 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1568 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1569 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1570 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1572 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001573 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001574 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1575 EXPECT_GL_NO_ERROR();
1576}
Jamie Madillfa05f602015-05-07 13:47:11 -04001577
Austin Kinross08528e12015-10-07 16:24:40 -07001578// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1579// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001580TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001581{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001582 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1583 // 1278)
1584 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1585 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1586 {
1587 std::cout << "Test disabled on OpenGL." << std::endl;
1588 return;
1589 }
1590
Austin Kinross08528e12015-10-07 16:24:40 -07001591 glActiveTexture(GL_TEXTURE0);
1592 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1593
1594 // Create an 8x8 (i.e. power-of-two) texture.
1595 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1596 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1597 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1598 glGenerateMipmap(GL_TEXTURE_2D);
1599
1600 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1601 // This should always work, even if GL_OES_texture_npot isn't active.
1602 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1603
1604 EXPECT_GL_NO_ERROR();
1605}
1606
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001607// Test to check that texture completeness is determined correctly when the texture base level is
1608// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1609TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1610{
1611 glActiveTexture(GL_TEXTURE0);
1612 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1613 GLubyte texDataRed[4u * 4u * 4u];
Olli Etuaho356f5162016-03-18 14:19:41 +02001614 FillWithRGBA<GLubyte>(4u * 4u, 255u, 0u, 0u, 255u, texDataRed);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001615 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
1616 GLubyte texDataGreen[2u * 2u * 4u];
Olli Etuaho356f5162016-03-18 14:19:41 +02001617 FillWithRGBA<GLubyte>(2u * 2u, 0u, 255u, 0u, 255u, texDataGreen);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001618 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1619 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1620 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1621 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1622 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1623
1624 EXPECT_GL_NO_ERROR();
1625
1626 drawQuad(mProgram, "position", 0.5f);
1627
1628 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1629}
1630
Jamie Madill2453dbc2015-07-14 11:35:42 -04001631// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
1632// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
1633// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001634TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04001635{
1636 std::vector<GLubyte> pixelData;
1637 for (size_t count = 0; count < 5000; count++)
1638 {
1639 pixelData.push_back(0u);
1640 pixelData.push_back(255u);
1641 pixelData.push_back(0u);
1642 }
1643
1644 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001645 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001646 glUniform1i(mTextureArrayLocation, 0);
1647
1648 // The first draw worked correctly.
1649 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
1650
1651 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1652 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1653 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1654 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001655 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001656 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1657
1658 // The dimension of the respecification must match the original exactly to trigger the bug.
1659 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 +02001660 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001661 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1662
1663 ASSERT_GL_NO_ERROR();
1664}
1665
Olli Etuaho1a679902016-01-14 12:21:47 +02001666// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
1667// This test is needed especially to confirm that sampler registers get assigned correctly on
1668// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
1669TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
1670{
1671 glActiveTexture(GL_TEXTURE0);
1672 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1673 GLubyte texData[4];
1674 texData[0] = 0;
1675 texData[1] = 60;
1676 texData[2] = 0;
1677 texData[3] = 255;
1678 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1679
1680 glActiveTexture(GL_TEXTURE1);
1681 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1682 GLfloat depthTexData[1];
1683 depthTexData[0] = 0.5f;
1684 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1685 depthTexData);
1686
1687 glUseProgram(mProgram);
1688 glUniform1f(mDepthRefUniformLocation, 0.3f);
1689 glUniform1i(mTexture3DUniformLocation, 0);
1690 glUniform1i(mTextureShadowUniformLocation, 1);
1691
1692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1693 drawQuad(mProgram, "position", 0.5f);
1694 EXPECT_GL_NO_ERROR();
1695 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
1696 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
1697
1698 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
1699 drawQuad(mProgram, "position", 0.5f);
1700 EXPECT_GL_NO_ERROR();
1701 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
1702 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
1703}
1704
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001705// Test multiple different sampler types in the same shader.
1706// This test makes sure that even if sampler / texture registers get grouped together based on type
1707// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
1708// still has the right register index information for each ESSL sampler.
1709// The tested ESSL samplers have the following types in D3D11 HLSL:
1710// sampler2D: Texture2D + SamplerState
1711// samplerCube: TextureCube + SamplerState
1712// sampler2DShadow: Texture2D + SamplerComparisonState
1713// samplerCubeShadow: TextureCube + SamplerComparisonState
1714TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
1715{
1716 glActiveTexture(GL_TEXTURE0);
1717 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1718 GLubyte texData[4];
1719 texData[0] = 0;
1720 texData[1] = 0;
1721 texData[2] = 120;
1722 texData[3] = 255;
1723 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1724
1725 glActiveTexture(GL_TEXTURE1);
1726 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1727 texData[0] = 0;
1728 texData[1] = 90;
1729 texData[2] = 0;
1730 texData[3] = 255;
1731 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
1732 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1733 texData);
1734
1735 glActiveTexture(GL_TEXTURE2);
1736 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1738 GLfloat depthTexData[1];
1739 depthTexData[0] = 0.5f;
1740 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1741 depthTexData);
1742
1743 glActiveTexture(GL_TEXTURE3);
1744 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1745 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1746 depthTexData[0] = 0.2f;
1747 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1748 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
1749 depthTexData);
1750
1751 EXPECT_GL_NO_ERROR();
1752
1753 glUseProgram(mProgram);
1754 glUniform1f(mDepthRefUniformLocation, 0.3f);
1755 glUniform1i(mTexture2DUniformLocation, 0);
1756 glUniform1i(mTextureCubeUniformLocation, 1);
1757 glUniform1i(mTexture2DShadowUniformLocation, 2);
1758 glUniform1i(mTextureCubeShadowUniformLocation, 3);
1759
1760 drawQuad(mProgram, "position", 0.5f);
1761 EXPECT_GL_NO_ERROR();
1762 // The shader writes:
1763 // <texture 2d color> +
1764 // <cube map color> +
1765 // 0.25 * <comparison result (1.0)> +
1766 // 0.125 * <comparison result (0.0)>
1767 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
1768}
1769
Olli Etuahobce743a2016-01-15 17:18:28 +02001770// Test different base levels on textures accessed through the same sampler array.
1771// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
1772TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
1773{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001774 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02001775 {
1776 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
1777 return;
1778 }
1779 glActiveTexture(GL_TEXTURE0);
1780 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
1781 GLsizei size = 64;
1782 for (GLint level = 0; level < 7; ++level)
1783 {
1784 ASSERT_LT(0, size);
1785 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1786 nullptr);
1787 size = size / 2;
1788 }
1789 ASSERT_EQ(0, size);
1790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1791
1792 glActiveTexture(GL_TEXTURE1);
1793 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
1794 size = 128;
1795 for (GLint level = 0; level < 8; ++level)
1796 {
1797 ASSERT_LT(0, size);
1798 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1799 nullptr);
1800 size = size / 2;
1801 }
1802 ASSERT_EQ(0, size);
1803 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
1804 EXPECT_GL_NO_ERROR();
1805
1806 glUseProgram(mProgram);
1807 glUniform1i(mTexture0Location, 0);
1808 glUniform1i(mTexture1Location, 1);
1809
1810 drawQuad(mProgram, "position", 0.5f);
1811 EXPECT_GL_NO_ERROR();
1812 // Red channel: width of level 1 of texture A: 32.
1813 // Green channel: width of level 3 of texture B: 16.
1814 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
1815}
1816
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001817// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1818// ES 3.0.4 table 3.24
1819TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
1820{
1821 glActiveTexture(GL_TEXTURE0);
1822 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1823 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1824 EXPECT_GL_NO_ERROR();
1825
1826 drawQuad(mProgram, "position", 0.5f);
1827
1828 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1829}
1830
1831// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1832// ES 3.0.4 table 3.24
1833TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
1834{
1835 glActiveTexture(GL_TEXTURE0);
1836 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1837 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
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(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
1848{
1849 if (extensionEnabled("GL_OES_texture_float"))
1850 {
1851 glActiveTexture(GL_TEXTURE0);
1852 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1853 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
1854 EXPECT_GL_NO_ERROR();
1855
1856 drawQuad(mProgram, "position", 0.5f);
1857
1858 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1859 }
1860}
1861
1862// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1863// ES 3.0.4 table 3.24
1864TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
1865{
1866 if (extensionEnabled("GL_OES_texture_half_float"))
1867 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001868 if (IsNVIDIA() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001869 {
1870 std::cout << "Test skipped on NVIDIA" << std::endl;
1871 return;
1872 }
1873 glActiveTexture(GL_TEXTURE0);
1874 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1875 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
1876 nullptr);
1877 EXPECT_GL_NO_ERROR();
1878
1879 drawQuad(mProgram, "position", 0.5f);
1880
1881 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1882 }
1883}
1884
1885// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1886// ES 3.0.4 table 3.24
1887TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
1888{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001889 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001890 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001891 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001892 return;
1893 }
1894 glActiveTexture(GL_TEXTURE0);
1895 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1896 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
1897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1898 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1899 EXPECT_GL_NO_ERROR();
1900
1901 drawQuad(mProgram, "position", 0.5f);
1902
1903 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1904}
1905
1906// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1907// ES 3.0.4 table 3.24
1908TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
1909{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001910 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001911 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001912 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001913 return;
1914 }
1915 glActiveTexture(GL_TEXTURE0);
1916 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1917
1918 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
1919 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1920 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1921 EXPECT_GL_NO_ERROR();
1922
1923 drawQuad(mProgram, "position", 0.5f);
1924
1925 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1926}
1927
1928// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1929// ES 3.0.4 table 3.24
1930TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
1931{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001932 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001933 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001934 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001935 return;
1936 }
1937 glActiveTexture(GL_TEXTURE0);
1938 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1939 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
1940 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1941 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1942 EXPECT_GL_NO_ERROR();
1943
1944 drawQuad(mProgram, "position", 0.5f);
1945
1946 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1947}
1948
1949// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1950// ES 3.0.4 table 3.24
1951TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
1952{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001953 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001954 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001955 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001956 return;
1957 }
1958 glActiveTexture(GL_TEXTURE0);
1959 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1960 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
1961 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1962 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1963 EXPECT_GL_NO_ERROR();
1964
1965 drawQuad(mProgram, "position", 0.5f);
1966
1967 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1968}
1969
1970// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1971// ES 3.0.4 table 3.24
1972TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
1973{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001974 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001975 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001976 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001977 return;
1978 }
1979 glActiveTexture(GL_TEXTURE0);
1980 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1981 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
1982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1984 EXPECT_GL_NO_ERROR();
1985
1986 drawQuad(mProgram, "position", 0.5f);
1987
1988 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1989}
1990
1991// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1992// ES 3.0.4 table 3.24
1993TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
1994{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001995 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001996 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05001997 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001998 return;
1999 }
2000 glActiveTexture(GL_TEXTURE0);
2001 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2002 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
2003 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2004 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2005 EXPECT_GL_NO_ERROR();
2006
2007 drawQuad(mProgram, "position", 0.5f);
2008
2009 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2010}
2011
2012// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2013// ES 3.0.4 table 3.24
2014TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
2015{
2016 glActiveTexture(GL_TEXTURE0);
2017 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2018 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
2019 EXPECT_GL_NO_ERROR();
2020
2021 drawQuad(mProgram, "position", 0.5f);
2022
2023 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2024}
2025
2026// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2027// ES 3.0.4 table 3.24
2028TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
2029{
2030 glActiveTexture(GL_TEXTURE0);
2031 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2032 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
2033 nullptr);
2034 EXPECT_GL_NO_ERROR();
2035
2036 drawQuad(mProgram, "position", 0.5f);
2037
2038 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2039}
2040
2041// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2042// ES 3.0.4 table 3.24
2043TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
2044{
2045 glActiveTexture(GL_TEXTURE0);
2046 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2047 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
2048 EXPECT_GL_NO_ERROR();
2049
2050 drawQuad(mProgram, "position", 0.5f);
2051
2052 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2053}
2054
2055// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2056// ES 3.0.4 table 3.24
2057TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
2058{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002059 if (IsIntel() && IsLinux())
2060 {
2061 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2062 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2063 return;
2064 }
2065
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002066 glActiveTexture(GL_TEXTURE0);
2067 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2068 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2069 EXPECT_GL_NO_ERROR();
2070
2071 drawQuad(mProgram, "position", 0.5f);
2072
2073 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2074}
2075
Olli Etuaho96963162016-03-21 11:54:33 +02002076// Use a sampler in a uniform struct.
2077TEST_P(SamplerInStructTest, SamplerInStruct)
2078{
2079 runSamplerInStructTest();
2080}
2081
2082// Use a sampler in a uniform struct that's passed as a function parameter.
2083TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2084{
2085 runSamplerInStructTest();
2086}
2087
2088// Use a sampler in a uniform struct array with a struct from the array passed as a function
2089// parameter.
2090TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2091{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002092 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2093 {
2094 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2095 return;
2096 }
Olli Etuaho96963162016-03-21 11:54:33 +02002097 runSamplerInStructTest();
2098}
2099
2100// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2101// parameter.
2102TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2103{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002104 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2105 {
2106 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2107 return;
2108 }
Olli Etuaho96963162016-03-21 11:54:33 +02002109 runSamplerInStructTest();
2110}
2111
2112// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2113// similarly named uniform.
2114TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2115{
2116 runSamplerInStructTest();
2117}
2118
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002119class TextureLimitsTest : public ANGLETest
2120{
2121 protected:
2122 struct RGBA8
2123 {
2124 uint8_t R, G, B, A;
2125 };
2126
2127 TextureLimitsTest()
2128 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2129 {
2130 setWindowWidth(128);
2131 setWindowHeight(128);
2132 setConfigRedBits(8);
2133 setConfigGreenBits(8);
2134 setConfigBlueBits(8);
2135 setConfigAlphaBits(8);
2136 }
2137
2138 ~TextureLimitsTest()
2139 {
2140 if (mProgram != 0)
2141 {
2142 glDeleteProgram(mProgram);
2143 mProgram = 0;
2144
2145 if (!mTextures.empty())
2146 {
2147 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2148 }
2149 }
2150 }
2151
2152 void SetUp() override
2153 {
2154 ANGLETest::SetUp();
2155
2156 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2157 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2158 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2159
2160 ASSERT_GL_NO_ERROR();
2161 }
2162
2163 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2164 GLint vertexTextureCount,
2165 GLint vertexActiveTextureCount,
2166 const std::string &fragPrefix,
2167 GLint fragmentTextureCount,
2168 GLint fragmentActiveTextureCount)
2169 {
2170 std::stringstream vertexShaderStr;
2171 vertexShaderStr << "attribute vec2 position;\n"
2172 << "varying vec4 color;\n"
2173 << "varying vec2 texCoord;\n";
2174
2175 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2176 {
2177 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2178 }
2179
2180 vertexShaderStr << "void main() {\n"
2181 << " gl_Position = vec4(position, 0, 1);\n"
2182 << " texCoord = (position * 0.5) + 0.5;\n"
2183 << " color = vec4(0);\n";
2184
2185 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2186 {
2187 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2188 << ", texCoord);\n";
2189 }
2190
2191 vertexShaderStr << "}";
2192
2193 std::stringstream fragmentShaderStr;
2194 fragmentShaderStr << "varying mediump vec4 color;\n"
2195 << "varying mediump vec2 texCoord;\n";
2196
2197 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2198 {
2199 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2200 }
2201
2202 fragmentShaderStr << "void main() {\n"
2203 << " gl_FragColor = color;\n";
2204
2205 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2206 {
2207 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2208 << ", texCoord);\n";
2209 }
2210
2211 fragmentShaderStr << "}";
2212
2213 const std::string &vertexShaderSource = vertexShaderStr.str();
2214 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2215
2216 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2217 }
2218
2219 RGBA8 getPixel(GLint texIndex)
2220 {
2221 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2222 0, 255u};
2223 return pixel;
2224 }
2225
2226 void initTextures(GLint tex2DCount, GLint texCubeCount)
2227 {
2228 GLint totalCount = tex2DCount + texCubeCount;
2229 mTextures.assign(totalCount, 0);
2230 glGenTextures(totalCount, &mTextures[0]);
2231 ASSERT_GL_NO_ERROR();
2232
2233 std::vector<RGBA8> texData(16 * 16);
2234
2235 GLint texIndex = 0;
2236 for (; texIndex < tex2DCount; ++texIndex)
2237 {
2238 texData.assign(texData.size(), getPixel(texIndex));
2239 glActiveTexture(GL_TEXTURE0 + texIndex);
2240 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2241 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2242 &texData[0]);
2243 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2246 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2247 }
2248
2249 ASSERT_GL_NO_ERROR();
2250
2251 for (; texIndex < texCubeCount; ++texIndex)
2252 {
2253 texData.assign(texData.size(), getPixel(texIndex));
2254 glActiveTexture(GL_TEXTURE0 + texIndex);
2255 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2256 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2257 GL_UNSIGNED_BYTE, &texData[0]);
2258 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2259 GL_UNSIGNED_BYTE, &texData[0]);
2260 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2261 GL_UNSIGNED_BYTE, &texData[0]);
2262 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2263 GL_UNSIGNED_BYTE, &texData[0]);
2264 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2265 GL_UNSIGNED_BYTE, &texData[0]);
2266 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2267 GL_UNSIGNED_BYTE, &texData[0]);
2268 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2269 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2270 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2271 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2272 }
2273
2274 ASSERT_GL_NO_ERROR();
2275 }
2276
2277 void testWithTextures(GLint vertexTextureCount,
2278 const std::string &vertexTexturePrefix,
2279 GLint fragmentTextureCount,
2280 const std::string &fragmentTexturePrefix)
2281 {
2282 // Generate textures
2283 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2284
2285 glUseProgram(mProgram);
2286 RGBA8 expectedSum = {0};
2287 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2288 {
2289 std::stringstream uniformNameStr;
2290 uniformNameStr << vertexTexturePrefix << texIndex;
2291 const std::string &uniformName = uniformNameStr.str();
2292 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2293 ASSERT_NE(-1, location);
2294
2295 glUniform1i(location, texIndex);
2296 RGBA8 contribution = getPixel(texIndex);
2297 expectedSum.R += contribution.R;
2298 expectedSum.G += contribution.G;
2299 }
2300
2301 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2302 {
2303 std::stringstream uniformNameStr;
2304 uniformNameStr << fragmentTexturePrefix << texIndex;
2305 const std::string &uniformName = uniformNameStr.str();
2306 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2307 ASSERT_NE(-1, location);
2308
2309 glUniform1i(location, texIndex + vertexTextureCount);
2310 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
2311 expectedSum.R += contribution.R;
2312 expectedSum.G += contribution.G;
2313 }
2314
2315 ASSERT_GE(256u, expectedSum.G);
2316
2317 drawQuad(mProgram, "position", 0.5f);
2318 ASSERT_GL_NO_ERROR();
2319 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
2320 }
2321
2322 GLuint mProgram;
2323 std::vector<GLuint> mTextures;
2324 GLint mMaxVertexTextures;
2325 GLint mMaxFragmentTextures;
2326 GLint mMaxCombinedTextures;
2327};
2328
2329// Test rendering with the maximum vertex texture units.
2330TEST_P(TextureLimitsTest, MaxVertexTextures)
2331{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002332 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002333 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002334 {
2335 std::cout << "Test skipped on Intel." << std::endl;
2336 return;
2337 }
2338
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002339 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
2340 ASSERT_NE(0u, mProgram);
2341 ASSERT_GL_NO_ERROR();
2342
2343 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2344}
2345
2346// Test rendering with the maximum fragment texture units.
2347TEST_P(TextureLimitsTest, MaxFragmentTextures)
2348{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002349 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002350 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002351 {
2352 std::cout << "Test skipped on Intel." << std::endl;
2353 return;
2354 }
2355
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002356 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
2357 ASSERT_NE(0u, mProgram);
2358 ASSERT_GL_NO_ERROR();
2359
2360 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
2361}
2362
2363// Test rendering with maximum combined texture units.
2364TEST_P(TextureLimitsTest, MaxCombinedTextures)
2365{
Jamie Madill412f17d2015-09-25 08:43:54 -04002366 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002367 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04002368 {
2369 std::cout << "Test skipped on Intel." << std::endl;
2370 return;
2371 }
2372
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002373 GLint vertexTextures = mMaxVertexTextures;
2374
2375 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
2376 {
2377 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
2378 }
2379
2380 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
2381 mMaxFragmentTextures, mMaxFragmentTextures);
2382 ASSERT_NE(0u, mProgram);
2383 ASSERT_GL_NO_ERROR();
2384
2385 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
2386}
2387
2388// Negative test for exceeding the number of vertex textures
2389TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
2390{
2391 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
2392 0);
2393 ASSERT_EQ(0u, mProgram);
2394}
2395
2396// Negative test for exceeding the number of fragment textures
2397TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
2398{
2399 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
2400 mMaxFragmentTextures + 1);
2401 ASSERT_EQ(0u, mProgram);
2402}
2403
2404// Test active vertex textures under the limit, but excessive textures specified.
2405TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
2406{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002407 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002408 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002409 {
2410 std::cout << "Test skipped on Intel." << std::endl;
2411 return;
2412 }
2413
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002414 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
2415 ASSERT_NE(0u, mProgram);
2416 ASSERT_GL_NO_ERROR();
2417
2418 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2419}
2420
2421// Test active fragment textures under the limit, but excessive textures specified.
2422TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
2423{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002424 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05002425 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002426 {
2427 std::cout << "Test skipped on Intel." << std::endl;
2428 return;
2429 }
2430
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002431 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
2432 mMaxFragmentTextures);
2433 ASSERT_NE(0u, mProgram);
2434 ASSERT_GL_NO_ERROR();
2435
2436 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
2437}
2438
2439// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002440// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002441TEST_P(TextureLimitsTest, TextureTypeConflict)
2442{
2443 const std::string &vertexShader =
2444 "attribute vec2 position;\n"
2445 "varying float color;\n"
2446 "uniform sampler2D tex2D;\n"
2447 "uniform samplerCube texCube;\n"
2448 "void main() {\n"
2449 " gl_Position = vec4(position, 0, 1);\n"
2450 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2451 " color = texture2D(tex2D, texCoord).x;\n"
2452 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
2453 "}";
2454 const std::string &fragmentShader =
2455 "varying mediump float color;\n"
2456 "void main() {\n"
2457 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2458 "}";
2459
2460 mProgram = CompileProgram(vertexShader, fragmentShader);
2461 ASSERT_NE(0u, mProgram);
2462
2463 initTextures(1, 0);
2464
2465 glUseProgram(mProgram);
2466 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2467 ASSERT_NE(-1, tex2DLocation);
2468 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
2469 ASSERT_NE(-1, texCubeLocation);
2470
2471 glUniform1i(tex2DLocation, 0);
2472 glUniform1i(texCubeLocation, 0);
2473 ASSERT_GL_NO_ERROR();
2474
2475 drawQuad(mProgram, "position", 0.5f);
2476 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2477}
2478
2479// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002480// TODO(jmadill): Possibly adjust the test according to the spec:
2481// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
2482// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002483TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
2484{
2485 const std::string &vertexShader =
2486 "attribute vec2 position;\n"
2487 "varying float color;\n"
2488 "uniform sampler2D tex2D;\n"
2489 "void main() {\n"
2490 " gl_Position = vec4(position, 0, 1);\n"
2491 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2492 " color = texture2D(tex2D, texCoord).x;\n"
2493 "}";
2494 const std::string &fragmentShader =
2495 "varying mediump float color;\n"
2496 "void main() {\n"
2497 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2498 "}";
2499
2500 mProgram = CompileProgram(vertexShader, fragmentShader);
2501 ASSERT_NE(0u, mProgram);
2502
2503 glUseProgram(mProgram);
2504 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2505 ASSERT_NE(-1, tex2DLocation);
2506
2507 glUniform1i(tex2DLocation, mMaxCombinedTextures);
2508 ASSERT_GL_NO_ERROR();
2509
2510 drawQuad(mProgram, "position", 0.5f);
2511 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2512}
2513
Jamie Madillfa05f602015-05-07 13:47:11 -04002514// 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 +02002515// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05002516ANGLE_INSTANTIATE_TEST(Texture2DTest,
2517 ES2_D3D9(),
2518 ES2_D3D11(),
2519 ES2_D3D11_FL9_3(),
2520 ES2_OPENGL(),
2521 ES2_OPENGLES());
2522ANGLE_INSTANTIATE_TEST(TextureCubeTest,
2523 ES2_D3D9(),
2524 ES2_D3D11(),
2525 ES2_D3D11_FL9_3(),
2526 ES2_OPENGL(),
2527 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002528ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
2529 ES2_D3D9(),
2530 ES2_D3D11(),
2531 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002532 ES2_OPENGL(),
2533 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002534ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
2535 ES2_D3D9(),
2536 ES2_D3D11(),
2537 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002538 ES2_OPENGL(),
2539 ES2_OPENGLES());
2540ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
2541 ES2_D3D9(),
2542 ES2_D3D11(),
2543 ES2_D3D11_FL9_3(),
2544 ES2_OPENGL(),
2545 ES2_OPENGLES());
2546ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
2547 ES2_D3D9(),
2548 ES2_D3D11(),
2549 ES2_D3D11_FL9_3(),
2550 ES2_OPENGL(),
2551 ES2_OPENGLES());
2552ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002553ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2554ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
2555 ES3_D3D11(),
2556 ES3_OPENGL(),
2557 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002558ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
2559 ES3_D3D11(),
2560 ES3_OPENGL(),
2561 ES3_OPENGLES());
2562ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2563ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02002564ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02002565ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
2566 ES2_D3D11(),
2567 ES2_D3D11_FL9_3(),
2568 ES2_D3D9(),
2569 ES2_OPENGL(),
2570 ES2_OPENGLES());
2571ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
2572 ES2_D3D11(),
2573 ES2_D3D11_FL9_3(),
2574 ES2_D3D9(),
2575 ES2_OPENGL(),
2576 ES2_OPENGLES());
2577ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
2578 ES2_D3D11(),
2579 ES2_D3D11_FL9_3(),
2580 ES2_D3D9(),
2581 ES2_OPENGL(),
2582 ES2_OPENGLES());
2583ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
2584 ES2_D3D11(),
2585 ES2_D3D11_FL9_3(),
2586 ES2_D3D9(),
2587 ES2_OPENGL(),
2588 ES2_OPENGLES());
2589ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
2590 ES2_D3D11(),
2591 ES2_D3D11_FL9_3(),
2592 ES2_D3D9(),
2593 ES2_OPENGL(),
2594 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002595ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04002596
2597} // namespace