blob: d4afbb1ed06ebf4078920076384fba43ec78646c [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
46 void SetUp() override
47 {
48 ANGLETest::SetUp();
49 const std::string vertexShaderSource = getVertexShaderSource();
50 const std::string fragmentShaderSource = getFragmentShaderSource();
51
52 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
53 ASSERT_NE(0u, mProgram);
54 ASSERT_GL_NO_ERROR();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020055
56 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020057 }
58
59 void TearDown() override
60 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020061 glBindFramebuffer(GL_FRAMEBUFFER, 0);
62 glDeleteFramebuffers(1, &mFramebuffer);
63 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020064 glDeleteProgram(mProgram);
65 ANGLETest::TearDown();
66 }
67
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020068 void setUpFramebuffer()
69 {
70 // We use an FBO to work around an issue where the default framebuffer applies SRGB
71 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
72 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
73 // section 4.4 says that the format of the default framebuffer is entirely up to the window
74 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
75 // SRGB conversion like desktop GL does.
76 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
77 glGenFramebuffers(1, &mFramebuffer);
78 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
79
80 glGenTextures(1, &mFramebufferColorTexture);
81 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
82 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
83 GL_UNSIGNED_BYTE, nullptr);
84 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
85 mFramebufferColorTexture, 0);
86 ASSERT_GL_NO_ERROR();
87 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
88 glBindTexture(GL_TEXTURE_2D, 0);
89 }
90
Olli Etuaho4a8329f2016-01-11 17:12:57 +020091 // Returns the created texture ID.
92 GLuint create2DTexture()
93 {
94 GLuint texture2D;
95 glGenTextures(1, &texture2D);
96 glBindTexture(GL_TEXTURE_2D, texture2D);
97 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
98 EXPECT_GL_NO_ERROR();
99 return texture2D;
100 }
101
102 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200103 GLuint mFramebuffer;
104
105 private:
106 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200107};
108
109class Texture2DTest : public TexCoordDrawTest
110{
111 protected:
112 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
113
114 std::string getFragmentShaderSource() override
115 {
116 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400117 (
118 precision highp float;
119 uniform sampler2D tex;
120 varying vec2 texcoord;
121
122 void main()
123 {
124 gl_FragColor = texture2D(tex, texcoord);
125 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200126 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400127 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200128 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400129
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200130 void SetUp() override
131 {
132 TexCoordDrawTest::SetUp();
133 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400134
Jamie Madill9aca0592014-10-06 16:26:59 -0400135 ASSERT_GL_NO_ERROR();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200136
137 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex");
138 ASSERT_NE(-1, mTexture2DUniformLocation);
Jamie Madillf67115c2014-04-22 13:14:05 -0400139 }
140
Jamie Madillfa05f602015-05-07 13:47:11 -0400141 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400142 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400143 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200144 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400145 }
146
Jamie Madillbc393df2015-01-29 13:46:07 -0500147 // Tests CopyTexSubImage with floating point textures of various formats.
148 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
149 {
Geoff Langbde666a2015-04-07 17:17:08 -0400150 // TODO(jmadill): Figure out why this is broken on Intel D3D11
151 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
152 {
153 std::cout << "Test skipped on Intel D3D11." << std::endl;
154 return;
155 }
156
Geoff Langfbfa47c2015-03-31 11:26:00 -0400157 if (getClientVersion() < 3)
158 {
159 if (!extensionEnabled("GL_OES_texture_float"))
160 {
161 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
162 return;
163 }
164
165 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
166 {
167 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
168 return;
169 }
170 }
171
Jamie Madillbc393df2015-01-29 13:46:07 -0500172 GLfloat sourceImageData[4][16] =
173 {
174 { // R
175 1.0f,
176 0.0f,
177 0.0f,
178 1.0f
179 },
180 { // RG
181 1.0f, 0.0f,
182 0.0f, 1.0f,
183 0.0f, 0.0f,
184 1.0f, 1.0f
185 },
186 { // RGB
187 1.0f, 0.0f, 0.0f,
188 0.0f, 1.0f, 0.0f,
189 0.0f, 0.0f, 1.0f,
190 1.0f, 1.0f, 0.0f
191 },
192 { // RGBA
193 1.0f, 0.0f, 0.0f, 1.0f,
194 0.0f, 1.0f, 0.0f, 1.0f,
195 0.0f, 0.0f, 1.0f, 1.0f,
196 1.0f, 1.0f, 0.0f, 1.0f
197 },
198 };
199
200 GLenum imageFormats[] =
201 {
202 GL_R32F,
203 GL_RG32F,
204 GL_RGB32F,
205 GL_RGBA32F,
206 };
207
208 GLenum sourceUnsizedFormats[] =
209 {
210 GL_RED,
211 GL_RG,
212 GL_RGB,
213 GL_RGBA,
214 };
215
216 GLuint textures[2];
217
218 glGenTextures(2, textures);
219
220 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
221 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
222 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
223 GLenum destImageFormat = imageFormats[destImageChannels - 1];
224
225 glBindTexture(GL_TEXTURE_2D, textures[0]);
226 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
229 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
230
hendrikwb27f79a2015-03-04 11:26:46 -0800231 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500232 {
233 // This is not supported
234 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
235 }
236 else
237 {
238 ASSERT_GL_NO_ERROR();
239 }
240
241 GLuint fbo;
242 glGenFramebuffers(1, &fbo);
243 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
244 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
245
246 glBindTexture(GL_TEXTURE_2D, textures[1]);
247 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
250
251 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
252 ASSERT_GL_NO_ERROR();
253
254 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200255 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500256
257 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
258
259 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
260 if (testImageChannels > 1)
261 {
262 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
263 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
264 if (testImageChannels > 2)
265 {
266 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
267 }
268 }
269
270 glDeleteFramebuffers(1, &fbo);
271 glDeleteTextures(2, textures);
272
273 ASSERT_GL_NO_ERROR();
274 }
275
Jamie Madilld4cfa572014-07-08 10:00:32 -0400276 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400277 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400278};
279
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200280class Texture2DTestES3 : public Texture2DTest
281{
282 protected:
283 Texture2DTestES3() : Texture2DTest() {}
284
285 std::string getVertexShaderSource() override
286 {
287 return std::string(
288 "#version 300 es\n"
289 "out vec2 texcoord;\n"
290 "in vec4 position;\n"
291 "void main()\n"
292 "{\n"
293 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
294 " texcoord = (position.xy * 0.5) + 0.5;\n"
295 "}\n");
296 }
297
298 std::string getFragmentShaderSource() override
299 {
300 return std::string(
301 "#version 300 es\n"
302 "precision highp float;\n"
303 "uniform highp sampler2D tex;\n"
304 "in vec2 texcoord;\n"
305 "out vec4 fragColor;\n"
306 "void main()\n"
307 "{\n"
308 " fragColor = texture(tex, texcoord);\n"
309 "}\n");
310 }
311};
312
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200313class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
314{
315 protected:
316 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
317
318 std::string getVertexShaderSource() override
319 {
320 return std::string(
321 "#version 300 es\n"
322 "out vec2 texcoord;\n"
323 "in vec4 position;\n"
324 "void main()\n"
325 "{\n"
326 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
327 " texcoord = (position.xy * 0.5) + 0.5;\n"
328 "}\n");
329 }
330
331 std::string getFragmentShaderSource() override
332 {
333 return std::string(
334 "#version 300 es\n"
335 "precision highp float;\n"
336 "uniform highp isampler2D tex;\n"
337 "in vec2 texcoord;\n"
338 "out vec4 fragColor;\n"
339 "void main()\n"
340 "{\n"
341 " vec4 green = vec4(0, 1, 0, 1);\n"
342 " vec4 black = vec4(0, 0, 0, 0);\n"
343 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
344 "}\n");
345 }
346};
347
348class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
349{
350 protected:
351 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
352
353 std::string getVertexShaderSource() override
354 {
355 return std::string(
356 "#version 300 es\n"
357 "out vec2 texcoord;\n"
358 "in vec4 position;\n"
359 "void main()\n"
360 "{\n"
361 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
362 " texcoord = (position.xy * 0.5) + 0.5;\n"
363 "}\n");
364 }
365
366 std::string getFragmentShaderSource() override
367 {
368 return std::string(
369 "#version 300 es\n"
370 "precision highp float;\n"
371 "uniform highp usampler2D tex;\n"
372 "in vec2 texcoord;\n"
373 "out vec4 fragColor;\n"
374 "void main()\n"
375 "{\n"
376 " vec4 green = vec4(0, 1, 0, 1);\n"
377 " vec4 black = vec4(0, 0, 0, 0);\n"
378 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
379 "}\n");
380 }
381};
382
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200383class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400384{
385 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200386 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
387
388 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400389 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200390 return std::string(SHADER_SOURCE
391 (
392 precision highp float;
393 attribute vec4 position;
394 varying vec2 texcoord;
395
396 uniform vec2 drawScale;
397
398 void main()
399 {
400 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
401 texcoord = (position.xy * 0.5) + 0.5;
402 }
403 )
404 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400405 }
406
407 void SetUp() override
408 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200409 Texture2DTest::SetUp();
410 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
411 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400412
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200413 glUseProgram(mProgram);
414 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
415 glUseProgram(0);
416 ASSERT_GL_NO_ERROR();
417 }
418
419 GLint mDrawScaleUniformLocation;
420};
421
Olli Etuaho4644a202016-01-12 15:12:53 +0200422class Sampler2DAsFunctionParameterTest : public Texture2DTest
423{
424 protected:
425 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
426
427 std::string getFragmentShaderSource() override
428 {
429 return std::string(SHADER_SOURCE
430 (
431 precision highp float;
432 uniform sampler2D tex;
433 varying vec2 texcoord;
434
435 vec4 computeFragColor(sampler2D aTex)
436 {
437 return texture2D(aTex, texcoord);
438 }
439
440 void main()
441 {
442 gl_FragColor = computeFragColor(tex);
443 }
444 )
445 );
446 }
447};
448
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200449class TextureCubeTest : public TexCoordDrawTest
450{
451 protected:
452 TextureCubeTest()
453 : TexCoordDrawTest(),
454 mTexture2D(0),
455 mTextureCube(0),
456 mTexture2DUniformLocation(-1),
457 mTextureCubeUniformLocation(-1)
458 {
459 }
460
461 std::string getFragmentShaderSource() override
462 {
463 return std::string(SHADER_SOURCE
464 (
465 precision highp float;
466 uniform sampler2D tex2D;
467 uniform samplerCube texCube;
468 varying vec2 texcoord;
469
470 void main()
471 {
472 gl_FragColor = texture2D(tex2D, texcoord);
473 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
474 }
475 )
476 );
477 }
478
479 void SetUp() override
480 {
481 TexCoordDrawTest::SetUp();
482
483 glGenTextures(1, &mTextureCube);
484 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
485 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
486 EXPECT_GL_NO_ERROR();
487
488 mTexture2D = create2DTexture();
489
490 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
491 ASSERT_NE(-1, mTexture2DUniformLocation);
492 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
493 ASSERT_NE(-1, mTextureCubeUniformLocation);
494 }
495
496 void TearDown() override
497 {
498 glDeleteTextures(1, &mTextureCube);
499 TexCoordDrawTest::TearDown();
500 }
501
502 GLuint mTexture2D;
503 GLuint mTextureCube;
504 GLint mTexture2DUniformLocation;
505 GLint mTextureCubeUniformLocation;
506};
507
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200508class SamplerArrayTest : public TexCoordDrawTest
509{
510 protected:
511 SamplerArrayTest()
512 : TexCoordDrawTest(),
513 mTexture2DA(0),
514 mTexture2DB(0),
515 mTexture0UniformLocation(-1),
516 mTexture1UniformLocation(-1)
517 {
518 }
519
520 std::string getFragmentShaderSource() override
521 {
522 return std::string(SHADER_SOURCE
523 (
524 precision mediump float;
525 uniform highp sampler2D tex2DArray[2];
526 varying vec2 texcoord;
527 void main()
528 {
529 gl_FragColor = texture2D(tex2DArray[0], texcoord);
530 gl_FragColor += texture2D(tex2DArray[1], texcoord);
531 }
532 )
533 );
534 }
535
536 void SetUp() override
537 {
538 TexCoordDrawTest::SetUp();
539
540 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
541 ASSERT_NE(-1, mTexture0UniformLocation);
542 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
543 ASSERT_NE(-1, mTexture1UniformLocation);
544
545 mTexture2DA = create2DTexture();
546 mTexture2DB = create2DTexture();
547 ASSERT_GL_NO_ERROR();
548 }
549
550 void TearDown() override
551 {
552 glDeleteTextures(1, &mTexture2DA);
553 glDeleteTextures(1, &mTexture2DB);
554 TexCoordDrawTest::TearDown();
555 }
556
557 void testSamplerArrayDraw()
558 {
559 GLubyte texData[4];
560 texData[0] = 0;
561 texData[1] = 60;
562 texData[2] = 0;
563 texData[3] = 255;
564
565 glActiveTexture(GL_TEXTURE0);
566 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
567 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
568
569 texData[1] = 120;
570 glActiveTexture(GL_TEXTURE1);
571 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
572 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
573 EXPECT_GL_ERROR(GL_NO_ERROR);
574
575 glUseProgram(mProgram);
576 glUniform1i(mTexture0UniformLocation, 0);
577 glUniform1i(mTexture1UniformLocation, 1);
578 drawQuad(mProgram, "position", 0.5f);
579 EXPECT_GL_NO_ERROR();
580
581 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
582 }
583
584 GLuint mTexture2DA;
585 GLuint mTexture2DB;
586 GLint mTexture0UniformLocation;
587 GLint mTexture1UniformLocation;
588};
589
590
591class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
592{
593 protected:
594 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
595
596 std::string getFragmentShaderSource() override
597 {
598 return std::string(SHADER_SOURCE
599 (
600 precision mediump float;
601 uniform highp sampler2D tex2DArray[2];
602 varying vec2 texcoord;
603
604 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
605 {
606 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
607 }
608
609 void main()
610 {
611 gl_FragColor = computeFragColor(tex2DArray);
612 }
613 )
614 );
615 }
616};
617
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200618class Texture2DArrayTestES3 : public TexCoordDrawTest
619{
620 protected:
621 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
622
623 std::string getVertexShaderSource() override
624 {
625 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400626 "#version 300 es\n"
627 "out vec2 texcoord;\n"
628 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200629 "void main()\n"
630 "{\n"
631 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
632 " texcoord = (position.xy * 0.5) + 0.5;\n"
633 "}\n");
634 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400635
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200636 std::string getFragmentShaderSource() override
637 {
638 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400639 "#version 300 es\n"
640 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200641 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400642 "in vec2 texcoord;\n"
643 "out vec4 fragColor;\n"
644 "void main()\n"
645 "{\n"
646 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200647 "}\n");
648 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400649
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200650 void SetUp() override
651 {
652 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400653
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200654 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400655 ASSERT_NE(-1, mTextureArrayLocation);
656
657 glGenTextures(1, &m2DArrayTexture);
658 ASSERT_GL_NO_ERROR();
659 }
660
661 void TearDown() override
662 {
663 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200664 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400665 }
666
667 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400668 GLint mTextureArrayLocation;
669};
670
Olli Etuahobce743a2016-01-15 17:18:28 +0200671class TextureSizeTextureArrayTest : public TexCoordDrawTest
672{
673 protected:
674 TextureSizeTextureArrayTest()
675 : TexCoordDrawTest(),
676 mTexture2DA(0),
677 mTexture2DB(0),
678 mTexture0Location(-1),
679 mTexture1Location(-1)
680 {
681 }
682
683 std::string getVertexShaderSource() override
684 {
685 return std::string(
686 "#version 300 es\n"
687 "in vec4 position;\n"
688 "void main()\n"
689 "{\n"
690 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
691 "}\n");
692 }
693
694 std::string getFragmentShaderSource() override
695 {
696 return std::string(
697 "#version 300 es\n"
698 "precision highp float;\n"
699 "uniform highp sampler2D tex2DArray[2];\n"
700 "out vec4 fragColor;\n"
701 "void main()\n"
702 "{\n"
703 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
704 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
705 " fragColor = vec4(red, green, 0.0, 1.0);\n"
706 "}\n");
707 }
708
709 void SetUp() override
710 {
711 TexCoordDrawTest::SetUp();
712
713 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
714 ASSERT_NE(-1, mTexture0Location);
715 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
716 ASSERT_NE(-1, mTexture1Location);
717
718 mTexture2DA = create2DTexture();
719 mTexture2DB = create2DTexture();
720 ASSERT_GL_NO_ERROR();
721 }
722
723 void TearDown() override
724 {
725 glDeleteTextures(1, &mTexture2DA);
726 glDeleteTextures(1, &mTexture2DB);
727 TexCoordDrawTest::TearDown();
728 }
729
730 GLuint mTexture2DA;
731 GLuint mTexture2DB;
732 GLint mTexture0Location;
733 GLint mTexture1Location;
734};
735
Olli Etuaho1a679902016-01-14 12:21:47 +0200736class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
737{
738 protected:
739 ShadowSamplerPlusSampler3DTestES3()
740 : TexCoordDrawTest(),
741 mTextureShadow(0),
742 mTexture3D(0),
743 mTextureShadowUniformLocation(-1),
744 mTexture3DUniformLocation(-1),
745 mDepthRefUniformLocation(-1)
746 {
747 }
748
749 std::string getVertexShaderSource() override
750 {
751 return std::string(
752 "#version 300 es\n"
753 "out vec2 texcoord;\n"
754 "in vec4 position;\n"
755 "void main()\n"
756 "{\n"
757 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
758 " texcoord = (position.xy * 0.5) + 0.5;\n"
759 "}\n");
760 }
761
762 std::string getFragmentShaderSource() override
763 {
764 return std::string(
765 "#version 300 es\n"
766 "precision highp float;\n"
767 "uniform highp sampler2DShadow tex2DShadow;\n"
768 "uniform highp sampler3D tex3D;\n"
769 "in vec2 texcoord;\n"
770 "uniform float depthRef;\n"
771 "out vec4 fragColor;\n"
772 "void main()\n"
773 "{\n"
774 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
775 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
776 "}\n");
777 }
778
779 void SetUp() override
780 {
781 TexCoordDrawTest::SetUp();
782
783 glGenTextures(1, &mTexture3D);
784
785 glGenTextures(1, &mTextureShadow);
786 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
787 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
788
789 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
790 ASSERT_NE(-1, mTextureShadowUniformLocation);
791 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
792 ASSERT_NE(-1, mTexture3DUniformLocation);
793 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
794 ASSERT_NE(-1, mDepthRefUniformLocation);
795 }
796
797 void TearDown() override
798 {
799 glDeleteTextures(1, &mTextureShadow);
800 glDeleteTextures(1, &mTexture3D);
801 TexCoordDrawTest::TearDown();
802 }
803
804 GLuint mTextureShadow;
805 GLuint mTexture3D;
806 GLint mTextureShadowUniformLocation;
807 GLint mTexture3DUniformLocation;
808 GLint mDepthRefUniformLocation;
809};
810
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200811class SamplerTypeMixTestES3 : public TexCoordDrawTest
812{
813 protected:
814 SamplerTypeMixTestES3()
815 : TexCoordDrawTest(),
816 mTexture2D(0),
817 mTextureCube(0),
818 mTexture2DShadow(0),
819 mTextureCubeShadow(0),
820 mTexture2DUniformLocation(-1),
821 mTextureCubeUniformLocation(-1),
822 mTexture2DShadowUniformLocation(-1),
823 mTextureCubeShadowUniformLocation(-1),
824 mDepthRefUniformLocation(-1)
825 {
826 }
827
828 std::string getVertexShaderSource() override
829 {
830 return std::string(
831 "#version 300 es\n"
832 "out vec2 texcoord;\n"
833 "in vec4 position;\n"
834 "void main()\n"
835 "{\n"
836 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
837 " texcoord = (position.xy * 0.5) + 0.5;\n"
838 "}\n");
839 }
840
841 std::string getFragmentShaderSource() override
842 {
843 return std::string(
844 "#version 300 es\n"
845 "precision highp float;\n"
846 "uniform highp sampler2D tex2D;\n"
847 "uniform highp samplerCube texCube;\n"
848 "uniform highp sampler2DShadow tex2DShadow;\n"
849 "uniform highp samplerCubeShadow texCubeShadow;\n"
850 "in vec2 texcoord;\n"
851 "uniform float depthRef;\n"
852 "out vec4 fragColor;\n"
853 "void main()\n"
854 "{\n"
855 " fragColor = texture(tex2D, texcoord);\n"
856 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
857 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
858 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
859 "0.125);\n"
860 "}\n");
861 }
862
863 void SetUp() override
864 {
865 TexCoordDrawTest::SetUp();
866
867 glGenTextures(1, &mTexture2D);
868 glGenTextures(1, &mTextureCube);
869
870 glGenTextures(1, &mTexture2DShadow);
871 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
872 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
873
874 glGenTextures(1, &mTextureCubeShadow);
875 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
876 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
877
878 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
879 ASSERT_NE(-1, mTexture2DUniformLocation);
880 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
881 ASSERT_NE(-1, mTextureCubeUniformLocation);
882 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
883 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
884 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
885 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
886 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
887 ASSERT_NE(-1, mDepthRefUniformLocation);
888
889 ASSERT_GL_NO_ERROR();
890 }
891
892 void TearDown() override
893 {
894 glDeleteTextures(1, &mTexture2D);
895 glDeleteTextures(1, &mTextureCube);
896 glDeleteTextures(1, &mTexture2DShadow);
897 glDeleteTextures(1, &mTextureCubeShadow);
898 TexCoordDrawTest::TearDown();
899 }
900
901 GLuint mTexture2D;
902 GLuint mTextureCube;
903 GLuint mTexture2DShadow;
904 GLuint mTextureCubeShadow;
905 GLint mTexture2DUniformLocation;
906 GLint mTextureCubeUniformLocation;
907 GLint mTexture2DShadowUniformLocation;
908 GLint mTextureCubeShadowUniformLocation;
909 GLint mDepthRefUniformLocation;
910};
911
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200912TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400913{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400914 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400915 EXPECT_GL_ERROR(GL_NO_ERROR);
916
917 const GLubyte *pixels[20] = { 0 };
918 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
919 EXPECT_GL_ERROR(GL_INVALID_VALUE);
920}
Geoff Langc41e42d2014-04-28 10:58:16 -0400921
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200922TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400923{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400924 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400925 EXPECT_GL_ERROR(GL_NO_ERROR);
926
927 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200928 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400929 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200930 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400931
932 const GLubyte *pixel[4] = { 0 };
933
934 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
935 EXPECT_GL_NO_ERROR();
936
937 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
938 EXPECT_GL_NO_ERROR();
939
940 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
941 EXPECT_GL_NO_ERROR();
942}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400943
944// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200945TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400946{
947 glActiveTexture(GL_TEXTURE0);
948 glBindTexture(GL_TEXTURE_2D, mTexture2D);
949 glActiveTexture(GL_TEXTURE1);
950 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
951 EXPECT_GL_ERROR(GL_NO_ERROR);
952
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200953 glUseProgram(mProgram);
954 glUniform1i(mTexture2DUniformLocation, 0);
955 glUniform1i(mTextureCubeUniformLocation, 1);
956 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400957 EXPECT_GL_NO_ERROR();
958}
Jamie Madill9aca0592014-10-06 16:26:59 -0400959
Olli Etuaho53a2da12016-01-11 15:43:32 +0200960// Test drawing with two texture types accessed from the same shader and check that the result of
961// drawing is correct.
962TEST_P(TextureCubeTest, CubeMapDraw)
963{
964 GLubyte texData[4];
965 texData[0] = 0;
966 texData[1] = 60;
967 texData[2] = 0;
968 texData[3] = 255;
969
970 glActiveTexture(GL_TEXTURE0);
971 glBindTexture(GL_TEXTURE_2D, mTexture2D);
972 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
973
974 glActiveTexture(GL_TEXTURE1);
975 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
976 texData[1] = 120;
977 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
978 texData);
979 EXPECT_GL_ERROR(GL_NO_ERROR);
980
981 glUseProgram(mProgram);
982 glUniform1i(mTexture2DUniformLocation, 0);
983 glUniform1i(mTextureCubeUniformLocation, 1);
984 drawQuad(mProgram, "position", 0.5f);
985 EXPECT_GL_NO_ERROR();
986
987 int px = getWindowWidth() - 1;
988 int py = 0;
989 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
990}
991
Olli Etuaho4644a202016-01-12 15:12:53 +0200992TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
993{
994 glActiveTexture(GL_TEXTURE0);
995 glBindTexture(GL_TEXTURE_2D, mTexture2D);
996 GLubyte texData[4];
997 texData[0] = 0;
998 texData[1] = 128;
999 texData[2] = 0;
1000 texData[3] = 255;
1001 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1002 glUseProgram(mProgram);
1003 glUniform1i(mTexture2DUniformLocation, 0);
1004 drawQuad(mProgram, "position", 0.5f);
1005 EXPECT_GL_NO_ERROR();
1006
1007 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1008}
1009
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001010// Test drawing with two textures passed to the shader in a sampler array.
1011TEST_P(SamplerArrayTest, SamplerArrayDraw)
1012{
1013 testSamplerArrayDraw();
1014}
1015
1016// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1017// user-defined function in the shader.
1018TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1019{
1020 testSamplerArrayDraw();
1021}
1022
Jamie Madill9aca0592014-10-06 16:26:59 -04001023// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001024TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001025{
1026 int px = getWindowWidth() / 2;
1027 int py = getWindowHeight() / 2;
1028
1029 glActiveTexture(GL_TEXTURE0);
1030 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1031
1032 // Fill with red
1033 std::vector<GLubyte> pixels(4 * 16 * 16);
1034 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1035 {
1036 pixels[pixelId * 4 + 0] = 255;
1037 pixels[pixelId * 4 + 1] = 0;
1038 pixels[pixelId * 4 + 2] = 0;
1039 pixels[pixelId * 4 + 3] = 255;
1040 }
1041
1042 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1043 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1044 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1045 glGenerateMipmap(GL_TEXTURE_2D);
1046
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001047 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001048 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001049 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1050 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001051 EXPECT_GL_NO_ERROR();
1052 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
1053
1054 // Fill with blue
1055 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1056 {
1057 pixels[pixelId * 4 + 0] = 0;
1058 pixels[pixelId * 4 + 1] = 0;
1059 pixels[pixelId * 4 + 2] = 255;
1060 pixels[pixelId * 4 + 3] = 255;
1061 }
1062
1063 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1064 glGenerateMipmap(GL_TEXTURE_2D);
1065
1066 // Fill with green
1067 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1068 {
1069 pixels[pixelId * 4 + 0] = 0;
1070 pixels[pixelId * 4 + 1] = 255;
1071 pixels[pixelId * 4 + 2] = 0;
1072 pixels[pixelId * 4 + 3] = 255;
1073 }
1074
1075 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1076 glGenerateMipmap(GL_TEXTURE_2D);
1077
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001078 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001079
1080 EXPECT_GL_NO_ERROR();
1081 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
1082}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001083
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001084// Test creating a FBO with a cube map render target, to test an ANGLE bug
1085// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001086TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001087{
1088 GLuint fbo;
1089 glGenFramebuffers(1, &fbo);
1090 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1091
1092 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1093 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1094
Corentin Wallez322653b2015-06-17 18:33:56 +02001095 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001096
1097 glDeleteFramebuffers(1, &fbo);
1098
1099 EXPECT_GL_NO_ERROR();
1100}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001101
1102// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001103TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001104{
1105 int width = getWindowWidth();
1106 int height = getWindowHeight();
1107
1108 GLuint tex2D;
1109 glGenTextures(1, &tex2D);
1110 glActiveTexture(GL_TEXTURE0);
1111 glBindTexture(GL_TEXTURE_2D, tex2D);
1112
1113 // Fill with red
1114 std::vector<GLubyte> pixels(3 * 16 * 16);
1115 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1116 {
1117 pixels[pixelId * 3 + 0] = 255;
1118 pixels[pixelId * 3 + 1] = 0;
1119 pixels[pixelId * 3 + 2] = 0;
1120 }
1121
1122 // ANGLE internally uses RGBA as the DirectX format for RGB images
1123 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1124 // The data is kept in a CPU-side image and the image is marked as dirty.
1125 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1126
1127 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1128 // glTexSubImage2D should take into account that the image is dirty.
1129 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1132
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001133 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001134 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001135 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001136 glDeleteTextures(1, &tex2D);
1137 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001138 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001139
1140 // Validate that the region of the texture without data has an alpha of 1.0
1141 GLubyte pixel[4];
1142 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1143 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001144}
1145
1146// 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 +02001147TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001148{
1149 if (extensionEnabled("NV_pixel_buffer_object"))
1150 {
1151 int width = getWindowWidth();
1152 int height = getWindowHeight();
1153
1154 GLuint tex2D;
1155 glGenTextures(1, &tex2D);
1156 glActiveTexture(GL_TEXTURE0);
1157 glBindTexture(GL_TEXTURE_2D, tex2D);
1158
1159 // Fill with red
1160 std::vector<GLubyte> pixels(3 * 16 * 16);
1161 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1162 {
1163 pixels[pixelId * 3 + 0] = 255;
1164 pixels[pixelId * 3 + 1] = 0;
1165 pixels[pixelId * 3 + 2] = 0;
1166 }
1167
1168 // Read 16x16 region from red backbuffer to PBO
1169 GLuint pbo;
1170 glGenBuffers(1, &pbo);
1171 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1172 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1173
1174 // ANGLE internally uses RGBA as the DirectX format for RGB images
1175 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1176 // The data is kept in a CPU-side image and the image is marked as dirty.
1177 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1178
1179 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1180 // glTexSubImage2D should take into account that the image is dirty.
1181 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1184
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001185 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001186 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001187 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001188 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001189 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001190 EXPECT_GL_NO_ERROR();
1191 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1192 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1193 }
1194}
Jamie Madillbc393df2015-01-29 13:46:07 -05001195
1196// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001197TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001198{
1199 testFloatCopySubImage(1, 1);
1200}
1201
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001202TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001203{
1204 testFloatCopySubImage(2, 1);
1205}
1206
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001207TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001208{
1209 testFloatCopySubImage(2, 2);
1210}
1211
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001212TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001213{
1214 testFloatCopySubImage(3, 1);
1215}
1216
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001217TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001218{
1219 testFloatCopySubImage(3, 2);
1220}
1221
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001222TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001223{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001224 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1225 if (isD3D11_FL93())
1226 {
1227 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1228 return;
1229 }
1230
Jamie Madillbc393df2015-01-29 13:46:07 -05001231 testFloatCopySubImage(3, 3);
1232}
1233
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001234TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001235{
1236 testFloatCopySubImage(4, 1);
1237}
1238
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001239TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001240{
1241 testFloatCopySubImage(4, 2);
1242}
1243
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001244TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001245{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001246 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1247 if (isD3D11_FL93())
1248 {
1249 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1250 return;
1251 }
1252
Jamie Madillbc393df2015-01-29 13:46:07 -05001253 testFloatCopySubImage(4, 3);
1254}
1255
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001256TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001257{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001258 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1259 if (isD3D11_FL93())
1260 {
1261 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1262 return;
1263 }
1264
Jamie Madillbc393df2015-01-29 13:46:07 -05001265 testFloatCopySubImage(4, 4);
1266}
Austin Kinross07285142015-03-26 11:36:16 -07001267
1268// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1269// 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 +02001270TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001271{
1272 const int npotTexSize = 5;
1273 const int potTexSize = 4; // Should be less than npotTexSize
1274 GLuint tex2D;
1275
1276 if (extensionEnabled("GL_OES_texture_npot"))
1277 {
1278 // This test isn't applicable if texture_npot is enabled
1279 return;
1280 }
1281
1282 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1283
Austin Kinross5faa15b2016-01-11 13:32:48 -08001284 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1285 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1286
Austin Kinross07285142015-03-26 11:36:16 -07001287 glActiveTexture(GL_TEXTURE0);
1288 glGenTextures(1, &tex2D);
1289 glBindTexture(GL_TEXTURE_2D, tex2D);
1290
1291 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1292 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1293 {
1294 pixels[pixelId] = 64;
1295 }
1296
1297 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1299
1300 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1301 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1302 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1303
1304 // Check that an NPOT texture on level 0 succeeds
1305 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1306 EXPECT_GL_NO_ERROR();
1307
1308 // Check that generateMipmap fails on NPOT
1309 glGenerateMipmap(GL_TEXTURE_2D);
1310 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1311
1312 // Check that nothing is drawn if filtering is not correct for NPOT
1313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1317 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001318 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001319 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1320
1321 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1322 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1323 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1324 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1325 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001326 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001327 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1328
1329 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1330 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1331 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001332 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001333 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1334
1335 // Check that glTexImage2D for POT texture succeeds
1336 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1337 EXPECT_GL_NO_ERROR();
1338
1339 // Check that generateMipmap for an POT texture succeeds
1340 glGenerateMipmap(GL_TEXTURE_2D);
1341 EXPECT_GL_NO_ERROR();
1342
1343 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1344 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1345 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1346 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1347 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1348 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001349 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001350 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1351 EXPECT_GL_NO_ERROR();
1352}
Jamie Madillfa05f602015-05-07 13:47:11 -04001353
Austin Kinross08528e12015-10-07 16:24:40 -07001354// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1355// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001356TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001357{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001358 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1359 // 1278)
1360 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1361 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1362 {
1363 std::cout << "Test disabled on OpenGL." << std::endl;
1364 return;
1365 }
1366
Austin Kinross08528e12015-10-07 16:24:40 -07001367 glActiveTexture(GL_TEXTURE0);
1368 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1369
1370 // Create an 8x8 (i.e. power-of-two) texture.
1371 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1374 glGenerateMipmap(GL_TEXTURE_2D);
1375
1376 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1377 // This should always work, even if GL_OES_texture_npot isn't active.
1378 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1379
1380 EXPECT_GL_NO_ERROR();
1381}
1382
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001383// Test to check that texture completeness is determined correctly when the texture base level is
1384// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1385TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1386{
1387 glActiveTexture(GL_TEXTURE0);
1388 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1389 GLubyte texDataRed[4u * 4u * 4u];
1390 for (size_t i = 0u; i < 4u * 4u; ++i)
1391 {
1392 texDataRed[i * 4u] = 255u;
1393 texDataRed[i * 4u + 1u] = 0u;
1394 texDataRed[i * 4u + 2u] = 0u;
1395 texDataRed[i * 4u + 3u] = 255u;
1396 }
1397 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
1398 GLubyte texDataGreen[2u * 2u * 4u];
1399 for (size_t i = 0u; i < 2u * 2u; ++i)
1400 {
1401 texDataGreen[i * 4u] = 0u;
1402 texDataGreen[i * 4u + 1u] = 255u;
1403 texDataGreen[i * 4u + 2u] = 0u;
1404 texDataGreen[i * 4u + 3u] = 255u;
1405 }
1406 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1407 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1411
1412 EXPECT_GL_NO_ERROR();
1413
1414 drawQuad(mProgram, "position", 0.5f);
1415
1416 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1417}
1418
Jamie Madill2453dbc2015-07-14 11:35:42 -04001419// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
1420// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
1421// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001422TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04001423{
1424 std::vector<GLubyte> pixelData;
1425 for (size_t count = 0; count < 5000; count++)
1426 {
1427 pixelData.push_back(0u);
1428 pixelData.push_back(255u);
1429 pixelData.push_back(0u);
1430 }
1431
1432 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001433 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001434 glUniform1i(mTextureArrayLocation, 0);
1435
1436 // The first draw worked correctly.
1437 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
1438
1439 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1440 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1441 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1442 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001443 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001444 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1445
1446 // The dimension of the respecification must match the original exactly to trigger the bug.
1447 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 +02001448 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001449 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1450
1451 ASSERT_GL_NO_ERROR();
1452}
1453
Olli Etuaho1a679902016-01-14 12:21:47 +02001454// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
1455// This test is needed especially to confirm that sampler registers get assigned correctly on
1456// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
1457TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
1458{
1459 glActiveTexture(GL_TEXTURE0);
1460 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1461 GLubyte texData[4];
1462 texData[0] = 0;
1463 texData[1] = 60;
1464 texData[2] = 0;
1465 texData[3] = 255;
1466 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1467
1468 glActiveTexture(GL_TEXTURE1);
1469 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1470 GLfloat depthTexData[1];
1471 depthTexData[0] = 0.5f;
1472 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1473 depthTexData);
1474
1475 glUseProgram(mProgram);
1476 glUniform1f(mDepthRefUniformLocation, 0.3f);
1477 glUniform1i(mTexture3DUniformLocation, 0);
1478 glUniform1i(mTextureShadowUniformLocation, 1);
1479
1480 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1481 drawQuad(mProgram, "position", 0.5f);
1482 EXPECT_GL_NO_ERROR();
1483 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
1484 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
1485
1486 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
1487 drawQuad(mProgram, "position", 0.5f);
1488 EXPECT_GL_NO_ERROR();
1489 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
1490 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
1491}
1492
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001493// Test multiple different sampler types in the same shader.
1494// This test makes sure that even if sampler / texture registers get grouped together based on type
1495// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
1496// still has the right register index information for each ESSL sampler.
1497// The tested ESSL samplers have the following types in D3D11 HLSL:
1498// sampler2D: Texture2D + SamplerState
1499// samplerCube: TextureCube + SamplerState
1500// sampler2DShadow: Texture2D + SamplerComparisonState
1501// samplerCubeShadow: TextureCube + SamplerComparisonState
1502TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
1503{
1504 glActiveTexture(GL_TEXTURE0);
1505 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1506 GLubyte texData[4];
1507 texData[0] = 0;
1508 texData[1] = 0;
1509 texData[2] = 120;
1510 texData[3] = 255;
1511 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1512
1513 glActiveTexture(GL_TEXTURE1);
1514 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1515 texData[0] = 0;
1516 texData[1] = 90;
1517 texData[2] = 0;
1518 texData[3] = 255;
1519 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
1520 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1521 texData);
1522
1523 glActiveTexture(GL_TEXTURE2);
1524 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1525 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1526 GLfloat depthTexData[1];
1527 depthTexData[0] = 0.5f;
1528 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1529 depthTexData);
1530
1531 glActiveTexture(GL_TEXTURE3);
1532 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1533 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1534 depthTexData[0] = 0.2f;
1535 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1536 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
1537 depthTexData);
1538
1539 EXPECT_GL_NO_ERROR();
1540
1541 glUseProgram(mProgram);
1542 glUniform1f(mDepthRefUniformLocation, 0.3f);
1543 glUniform1i(mTexture2DUniformLocation, 0);
1544 glUniform1i(mTextureCubeUniformLocation, 1);
1545 glUniform1i(mTexture2DShadowUniformLocation, 2);
1546 glUniform1i(mTextureCubeShadowUniformLocation, 3);
1547
1548 drawQuad(mProgram, "position", 0.5f);
1549 EXPECT_GL_NO_ERROR();
1550 // The shader writes:
1551 // <texture 2d color> +
1552 // <cube map color> +
1553 // 0.25 * <comparison result (1.0)> +
1554 // 0.125 * <comparison result (0.0)>
1555 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
1556}
1557
Olli Etuahobce743a2016-01-15 17:18:28 +02001558// Test different base levels on textures accessed through the same sampler array.
1559// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
1560TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
1561{
1562 if ((isAMD() || isIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
1563 {
1564 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
1565 return;
1566 }
1567 glActiveTexture(GL_TEXTURE0);
1568 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
1569 GLsizei size = 64;
1570 for (GLint level = 0; level < 7; ++level)
1571 {
1572 ASSERT_LT(0, size);
1573 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1574 nullptr);
1575 size = size / 2;
1576 }
1577 ASSERT_EQ(0, size);
1578 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1579
1580 glActiveTexture(GL_TEXTURE1);
1581 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
1582 size = 128;
1583 for (GLint level = 0; level < 8; ++level)
1584 {
1585 ASSERT_LT(0, size);
1586 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1587 nullptr);
1588 size = size / 2;
1589 }
1590 ASSERT_EQ(0, size);
1591 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
1592 EXPECT_GL_NO_ERROR();
1593
1594 glUseProgram(mProgram);
1595 glUniform1i(mTexture0Location, 0);
1596 glUniform1i(mTexture1Location, 1);
1597
1598 drawQuad(mProgram, "position", 0.5f);
1599 EXPECT_GL_NO_ERROR();
1600 // Red channel: width of level 1 of texture A: 32.
1601 // Green channel: width of level 3 of texture B: 16.
1602 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
1603}
1604
Olli Etuaho6ee394a2016-02-18 13:30:09 +02001605// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1606// ES 3.0.4 table 3.24
1607TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
1608{
1609 glActiveTexture(GL_TEXTURE0);
1610 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1611 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1612 EXPECT_GL_NO_ERROR();
1613
1614 drawQuad(mProgram, "position", 0.5f);
1615
1616 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1617}
1618
1619// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1620// ES 3.0.4 table 3.24
1621TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
1622{
1623 glActiveTexture(GL_TEXTURE0);
1624 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1625 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1626 EXPECT_GL_NO_ERROR();
1627
1628 drawQuad(mProgram, "position", 0.5f);
1629
1630 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1631}
1632
1633// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1634// ES 3.0.4 table 3.24
1635TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
1636{
1637 if (extensionEnabled("GL_OES_texture_float"))
1638 {
1639 glActiveTexture(GL_TEXTURE0);
1640 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1641 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
1642 EXPECT_GL_NO_ERROR();
1643
1644 drawQuad(mProgram, "position", 0.5f);
1645
1646 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1647 }
1648}
1649
1650// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1651// ES 3.0.4 table 3.24
1652TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
1653{
1654 if (extensionEnabled("GL_OES_texture_half_float"))
1655 {
1656 if (isNVidia() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1657 {
1658 std::cout << "Test skipped on NVIDIA" << std::endl;
1659 return;
1660 }
1661 glActiveTexture(GL_TEXTURE0);
1662 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1663 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
1664 nullptr);
1665 EXPECT_GL_NO_ERROR();
1666
1667 drawQuad(mProgram, "position", 0.5f);
1668
1669 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1670 }
1671}
1672
1673// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1674// ES 3.0.4 table 3.24
1675TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
1676{
1677 if (isOSX() && isIntel())
1678 {
1679 std::cout << "Test disabled on OSX Intel." << std::endl;
1680 return;
1681 }
1682 glActiveTexture(GL_TEXTURE0);
1683 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1684 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
1685 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1686 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1687 EXPECT_GL_NO_ERROR();
1688
1689 drawQuad(mProgram, "position", 0.5f);
1690
1691 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1692}
1693
1694// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1695// ES 3.0.4 table 3.24
1696TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
1697{
1698 if (isOSX() && isIntel())
1699 {
1700 std::cout << "Test disabled on OSX Intel." << std::endl;
1701 return;
1702 }
1703 glActiveTexture(GL_TEXTURE0);
1704 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1705
1706 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
1707 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1708 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1709 EXPECT_GL_NO_ERROR();
1710
1711 drawQuad(mProgram, "position", 0.5f);
1712
1713 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1714}
1715
1716// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1717// ES 3.0.4 table 3.24
1718TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
1719{
1720 if (isOSX() && isIntel())
1721 {
1722 std::cout << "Test disabled on OSX Intel." << std::endl;
1723 return;
1724 }
1725 glActiveTexture(GL_TEXTURE0);
1726 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1727 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
1728 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1729 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1730 EXPECT_GL_NO_ERROR();
1731
1732 drawQuad(mProgram, "position", 0.5f);
1733
1734 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1735}
1736
1737// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1738// ES 3.0.4 table 3.24
1739TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
1740{
1741 if (isOSX() && isIntel())
1742 {
1743 std::cout << "Test disabled on OSX Intel." << std::endl;
1744 return;
1745 }
1746 glActiveTexture(GL_TEXTURE0);
1747 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1748 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
1749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1751 EXPECT_GL_NO_ERROR();
1752
1753 drawQuad(mProgram, "position", 0.5f);
1754
1755 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1756}
1757
1758// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1759// ES 3.0.4 table 3.24
1760TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
1761{
1762 if (isOSX() && isIntel())
1763 {
1764 std::cout << "Test disabled on OSX Intel." << std::endl;
1765 return;
1766 }
1767 glActiveTexture(GL_TEXTURE0);
1768 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1769 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
1770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1771 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1772 EXPECT_GL_NO_ERROR();
1773
1774 drawQuad(mProgram, "position", 0.5f);
1775
1776 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1777}
1778
1779// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1780// ES 3.0.4 table 3.24
1781TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
1782{
1783 if (isOSX() && isIntel())
1784 {
1785 std::cout << "Test disabled on OSX Intel." << std::endl;
1786 return;
1787 }
1788 glActiveTexture(GL_TEXTURE0);
1789 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1790 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
1791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1793 EXPECT_GL_NO_ERROR();
1794
1795 drawQuad(mProgram, "position", 0.5f);
1796
1797 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1798}
1799
1800// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1801// ES 3.0.4 table 3.24
1802TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
1803{
1804 glActiveTexture(GL_TEXTURE0);
1805 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1806 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
1807 EXPECT_GL_NO_ERROR();
1808
1809 drawQuad(mProgram, "position", 0.5f);
1810
1811 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1812}
1813
1814// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1815// ES 3.0.4 table 3.24
1816TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
1817{
1818 glActiveTexture(GL_TEXTURE0);
1819 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1820 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
1821 nullptr);
1822 EXPECT_GL_NO_ERROR();
1823
1824 drawQuad(mProgram, "position", 0.5f);
1825
1826 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1827}
1828
1829// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1830// ES 3.0.4 table 3.24
1831TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
1832{
1833 glActiveTexture(GL_TEXTURE0);
1834 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1835 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
1836 EXPECT_GL_NO_ERROR();
1837
1838 drawQuad(mProgram, "position", 0.5f);
1839
1840 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1841}
1842
1843// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
1844// ES 3.0.4 table 3.24
1845TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
1846{
1847 glActiveTexture(GL_TEXTURE0);
1848 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1849 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
1850 EXPECT_GL_NO_ERROR();
1851
1852 drawQuad(mProgram, "position", 0.5f);
1853
1854 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
1855}
1856
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001857class TextureLimitsTest : public ANGLETest
1858{
1859 protected:
1860 struct RGBA8
1861 {
1862 uint8_t R, G, B, A;
1863 };
1864
1865 TextureLimitsTest()
1866 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
1867 {
1868 setWindowWidth(128);
1869 setWindowHeight(128);
1870 setConfigRedBits(8);
1871 setConfigGreenBits(8);
1872 setConfigBlueBits(8);
1873 setConfigAlphaBits(8);
1874 }
1875
1876 ~TextureLimitsTest()
1877 {
1878 if (mProgram != 0)
1879 {
1880 glDeleteProgram(mProgram);
1881 mProgram = 0;
1882
1883 if (!mTextures.empty())
1884 {
1885 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
1886 }
1887 }
1888 }
1889
1890 void SetUp() override
1891 {
1892 ANGLETest::SetUp();
1893
1894 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
1895 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
1896 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
1897
1898 ASSERT_GL_NO_ERROR();
1899 }
1900
1901 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
1902 GLint vertexTextureCount,
1903 GLint vertexActiveTextureCount,
1904 const std::string &fragPrefix,
1905 GLint fragmentTextureCount,
1906 GLint fragmentActiveTextureCount)
1907 {
1908 std::stringstream vertexShaderStr;
1909 vertexShaderStr << "attribute vec2 position;\n"
1910 << "varying vec4 color;\n"
1911 << "varying vec2 texCoord;\n";
1912
1913 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
1914 {
1915 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
1916 }
1917
1918 vertexShaderStr << "void main() {\n"
1919 << " gl_Position = vec4(position, 0, 1);\n"
1920 << " texCoord = (position * 0.5) + 0.5;\n"
1921 << " color = vec4(0);\n";
1922
1923 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
1924 {
1925 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
1926 << ", texCoord);\n";
1927 }
1928
1929 vertexShaderStr << "}";
1930
1931 std::stringstream fragmentShaderStr;
1932 fragmentShaderStr << "varying mediump vec4 color;\n"
1933 << "varying mediump vec2 texCoord;\n";
1934
1935 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
1936 {
1937 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
1938 }
1939
1940 fragmentShaderStr << "void main() {\n"
1941 << " gl_FragColor = color;\n";
1942
1943 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
1944 {
1945 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
1946 << ", texCoord);\n";
1947 }
1948
1949 fragmentShaderStr << "}";
1950
1951 const std::string &vertexShaderSource = vertexShaderStr.str();
1952 const std::string &fragmentShaderSource = fragmentShaderStr.str();
1953
1954 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
1955 }
1956
1957 RGBA8 getPixel(GLint texIndex)
1958 {
1959 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
1960 0, 255u};
1961 return pixel;
1962 }
1963
1964 void initTextures(GLint tex2DCount, GLint texCubeCount)
1965 {
1966 GLint totalCount = tex2DCount + texCubeCount;
1967 mTextures.assign(totalCount, 0);
1968 glGenTextures(totalCount, &mTextures[0]);
1969 ASSERT_GL_NO_ERROR();
1970
1971 std::vector<RGBA8> texData(16 * 16);
1972
1973 GLint texIndex = 0;
1974 for (; texIndex < tex2DCount; ++texIndex)
1975 {
1976 texData.assign(texData.size(), getPixel(texIndex));
1977 glActiveTexture(GL_TEXTURE0 + texIndex);
1978 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
1979 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1980 &texData[0]);
1981 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1984 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1985 }
1986
1987 ASSERT_GL_NO_ERROR();
1988
1989 for (; texIndex < texCubeCount; ++texIndex)
1990 {
1991 texData.assign(texData.size(), getPixel(texIndex));
1992 glActiveTexture(GL_TEXTURE0 + texIndex);
1993 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
1994 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1995 GL_UNSIGNED_BYTE, &texData[0]);
1996 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1997 GL_UNSIGNED_BYTE, &texData[0]);
1998 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1999 GL_UNSIGNED_BYTE, &texData[0]);
2000 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2001 GL_UNSIGNED_BYTE, &texData[0]);
2002 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2003 GL_UNSIGNED_BYTE, &texData[0]);
2004 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2005 GL_UNSIGNED_BYTE, &texData[0]);
2006 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2007 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2008 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2009 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2010 }
2011
2012 ASSERT_GL_NO_ERROR();
2013 }
2014
2015 void testWithTextures(GLint vertexTextureCount,
2016 const std::string &vertexTexturePrefix,
2017 GLint fragmentTextureCount,
2018 const std::string &fragmentTexturePrefix)
2019 {
2020 // Generate textures
2021 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2022
2023 glUseProgram(mProgram);
2024 RGBA8 expectedSum = {0};
2025 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2026 {
2027 std::stringstream uniformNameStr;
2028 uniformNameStr << vertexTexturePrefix << texIndex;
2029 const std::string &uniformName = uniformNameStr.str();
2030 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2031 ASSERT_NE(-1, location);
2032
2033 glUniform1i(location, texIndex);
2034 RGBA8 contribution = getPixel(texIndex);
2035 expectedSum.R += contribution.R;
2036 expectedSum.G += contribution.G;
2037 }
2038
2039 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2040 {
2041 std::stringstream uniformNameStr;
2042 uniformNameStr << fragmentTexturePrefix << texIndex;
2043 const std::string &uniformName = uniformNameStr.str();
2044 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2045 ASSERT_NE(-1, location);
2046
2047 glUniform1i(location, texIndex + vertexTextureCount);
2048 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
2049 expectedSum.R += contribution.R;
2050 expectedSum.G += contribution.G;
2051 }
2052
2053 ASSERT_GE(256u, expectedSum.G);
2054
2055 drawQuad(mProgram, "position", 0.5f);
2056 ASSERT_GL_NO_ERROR();
2057 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
2058 }
2059
2060 GLuint mProgram;
2061 std::vector<GLuint> mTextures;
2062 GLint mMaxVertexTextures;
2063 GLint mMaxFragmentTextures;
2064 GLint mMaxCombinedTextures;
2065};
2066
2067// Test rendering with the maximum vertex texture units.
2068TEST_P(TextureLimitsTest, MaxVertexTextures)
2069{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002070 // TODO(jmadill): Figure out why this fails on Intel.
2071 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2072 {
2073 std::cout << "Test skipped on Intel." << std::endl;
2074 return;
2075 }
2076
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002077 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
2078 ASSERT_NE(0u, mProgram);
2079 ASSERT_GL_NO_ERROR();
2080
2081 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2082}
2083
2084// Test rendering with the maximum fragment texture units.
2085TEST_P(TextureLimitsTest, MaxFragmentTextures)
2086{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002087 // TODO(jmadill): Figure out why this fails on Intel.
2088 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2089 {
2090 std::cout << "Test skipped on Intel." << std::endl;
2091 return;
2092 }
2093
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002094 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
2095 ASSERT_NE(0u, mProgram);
2096 ASSERT_GL_NO_ERROR();
2097
2098 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
2099}
2100
2101// Test rendering with maximum combined texture units.
2102TEST_P(TextureLimitsTest, MaxCombinedTextures)
2103{
Jamie Madill412f17d2015-09-25 08:43:54 -04002104 // TODO(jmadill): Investigate workaround.
2105 if (isIntel() && GetParam() == ES2_OPENGL())
2106 {
2107 std::cout << "Test skipped on Intel." << std::endl;
2108 return;
2109 }
2110
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002111 GLint vertexTextures = mMaxVertexTextures;
2112
2113 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
2114 {
2115 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
2116 }
2117
2118 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
2119 mMaxFragmentTextures, mMaxFragmentTextures);
2120 ASSERT_NE(0u, mProgram);
2121 ASSERT_GL_NO_ERROR();
2122
2123 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
2124}
2125
2126// Negative test for exceeding the number of vertex textures
2127TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
2128{
2129 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
2130 0);
2131 ASSERT_EQ(0u, mProgram);
2132}
2133
2134// Negative test for exceeding the number of fragment textures
2135TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
2136{
2137 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
2138 mMaxFragmentTextures + 1);
2139 ASSERT_EQ(0u, mProgram);
2140}
2141
2142// Test active vertex textures under the limit, but excessive textures specified.
2143TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
2144{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002145 // TODO(jmadill): Figure out why this fails on Intel.
2146 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2147 {
2148 std::cout << "Test skipped on Intel." << std::endl;
2149 return;
2150 }
2151
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002152 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
2153 ASSERT_NE(0u, mProgram);
2154 ASSERT_GL_NO_ERROR();
2155
2156 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
2157}
2158
2159// Test active fragment textures under the limit, but excessive textures specified.
2160TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
2161{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002162 // TODO(jmadill): Figure out why this fails on Intel.
2163 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2164 {
2165 std::cout << "Test skipped on Intel." << std::endl;
2166 return;
2167 }
2168
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002169 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
2170 mMaxFragmentTextures);
2171 ASSERT_NE(0u, mProgram);
2172 ASSERT_GL_NO_ERROR();
2173
2174 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
2175}
2176
2177// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002178// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002179TEST_P(TextureLimitsTest, TextureTypeConflict)
2180{
2181 const std::string &vertexShader =
2182 "attribute vec2 position;\n"
2183 "varying float color;\n"
2184 "uniform sampler2D tex2D;\n"
2185 "uniform samplerCube texCube;\n"
2186 "void main() {\n"
2187 " gl_Position = vec4(position, 0, 1);\n"
2188 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2189 " color = texture2D(tex2D, texCoord).x;\n"
2190 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
2191 "}";
2192 const std::string &fragmentShader =
2193 "varying mediump float color;\n"
2194 "void main() {\n"
2195 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2196 "}";
2197
2198 mProgram = CompileProgram(vertexShader, fragmentShader);
2199 ASSERT_NE(0u, mProgram);
2200
2201 initTextures(1, 0);
2202
2203 glUseProgram(mProgram);
2204 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2205 ASSERT_NE(-1, tex2DLocation);
2206 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
2207 ASSERT_NE(-1, texCubeLocation);
2208
2209 glUniform1i(tex2DLocation, 0);
2210 glUniform1i(texCubeLocation, 0);
2211 ASSERT_GL_NO_ERROR();
2212
2213 drawQuad(mProgram, "position", 0.5f);
2214 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2215}
2216
2217// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002218// TODO(jmadill): Possibly adjust the test according to the spec:
2219// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
2220// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002221TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
2222{
2223 const std::string &vertexShader =
2224 "attribute vec2 position;\n"
2225 "varying float color;\n"
2226 "uniform sampler2D tex2D;\n"
2227 "void main() {\n"
2228 " gl_Position = vec4(position, 0, 1);\n"
2229 " vec2 texCoord = (position * 0.5) + 0.5;\n"
2230 " color = texture2D(tex2D, texCoord).x;\n"
2231 "}";
2232 const std::string &fragmentShader =
2233 "varying mediump float color;\n"
2234 "void main() {\n"
2235 " gl_FragColor = vec4(color, 0, 0, 1);\n"
2236 "}";
2237
2238 mProgram = CompileProgram(vertexShader, fragmentShader);
2239 ASSERT_NE(0u, mProgram);
2240
2241 glUseProgram(mProgram);
2242 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
2243 ASSERT_NE(-1, tex2DLocation);
2244
2245 glUniform1i(tex2DLocation, mMaxCombinedTextures);
2246 ASSERT_GL_NO_ERROR();
2247
2248 drawQuad(mProgram, "position", 0.5f);
2249 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2250}
2251
Jamie Madillfa05f602015-05-07 13:47:11 -04002252// 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 +02002253// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05002254ANGLE_INSTANTIATE_TEST(Texture2DTest,
2255 ES2_D3D9(),
2256 ES2_D3D11(),
2257 ES2_D3D11_FL9_3(),
2258 ES2_OPENGL(),
2259 ES2_OPENGLES());
2260ANGLE_INSTANTIATE_TEST(TextureCubeTest,
2261 ES2_D3D9(),
2262 ES2_D3D11(),
2263 ES2_D3D11_FL9_3(),
2264 ES2_OPENGL(),
2265 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002266ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
2267 ES2_D3D9(),
2268 ES2_D3D11(),
2269 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002270 ES2_OPENGL(),
2271 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02002272ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
2273 ES2_D3D9(),
2274 ES2_D3D11(),
2275 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05002276 ES2_OPENGL(),
2277 ES2_OPENGLES());
2278ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
2279 ES2_D3D9(),
2280 ES2_D3D11(),
2281 ES2_D3D11_FL9_3(),
2282 ES2_OPENGL(),
2283 ES2_OPENGLES());
2284ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
2285 ES2_D3D9(),
2286 ES2_D3D11(),
2287 ES2_D3D11_FL9_3(),
2288 ES2_OPENGL(),
2289 ES2_OPENGLES());
2290ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002291ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2292ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
2293 ES3_D3D11(),
2294 ES3_OPENGL(),
2295 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002296ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
2297 ES3_D3D11(),
2298 ES3_OPENGL(),
2299 ES3_OPENGLES());
2300ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2301ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02002302ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Geoff Lange0cc2a42016-01-20 10:58:17 -05002303ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04002304
2305} // namespace