blob: 821fb7ec43f720a5e52b7da3851dc5c482ae07ac [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
Austin Kinross5faa15b2016-01-11 13:32:48 -0800888 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
889 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
890
Austin Kinross07285142015-03-26 11:36:16 -0700891 glActiveTexture(GL_TEXTURE0);
892 glGenTextures(1, &tex2D);
893 glBindTexture(GL_TEXTURE_2D, tex2D);
894
895 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
896 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
897 {
898 pixels[pixelId] = 64;
899 }
900
901 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
902 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
903
904 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
905 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
906 EXPECT_GL_ERROR(GL_INVALID_VALUE);
907
908 // Check that an NPOT texture on level 0 succeeds
909 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
910 EXPECT_GL_NO_ERROR();
911
912 // Check that generateMipmap fails on NPOT
913 glGenerateMipmap(GL_TEXTURE_2D);
914 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
915
916 // Check that nothing is drawn if filtering is not correct for NPOT
917 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
918 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
919 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
920 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
921 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200922 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700923 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
924
925 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
926 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
927 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
928 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
929 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200930 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700931 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
932
933 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
935 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200936 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700937 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
938
939 // Check that glTexImage2D for POT texture succeeds
940 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
941 EXPECT_GL_NO_ERROR();
942
943 // Check that generateMipmap for an POT texture succeeds
944 glGenerateMipmap(GL_TEXTURE_2D);
945 EXPECT_GL_NO_ERROR();
946
947 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
948 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
949 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
950 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
951 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
952 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200953 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700954 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
955 EXPECT_GL_NO_ERROR();
956}
Jamie Madillfa05f602015-05-07 13:47:11 -0400957
Austin Kinross08528e12015-10-07 16:24:40 -0700958// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
959// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200960TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -0700961{
962 glActiveTexture(GL_TEXTURE0);
963 glBindTexture(GL_TEXTURE_2D, mTexture2D);
964
965 // Create an 8x8 (i.e. power-of-two) texture.
966 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
967 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
968 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
969 glGenerateMipmap(GL_TEXTURE_2D);
970
971 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
972 // This should always work, even if GL_OES_texture_npot isn't active.
973 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
974
975 EXPECT_GL_NO_ERROR();
976}
977
Jamie Madill2453dbc2015-07-14 11:35:42 -0400978// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
979// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
980// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200981TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -0400982{
983 std::vector<GLubyte> pixelData;
984 for (size_t count = 0; count < 5000; count++)
985 {
986 pixelData.push_back(0u);
987 pixelData.push_back(255u);
988 pixelData.push_back(0u);
989 }
990
991 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200992 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400993 glUniform1i(mTextureArrayLocation, 0);
994
995 // The first draw worked correctly.
996 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
997
998 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
999 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1000 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1001 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001002 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001003 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1004
1005 // The dimension of the respecification must match the original exactly to trigger the bug.
1006 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 +02001007 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001008 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1009
1010 ASSERT_GL_NO_ERROR();
1011}
1012
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001013class TextureLimitsTest : public ANGLETest
1014{
1015 protected:
1016 struct RGBA8
1017 {
1018 uint8_t R, G, B, A;
1019 };
1020
1021 TextureLimitsTest()
1022 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
1023 {
1024 setWindowWidth(128);
1025 setWindowHeight(128);
1026 setConfigRedBits(8);
1027 setConfigGreenBits(8);
1028 setConfigBlueBits(8);
1029 setConfigAlphaBits(8);
1030 }
1031
1032 ~TextureLimitsTest()
1033 {
1034 if (mProgram != 0)
1035 {
1036 glDeleteProgram(mProgram);
1037 mProgram = 0;
1038
1039 if (!mTextures.empty())
1040 {
1041 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
1042 }
1043 }
1044 }
1045
1046 void SetUp() override
1047 {
1048 ANGLETest::SetUp();
1049
1050 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
1051 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
1052 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
1053
1054 ASSERT_GL_NO_ERROR();
1055 }
1056
1057 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
1058 GLint vertexTextureCount,
1059 GLint vertexActiveTextureCount,
1060 const std::string &fragPrefix,
1061 GLint fragmentTextureCount,
1062 GLint fragmentActiveTextureCount)
1063 {
1064 std::stringstream vertexShaderStr;
1065 vertexShaderStr << "attribute vec2 position;\n"
1066 << "varying vec4 color;\n"
1067 << "varying vec2 texCoord;\n";
1068
1069 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
1070 {
1071 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
1072 }
1073
1074 vertexShaderStr << "void main() {\n"
1075 << " gl_Position = vec4(position, 0, 1);\n"
1076 << " texCoord = (position * 0.5) + 0.5;\n"
1077 << " color = vec4(0);\n";
1078
1079 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
1080 {
1081 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
1082 << ", texCoord);\n";
1083 }
1084
1085 vertexShaderStr << "}";
1086
1087 std::stringstream fragmentShaderStr;
1088 fragmentShaderStr << "varying mediump vec4 color;\n"
1089 << "varying mediump vec2 texCoord;\n";
1090
1091 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
1092 {
1093 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
1094 }
1095
1096 fragmentShaderStr << "void main() {\n"
1097 << " gl_FragColor = color;\n";
1098
1099 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
1100 {
1101 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
1102 << ", texCoord);\n";
1103 }
1104
1105 fragmentShaderStr << "}";
1106
1107 const std::string &vertexShaderSource = vertexShaderStr.str();
1108 const std::string &fragmentShaderSource = fragmentShaderStr.str();
1109
1110 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
1111 }
1112
1113 RGBA8 getPixel(GLint texIndex)
1114 {
1115 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
1116 0, 255u};
1117 return pixel;
1118 }
1119
1120 void initTextures(GLint tex2DCount, GLint texCubeCount)
1121 {
1122 GLint totalCount = tex2DCount + texCubeCount;
1123 mTextures.assign(totalCount, 0);
1124 glGenTextures(totalCount, &mTextures[0]);
1125 ASSERT_GL_NO_ERROR();
1126
1127 std::vector<RGBA8> texData(16 * 16);
1128
1129 GLint texIndex = 0;
1130 for (; texIndex < tex2DCount; ++texIndex)
1131 {
1132 texData.assign(texData.size(), getPixel(texIndex));
1133 glActiveTexture(GL_TEXTURE0 + texIndex);
1134 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
1135 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1136 &texData[0]);
1137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1141 }
1142
1143 ASSERT_GL_NO_ERROR();
1144
1145 for (; texIndex < texCubeCount; ++texIndex)
1146 {
1147 texData.assign(texData.size(), getPixel(texIndex));
1148 glActiveTexture(GL_TEXTURE0 + texIndex);
1149 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
1150 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1151 GL_UNSIGNED_BYTE, &texData[0]);
1152 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1153 GL_UNSIGNED_BYTE, &texData[0]);
1154 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1155 GL_UNSIGNED_BYTE, &texData[0]);
1156 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1157 GL_UNSIGNED_BYTE, &texData[0]);
1158 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1159 GL_UNSIGNED_BYTE, &texData[0]);
1160 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1161 GL_UNSIGNED_BYTE, &texData[0]);
1162 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1163 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1164 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1165 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1166 }
1167
1168 ASSERT_GL_NO_ERROR();
1169 }
1170
1171 void testWithTextures(GLint vertexTextureCount,
1172 const std::string &vertexTexturePrefix,
1173 GLint fragmentTextureCount,
1174 const std::string &fragmentTexturePrefix)
1175 {
1176 // Generate textures
1177 initTextures(vertexTextureCount + fragmentTextureCount, 0);
1178
1179 glUseProgram(mProgram);
1180 RGBA8 expectedSum = {0};
1181 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
1182 {
1183 std::stringstream uniformNameStr;
1184 uniformNameStr << vertexTexturePrefix << texIndex;
1185 const std::string &uniformName = uniformNameStr.str();
1186 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1187 ASSERT_NE(-1, location);
1188
1189 glUniform1i(location, texIndex);
1190 RGBA8 contribution = getPixel(texIndex);
1191 expectedSum.R += contribution.R;
1192 expectedSum.G += contribution.G;
1193 }
1194
1195 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
1196 {
1197 std::stringstream uniformNameStr;
1198 uniformNameStr << fragmentTexturePrefix << texIndex;
1199 const std::string &uniformName = uniformNameStr.str();
1200 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1201 ASSERT_NE(-1, location);
1202
1203 glUniform1i(location, texIndex + vertexTextureCount);
1204 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
1205 expectedSum.R += contribution.R;
1206 expectedSum.G += contribution.G;
1207 }
1208
1209 ASSERT_GE(256u, expectedSum.G);
1210
1211 drawQuad(mProgram, "position", 0.5f);
1212 ASSERT_GL_NO_ERROR();
1213 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
1214 }
1215
1216 GLuint mProgram;
1217 std::vector<GLuint> mTextures;
1218 GLint mMaxVertexTextures;
1219 GLint mMaxFragmentTextures;
1220 GLint mMaxCombinedTextures;
1221};
1222
1223// Test rendering with the maximum vertex texture units.
1224TEST_P(TextureLimitsTest, MaxVertexTextures)
1225{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001226 // TODO(jmadill): Figure out why this fails on Intel.
1227 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1228 {
1229 std::cout << "Test skipped on Intel." << std::endl;
1230 return;
1231 }
1232
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001233 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
1234 ASSERT_NE(0u, mProgram);
1235 ASSERT_GL_NO_ERROR();
1236
1237 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1238}
1239
1240// Test rendering with the maximum fragment texture units.
1241TEST_P(TextureLimitsTest, MaxFragmentTextures)
1242{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001243 // TODO(jmadill): Figure out why this fails on Intel.
1244 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1245 {
1246 std::cout << "Test skipped on Intel." << std::endl;
1247 return;
1248 }
1249
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001250 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
1251 ASSERT_NE(0u, mProgram);
1252 ASSERT_GL_NO_ERROR();
1253
1254 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
1255}
1256
1257// Test rendering with maximum combined texture units.
1258TEST_P(TextureLimitsTest, MaxCombinedTextures)
1259{
Jamie Madill412f17d2015-09-25 08:43:54 -04001260 // TODO(jmadill): Investigate workaround.
1261 if (isIntel() && GetParam() == ES2_OPENGL())
1262 {
1263 std::cout << "Test skipped on Intel." << std::endl;
1264 return;
1265 }
1266
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001267 GLint vertexTextures = mMaxVertexTextures;
1268
1269 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
1270 {
1271 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
1272 }
1273
1274 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
1275 mMaxFragmentTextures, mMaxFragmentTextures);
1276 ASSERT_NE(0u, mProgram);
1277 ASSERT_GL_NO_ERROR();
1278
1279 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
1280}
1281
1282// Negative test for exceeding the number of vertex textures
1283TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
1284{
1285 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
1286 0);
1287 ASSERT_EQ(0u, mProgram);
1288}
1289
1290// Negative test for exceeding the number of fragment textures
1291TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
1292{
1293 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
1294 mMaxFragmentTextures + 1);
1295 ASSERT_EQ(0u, mProgram);
1296}
1297
1298// Test active vertex textures under the limit, but excessive textures specified.
1299TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
1300{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001301 // TODO(jmadill): Figure out why this fails on Intel.
1302 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1303 {
1304 std::cout << "Test skipped on Intel." << std::endl;
1305 return;
1306 }
1307
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001308 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
1309 ASSERT_NE(0u, mProgram);
1310 ASSERT_GL_NO_ERROR();
1311
1312 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1313}
1314
1315// Test active fragment textures under the limit, but excessive textures specified.
1316TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
1317{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001318 // TODO(jmadill): Figure out why this fails on Intel.
1319 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1320 {
1321 std::cout << "Test skipped on Intel." << std::endl;
1322 return;
1323 }
1324
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001325 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
1326 mMaxFragmentTextures);
1327 ASSERT_NE(0u, mProgram);
1328 ASSERT_GL_NO_ERROR();
1329
1330 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
1331}
1332
1333// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001334// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001335TEST_P(TextureLimitsTest, TextureTypeConflict)
1336{
1337 const std::string &vertexShader =
1338 "attribute vec2 position;\n"
1339 "varying float color;\n"
1340 "uniform sampler2D tex2D;\n"
1341 "uniform samplerCube texCube;\n"
1342 "void main() {\n"
1343 " gl_Position = vec4(position, 0, 1);\n"
1344 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1345 " color = texture2D(tex2D, texCoord).x;\n"
1346 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
1347 "}";
1348 const std::string &fragmentShader =
1349 "varying mediump float color;\n"
1350 "void main() {\n"
1351 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1352 "}";
1353
1354 mProgram = CompileProgram(vertexShader, fragmentShader);
1355 ASSERT_NE(0u, mProgram);
1356
1357 initTextures(1, 0);
1358
1359 glUseProgram(mProgram);
1360 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1361 ASSERT_NE(-1, tex2DLocation);
1362 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
1363 ASSERT_NE(-1, texCubeLocation);
1364
1365 glUniform1i(tex2DLocation, 0);
1366 glUniform1i(texCubeLocation, 0);
1367 ASSERT_GL_NO_ERROR();
1368
1369 drawQuad(mProgram, "position", 0.5f);
1370 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1371}
1372
1373// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001374// TODO(jmadill): Possibly adjust the test according to the spec:
1375// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
1376// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001377TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
1378{
1379 const std::string &vertexShader =
1380 "attribute vec2 position;\n"
1381 "varying float color;\n"
1382 "uniform sampler2D tex2D;\n"
1383 "void main() {\n"
1384 " gl_Position = vec4(position, 0, 1);\n"
1385 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1386 " color = texture2D(tex2D, texCoord).x;\n"
1387 "}";
1388 const std::string &fragmentShader =
1389 "varying mediump float color;\n"
1390 "void main() {\n"
1391 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1392 "}";
1393
1394 mProgram = CompileProgram(vertexShader, fragmentShader);
1395 ASSERT_NE(0u, mProgram);
1396
1397 glUseProgram(mProgram);
1398 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1399 ASSERT_NE(-1, tex2DLocation);
1400
1401 glUniform1i(tex2DLocation, mMaxCombinedTextures);
1402 ASSERT_GL_NO_ERROR();
1403
1404 drawQuad(mProgram, "position", 0.5f);
1405 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1406}
1407
Jamie Madillfa05f602015-05-07 13:47:11 -04001408// 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 +02001409// TODO(geofflang): Figure out why tests below fail on Intel OpenGL:
1410ANGLE_INSTANTIATE_TEST(Texture2DTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
1411ANGLE_INSTANTIATE_TEST(TextureCubeTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
1412ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho4644a202016-01-12 15:12:53 +02001413ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001414ANGLE_INSTANTIATE_TEST(SamplerArrayTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
1415ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001416ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001417ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL());
Jamie Madillfa05f602015-05-07 13:47:11 -04001418
1419} // namespace