blob: 844cb7c39607cdf7b2f8d6c542ddd6bccd8b3590 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Jamie Madillf67115c2014-04-22 13:14:05 -04008
Jamie Madillfa05f602015-05-07 13:47:11 -04009using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070010
Jamie Madillfa05f602015-05-07 13:47:11 -040011namespace
12{
13
Olli Etuaho4a8329f2016-01-11 17:12:57 +020014class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -040015{
Jamie Madillbc393df2015-01-29 13:46:07 -050016 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020017 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -040018 {
19 setWindowWidth(128);
20 setWindowHeight(128);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 }
26
Olli Etuaho4a8329f2016-01-11 17:12:57 +020027 virtual std::string getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -040028 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020029 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040030 (
31 precision highp float;
32 attribute vec4 position;
33 varying vec2 texcoord;
34
35 void main()
36 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020037 gl_Position = vec4(position.xy, 0.0, 1.0);
Geoff Langc41e42d2014-04-28 10:58:16 -040038 texcoord = (position.xy * 0.5) + 0.5;
39 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +020040 )
Geoff Langc41e42d2014-04-28 10:58:16 -040041 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +020042 }
Geoff Langc41e42d2014-04-28 10:58:16 -040043
Olli Etuaho4a8329f2016-01-11 17:12:57 +020044 virtual std::string getFragmentShaderSource() = 0;
45
46 void SetUp() override
47 {
48 ANGLETest::SetUp();
49 const std::string vertexShaderSource = getVertexShaderSource();
50 const std::string fragmentShaderSource = getFragmentShaderSource();
51
52 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
53 ASSERT_NE(0u, mProgram);
54 ASSERT_GL_NO_ERROR();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020055
56 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020057 }
58
59 void TearDown() override
60 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020061 glBindFramebuffer(GL_FRAMEBUFFER, 0);
62 glDeleteFramebuffers(1, &mFramebuffer);
63 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020064 glDeleteProgram(mProgram);
65 ANGLETest::TearDown();
66 }
67
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020068 void setUpFramebuffer()
69 {
70 // We use an FBO to work around an issue where the default framebuffer applies SRGB
71 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
72 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
73 // section 4.4 says that the format of the default framebuffer is entirely up to the window
74 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
75 // SRGB conversion like desktop GL does.
76 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
77 glGenFramebuffers(1, &mFramebuffer);
78 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
79
80 glGenTextures(1, &mFramebufferColorTexture);
81 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
82 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
83 GL_UNSIGNED_BYTE, nullptr);
84 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
85 mFramebufferColorTexture, 0);
86 ASSERT_GL_NO_ERROR();
87 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
88 glBindTexture(GL_TEXTURE_2D, 0);
89 }
90
Olli Etuaho4a8329f2016-01-11 17:12:57 +020091 // Returns the created texture ID.
92 GLuint create2DTexture()
93 {
94 GLuint texture2D;
95 glGenTextures(1, &texture2D);
96 glBindTexture(GL_TEXTURE_2D, texture2D);
97 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
98 EXPECT_GL_NO_ERROR();
99 return texture2D;
100 }
101
102 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200103 GLuint mFramebuffer;
104
105 private:
106 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200107};
108
109class Texture2DTest : public TexCoordDrawTest
110{
111 protected:
112 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
113
114 std::string getFragmentShaderSource() override
115 {
116 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400117 (
118 precision highp float;
119 uniform sampler2D tex;
120 varying vec2 texcoord;
121
122 void main()
123 {
124 gl_FragColor = texture2D(tex, texcoord);
125 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200126 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400127 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200128 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400129
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200130 void SetUp() override
131 {
132 TexCoordDrawTest::SetUp();
133 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400134
Jamie Madill9aca0592014-10-06 16:26:59 -0400135 ASSERT_GL_NO_ERROR();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200136
137 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex");
138 ASSERT_NE(-1, mTexture2DUniformLocation);
Jamie Madillf67115c2014-04-22 13:14:05 -0400139 }
140
Jamie Madillfa05f602015-05-07 13:47:11 -0400141 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400142 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400143 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200144 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400145 }
146
Jamie Madillbc393df2015-01-29 13:46:07 -0500147 // Tests CopyTexSubImage with floating point textures of various formats.
148 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
149 {
Geoff Langbde666a2015-04-07 17:17:08 -0400150 // TODO(jmadill): Figure out why this is broken on Intel D3D11
151 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
152 {
153 std::cout << "Test skipped on Intel D3D11." << std::endl;
154 return;
155 }
156
Geoff Langfbfa47c2015-03-31 11:26:00 -0400157 if (getClientVersion() < 3)
158 {
159 if (!extensionEnabled("GL_OES_texture_float"))
160 {
161 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
162 return;
163 }
164
165 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
166 {
167 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
168 return;
169 }
170 }
171
Jamie Madillbc393df2015-01-29 13:46:07 -0500172 GLfloat sourceImageData[4][16] =
173 {
174 { // R
175 1.0f,
176 0.0f,
177 0.0f,
178 1.0f
179 },
180 { // RG
181 1.0f, 0.0f,
182 0.0f, 1.0f,
183 0.0f, 0.0f,
184 1.0f, 1.0f
185 },
186 { // RGB
187 1.0f, 0.0f, 0.0f,
188 0.0f, 1.0f, 0.0f,
189 0.0f, 0.0f, 1.0f,
190 1.0f, 1.0f, 0.0f
191 },
192 { // RGBA
193 1.0f, 0.0f, 0.0f, 1.0f,
194 0.0f, 1.0f, 0.0f, 1.0f,
195 0.0f, 0.0f, 1.0f, 1.0f,
196 1.0f, 1.0f, 0.0f, 1.0f
197 },
198 };
199
200 GLenum imageFormats[] =
201 {
202 GL_R32F,
203 GL_RG32F,
204 GL_RGB32F,
205 GL_RGBA32F,
206 };
207
208 GLenum sourceUnsizedFormats[] =
209 {
210 GL_RED,
211 GL_RG,
212 GL_RGB,
213 GL_RGBA,
214 };
215
216 GLuint textures[2];
217
218 glGenTextures(2, textures);
219
220 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
221 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
222 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
223 GLenum destImageFormat = imageFormats[destImageChannels - 1];
224
225 glBindTexture(GL_TEXTURE_2D, textures[0]);
226 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
229 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
230
hendrikwb27f79a2015-03-04 11:26:46 -0800231 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500232 {
233 // This is not supported
234 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
235 }
236 else
237 {
238 ASSERT_GL_NO_ERROR();
239 }
240
241 GLuint fbo;
242 glGenFramebuffers(1, &fbo);
243 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
244 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
245
246 glBindTexture(GL_TEXTURE_2D, textures[1]);
247 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
250
251 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
252 ASSERT_GL_NO_ERROR();
253
254 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200255 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500256
257 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
258
259 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
260 if (testImageChannels > 1)
261 {
262 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
263 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
264 if (testImageChannels > 2)
265 {
266 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
267 }
268 }
269
270 glDeleteFramebuffers(1, &fbo);
271 glDeleteTextures(2, textures);
272
273 ASSERT_GL_NO_ERROR();
274 }
275
Jamie Madilld4cfa572014-07-08 10:00:32 -0400276 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400277 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400278};
279
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200280class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400281{
282 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200283 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
284
285 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400286 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200287 return std::string(SHADER_SOURCE
288 (
289 precision highp float;
290 attribute vec4 position;
291 varying vec2 texcoord;
292
293 uniform vec2 drawScale;
294
295 void main()
296 {
297 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
298 texcoord = (position.xy * 0.5) + 0.5;
299 }
300 )
301 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400302 }
303
304 void SetUp() override
305 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200306 Texture2DTest::SetUp();
307 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
308 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400309
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200310 glUseProgram(mProgram);
311 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
312 glUseProgram(0);
313 ASSERT_GL_NO_ERROR();
314 }
315
316 GLint mDrawScaleUniformLocation;
317};
318
Olli Etuaho4644a202016-01-12 15:12:53 +0200319class Sampler2DAsFunctionParameterTest : public Texture2DTest
320{
321 protected:
322 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
323
324 std::string getFragmentShaderSource() override
325 {
326 return std::string(SHADER_SOURCE
327 (
328 precision highp float;
329 uniform sampler2D tex;
330 varying vec2 texcoord;
331
332 vec4 computeFragColor(sampler2D aTex)
333 {
334 return texture2D(aTex, texcoord);
335 }
336
337 void main()
338 {
339 gl_FragColor = computeFragColor(tex);
340 }
341 )
342 );
343 }
344};
345
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200346class TextureCubeTest : public TexCoordDrawTest
347{
348 protected:
349 TextureCubeTest()
350 : TexCoordDrawTest(),
351 mTexture2D(0),
352 mTextureCube(0),
353 mTexture2DUniformLocation(-1),
354 mTextureCubeUniformLocation(-1)
355 {
356 }
357
358 std::string getFragmentShaderSource() override
359 {
360 return std::string(SHADER_SOURCE
361 (
362 precision highp float;
363 uniform sampler2D tex2D;
364 uniform samplerCube texCube;
365 varying vec2 texcoord;
366
367 void main()
368 {
369 gl_FragColor = texture2D(tex2D, texcoord);
370 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
371 }
372 )
373 );
374 }
375
376 void SetUp() override
377 {
378 TexCoordDrawTest::SetUp();
379
380 glGenTextures(1, &mTextureCube);
381 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
382 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
383 EXPECT_GL_NO_ERROR();
384
385 mTexture2D = create2DTexture();
386
387 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
388 ASSERT_NE(-1, mTexture2DUniformLocation);
389 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
390 ASSERT_NE(-1, mTextureCubeUniformLocation);
391 }
392
393 void TearDown() override
394 {
395 glDeleteTextures(1, &mTextureCube);
396 TexCoordDrawTest::TearDown();
397 }
398
399 GLuint mTexture2D;
400 GLuint mTextureCube;
401 GLint mTexture2DUniformLocation;
402 GLint mTextureCubeUniformLocation;
403};
404
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200405class SamplerArrayTest : public TexCoordDrawTest
406{
407 protected:
408 SamplerArrayTest()
409 : TexCoordDrawTest(),
410 mTexture2DA(0),
411 mTexture2DB(0),
412 mTexture0UniformLocation(-1),
413 mTexture1UniformLocation(-1)
414 {
415 }
416
417 std::string getFragmentShaderSource() override
418 {
419 return std::string(SHADER_SOURCE
420 (
421 precision mediump float;
422 uniform highp sampler2D tex2DArray[2];
423 varying vec2 texcoord;
424 void main()
425 {
426 gl_FragColor = texture2D(tex2DArray[0], texcoord);
427 gl_FragColor += texture2D(tex2DArray[1], texcoord);
428 }
429 )
430 );
431 }
432
433 void SetUp() override
434 {
435 TexCoordDrawTest::SetUp();
436
437 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
438 ASSERT_NE(-1, mTexture0UniformLocation);
439 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
440 ASSERT_NE(-1, mTexture1UniformLocation);
441
442 mTexture2DA = create2DTexture();
443 mTexture2DB = create2DTexture();
444 ASSERT_GL_NO_ERROR();
445 }
446
447 void TearDown() override
448 {
449 glDeleteTextures(1, &mTexture2DA);
450 glDeleteTextures(1, &mTexture2DB);
451 TexCoordDrawTest::TearDown();
452 }
453
454 void testSamplerArrayDraw()
455 {
456 GLubyte texData[4];
457 texData[0] = 0;
458 texData[1] = 60;
459 texData[2] = 0;
460 texData[3] = 255;
461
462 glActiveTexture(GL_TEXTURE0);
463 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
464 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
465
466 texData[1] = 120;
467 glActiveTexture(GL_TEXTURE1);
468 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
469 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
470 EXPECT_GL_ERROR(GL_NO_ERROR);
471
472 glUseProgram(mProgram);
473 glUniform1i(mTexture0UniformLocation, 0);
474 glUniform1i(mTexture1UniformLocation, 1);
475 drawQuad(mProgram, "position", 0.5f);
476 EXPECT_GL_NO_ERROR();
477
478 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
479 }
480
481 GLuint mTexture2DA;
482 GLuint mTexture2DB;
483 GLint mTexture0UniformLocation;
484 GLint mTexture1UniformLocation;
485};
486
487
488class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
489{
490 protected:
491 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
492
493 std::string getFragmentShaderSource() override
494 {
495 return std::string(SHADER_SOURCE
496 (
497 precision mediump float;
498 uniform highp sampler2D tex2DArray[2];
499 varying vec2 texcoord;
500
501 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
502 {
503 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
504 }
505
506 void main()
507 {
508 gl_FragColor = computeFragColor(tex2DArray);
509 }
510 )
511 );
512 }
513};
514
515
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200516class Texture2DArrayTestES3 : public TexCoordDrawTest
517{
518 protected:
519 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
520
521 std::string getVertexShaderSource() override
522 {
523 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400524 "#version 300 es\n"
525 "out vec2 texcoord;\n"
526 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200527 "void main()\n"
528 "{\n"
529 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
530 " texcoord = (position.xy * 0.5) + 0.5;\n"
531 "}\n");
532 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400533
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200534 std::string getFragmentShaderSource() override
535 {
536 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400537 "#version 300 es\n"
538 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200539 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400540 "in vec2 texcoord;\n"
541 "out vec4 fragColor;\n"
542 "void main()\n"
543 "{\n"
544 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200545 "}\n");
546 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400547
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200548 void SetUp() override
549 {
550 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400551
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200552 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400553 ASSERT_NE(-1, mTextureArrayLocation);
554
555 glGenTextures(1, &m2DArrayTexture);
556 ASSERT_GL_NO_ERROR();
557 }
558
559 void TearDown() override
560 {
561 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200562 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400563 }
564
565 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400566 GLint mTextureArrayLocation;
567};
568
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200569TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -0400570{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400571 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -0400572 EXPECT_GL_ERROR(GL_NO_ERROR);
573
574 const GLubyte *pixels[20] = { 0 };
575 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
576 EXPECT_GL_ERROR(GL_INVALID_VALUE);
577}
Geoff Langc41e42d2014-04-28 10:58:16 -0400578
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200579TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -0400580{
Jamie Madilld4cfa572014-07-08 10:00:32 -0400581 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -0400582 EXPECT_GL_ERROR(GL_NO_ERROR);
583
584 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200585 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400586 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200587 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -0400588
589 const GLubyte *pixel[4] = { 0 };
590
591 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
592 EXPECT_GL_NO_ERROR();
593
594 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
595 EXPECT_GL_NO_ERROR();
596
597 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
598 EXPECT_GL_NO_ERROR();
599}
Jamie Madilld4cfa572014-07-08 10:00:32 -0400600
601// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200602TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -0400603{
604 glActiveTexture(GL_TEXTURE0);
605 glBindTexture(GL_TEXTURE_2D, mTexture2D);
606 glActiveTexture(GL_TEXTURE1);
607 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
608 EXPECT_GL_ERROR(GL_NO_ERROR);
609
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200610 glUseProgram(mProgram);
611 glUniform1i(mTexture2DUniformLocation, 0);
612 glUniform1i(mTextureCubeUniformLocation, 1);
613 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -0400614 EXPECT_GL_NO_ERROR();
615}
Jamie Madill9aca0592014-10-06 16:26:59 -0400616
Olli Etuaho53a2da12016-01-11 15:43:32 +0200617// Test drawing with two texture types accessed from the same shader and check that the result of
618// drawing is correct.
619TEST_P(TextureCubeTest, CubeMapDraw)
620{
621 GLubyte texData[4];
622 texData[0] = 0;
623 texData[1] = 60;
624 texData[2] = 0;
625 texData[3] = 255;
626
627 glActiveTexture(GL_TEXTURE0);
628 glBindTexture(GL_TEXTURE_2D, mTexture2D);
629 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
630
631 glActiveTexture(GL_TEXTURE1);
632 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
633 texData[1] = 120;
634 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
635 texData);
636 EXPECT_GL_ERROR(GL_NO_ERROR);
637
638 glUseProgram(mProgram);
639 glUniform1i(mTexture2DUniformLocation, 0);
640 glUniform1i(mTextureCubeUniformLocation, 1);
641 drawQuad(mProgram, "position", 0.5f);
642 EXPECT_GL_NO_ERROR();
643
644 int px = getWindowWidth() - 1;
645 int py = 0;
646 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
647}
648
Olli Etuaho4644a202016-01-12 15:12:53 +0200649TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
650{
651 glActiveTexture(GL_TEXTURE0);
652 glBindTexture(GL_TEXTURE_2D, mTexture2D);
653 GLubyte texData[4];
654 texData[0] = 0;
655 texData[1] = 128;
656 texData[2] = 0;
657 texData[3] = 255;
658 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
659 glUseProgram(mProgram);
660 glUniform1i(mTexture2DUniformLocation, 0);
661 drawQuad(mProgram, "position", 0.5f);
662 EXPECT_GL_NO_ERROR();
663
664 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
665}
666
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200667// Test drawing with two textures passed to the shader in a sampler array.
668TEST_P(SamplerArrayTest, SamplerArrayDraw)
669{
670 testSamplerArrayDraw();
671}
672
673// Test drawing with two textures passed to the shader in a sampler array which is passed to a
674// user-defined function in the shader.
675TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
676{
677 testSamplerArrayDraw();
678}
679
Jamie Madill9aca0592014-10-06 16:26:59 -0400680// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200681TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -0400682{
683 int px = getWindowWidth() / 2;
684 int py = getWindowHeight() / 2;
685
686 glActiveTexture(GL_TEXTURE0);
687 glBindTexture(GL_TEXTURE_2D, mTexture2D);
688
689 // Fill with red
690 std::vector<GLubyte> pixels(4 * 16 * 16);
691 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
692 {
693 pixels[pixelId * 4 + 0] = 255;
694 pixels[pixelId * 4 + 1] = 0;
695 pixels[pixelId * 4 + 2] = 0;
696 pixels[pixelId * 4 + 3] = 255;
697 }
698
699 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
700 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
701 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
702 glGenerateMipmap(GL_TEXTURE_2D);
703
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200704 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -0400705 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200706 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
707 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -0400708 EXPECT_GL_NO_ERROR();
709 EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
710
711 // Fill with blue
712 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
713 {
714 pixels[pixelId * 4 + 0] = 0;
715 pixels[pixelId * 4 + 1] = 0;
716 pixels[pixelId * 4 + 2] = 255;
717 pixels[pixelId * 4 + 3] = 255;
718 }
719
720 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
721 glGenerateMipmap(GL_TEXTURE_2D);
722
723 // Fill with green
724 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
725 {
726 pixels[pixelId * 4 + 0] = 0;
727 pixels[pixelId * 4 + 1] = 255;
728 pixels[pixelId * 4 + 2] = 0;
729 pixels[pixelId * 4 + 3] = 255;
730 }
731
732 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
733 glGenerateMipmap(GL_TEXTURE_2D);
734
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200735 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -0400736
737 EXPECT_GL_NO_ERROR();
738 EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
739}
Jamie Madillf8fccb32014-11-12 15:05:26 -0500740
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500741// Test creating a FBO with a cube map render target, to test an ANGLE bug
742// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200743TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500744{
745 GLuint fbo;
746 glGenFramebuffers(1, &fbo);
747 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
748
749 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
750 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
751
Corentin Wallez322653b2015-06-17 18:33:56 +0200752 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -0500753
754 glDeleteFramebuffers(1, &fbo);
755
756 EXPECT_GL_NO_ERROR();
757}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000758
759// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200760TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000761{
762 int width = getWindowWidth();
763 int height = getWindowHeight();
764
765 GLuint tex2D;
766 glGenTextures(1, &tex2D);
767 glActiveTexture(GL_TEXTURE0);
768 glBindTexture(GL_TEXTURE_2D, tex2D);
769
770 // Fill with red
771 std::vector<GLubyte> pixels(3 * 16 * 16);
772 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
773 {
774 pixels[pixelId * 3 + 0] = 255;
775 pixels[pixelId * 3 + 1] = 0;
776 pixels[pixelId * 3 + 2] = 0;
777 }
778
779 // ANGLE internally uses RGBA as the DirectX format for RGB images
780 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
781 // The data is kept in a CPU-side image and the image is marked as dirty.
782 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
783
784 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
785 // glTexSubImage2D should take into account that the image is dirty.
786 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
787 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
788 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
789
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200790 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000791 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200792 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000793 glDeleteTextures(1, &tex2D);
794 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000795 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -0400796
797 // Validate that the region of the texture without data has an alpha of 1.0
798 GLubyte pixel[4];
799 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
800 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000801}
802
803// 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 +0200804TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000805{
806 if (extensionEnabled("NV_pixel_buffer_object"))
807 {
808 int width = getWindowWidth();
809 int height = getWindowHeight();
810
811 GLuint tex2D;
812 glGenTextures(1, &tex2D);
813 glActiveTexture(GL_TEXTURE0);
814 glBindTexture(GL_TEXTURE_2D, tex2D);
815
816 // Fill with red
817 std::vector<GLubyte> pixels(3 * 16 * 16);
818 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
819 {
820 pixels[pixelId * 3 + 0] = 255;
821 pixels[pixelId * 3 + 1] = 0;
822 pixels[pixelId * 3 + 2] = 0;
823 }
824
825 // Read 16x16 region from red backbuffer to PBO
826 GLuint pbo;
827 glGenBuffers(1, &pbo);
828 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
829 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
830
831 // ANGLE internally uses RGBA as the DirectX format for RGB images
832 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
833 // The data is kept in a CPU-side image and the image is marked as dirty.
834 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
835
836 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
837 // glTexSubImage2D should take into account that the image is dirty.
838 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
839 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
840 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
841
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200842 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000843 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200844 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000845 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +0200846 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +0000847 EXPECT_GL_NO_ERROR();
848 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
849 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
850 }
851}
Jamie Madillbc393df2015-01-29 13:46:07 -0500852
853// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200854TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500855{
856 testFloatCopySubImage(1, 1);
857}
858
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200859TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500860{
861 testFloatCopySubImage(2, 1);
862}
863
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200864TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500865{
866 testFloatCopySubImage(2, 2);
867}
868
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200869TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500870{
871 testFloatCopySubImage(3, 1);
872}
873
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200874TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500875{
876 testFloatCopySubImage(3, 2);
877}
878
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200879TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -0500880{
881 testFloatCopySubImage(3, 3);
882}
883
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200884TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -0500885{
886 testFloatCopySubImage(4, 1);
887}
888
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200889TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -0500890{
891 testFloatCopySubImage(4, 2);
892}
893
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200894TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -0500895{
896 testFloatCopySubImage(4, 3);
897}
898
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200899TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -0500900{
901 testFloatCopySubImage(4, 4);
902}
Austin Kinross07285142015-03-26 11:36:16 -0700903
904// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
905// 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 +0200906TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -0700907{
908 const int npotTexSize = 5;
909 const int potTexSize = 4; // Should be less than npotTexSize
910 GLuint tex2D;
911
912 if (extensionEnabled("GL_OES_texture_npot"))
913 {
914 // This test isn't applicable if texture_npot is enabled
915 return;
916 }
917
918 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
919
Austin Kinross5faa15b2016-01-11 13:32:48 -0800920 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
921 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
922
Austin Kinross07285142015-03-26 11:36:16 -0700923 glActiveTexture(GL_TEXTURE0);
924 glGenTextures(1, &tex2D);
925 glBindTexture(GL_TEXTURE_2D, tex2D);
926
927 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
928 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
929 {
930 pixels[pixelId] = 64;
931 }
932
933 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
935
936 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
937 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
938 EXPECT_GL_ERROR(GL_INVALID_VALUE);
939
940 // Check that an NPOT texture on level 0 succeeds
941 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
942 EXPECT_GL_NO_ERROR();
943
944 // Check that generateMipmap fails on NPOT
945 glGenerateMipmap(GL_TEXTURE_2D);
946 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
947
948 // Check that nothing is drawn if filtering is not correct for NPOT
949 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
950 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
951 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
952 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
953 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200954 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700955 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
956
957 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
958 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
959 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
960 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
961 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200962 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700963 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
964
965 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
967 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200968 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700969 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
970
971 // Check that glTexImage2D for POT texture succeeds
972 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
973 EXPECT_GL_NO_ERROR();
974
975 // Check that generateMipmap for an POT texture succeeds
976 glGenerateMipmap(GL_TEXTURE_2D);
977 EXPECT_GL_NO_ERROR();
978
979 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
980 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
981 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
984 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200985 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -0700986 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
987 EXPECT_GL_NO_ERROR();
988}
Jamie Madillfa05f602015-05-07 13:47:11 -0400989
Austin Kinross08528e12015-10-07 16:24:40 -0700990// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
991// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200992TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -0700993{
994 glActiveTexture(GL_TEXTURE0);
995 glBindTexture(GL_TEXTURE_2D, mTexture2D);
996
997 // Create an 8x8 (i.e. power-of-two) texture.
998 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
999 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1000 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1001 glGenerateMipmap(GL_TEXTURE_2D);
1002
1003 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1004 // This should always work, even if GL_OES_texture_npot isn't active.
1005 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1006
1007 EXPECT_GL_NO_ERROR();
1008}
1009
Jamie Madill2453dbc2015-07-14 11:35:42 -04001010// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
1011// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
1012// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001013TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04001014{
1015 std::vector<GLubyte> pixelData;
1016 for (size_t count = 0; count < 5000; count++)
1017 {
1018 pixelData.push_back(0u);
1019 pixelData.push_back(255u);
1020 pixelData.push_back(0u);
1021 }
1022
1023 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001024 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001025 glUniform1i(mTextureArrayLocation, 0);
1026
1027 // The first draw worked correctly.
1028 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
1029
1030 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1031 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1032 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
1033 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001034 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001035 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1036
1037 // The dimension of the respecification must match the original exactly to trigger the bug.
1038 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 +02001039 drawQuad(mProgram, "position", 1.0f);
Jamie Madill2453dbc2015-07-14 11:35:42 -04001040 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1041
1042 ASSERT_GL_NO_ERROR();
1043}
1044
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001045class TextureLimitsTest : public ANGLETest
1046{
1047 protected:
1048 struct RGBA8
1049 {
1050 uint8_t R, G, B, A;
1051 };
1052
1053 TextureLimitsTest()
1054 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
1055 {
1056 setWindowWidth(128);
1057 setWindowHeight(128);
1058 setConfigRedBits(8);
1059 setConfigGreenBits(8);
1060 setConfigBlueBits(8);
1061 setConfigAlphaBits(8);
1062 }
1063
1064 ~TextureLimitsTest()
1065 {
1066 if (mProgram != 0)
1067 {
1068 glDeleteProgram(mProgram);
1069 mProgram = 0;
1070
1071 if (!mTextures.empty())
1072 {
1073 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
1074 }
1075 }
1076 }
1077
1078 void SetUp() override
1079 {
1080 ANGLETest::SetUp();
1081
1082 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
1083 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
1084 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
1085
1086 ASSERT_GL_NO_ERROR();
1087 }
1088
1089 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
1090 GLint vertexTextureCount,
1091 GLint vertexActiveTextureCount,
1092 const std::string &fragPrefix,
1093 GLint fragmentTextureCount,
1094 GLint fragmentActiveTextureCount)
1095 {
1096 std::stringstream vertexShaderStr;
1097 vertexShaderStr << "attribute vec2 position;\n"
1098 << "varying vec4 color;\n"
1099 << "varying vec2 texCoord;\n";
1100
1101 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
1102 {
1103 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
1104 }
1105
1106 vertexShaderStr << "void main() {\n"
1107 << " gl_Position = vec4(position, 0, 1);\n"
1108 << " texCoord = (position * 0.5) + 0.5;\n"
1109 << " color = vec4(0);\n";
1110
1111 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
1112 {
1113 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
1114 << ", texCoord);\n";
1115 }
1116
1117 vertexShaderStr << "}";
1118
1119 std::stringstream fragmentShaderStr;
1120 fragmentShaderStr << "varying mediump vec4 color;\n"
1121 << "varying mediump vec2 texCoord;\n";
1122
1123 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
1124 {
1125 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
1126 }
1127
1128 fragmentShaderStr << "void main() {\n"
1129 << " gl_FragColor = color;\n";
1130
1131 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
1132 {
1133 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
1134 << ", texCoord);\n";
1135 }
1136
1137 fragmentShaderStr << "}";
1138
1139 const std::string &vertexShaderSource = vertexShaderStr.str();
1140 const std::string &fragmentShaderSource = fragmentShaderStr.str();
1141
1142 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
1143 }
1144
1145 RGBA8 getPixel(GLint texIndex)
1146 {
1147 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
1148 0, 255u};
1149 return pixel;
1150 }
1151
1152 void initTextures(GLint tex2DCount, GLint texCubeCount)
1153 {
1154 GLint totalCount = tex2DCount + texCubeCount;
1155 mTextures.assign(totalCount, 0);
1156 glGenTextures(totalCount, &mTextures[0]);
1157 ASSERT_GL_NO_ERROR();
1158
1159 std::vector<RGBA8> texData(16 * 16);
1160
1161 GLint texIndex = 0;
1162 for (; texIndex < tex2DCount; ++texIndex)
1163 {
1164 texData.assign(texData.size(), getPixel(texIndex));
1165 glActiveTexture(GL_TEXTURE0 + texIndex);
1166 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
1167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1168 &texData[0]);
1169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1173 }
1174
1175 ASSERT_GL_NO_ERROR();
1176
1177 for (; texIndex < texCubeCount; ++texIndex)
1178 {
1179 texData.assign(texData.size(), getPixel(texIndex));
1180 glActiveTexture(GL_TEXTURE0 + texIndex);
1181 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
1182 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1183 GL_UNSIGNED_BYTE, &texData[0]);
1184 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1185 GL_UNSIGNED_BYTE, &texData[0]);
1186 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1187 GL_UNSIGNED_BYTE, &texData[0]);
1188 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1189 GL_UNSIGNED_BYTE, &texData[0]);
1190 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1191 GL_UNSIGNED_BYTE, &texData[0]);
1192 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
1193 GL_UNSIGNED_BYTE, &texData[0]);
1194 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1195 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1196 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1197 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1198 }
1199
1200 ASSERT_GL_NO_ERROR();
1201 }
1202
1203 void testWithTextures(GLint vertexTextureCount,
1204 const std::string &vertexTexturePrefix,
1205 GLint fragmentTextureCount,
1206 const std::string &fragmentTexturePrefix)
1207 {
1208 // Generate textures
1209 initTextures(vertexTextureCount + fragmentTextureCount, 0);
1210
1211 glUseProgram(mProgram);
1212 RGBA8 expectedSum = {0};
1213 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
1214 {
1215 std::stringstream uniformNameStr;
1216 uniformNameStr << vertexTexturePrefix << texIndex;
1217 const std::string &uniformName = uniformNameStr.str();
1218 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1219 ASSERT_NE(-1, location);
1220
1221 glUniform1i(location, texIndex);
1222 RGBA8 contribution = getPixel(texIndex);
1223 expectedSum.R += contribution.R;
1224 expectedSum.G += contribution.G;
1225 }
1226
1227 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
1228 {
1229 std::stringstream uniformNameStr;
1230 uniformNameStr << fragmentTexturePrefix << texIndex;
1231 const std::string &uniformName = uniformNameStr.str();
1232 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
1233 ASSERT_NE(-1, location);
1234
1235 glUniform1i(location, texIndex + vertexTextureCount);
1236 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
1237 expectedSum.R += contribution.R;
1238 expectedSum.G += contribution.G;
1239 }
1240
1241 ASSERT_GE(256u, expectedSum.G);
1242
1243 drawQuad(mProgram, "position", 0.5f);
1244 ASSERT_GL_NO_ERROR();
1245 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
1246 }
1247
1248 GLuint mProgram;
1249 std::vector<GLuint> mTextures;
1250 GLint mMaxVertexTextures;
1251 GLint mMaxFragmentTextures;
1252 GLint mMaxCombinedTextures;
1253};
1254
1255// Test rendering with the maximum vertex texture units.
1256TEST_P(TextureLimitsTest, MaxVertexTextures)
1257{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001258 // TODO(jmadill): Figure out why this fails on Intel.
1259 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1260 {
1261 std::cout << "Test skipped on Intel." << std::endl;
1262 return;
1263 }
1264
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001265 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
1266 ASSERT_NE(0u, mProgram);
1267 ASSERT_GL_NO_ERROR();
1268
1269 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1270}
1271
1272// Test rendering with the maximum fragment texture units.
1273TEST_P(TextureLimitsTest, MaxFragmentTextures)
1274{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001275 // TODO(jmadill): Figure out why this fails on Intel.
1276 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1277 {
1278 std::cout << "Test skipped on Intel." << std::endl;
1279 return;
1280 }
1281
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001282 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
1283 ASSERT_NE(0u, mProgram);
1284 ASSERT_GL_NO_ERROR();
1285
1286 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
1287}
1288
1289// Test rendering with maximum combined texture units.
1290TEST_P(TextureLimitsTest, MaxCombinedTextures)
1291{
Jamie Madill412f17d2015-09-25 08:43:54 -04001292 // TODO(jmadill): Investigate workaround.
1293 if (isIntel() && GetParam() == ES2_OPENGL())
1294 {
1295 std::cout << "Test skipped on Intel." << std::endl;
1296 return;
1297 }
1298
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001299 GLint vertexTextures = mMaxVertexTextures;
1300
1301 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
1302 {
1303 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
1304 }
1305
1306 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
1307 mMaxFragmentTextures, mMaxFragmentTextures);
1308 ASSERT_NE(0u, mProgram);
1309 ASSERT_GL_NO_ERROR();
1310
1311 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
1312}
1313
1314// Negative test for exceeding the number of vertex textures
1315TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
1316{
1317 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
1318 0);
1319 ASSERT_EQ(0u, mProgram);
1320}
1321
1322// Negative test for exceeding the number of fragment textures
1323TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
1324{
1325 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
1326 mMaxFragmentTextures + 1);
1327 ASSERT_EQ(0u, mProgram);
1328}
1329
1330// Test active vertex textures under the limit, but excessive textures specified.
1331TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
1332{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001333 // TODO(jmadill): Figure out why this fails on Intel.
1334 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1335 {
1336 std::cout << "Test skipped on Intel." << std::endl;
1337 return;
1338 }
1339
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001340 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
1341 ASSERT_NE(0u, mProgram);
1342 ASSERT_GL_NO_ERROR();
1343
1344 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
1345}
1346
1347// Test active fragment textures under the limit, but excessive textures specified.
1348TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
1349{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04001350 // TODO(jmadill): Figure out why this fails on Intel.
1351 if (isIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1352 {
1353 std::cout << "Test skipped on Intel." << std::endl;
1354 return;
1355 }
1356
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001357 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
1358 mMaxFragmentTextures);
1359 ASSERT_NE(0u, mProgram);
1360 ASSERT_GL_NO_ERROR();
1361
1362 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
1363}
1364
1365// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001366// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001367TEST_P(TextureLimitsTest, TextureTypeConflict)
1368{
1369 const std::string &vertexShader =
1370 "attribute vec2 position;\n"
1371 "varying float color;\n"
1372 "uniform sampler2D tex2D;\n"
1373 "uniform samplerCube texCube;\n"
1374 "void main() {\n"
1375 " gl_Position = vec4(position, 0, 1);\n"
1376 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1377 " color = texture2D(tex2D, texCoord).x;\n"
1378 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
1379 "}";
1380 const std::string &fragmentShader =
1381 "varying mediump float color;\n"
1382 "void main() {\n"
1383 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1384 "}";
1385
1386 mProgram = CompileProgram(vertexShader, fragmentShader);
1387 ASSERT_NE(0u, mProgram);
1388
1389 initTextures(1, 0);
1390
1391 glUseProgram(mProgram);
1392 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1393 ASSERT_NE(-1, tex2DLocation);
1394 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
1395 ASSERT_NE(-1, texCubeLocation);
1396
1397 glUniform1i(tex2DLocation, 0);
1398 glUniform1i(texCubeLocation, 0);
1399 ASSERT_GL_NO_ERROR();
1400
1401 drawQuad(mProgram, "position", 0.5f);
1402 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1403}
1404
1405// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001406// TODO(jmadill): Possibly adjust the test according to the spec:
1407// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
1408// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001409TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
1410{
1411 const std::string &vertexShader =
1412 "attribute vec2 position;\n"
1413 "varying float color;\n"
1414 "uniform sampler2D tex2D;\n"
1415 "void main() {\n"
1416 " gl_Position = vec4(position, 0, 1);\n"
1417 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1418 " color = texture2D(tex2D, texCoord).x;\n"
1419 "}";
1420 const std::string &fragmentShader =
1421 "varying mediump float color;\n"
1422 "void main() {\n"
1423 " gl_FragColor = vec4(color, 0, 0, 1);\n"
1424 "}";
1425
1426 mProgram = CompileProgram(vertexShader, fragmentShader);
1427 ASSERT_NE(0u, mProgram);
1428
1429 glUseProgram(mProgram);
1430 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
1431 ASSERT_NE(-1, tex2DLocation);
1432
1433 glUniform1i(tex2DLocation, mMaxCombinedTextures);
1434 ASSERT_GL_NO_ERROR();
1435
1436 drawQuad(mProgram, "position", 0.5f);
1437 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1438}
1439
Jamie Madillfa05f602015-05-07 13:47:11 -04001440// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02001441// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001442ANGLE_INSTANTIATE_TEST(Texture2DTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02001443ANGLE_INSTANTIATE_TEST(TextureCubeTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL());
1444ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
1445 ES2_D3D9(),
1446 ES2_D3D11(),
1447 ES2_D3D11_FL9_3(),
1448 ES2_OPENGL());
1449ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
1450 ES2_D3D9(),
1451 ES2_D3D11(),
1452 ES2_D3D11_FL9_3(),
1453 ES2_OPENGL());
1454ANGLE_INSTANTIATE_TEST(SamplerArrayTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL());
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001455ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001456ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001457ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL());
Jamie Madillfa05f602015-05-07 13:47:11 -04001458
1459} // namespace