blob: 69fa5581fcaffe6be0dd43c245d26db0416ae381 [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 Etuaho4a8329f2016-01-11 17:12:57 +0200313class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400314{
315 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200316 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
317
318 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400319 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200320 return std::string(SHADER_SOURCE
321 (
322 precision highp float;
323 attribute vec4 position;
324 varying vec2 texcoord;
325
326 uniform vec2 drawScale;
327
328 void main()
329 {
330 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
331 texcoord = (position.xy * 0.5) + 0.5;
332 }
333 )
334 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400335 }
336
337 void SetUp() override
338 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200339 Texture2DTest::SetUp();
340 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
341 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400342
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200343 glUseProgram(mProgram);
344 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
345 glUseProgram(0);
346 ASSERT_GL_NO_ERROR();
347 }
348
349 GLint mDrawScaleUniformLocation;
350};
351
Olli Etuaho4644a202016-01-12 15:12:53 +0200352class Sampler2DAsFunctionParameterTest : public Texture2DTest
353{
354 protected:
355 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
356
357 std::string getFragmentShaderSource() override
358 {
359 return std::string(SHADER_SOURCE
360 (
361 precision highp float;
362 uniform sampler2D tex;
363 varying vec2 texcoord;
364
365 vec4 computeFragColor(sampler2D aTex)
366 {
367 return texture2D(aTex, texcoord);
368 }
369
370 void main()
371 {
372 gl_FragColor = computeFragColor(tex);
373 }
374 )
375 );
376 }
377};
378
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200379class TextureCubeTest : public TexCoordDrawTest
380{
381 protected:
382 TextureCubeTest()
383 : TexCoordDrawTest(),
384 mTexture2D(0),
385 mTextureCube(0),
386 mTexture2DUniformLocation(-1),
387 mTextureCubeUniformLocation(-1)
388 {
389 }
390
391 std::string getFragmentShaderSource() override
392 {
393 return std::string(SHADER_SOURCE
394 (
395 precision highp float;
396 uniform sampler2D tex2D;
397 uniform samplerCube texCube;
398 varying vec2 texcoord;
399
400 void main()
401 {
402 gl_FragColor = texture2D(tex2D, texcoord);
403 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
404 }
405 )
406 );
407 }
408
409 void SetUp() override
410 {
411 TexCoordDrawTest::SetUp();
412
413 glGenTextures(1, &mTextureCube);
414 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
415 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
416 EXPECT_GL_NO_ERROR();
417
418 mTexture2D = create2DTexture();
419
420 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
421 ASSERT_NE(-1, mTexture2DUniformLocation);
422 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
423 ASSERT_NE(-1, mTextureCubeUniformLocation);
424 }
425
426 void TearDown() override
427 {
428 glDeleteTextures(1, &mTextureCube);
429 TexCoordDrawTest::TearDown();
430 }
431
432 GLuint mTexture2D;
433 GLuint mTextureCube;
434 GLint mTexture2DUniformLocation;
435 GLint mTextureCubeUniformLocation;
436};
437
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200438class SamplerArrayTest : public TexCoordDrawTest
439{
440 protected:
441 SamplerArrayTest()
442 : TexCoordDrawTest(),
443 mTexture2DA(0),
444 mTexture2DB(0),
445 mTexture0UniformLocation(-1),
446 mTexture1UniformLocation(-1)
447 {
448 }
449
450 std::string getFragmentShaderSource() override
451 {
452 return std::string(SHADER_SOURCE
453 (
454 precision mediump float;
455 uniform highp sampler2D tex2DArray[2];
456 varying vec2 texcoord;
457 void main()
458 {
459 gl_FragColor = texture2D(tex2DArray[0], texcoord);
460 gl_FragColor += texture2D(tex2DArray[1], texcoord);
461 }
462 )
463 );
464 }
465
466 void SetUp() override
467 {
468 TexCoordDrawTest::SetUp();
469
470 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
471 ASSERT_NE(-1, mTexture0UniformLocation);
472 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
473 ASSERT_NE(-1, mTexture1UniformLocation);
474
475 mTexture2DA = create2DTexture();
476 mTexture2DB = create2DTexture();
477 ASSERT_GL_NO_ERROR();
478 }
479
480 void TearDown() override
481 {
482 glDeleteTextures(1, &mTexture2DA);
483 glDeleteTextures(1, &mTexture2DB);
484 TexCoordDrawTest::TearDown();
485 }
486
487 void testSamplerArrayDraw()
488 {
489 GLubyte texData[4];
490 texData[0] = 0;
491 texData[1] = 60;
492 texData[2] = 0;
493 texData[3] = 255;
494
495 glActiveTexture(GL_TEXTURE0);
496 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
497 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
498
499 texData[1] = 120;
500 glActiveTexture(GL_TEXTURE1);
501 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
502 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
503 EXPECT_GL_ERROR(GL_NO_ERROR);
504
505 glUseProgram(mProgram);
506 glUniform1i(mTexture0UniformLocation, 0);
507 glUniform1i(mTexture1UniformLocation, 1);
508 drawQuad(mProgram, "position", 0.5f);
509 EXPECT_GL_NO_ERROR();
510
511 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
512 }
513
514 GLuint mTexture2DA;
515 GLuint mTexture2DB;
516 GLint mTexture0UniformLocation;
517 GLint mTexture1UniformLocation;
518};
519
520
521class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
522{
523 protected:
524 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
525
526 std::string getFragmentShaderSource() override
527 {
528 return std::string(SHADER_SOURCE
529 (
530 precision mediump float;
531 uniform highp sampler2D tex2DArray[2];
532 varying vec2 texcoord;
533
534 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
535 {
536 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
537 }
538
539 void main()
540 {
541 gl_FragColor = computeFragColor(tex2DArray);
542 }
543 )
544 );
545 }
546};
547
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200548class Texture2DArrayTestES3 : public TexCoordDrawTest
549{
550 protected:
551 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
552
553 std::string getVertexShaderSource() override
554 {
555 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400556 "#version 300 es\n"
557 "out vec2 texcoord;\n"
558 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200559 "void main()\n"
560 "{\n"
561 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
562 " texcoord = (position.xy * 0.5) + 0.5;\n"
563 "}\n");
564 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400565
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200566 std::string getFragmentShaderSource() override
567 {
568 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400569 "#version 300 es\n"
570 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200571 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400572 "in vec2 texcoord;\n"
573 "out vec4 fragColor;\n"
574 "void main()\n"
575 "{\n"
576 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200577 "}\n");
578 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400579
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200580 void SetUp() override
581 {
582 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400583
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200584 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400585 ASSERT_NE(-1, mTextureArrayLocation);
586
587 glGenTextures(1, &m2DArrayTexture);
588 ASSERT_GL_NO_ERROR();
589 }
590
591 void TearDown() override
592 {
593 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200594 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400595 }
596
597 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400598 GLint mTextureArrayLocation;
599};
600
Olli Etuahobce743a2016-01-15 17:18:28 +0200601class TextureSizeTextureArrayTest : public TexCoordDrawTest
602{
603 protected:
604 TextureSizeTextureArrayTest()
605 : TexCoordDrawTest(),
606 mTexture2DA(0),
607 mTexture2DB(0),
608 mTexture0Location(-1),
609 mTexture1Location(-1)
610 {
611 }
612
613 std::string getVertexShaderSource() override
614 {
615 return std::string(
616 "#version 300 es\n"
617 "in vec4 position;\n"
618 "void main()\n"
619 "{\n"
620 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
621 "}\n");
622 }
623
624 std::string getFragmentShaderSource() override
625 {
626 return std::string(
627 "#version 300 es\n"
628 "precision highp float;\n"
629 "uniform highp sampler2D tex2DArray[2];\n"
630 "out vec4 fragColor;\n"
631 "void main()\n"
632 "{\n"
633 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
634 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
635 " fragColor = vec4(red, green, 0.0, 1.0);\n"
636 "}\n");
637 }
638
639 void SetUp() override
640 {
641 TexCoordDrawTest::SetUp();
642
643 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
644 ASSERT_NE(-1, mTexture0Location);
645 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
646 ASSERT_NE(-1, mTexture1Location);
647
648 mTexture2DA = create2DTexture();
649 mTexture2DB = create2DTexture();
650 ASSERT_GL_NO_ERROR();
651 }
652
653 void TearDown() override
654 {
655 glDeleteTextures(1, &mTexture2DA);
656 glDeleteTextures(1, &mTexture2DB);
657 TexCoordDrawTest::TearDown();
658 }
659
660 GLuint mTexture2DA;
661 GLuint mTexture2DB;
662 GLint mTexture0Location;
663 GLint mTexture1Location;
664};
665
Olli Etuaho1a679902016-01-14 12:21:47 +0200666class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
667{
668 protected:
669 ShadowSamplerPlusSampler3DTestES3()
670 : TexCoordDrawTest(),
671 mTextureShadow(0),
672 mTexture3D(0),
673 mTextureShadowUniformLocation(-1),
674 mTexture3DUniformLocation(-1),
675 mDepthRefUniformLocation(-1)
676 {
677 }
678
679 std::string getVertexShaderSource() override
680 {
681 return std::string(
682 "#version 300 es\n"
683 "out vec2 texcoord;\n"
684 "in vec4 position;\n"
685 "void main()\n"
686 "{\n"
687 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
688 " texcoord = (position.xy * 0.5) + 0.5;\n"
689 "}\n");
690 }
691
692 std::string getFragmentShaderSource() override
693 {
694 return std::string(
695 "#version 300 es\n"
696 "precision highp float;\n"
697 "uniform highp sampler2DShadow tex2DShadow;\n"
698 "uniform highp sampler3D tex3D;\n"
699 "in vec2 texcoord;\n"
700 "uniform float depthRef;\n"
701 "out vec4 fragColor;\n"
702 "void main()\n"
703 "{\n"
704 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
705 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
706 "}\n");
707 }
708
709 void SetUp() override
710 {
711 TexCoordDrawTest::SetUp();
712
713 glGenTextures(1, &mTexture3D);
714
715 glGenTextures(1, &mTextureShadow);
716 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
718
719 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
720 ASSERT_NE(-1, mTextureShadowUniformLocation);
721 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
722 ASSERT_NE(-1, mTexture3DUniformLocation);
723 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
724 ASSERT_NE(-1, mDepthRefUniformLocation);
725 }
726
727 void TearDown() override
728 {
729 glDeleteTextures(1, &mTextureShadow);
730 glDeleteTextures(1, &mTexture3D);
731 TexCoordDrawTest::TearDown();
732 }
733
734 GLuint mTextureShadow;
735 GLuint mTexture3D;
736 GLint mTextureShadowUniformLocation;
737 GLint mTexture3DUniformLocation;
738 GLint mDepthRefUniformLocation;
739};
740
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200741class SamplerTypeMixTestES3 : public TexCoordDrawTest
742{
743 protected:
744 SamplerTypeMixTestES3()
745 : TexCoordDrawTest(),
746 mTexture2D(0),
747 mTextureCube(0),
748 mTexture2DShadow(0),
749 mTextureCubeShadow(0),
750 mTexture2DUniformLocation(-1),
751 mTextureCubeUniformLocation(-1),
752 mTexture2DShadowUniformLocation(-1),
753 mTextureCubeShadowUniformLocation(-1),
754 mDepthRefUniformLocation(-1)
755 {
756 }
757
758 std::string getVertexShaderSource() override
759 {
760 return std::string(
761 "#version 300 es\n"
762 "out vec2 texcoord;\n"
763 "in vec4 position;\n"
764 "void main()\n"
765 "{\n"
766 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
767 " texcoord = (position.xy * 0.5) + 0.5;\n"
768 "}\n");
769 }
770
771 std::string getFragmentShaderSource() override
772 {
773 return std::string(
774 "#version 300 es\n"
775 "precision highp float;\n"
776 "uniform highp sampler2D tex2D;\n"
777 "uniform highp samplerCube texCube;\n"
778 "uniform highp sampler2DShadow tex2DShadow;\n"
779 "uniform highp samplerCubeShadow texCubeShadow;\n"
780 "in vec2 texcoord;\n"
781 "uniform float depthRef;\n"
782 "out vec4 fragColor;\n"
783 "void main()\n"
784 "{\n"
785 " fragColor = texture(tex2D, texcoord);\n"
786 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
787 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
788 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
789 "0.125);\n"
790 "}\n");
791 }
792
793 void SetUp() override
794 {
795 TexCoordDrawTest::SetUp();
796
797 glGenTextures(1, &mTexture2D);
798 glGenTextures(1, &mTextureCube);
799
800 glGenTextures(1, &mTexture2DShadow);
801 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
802 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
803
804 glGenTextures(1, &mTextureCubeShadow);
805 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
806 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
807
808 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
809 ASSERT_NE(-1, mTexture2DUniformLocation);
810 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
811 ASSERT_NE(-1, mTextureCubeUniformLocation);
812 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
813 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
814 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
815 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
816 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
817 ASSERT_NE(-1, mDepthRefUniformLocation);
818
819 ASSERT_GL_NO_ERROR();
820 }
821
822 void TearDown() override
823 {
824 glDeleteTextures(1, &mTexture2D);
825 glDeleteTextures(1, &mTextureCube);
826 glDeleteTextures(1, &mTexture2DShadow);
827 glDeleteTextures(1, &mTextureCubeShadow);
828 TexCoordDrawTest::TearDown();
829 }
830
831 GLuint mTexture2D;
832 GLuint mTextureCube;
833 GLuint mTexture2DShadow;
834 GLuint mTextureCubeShadow;
835 GLint mTexture2DUniformLocation;
836 GLint mTextureCubeUniformLocation;
837 GLint mTexture2DShadowUniformLocation;
838 GLint mTextureCubeShadowUniformLocation;
839 GLint mDepthRefUniformLocation;
840};
841
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200842TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400843{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400844 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400845 EXPECT_GL_ERROR(GL_NO_ERROR);
846
847 const GLubyte *pixels[20] = { 0 };
848 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
849 EXPECT_GL_ERROR(GL_INVALID_VALUE);
850}
Geoff Langc41e42d2014-04-28 10:58:16 -0400851
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200852TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400853{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400854 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400855 EXPECT_GL_ERROR(GL_NO_ERROR);
856
857 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200858 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400859 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200860 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400861
862 const GLubyte *pixel[4] = { 0 };
863
864 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
865 EXPECT_GL_NO_ERROR();
866
867 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
868 EXPECT_GL_NO_ERROR();
869
870 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
871 EXPECT_GL_NO_ERROR();
872}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400873
874// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200875TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400876{
877 glActiveTexture(GL_TEXTURE0);
878 glBindTexture(GL_TEXTURE_2D, mTexture2D);
879 glActiveTexture(GL_TEXTURE1);
880 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
881 EXPECT_GL_ERROR(GL_NO_ERROR);
882
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200883 glUseProgram(mProgram);
884 glUniform1i(mTexture2DUniformLocation, 0);
885 glUniform1i(mTextureCubeUniformLocation, 1);
886 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400887 EXPECT_GL_NO_ERROR();
888}
Jamie Madill9aca0592014-10-06 16:26:59 -0400889
Olli Etuaho53a2da12016-01-11 15:43:32 +0200890// Test drawing with two texture types accessed from the same shader and check that the result of
891// drawing is correct.
892TEST_P(TextureCubeTest, CubeMapDraw)
893{
894 GLubyte texData[4];
895 texData[0] = 0;
896 texData[1] = 60;
897 texData[2] = 0;
898 texData[3] = 255;
899
900 glActiveTexture(GL_TEXTURE0);
901 glBindTexture(GL_TEXTURE_2D, mTexture2D);
902 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
903
904 glActiveTexture(GL_TEXTURE1);
905 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
906 texData[1] = 120;
907 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
908 texData);
909 EXPECT_GL_ERROR(GL_NO_ERROR);
910
911 glUseProgram(mProgram);
912 glUniform1i(mTexture2DUniformLocation, 0);
913 glUniform1i(mTextureCubeUniformLocation, 1);
914 drawQuad(mProgram, "position", 0.5f);
915 EXPECT_GL_NO_ERROR();
916
917 int px = getWindowWidth() - 1;
918 int py = 0;
919 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
920}
921
Olli Etuaho4644a202016-01-12 15:12:53 +0200922TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
923{
924 glActiveTexture(GL_TEXTURE0);
925 glBindTexture(GL_TEXTURE_2D, mTexture2D);
926 GLubyte texData[4];
927 texData[0] = 0;
928 texData[1] = 128;
929 texData[2] = 0;
930 texData[3] = 255;
931 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
932 glUseProgram(mProgram);
933 glUniform1i(mTexture2DUniformLocation, 0);
934 drawQuad(mProgram, "position", 0.5f);
935 EXPECT_GL_NO_ERROR();
936
937 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
938}
939
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200940// Test drawing with two textures passed to the shader in a sampler array.
941TEST_P(SamplerArrayTest, SamplerArrayDraw)
942{
943 testSamplerArrayDraw();
944}
945
946// Test drawing with two textures passed to the shader in a sampler array which is passed to a
947// user-defined function in the shader.
948TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
949{
950 testSamplerArrayDraw();
951}
952
Jamie Madill9aca0592014-10-06 16:26:59 -0400953// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200954TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -0400955{
956 int px = getWindowWidth() / 2;
957 int py = getWindowHeight() / 2;
958
959 glActiveTexture(GL_TEXTURE0);
960 glBindTexture(GL_TEXTURE_2D, mTexture2D);
961
962 // Fill with red
963 std::vector<GLubyte> pixels(4 * 16 * 16);
964 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
965 {
966 pixels[pixelId * 4 + 0] = 255;
967 pixels[pixelId * 4 + 1] = 0;
968 pixels[pixelId * 4 + 2] = 0;
969 pixels[pixelId * 4 + 3] = 255;
970 }
971
972 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
973 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
974 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
975 glGenerateMipmap(GL_TEXTURE_2D);
976
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200977 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -0400978 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200979 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
980 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -0400981 EXPECT_GL_NO_ERROR();
982 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
983
984 // Fill with blue
985 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
986 {
987 pixels[pixelId * 4 + 0] = 0;
988 pixels[pixelId * 4 + 1] = 0;
989 pixels[pixelId * 4 + 2] = 255;
990 pixels[pixelId * 4 + 3] = 255;
991 }
992
993 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
994 glGenerateMipmap(GL_TEXTURE_2D);
995
996 // Fill with green
997 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
998 {
999 pixels[pixelId * 4 + 0] = 0;
1000 pixels[pixelId * 4 + 1] = 255;
1001 pixels[pixelId * 4 + 2] = 0;
1002 pixels[pixelId * 4 + 3] = 255;
1003 }
1004
1005 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1006 glGenerateMipmap(GL_TEXTURE_2D);
1007
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001008 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001009
1010 EXPECT_GL_NO_ERROR();
1011 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
1012}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001013
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001014// Test creating a FBO with a cube map render target, to test an ANGLE bug
1015// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001016TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001017{
1018 GLuint fbo;
1019 glGenFramebuffers(1, &fbo);
1020 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1021
1022 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1023 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1024
Corentin Wallez322653b2015-06-17 18:33:56 +02001025 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001026
1027 glDeleteFramebuffers(1, &fbo);
1028
1029 EXPECT_GL_NO_ERROR();
1030}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001031
1032// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001033TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001034{
1035 int width = getWindowWidth();
1036 int height = getWindowHeight();
1037
1038 GLuint tex2D;
1039 glGenTextures(1, &tex2D);
1040 glActiveTexture(GL_TEXTURE0);
1041 glBindTexture(GL_TEXTURE_2D, tex2D);
1042
1043 // Fill with red
1044 std::vector<GLubyte> pixels(3 * 16 * 16);
1045 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1046 {
1047 pixels[pixelId * 3 + 0] = 255;
1048 pixels[pixelId * 3 + 1] = 0;
1049 pixels[pixelId * 3 + 2] = 0;
1050 }
1051
1052 // ANGLE internally uses RGBA as the DirectX format for RGB images
1053 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1054 // The data is kept in a CPU-side image and the image is marked as dirty.
1055 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1056
1057 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1058 // glTexSubImage2D should take into account that the image is dirty.
1059 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1062
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001063 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001064 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001065 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001066 glDeleteTextures(1, &tex2D);
1067 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001068 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001069
1070 // Validate that the region of the texture without data has an alpha of 1.0
1071 GLubyte pixel[4];
1072 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1073 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001074}
1075
1076// 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 +02001077TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001078{
1079 if (extensionEnabled("NV_pixel_buffer_object"))
1080 {
1081 int width = getWindowWidth();
1082 int height = getWindowHeight();
1083
1084 GLuint tex2D;
1085 glGenTextures(1, &tex2D);
1086 glActiveTexture(GL_TEXTURE0);
1087 glBindTexture(GL_TEXTURE_2D, tex2D);
1088
1089 // Fill with red
1090 std::vector<GLubyte> pixels(3 * 16 * 16);
1091 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1092 {
1093 pixels[pixelId * 3 + 0] = 255;
1094 pixels[pixelId * 3 + 1] = 0;
1095 pixels[pixelId * 3 + 2] = 0;
1096 }
1097
1098 // Read 16x16 region from red backbuffer to PBO
1099 GLuint pbo;
1100 glGenBuffers(1, &pbo);
1101 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1102 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1103
1104 // ANGLE internally uses RGBA as the DirectX format for RGB images
1105 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1106 // The data is kept in a CPU-side image and the image is marked as dirty.
1107 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1108
1109 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1110 // glTexSubImage2D should take into account that the image is dirty.
1111 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1114
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001115 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001116 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001117 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001118 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001119 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001120 EXPECT_GL_NO_ERROR();
1121 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1122 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1123 }
1124}
Jamie Madillbc393df2015-01-29 13:46:07 -05001125
1126// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001127TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001128{
1129 testFloatCopySubImage(1, 1);
1130}
1131
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001132TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001133{
1134 testFloatCopySubImage(2, 1);
1135}
1136
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001137TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001138{
1139 testFloatCopySubImage(2, 2);
1140}
1141
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001142TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001143{
1144 testFloatCopySubImage(3, 1);
1145}
1146
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001147TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001148{
1149 testFloatCopySubImage(3, 2);
1150}
1151
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001152TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001153{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001154 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1155 if (isD3D11_FL93())
1156 {
1157 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1158 return;
1159 }
1160
Jamie Madillbc393df2015-01-29 13:46:07 -05001161 testFloatCopySubImage(3, 3);
1162}
1163
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001164TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001165{
1166 testFloatCopySubImage(4, 1);
1167}
1168
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001169TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001170{
1171 testFloatCopySubImage(4, 2);
1172}
1173
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001174TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001175{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001176 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1177 if (isD3D11_FL93())
1178 {
1179 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1180 return;
1181 }
1182
Jamie Madillbc393df2015-01-29 13:46:07 -05001183 testFloatCopySubImage(4, 3);
1184}
1185
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001186TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001187{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001188 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1189 if (isD3D11_FL93())
1190 {
1191 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1192 return;
1193 }
1194
Jamie Madillbc393df2015-01-29 13:46:07 -05001195 testFloatCopySubImage(4, 4);
1196}
Austin Kinross07285142015-03-26 11:36:16 -07001197
1198// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1199// 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 +02001200TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001201{
1202 const int npotTexSize = 5;
1203 const int potTexSize = 4; // Should be less than npotTexSize
1204 GLuint tex2D;
1205
1206 if (extensionEnabled("GL_OES_texture_npot"))
1207 {
1208 // This test isn't applicable if texture_npot is enabled
1209 return;
1210 }
1211
1212 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1213
Austin Kinross5faa15b2016-01-11 13:32:48 -08001214 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1215 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1216
Austin Kinross07285142015-03-26 11:36:16 -07001217 glActiveTexture(GL_TEXTURE0);
1218 glGenTextures(1, &tex2D);
1219 glBindTexture(GL_TEXTURE_2D, tex2D);
1220
1221 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1222 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1223 {
1224 pixels[pixelId] = 64;
1225 }
1226
1227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1229
1230 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1231 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1232 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1233
1234 // Check that an NPOT texture on level 0 succeeds
1235 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1236 EXPECT_GL_NO_ERROR();
1237
1238 // Check that generateMipmap fails on NPOT
1239 glGenerateMipmap(GL_TEXTURE_2D);
1240 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1241
1242 // Check that nothing is drawn if filtering is not correct for NPOT
1243 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1246 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1247 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001248 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001249 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1250
1251 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1255 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001256 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001257 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1258
1259 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1261 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001262 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001263 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1264
1265 // Check that glTexImage2D for POT texture succeeds
1266 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1267 EXPECT_GL_NO_ERROR();
1268
1269 // Check that generateMipmap for an POT texture succeeds
1270 glGenerateMipmap(GL_TEXTURE_2D);
1271 EXPECT_GL_NO_ERROR();
1272
1273 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1277 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1278 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001279 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001280 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1281 EXPECT_GL_NO_ERROR();
1282}
Jamie Madillfa05f602015-05-07 13:47:11 -04001283
Austin Kinross08528e12015-10-07 16:24:40 -07001284// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1285// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001286TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001287{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001288 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1289 // 1278)
1290 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1291 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1292 {
1293 std::cout << "Test disabled on OpenGL." << std::endl;
1294 return;
1295 }
1296
Austin Kinross08528e12015-10-07 16:24:40 -07001297 glActiveTexture(GL_TEXTURE0);
1298 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1299
1300 // Create an 8x8 (i.e. power-of-two) texture.
1301 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1303 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1304 glGenerateMipmap(GL_TEXTURE_2D);
1305
1306 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1307 // This should always work, even if GL_OES_texture_npot isn't active.
1308 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1309
1310 EXPECT_GL_NO_ERROR();
1311}
1312
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001313// Test to check that texture completeness is determined correctly when the texture base level is
1314// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1315TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1316{
1317 glActiveTexture(GL_TEXTURE0);
1318 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1319 GLubyte texDataRed[4u * 4u * 4u];
1320 for (size_t i = 0u; i < 4u * 4u; ++i)
1321 {
1322 texDataRed[i * 4u] = 255u;
1323 texDataRed[i * 4u + 1u] = 0u;
1324 texDataRed[i * 4u + 2u] = 0u;
1325 texDataRed[i * 4u + 3u] = 255u;
1326 }
1327 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
1328 GLubyte texDataGreen[2u * 2u * 4u];
1329 for (size_t i = 0u; i < 2u * 2u; ++i)
1330 {
1331 texDataGreen[i * 4u] = 0u;
1332 texDataGreen[i * 4u + 1u] = 255u;
1333 texDataGreen[i * 4u + 2u] = 0u;
1334 texDataGreen[i * 4u + 3u] = 255u;
1335 }
1336 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1337 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1338 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1339 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1341
1342 EXPECT_GL_NO_ERROR();
1343
1344 drawQuad(mProgram, "position", 0.5f);
1345
1346 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1347}
1348
Jamie Madill2453dbc2015-07-14 11:35:42 -04001349// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
1350// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
1351// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001352TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04001353{
1354 std::vector<GLubyte> pixelData;
1355 for (size_t count = 0; count < 5000; count++)
1356 {
1357 pixelData.push_back(0u);
1358 pixelData.push_back(255u);
1359 pixelData.push_back(0u);
1360 }
1361
1362 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001363 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001364 glUniform1i(mTextureArrayLocation, 0);
1365
1366 // The first draw worked correctly.
1367 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
1368
1369 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1370 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1371 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1372 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001373 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001374 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1375
1376 // The dimension of the respecification must match the original exactly to trigger the bug.
1377 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 +02001378 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001379 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1380
1381 ASSERT_GL_NO_ERROR();
1382}
1383
Olli Etuaho1a679902016-01-14 12:21:47 +02001384// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
1385// This test is needed especially to confirm that sampler registers get assigned correctly on
1386// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
1387TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
1388{
1389 glActiveTexture(GL_TEXTURE0);
1390 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1391 GLubyte texData[4];
1392 texData[0] = 0;
1393 texData[1] = 60;
1394 texData[2] = 0;
1395 texData[3] = 255;
1396 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1397
1398 glActiveTexture(GL_TEXTURE1);
1399 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1400 GLfloat depthTexData[1];
1401 depthTexData[0] = 0.5f;
1402 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1403 depthTexData);
1404
1405 glUseProgram(mProgram);
1406 glUniform1f(mDepthRefUniformLocation, 0.3f);
1407 glUniform1i(mTexture3DUniformLocation, 0);
1408 glUniform1i(mTextureShadowUniformLocation, 1);
1409
1410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1411 drawQuad(mProgram, "position", 0.5f);
1412 EXPECT_GL_NO_ERROR();
1413 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
1414 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
1415
1416 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
1417 drawQuad(mProgram, "position", 0.5f);
1418 EXPECT_GL_NO_ERROR();
1419 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
1420 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
1421}
1422
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001423// Test multiple different sampler types in the same shader.
1424// This test makes sure that even if sampler / texture registers get grouped together based on type
1425// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
1426// still has the right register index information for each ESSL sampler.
1427// The tested ESSL samplers have the following types in D3D11 HLSL:
1428// sampler2D: Texture2D + SamplerState
1429// samplerCube: TextureCube + SamplerState
1430// sampler2DShadow: Texture2D + SamplerComparisonState
1431// samplerCubeShadow: TextureCube + SamplerComparisonState
1432TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
1433{
1434 glActiveTexture(GL_TEXTURE0);
1435 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1436 GLubyte texData[4];
1437 texData[0] = 0;
1438 texData[1] = 0;
1439 texData[2] = 120;
1440 texData[3] = 255;
1441 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1442
1443 glActiveTexture(GL_TEXTURE1);
1444 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1445 texData[0] = 0;
1446 texData[1] = 90;
1447 texData[2] = 0;
1448 texData[3] = 255;
1449 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
1450 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1451 texData);
1452
1453 glActiveTexture(GL_TEXTURE2);
1454 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1455 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1456 GLfloat depthTexData[1];
1457 depthTexData[0] = 0.5f;
1458 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1459 depthTexData);
1460
1461 glActiveTexture(GL_TEXTURE3);
1462 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1463 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1464 depthTexData[0] = 0.2f;
1465 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1466 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
1467 depthTexData);
1468
1469 EXPECT_GL_NO_ERROR();
1470
1471 glUseProgram(mProgram);
1472 glUniform1f(mDepthRefUniformLocation, 0.3f);
1473 glUniform1i(mTexture2DUniformLocation, 0);
1474 glUniform1i(mTextureCubeUniformLocation, 1);
1475 glUniform1i(mTexture2DShadowUniformLocation, 2);
1476 glUniform1i(mTextureCubeShadowUniformLocation, 3);
1477
1478 drawQuad(mProgram, "position", 0.5f);
1479 EXPECT_GL_NO_ERROR();
1480 // The shader writes:
1481 // <texture 2d color> +
1482 // <cube map color> +
1483 // 0.25 * <comparison result (1.0)> +
1484 // 0.125 * <comparison result (0.0)>
1485 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
1486}
1487
Olli Etuahobce743a2016-01-15 17:18:28 +02001488// Test different base levels on textures accessed through the same sampler array.
1489// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
1490TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
1491{
1492 if ((isAMD() || isIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
1493 {
1494 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
1495 return;
1496 }
1497 glActiveTexture(GL_TEXTURE0);
1498 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
1499 GLsizei size = 64;
1500 for (GLint level = 0; level < 7; ++level)
1501 {
1502 ASSERT_LT(0, size);
1503 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1504 nullptr);
1505 size = size / 2;
1506 }
1507 ASSERT_EQ(0, size);
1508 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1509
1510 glActiveTexture(GL_TEXTURE1);
1511 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
1512 size = 128;
1513 for (GLint level = 0; level < 8; ++level)
1514 {
1515 ASSERT_LT(0, size);
1516 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1517 nullptr);
1518 size = size / 2;
1519 }
1520 ASSERT_EQ(0, size);
1521 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
1522 EXPECT_GL_NO_ERROR();
1523
1524 glUseProgram(mProgram);
1525 glUniform1i(mTexture0Location, 0);
1526 glUniform1i(mTexture1Location, 1);
1527
1528 drawQuad(mProgram, "position", 0.5f);
1529 EXPECT_GL_NO_ERROR();
1530 // Red channel: width of level 1 of texture A: 32.
1531 // Green channel: width of level 3 of texture B: 16.
1532 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
1533}
1534
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001535class TextureLimitsTest : public ANGLETest
1536{
1537 protected:
1538 struct RGBA8
1539 {
1540 uint8_t R, G, B, A;
1541 };
1542
1543 TextureLimitsTest()
1544 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
1545 {
1546 setWindowWidth(128);
1547 setWindowHeight(128);
1548 setConfigRedBits(8);
1549 setConfigGreenBits(8);
1550 setConfigBlueBits(8);
1551 setConfigAlphaBits(8);
1552 }
1553
1554 ~TextureLimitsTest()
1555 {
1556 if (mProgram != 0)
1557 {
1558 glDeleteProgram(mProgram);
1559 mProgram = 0;
1560
1561 if (!mTextures.empty())
1562 {
1563 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
1564 }
1565 }
1566 }
1567
1568 void SetUp() override
1569 {
1570 ANGLETest::SetUp();
1571
1572 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
1573 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
1574 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
1575
1576 ASSERT_GL_NO_ERROR();
1577 }
1578
1579 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
1580 GLint vertexTextureCount,
1581 GLint vertexActiveTextureCount,
1582 const std::string &fragPrefix,
1583 GLint fragmentTextureCount,
1584 GLint fragmentActiveTextureCount)
1585 {
1586 std::stringstream vertexShaderStr;
1587 vertexShaderStr << "attribute vec2 position;\n"
1588 << "varying vec4 color;\n"
1589 << "varying vec2 texCoord;\n";
1590
1591 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
1592 {
1593 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
1594 }
1595
1596 vertexShaderStr << "void main() {\n"
1597 << " gl_Position = vec4(position, 0, 1);\n"
1598 << " texCoord = (position * 0.5) + 0.5;\n"
1599 << " color = vec4(0);\n";
1600
1601 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
1602 {
1603 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
1604 << ", texCoord);\n";
1605 }
1606
1607 vertexShaderStr << "}";
1608
1609 std::stringstream fragmentShaderStr;
1610 fragmentShaderStr << "varying mediump vec4 color;\n"
1611 << "varying mediump vec2 texCoord;\n";
1612
1613 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
1614 {
1615 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
1616 }
1617
1618 fragmentShaderStr << "void main() {\n"
1619 << " gl_FragColor = color;\n";
1620
1621 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
1622 {
1623 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
1624 << ", texCoord);\n";
1625 }
1626
1627 fragmentShaderStr << "}";
1628
1629 const std::string &vertexShaderSource = vertexShaderStr.str();
1630 const std::string &fragmentShaderSource = fragmentShaderStr.str();
1631
1632 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
1633 }
1634
1635 RGBA8 getPixel(GLint texIndex)
1636 {
1637 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
1638 0, 255u};
1639 return pixel;
1640 }
1641
1642 void initTextures(GLint tex2DCount, GLint texCubeCount)
1643 {
1644 GLint totalCount = tex2DCount + texCubeCount;
1645 mTextures.assign(totalCount, 0);
1646 glGenTextures(totalCount, &mTextures[0]);
1647 ASSERT_GL_NO_ERROR();
1648
1649 std::vector<RGBA8> texData(16 * 16);
1650
1651 GLint texIndex = 0;
1652 for (; texIndex < tex2DCount; ++texIndex)
1653 {
1654 texData.assign(texData.size(), getPixel(texIndex));
1655 glActiveTexture(GL_TEXTURE0 + texIndex);
1656 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
1657 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1658 &texData[0]);
1659 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1660 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1661 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1662 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1663 }
1664
1665 ASSERT_GL_NO_ERROR();
1666
1667 for (; texIndex < texCubeCount; ++texIndex)
1668 {
1669 texData.assign(texData.size(), getPixel(texIndex));
1670 glActiveTexture(GL_TEXTURE0 + texIndex);
1671 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
1672 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1673 GL_UNSIGNED_BYTE, &texData[0]);
1674 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1675 GL_UNSIGNED_BYTE, &texData[0]);
1676 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1677 GL_UNSIGNED_BYTE, &texData[0]);
1678 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1679 GL_UNSIGNED_BYTE, &texData[0]);
1680 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1681 GL_UNSIGNED_BYTE, &texData[0]);
1682 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1683 GL_UNSIGNED_BYTE, &texData[0]);
1684 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1685 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1686 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1687 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1688 }
1689
1690 ASSERT_GL_NO_ERROR();
1691 }
1692
1693 void testWithTextures(GLint vertexTextureCount,
1694 const std::string &vertexTexturePrefix,
1695 GLint fragmentTextureCount,
1696 const std::string &fragmentTexturePrefix)
1697 {
1698 // Generate textures
1699 initTextures(vertexTextureCount + fragmentTextureCount, 0);
1700
1701 glUseProgram(mProgram);
1702 RGBA8 expectedSum = {0};
1703 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
1704 {
1705 std::stringstream uniformNameStr;
1706 uniformNameStr << vertexTexturePrefix << texIndex;
1707 const std::string &uniformName = uniformNameStr.str();
1708 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1709 ASSERT_NE(-1, location);
1710
1711 glUniform1i(location, texIndex);
1712 RGBA8 contribution = getPixel(texIndex);
1713 expectedSum.R += contribution.R;
1714 expectedSum.G += contribution.G;
1715 }
1716
1717 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
1718 {
1719 std::stringstream uniformNameStr;
1720 uniformNameStr << fragmentTexturePrefix << texIndex;
1721 const std::string &uniformName = uniformNameStr.str();
1722 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1723 ASSERT_NE(-1, location);
1724
1725 glUniform1i(location, texIndex + vertexTextureCount);
1726 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
1727 expectedSum.R += contribution.R;
1728 expectedSum.G += contribution.G;
1729 }
1730
1731 ASSERT_GE(256u, expectedSum.G);
1732
1733 drawQuad(mProgram, "position", 0.5f);
1734 ASSERT_GL_NO_ERROR();
1735 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
1736 }
1737
1738 GLuint mProgram;
1739 std::vector<GLuint> mTextures;
1740 GLint mMaxVertexTextures;
1741 GLint mMaxFragmentTextures;
1742 GLint mMaxCombinedTextures;
1743};
1744
1745// Test rendering with the maximum vertex texture units.
1746TEST_P(TextureLimitsTest, MaxVertexTextures)
1747{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001748 // TODO(jmadill): Figure out why this fails on Intel.
1749 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1750 {
1751 std::cout << "Test skipped on Intel." << std::endl;
1752 return;
1753 }
1754
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001755 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
1756 ASSERT_NE(0u, mProgram);
1757 ASSERT_GL_NO_ERROR();
1758
1759 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1760}
1761
1762// Test rendering with the maximum fragment texture units.
1763TEST_P(TextureLimitsTest, MaxFragmentTextures)
1764{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001765 // TODO(jmadill): Figure out why this fails on Intel.
1766 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1767 {
1768 std::cout << "Test skipped on Intel." << std::endl;
1769 return;
1770 }
1771
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001772 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
1773 ASSERT_NE(0u, mProgram);
1774 ASSERT_GL_NO_ERROR();
1775
1776 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
1777}
1778
1779// Test rendering with maximum combined texture units.
1780TEST_P(TextureLimitsTest, MaxCombinedTextures)
1781{
Jamie Madill412f17d2015-09-25 08:43:54 -04001782 // TODO(jmadill): Investigate workaround.
1783 if (isIntel() && GetParam() == ES2_OPENGL())
1784 {
1785 std::cout << "Test skipped on Intel." << std::endl;
1786 return;
1787 }
1788
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001789 GLint vertexTextures = mMaxVertexTextures;
1790
1791 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
1792 {
1793 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
1794 }
1795
1796 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
1797 mMaxFragmentTextures, mMaxFragmentTextures);
1798 ASSERT_NE(0u, mProgram);
1799 ASSERT_GL_NO_ERROR();
1800
1801 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
1802}
1803
1804// Negative test for exceeding the number of vertex textures
1805TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
1806{
1807 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
1808 0);
1809 ASSERT_EQ(0u, mProgram);
1810}
1811
1812// Negative test for exceeding the number of fragment textures
1813TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
1814{
1815 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
1816 mMaxFragmentTextures + 1);
1817 ASSERT_EQ(0u, mProgram);
1818}
1819
1820// Test active vertex textures under the limit, but excessive textures specified.
1821TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
1822{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001823 // TODO(jmadill): Figure out why this fails on Intel.
1824 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1825 {
1826 std::cout << "Test skipped on Intel." << std::endl;
1827 return;
1828 }
1829
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001830 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
1831 ASSERT_NE(0u, mProgram);
1832 ASSERT_GL_NO_ERROR();
1833
1834 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1835}
1836
1837// Test active fragment textures under the limit, but excessive textures specified.
1838TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
1839{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001840 // TODO(jmadill): Figure out why this fails on Intel.
1841 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1842 {
1843 std::cout << "Test skipped on Intel." << std::endl;
1844 return;
1845 }
1846
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001847 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
1848 mMaxFragmentTextures);
1849 ASSERT_NE(0u, mProgram);
1850 ASSERT_GL_NO_ERROR();
1851
1852 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
1853}
1854
1855// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001856// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001857TEST_P(TextureLimitsTest, TextureTypeConflict)
1858{
1859 const std::string &vertexShader =
1860 "attribute vec2 position;\n"
1861 "varying float color;\n"
1862 "uniform sampler2D tex2D;\n"
1863 "uniform samplerCube texCube;\n"
1864 "void main() {\n"
1865 " gl_Position = vec4(position, 0, 1);\n"
1866 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1867 " color = texture2D(tex2D, texCoord).x;\n"
1868 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
1869 "}";
1870 const std::string &fragmentShader =
1871 "varying mediump float color;\n"
1872 "void main() {\n"
1873 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1874 "}";
1875
1876 mProgram = CompileProgram(vertexShader, fragmentShader);
1877 ASSERT_NE(0u, mProgram);
1878
1879 initTextures(1, 0);
1880
1881 glUseProgram(mProgram);
1882 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1883 ASSERT_NE(-1, tex2DLocation);
1884 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
1885 ASSERT_NE(-1, texCubeLocation);
1886
1887 glUniform1i(tex2DLocation, 0);
1888 glUniform1i(texCubeLocation, 0);
1889 ASSERT_GL_NO_ERROR();
1890
1891 drawQuad(mProgram, "position", 0.5f);
1892 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1893}
1894
1895// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001896// TODO(jmadill): Possibly adjust the test according to the spec:
1897// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
1898// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001899TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
1900{
1901 const std::string &vertexShader =
1902 "attribute vec2 position;\n"
1903 "varying float color;\n"
1904 "uniform sampler2D tex2D;\n"
1905 "void main() {\n"
1906 " gl_Position = vec4(position, 0, 1);\n"
1907 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1908 " color = texture2D(tex2D, texCoord).x;\n"
1909 "}";
1910 const std::string &fragmentShader =
1911 "varying mediump float color;\n"
1912 "void main() {\n"
1913 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1914 "}";
1915
1916 mProgram = CompileProgram(vertexShader, fragmentShader);
1917 ASSERT_NE(0u, mProgram);
1918
1919 glUseProgram(mProgram);
1920 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1921 ASSERT_NE(-1, tex2DLocation);
1922
1923 glUniform1i(tex2DLocation, mMaxCombinedTextures);
1924 ASSERT_GL_NO_ERROR();
1925
1926 drawQuad(mProgram, "position", 0.5f);
1927 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1928}
1929
Jamie Madillfa05f602015-05-07 13:47:11 -04001930// 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 +02001931// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05001932ANGLE_INSTANTIATE_TEST(Texture2DTest,
1933 ES2_D3D9(),
1934 ES2_D3D11(),
1935 ES2_D3D11_FL9_3(),
1936 ES2_OPENGL(),
1937 ES2_OPENGLES());
1938ANGLE_INSTANTIATE_TEST(TextureCubeTest,
1939 ES2_D3D9(),
1940 ES2_D3D11(),
1941 ES2_D3D11_FL9_3(),
1942 ES2_OPENGL(),
1943 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02001944ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
1945 ES2_D3D9(),
1946 ES2_D3D11(),
1947 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05001948 ES2_OPENGL(),
1949 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02001950ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
1951 ES2_D3D9(),
1952 ES2_D3D11(),
1953 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05001954 ES2_OPENGL(),
1955 ES2_OPENGLES());
1956ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
1957 ES2_D3D9(),
1958 ES2_D3D11(),
1959 ES2_D3D11_FL9_3(),
1960 ES2_OPENGL(),
1961 ES2_OPENGLES());
1962ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
1963 ES2_D3D9(),
1964 ES2_D3D11(),
1965 ES2_D3D11_FL9_3(),
1966 ES2_OPENGL(),
1967 ES2_OPENGLES());
1968ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
1969ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
1970 ES3_D3D11(),
1971 ES3_OPENGL(),
1972 ES3_OPENGLES());
1973ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
1974ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02001975ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Geoff Lange0cc2a42016-01-20 10:58:17 -05001976ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04001977
1978} // namespace