blob: e0f1b117befeb04fb2d664341d035512f9d95d6d [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 Etuaho4a8329f2016-01-11 17:12:57 +020017 TexCoordDrawTest() : ANGLETest(), mProgram(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();
55 }
56
57 void TearDown() override
58 {
59 glDeleteProgram(mProgram);
60 ANGLETest::TearDown();
61 }
62
63 // Returns the created texture ID.
64 GLuint create2DTexture()
65 {
66 GLuint texture2D;
67 glGenTextures(1, &texture2D);
68 glBindTexture(GL_TEXTURE_2D, texture2D);
69 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
70 EXPECT_GL_NO_ERROR();
71 return texture2D;
72 }
73
74 GLuint mProgram;
75};
76
77class Texture2DTest : public TexCoordDrawTest
78{
79 protected:
80 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
81
82 std::string getFragmentShaderSource() override
83 {
84 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040085 (
86 precision highp float;
87 uniform sampler2D tex;
88 varying vec2 texcoord;
89
90 void main()
91 {
92 gl_FragColor = texture2D(tex, texcoord);
93 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +020094 )
Geoff Langc41e42d2014-04-28 10:58:16 -040095 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +020096 }
Geoff Langc41e42d2014-04-28 10:58:16 -040097
Olli Etuaho4a8329f2016-01-11 17:12:57 +020098 void SetUp() override
99 {
100 TexCoordDrawTest::SetUp();
101 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400102
Jamie Madill9aca0592014-10-06 16:26:59 -0400103 ASSERT_GL_NO_ERROR();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200104
105 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex");
106 ASSERT_NE(-1, mTexture2DUniformLocation);
Jamie Madillf67115c2014-04-22 13:14:05 -0400107 }
108
Jamie Madillfa05f602015-05-07 13:47:11 -0400109 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400110 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400111 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200112 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400113 }
114
Jamie Madillbc393df2015-01-29 13:46:07 -0500115 // Tests CopyTexSubImage with floating point textures of various formats.
116 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
117 {
Geoff Langbde666a2015-04-07 17:17:08 -0400118 // TODO(jmadill): Figure out why this is broken on Intel D3D11
119 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
120 {
121 std::cout << "Test skipped on Intel D3D11." << std::endl;
122 return;
123 }
124
Geoff Langfbfa47c2015-03-31 11:26:00 -0400125 if (getClientVersion() < 3)
126 {
127 if (!extensionEnabled("GL_OES_texture_float"))
128 {
129 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
130 return;
131 }
132
133 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
134 {
135 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
136 return;
137 }
138 }
139
Jamie Madillbc393df2015-01-29 13:46:07 -0500140 GLfloat sourceImageData[4][16] =
141 {
142 { // R
143 1.0f,
144 0.0f,
145 0.0f,
146 1.0f
147 },
148 { // RG
149 1.0f, 0.0f,
150 0.0f, 1.0f,
151 0.0f, 0.0f,
152 1.0f, 1.0f
153 },
154 { // RGB
155 1.0f, 0.0f, 0.0f,
156 0.0f, 1.0f, 0.0f,
157 0.0f, 0.0f, 1.0f,
158 1.0f, 1.0f, 0.0f
159 },
160 { // RGBA
161 1.0f, 0.0f, 0.0f, 1.0f,
162 0.0f, 1.0f, 0.0f, 1.0f,
163 0.0f, 0.0f, 1.0f, 1.0f,
164 1.0f, 1.0f, 0.0f, 1.0f
165 },
166 };
167
168 GLenum imageFormats[] =
169 {
170 GL_R32F,
171 GL_RG32F,
172 GL_RGB32F,
173 GL_RGBA32F,
174 };
175
176 GLenum sourceUnsizedFormats[] =
177 {
178 GL_RED,
179 GL_RG,
180 GL_RGB,
181 GL_RGBA,
182 };
183
184 GLuint textures[2];
185
186 glGenTextures(2, textures);
187
188 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
189 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
190 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
191 GLenum destImageFormat = imageFormats[destImageChannels - 1];
192
193 glBindTexture(GL_TEXTURE_2D, textures[0]);
194 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
197 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
198
hendrikwb27f79a2015-03-04 11:26:46 -0800199 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500200 {
201 // This is not supported
202 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
203 }
204 else
205 {
206 ASSERT_GL_NO_ERROR();
207 }
208
209 GLuint fbo;
210 glGenFramebuffers(1, &fbo);
211 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
212 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
213
214 glBindTexture(GL_TEXTURE_2D, textures[1]);
215 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
217 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
218
219 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
220 ASSERT_GL_NO_ERROR();
221
222 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200223 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500224
225 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
226
227 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
228 if (testImageChannels > 1)
229 {
230 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
231 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
232 if (testImageChannels > 2)
233 {
234 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
235 }
236 }
237
238 glDeleteFramebuffers(1, &fbo);
239 glDeleteTextures(2, textures);
240
241 ASSERT_GL_NO_ERROR();
242 }
243
Jamie Madilld4cfa572014-07-08 10:00:32 -0400244 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400245 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400246};
247
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200248class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400249{
250 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200251 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
252
253 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400254 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200255 return std::string(SHADER_SOURCE
256 (
257 precision highp float;
258 attribute vec4 position;
259 varying vec2 texcoord;
260
261 uniform vec2 drawScale;
262
263 void main()
264 {
265 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
266 texcoord = (position.xy * 0.5) + 0.5;
267 }
268 )
269 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400270 }
271
272 void SetUp() override
273 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200274 Texture2DTest::SetUp();
275 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
276 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400277
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200278 glUseProgram(mProgram);
279 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
280 glUseProgram(0);
281 ASSERT_GL_NO_ERROR();
282 }
283
284 GLint mDrawScaleUniformLocation;
285};
286
Olli Etuaho4644a202016-01-12 15:12:53 +0200287class Sampler2DAsFunctionParameterTest : public Texture2DTest
288{
289 protected:
290 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
291
292 std::string getFragmentShaderSource() override
293 {
294 return std::string(SHADER_SOURCE
295 (
296 precision highp float;
297 uniform sampler2D tex;
298 varying vec2 texcoord;
299
300 vec4 computeFragColor(sampler2D aTex)
301 {
302 return texture2D(aTex, texcoord);
303 }
304
305 void main()
306 {
307 gl_FragColor = computeFragColor(tex);
308 }
309 )
310 );
311 }
312};
313
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200314class TextureCubeTest : public TexCoordDrawTest
315{
316 protected:
317 TextureCubeTest()
318 : TexCoordDrawTest(),
319 mTexture2D(0),
320 mTextureCube(0),
321 mTexture2DUniformLocation(-1),
322 mTextureCubeUniformLocation(-1)
323 {
324 }
325
326 std::string getFragmentShaderSource() override
327 {
328 return std::string(SHADER_SOURCE
329 (
330 precision highp float;
331 uniform sampler2D tex2D;
332 uniform samplerCube texCube;
333 varying vec2 texcoord;
334
335 void main()
336 {
337 gl_FragColor = texture2D(tex2D, texcoord);
338 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
339 }
340 )
341 );
342 }
343
344 void SetUp() override
345 {
346 TexCoordDrawTest::SetUp();
347
348 glGenTextures(1, &mTextureCube);
349 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
350 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
351 EXPECT_GL_NO_ERROR();
352
353 mTexture2D = create2DTexture();
354
355 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
356 ASSERT_NE(-1, mTexture2DUniformLocation);
357 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
358 ASSERT_NE(-1, mTextureCubeUniformLocation);
359 }
360
361 void TearDown() override
362 {
363 glDeleteTextures(1, &mTextureCube);
364 TexCoordDrawTest::TearDown();
365 }
366
367 GLuint mTexture2D;
368 GLuint mTextureCube;
369 GLint mTexture2DUniformLocation;
370 GLint mTextureCubeUniformLocation;
371};
372
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200373class SamplerArrayTest : public TexCoordDrawTest
374{
375 protected:
376 SamplerArrayTest()
377 : TexCoordDrawTest(),
378 mTexture2DA(0),
379 mTexture2DB(0),
380 mTexture0UniformLocation(-1),
381 mTexture1UniformLocation(-1)
382 {
383 }
384
385 std::string getFragmentShaderSource() override
386 {
387 return std::string(SHADER_SOURCE
388 (
389 precision mediump float;
390 uniform highp sampler2D tex2DArray[2];
391 varying vec2 texcoord;
392 void main()
393 {
394 gl_FragColor = texture2D(tex2DArray[0], texcoord);
395 gl_FragColor += texture2D(tex2DArray[1], texcoord);
396 }
397 )
398 );
399 }
400
401 void SetUp() override
402 {
403 TexCoordDrawTest::SetUp();
404
405 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
406 ASSERT_NE(-1, mTexture0UniformLocation);
407 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
408 ASSERT_NE(-1, mTexture1UniformLocation);
409
410 mTexture2DA = create2DTexture();
411 mTexture2DB = create2DTexture();
412 ASSERT_GL_NO_ERROR();
413 }
414
415 void TearDown() override
416 {
417 glDeleteTextures(1, &mTexture2DA);
418 glDeleteTextures(1, &mTexture2DB);
419 TexCoordDrawTest::TearDown();
420 }
421
422 void testSamplerArrayDraw()
423 {
424 GLubyte texData[4];
425 texData[0] = 0;
426 texData[1] = 60;
427 texData[2] = 0;
428 texData[3] = 255;
429
430 glActiveTexture(GL_TEXTURE0);
431 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
432 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
433
434 texData[1] = 120;
435 glActiveTexture(GL_TEXTURE1);
436 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
437 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
438 EXPECT_GL_ERROR(GL_NO_ERROR);
439
440 glUseProgram(mProgram);
441 glUniform1i(mTexture0UniformLocation, 0);
442 glUniform1i(mTexture1UniformLocation, 1);
443 drawQuad(mProgram, "position", 0.5f);
444 EXPECT_GL_NO_ERROR();
445
446 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
447 }
448
449 GLuint mTexture2DA;
450 GLuint mTexture2DB;
451 GLint mTexture0UniformLocation;
452 GLint mTexture1UniformLocation;
453};
454
455
456class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
457{
458 protected:
459 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
460
461 std::string getFragmentShaderSource() override
462 {
463 return std::string(SHADER_SOURCE
464 (
465 precision mediump float;
466 uniform highp sampler2D tex2DArray[2];
467 varying vec2 texcoord;
468
469 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
470 {
471 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
472 }
473
474 void main()
475 {
476 gl_FragColor = computeFragColor(tex2DArray);
477 }
478 )
479 );
480 }
481};
482
483
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200484class Texture2DArrayTestES3 : public TexCoordDrawTest
485{
486 protected:
487 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
488
489 std::string getVertexShaderSource() override
490 {
491 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400492 "#version 300 es\n"
493 "out vec2 texcoord;\n"
494 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200495 "void main()\n"
496 "{\n"
497 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
498 " texcoord = (position.xy * 0.5) + 0.5;\n"
499 "}\n");
500 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400501
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200502 std::string getFragmentShaderSource() override
503 {
504 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400505 "#version 300 es\n"
506 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200507 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400508 "in vec2 texcoord;\n"
509 "out vec4 fragColor;\n"
510 "void main()\n"
511 "{\n"
512 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200513 "}\n");
514 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400515
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200516 void SetUp() override
517 {
518 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400519
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200520 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400521 ASSERT_NE(-1, mTextureArrayLocation);
522
523 glGenTextures(1, &m2DArrayTexture);
524 ASSERT_GL_NO_ERROR();
525 }
526
527 void TearDown() override
528 {
529 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200530 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400531 }
532
533 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400534 GLint mTextureArrayLocation;
535};
536
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200537TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400538{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400539 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400540 EXPECT_GL_ERROR(GL_NO_ERROR);
541
542 const GLubyte *pixels[20] = { 0 };
543 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
544 EXPECT_GL_ERROR(GL_INVALID_VALUE);
545}
Geoff Langc41e42d2014-04-28 10:58:16 -0400546
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200547TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400548{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400549 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400550 EXPECT_GL_ERROR(GL_NO_ERROR);
551
552 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200553 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400554 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200555 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400556
557 const GLubyte *pixel[4] = { 0 };
558
559 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
560 EXPECT_GL_NO_ERROR();
561
562 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
563 EXPECT_GL_NO_ERROR();
564
565 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
566 EXPECT_GL_NO_ERROR();
567}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400568
569// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200570TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400571{
572 glActiveTexture(GL_TEXTURE0);
573 glBindTexture(GL_TEXTURE_2D, mTexture2D);
574 glActiveTexture(GL_TEXTURE1);
575 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
576 EXPECT_GL_ERROR(GL_NO_ERROR);
577
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200578 glUseProgram(mProgram);
579 glUniform1i(mTexture2DUniformLocation, 0);
580 glUniform1i(mTextureCubeUniformLocation, 1);
581 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400582 EXPECT_GL_NO_ERROR();
583}
Jamie Madill9aca0592014-10-06 16:26:59 -0400584
Olli Etuaho53a2da12016-01-11 15:43:32 +0200585// Test drawing with two texture types accessed from the same shader and check that the result of
586// drawing is correct.
587TEST_P(TextureCubeTest, CubeMapDraw)
588{
589 GLubyte texData[4];
590 texData[0] = 0;
591 texData[1] = 60;
592 texData[2] = 0;
593 texData[3] = 255;
594
595 glActiveTexture(GL_TEXTURE0);
596 glBindTexture(GL_TEXTURE_2D, mTexture2D);
597 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
598
599 glActiveTexture(GL_TEXTURE1);
600 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
601 texData[1] = 120;
602 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
603 texData);
604 EXPECT_GL_ERROR(GL_NO_ERROR);
605
606 glUseProgram(mProgram);
607 glUniform1i(mTexture2DUniformLocation, 0);
608 glUniform1i(mTextureCubeUniformLocation, 1);
609 drawQuad(mProgram, "position", 0.5f);
610 EXPECT_GL_NO_ERROR();
611
612 int px = getWindowWidth() - 1;
613 int py = 0;
614 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
615}
616
Olli Etuaho4644a202016-01-12 15:12:53 +0200617TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
618{
619 glActiveTexture(GL_TEXTURE0);
620 glBindTexture(GL_TEXTURE_2D, mTexture2D);
621 GLubyte texData[4];
622 texData[0] = 0;
623 texData[1] = 128;
624 texData[2] = 0;
625 texData[3] = 255;
626 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
627 glUseProgram(mProgram);
628 glUniform1i(mTexture2DUniformLocation, 0);
629 drawQuad(mProgram, "position", 0.5f);
630 EXPECT_GL_NO_ERROR();
631
632 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
633}
634
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200635// Test drawing with two textures passed to the shader in a sampler array.
636TEST_P(SamplerArrayTest, SamplerArrayDraw)
637{
638 testSamplerArrayDraw();
639}
640
641// Test drawing with two textures passed to the shader in a sampler array which is passed to a
642// user-defined function in the shader.
643TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
644{
645 testSamplerArrayDraw();
646}
647
Jamie Madill9aca0592014-10-06 16:26:59 -0400648// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200649TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -0400650{
651 int px = getWindowWidth() / 2;
652 int py = getWindowHeight() / 2;
653
654 glActiveTexture(GL_TEXTURE0);
655 glBindTexture(GL_TEXTURE_2D, mTexture2D);
656
657 // Fill with red
658 std::vector<GLubyte> pixels(4 * 16 * 16);
659 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
660 {
661 pixels[pixelId * 4 + 0] = 255;
662 pixels[pixelId * 4 + 1] = 0;
663 pixels[pixelId * 4 + 2] = 0;
664 pixels[pixelId * 4 + 3] = 255;
665 }
666
667 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
668 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
669 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
670 glGenerateMipmap(GL_TEXTURE_2D);
671
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200672 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -0400673 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200674 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
675 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -0400676 EXPECT_GL_NO_ERROR();
677 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
678
679 // Fill with blue
680 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
681 {
682 pixels[pixelId * 4 + 0] = 0;
683 pixels[pixelId * 4 + 1] = 0;
684 pixels[pixelId * 4 + 2] = 255;
685 pixels[pixelId * 4 + 3] = 255;
686 }
687
688 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
689 glGenerateMipmap(GL_TEXTURE_2D);
690
691 // Fill with green
692 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
693 {
694 pixels[pixelId * 4 + 0] = 0;
695 pixels[pixelId * 4 + 1] = 255;
696 pixels[pixelId * 4 + 2] = 0;
697 pixels[pixelId * 4 + 3] = 255;
698 }
699
700 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
701 glGenerateMipmap(GL_TEXTURE_2D);
702
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200703 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -0400704
705 EXPECT_GL_NO_ERROR();
706 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
707}
Jamie Madillf8fccb32014-11-12 15:05:26 -0500708
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500709// Test creating a FBO with a cube map render target, to test an ANGLE bug
710// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200711TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500712{
713 GLuint fbo;
714 glGenFramebuffers(1, &fbo);
715 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
716
717 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
718 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
719
Corentin Wallez322653b2015-06-17 18:33:56 +0200720 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500721
722 glDeleteFramebuffers(1, &fbo);
723
724 EXPECT_GL_NO_ERROR();
725}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000726
727// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200728TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000729{
730 int width = getWindowWidth();
731 int height = getWindowHeight();
732
733 GLuint tex2D;
734 glGenTextures(1, &tex2D);
735 glActiveTexture(GL_TEXTURE0);
736 glBindTexture(GL_TEXTURE_2D, tex2D);
737
738 // Fill with red
739 std::vector<GLubyte> pixels(3 * 16 * 16);
740 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
741 {
742 pixels[pixelId * 3 + 0] = 255;
743 pixels[pixelId * 3 + 1] = 0;
744 pixels[pixelId * 3 + 2] = 0;
745 }
746
747 // ANGLE internally uses RGBA as the DirectX format for RGB images
748 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
749 // The data is kept in a CPU-side image and the image is marked as dirty.
750 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
751
752 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
753 // glTexSubImage2D should take into account that the image is dirty.
754 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
755 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
756 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
757
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200758 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000759 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200760 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000761 glDeleteTextures(1, &tex2D);
762 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000763 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -0400764
765 // Validate that the region of the texture without data has an alpha of 1.0
766 GLubyte pixel[4];
767 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
768 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000769}
770
771// 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 +0200772TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000773{
774 if (extensionEnabled("NV_pixel_buffer_object"))
775 {
776 int width = getWindowWidth();
777 int height = getWindowHeight();
778
779 GLuint tex2D;
780 glGenTextures(1, &tex2D);
781 glActiveTexture(GL_TEXTURE0);
782 glBindTexture(GL_TEXTURE_2D, tex2D);
783
784 // Fill with red
785 std::vector<GLubyte> pixels(3 * 16 * 16);
786 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
787 {
788 pixels[pixelId * 3 + 0] = 255;
789 pixels[pixelId * 3 + 1] = 0;
790 pixels[pixelId * 3 + 2] = 0;
791 }
792
793 // Read 16x16 region from red backbuffer to PBO
794 GLuint pbo;
795 glGenBuffers(1, &pbo);
796 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
797 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
798
799 // ANGLE internally uses RGBA as the DirectX format for RGB images
800 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
801 // The data is kept in a CPU-side image and the image is marked as dirty.
802 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
803
804 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
805 // glTexSubImage2D should take into account that the image is dirty.
806 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
807 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
808 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
809
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200810 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000811 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200812 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000813 glDeleteTextures(1, &tex2D);
814 glDeleteTextures(1, &pbo);
815 EXPECT_GL_NO_ERROR();
816 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
817 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
818 }
819}
Jamie Madillbc393df2015-01-29 13:46:07 -0500820
821// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200822TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500823{
824 testFloatCopySubImage(1, 1);
825}
826
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200827TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500828{
829 testFloatCopySubImage(2, 1);
830}
831
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200832TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500833{
834 testFloatCopySubImage(2, 2);
835}
836
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200837TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500838{
839 testFloatCopySubImage(3, 1);
840}
841
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200842TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500843{
844 testFloatCopySubImage(3, 2);
845}
846
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200847TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -0500848{
849 testFloatCopySubImage(3, 3);
850}
851
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200852TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500853{
854 testFloatCopySubImage(4, 1);
855}
856
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200857TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500858{
859 testFloatCopySubImage(4, 2);
860}
861
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200862TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -0500863{
864 testFloatCopySubImage(4, 3);
865}
866
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200867TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -0500868{
869 testFloatCopySubImage(4, 4);
870}
Austin Kinross07285142015-03-26 11:36:16 -0700871
872// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
873// 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 +0200874TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -0700875{
876 const int npotTexSize = 5;
877 const int potTexSize = 4; // Should be less than npotTexSize
878 GLuint tex2D;
879
880 if (extensionEnabled("GL_OES_texture_npot"))
881 {
882 // This test isn't applicable if texture_npot is enabled
883 return;
884 }
885
886 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
887
888 glActiveTexture(GL_TEXTURE0);
889 glGenTextures(1, &tex2D);
890 glBindTexture(GL_TEXTURE_2D, tex2D);
891
892 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
893 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
894 {
895 pixels[pixelId] = 64;
896 }
897
898 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
899 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
900
901 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
902 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
903 EXPECT_GL_ERROR(GL_INVALID_VALUE);
904
905 // Check that an NPOT texture on level 0 succeeds
906 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
907 EXPECT_GL_NO_ERROR();
908
909 // Check that generateMipmap fails on NPOT
910 glGenerateMipmap(GL_TEXTURE_2D);
911 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
912
913 // Check that nothing is drawn if filtering is not correct for NPOT
914 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
915 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
916 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
917 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
918 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200919 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700920 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
921
922 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
923 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
924 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
925 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
926 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200927 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700928 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
929
930 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
931 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
932 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200933 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700934 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
935
936 // Check that glTexImage2D for POT texture succeeds
937 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
938 EXPECT_GL_NO_ERROR();
939
940 // Check that generateMipmap for an POT texture succeeds
941 glGenerateMipmap(GL_TEXTURE_2D);
942 EXPECT_GL_NO_ERROR();
943
944 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
945 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
946 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
948 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
949 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200950 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700951 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
952 EXPECT_GL_NO_ERROR();
953}
Jamie Madillfa05f602015-05-07 13:47:11 -0400954
Austin Kinross08528e12015-10-07 16:24:40 -0700955// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
956// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200957TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -0700958{
959 glActiveTexture(GL_TEXTURE0);
960 glBindTexture(GL_TEXTURE_2D, mTexture2D);
961
962 // Create an 8x8 (i.e. power-of-two) texture.
963 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
964 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
965 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
966 glGenerateMipmap(GL_TEXTURE_2D);
967
968 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
969 // This should always work, even if GL_OES_texture_npot isn't active.
970 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
971
972 EXPECT_GL_NO_ERROR();
973}
974
Jamie Madill2453dbc2015-07-14 11:35:42 -0400975// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
976// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
977// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200978TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -0400979{
980 std::vector<GLubyte> pixelData;
981 for (size_t count = 0; count < 5000; count++)
982 {
983 pixelData.push_back(0u);
984 pixelData.push_back(255u);
985 pixelData.push_back(0u);
986 }
987
988 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200989 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400990 glUniform1i(mTextureArrayLocation, 0);
991
992 // The first draw worked correctly.
993 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
994
995 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
996 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
997 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
998 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200999 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001000 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1001
1002 // The dimension of the respecification must match the original exactly to trigger the bug.
1003 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 +02001004 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001005 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1006
1007 ASSERT_GL_NO_ERROR();
1008}
1009
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001010class TextureLimitsTest : public ANGLETest
1011{
1012 protected:
1013 struct RGBA8
1014 {
1015 uint8_t R, G, B, A;
1016 };
1017
1018 TextureLimitsTest()
1019 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
1020 {
1021 setWindowWidth(128);
1022 setWindowHeight(128);
1023 setConfigRedBits(8);
1024 setConfigGreenBits(8);
1025 setConfigBlueBits(8);
1026 setConfigAlphaBits(8);
1027 }
1028
1029 ~TextureLimitsTest()
1030 {
1031 if (mProgram != 0)
1032 {
1033 glDeleteProgram(mProgram);
1034 mProgram = 0;
1035
1036 if (!mTextures.empty())
1037 {
1038 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
1039 }
1040 }
1041 }
1042
1043 void SetUp() override
1044 {
1045 ANGLETest::SetUp();
1046
1047 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
1048 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
1049 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
1050
1051 ASSERT_GL_NO_ERROR();
1052 }
1053
1054 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
1055 GLint vertexTextureCount,
1056 GLint vertexActiveTextureCount,
1057 const std::string &fragPrefix,
1058 GLint fragmentTextureCount,
1059 GLint fragmentActiveTextureCount)
1060 {
1061 std::stringstream vertexShaderStr;
1062 vertexShaderStr << "attribute vec2 position;\n"
1063 << "varying vec4 color;\n"
1064 << "varying vec2 texCoord;\n";
1065
1066 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
1067 {
1068 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
1069 }
1070
1071 vertexShaderStr << "void main() {\n"
1072 << " gl_Position = vec4(position, 0, 1);\n"
1073 << " texCoord = (position * 0.5) + 0.5;\n"
1074 << " color = vec4(0);\n";
1075
1076 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
1077 {
1078 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
1079 << ", texCoord);\n";
1080 }
1081
1082 vertexShaderStr << "}";
1083
1084 std::stringstream fragmentShaderStr;
1085 fragmentShaderStr << "varying mediump vec4 color;\n"
1086 << "varying mediump vec2 texCoord;\n";
1087
1088 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
1089 {
1090 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
1091 }
1092
1093 fragmentShaderStr << "void main() {\n"
1094 << " gl_FragColor = color;\n";
1095
1096 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
1097 {
1098 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
1099 << ", texCoord);\n";
1100 }
1101
1102 fragmentShaderStr << "}";
1103
1104 const std::string &vertexShaderSource = vertexShaderStr.str();
1105 const std::string &fragmentShaderSource = fragmentShaderStr.str();
1106
1107 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
1108 }
1109
1110 RGBA8 getPixel(GLint texIndex)
1111 {
1112 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
1113 0, 255u};
1114 return pixel;
1115 }
1116
1117 void initTextures(GLint tex2DCount, GLint texCubeCount)
1118 {
1119 GLint totalCount = tex2DCount + texCubeCount;
1120 mTextures.assign(totalCount, 0);
1121 glGenTextures(totalCount, &mTextures[0]);
1122 ASSERT_GL_NO_ERROR();
1123
1124 std::vector<RGBA8> texData(16 * 16);
1125
1126 GLint texIndex = 0;
1127 for (; texIndex < tex2DCount; ++texIndex)
1128 {
1129 texData.assign(texData.size(), getPixel(texIndex));
1130 glActiveTexture(GL_TEXTURE0 + texIndex);
1131 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
1132 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1133 &texData[0]);
1134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1138 }
1139
1140 ASSERT_GL_NO_ERROR();
1141
1142 for (; texIndex < texCubeCount; ++texIndex)
1143 {
1144 texData.assign(texData.size(), getPixel(texIndex));
1145 glActiveTexture(GL_TEXTURE0 + texIndex);
1146 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
1147 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1148 GL_UNSIGNED_BYTE, &texData[0]);
1149 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1150 GL_UNSIGNED_BYTE, &texData[0]);
1151 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1152 GL_UNSIGNED_BYTE, &texData[0]);
1153 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1154 GL_UNSIGNED_BYTE, &texData[0]);
1155 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1156 GL_UNSIGNED_BYTE, &texData[0]);
1157 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1158 GL_UNSIGNED_BYTE, &texData[0]);
1159 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1160 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1161 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1162 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1163 }
1164
1165 ASSERT_GL_NO_ERROR();
1166 }
1167
1168 void testWithTextures(GLint vertexTextureCount,
1169 const std::string &vertexTexturePrefix,
1170 GLint fragmentTextureCount,
1171 const std::string &fragmentTexturePrefix)
1172 {
1173 // Generate textures
1174 initTextures(vertexTextureCount + fragmentTextureCount, 0);
1175
1176 glUseProgram(mProgram);
1177 RGBA8 expectedSum = {0};
1178 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
1179 {
1180 std::stringstream uniformNameStr;
1181 uniformNameStr << vertexTexturePrefix << texIndex;
1182 const std::string &uniformName = uniformNameStr.str();
1183 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1184 ASSERT_NE(-1, location);
1185
1186 glUniform1i(location, texIndex);
1187 RGBA8 contribution = getPixel(texIndex);
1188 expectedSum.R += contribution.R;
1189 expectedSum.G += contribution.G;
1190 }
1191
1192 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
1193 {
1194 std::stringstream uniformNameStr;
1195 uniformNameStr << fragmentTexturePrefix << texIndex;
1196 const std::string &uniformName = uniformNameStr.str();
1197 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1198 ASSERT_NE(-1, location);
1199
1200 glUniform1i(location, texIndex + vertexTextureCount);
1201 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
1202 expectedSum.R += contribution.R;
1203 expectedSum.G += contribution.G;
1204 }
1205
1206 ASSERT_GE(256u, expectedSum.G);
1207
1208 drawQuad(mProgram, "position", 0.5f);
1209 ASSERT_GL_NO_ERROR();
1210 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
1211 }
1212
1213 GLuint mProgram;
1214 std::vector<GLuint> mTextures;
1215 GLint mMaxVertexTextures;
1216 GLint mMaxFragmentTextures;
1217 GLint mMaxCombinedTextures;
1218};
1219
1220// Test rendering with the maximum vertex texture units.
1221TEST_P(TextureLimitsTest, MaxVertexTextures)
1222{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001223 // TODO(jmadill): Figure out why this fails on Intel.
1224 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1225 {
1226 std::cout << "Test skipped on Intel." << std::endl;
1227 return;
1228 }
1229
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001230 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
1231 ASSERT_NE(0u, mProgram);
1232 ASSERT_GL_NO_ERROR();
1233
1234 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1235}
1236
1237// Test rendering with the maximum fragment texture units.
1238TEST_P(TextureLimitsTest, MaxFragmentTextures)
1239{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001240 // TODO(jmadill): Figure out why this fails on Intel.
1241 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1242 {
1243 std::cout << "Test skipped on Intel." << std::endl;
1244 return;
1245 }
1246
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001247 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
1248 ASSERT_NE(0u, mProgram);
1249 ASSERT_GL_NO_ERROR();
1250
1251 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
1252}
1253
1254// Test rendering with maximum combined texture units.
1255TEST_P(TextureLimitsTest, MaxCombinedTextures)
1256{
Jamie Madill412f17d2015-09-25 08:43:54 -04001257 // TODO(jmadill): Investigate workaround.
1258 if (isIntel() && GetParam() == ES2_OPENGL())
1259 {
1260 std::cout << "Test skipped on Intel." << std::endl;
1261 return;
1262 }
1263
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001264 GLint vertexTextures = mMaxVertexTextures;
1265
1266 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
1267 {
1268 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
1269 }
1270
1271 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
1272 mMaxFragmentTextures, mMaxFragmentTextures);
1273 ASSERT_NE(0u, mProgram);
1274 ASSERT_GL_NO_ERROR();
1275
1276 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
1277}
1278
1279// Negative test for exceeding the number of vertex textures
1280TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
1281{
1282 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
1283 0);
1284 ASSERT_EQ(0u, mProgram);
1285}
1286
1287// Negative test for exceeding the number of fragment textures
1288TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
1289{
1290 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
1291 mMaxFragmentTextures + 1);
1292 ASSERT_EQ(0u, mProgram);
1293}
1294
1295// Test active vertex textures under the limit, but excessive textures specified.
1296TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
1297{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001298 // TODO(jmadill): Figure out why this fails on Intel.
1299 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1300 {
1301 std::cout << "Test skipped on Intel." << std::endl;
1302 return;
1303 }
1304
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001305 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
1306 ASSERT_NE(0u, mProgram);
1307 ASSERT_GL_NO_ERROR();
1308
1309 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1310}
1311
1312// Test active fragment textures under the limit, but excessive textures specified.
1313TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
1314{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001315 // TODO(jmadill): Figure out why this fails on Intel.
1316 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1317 {
1318 std::cout << "Test skipped on Intel." << std::endl;
1319 return;
1320 }
1321
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001322 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
1323 mMaxFragmentTextures);
1324 ASSERT_NE(0u, mProgram);
1325 ASSERT_GL_NO_ERROR();
1326
1327 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
1328}
1329
1330// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001331// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001332TEST_P(TextureLimitsTest, TextureTypeConflict)
1333{
1334 const std::string &vertexShader =
1335 "attribute vec2 position;\n"
1336 "varying float color;\n"
1337 "uniform sampler2D tex2D;\n"
1338 "uniform samplerCube texCube;\n"
1339 "void main() {\n"
1340 " gl_Position = vec4(position, 0, 1);\n"
1341 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1342 " color = texture2D(tex2D, texCoord).x;\n"
1343 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
1344 "}";
1345 const std::string &fragmentShader =
1346 "varying mediump float color;\n"
1347 "void main() {\n"
1348 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1349 "}";
1350
1351 mProgram = CompileProgram(vertexShader, fragmentShader);
1352 ASSERT_NE(0u, mProgram);
1353
1354 initTextures(1, 0);
1355
1356 glUseProgram(mProgram);
1357 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1358 ASSERT_NE(-1, tex2DLocation);
1359 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
1360 ASSERT_NE(-1, texCubeLocation);
1361
1362 glUniform1i(tex2DLocation, 0);
1363 glUniform1i(texCubeLocation, 0);
1364 ASSERT_GL_NO_ERROR();
1365
1366 drawQuad(mProgram, "position", 0.5f);
1367 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1368}
1369
1370// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001371// TODO(jmadill): Possibly adjust the test according to the spec:
1372// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
1373// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001374TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
1375{
1376 const std::string &vertexShader =
1377 "attribute vec2 position;\n"
1378 "varying float color;\n"
1379 "uniform sampler2D tex2D;\n"
1380 "void main() {\n"
1381 " gl_Position = vec4(position, 0, 1);\n"
1382 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1383 " color = texture2D(tex2D, texCoord).x;\n"
1384 "}";
1385 const std::string &fragmentShader =
1386 "varying mediump float color;\n"
1387 "void main() {\n"
1388 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1389 "}";
1390
1391 mProgram = CompileProgram(vertexShader, fragmentShader);
1392 ASSERT_NE(0u, mProgram);
1393
1394 glUseProgram(mProgram);
1395 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1396 ASSERT_NE(-1, tex2DLocation);
1397
1398 glUniform1i(tex2DLocation, mMaxCombinedTextures);
1399 ASSERT_GL_NO_ERROR();
1400
1401 drawQuad(mProgram, "position", 0.5f);
1402 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1403}
1404
Jamie Madillfa05f602015-05-07 13:47:11 -04001405// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001406// TODO(geofflang): Figure out why tests below fail on Intel OpenGL:
1407ANGLE_INSTANTIATE_TEST(Texture2DTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
1408ANGLE_INSTANTIATE_TEST(TextureCubeTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
1409ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho4644a202016-01-12 15:12:53 +02001410ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001411ANGLE_INSTANTIATE_TEST(SamplerArrayTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
1412ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001413ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001414ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL());
Jamie Madillfa05f602015-05-07 13:47:11 -04001415
1416} // namespace