blob: 261ff743b48a29e9a6ac29f57302b6034c05dc08 [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 Etuaho1a679902016-01-14 12:21:47 +0200601class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
602{
603 protected:
604 ShadowSamplerPlusSampler3DTestES3()
605 : TexCoordDrawTest(),
606 mTextureShadow(0),
607 mTexture3D(0),
608 mTextureShadowUniformLocation(-1),
609 mTexture3DUniformLocation(-1),
610 mDepthRefUniformLocation(-1)
611 {
612 }
613
614 std::string getVertexShaderSource() override
615 {
616 return std::string(
617 "#version 300 es\n"
618 "out vec2 texcoord;\n"
619 "in vec4 position;\n"
620 "void main()\n"
621 "{\n"
622 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
623 " texcoord = (position.xy * 0.5) + 0.5;\n"
624 "}\n");
625 }
626
627 std::string getFragmentShaderSource() override
628 {
629 return std::string(
630 "#version 300 es\n"
631 "precision highp float;\n"
632 "uniform highp sampler2DShadow tex2DShadow;\n"
633 "uniform highp sampler3D tex3D;\n"
634 "in vec2 texcoord;\n"
635 "uniform float depthRef;\n"
636 "out vec4 fragColor;\n"
637 "void main()\n"
638 "{\n"
639 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
640 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
641 "}\n");
642 }
643
644 void SetUp() override
645 {
646 TexCoordDrawTest::SetUp();
647
648 glGenTextures(1, &mTexture3D);
649
650 glGenTextures(1, &mTextureShadow);
651 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
652 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
653
654 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
655 ASSERT_NE(-1, mTextureShadowUniformLocation);
656 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
657 ASSERT_NE(-1, mTexture3DUniformLocation);
658 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
659 ASSERT_NE(-1, mDepthRefUniformLocation);
660 }
661
662 void TearDown() override
663 {
664 glDeleteTextures(1, &mTextureShadow);
665 glDeleteTextures(1, &mTexture3D);
666 TexCoordDrawTest::TearDown();
667 }
668
669 GLuint mTextureShadow;
670 GLuint mTexture3D;
671 GLint mTextureShadowUniformLocation;
672 GLint mTexture3DUniformLocation;
673 GLint mDepthRefUniformLocation;
674};
675
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200676class SamplerTypeMixTestES3 : public TexCoordDrawTest
677{
678 protected:
679 SamplerTypeMixTestES3()
680 : TexCoordDrawTest(),
681 mTexture2D(0),
682 mTextureCube(0),
683 mTexture2DShadow(0),
684 mTextureCubeShadow(0),
685 mTexture2DUniformLocation(-1),
686 mTextureCubeUniformLocation(-1),
687 mTexture2DShadowUniformLocation(-1),
688 mTextureCubeShadowUniformLocation(-1),
689 mDepthRefUniformLocation(-1)
690 {
691 }
692
693 std::string getVertexShaderSource() override
694 {
695 return std::string(
696 "#version 300 es\n"
697 "out vec2 texcoord;\n"
698 "in vec4 position;\n"
699 "void main()\n"
700 "{\n"
701 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
702 " texcoord = (position.xy * 0.5) + 0.5;\n"
703 "}\n");
704 }
705
706 std::string getFragmentShaderSource() override
707 {
708 return std::string(
709 "#version 300 es\n"
710 "precision highp float;\n"
711 "uniform highp sampler2D tex2D;\n"
712 "uniform highp samplerCube texCube;\n"
713 "uniform highp sampler2DShadow tex2DShadow;\n"
714 "uniform highp samplerCubeShadow texCubeShadow;\n"
715 "in vec2 texcoord;\n"
716 "uniform float depthRef;\n"
717 "out vec4 fragColor;\n"
718 "void main()\n"
719 "{\n"
720 " fragColor = texture(tex2D, texcoord);\n"
721 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
722 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
723 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
724 "0.125);\n"
725 "}\n");
726 }
727
728 void SetUp() override
729 {
730 TexCoordDrawTest::SetUp();
731
732 glGenTextures(1, &mTexture2D);
733 glGenTextures(1, &mTextureCube);
734
735 glGenTextures(1, &mTexture2DShadow);
736 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
738
739 glGenTextures(1, &mTextureCubeShadow);
740 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
741 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
742
743 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
744 ASSERT_NE(-1, mTexture2DUniformLocation);
745 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
746 ASSERT_NE(-1, mTextureCubeUniformLocation);
747 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
748 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
749 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
750 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
751 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
752 ASSERT_NE(-1, mDepthRefUniformLocation);
753
754 ASSERT_GL_NO_ERROR();
755 }
756
757 void TearDown() override
758 {
759 glDeleteTextures(1, &mTexture2D);
760 glDeleteTextures(1, &mTextureCube);
761 glDeleteTextures(1, &mTexture2DShadow);
762 glDeleteTextures(1, &mTextureCubeShadow);
763 TexCoordDrawTest::TearDown();
764 }
765
766 GLuint mTexture2D;
767 GLuint mTextureCube;
768 GLuint mTexture2DShadow;
769 GLuint mTextureCubeShadow;
770 GLint mTexture2DUniformLocation;
771 GLint mTextureCubeUniformLocation;
772 GLint mTexture2DShadowUniformLocation;
773 GLint mTextureCubeShadowUniformLocation;
774 GLint mDepthRefUniformLocation;
775};
776
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200777TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400778{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400779 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400780 EXPECT_GL_ERROR(GL_NO_ERROR);
781
782 const GLubyte *pixels[20] = { 0 };
783 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
784 EXPECT_GL_ERROR(GL_INVALID_VALUE);
785}
Geoff Langc41e42d2014-04-28 10:58:16 -0400786
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200787TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400788{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400789 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400790 EXPECT_GL_ERROR(GL_NO_ERROR);
791
792 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200793 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400794 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200795 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400796
797 const GLubyte *pixel[4] = { 0 };
798
799 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
800 EXPECT_GL_NO_ERROR();
801
802 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
803 EXPECT_GL_NO_ERROR();
804
805 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
806 EXPECT_GL_NO_ERROR();
807}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400808
809// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200810TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400811{
812 glActiveTexture(GL_TEXTURE0);
813 glBindTexture(GL_TEXTURE_2D, mTexture2D);
814 glActiveTexture(GL_TEXTURE1);
815 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
816 EXPECT_GL_ERROR(GL_NO_ERROR);
817
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200818 glUseProgram(mProgram);
819 glUniform1i(mTexture2DUniformLocation, 0);
820 glUniform1i(mTextureCubeUniformLocation, 1);
821 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400822 EXPECT_GL_NO_ERROR();
823}
Jamie Madill9aca0592014-10-06 16:26:59 -0400824
Olli Etuaho53a2da12016-01-11 15:43:32 +0200825// Test drawing with two texture types accessed from the same shader and check that the result of
826// drawing is correct.
827TEST_P(TextureCubeTest, CubeMapDraw)
828{
829 GLubyte texData[4];
830 texData[0] = 0;
831 texData[1] = 60;
832 texData[2] = 0;
833 texData[3] = 255;
834
835 glActiveTexture(GL_TEXTURE0);
836 glBindTexture(GL_TEXTURE_2D, mTexture2D);
837 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
838
839 glActiveTexture(GL_TEXTURE1);
840 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
841 texData[1] = 120;
842 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
843 texData);
844 EXPECT_GL_ERROR(GL_NO_ERROR);
845
846 glUseProgram(mProgram);
847 glUniform1i(mTexture2DUniformLocation, 0);
848 glUniform1i(mTextureCubeUniformLocation, 1);
849 drawQuad(mProgram, "position", 0.5f);
850 EXPECT_GL_NO_ERROR();
851
852 int px = getWindowWidth() - 1;
853 int py = 0;
854 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
855}
856
Olli Etuaho4644a202016-01-12 15:12:53 +0200857TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
858{
859 glActiveTexture(GL_TEXTURE0);
860 glBindTexture(GL_TEXTURE_2D, mTexture2D);
861 GLubyte texData[4];
862 texData[0] = 0;
863 texData[1] = 128;
864 texData[2] = 0;
865 texData[3] = 255;
866 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
867 glUseProgram(mProgram);
868 glUniform1i(mTexture2DUniformLocation, 0);
869 drawQuad(mProgram, "position", 0.5f);
870 EXPECT_GL_NO_ERROR();
871
872 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
873}
874
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200875// Test drawing with two textures passed to the shader in a sampler array.
876TEST_P(SamplerArrayTest, SamplerArrayDraw)
877{
878 testSamplerArrayDraw();
879}
880
881// Test drawing with two textures passed to the shader in a sampler array which is passed to a
882// user-defined function in the shader.
883TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
884{
885 testSamplerArrayDraw();
886}
887
Jamie Madill9aca0592014-10-06 16:26:59 -0400888// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200889TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -0400890{
891 int px = getWindowWidth() / 2;
892 int py = getWindowHeight() / 2;
893
894 glActiveTexture(GL_TEXTURE0);
895 glBindTexture(GL_TEXTURE_2D, mTexture2D);
896
897 // Fill with red
898 std::vector<GLubyte> pixels(4 * 16 * 16);
899 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
900 {
901 pixels[pixelId * 4 + 0] = 255;
902 pixels[pixelId * 4 + 1] = 0;
903 pixels[pixelId * 4 + 2] = 0;
904 pixels[pixelId * 4 + 3] = 255;
905 }
906
907 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
908 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
909 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
910 glGenerateMipmap(GL_TEXTURE_2D);
911
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200912 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -0400913 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200914 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
915 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -0400916 EXPECT_GL_NO_ERROR();
917 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
918
919 // Fill with blue
920 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
921 {
922 pixels[pixelId * 4 + 0] = 0;
923 pixels[pixelId * 4 + 1] = 0;
924 pixels[pixelId * 4 + 2] = 255;
925 pixels[pixelId * 4 + 3] = 255;
926 }
927
928 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
929 glGenerateMipmap(GL_TEXTURE_2D);
930
931 // Fill with green
932 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
933 {
934 pixels[pixelId * 4 + 0] = 0;
935 pixels[pixelId * 4 + 1] = 255;
936 pixels[pixelId * 4 + 2] = 0;
937 pixels[pixelId * 4 + 3] = 255;
938 }
939
940 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
941 glGenerateMipmap(GL_TEXTURE_2D);
942
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200943 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -0400944
945 EXPECT_GL_NO_ERROR();
946 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
947}
Jamie Madillf8fccb32014-11-12 15:05:26 -0500948
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500949// Test creating a FBO with a cube map render target, to test an ANGLE bug
950// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200951TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500952{
953 GLuint fbo;
954 glGenFramebuffers(1, &fbo);
955 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
956
957 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
958 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
959
Corentin Wallez322653b2015-06-17 18:33:56 +0200960 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500961
962 glDeleteFramebuffers(1, &fbo);
963
964 EXPECT_GL_NO_ERROR();
965}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000966
967// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200968TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000969{
970 int width = getWindowWidth();
971 int height = getWindowHeight();
972
973 GLuint tex2D;
974 glGenTextures(1, &tex2D);
975 glActiveTexture(GL_TEXTURE0);
976 glBindTexture(GL_TEXTURE_2D, tex2D);
977
978 // Fill with red
979 std::vector<GLubyte> pixels(3 * 16 * 16);
980 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
981 {
982 pixels[pixelId * 3 + 0] = 255;
983 pixels[pixelId * 3 + 1] = 0;
984 pixels[pixelId * 3 + 2] = 0;
985 }
986
987 // ANGLE internally uses RGBA as the DirectX format for RGB images
988 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
989 // The data is kept in a CPU-side image and the image is marked as dirty.
990 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
991
992 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
993 // glTexSubImage2D should take into account that the image is dirty.
994 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
995 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
996 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
997
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200998 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000999 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001000 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001001 glDeleteTextures(1, &tex2D);
1002 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001003 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001004
1005 // Validate that the region of the texture without data has an alpha of 1.0
1006 GLubyte pixel[4];
1007 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1008 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001009}
1010
1011// 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 +02001012TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001013{
1014 if (extensionEnabled("NV_pixel_buffer_object"))
1015 {
1016 int width = getWindowWidth();
1017 int height = getWindowHeight();
1018
1019 GLuint tex2D;
1020 glGenTextures(1, &tex2D);
1021 glActiveTexture(GL_TEXTURE0);
1022 glBindTexture(GL_TEXTURE_2D, tex2D);
1023
1024 // Fill with red
1025 std::vector<GLubyte> pixels(3 * 16 * 16);
1026 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1027 {
1028 pixels[pixelId * 3 + 0] = 255;
1029 pixels[pixelId * 3 + 1] = 0;
1030 pixels[pixelId * 3 + 2] = 0;
1031 }
1032
1033 // Read 16x16 region from red backbuffer to PBO
1034 GLuint pbo;
1035 glGenBuffers(1, &pbo);
1036 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1037 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1038
1039 // ANGLE internally uses RGBA as the DirectX format for RGB images
1040 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1041 // The data is kept in a CPU-side image and the image is marked as dirty.
1042 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1043
1044 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1045 // glTexSubImage2D should take into account that the image is dirty.
1046 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1047 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1048 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1049
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001050 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001051 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001052 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001053 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001054 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001055 EXPECT_GL_NO_ERROR();
1056 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1057 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1058 }
1059}
Jamie Madillbc393df2015-01-29 13:46:07 -05001060
1061// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001062TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001063{
1064 testFloatCopySubImage(1, 1);
1065}
1066
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001067TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001068{
1069 testFloatCopySubImage(2, 1);
1070}
1071
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001072TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001073{
1074 testFloatCopySubImage(2, 2);
1075}
1076
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001077TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001078{
1079 testFloatCopySubImage(3, 1);
1080}
1081
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001082TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001083{
1084 testFloatCopySubImage(3, 2);
1085}
1086
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001087TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001088{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001089 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1090 if (isD3D11_FL93())
1091 {
1092 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1093 return;
1094 }
1095
Jamie Madillbc393df2015-01-29 13:46:07 -05001096 testFloatCopySubImage(3, 3);
1097}
1098
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001099TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001100{
1101 testFloatCopySubImage(4, 1);
1102}
1103
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001104TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001105{
1106 testFloatCopySubImage(4, 2);
1107}
1108
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001109TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001110{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001111 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1112 if (isD3D11_FL93())
1113 {
1114 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1115 return;
1116 }
1117
Jamie Madillbc393df2015-01-29 13:46:07 -05001118 testFloatCopySubImage(4, 3);
1119}
1120
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001121TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001122{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001123 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
1124 if (isD3D11_FL93())
1125 {
1126 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1127 return;
1128 }
1129
Jamie Madillbc393df2015-01-29 13:46:07 -05001130 testFloatCopySubImage(4, 4);
1131}
Austin Kinross07285142015-03-26 11:36:16 -07001132
1133// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1134// 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 +02001135TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001136{
1137 const int npotTexSize = 5;
1138 const int potTexSize = 4; // Should be less than npotTexSize
1139 GLuint tex2D;
1140
1141 if (extensionEnabled("GL_OES_texture_npot"))
1142 {
1143 // This test isn't applicable if texture_npot is enabled
1144 return;
1145 }
1146
1147 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1148
Austin Kinross5faa15b2016-01-11 13:32:48 -08001149 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1150 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1151
Austin Kinross07285142015-03-26 11:36:16 -07001152 glActiveTexture(GL_TEXTURE0);
1153 glGenTextures(1, &tex2D);
1154 glBindTexture(GL_TEXTURE_2D, tex2D);
1155
1156 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1157 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1158 {
1159 pixels[pixelId] = 64;
1160 }
1161
1162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1164
1165 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1166 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1167 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1168
1169 // Check that an NPOT texture on level 0 succeeds
1170 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1171 EXPECT_GL_NO_ERROR();
1172
1173 // Check that generateMipmap fails on NPOT
1174 glGenerateMipmap(GL_TEXTURE_2D);
1175 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1176
1177 // Check that nothing is drawn if filtering is not correct for NPOT
1178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1182 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001183 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001184 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1185
1186 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1187 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1190 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001191 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001192 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1193
1194 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1196 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001197 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001198 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1199
1200 // Check that glTexImage2D for POT texture succeeds
1201 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1202 EXPECT_GL_NO_ERROR();
1203
1204 // Check that generateMipmap for an POT texture succeeds
1205 glGenerateMipmap(GL_TEXTURE_2D);
1206 EXPECT_GL_NO_ERROR();
1207
1208 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1209 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1210 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1211 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1213 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001214 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001215 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1216 EXPECT_GL_NO_ERROR();
1217}
Jamie Madillfa05f602015-05-07 13:47:11 -04001218
Austin Kinross08528e12015-10-07 16:24:40 -07001219// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1220// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001221TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001222{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001223 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1224 // 1278)
1225 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1226 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1227 {
1228 std::cout << "Test disabled on OpenGL." << std::endl;
1229 return;
1230 }
1231
Austin Kinross08528e12015-10-07 16:24:40 -07001232 glActiveTexture(GL_TEXTURE0);
1233 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1234
1235 // Create an 8x8 (i.e. power-of-two) texture.
1236 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1239 glGenerateMipmap(GL_TEXTURE_2D);
1240
1241 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1242 // This should always work, even if GL_OES_texture_npot isn't active.
1243 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1244
1245 EXPECT_GL_NO_ERROR();
1246}
1247
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001248// Test to check that texture completeness is determined correctly when the texture base level is
1249// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1250TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1251{
1252 glActiveTexture(GL_TEXTURE0);
1253 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1254 GLubyte texDataRed[4u * 4u * 4u];
1255 for (size_t i = 0u; i < 4u * 4u; ++i)
1256 {
1257 texDataRed[i * 4u] = 255u;
1258 texDataRed[i * 4u + 1u] = 0u;
1259 texDataRed[i * 4u + 2u] = 0u;
1260 texDataRed[i * 4u + 3u] = 255u;
1261 }
1262 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
1263 GLubyte texDataGreen[2u * 2u * 4u];
1264 for (size_t i = 0u; i < 2u * 2u; ++i)
1265 {
1266 texDataGreen[i * 4u] = 0u;
1267 texDataGreen[i * 4u + 1u] = 255u;
1268 texDataGreen[i * 4u + 2u] = 0u;
1269 texDataGreen[i * 4u + 3u] = 255u;
1270 }
1271 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1272 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataGreen);
1273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1276
1277 EXPECT_GL_NO_ERROR();
1278
1279 drawQuad(mProgram, "position", 0.5f);
1280
1281 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1282}
1283
Jamie Madill2453dbc2015-07-14 11:35:42 -04001284// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
1285// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
1286// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001287TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04001288{
1289 std::vector<GLubyte> pixelData;
1290 for (size_t count = 0; count < 5000; count++)
1291 {
1292 pixelData.push_back(0u);
1293 pixelData.push_back(255u);
1294 pixelData.push_back(0u);
1295 }
1296
1297 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001298 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001299 glUniform1i(mTextureArrayLocation, 0);
1300
1301 // The first draw worked correctly.
1302 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
1303
1304 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1305 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1306 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1307 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001308 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001309 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1310
1311 // The dimension of the respecification must match the original exactly to trigger the bug.
1312 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 +02001313 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001314 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1315
1316 ASSERT_GL_NO_ERROR();
1317}
1318
Olli Etuaho1a679902016-01-14 12:21:47 +02001319// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
1320// This test is needed especially to confirm that sampler registers get assigned correctly on
1321// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
1322TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
1323{
1324 glActiveTexture(GL_TEXTURE0);
1325 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1326 GLubyte texData[4];
1327 texData[0] = 0;
1328 texData[1] = 60;
1329 texData[2] = 0;
1330 texData[3] = 255;
1331 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1332
1333 glActiveTexture(GL_TEXTURE1);
1334 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1335 GLfloat depthTexData[1];
1336 depthTexData[0] = 0.5f;
1337 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1338 depthTexData);
1339
1340 glUseProgram(mProgram);
1341 glUniform1f(mDepthRefUniformLocation, 0.3f);
1342 glUniform1i(mTexture3DUniformLocation, 0);
1343 glUniform1i(mTextureShadowUniformLocation, 1);
1344
1345 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1346 drawQuad(mProgram, "position", 0.5f);
1347 EXPECT_GL_NO_ERROR();
1348 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
1349 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
1350
1351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
1352 drawQuad(mProgram, "position", 0.5f);
1353 EXPECT_GL_NO_ERROR();
1354 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
1355 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
1356}
1357
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001358// Test multiple different sampler types in the same shader.
1359// This test makes sure that even if sampler / texture registers get grouped together based on type
1360// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
1361// still has the right register index information for each ESSL sampler.
1362// The tested ESSL samplers have the following types in D3D11 HLSL:
1363// sampler2D: Texture2D + SamplerState
1364// samplerCube: TextureCube + SamplerState
1365// sampler2DShadow: Texture2D + SamplerComparisonState
1366// samplerCubeShadow: TextureCube + SamplerComparisonState
1367TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
1368{
1369 glActiveTexture(GL_TEXTURE0);
1370 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1371 GLubyte texData[4];
1372 texData[0] = 0;
1373 texData[1] = 0;
1374 texData[2] = 120;
1375 texData[3] = 255;
1376 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1377
1378 glActiveTexture(GL_TEXTURE1);
1379 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1380 texData[0] = 0;
1381 texData[1] = 90;
1382 texData[2] = 0;
1383 texData[3] = 255;
1384 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
1385 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1386 texData);
1387
1388 glActiveTexture(GL_TEXTURE2);
1389 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1391 GLfloat depthTexData[1];
1392 depthTexData[0] = 0.5f;
1393 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
1394 depthTexData);
1395
1396 glActiveTexture(GL_TEXTURE3);
1397 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1398 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
1399 depthTexData[0] = 0.2f;
1400 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1401 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
1402 depthTexData);
1403
1404 EXPECT_GL_NO_ERROR();
1405
1406 glUseProgram(mProgram);
1407 glUniform1f(mDepthRefUniformLocation, 0.3f);
1408 glUniform1i(mTexture2DUniformLocation, 0);
1409 glUniform1i(mTextureCubeUniformLocation, 1);
1410 glUniform1i(mTexture2DShadowUniformLocation, 2);
1411 glUniform1i(mTextureCubeShadowUniformLocation, 3);
1412
1413 drawQuad(mProgram, "position", 0.5f);
1414 EXPECT_GL_NO_ERROR();
1415 // The shader writes:
1416 // <texture 2d color> +
1417 // <cube map color> +
1418 // 0.25 * <comparison result (1.0)> +
1419 // 0.125 * <comparison result (0.0)>
1420 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
1421}
1422
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001423class TextureLimitsTest : public ANGLETest
1424{
1425 protected:
1426 struct RGBA8
1427 {
1428 uint8_t R, G, B, A;
1429 };
1430
1431 TextureLimitsTest()
1432 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
1433 {
1434 setWindowWidth(128);
1435 setWindowHeight(128);
1436 setConfigRedBits(8);
1437 setConfigGreenBits(8);
1438 setConfigBlueBits(8);
1439 setConfigAlphaBits(8);
1440 }
1441
1442 ~TextureLimitsTest()
1443 {
1444 if (mProgram != 0)
1445 {
1446 glDeleteProgram(mProgram);
1447 mProgram = 0;
1448
1449 if (!mTextures.empty())
1450 {
1451 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
1452 }
1453 }
1454 }
1455
1456 void SetUp() override
1457 {
1458 ANGLETest::SetUp();
1459
1460 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
1461 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
1462 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
1463
1464 ASSERT_GL_NO_ERROR();
1465 }
1466
1467 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
1468 GLint vertexTextureCount,
1469 GLint vertexActiveTextureCount,
1470 const std::string &fragPrefix,
1471 GLint fragmentTextureCount,
1472 GLint fragmentActiveTextureCount)
1473 {
1474 std::stringstream vertexShaderStr;
1475 vertexShaderStr << "attribute vec2 position;\n"
1476 << "varying vec4 color;\n"
1477 << "varying vec2 texCoord;\n";
1478
1479 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
1480 {
1481 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
1482 }
1483
1484 vertexShaderStr << "void main() {\n"
1485 << " gl_Position = vec4(position, 0, 1);\n"
1486 << " texCoord = (position * 0.5) + 0.5;\n"
1487 << " color = vec4(0);\n";
1488
1489 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
1490 {
1491 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
1492 << ", texCoord);\n";
1493 }
1494
1495 vertexShaderStr << "}";
1496
1497 std::stringstream fragmentShaderStr;
1498 fragmentShaderStr << "varying mediump vec4 color;\n"
1499 << "varying mediump vec2 texCoord;\n";
1500
1501 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
1502 {
1503 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
1504 }
1505
1506 fragmentShaderStr << "void main() {\n"
1507 << " gl_FragColor = color;\n";
1508
1509 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
1510 {
1511 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
1512 << ", texCoord);\n";
1513 }
1514
1515 fragmentShaderStr << "}";
1516
1517 const std::string &vertexShaderSource = vertexShaderStr.str();
1518 const std::string &fragmentShaderSource = fragmentShaderStr.str();
1519
1520 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
1521 }
1522
1523 RGBA8 getPixel(GLint texIndex)
1524 {
1525 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
1526 0, 255u};
1527 return pixel;
1528 }
1529
1530 void initTextures(GLint tex2DCount, GLint texCubeCount)
1531 {
1532 GLint totalCount = tex2DCount + texCubeCount;
1533 mTextures.assign(totalCount, 0);
1534 glGenTextures(totalCount, &mTextures[0]);
1535 ASSERT_GL_NO_ERROR();
1536
1537 std::vector<RGBA8> texData(16 * 16);
1538
1539 GLint texIndex = 0;
1540 for (; texIndex < tex2DCount; ++texIndex)
1541 {
1542 texData.assign(texData.size(), getPixel(texIndex));
1543 glActiveTexture(GL_TEXTURE0 + texIndex);
1544 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
1545 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1546 &texData[0]);
1547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1550 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1551 }
1552
1553 ASSERT_GL_NO_ERROR();
1554
1555 for (; texIndex < texCubeCount; ++texIndex)
1556 {
1557 texData.assign(texData.size(), getPixel(texIndex));
1558 glActiveTexture(GL_TEXTURE0 + texIndex);
1559 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
1560 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1561 GL_UNSIGNED_BYTE, &texData[0]);
1562 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1563 GL_UNSIGNED_BYTE, &texData[0]);
1564 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1565 GL_UNSIGNED_BYTE, &texData[0]);
1566 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1567 GL_UNSIGNED_BYTE, &texData[0]);
1568 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1569 GL_UNSIGNED_BYTE, &texData[0]);
1570 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1571 GL_UNSIGNED_BYTE, &texData[0]);
1572 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1573 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1574 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1575 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1576 }
1577
1578 ASSERT_GL_NO_ERROR();
1579 }
1580
1581 void testWithTextures(GLint vertexTextureCount,
1582 const std::string &vertexTexturePrefix,
1583 GLint fragmentTextureCount,
1584 const std::string &fragmentTexturePrefix)
1585 {
1586 // Generate textures
1587 initTextures(vertexTextureCount + fragmentTextureCount, 0);
1588
1589 glUseProgram(mProgram);
1590 RGBA8 expectedSum = {0};
1591 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
1592 {
1593 std::stringstream uniformNameStr;
1594 uniformNameStr << vertexTexturePrefix << texIndex;
1595 const std::string &uniformName = uniformNameStr.str();
1596 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1597 ASSERT_NE(-1, location);
1598
1599 glUniform1i(location, texIndex);
1600 RGBA8 contribution = getPixel(texIndex);
1601 expectedSum.R += contribution.R;
1602 expectedSum.G += contribution.G;
1603 }
1604
1605 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
1606 {
1607 std::stringstream uniformNameStr;
1608 uniformNameStr << fragmentTexturePrefix << texIndex;
1609 const std::string &uniformName = uniformNameStr.str();
1610 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1611 ASSERT_NE(-1, location);
1612
1613 glUniform1i(location, texIndex + vertexTextureCount);
1614 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
1615 expectedSum.R += contribution.R;
1616 expectedSum.G += contribution.G;
1617 }
1618
1619 ASSERT_GE(256u, expectedSum.G);
1620
1621 drawQuad(mProgram, "position", 0.5f);
1622 ASSERT_GL_NO_ERROR();
1623 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
1624 }
1625
1626 GLuint mProgram;
1627 std::vector<GLuint> mTextures;
1628 GLint mMaxVertexTextures;
1629 GLint mMaxFragmentTextures;
1630 GLint mMaxCombinedTextures;
1631};
1632
1633// Test rendering with the maximum vertex texture units.
1634TEST_P(TextureLimitsTest, MaxVertexTextures)
1635{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001636 // TODO(jmadill): Figure out why this fails on Intel.
1637 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1638 {
1639 std::cout << "Test skipped on Intel." << std::endl;
1640 return;
1641 }
1642
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001643 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
1644 ASSERT_NE(0u, mProgram);
1645 ASSERT_GL_NO_ERROR();
1646
1647 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1648}
1649
1650// Test rendering with the maximum fragment texture units.
1651TEST_P(TextureLimitsTest, MaxFragmentTextures)
1652{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001653 // TODO(jmadill): Figure out why this fails on Intel.
1654 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1655 {
1656 std::cout << "Test skipped on Intel." << std::endl;
1657 return;
1658 }
1659
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001660 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
1661 ASSERT_NE(0u, mProgram);
1662 ASSERT_GL_NO_ERROR();
1663
1664 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
1665}
1666
1667// Test rendering with maximum combined texture units.
1668TEST_P(TextureLimitsTest, MaxCombinedTextures)
1669{
Jamie Madill412f17d2015-09-25 08:43:54 -04001670 // TODO(jmadill): Investigate workaround.
1671 if (isIntel() && GetParam() == ES2_OPENGL())
1672 {
1673 std::cout << "Test skipped on Intel." << std::endl;
1674 return;
1675 }
1676
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001677 GLint vertexTextures = mMaxVertexTextures;
1678
1679 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
1680 {
1681 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
1682 }
1683
1684 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
1685 mMaxFragmentTextures, mMaxFragmentTextures);
1686 ASSERT_NE(0u, mProgram);
1687 ASSERT_GL_NO_ERROR();
1688
1689 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
1690}
1691
1692// Negative test for exceeding the number of vertex textures
1693TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
1694{
1695 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
1696 0);
1697 ASSERT_EQ(0u, mProgram);
1698}
1699
1700// Negative test for exceeding the number of fragment textures
1701TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
1702{
1703 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
1704 mMaxFragmentTextures + 1);
1705 ASSERT_EQ(0u, mProgram);
1706}
1707
1708// Test active vertex textures under the limit, but excessive textures specified.
1709TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
1710{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001711 // TODO(jmadill): Figure out why this fails on Intel.
1712 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1713 {
1714 std::cout << "Test skipped on Intel." << std::endl;
1715 return;
1716 }
1717
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001718 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
1719 ASSERT_NE(0u, mProgram);
1720 ASSERT_GL_NO_ERROR();
1721
1722 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1723}
1724
1725// Test active fragment textures under the limit, but excessive textures specified.
1726TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
1727{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001728 // TODO(jmadill): Figure out why this fails on Intel.
1729 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1730 {
1731 std::cout << "Test skipped on Intel." << std::endl;
1732 return;
1733 }
1734
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001735 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
1736 mMaxFragmentTextures);
1737 ASSERT_NE(0u, mProgram);
1738 ASSERT_GL_NO_ERROR();
1739
1740 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
1741}
1742
1743// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001744// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001745TEST_P(TextureLimitsTest, TextureTypeConflict)
1746{
1747 const std::string &vertexShader =
1748 "attribute vec2 position;\n"
1749 "varying float color;\n"
1750 "uniform sampler2D tex2D;\n"
1751 "uniform samplerCube texCube;\n"
1752 "void main() {\n"
1753 " gl_Position = vec4(position, 0, 1);\n"
1754 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1755 " color = texture2D(tex2D, texCoord).x;\n"
1756 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
1757 "}";
1758 const std::string &fragmentShader =
1759 "varying mediump float color;\n"
1760 "void main() {\n"
1761 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1762 "}";
1763
1764 mProgram = CompileProgram(vertexShader, fragmentShader);
1765 ASSERT_NE(0u, mProgram);
1766
1767 initTextures(1, 0);
1768
1769 glUseProgram(mProgram);
1770 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1771 ASSERT_NE(-1, tex2DLocation);
1772 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
1773 ASSERT_NE(-1, texCubeLocation);
1774
1775 glUniform1i(tex2DLocation, 0);
1776 glUniform1i(texCubeLocation, 0);
1777 ASSERT_GL_NO_ERROR();
1778
1779 drawQuad(mProgram, "position", 0.5f);
1780 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1781}
1782
1783// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001784// TODO(jmadill): Possibly adjust the test according to the spec:
1785// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
1786// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001787TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
1788{
1789 const std::string &vertexShader =
1790 "attribute vec2 position;\n"
1791 "varying float color;\n"
1792 "uniform sampler2D tex2D;\n"
1793 "void main() {\n"
1794 " gl_Position = vec4(position, 0, 1);\n"
1795 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1796 " color = texture2D(tex2D, texCoord).x;\n"
1797 "}";
1798 const std::string &fragmentShader =
1799 "varying mediump float color;\n"
1800 "void main() {\n"
1801 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1802 "}";
1803
1804 mProgram = CompileProgram(vertexShader, fragmentShader);
1805 ASSERT_NE(0u, mProgram);
1806
1807 glUseProgram(mProgram);
1808 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1809 ASSERT_NE(-1, tex2DLocation);
1810
1811 glUniform1i(tex2DLocation, mMaxCombinedTextures);
1812 ASSERT_GL_NO_ERROR();
1813
1814 drawQuad(mProgram, "position", 0.5f);
1815 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1816}
1817
Jamie Madillfa05f602015-05-07 13:47:11 -04001818// 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 +02001819// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05001820ANGLE_INSTANTIATE_TEST(Texture2DTest,
1821 ES2_D3D9(),
1822 ES2_D3D11(),
1823 ES2_D3D11_FL9_3(),
1824 ES2_OPENGL(),
1825 ES2_OPENGLES());
1826ANGLE_INSTANTIATE_TEST(TextureCubeTest,
1827 ES2_D3D9(),
1828 ES2_D3D11(),
1829 ES2_D3D11_FL9_3(),
1830 ES2_OPENGL(),
1831 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02001832ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
1833 ES2_D3D9(),
1834 ES2_D3D11(),
1835 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05001836 ES2_OPENGL(),
1837 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02001838ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
1839 ES2_D3D9(),
1840 ES2_D3D11(),
1841 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05001842 ES2_OPENGL(),
1843 ES2_OPENGLES());
1844ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
1845 ES2_D3D9(),
1846 ES2_D3D11(),
1847 ES2_D3D11_FL9_3(),
1848 ES2_OPENGL(),
1849 ES2_OPENGLES());
1850ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
1851 ES2_D3D9(),
1852 ES2_D3D11(),
1853 ES2_D3D11_FL9_3(),
1854 ES2_OPENGL(),
1855 ES2_OPENGLES());
1856ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
1857ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
1858 ES3_D3D11(),
1859 ES3_OPENGL(),
1860 ES3_OPENGLES());
1861ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
1862ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
1863ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04001864
1865} // namespace