blob: f1d4cc4f7fccc5885dc4cc5f598ae7dac5816047 [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
Jamie Madill14718762016-09-06 15:56:54 -04007#include "common/mathutil.h"
Corentin Wallezd3970de2015-05-14 11:07:48 -04008#include "test_utils/ANGLETest.h"
Olli Etuaho989cac32016-06-08 16:18:49 -07009#include "test_utils/gl_raii.h"
Jamie Madillf67115c2014-04-22 13:14:05 -040010
Jamie Madillfa05f602015-05-07 13:47:11 -040011using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070012
Jamie Madillfa05f602015-05-07 13:47:11 -040013namespace
14{
15
Vincent Lang25ab4512016-05-13 18:13:59 +020016// Take a pixel, and reset the components not covered by the format to default
17// values. In particular, the default value for the alpha component is 65535
18// (1.0 as unsigned normalized fixed point value).
19GLColor16 SliceFormatColor16(GLenum format, GLColor16 full)
20{
21 switch (format)
22 {
23 case GL_RED:
24 return GLColor16(full.R, 0, 0, 65535u);
25 case GL_RG:
26 return GLColor16(full.R, full.G, 0, 65535u);
27 case GL_RGB:
28 return GLColor16(full.R, full.G, full.B, 65535u);
29 case GL_RGBA:
30 return full;
31 default:
32 UNREACHABLE();
33 }
34 return GLColor16::white;
35}
36
Olli Etuaho4a8329f2016-01-11 17:12:57 +020037class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -040038{
Jamie Madillbc393df2015-01-29 13:46:07 -050039 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020040 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -040041 {
42 setWindowWidth(128);
43 setWindowHeight(128);
44 setConfigRedBits(8);
45 setConfigGreenBits(8);
46 setConfigBlueBits(8);
47 setConfigAlphaBits(8);
48 }
49
Olli Etuaho4a8329f2016-01-11 17:12:57 +020050 virtual std::string getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -040051 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020052 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040053 (
54 precision highp float;
55 attribute vec4 position;
56 varying vec2 texcoord;
57
58 void main()
59 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020060 gl_Position = vec4(position.xy, 0.0, 1.0);
Geoff Langc41e42d2014-04-28 10:58:16 -040061 texcoord = (position.xy * 0.5) + 0.5;
62 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +020063 )
Geoff Langc41e42d2014-04-28 10:58:16 -040064 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +020065 }
Geoff Langc41e42d2014-04-28 10:58:16 -040066
Olli Etuaho4a8329f2016-01-11 17:12:57 +020067 virtual std::string getFragmentShaderSource() = 0;
68
Olli Etuahoa1c917f2016-04-06 13:50:03 +030069 virtual void setUpProgram()
Olli Etuaho4a8329f2016-01-11 17:12:57 +020070 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020071 const std::string vertexShaderSource = getVertexShaderSource();
72 const std::string fragmentShaderSource = getFragmentShaderSource();
73
74 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
75 ASSERT_NE(0u, mProgram);
76 ASSERT_GL_NO_ERROR();
Olli Etuahoa1c917f2016-04-06 13:50:03 +030077 }
78
79 void SetUp() override
80 {
81 ANGLETest::SetUp();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020082
83 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020084 }
85
86 void TearDown() override
87 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020088 glBindFramebuffer(GL_FRAMEBUFFER, 0);
89 glDeleteFramebuffers(1, &mFramebuffer);
90 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020091 glDeleteProgram(mProgram);
92 ANGLETest::TearDown();
93 }
94
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020095 void setUpFramebuffer()
96 {
97 // We use an FBO to work around an issue where the default framebuffer applies SRGB
98 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
99 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
100 // section 4.4 says that the format of the default framebuffer is entirely up to the window
101 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
102 // SRGB conversion like desktop GL does.
103 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
104 glGenFramebuffers(1, &mFramebuffer);
105 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
106
107 glGenTextures(1, &mFramebufferColorTexture);
108 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
109 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
110 GL_UNSIGNED_BYTE, nullptr);
111 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
112 mFramebufferColorTexture, 0);
113 ASSERT_GL_NO_ERROR();
114 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
115 glBindTexture(GL_TEXTURE_2D, 0);
116 }
117
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200118 // Returns the created texture ID.
119 GLuint create2DTexture()
120 {
121 GLuint texture2D;
122 glGenTextures(1, &texture2D);
123 glBindTexture(GL_TEXTURE_2D, texture2D);
124 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
125 EXPECT_GL_NO_ERROR();
126 return texture2D;
127 }
128
129 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200130 GLuint mFramebuffer;
131
132 private:
133 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200134};
135
136class Texture2DTest : public TexCoordDrawTest
137{
138 protected:
139 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
140
141 std::string getFragmentShaderSource() override
142 {
143 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400144 (
145 precision highp float;
146 uniform sampler2D tex;
147 varying vec2 texcoord;
148
149 void main()
150 {
151 gl_FragColor = texture2D(tex, texcoord);
152 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200153 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400154 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200155 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400156
Olli Etuaho96963162016-03-21 11:54:33 +0200157 virtual const char *getTextureUniformName() { return "tex"; }
158
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300159 void setUpProgram() override
160 {
161 TexCoordDrawTest::setUpProgram();
162 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
163 ASSERT_NE(-1, mTexture2DUniformLocation);
164 }
165
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200166 void SetUp() override
167 {
168 TexCoordDrawTest::SetUp();
169 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400170
Jamie Madill9aca0592014-10-06 16:26:59 -0400171 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -0400172 }
173
Jamie Madillfa05f602015-05-07 13:47:11 -0400174 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400175 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400176 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200177 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400178 }
179
Jamie Madillbc393df2015-01-29 13:46:07 -0500180 // Tests CopyTexSubImage with floating point textures of various formats.
181 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
182 {
Geoff Langbde666a2015-04-07 17:17:08 -0400183 // TODO(jmadill): Figure out why this is broken on Intel D3D11
Jamie Madill518b9fa2016-03-02 11:26:02 -0500184 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Geoff Langbde666a2015-04-07 17:17:08 -0400185 {
186 std::cout << "Test skipped on Intel D3D11." << std::endl;
187 return;
188 }
189
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300190 setUpProgram();
191
Martin Radev1be913c2016-07-11 17:59:16 +0300192 if (getClientMajorVersion() < 3)
Geoff Langfbfa47c2015-03-31 11:26:00 -0400193 {
194 if (!extensionEnabled("GL_OES_texture_float"))
195 {
196 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
197 return;
198 }
199
200 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
201 {
202 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
203 return;
204 }
205 }
206
Jamie Madillbc393df2015-01-29 13:46:07 -0500207 GLfloat sourceImageData[4][16] =
208 {
209 { // R
210 1.0f,
211 0.0f,
212 0.0f,
213 1.0f
214 },
215 { // RG
216 1.0f, 0.0f,
217 0.0f, 1.0f,
218 0.0f, 0.0f,
219 1.0f, 1.0f
220 },
221 { // RGB
222 1.0f, 0.0f, 0.0f,
223 0.0f, 1.0f, 0.0f,
224 0.0f, 0.0f, 1.0f,
225 1.0f, 1.0f, 0.0f
226 },
227 { // RGBA
228 1.0f, 0.0f, 0.0f, 1.0f,
229 0.0f, 1.0f, 0.0f, 1.0f,
230 0.0f, 0.0f, 1.0f, 1.0f,
231 1.0f, 1.0f, 0.0f, 1.0f
232 },
233 };
234
235 GLenum imageFormats[] =
236 {
237 GL_R32F,
238 GL_RG32F,
239 GL_RGB32F,
240 GL_RGBA32F,
241 };
242
243 GLenum sourceUnsizedFormats[] =
244 {
245 GL_RED,
246 GL_RG,
247 GL_RGB,
248 GL_RGBA,
249 };
250
251 GLuint textures[2];
252
253 glGenTextures(2, textures);
254
255 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
256 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
257 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
258 GLenum destImageFormat = imageFormats[destImageChannels - 1];
259
260 glBindTexture(GL_TEXTURE_2D, textures[0]);
261 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
264 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
265
hendrikwb27f79a2015-03-04 11:26:46 -0800266 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500267 {
268 // This is not supported
269 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
270 }
271 else
272 {
273 ASSERT_GL_NO_ERROR();
274 }
275
276 GLuint fbo;
277 glGenFramebuffers(1, &fbo);
278 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
279 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
280
281 glBindTexture(GL_TEXTURE_2D, textures[1]);
282 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
283 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
284 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
285
286 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
287 ASSERT_GL_NO_ERROR();
288
289 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200290 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500291
292 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
293
Olli Etuahoa314b612016-03-10 16:43:00 +0200294 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Jamie Madillbc393df2015-01-29 13:46:07 -0500295 if (testImageChannels > 1)
296 {
297 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
298 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
299 if (testImageChannels > 2)
300 {
301 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
302 }
303 }
304
305 glDeleteFramebuffers(1, &fbo);
306 glDeleteTextures(2, textures);
307
308 ASSERT_GL_NO_ERROR();
309 }
310
Jamie Madilld4cfa572014-07-08 10:00:32 -0400311 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400312 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400313};
314
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200315class Texture2DTestES3 : public Texture2DTest
316{
317 protected:
318 Texture2DTestES3() : Texture2DTest() {}
319
320 std::string getVertexShaderSource() override
321 {
322 return std::string(
323 "#version 300 es\n"
324 "out vec2 texcoord;\n"
325 "in vec4 position;\n"
326 "void main()\n"
327 "{\n"
328 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
329 " texcoord = (position.xy * 0.5) + 0.5;\n"
330 "}\n");
331 }
332
333 std::string getFragmentShaderSource() override
334 {
335 return std::string(
336 "#version 300 es\n"
337 "precision highp float;\n"
338 "uniform highp sampler2D tex;\n"
339 "in vec2 texcoord;\n"
340 "out vec4 fragColor;\n"
341 "void main()\n"
342 "{\n"
343 " fragColor = texture(tex, texcoord);\n"
344 "}\n");
345 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300346
347 void SetUp() override
348 {
349 Texture2DTest::SetUp();
350 setUpProgram();
351 }
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200352};
353
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200354class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
355{
356 protected:
357 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
358
359 std::string getVertexShaderSource() override
360 {
361 return std::string(
362 "#version 300 es\n"
363 "out vec2 texcoord;\n"
364 "in vec4 position;\n"
365 "void main()\n"
366 "{\n"
367 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
368 " texcoord = (position.xy * 0.5) + 0.5;\n"
369 "}\n");
370 }
371
372 std::string getFragmentShaderSource() override
373 {
374 return std::string(
375 "#version 300 es\n"
376 "precision highp float;\n"
377 "uniform highp isampler2D tex;\n"
378 "in vec2 texcoord;\n"
379 "out vec4 fragColor;\n"
380 "void main()\n"
381 "{\n"
382 " vec4 green = vec4(0, 1, 0, 1);\n"
383 " vec4 black = vec4(0, 0, 0, 0);\n"
384 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
385 "}\n");
386 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300387
388 void SetUp() override
389 {
390 Texture2DTest::SetUp();
391 setUpProgram();
392 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200393};
394
395class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
396{
397 protected:
398 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
399
400 std::string getVertexShaderSource() override
401 {
402 return std::string(
403 "#version 300 es\n"
404 "out vec2 texcoord;\n"
405 "in vec4 position;\n"
406 "void main()\n"
407 "{\n"
408 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
409 " texcoord = (position.xy * 0.5) + 0.5;\n"
410 "}\n");
411 }
412
413 std::string getFragmentShaderSource() override
414 {
415 return std::string(
416 "#version 300 es\n"
417 "precision highp float;\n"
418 "uniform highp usampler2D tex;\n"
419 "in vec2 texcoord;\n"
420 "out vec4 fragColor;\n"
421 "void main()\n"
422 "{\n"
423 " vec4 green = vec4(0, 1, 0, 1);\n"
424 " vec4 black = vec4(0, 0, 0, 0);\n"
425 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
426 "}\n");
427 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300428
429 void SetUp() override
430 {
431 Texture2DTest::SetUp();
432 setUpProgram();
433 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200434};
435
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200436class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400437{
438 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200439 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
440
441 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400442 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200443 return std::string(SHADER_SOURCE
444 (
445 precision highp float;
446 attribute vec4 position;
447 varying vec2 texcoord;
448
449 uniform vec2 drawScale;
450
451 void main()
452 {
453 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
454 texcoord = (position.xy * 0.5) + 0.5;
455 }
456 )
457 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400458 }
459
460 void SetUp() override
461 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200462 Texture2DTest::SetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300463
464 setUpProgram();
465
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200466 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
467 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400468
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200469 glUseProgram(mProgram);
470 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
471 glUseProgram(0);
472 ASSERT_GL_NO_ERROR();
473 }
474
475 GLint mDrawScaleUniformLocation;
476};
477
Olli Etuaho4644a202016-01-12 15:12:53 +0200478class Sampler2DAsFunctionParameterTest : public Texture2DTest
479{
480 protected:
481 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
482
483 std::string getFragmentShaderSource() override
484 {
485 return std::string(SHADER_SOURCE
486 (
487 precision highp float;
488 uniform sampler2D tex;
489 varying vec2 texcoord;
490
491 vec4 computeFragColor(sampler2D aTex)
492 {
493 return texture2D(aTex, texcoord);
494 }
495
496 void main()
497 {
498 gl_FragColor = computeFragColor(tex);
499 }
500 )
501 );
502 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300503
504 void SetUp() override
505 {
506 Texture2DTest::SetUp();
507 setUpProgram();
508 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200509};
510
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200511class TextureCubeTest : public TexCoordDrawTest
512{
513 protected:
514 TextureCubeTest()
515 : TexCoordDrawTest(),
516 mTexture2D(0),
517 mTextureCube(0),
518 mTexture2DUniformLocation(-1),
519 mTextureCubeUniformLocation(-1)
520 {
521 }
522
523 std::string getFragmentShaderSource() override
524 {
525 return std::string(SHADER_SOURCE
526 (
527 precision highp float;
528 uniform sampler2D tex2D;
529 uniform samplerCube texCube;
530 varying vec2 texcoord;
531
532 void main()
533 {
534 gl_FragColor = texture2D(tex2D, texcoord);
535 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
536 }
537 )
538 );
539 }
540
541 void SetUp() override
542 {
543 TexCoordDrawTest::SetUp();
544
545 glGenTextures(1, &mTextureCube);
546 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
547 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
548 EXPECT_GL_NO_ERROR();
549
550 mTexture2D = create2DTexture();
551
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300552 setUpProgram();
553
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200554 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
555 ASSERT_NE(-1, mTexture2DUniformLocation);
556 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
557 ASSERT_NE(-1, mTextureCubeUniformLocation);
558 }
559
560 void TearDown() override
561 {
562 glDeleteTextures(1, &mTextureCube);
563 TexCoordDrawTest::TearDown();
564 }
565
566 GLuint mTexture2D;
567 GLuint mTextureCube;
568 GLint mTexture2DUniformLocation;
569 GLint mTextureCubeUniformLocation;
570};
571
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200572class SamplerArrayTest : public TexCoordDrawTest
573{
574 protected:
575 SamplerArrayTest()
576 : TexCoordDrawTest(),
577 mTexture2DA(0),
578 mTexture2DB(0),
579 mTexture0UniformLocation(-1),
580 mTexture1UniformLocation(-1)
581 {
582 }
583
584 std::string getFragmentShaderSource() override
585 {
586 return std::string(SHADER_SOURCE
587 (
588 precision mediump float;
589 uniform highp sampler2D tex2DArray[2];
590 varying vec2 texcoord;
591 void main()
592 {
593 gl_FragColor = texture2D(tex2DArray[0], texcoord);
594 gl_FragColor += texture2D(tex2DArray[1], texcoord);
595 }
596 )
597 );
598 }
599
600 void SetUp() override
601 {
602 TexCoordDrawTest::SetUp();
603
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300604 setUpProgram();
605
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200606 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
607 ASSERT_NE(-1, mTexture0UniformLocation);
608 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
609 ASSERT_NE(-1, mTexture1UniformLocation);
610
611 mTexture2DA = create2DTexture();
612 mTexture2DB = create2DTexture();
613 ASSERT_GL_NO_ERROR();
614 }
615
616 void TearDown() override
617 {
618 glDeleteTextures(1, &mTexture2DA);
619 glDeleteTextures(1, &mTexture2DB);
620 TexCoordDrawTest::TearDown();
621 }
622
623 void testSamplerArrayDraw()
624 {
625 GLubyte texData[4];
626 texData[0] = 0;
627 texData[1] = 60;
628 texData[2] = 0;
629 texData[3] = 255;
630
631 glActiveTexture(GL_TEXTURE0);
632 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
633 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
634
635 texData[1] = 120;
636 glActiveTexture(GL_TEXTURE1);
637 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
638 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
639 EXPECT_GL_ERROR(GL_NO_ERROR);
640
641 glUseProgram(mProgram);
642 glUniform1i(mTexture0UniformLocation, 0);
643 glUniform1i(mTexture1UniformLocation, 1);
644 drawQuad(mProgram, "position", 0.5f);
645 EXPECT_GL_NO_ERROR();
646
647 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
648 }
649
650 GLuint mTexture2DA;
651 GLuint mTexture2DB;
652 GLint mTexture0UniformLocation;
653 GLint mTexture1UniformLocation;
654};
655
656
657class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
658{
659 protected:
660 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
661
662 std::string getFragmentShaderSource() override
663 {
664 return std::string(SHADER_SOURCE
665 (
666 precision mediump float;
667 uniform highp sampler2D tex2DArray[2];
668 varying vec2 texcoord;
669
670 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
671 {
672 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
673 }
674
675 void main()
676 {
677 gl_FragColor = computeFragColor(tex2DArray);
678 }
679 )
680 );
681 }
682};
683
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200684class Texture2DArrayTestES3 : public TexCoordDrawTest
685{
686 protected:
687 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
688
689 std::string getVertexShaderSource() override
690 {
691 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400692 "#version 300 es\n"
693 "out vec2 texcoord;\n"
694 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200695 "void main()\n"
696 "{\n"
697 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
698 " texcoord = (position.xy * 0.5) + 0.5;\n"
699 "}\n");
700 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400701
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200702 std::string getFragmentShaderSource() override
703 {
704 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400705 "#version 300 es\n"
706 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200707 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400708 "in vec2 texcoord;\n"
709 "out vec4 fragColor;\n"
710 "void main()\n"
711 "{\n"
712 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200713 "}\n");
714 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400715
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200716 void SetUp() override
717 {
718 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400719
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300720 setUpProgram();
721
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200722 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400723 ASSERT_NE(-1, mTextureArrayLocation);
724
725 glGenTextures(1, &m2DArrayTexture);
726 ASSERT_GL_NO_ERROR();
727 }
728
729 void TearDown() override
730 {
731 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200732 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400733 }
734
735 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400736 GLint mTextureArrayLocation;
737};
738
Olli Etuahobce743a2016-01-15 17:18:28 +0200739class TextureSizeTextureArrayTest : public TexCoordDrawTest
740{
741 protected:
742 TextureSizeTextureArrayTest()
743 : TexCoordDrawTest(),
744 mTexture2DA(0),
745 mTexture2DB(0),
746 mTexture0Location(-1),
747 mTexture1Location(-1)
748 {
749 }
750
751 std::string getVertexShaderSource() override
752 {
753 return std::string(
754 "#version 300 es\n"
755 "in vec4 position;\n"
756 "void main()\n"
757 "{\n"
758 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
759 "}\n");
760 }
761
762 std::string getFragmentShaderSource() override
763 {
764 return std::string(
765 "#version 300 es\n"
766 "precision highp float;\n"
767 "uniform highp sampler2D tex2DArray[2];\n"
768 "out vec4 fragColor;\n"
769 "void main()\n"
770 "{\n"
771 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
772 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
773 " fragColor = vec4(red, green, 0.0, 1.0);\n"
774 "}\n");
775 }
776
777 void SetUp() override
778 {
779 TexCoordDrawTest::SetUp();
780
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300781 setUpProgram();
782
Olli Etuahobce743a2016-01-15 17:18:28 +0200783 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
784 ASSERT_NE(-1, mTexture0Location);
785 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
786 ASSERT_NE(-1, mTexture1Location);
787
788 mTexture2DA = create2DTexture();
789 mTexture2DB = create2DTexture();
790 ASSERT_GL_NO_ERROR();
791 }
792
793 void TearDown() override
794 {
795 glDeleteTextures(1, &mTexture2DA);
796 glDeleteTextures(1, &mTexture2DB);
797 TexCoordDrawTest::TearDown();
798 }
799
800 GLuint mTexture2DA;
801 GLuint mTexture2DB;
802 GLint mTexture0Location;
803 GLint mTexture1Location;
804};
805
Olli Etuahoa314b612016-03-10 16:43:00 +0200806class Texture3DTestES3 : public TexCoordDrawTest
807{
808 protected:
809 Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
810
811 std::string getVertexShaderSource() override
812 {
813 return std::string(
814 "#version 300 es\n"
815 "out vec2 texcoord;\n"
816 "in vec4 position;\n"
817 "void main()\n"
818 "{\n"
819 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
820 " texcoord = (position.xy * 0.5) + 0.5;\n"
821 "}\n");
822 }
823
824 std::string getFragmentShaderSource() override
825 {
826 return std::string(
827 "#version 300 es\n"
828 "precision highp float;\n"
829 "uniform highp sampler3D tex3D;\n"
830 "in vec2 texcoord;\n"
831 "out vec4 fragColor;\n"
832 "void main()\n"
833 "{\n"
834 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
835 "}\n");
836 }
837
838 void SetUp() override
839 {
840 TexCoordDrawTest::SetUp();
841
842 glGenTextures(1, &mTexture3D);
843
844 setUpProgram();
845
846 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
847 ASSERT_NE(-1, mTexture3DUniformLocation);
848 }
849
850 void TearDown() override
851 {
852 glDeleteTextures(1, &mTexture3D);
853 TexCoordDrawTest::TearDown();
854 }
855
856 GLuint mTexture3D;
857 GLint mTexture3DUniformLocation;
858};
859
Olli Etuaho1a679902016-01-14 12:21:47 +0200860class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
861{
862 protected:
863 ShadowSamplerPlusSampler3DTestES3()
864 : TexCoordDrawTest(),
865 mTextureShadow(0),
866 mTexture3D(0),
867 mTextureShadowUniformLocation(-1),
868 mTexture3DUniformLocation(-1),
869 mDepthRefUniformLocation(-1)
870 {
871 }
872
873 std::string getVertexShaderSource() override
874 {
875 return std::string(
876 "#version 300 es\n"
877 "out vec2 texcoord;\n"
878 "in vec4 position;\n"
879 "void main()\n"
880 "{\n"
881 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
882 " texcoord = (position.xy * 0.5) + 0.5;\n"
883 "}\n");
884 }
885
886 std::string getFragmentShaderSource() override
887 {
888 return std::string(
889 "#version 300 es\n"
890 "precision highp float;\n"
891 "uniform highp sampler2DShadow tex2DShadow;\n"
892 "uniform highp sampler3D tex3D;\n"
893 "in vec2 texcoord;\n"
894 "uniform float depthRef;\n"
895 "out vec4 fragColor;\n"
896 "void main()\n"
897 "{\n"
898 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
899 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
900 "}\n");
901 }
902
903 void SetUp() override
904 {
905 TexCoordDrawTest::SetUp();
906
907 glGenTextures(1, &mTexture3D);
908
909 glGenTextures(1, &mTextureShadow);
910 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
911 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
912
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300913 setUpProgram();
914
Olli Etuaho1a679902016-01-14 12:21:47 +0200915 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
916 ASSERT_NE(-1, mTextureShadowUniformLocation);
917 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
918 ASSERT_NE(-1, mTexture3DUniformLocation);
919 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
920 ASSERT_NE(-1, mDepthRefUniformLocation);
921 }
922
923 void TearDown() override
924 {
925 glDeleteTextures(1, &mTextureShadow);
926 glDeleteTextures(1, &mTexture3D);
927 TexCoordDrawTest::TearDown();
928 }
929
930 GLuint mTextureShadow;
931 GLuint mTexture3D;
932 GLint mTextureShadowUniformLocation;
933 GLint mTexture3DUniformLocation;
934 GLint mDepthRefUniformLocation;
935};
936
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200937class SamplerTypeMixTestES3 : public TexCoordDrawTest
938{
939 protected:
940 SamplerTypeMixTestES3()
941 : TexCoordDrawTest(),
942 mTexture2D(0),
943 mTextureCube(0),
944 mTexture2DShadow(0),
945 mTextureCubeShadow(0),
946 mTexture2DUniformLocation(-1),
947 mTextureCubeUniformLocation(-1),
948 mTexture2DShadowUniformLocation(-1),
949 mTextureCubeShadowUniformLocation(-1),
950 mDepthRefUniformLocation(-1)
951 {
952 }
953
954 std::string getVertexShaderSource() override
955 {
956 return std::string(
957 "#version 300 es\n"
958 "out vec2 texcoord;\n"
959 "in vec4 position;\n"
960 "void main()\n"
961 "{\n"
962 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
963 " texcoord = (position.xy * 0.5) + 0.5;\n"
964 "}\n");
965 }
966
967 std::string getFragmentShaderSource() override
968 {
969 return std::string(
970 "#version 300 es\n"
971 "precision highp float;\n"
972 "uniform highp sampler2D tex2D;\n"
973 "uniform highp samplerCube texCube;\n"
974 "uniform highp sampler2DShadow tex2DShadow;\n"
975 "uniform highp samplerCubeShadow texCubeShadow;\n"
976 "in vec2 texcoord;\n"
977 "uniform float depthRef;\n"
978 "out vec4 fragColor;\n"
979 "void main()\n"
980 "{\n"
981 " fragColor = texture(tex2D, texcoord);\n"
982 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
983 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
984 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
985 "0.125);\n"
986 "}\n");
987 }
988
989 void SetUp() override
990 {
991 TexCoordDrawTest::SetUp();
992
993 glGenTextures(1, &mTexture2D);
994 glGenTextures(1, &mTextureCube);
995
996 glGenTextures(1, &mTexture2DShadow);
997 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
998 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
999
1000 glGenTextures(1, &mTextureCubeShadow);
1001 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1002 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1003
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001004 setUpProgram();
1005
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001006 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1007 ASSERT_NE(-1, mTexture2DUniformLocation);
1008 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1009 ASSERT_NE(-1, mTextureCubeUniformLocation);
1010 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1011 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1012 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1013 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1014 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1015 ASSERT_NE(-1, mDepthRefUniformLocation);
1016
1017 ASSERT_GL_NO_ERROR();
1018 }
1019
1020 void TearDown() override
1021 {
1022 glDeleteTextures(1, &mTexture2D);
1023 glDeleteTextures(1, &mTextureCube);
1024 glDeleteTextures(1, &mTexture2DShadow);
1025 glDeleteTextures(1, &mTextureCubeShadow);
1026 TexCoordDrawTest::TearDown();
1027 }
1028
1029 GLuint mTexture2D;
1030 GLuint mTextureCube;
1031 GLuint mTexture2DShadow;
1032 GLuint mTextureCubeShadow;
1033 GLint mTexture2DUniformLocation;
1034 GLint mTextureCubeUniformLocation;
1035 GLint mTexture2DShadowUniformLocation;
1036 GLint mTextureCubeShadowUniformLocation;
1037 GLint mDepthRefUniformLocation;
1038};
1039
Olli Etuaho96963162016-03-21 11:54:33 +02001040class SamplerInStructTest : public Texture2DTest
1041{
1042 protected:
1043 SamplerInStructTest() : Texture2DTest() {}
1044
1045 const char *getTextureUniformName() override { return "us.tex"; }
1046
1047 std::string getFragmentShaderSource() override
1048 {
1049 return std::string(
1050 "precision highp float;\n"
1051 "struct S\n"
1052 "{\n"
1053 " vec4 a;\n"
1054 " highp sampler2D tex;\n"
1055 "};\n"
1056 "uniform S us;\n"
1057 "varying vec2 texcoord;\n"
1058 "void main()\n"
1059 "{\n"
1060 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1061 "}\n");
1062 }
1063
1064 void runSamplerInStructTest()
1065 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001066 setUpProgram();
1067
Olli Etuaho96963162016-03-21 11:54:33 +02001068 glActiveTexture(GL_TEXTURE0);
1069 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001070 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1071 &GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001072 drawQuad(mProgram, "position", 0.5f);
Olli Etuahoa314b612016-03-10 16:43:00 +02001073 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001074 }
1075};
1076
1077class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1078{
1079 protected:
1080 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1081
1082 std::string getFragmentShaderSource() override
1083 {
1084 return std::string(
1085 "precision highp float;\n"
1086 "struct S\n"
1087 "{\n"
1088 " vec4 a;\n"
1089 " highp sampler2D tex;\n"
1090 "};\n"
1091 "uniform S us;\n"
1092 "varying vec2 texcoord;\n"
1093 "vec4 sampleFrom(S s) {\n"
1094 " return texture2D(s.tex, texcoord + s.a.x);\n"
1095 "}\n"
1096 "void main()\n"
1097 "{\n"
1098 " gl_FragColor = sampleFrom(us);\n"
1099 "}\n");
1100 }
1101};
1102
1103class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1104{
1105 protected:
1106 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1107
1108 const char *getTextureUniformName() override { return "us[0].tex"; }
1109
1110 std::string getFragmentShaderSource() override
1111 {
1112 return std::string(
1113 "precision highp float;\n"
1114 "struct S\n"
1115 "{\n"
1116 " vec4 a;\n"
1117 " highp sampler2D tex;\n"
1118 "};\n"
1119 "uniform S us[1];\n"
1120 "varying vec2 texcoord;\n"
1121 "vec4 sampleFrom(S s) {\n"
1122 " return texture2D(s.tex, texcoord + s.a.x);\n"
1123 "}\n"
1124 "void main()\n"
1125 "{\n"
1126 " gl_FragColor = sampleFrom(us[0]);\n"
1127 "}\n");
1128 }
1129};
1130
1131class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1132{
1133 protected:
1134 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1135
1136 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1137
1138 std::string getFragmentShaderSource() override
1139 {
1140 return std::string(
1141 "precision highp float;\n"
1142 "struct SUB\n"
1143 "{\n"
1144 " vec4 a;\n"
1145 " highp sampler2D tex;\n"
1146 "};\n"
1147 "struct S\n"
1148 "{\n"
1149 " SUB sub;\n"
1150 "};\n"
1151 "uniform S us[1];\n"
1152 "varying vec2 texcoord;\n"
1153 "vec4 sampleFrom(SUB s) {\n"
1154 " return texture2D(s.tex, texcoord + s.a.x);\n"
1155 "}\n"
1156 "void main()\n"
1157 "{\n"
1158 " gl_FragColor = sampleFrom(us[0].sub);\n"
1159 "}\n");
1160 }
1161};
1162
1163class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1164{
1165 protected:
1166 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1167
1168 std::string getFragmentShaderSource() override
1169 {
1170 return std::string(
1171 "precision highp float;\n"
1172 "struct S\n"
1173 "{\n"
1174 " vec4 a;\n"
1175 " highp sampler2D tex;\n"
1176 "};\n"
1177 "uniform S us;\n"
1178 "uniform float us_tex;\n"
1179 "varying vec2 texcoord;\n"
1180 "void main()\n"
1181 "{\n"
1182 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1183 "}\n");
1184 }
1185};
1186
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001187TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001188{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001189 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001190 EXPECT_GL_ERROR(GL_NO_ERROR);
1191
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001192 setUpProgram();
1193
Jamie Madillf67115c2014-04-22 13:14:05 -04001194 const GLubyte *pixels[20] = { 0 };
1195 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1196 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1197}
Geoff Langc41e42d2014-04-28 10:58:16 -04001198
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001199TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001200{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001201 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001202 EXPECT_GL_ERROR(GL_NO_ERROR);
1203
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001204 setUpProgram();
1205
Geoff Langc41e42d2014-04-28 10:58:16 -04001206 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001207 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001208 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001209 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001210
1211 const GLubyte *pixel[4] = { 0 };
1212
1213 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1214 EXPECT_GL_NO_ERROR();
1215
1216 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1217 EXPECT_GL_NO_ERROR();
1218
1219 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1220 EXPECT_GL_NO_ERROR();
1221}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001222
1223// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001224TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001225{
1226 glActiveTexture(GL_TEXTURE0);
1227 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1228 glActiveTexture(GL_TEXTURE1);
1229 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1230 EXPECT_GL_ERROR(GL_NO_ERROR);
1231
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001232 glUseProgram(mProgram);
1233 glUniform1i(mTexture2DUniformLocation, 0);
1234 glUniform1i(mTextureCubeUniformLocation, 1);
1235 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001236 EXPECT_GL_NO_ERROR();
1237}
Jamie Madill9aca0592014-10-06 16:26:59 -04001238
Olli Etuaho53a2da12016-01-11 15:43:32 +02001239// Test drawing with two texture types accessed from the same shader and check that the result of
1240// drawing is correct.
1241TEST_P(TextureCubeTest, CubeMapDraw)
1242{
1243 GLubyte texData[4];
1244 texData[0] = 0;
1245 texData[1] = 60;
1246 texData[2] = 0;
1247 texData[3] = 255;
1248
1249 glActiveTexture(GL_TEXTURE0);
1250 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1251 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1252
1253 glActiveTexture(GL_TEXTURE1);
1254 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1255 texData[1] = 120;
1256 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1257 texData);
1258 EXPECT_GL_ERROR(GL_NO_ERROR);
1259
1260 glUseProgram(mProgram);
1261 glUniform1i(mTexture2DUniformLocation, 0);
1262 glUniform1i(mTextureCubeUniformLocation, 1);
1263 drawQuad(mProgram, "position", 0.5f);
1264 EXPECT_GL_NO_ERROR();
1265
1266 int px = getWindowWidth() - 1;
1267 int py = 0;
1268 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1269}
1270
Olli Etuaho4644a202016-01-12 15:12:53 +02001271TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1272{
1273 glActiveTexture(GL_TEXTURE0);
1274 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1275 GLubyte texData[4];
1276 texData[0] = 0;
1277 texData[1] = 128;
1278 texData[2] = 0;
1279 texData[3] = 255;
1280 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1281 glUseProgram(mProgram);
1282 glUniform1i(mTexture2DUniformLocation, 0);
1283 drawQuad(mProgram, "position", 0.5f);
1284 EXPECT_GL_NO_ERROR();
1285
1286 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1287}
1288
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001289// Test drawing with two textures passed to the shader in a sampler array.
1290TEST_P(SamplerArrayTest, SamplerArrayDraw)
1291{
1292 testSamplerArrayDraw();
1293}
1294
1295// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1296// user-defined function in the shader.
1297TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1298{
1299 testSamplerArrayDraw();
1300}
1301
Jamie Madill9aca0592014-10-06 16:26:59 -04001302// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001303TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001304{
1305 int px = getWindowWidth() / 2;
1306 int py = getWindowHeight() / 2;
1307
1308 glActiveTexture(GL_TEXTURE0);
1309 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1310
Olli Etuahoa314b612016-03-10 16:43:00 +02001311 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001312
Olli Etuahoa314b612016-03-10 16:43:00 +02001313 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1316 glGenerateMipmap(GL_TEXTURE_2D);
1317
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001318 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001319 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001320 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1321 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001322 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001323 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001324
Olli Etuahoa314b612016-03-10 16:43:00 +02001325 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001326
Olli Etuahoa314b612016-03-10 16:43:00 +02001327 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1328 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001329 glGenerateMipmap(GL_TEXTURE_2D);
1330
Olli Etuahoa314b612016-03-10 16:43:00 +02001331 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001332
Olli Etuahoa314b612016-03-10 16:43:00 +02001333 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1334 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001335 glGenerateMipmap(GL_TEXTURE_2D);
1336
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001337 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001338
1339 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001340 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001341}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001342
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001343// Test creating a FBO with a cube map render target, to test an ANGLE bug
1344// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001345TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001346{
1347 GLuint fbo;
1348 glGenFramebuffers(1, &fbo);
1349 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1350
1351 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1352 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1353
Corentin Wallez322653b2015-06-17 18:33:56 +02001354 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001355
1356 glDeleteFramebuffers(1, &fbo);
1357
1358 EXPECT_GL_NO_ERROR();
1359}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001360
1361// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001362TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001363{
1364 int width = getWindowWidth();
1365 int height = getWindowHeight();
1366
1367 GLuint tex2D;
1368 glGenTextures(1, &tex2D);
1369 glActiveTexture(GL_TEXTURE0);
1370 glBindTexture(GL_TEXTURE_2D, tex2D);
1371
1372 // Fill with red
1373 std::vector<GLubyte> pixels(3 * 16 * 16);
1374 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1375 {
1376 pixels[pixelId * 3 + 0] = 255;
1377 pixels[pixelId * 3 + 1] = 0;
1378 pixels[pixelId * 3 + 2] = 0;
1379 }
1380
1381 // ANGLE internally uses RGBA as the DirectX format for RGB images
1382 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1383 // The data is kept in a CPU-side image and the image is marked as dirty.
1384 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1385
1386 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1387 // glTexSubImage2D should take into account that the image is dirty.
1388 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1391
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001392 setUpProgram();
1393
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001394 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001395 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001396 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001397 glDeleteTextures(1, &tex2D);
1398 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001399 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001400
1401 // Validate that the region of the texture without data has an alpha of 1.0
1402 GLubyte pixel[4];
1403 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1404 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001405}
1406
1407// 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 +02001408TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001409{
1410 if (extensionEnabled("NV_pixel_buffer_object"))
1411 {
1412 int width = getWindowWidth();
1413 int height = getWindowHeight();
1414
1415 GLuint tex2D;
1416 glGenTextures(1, &tex2D);
1417 glActiveTexture(GL_TEXTURE0);
1418 glBindTexture(GL_TEXTURE_2D, tex2D);
1419
1420 // Fill with red
1421 std::vector<GLubyte> pixels(3 * 16 * 16);
1422 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1423 {
1424 pixels[pixelId * 3 + 0] = 255;
1425 pixels[pixelId * 3 + 1] = 0;
1426 pixels[pixelId * 3 + 2] = 0;
1427 }
1428
1429 // Read 16x16 region from red backbuffer to PBO
1430 GLuint pbo;
1431 glGenBuffers(1, &pbo);
1432 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1433 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1434
1435 // ANGLE internally uses RGBA as the DirectX format for RGB images
1436 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1437 // The data is kept in a CPU-side image and the image is marked as dirty.
1438 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1439
1440 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1441 // glTexSubImage2D should take into account that the image is dirty.
1442 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1443 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1444 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1445
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001446 setUpProgram();
1447
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001448 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001449 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001450 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001451 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001452 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001453 EXPECT_GL_NO_ERROR();
1454 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1455 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1456 }
1457}
Jamie Madillbc393df2015-01-29 13:46:07 -05001458
1459// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001460TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001461{
1462 testFloatCopySubImage(1, 1);
1463}
1464
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001465TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001466{
1467 testFloatCopySubImage(2, 1);
1468}
1469
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001470TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001471{
1472 testFloatCopySubImage(2, 2);
1473}
1474
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001475TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001476{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001477 if (IsIntel() && IsLinux())
1478 {
1479 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1480 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1481 return;
1482 }
1483
Jamie Madillbc393df2015-01-29 13:46:07 -05001484 testFloatCopySubImage(3, 1);
1485}
1486
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001487TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001488{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001489 if (IsIntel() && IsLinux())
1490 {
1491 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1492 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1493 return;
1494 }
1495
Jamie Madillbc393df2015-01-29 13:46:07 -05001496 testFloatCopySubImage(3, 2);
1497}
1498
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001499TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001500{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001501 if (IsIntel() && IsLinux())
1502 {
1503 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1504 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1505 return;
1506 }
1507
Austin Kinrossd544cc92016-01-11 15:26:42 -08001508 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001509 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001510 {
1511 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1512 return;
1513 }
1514
Jamie Madillbc393df2015-01-29 13:46:07 -05001515 testFloatCopySubImage(3, 3);
1516}
1517
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001518TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001519{
1520 testFloatCopySubImage(4, 1);
1521}
1522
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001523TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001524{
1525 testFloatCopySubImage(4, 2);
1526}
1527
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001528TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001529{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001530 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001531 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001532 {
1533 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1534 return;
1535 }
1536
Jamie Madillbc393df2015-01-29 13:46:07 -05001537 testFloatCopySubImage(4, 3);
1538}
1539
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001540TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001541{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001542 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001543 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001544 {
1545 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1546 return;
1547 }
1548
Jamie Madillbc393df2015-01-29 13:46:07 -05001549 testFloatCopySubImage(4, 4);
1550}
Austin Kinross07285142015-03-26 11:36:16 -07001551
1552// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1553// 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 +02001554TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001555{
1556 const int npotTexSize = 5;
1557 const int potTexSize = 4; // Should be less than npotTexSize
1558 GLuint tex2D;
1559
1560 if (extensionEnabled("GL_OES_texture_npot"))
1561 {
1562 // This test isn't applicable if texture_npot is enabled
1563 return;
1564 }
1565
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001566 setUpProgram();
1567
Austin Kinross07285142015-03-26 11:36:16 -07001568 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1569
Austin Kinross5faa15b2016-01-11 13:32:48 -08001570 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1571 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1572
Austin Kinross07285142015-03-26 11:36:16 -07001573 glActiveTexture(GL_TEXTURE0);
1574 glGenTextures(1, &tex2D);
1575 glBindTexture(GL_TEXTURE_2D, tex2D);
1576
1577 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1578 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1579 {
1580 pixels[pixelId] = 64;
1581 }
1582
1583 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1585
1586 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1587 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1588 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1589
1590 // Check that an NPOT texture on level 0 succeeds
1591 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1592 EXPECT_GL_NO_ERROR();
1593
1594 // Check that generateMipmap fails on NPOT
1595 glGenerateMipmap(GL_TEXTURE_2D);
1596 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1597
1598 // Check that nothing is drawn if filtering is not correct for NPOT
1599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1600 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1601 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1602 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1603 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001604 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001605 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1606
1607 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1611 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001612 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001613 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1614
1615 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1617 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001618 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001619 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1620
1621 // Check that glTexImage2D for POT texture succeeds
1622 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1623 EXPECT_GL_NO_ERROR();
1624
1625 // Check that generateMipmap for an POT texture succeeds
1626 glGenerateMipmap(GL_TEXTURE_2D);
1627 EXPECT_GL_NO_ERROR();
1628
1629 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1630 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1631 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1632 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1633 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1634 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001635 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001636 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1637 EXPECT_GL_NO_ERROR();
1638}
Jamie Madillfa05f602015-05-07 13:47:11 -04001639
Austin Kinross08528e12015-10-07 16:24:40 -07001640// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1641// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001642TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001643{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001644 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1645 // 1278)
1646 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1647 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1648 {
1649 std::cout << "Test disabled on OpenGL." << std::endl;
1650 return;
1651 }
1652
Austin Kinross08528e12015-10-07 16:24:40 -07001653 glActiveTexture(GL_TEXTURE0);
1654 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1655
1656 // Create an 8x8 (i.e. power-of-two) texture.
1657 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1659 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1660 glGenerateMipmap(GL_TEXTURE_2D);
1661
1662 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1663 // This should always work, even if GL_OES_texture_npot isn't active.
1664 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1665
1666 EXPECT_GL_NO_ERROR();
1667}
1668
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001669// Test to check that texture completeness is determined correctly when the texture base level is
1670// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1671TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1672{
1673 glActiveTexture(GL_TEXTURE0);
1674 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001675
1676 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
1677 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1678 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1679 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1680 texDataGreen.data());
1681 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1682 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001683 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1684 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1685 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1686
1687 EXPECT_GL_NO_ERROR();
1688
1689 drawQuad(mProgram, "position", 0.5f);
1690
Olli Etuahoa314b612016-03-10 16:43:00 +02001691 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1692}
1693
1694// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1695// have images defined.
1696TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
1697{
1698 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1699 {
1700 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
1701 std::cout << "Test skipped on AMD OpenGL." << std::endl;
1702 return;
1703 }
1704 if (IsOSX())
1705 {
1706 // Observed incorrect rendering on OSX.
1707 std::cout << "Test skipped on OSX." << std::endl;
1708 return;
1709 }
1710 glActiveTexture(GL_TEXTURE0);
1711 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1712 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1713 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1714 texDataGreen.data());
1715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1716 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1719
1720 EXPECT_GL_NO_ERROR();
1721
1722 drawQuad(mProgram, "position", 0.5f);
1723
1724 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1725}
1726
Olli Etuahoe8528d82016-05-16 17:50:52 +03001727// Test that drawing works correctly when level 0 is undefined and base level is 1.
1728TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
1729{
1730 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1731 {
1732 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
1733 std::cout << "Test skipped on AMD OpenGL." << std::endl;
1734 return;
1735 }
1736 if (IsOSX())
1737 {
1738 // Observed incorrect rendering on OSX.
1739 std::cout << "Test skipped on OSX." << std::endl;
1740 return;
1741 }
1742 glActiveTexture(GL_TEXTURE0);
1743 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1744 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1745 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1746 texDataGreen.data());
1747 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1748 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1751
1752 EXPECT_GL_NO_ERROR();
1753
1754 // Texture is incomplete.
1755 drawQuad(mProgram, "position", 0.5f);
1756 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
1757
1758 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1759 texDataGreen.data());
1760
1761 // Texture is now complete.
1762 drawQuad(mProgram, "position", 0.5f);
1763 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1764}
1765
Olli Etuahoa314b612016-03-10 16:43:00 +02001766// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1767// dimensions that don't fit the images inside the range.
1768// GLES 3.0.4 section 3.8.13 Texture completeness
1769TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1770{
1771 if (IsOSX())
1772 {
1773 // Observed incorrect rendering on OSX.
1774 std::cout << "Test skipped on OSX." << std::endl;
1775 return;
1776 }
1777 glActiveTexture(GL_TEXTURE0);
1778 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1779 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
1780 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1781 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
1782
1783 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1784 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1785
1786 // Two levels that are initially unused.
1787 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1788 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1789 texDataCyan.data());
1790
1791 // One level that is used - only this level should affect completeness.
1792 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1793 texDataGreen.data());
1794
1795 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1796 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1797
1798 EXPECT_GL_NO_ERROR();
1799
1800 drawQuad(mProgram, "position", 0.5f);
1801
1802 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1803
1804 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1805 {
1806 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1807 // level was changed.
1808 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1809 return;
1810 }
1811
1812 // Switch the level that is being used to the cyan level 2.
1813 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
1814 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1815
1816 EXPECT_GL_NO_ERROR();
1817
1818 drawQuad(mProgram, "position", 0.5f);
1819
1820 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1821}
1822
1823// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1824// have images defined.
1825TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
1826{
1827 if (IsOSX())
1828 {
1829 // Observed incorrect rendering on OSX.
1830 std::cout << "Test skipped on OSX." << std::endl;
1831 return;
1832 }
1833 glActiveTexture(GL_TEXTURE0);
1834 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1835 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1836 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1837 texDataGreen.data());
1838 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1839 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1840 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1841 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1842
1843 EXPECT_GL_NO_ERROR();
1844
1845 drawQuad(mProgram, "position", 0.5f);
1846
1847 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1848}
1849
1850// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1851// dimensions that don't fit the images inside the range.
1852// GLES 3.0.4 section 3.8.13 Texture completeness
1853TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1854{
1855 if (IsOSX())
1856 {
1857 // Observed incorrect rendering on OSX.
1858 std::cout << "Test skipped on OSX." << std::endl;
1859 return;
1860 }
1861 glActiveTexture(GL_TEXTURE0);
1862 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1863 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1864 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1865 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1866
1867 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1868 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1869
1870 // Two levels that are initially unused.
1871 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1872 texDataRed.data());
1873 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1874 texDataCyan.data());
1875
1876 // One level that is used - only this level should affect completeness.
1877 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1878 texDataGreen.data());
1879
1880 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1881 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1882
1883 EXPECT_GL_NO_ERROR();
1884
1885 drawQuad(mProgram, "position", 0.5f);
1886
1887 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1888
1889 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1890 {
1891 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1892 // level was changed.
1893 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1894 return;
1895 }
1896
1897 // Switch the level that is being used to the cyan level 2.
1898 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
1899 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
1900
1901 EXPECT_GL_NO_ERROR();
1902
1903 drawQuad(mProgram, "position", 0.5f);
1904
1905 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1906}
1907
1908// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1909// have images defined.
1910TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
1911{
1912 if (IsOSX())
1913 {
1914 // Observed incorrect rendering on OSX.
1915 std::cout << "Test skipped on OSX." << std::endl;
1916 return;
1917 }
1918 glActiveTexture(GL_TEXTURE0);
1919 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
1920 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1921 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1922 texDataGreen.data());
1923 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1924 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1925 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1926 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1927
1928 EXPECT_GL_NO_ERROR();
1929
1930 drawQuad(mProgram, "position", 0.5f);
1931
1932 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1933}
1934
1935// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1936// dimensions that don't fit the images inside the range.
1937// GLES 3.0.4 section 3.8.13 Texture completeness
1938TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1939{
1940 if (IsOSX())
1941 {
1942 // Observed incorrect rendering on OSX.
1943 std::cout << "Test skipped on OSX." << std::endl;
1944 return;
1945 }
1946 glActiveTexture(GL_TEXTURE0);
1947 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
1948 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1949 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1950 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1951
1952 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1953 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1954
1955 // Two levels that are initially unused.
1956 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1957 texDataRed.data());
1958 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1959 texDataCyan.data());
1960
1961 // One level that is used - only this level should affect completeness.
1962 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1963 texDataGreen.data());
1964
1965 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1966 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1967
1968 EXPECT_GL_NO_ERROR();
1969
1970 drawQuad(mProgram, "position", 0.5f);
1971
1972 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1973
1974 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1975 {
1976 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1977 // level was changed.
1978 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1979 return;
1980 }
1981 if (IsNVIDIA() && (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1982 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE))
1983 {
1984 // NVIDIA was observed drawing color 0,0,0,0 instead of the texture color after the base
1985 // level was changed.
1986 std::cout << "Test partially skipped on NVIDIA OpenGL." << std::endl;
1987 return;
1988 }
1989
1990 // Switch the level that is being used to the cyan level 2.
1991 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
1992 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
1993
1994 EXPECT_GL_NO_ERROR();
1995
1996 drawQuad(mProgram, "position", 0.5f);
1997
1998 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1999}
2000
2001// Test that texture completeness is updated if texture max level changes.
2002// GLES 3.0.4 section 3.8.13 Texture completeness
2003TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2004{
2005 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2006 {
2007 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2008 // the base level.
2009 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2010 return;
2011 }
2012 if (IsOSX())
2013 {
2014 // Observed incorrect rendering on OSX.
2015 std::cout << "Test skipped on OSX." << std::endl;
2016 return;
2017 }
2018
2019 glActiveTexture(GL_TEXTURE0);
2020 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2021 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2022
2023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2024 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2025
2026 // A level that is initially unused.
2027 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2028 texDataGreen.data());
2029
2030 // One level that is initially used - only this level should affect completeness.
2031 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2032 texDataGreen.data());
2033
2034 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2035 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2036
2037 EXPECT_GL_NO_ERROR();
2038
2039 drawQuad(mProgram, "position", 0.5f);
2040
2041 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2042
2043 // Switch the max level to level 1. The levels within the used range now have inconsistent
2044 // dimensions and the texture should be incomplete.
2045 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2046
2047 EXPECT_GL_NO_ERROR();
2048
2049 drawQuad(mProgram, "position", 0.5f);
2050
2051 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2052}
2053
2054// Test that 3D texture completeness is updated if texture max level changes.
2055// GLES 3.0.4 section 3.8.13 Texture completeness
2056TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2057{
2058 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2059 {
2060 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2061 // the base level.
2062 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2063 return;
2064 }
2065 if (IsOSX())
2066 {
2067 // Observed incorrect rendering on OSX.
2068 std::cout << "Test skipped on OSX." << std::endl;
2069 return;
2070 }
2071
2072 glActiveTexture(GL_TEXTURE0);
2073 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2074 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2075
2076 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2077 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2078
2079 // A level that is initially unused.
2080 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2081 texDataGreen.data());
2082
2083 // One level that is initially used - only this level should affect completeness.
2084 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2085 texDataGreen.data());
2086
2087 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2088 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2089
2090 EXPECT_GL_NO_ERROR();
2091
2092 drawQuad(mProgram, "position", 0.5f);
2093
2094 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2095
2096 // Switch the max level to level 1. The levels within the used range now have inconsistent
2097 // dimensions and the texture should be incomplete.
2098 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2099
2100 EXPECT_GL_NO_ERROR();
2101
2102 drawQuad(mProgram, "position", 0.5f);
2103
2104 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2105}
2106
2107// Test that texture completeness is updated if texture base level changes.
2108// GLES 3.0.4 section 3.8.13 Texture completeness
2109TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2110{
2111 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2112 {
2113 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2114 // the base level.
2115 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2116 return;
2117 }
2118
2119 glActiveTexture(GL_TEXTURE0);
2120 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2121 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2122
2123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2125
2126 // Two levels that are initially unused.
2127 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2128 texDataGreen.data());
2129 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2130 texDataGreen.data());
2131
2132 // One level that is initially used - only this level should affect completeness.
2133 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2134 texDataGreen.data());
2135
2136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2138
2139 EXPECT_GL_NO_ERROR();
2140
2141 drawQuad(mProgram, "position", 0.5f);
2142
2143 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2144
2145 // Switch the base level to level 1. The levels within the used range now have inconsistent
2146 // dimensions and the texture should be incomplete.
2147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2148
2149 EXPECT_GL_NO_ERROR();
2150
2151 drawQuad(mProgram, "position", 0.5f);
2152
2153 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2154}
2155
2156// Test that texture is not complete if base level is greater than max level.
2157// GLES 3.0.4 section 3.8.13 Texture completeness
2158TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2159{
2160 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2161 {
2162 // Intel Windows OpenGL driver crashes if the base level of a non-immutable texture is out
2163 // of range.
2164 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2165 return;
2166 }
2167
2168 glActiveTexture(GL_TEXTURE0);
2169 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2170
2171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2173
2174 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2175
2176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2178
2179 EXPECT_GL_NO_ERROR();
2180
2181 drawQuad(mProgram, "position", 0.5f);
2182
2183 // Texture should be incomplete.
2184 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2185}
2186
2187// Test that immutable texture base level and max level are clamped.
2188// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2189TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2190{
Olli Etuahoa314b612016-03-10 16:43:00 +02002191 glActiveTexture(GL_TEXTURE0);
2192 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2193
2194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2196
2197 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2198
2199 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2200
2201 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2202 // should be clamped to [base_level, levels - 1].
2203 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2204 // In the case of this test, those rules make the effective base level and max level 0.
2205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2207
2208 EXPECT_GL_NO_ERROR();
2209
2210 drawQuad(mProgram, "position", 0.5f);
2211
2212 // Texture should be complete.
2213 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2214}
2215
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002216// Test that changing base level works when it affects the format of the texture.
2217TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2218{
Corentin Wallezc7f59d02016-06-20 10:12:08 -04002219 if (IsNVIDIA() && IsOpenGL())
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002220 {
2221 // Observed rendering corruption on NVIDIA OpenGL.
2222 std::cout << "Test skipped on NVIDIA OpenGL." << std::endl;
2223 return;
2224 }
Corentin Wallezc7f59d02016-06-20 10:12:08 -04002225 if (IsIntel() && IsDesktopOpenGL())
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002226 {
2227 // Observed incorrect rendering on Intel OpenGL.
2228 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2229 return;
2230 }
Corentin Wallezc7f59d02016-06-20 10:12:08 -04002231 if (IsAMD() && IsDesktopOpenGL())
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002232 {
2233 // Observed incorrect rendering on AMD OpenGL.
2234 std::cout << "Test skipped on AMD OpenGL." << std::endl;
2235 return;
2236 }
2237
2238 glActiveTexture(GL_TEXTURE0);
2239 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2240 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2241 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2242
2243 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2245
2246 // RGBA8 level that's initially unused.
2247 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2248 texDataCyan.data());
2249
2250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2252
2253 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2254 // format. It reads green channel data from the green and alpha channels of texDataGreen
2255 // (this is a bit hacky but works).
2256 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2257
2258 EXPECT_GL_NO_ERROR();
2259
2260 drawQuad(mProgram, "position", 0.5f);
2261
2262 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2263
2264 // Switch the texture to use the cyan level 0 with the RGBA format.
2265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2267
2268 EXPECT_GL_NO_ERROR();
2269
2270 drawQuad(mProgram, "position", 0.5f);
2271
2272 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2273}
2274
Olli Etuahoa314b612016-03-10 16:43:00 +02002275// Test that setting a texture image works when base level is out of range.
2276TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2277{
2278 glActiveTexture(GL_TEXTURE0);
2279 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2280
2281 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2282 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2283
2284 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2285 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2286
2287 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2288
2289 EXPECT_GL_NO_ERROR();
2290
2291 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2292
2293 drawQuad(mProgram, "position", 0.5f);
2294
2295 // Texture should be complete.
2296 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002297}
2298
Jamie Madill2453dbc2015-07-14 11:35:42 -04002299// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
2300// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
2301// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002302TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002303{
2304 std::vector<GLubyte> pixelData;
2305 for (size_t count = 0; count < 5000; count++)
2306 {
2307 pixelData.push_back(0u);
2308 pixelData.push_back(255u);
2309 pixelData.push_back(0u);
2310 }
2311
2312 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002313 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002314 glUniform1i(mTextureArrayLocation, 0);
2315
2316 // The first draw worked correctly.
2317 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
2318
2319 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2320 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2321 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2322 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002323 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002324 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002325
2326 // The dimension of the respecification must match the original exactly to trigger the bug.
2327 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 +02002328 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002329 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002330
2331 ASSERT_GL_NO_ERROR();
2332}
2333
Olli Etuaho1a679902016-01-14 12:21:47 +02002334// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2335// This test is needed especially to confirm that sampler registers get assigned correctly on
2336// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2337TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2338{
2339 glActiveTexture(GL_TEXTURE0);
2340 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2341 GLubyte texData[4];
2342 texData[0] = 0;
2343 texData[1] = 60;
2344 texData[2] = 0;
2345 texData[3] = 255;
2346 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2347
2348 glActiveTexture(GL_TEXTURE1);
2349 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2350 GLfloat depthTexData[1];
2351 depthTexData[0] = 0.5f;
2352 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2353 depthTexData);
2354
2355 glUseProgram(mProgram);
2356 glUniform1f(mDepthRefUniformLocation, 0.3f);
2357 glUniform1i(mTexture3DUniformLocation, 0);
2358 glUniform1i(mTextureShadowUniformLocation, 1);
2359
2360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2361 drawQuad(mProgram, "position", 0.5f);
2362 EXPECT_GL_NO_ERROR();
2363 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2364 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2365
2366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2367 drawQuad(mProgram, "position", 0.5f);
2368 EXPECT_GL_NO_ERROR();
2369 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2370 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2371}
2372
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002373// Test multiple different sampler types in the same shader.
2374// This test makes sure that even if sampler / texture registers get grouped together based on type
2375// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2376// still has the right register index information for each ESSL sampler.
2377// The tested ESSL samplers have the following types in D3D11 HLSL:
2378// sampler2D: Texture2D + SamplerState
2379// samplerCube: TextureCube + SamplerState
2380// sampler2DShadow: Texture2D + SamplerComparisonState
2381// samplerCubeShadow: TextureCube + SamplerComparisonState
2382TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2383{
2384 glActiveTexture(GL_TEXTURE0);
2385 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2386 GLubyte texData[4];
2387 texData[0] = 0;
2388 texData[1] = 0;
2389 texData[2] = 120;
2390 texData[3] = 255;
2391 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2392
2393 glActiveTexture(GL_TEXTURE1);
2394 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2395 texData[0] = 0;
2396 texData[1] = 90;
2397 texData[2] = 0;
2398 texData[3] = 255;
2399 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2400 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2401 texData);
2402
2403 glActiveTexture(GL_TEXTURE2);
2404 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2406 GLfloat depthTexData[1];
2407 depthTexData[0] = 0.5f;
2408 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2409 depthTexData);
2410
2411 glActiveTexture(GL_TEXTURE3);
2412 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2413 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2414 depthTexData[0] = 0.2f;
2415 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2416 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2417 depthTexData);
2418
2419 EXPECT_GL_NO_ERROR();
2420
2421 glUseProgram(mProgram);
2422 glUniform1f(mDepthRefUniformLocation, 0.3f);
2423 glUniform1i(mTexture2DUniformLocation, 0);
2424 glUniform1i(mTextureCubeUniformLocation, 1);
2425 glUniform1i(mTexture2DShadowUniformLocation, 2);
2426 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2427
2428 drawQuad(mProgram, "position", 0.5f);
2429 EXPECT_GL_NO_ERROR();
2430 // The shader writes:
2431 // <texture 2d color> +
2432 // <cube map color> +
2433 // 0.25 * <comparison result (1.0)> +
2434 // 0.125 * <comparison result (0.0)>
2435 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2436}
2437
Olli Etuahobce743a2016-01-15 17:18:28 +02002438// Test different base levels on textures accessed through the same sampler array.
2439// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2440TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2441{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002442 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02002443 {
2444 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
2445 return;
2446 }
2447 glActiveTexture(GL_TEXTURE0);
2448 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2449 GLsizei size = 64;
2450 for (GLint level = 0; level < 7; ++level)
2451 {
2452 ASSERT_LT(0, size);
2453 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2454 nullptr);
2455 size = size / 2;
2456 }
2457 ASSERT_EQ(0, size);
2458 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2459
2460 glActiveTexture(GL_TEXTURE1);
2461 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2462 size = 128;
2463 for (GLint level = 0; level < 8; ++level)
2464 {
2465 ASSERT_LT(0, size);
2466 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2467 nullptr);
2468 size = size / 2;
2469 }
2470 ASSERT_EQ(0, size);
2471 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2472 EXPECT_GL_NO_ERROR();
2473
2474 glUseProgram(mProgram);
2475 glUniform1i(mTexture0Location, 0);
2476 glUniform1i(mTexture1Location, 1);
2477
2478 drawQuad(mProgram, "position", 0.5f);
2479 EXPECT_GL_NO_ERROR();
2480 // Red channel: width of level 1 of texture A: 32.
2481 // Green channel: width of level 3 of texture B: 16.
2482 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2483}
2484
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002485// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2486// ES 3.0.4 table 3.24
2487TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2488{
2489 glActiveTexture(GL_TEXTURE0);
2490 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2491 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2492 EXPECT_GL_NO_ERROR();
2493
2494 drawQuad(mProgram, "position", 0.5f);
2495
2496 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2497}
2498
2499// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2500// ES 3.0.4 table 3.24
2501TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
2502{
2503 glActiveTexture(GL_TEXTURE0);
2504 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2505 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2506 EXPECT_GL_NO_ERROR();
2507
2508 drawQuad(mProgram, "position", 0.5f);
2509
2510 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2511}
2512
2513// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2514// ES 3.0.4 table 3.24
2515TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
2516{
2517 if (extensionEnabled("GL_OES_texture_float"))
2518 {
2519 glActiveTexture(GL_TEXTURE0);
2520 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2521 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
2522 EXPECT_GL_NO_ERROR();
2523
2524 drawQuad(mProgram, "position", 0.5f);
2525
2526 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2527 }
2528}
2529
2530// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2531// ES 3.0.4 table 3.24
2532TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
2533{
2534 if (extensionEnabled("GL_OES_texture_half_float"))
2535 {
Yuly Novikovafcec832016-06-21 22:19:51 -04002536 if (IsNVIDIA() && IsOpenGLES())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002537 {
2538 std::cout << "Test skipped on NVIDIA" << std::endl;
2539 return;
2540 }
Yuly Novikovafcec832016-06-21 22:19:51 -04002541 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
2542 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2543 {
2544 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2545 return;
2546 }
2547
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002548 glActiveTexture(GL_TEXTURE0);
2549 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2550 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
2551 nullptr);
2552 EXPECT_GL_NO_ERROR();
2553
2554 drawQuad(mProgram, "position", 0.5f);
2555
2556 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2557 }
2558}
2559
2560// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2561// ES 3.0.4 table 3.24
2562TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
2563{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002564 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002565 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002566 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002567 return;
2568 }
2569 glActiveTexture(GL_TEXTURE0);
2570 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2571 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
2572 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2573 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2574 EXPECT_GL_NO_ERROR();
2575
2576 drawQuad(mProgram, "position", 0.5f);
2577
2578 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2579}
2580
2581// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2582// ES 3.0.4 table 3.24
2583TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
2584{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002585 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002586 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002587 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002588 return;
2589 }
2590 glActiveTexture(GL_TEXTURE0);
2591 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2592
2593 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
2594 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2595 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2596 EXPECT_GL_NO_ERROR();
2597
2598 drawQuad(mProgram, "position", 0.5f);
2599
2600 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2601}
2602
2603// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2604// ES 3.0.4 table 3.24
2605TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
2606{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002607 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002608 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002609 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002610 return;
2611 }
2612 glActiveTexture(GL_TEXTURE0);
2613 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2614 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
2615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2617 EXPECT_GL_NO_ERROR();
2618
2619 drawQuad(mProgram, "position", 0.5f);
2620
2621 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2622}
2623
2624// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2625// ES 3.0.4 table 3.24
2626TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
2627{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002628 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002629 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002630 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002631 return;
2632 }
2633 glActiveTexture(GL_TEXTURE0);
2634 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2635 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
2636 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2637 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2638 EXPECT_GL_NO_ERROR();
2639
2640 drawQuad(mProgram, "position", 0.5f);
2641
2642 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2643}
2644
2645// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2646// ES 3.0.4 table 3.24
2647TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
2648{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002649 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002650 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002651 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002652 return;
2653 }
2654 glActiveTexture(GL_TEXTURE0);
2655 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2656 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
2657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2659 EXPECT_GL_NO_ERROR();
2660
2661 drawQuad(mProgram, "position", 0.5f);
2662
2663 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2664}
2665
2666// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2667// ES 3.0.4 table 3.24
2668TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
2669{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002670 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002671 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002672 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002673 return;
2674 }
2675 glActiveTexture(GL_TEXTURE0);
2676 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2677 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
2678 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2679 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2680 EXPECT_GL_NO_ERROR();
2681
2682 drawQuad(mProgram, "position", 0.5f);
2683
2684 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2685}
2686
2687// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2688// ES 3.0.4 table 3.24
2689TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
2690{
2691 glActiveTexture(GL_TEXTURE0);
2692 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2693 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
2694 EXPECT_GL_NO_ERROR();
2695
2696 drawQuad(mProgram, "position", 0.5f);
2697
2698 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2699}
2700
2701// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2702// ES 3.0.4 table 3.24
2703TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
2704{
2705 glActiveTexture(GL_TEXTURE0);
2706 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2707 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
2708 nullptr);
2709 EXPECT_GL_NO_ERROR();
2710
2711 drawQuad(mProgram, "position", 0.5f);
2712
2713 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2714}
2715
2716// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2717// ES 3.0.4 table 3.24
2718TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
2719{
2720 glActiveTexture(GL_TEXTURE0);
2721 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2722 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
2723 EXPECT_GL_NO_ERROR();
2724
2725 drawQuad(mProgram, "position", 0.5f);
2726
2727 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2728}
2729
2730// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2731// ES 3.0.4 table 3.24
2732TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
2733{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002734 if (IsIntel() && IsLinux())
2735 {
2736 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2737 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2738 return;
2739 }
2740
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002741 glActiveTexture(GL_TEXTURE0);
2742 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2743 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2744 EXPECT_GL_NO_ERROR();
2745
2746 drawQuad(mProgram, "position", 0.5f);
2747
2748 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2749}
2750
Olli Etuaho96963162016-03-21 11:54:33 +02002751// Use a sampler in a uniform struct.
2752TEST_P(SamplerInStructTest, SamplerInStruct)
2753{
2754 runSamplerInStructTest();
2755}
2756
2757// Use a sampler in a uniform struct that's passed as a function parameter.
2758TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2759{
Yuly Novikovad6c0452016-06-24 22:24:37 -04002760 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
2761 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2762 {
2763 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2764 return;
2765 }
Olli Etuaho96963162016-03-21 11:54:33 +02002766 runSamplerInStructTest();
2767}
2768
2769// Use a sampler in a uniform struct array with a struct from the array passed as a function
2770// parameter.
2771TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2772{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002773 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2774 {
2775 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2776 return;
2777 }
Yuly Novikovad6c0452016-06-24 22:24:37 -04002778 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
2779 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2780 {
2781 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2782 return;
2783 }
Olli Etuaho96963162016-03-21 11:54:33 +02002784 runSamplerInStructTest();
2785}
2786
2787// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2788// parameter.
2789TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2790{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002791 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2792 {
2793 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2794 return;
2795 }
Yuly Novikovad6c0452016-06-24 22:24:37 -04002796 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
2797 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2798 {
2799 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2800 return;
2801 }
Olli Etuaho96963162016-03-21 11:54:33 +02002802 runSamplerInStructTest();
2803}
2804
2805// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2806// similarly named uniform.
2807TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2808{
2809 runSamplerInStructTest();
2810}
2811
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002812class TextureLimitsTest : public ANGLETest
2813{
2814 protected:
2815 struct RGBA8
2816 {
2817 uint8_t R, G, B, A;
2818 };
2819
2820 TextureLimitsTest()
2821 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2822 {
2823 setWindowWidth(128);
2824 setWindowHeight(128);
2825 setConfigRedBits(8);
2826 setConfigGreenBits(8);
2827 setConfigBlueBits(8);
2828 setConfigAlphaBits(8);
2829 }
2830
2831 ~TextureLimitsTest()
2832 {
2833 if (mProgram != 0)
2834 {
2835 glDeleteProgram(mProgram);
2836 mProgram = 0;
2837
2838 if (!mTextures.empty())
2839 {
2840 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2841 }
2842 }
2843 }
2844
2845 void SetUp() override
2846 {
2847 ANGLETest::SetUp();
2848
2849 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2850 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2851 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2852
2853 ASSERT_GL_NO_ERROR();
2854 }
2855
2856 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2857 GLint vertexTextureCount,
2858 GLint vertexActiveTextureCount,
2859 const std::string &fragPrefix,
2860 GLint fragmentTextureCount,
2861 GLint fragmentActiveTextureCount)
2862 {
2863 std::stringstream vertexShaderStr;
2864 vertexShaderStr << "attribute vec2 position;\n"
2865 << "varying vec4 color;\n"
2866 << "varying vec2 texCoord;\n";
2867
2868 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2869 {
2870 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2871 }
2872
2873 vertexShaderStr << "void main() {\n"
2874 << " gl_Position = vec4(position, 0, 1);\n"
2875 << " texCoord = (position * 0.5) + 0.5;\n"
2876 << " color = vec4(0);\n";
2877
2878 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2879 {
2880 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2881 << ", texCoord);\n";
2882 }
2883
2884 vertexShaderStr << "}";
2885
2886 std::stringstream fragmentShaderStr;
2887 fragmentShaderStr << "varying mediump vec4 color;\n"
2888 << "varying mediump vec2 texCoord;\n";
2889
2890 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2891 {
2892 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2893 }
2894
2895 fragmentShaderStr << "void main() {\n"
2896 << " gl_FragColor = color;\n";
2897
2898 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2899 {
2900 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2901 << ", texCoord);\n";
2902 }
2903
2904 fragmentShaderStr << "}";
2905
2906 const std::string &vertexShaderSource = vertexShaderStr.str();
2907 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2908
2909 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2910 }
2911
2912 RGBA8 getPixel(GLint texIndex)
2913 {
2914 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2915 0, 255u};
2916 return pixel;
2917 }
2918
2919 void initTextures(GLint tex2DCount, GLint texCubeCount)
2920 {
2921 GLint totalCount = tex2DCount + texCubeCount;
2922 mTextures.assign(totalCount, 0);
2923 glGenTextures(totalCount, &mTextures[0]);
2924 ASSERT_GL_NO_ERROR();
2925
2926 std::vector<RGBA8> texData(16 * 16);
2927
2928 GLint texIndex = 0;
2929 for (; texIndex < tex2DCount; ++texIndex)
2930 {
2931 texData.assign(texData.size(), getPixel(texIndex));
2932 glActiveTexture(GL_TEXTURE0 + texIndex);
2933 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2934 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2935 &texData[0]);
2936 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2937 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2938 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2939 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2940 }
2941
2942 ASSERT_GL_NO_ERROR();
2943
2944 for (; texIndex < texCubeCount; ++texIndex)
2945 {
2946 texData.assign(texData.size(), getPixel(texIndex));
2947 glActiveTexture(GL_TEXTURE0 + texIndex);
2948 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2949 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2950 GL_UNSIGNED_BYTE, &texData[0]);
2951 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2952 GL_UNSIGNED_BYTE, &texData[0]);
2953 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2954 GL_UNSIGNED_BYTE, &texData[0]);
2955 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2956 GL_UNSIGNED_BYTE, &texData[0]);
2957 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2958 GL_UNSIGNED_BYTE, &texData[0]);
2959 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2960 GL_UNSIGNED_BYTE, &texData[0]);
2961 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2962 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2963 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2964 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2965 }
2966
2967 ASSERT_GL_NO_ERROR();
2968 }
2969
2970 void testWithTextures(GLint vertexTextureCount,
2971 const std::string &vertexTexturePrefix,
2972 GLint fragmentTextureCount,
2973 const std::string &fragmentTexturePrefix)
2974 {
2975 // Generate textures
2976 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2977
2978 glUseProgram(mProgram);
2979 RGBA8 expectedSum = {0};
2980 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2981 {
2982 std::stringstream uniformNameStr;
2983 uniformNameStr << vertexTexturePrefix << texIndex;
2984 const std::string &uniformName = uniformNameStr.str();
2985 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2986 ASSERT_NE(-1, location);
2987
2988 glUniform1i(location, texIndex);
2989 RGBA8 contribution = getPixel(texIndex);
2990 expectedSum.R += contribution.R;
2991 expectedSum.G += contribution.G;
2992 }
2993
2994 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2995 {
2996 std::stringstream uniformNameStr;
2997 uniformNameStr << fragmentTexturePrefix << texIndex;
2998 const std::string &uniformName = uniformNameStr.str();
2999 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
3000 ASSERT_NE(-1, location);
3001
3002 glUniform1i(location, texIndex + vertexTextureCount);
3003 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
3004 expectedSum.R += contribution.R;
3005 expectedSum.G += contribution.G;
3006 }
3007
3008 ASSERT_GE(256u, expectedSum.G);
3009
3010 drawQuad(mProgram, "position", 0.5f);
3011 ASSERT_GL_NO_ERROR();
3012 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
3013 }
3014
3015 GLuint mProgram;
3016 std::vector<GLuint> mTextures;
3017 GLint mMaxVertexTextures;
3018 GLint mMaxFragmentTextures;
3019 GLint mMaxCombinedTextures;
3020};
3021
3022// Test rendering with the maximum vertex texture units.
3023TEST_P(TextureLimitsTest, MaxVertexTextures)
3024{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003025 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003026 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003027 {
3028 std::cout << "Test skipped on Intel." << std::endl;
3029 return;
3030 }
3031
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003032 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
3033 ASSERT_NE(0u, mProgram);
3034 ASSERT_GL_NO_ERROR();
3035
3036 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3037}
3038
3039// Test rendering with the maximum fragment texture units.
3040TEST_P(TextureLimitsTest, MaxFragmentTextures)
3041{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003042 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003043 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003044 {
3045 std::cout << "Test skipped on Intel." << std::endl;
3046 return;
3047 }
3048
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003049 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
3050 ASSERT_NE(0u, mProgram);
3051 ASSERT_GL_NO_ERROR();
3052
3053 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
3054}
3055
3056// Test rendering with maximum combined texture units.
3057TEST_P(TextureLimitsTest, MaxCombinedTextures)
3058{
Jamie Madill412f17d2015-09-25 08:43:54 -04003059 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003060 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04003061 {
3062 std::cout << "Test skipped on Intel." << std::endl;
3063 return;
3064 }
3065
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003066 GLint vertexTextures = mMaxVertexTextures;
3067
3068 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
3069 {
3070 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
3071 }
3072
3073 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
3074 mMaxFragmentTextures, mMaxFragmentTextures);
3075 ASSERT_NE(0u, mProgram);
3076 ASSERT_GL_NO_ERROR();
3077
3078 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
3079}
3080
3081// Negative test for exceeding the number of vertex textures
3082TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
3083{
3084 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
3085 0);
3086 ASSERT_EQ(0u, mProgram);
3087}
3088
3089// Negative test for exceeding the number of fragment textures
3090TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
3091{
3092 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
3093 mMaxFragmentTextures + 1);
3094 ASSERT_EQ(0u, mProgram);
3095}
3096
3097// Test active vertex textures under the limit, but excessive textures specified.
3098TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
3099{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003100 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003101 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003102 {
3103 std::cout << "Test skipped on Intel." << std::endl;
3104 return;
3105 }
3106
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003107 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
3108 ASSERT_NE(0u, mProgram);
3109 ASSERT_GL_NO_ERROR();
3110
3111 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3112}
3113
3114// Test active fragment textures under the limit, but excessive textures specified.
3115TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
3116{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003117 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003118 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003119 {
3120 std::cout << "Test skipped on Intel." << std::endl;
3121 return;
3122 }
3123
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003124 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
3125 mMaxFragmentTextures);
3126 ASSERT_NE(0u, mProgram);
3127 ASSERT_GL_NO_ERROR();
3128
3129 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
3130}
3131
3132// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003133// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003134TEST_P(TextureLimitsTest, TextureTypeConflict)
3135{
3136 const std::string &vertexShader =
3137 "attribute vec2 position;\n"
3138 "varying float color;\n"
3139 "uniform sampler2D tex2D;\n"
3140 "uniform samplerCube texCube;\n"
3141 "void main() {\n"
3142 " gl_Position = vec4(position, 0, 1);\n"
3143 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3144 " color = texture2D(tex2D, texCoord).x;\n"
3145 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
3146 "}";
3147 const std::string &fragmentShader =
3148 "varying mediump float color;\n"
3149 "void main() {\n"
3150 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3151 "}";
3152
3153 mProgram = CompileProgram(vertexShader, fragmentShader);
3154 ASSERT_NE(0u, mProgram);
3155
3156 initTextures(1, 0);
3157
3158 glUseProgram(mProgram);
3159 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3160 ASSERT_NE(-1, tex2DLocation);
3161 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
3162 ASSERT_NE(-1, texCubeLocation);
3163
3164 glUniform1i(tex2DLocation, 0);
3165 glUniform1i(texCubeLocation, 0);
3166 ASSERT_GL_NO_ERROR();
3167
3168 drawQuad(mProgram, "position", 0.5f);
3169 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3170}
3171
3172// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003173// TODO(jmadill): Possibly adjust the test according to the spec:
3174// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
3175// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003176TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
3177{
3178 const std::string &vertexShader =
3179 "attribute vec2 position;\n"
3180 "varying float color;\n"
3181 "uniform sampler2D tex2D;\n"
3182 "void main() {\n"
3183 " gl_Position = vec4(position, 0, 1);\n"
3184 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3185 " color = texture2D(tex2D, texCoord).x;\n"
3186 "}";
3187 const std::string &fragmentShader =
3188 "varying mediump float color;\n"
3189 "void main() {\n"
3190 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3191 "}";
3192
3193 mProgram = CompileProgram(vertexShader, fragmentShader);
3194 ASSERT_NE(0u, mProgram);
3195
3196 glUseProgram(mProgram);
3197 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3198 ASSERT_NE(-1, tex2DLocation);
3199
3200 glUniform1i(tex2DLocation, mMaxCombinedTextures);
3201 ASSERT_GL_NO_ERROR();
3202
3203 drawQuad(mProgram, "position", 0.5f);
3204 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3205}
3206
Vincent Lang25ab4512016-05-13 18:13:59 +02003207class Texture2DNorm16TestES3 : public Texture2DTestES3
3208{
3209 protected:
3210 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
3211
3212 void SetUp() override
3213 {
3214 Texture2DTestES3::SetUp();
3215
3216 glActiveTexture(GL_TEXTURE0);
3217 glGenTextures(3, mTextures);
3218 glGenFramebuffers(1, &mFBO);
3219 glGenRenderbuffers(1, &mRenderbuffer);
3220
3221 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
3222 {
3223 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
3224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3226 }
3227
3228 glBindTexture(GL_TEXTURE_2D, 0);
3229
3230 ASSERT_GL_NO_ERROR();
3231 }
3232
3233 void TearDown() override
3234 {
3235 glDeleteTextures(3, mTextures);
3236 glDeleteFramebuffers(1, &mFBO);
3237 glDeleteRenderbuffers(1, &mRenderbuffer);
3238
3239 Texture2DTestES3::TearDown();
3240 }
3241
3242 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
3243 {
3244 GLushort pixelValue = type == GL_SHORT ? 0x7FFF : 0x6A35;
3245 GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
3246
3247 setUpProgram();
3248
3249 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
3250 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
3251 0);
3252
3253 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
3254 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
3255
3256 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
3257 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
3258
3259 EXPECT_GL_NO_ERROR();
3260
3261 drawQuad(mProgram, "position", 0.5f);
3262
3263 GLColor16 expectedValue = imageData;
3264 if (type == GL_SHORT)
3265 {
3266 // sampled as signed value; then stored as unsigned value
3267 expectedValue = GLColor16::white;
3268 }
3269
3270 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
3271
3272 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3273
3274 ASSERT_GL_NO_ERROR();
3275 }
3276
3277 void testNorm16Render(GLint internalformat, GLenum format, GLenum type)
3278 {
3279 GLushort pixelValue = 0x6A35;
3280 GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
3281
3282 setUpProgram();
3283
3284 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
3285 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, nullptr);
3286
3287 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
3288 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
3289 0);
3290
3291 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
3292 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
3293
3294 EXPECT_GL_NO_ERROR();
3295
3296 drawQuad(mProgram, "position", 0.5f);
3297
3298 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, imageData));
3299
3300 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
3301 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
3302 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3303 mRenderbuffer);
3304 glBindRenderbuffer(GL_RENDERBUFFER, 0);
3305 EXPECT_GL_NO_ERROR();
3306
3307 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
3308 glClear(GL_COLOR_BUFFER_BIT);
3309
3310 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
3311
3312 GLColor16 expectedValue = GLColor16::white;
3313 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
3314
3315 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3316
3317 ASSERT_GL_NO_ERROR();
3318 }
3319
3320 GLuint mTextures[3];
3321 GLuint mFBO;
3322 GLuint mRenderbuffer;
3323};
3324
3325// Test texture formats enabled by the GL_EXT_texture_norm16 extension.
3326TEST_P(Texture2DNorm16TestES3, TextureNorm16Test)
3327{
3328 if (!extensionEnabled("GL_EXT_texture_norm16"))
3329 {
3330 std::cout << "Test skipped due to missing GL_EXT_texture_norm16." << std::endl;
3331 return;
3332 }
3333
3334 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
3335 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
3336 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
3337 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
3338 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
3339 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
3340 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
3341 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
3342
3343 testNorm16Render(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
3344 testNorm16Render(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
3345 testNorm16Render(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
3346}
3347
Olli Etuaho95faa232016-06-07 14:01:53 -07003348// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
3349// GLES 3.0.4 section 3.8.3.
3350TEST_P(Texture2DTestES3, UnpackSkipImages2D)
3351{
Corentin Wallezc7f59d02016-06-20 10:12:08 -04003352 if (IsIntel() && IsDesktopOpenGL())
Olli Etuaho95faa232016-06-07 14:01:53 -07003353 {
3354 std::cout << "Test skipped on Intel OpenGL." << std::endl;
3355 return;
3356 }
Yuly Novikov3c754192016-06-27 19:36:41 -04003357 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1429 is fixed
3358 if (IsAndroid() && IsAdreno() && IsOpenGLES())
3359 {
3360 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
3361 return;
3362 }
Olli Etuaho95faa232016-06-07 14:01:53 -07003363
3364 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3367 ASSERT_GL_NO_ERROR();
3368
3369 // SKIP_IMAGES should not have an effect on uploading 2D textures
3370 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
3371 ASSERT_GL_NO_ERROR();
3372
3373 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
3374
3375 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3376 pixelsGreen.data());
3377 ASSERT_GL_NO_ERROR();
3378
3379 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
3380 pixelsGreen.data());
3381 ASSERT_GL_NO_ERROR();
3382
3383 glUseProgram(mProgram);
3384 drawQuad(mProgram, "position", 0.5f);
3385 ASSERT_GL_NO_ERROR();
3386
3387 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3388}
3389
Olli Etuaho989cac32016-06-08 16:18:49 -07003390// Test that skip defined in unpack parameters is taken into account when determining whether
3391// unpacking source extends outside unpack buffer bounds.
3392TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
3393{
3394 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3395 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3396 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3397 ASSERT_GL_NO_ERROR();
3398
3399 GLBuffer buf;
3400 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
3401 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
3402 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
3403 GL_DYNAMIC_COPY);
3404 ASSERT_GL_NO_ERROR();
3405
3406 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3407 ASSERT_GL_NO_ERROR();
3408
3409 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
3410 ASSERT_GL_NO_ERROR();
3411
3412 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3413 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3414
3415 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3416 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
3417 ASSERT_GL_NO_ERROR();
3418
3419 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3420 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3421}
3422
Olli Etuaho218cf9e2016-05-20 13:55:24 +03003423// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
3424TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
3425{
3426 if (IsD3D11())
3427 {
3428 std::cout << "Test skipped on D3D." << std::endl;
3429 return;
3430 }
3431 if (IsOSX() && IsAMD())
3432 {
3433 // Incorrect rendering results seen on OSX AMD.
3434 std::cout << "Test skipped on OSX AMD." << std::endl;
3435 return;
3436 }
3437
3438 const GLuint width = 8u;
3439 const GLuint height = 8u;
3440 const GLuint unpackRowLength = 5u;
3441 const GLuint unpackSkipPixels = 1u;
3442
3443 setWindowWidth(width);
3444 setWindowHeight(height);
3445
3446 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3447 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3448 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3449 ASSERT_GL_NO_ERROR();
3450
3451 GLBuffer buf;
3452 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
3453 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
3454 GLColor::green);
3455
3456 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
3457 {
3458 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
3459 }
3460
3461 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
3462 GL_DYNAMIC_COPY);
3463 ASSERT_GL_NO_ERROR();
3464
3465 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
3466 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
3467 ASSERT_GL_NO_ERROR();
3468
3469 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3470 ASSERT_GL_NO_ERROR();
3471
3472 glUseProgram(mProgram);
3473 drawQuad(mProgram, "position", 0.5f);
3474 ASSERT_GL_NO_ERROR();
3475
3476 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
3477 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
3478 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
3479 actual.data());
3480 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
3481 EXPECT_EQ(expected, actual);
3482}
3483
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04003484template <typename T>
3485T UNorm(double value)
3486{
3487 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
3488}
3489
3490// Test rendering a depth texture with mipmaps.
3491TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
3492{
Corentin Walleze731d8a2016-09-07 10:56:25 -04003493 //TODO(cwallez) this is failing on Intel Win7 OpenGL
3494 if (IsIntel() && IsWindows() && IsOpenGL())
3495 {
3496 std::cout << "Test skipped on Intel OpenGL." << std::endl;
3497 return;
3498 }
3499
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04003500 const int size = getWindowWidth();
3501
3502 auto dim = [size](int level) { return size >> level; };
Jamie Madill14718762016-09-06 15:56:54 -04003503 int levels = gl::log2(size);
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04003504
3505 glActiveTexture(GL_TEXTURE0);
3506 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3507 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
3508 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3509 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3510 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3511 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3512 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3513 ASSERT_GL_NO_ERROR();
3514
3515 glUseProgram(mProgram);
3516 glUniform1i(mTexture2DUniformLocation, 0);
3517
3518 std::vector<unsigned char> expected;
3519
3520 for (int level = 0; level < levels; ++level)
3521 {
3522 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
3523 expected.push_back(UNorm<unsigned char>(value));
3524
3525 int levelDim = dim(level);
3526
3527 ASSERT_GT(levelDim, 0);
3528
3529 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
3530 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
3531 GL_UNSIGNED_INT, initData.data());
3532 }
3533 ASSERT_GL_NO_ERROR();
3534
3535 for (int level = 0; level < levels; ++level)
3536 {
3537 glViewport(0, 0, dim(level), dim(level));
3538 drawQuad(mProgram, "position", 0.5f);
3539 GLColor actual = ReadColor(0, 0);
3540 EXPECT_NEAR(expected[level], actual.R, 10u);
3541 }
3542
3543 ASSERT_GL_NO_ERROR();
3544}
3545
Jamie Madillfa05f602015-05-07 13:47:11 -04003546// 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 +02003547// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05003548ANGLE_INSTANTIATE_TEST(Texture2DTest,
3549 ES2_D3D9(),
3550 ES2_D3D11(),
3551 ES2_D3D11_FL9_3(),
3552 ES2_OPENGL(),
3553 ES2_OPENGLES());
3554ANGLE_INSTANTIATE_TEST(TextureCubeTest,
3555 ES2_D3D9(),
3556 ES2_D3D11(),
3557 ES2_D3D11_FL9_3(),
3558 ES2_OPENGL(),
3559 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003560ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
3561 ES2_D3D9(),
3562 ES2_D3D11(),
3563 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003564 ES2_OPENGL(),
3565 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003566ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
3567 ES2_D3D9(),
3568 ES2_D3D11(),
3569 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003570 ES2_OPENGL(),
3571 ES2_OPENGLES());
3572ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
3573 ES2_D3D9(),
3574 ES2_D3D11(),
3575 ES2_D3D11_FL9_3(),
3576 ES2_OPENGL(),
3577 ES2_OPENGLES());
3578ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
3579 ES2_D3D9(),
3580 ES2_D3D11(),
3581 ES2_D3D11_FL9_3(),
3582 ES2_OPENGL(),
3583 ES2_OPENGLES());
3584ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahoa314b612016-03-10 16:43:00 +02003585ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003586ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3587ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
3588 ES3_D3D11(),
3589 ES3_OPENGL(),
3590 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003591ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
3592 ES3_D3D11(),
3593 ES3_OPENGL(),
3594 ES3_OPENGLES());
3595ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3596ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02003597ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02003598ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
3599 ES2_D3D11(),
3600 ES2_D3D11_FL9_3(),
3601 ES2_D3D9(),
3602 ES2_OPENGL(),
3603 ES2_OPENGLES());
3604ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
3605 ES2_D3D11(),
3606 ES2_D3D11_FL9_3(),
3607 ES2_D3D9(),
3608 ES2_OPENGL(),
3609 ES2_OPENGLES());
3610ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
3611 ES2_D3D11(),
3612 ES2_D3D11_FL9_3(),
3613 ES2_D3D9(),
3614 ES2_OPENGL(),
3615 ES2_OPENGLES());
3616ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
3617 ES2_D3D11(),
3618 ES2_D3D11_FL9_3(),
3619 ES2_D3D9(),
3620 ES2_OPENGL(),
3621 ES2_OPENGLES());
3622ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
3623 ES2_D3D11(),
3624 ES2_D3D11_FL9_3(),
3625 ES2_D3D9(),
3626 ES2_OPENGL(),
3627 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003628ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Vincent Lang25ab4512016-05-13 18:13:59 +02003629ANGLE_INSTANTIATE_TEST(Texture2DNorm16TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04003630
3631} // namespace