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