blob: c86bdfb058ce61f3f430ecdacbefd75bfbf8a665 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Olli Etuaho989cac32016-06-08 16:18:49 -07008#include "test_utils/gl_raii.h"
Jamie Madillf67115c2014-04-22 13:14:05 -04009
Jamie Madillfa05f602015-05-07 13:47:11 -040010using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070011
Jamie Madillfa05f602015-05-07 13:47:11 -040012namespace
13{
14
Vincent Lang25ab4512016-05-13 18:13:59 +020015// Take a pixel, and reset the components not covered by the format to default
16// values. In particular, the default value for the alpha component is 65535
17// (1.0 as unsigned normalized fixed point value).
18GLColor16 SliceFormatColor16(GLenum format, GLColor16 full)
19{
20 switch (format)
21 {
22 case GL_RED:
23 return GLColor16(full.R, 0, 0, 65535u);
24 case GL_RG:
25 return GLColor16(full.R, full.G, 0, 65535u);
26 case GL_RGB:
27 return GLColor16(full.R, full.G, full.B, 65535u);
28 case GL_RGBA:
29 return full;
30 default:
31 UNREACHABLE();
32 }
33 return GLColor16::white;
34}
35
Olli Etuaho4a8329f2016-01-11 17:12:57 +020036class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -040037{
Jamie Madillbc393df2015-01-29 13:46:07 -050038 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020039 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -040040 {
41 setWindowWidth(128);
42 setWindowHeight(128);
43 setConfigRedBits(8);
44 setConfigGreenBits(8);
45 setConfigBlueBits(8);
46 setConfigAlphaBits(8);
47 }
48
Olli Etuaho4a8329f2016-01-11 17:12:57 +020049 virtual std::string getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -040050 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020051 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040052 (
53 precision highp float;
54 attribute vec4 position;
55 varying vec2 texcoord;
56
57 void main()
58 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020059 gl_Position = vec4(position.xy, 0.0, 1.0);
Geoff Langc41e42d2014-04-28 10:58:16 -040060 texcoord = (position.xy * 0.5) + 0.5;
61 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +020062 )
Geoff Langc41e42d2014-04-28 10:58:16 -040063 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +020064 }
Geoff Langc41e42d2014-04-28 10:58:16 -040065
Olli Etuaho4a8329f2016-01-11 17:12:57 +020066 virtual std::string getFragmentShaderSource() = 0;
67
Olli Etuahoa1c917f2016-04-06 13:50:03 +030068 virtual void setUpProgram()
Olli Etuaho4a8329f2016-01-11 17:12:57 +020069 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020070 const std::string vertexShaderSource = getVertexShaderSource();
71 const std::string fragmentShaderSource = getFragmentShaderSource();
72
73 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
74 ASSERT_NE(0u, mProgram);
75 ASSERT_GL_NO_ERROR();
Olli Etuahoa1c917f2016-04-06 13:50:03 +030076 }
77
78 void SetUp() override
79 {
80 ANGLETest::SetUp();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020081
82 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020083 }
84
85 void TearDown() override
86 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020087 glBindFramebuffer(GL_FRAMEBUFFER, 0);
88 glDeleteFramebuffers(1, &mFramebuffer);
89 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020090 glDeleteProgram(mProgram);
91 ANGLETest::TearDown();
92 }
93
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020094 void setUpFramebuffer()
95 {
96 // We use an FBO to work around an issue where the default framebuffer applies SRGB
97 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
98 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
99 // section 4.4 says that the format of the default framebuffer is entirely up to the window
100 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
101 // SRGB conversion like desktop GL does.
102 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
103 glGenFramebuffers(1, &mFramebuffer);
104 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
105
106 glGenTextures(1, &mFramebufferColorTexture);
107 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
108 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
109 GL_UNSIGNED_BYTE, nullptr);
110 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
111 mFramebufferColorTexture, 0);
112 ASSERT_GL_NO_ERROR();
113 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
114 glBindTexture(GL_TEXTURE_2D, 0);
115 }
116
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200117 // Returns the created texture ID.
118 GLuint create2DTexture()
119 {
120 GLuint texture2D;
121 glGenTextures(1, &texture2D);
122 glBindTexture(GL_TEXTURE_2D, texture2D);
123 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
124 EXPECT_GL_NO_ERROR();
125 return texture2D;
126 }
127
128 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200129 GLuint mFramebuffer;
130
131 private:
132 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200133};
134
135class Texture2DTest : public TexCoordDrawTest
136{
137 protected:
138 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
139
140 std::string getFragmentShaderSource() override
141 {
142 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400143 (
144 precision highp float;
145 uniform sampler2D tex;
146 varying vec2 texcoord;
147
148 void main()
149 {
150 gl_FragColor = texture2D(tex, texcoord);
151 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200152 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400153 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200154 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400155
Olli Etuaho96963162016-03-21 11:54:33 +0200156 virtual const char *getTextureUniformName() { return "tex"; }
157
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300158 void setUpProgram() override
159 {
160 TexCoordDrawTest::setUpProgram();
161 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
162 ASSERT_NE(-1, mTexture2DUniformLocation);
163 }
164
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200165 void SetUp() override
166 {
167 TexCoordDrawTest::SetUp();
168 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400169
Jamie Madill9aca0592014-10-06 16:26:59 -0400170 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -0400171 }
172
Jamie Madillfa05f602015-05-07 13:47:11 -0400173 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400174 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400175 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200176 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400177 }
178
Jamie Madillbc393df2015-01-29 13:46:07 -0500179 // Tests CopyTexSubImage with floating point textures of various formats.
180 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
181 {
Geoff Langbde666a2015-04-07 17:17:08 -0400182 // TODO(jmadill): Figure out why this is broken on Intel D3D11
Jamie Madill518b9fa2016-03-02 11:26:02 -0500183 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Geoff Langbde666a2015-04-07 17:17:08 -0400184 {
185 std::cout << "Test skipped on Intel D3D11." << std::endl;
186 return;
187 }
188
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300189 setUpProgram();
190
Geoff Langfbfa47c2015-03-31 11:26:00 -0400191 if (getClientVersion() < 3)
192 {
193 if (!extensionEnabled("GL_OES_texture_float"))
194 {
195 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
196 return;
197 }
198
199 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
200 {
201 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
202 return;
203 }
204 }
205
Jamie Madillbc393df2015-01-29 13:46:07 -0500206 GLfloat sourceImageData[4][16] =
207 {
208 { // R
209 1.0f,
210 0.0f,
211 0.0f,
212 1.0f
213 },
214 { // RG
215 1.0f, 0.0f,
216 0.0f, 1.0f,
217 0.0f, 0.0f,
218 1.0f, 1.0f
219 },
220 { // RGB
221 1.0f, 0.0f, 0.0f,
222 0.0f, 1.0f, 0.0f,
223 0.0f, 0.0f, 1.0f,
224 1.0f, 1.0f, 0.0f
225 },
226 { // RGBA
227 1.0f, 0.0f, 0.0f, 1.0f,
228 0.0f, 1.0f, 0.0f, 1.0f,
229 0.0f, 0.0f, 1.0f, 1.0f,
230 1.0f, 1.0f, 0.0f, 1.0f
231 },
232 };
233
234 GLenum imageFormats[] =
235 {
236 GL_R32F,
237 GL_RG32F,
238 GL_RGB32F,
239 GL_RGBA32F,
240 };
241
242 GLenum sourceUnsizedFormats[] =
243 {
244 GL_RED,
245 GL_RG,
246 GL_RGB,
247 GL_RGBA,
248 };
249
250 GLuint textures[2];
251
252 glGenTextures(2, textures);
253
254 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
255 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
256 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
257 GLenum destImageFormat = imageFormats[destImageChannels - 1];
258
259 glBindTexture(GL_TEXTURE_2D, textures[0]);
260 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
263 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
264
hendrikwb27f79a2015-03-04 11:26:46 -0800265 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500266 {
267 // This is not supported
268 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
269 }
270 else
271 {
272 ASSERT_GL_NO_ERROR();
273 }
274
275 GLuint fbo;
276 glGenFramebuffers(1, &fbo);
277 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
278 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
279
280 glBindTexture(GL_TEXTURE_2D, textures[1]);
281 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
282 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
283 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
284
285 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
286 ASSERT_GL_NO_ERROR();
287
288 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200289 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500290
291 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
292
Olli Etuahoa314b612016-03-10 16:43:00 +0200293 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Jamie Madillbc393df2015-01-29 13:46:07 -0500294 if (testImageChannels > 1)
295 {
296 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
297 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
298 if (testImageChannels > 2)
299 {
300 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
301 }
302 }
303
304 glDeleteFramebuffers(1, &fbo);
305 glDeleteTextures(2, textures);
306
307 ASSERT_GL_NO_ERROR();
308 }
309
Jamie Madilld4cfa572014-07-08 10:00:32 -0400310 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400311 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400312};
313
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200314class Texture2DTestES3 : public Texture2DTest
315{
316 protected:
317 Texture2DTestES3() : Texture2DTest() {}
318
319 std::string getVertexShaderSource() override
320 {
321 return std::string(
322 "#version 300 es\n"
323 "out vec2 texcoord;\n"
324 "in vec4 position;\n"
325 "void main()\n"
326 "{\n"
327 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
328 " texcoord = (position.xy * 0.5) + 0.5;\n"
329 "}\n");
330 }
331
332 std::string getFragmentShaderSource() override
333 {
334 return std::string(
335 "#version 300 es\n"
336 "precision highp float;\n"
337 "uniform highp sampler2D tex;\n"
338 "in vec2 texcoord;\n"
339 "out vec4 fragColor;\n"
340 "void main()\n"
341 "{\n"
342 " fragColor = texture(tex, texcoord);\n"
343 "}\n");
344 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300345
346 void SetUp() override
347 {
348 Texture2DTest::SetUp();
349 setUpProgram();
350 }
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200351};
352
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200353class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
354{
355 protected:
356 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
357
358 std::string getVertexShaderSource() override
359 {
360 return std::string(
361 "#version 300 es\n"
362 "out vec2 texcoord;\n"
363 "in vec4 position;\n"
364 "void main()\n"
365 "{\n"
366 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
367 " texcoord = (position.xy * 0.5) + 0.5;\n"
368 "}\n");
369 }
370
371 std::string getFragmentShaderSource() override
372 {
373 return std::string(
374 "#version 300 es\n"
375 "precision highp float;\n"
376 "uniform highp isampler2D tex;\n"
377 "in vec2 texcoord;\n"
378 "out vec4 fragColor;\n"
379 "void main()\n"
380 "{\n"
381 " vec4 green = vec4(0, 1, 0, 1);\n"
382 " vec4 black = vec4(0, 0, 0, 0);\n"
383 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
384 "}\n");
385 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300386
387 void SetUp() override
388 {
389 Texture2DTest::SetUp();
390 setUpProgram();
391 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200392};
393
394class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
395{
396 protected:
397 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
398
399 std::string getVertexShaderSource() override
400 {
401 return std::string(
402 "#version 300 es\n"
403 "out vec2 texcoord;\n"
404 "in vec4 position;\n"
405 "void main()\n"
406 "{\n"
407 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
408 " texcoord = (position.xy * 0.5) + 0.5;\n"
409 "}\n");
410 }
411
412 std::string getFragmentShaderSource() override
413 {
414 return std::string(
415 "#version 300 es\n"
416 "precision highp float;\n"
417 "uniform highp usampler2D tex;\n"
418 "in vec2 texcoord;\n"
419 "out vec4 fragColor;\n"
420 "void main()\n"
421 "{\n"
422 " vec4 green = vec4(0, 1, 0, 1);\n"
423 " vec4 black = vec4(0, 0, 0, 0);\n"
424 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
425 "}\n");
426 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300427
428 void SetUp() override
429 {
430 Texture2DTest::SetUp();
431 setUpProgram();
432 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200433};
434
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200435class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400436{
437 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200438 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
439
440 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400441 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200442 return std::string(SHADER_SOURCE
443 (
444 precision highp float;
445 attribute vec4 position;
446 varying vec2 texcoord;
447
448 uniform vec2 drawScale;
449
450 void main()
451 {
452 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
453 texcoord = (position.xy * 0.5) + 0.5;
454 }
455 )
456 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400457 }
458
459 void SetUp() override
460 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200461 Texture2DTest::SetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300462
463 setUpProgram();
464
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200465 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
466 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400467
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200468 glUseProgram(mProgram);
469 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
470 glUseProgram(0);
471 ASSERT_GL_NO_ERROR();
472 }
473
474 GLint mDrawScaleUniformLocation;
475};
476
Olli Etuaho4644a202016-01-12 15:12:53 +0200477class Sampler2DAsFunctionParameterTest : public Texture2DTest
478{
479 protected:
480 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
481
482 std::string getFragmentShaderSource() override
483 {
484 return std::string(SHADER_SOURCE
485 (
486 precision highp float;
487 uniform sampler2D tex;
488 varying vec2 texcoord;
489
490 vec4 computeFragColor(sampler2D aTex)
491 {
492 return texture2D(aTex, texcoord);
493 }
494
495 void main()
496 {
497 gl_FragColor = computeFragColor(tex);
498 }
499 )
500 );
501 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300502
503 void SetUp() override
504 {
505 Texture2DTest::SetUp();
506 setUpProgram();
507 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200508};
509
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200510class TextureCubeTest : public TexCoordDrawTest
511{
512 protected:
513 TextureCubeTest()
514 : TexCoordDrawTest(),
515 mTexture2D(0),
516 mTextureCube(0),
517 mTexture2DUniformLocation(-1),
518 mTextureCubeUniformLocation(-1)
519 {
520 }
521
522 std::string getFragmentShaderSource() override
523 {
524 return std::string(SHADER_SOURCE
525 (
526 precision highp float;
527 uniform sampler2D tex2D;
528 uniform samplerCube texCube;
529 varying vec2 texcoord;
530
531 void main()
532 {
533 gl_FragColor = texture2D(tex2D, texcoord);
534 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
535 }
536 )
537 );
538 }
539
540 void SetUp() override
541 {
542 TexCoordDrawTest::SetUp();
543
544 glGenTextures(1, &mTextureCube);
545 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
546 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
547 EXPECT_GL_NO_ERROR();
548
549 mTexture2D = create2DTexture();
550
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300551 setUpProgram();
552
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200553 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
554 ASSERT_NE(-1, mTexture2DUniformLocation);
555 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
556 ASSERT_NE(-1, mTextureCubeUniformLocation);
557 }
558
559 void TearDown() override
560 {
561 glDeleteTextures(1, &mTextureCube);
562 TexCoordDrawTest::TearDown();
563 }
564
565 GLuint mTexture2D;
566 GLuint mTextureCube;
567 GLint mTexture2DUniformLocation;
568 GLint mTextureCubeUniformLocation;
569};
570
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200571class SamplerArrayTest : public TexCoordDrawTest
572{
573 protected:
574 SamplerArrayTest()
575 : TexCoordDrawTest(),
576 mTexture2DA(0),
577 mTexture2DB(0),
578 mTexture0UniformLocation(-1),
579 mTexture1UniformLocation(-1)
580 {
581 }
582
583 std::string getFragmentShaderSource() override
584 {
585 return std::string(SHADER_SOURCE
586 (
587 precision mediump float;
588 uniform highp sampler2D tex2DArray[2];
589 varying vec2 texcoord;
590 void main()
591 {
592 gl_FragColor = texture2D(tex2DArray[0], texcoord);
593 gl_FragColor += texture2D(tex2DArray[1], texcoord);
594 }
595 )
596 );
597 }
598
599 void SetUp() override
600 {
601 TexCoordDrawTest::SetUp();
602
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300603 setUpProgram();
604
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200605 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
606 ASSERT_NE(-1, mTexture0UniformLocation);
607 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
608 ASSERT_NE(-1, mTexture1UniformLocation);
609
610 mTexture2DA = create2DTexture();
611 mTexture2DB = create2DTexture();
612 ASSERT_GL_NO_ERROR();
613 }
614
615 void TearDown() override
616 {
617 glDeleteTextures(1, &mTexture2DA);
618 glDeleteTextures(1, &mTexture2DB);
619 TexCoordDrawTest::TearDown();
620 }
621
622 void testSamplerArrayDraw()
623 {
624 GLubyte texData[4];
625 texData[0] = 0;
626 texData[1] = 60;
627 texData[2] = 0;
628 texData[3] = 255;
629
630 glActiveTexture(GL_TEXTURE0);
631 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
632 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
633
634 texData[1] = 120;
635 glActiveTexture(GL_TEXTURE1);
636 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
637 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
638 EXPECT_GL_ERROR(GL_NO_ERROR);
639
640 glUseProgram(mProgram);
641 glUniform1i(mTexture0UniformLocation, 0);
642 glUniform1i(mTexture1UniformLocation, 1);
643 drawQuad(mProgram, "position", 0.5f);
644 EXPECT_GL_NO_ERROR();
645
646 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
647 }
648
649 GLuint mTexture2DA;
650 GLuint mTexture2DB;
651 GLint mTexture0UniformLocation;
652 GLint mTexture1UniformLocation;
653};
654
655
656class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
657{
658 protected:
659 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
660
661 std::string getFragmentShaderSource() override
662 {
663 return std::string(SHADER_SOURCE
664 (
665 precision mediump float;
666 uniform highp sampler2D tex2DArray[2];
667 varying vec2 texcoord;
668
669 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
670 {
671 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
672 }
673
674 void main()
675 {
676 gl_FragColor = computeFragColor(tex2DArray);
677 }
678 )
679 );
680 }
681};
682
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200683class Texture2DArrayTestES3 : public TexCoordDrawTest
684{
685 protected:
686 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
687
688 std::string getVertexShaderSource() override
689 {
690 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400691 "#version 300 es\n"
692 "out vec2 texcoord;\n"
693 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200694 "void main()\n"
695 "{\n"
696 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
697 " texcoord = (position.xy * 0.5) + 0.5;\n"
698 "}\n");
699 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400700
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200701 std::string getFragmentShaderSource() override
702 {
703 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400704 "#version 300 es\n"
705 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200706 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400707 "in vec2 texcoord;\n"
708 "out vec4 fragColor;\n"
709 "void main()\n"
710 "{\n"
711 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200712 "}\n");
713 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400714
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200715 void SetUp() override
716 {
717 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400718
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300719 setUpProgram();
720
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200721 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400722 ASSERT_NE(-1, mTextureArrayLocation);
723
724 glGenTextures(1, &m2DArrayTexture);
725 ASSERT_GL_NO_ERROR();
726 }
727
728 void TearDown() override
729 {
730 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200731 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400732 }
733
734 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400735 GLint mTextureArrayLocation;
736};
737
Olli Etuahobce743a2016-01-15 17:18:28 +0200738class TextureSizeTextureArrayTest : public TexCoordDrawTest
739{
740 protected:
741 TextureSizeTextureArrayTest()
742 : TexCoordDrawTest(),
743 mTexture2DA(0),
744 mTexture2DB(0),
745 mTexture0Location(-1),
746 mTexture1Location(-1)
747 {
748 }
749
750 std::string getVertexShaderSource() override
751 {
752 return std::string(
753 "#version 300 es\n"
754 "in vec4 position;\n"
755 "void main()\n"
756 "{\n"
757 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
758 "}\n");
759 }
760
761 std::string getFragmentShaderSource() override
762 {
763 return std::string(
764 "#version 300 es\n"
765 "precision highp float;\n"
766 "uniform highp sampler2D tex2DArray[2];\n"
767 "out vec4 fragColor;\n"
768 "void main()\n"
769 "{\n"
770 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
771 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
772 " fragColor = vec4(red, green, 0.0, 1.0);\n"
773 "}\n");
774 }
775
776 void SetUp() override
777 {
778 TexCoordDrawTest::SetUp();
779
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300780 setUpProgram();
781
Olli Etuahobce743a2016-01-15 17:18:28 +0200782 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
783 ASSERT_NE(-1, mTexture0Location);
784 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
785 ASSERT_NE(-1, mTexture1Location);
786
787 mTexture2DA = create2DTexture();
788 mTexture2DB = create2DTexture();
789 ASSERT_GL_NO_ERROR();
790 }
791
792 void TearDown() override
793 {
794 glDeleteTextures(1, &mTexture2DA);
795 glDeleteTextures(1, &mTexture2DB);
796 TexCoordDrawTest::TearDown();
797 }
798
799 GLuint mTexture2DA;
800 GLuint mTexture2DB;
801 GLint mTexture0Location;
802 GLint mTexture1Location;
803};
804
Olli Etuahoa314b612016-03-10 16:43:00 +0200805class Texture3DTestES3 : public TexCoordDrawTest
806{
807 protected:
808 Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
809
810 std::string getVertexShaderSource() override
811 {
812 return std::string(
813 "#version 300 es\n"
814 "out vec2 texcoord;\n"
815 "in vec4 position;\n"
816 "void main()\n"
817 "{\n"
818 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
819 " texcoord = (position.xy * 0.5) + 0.5;\n"
820 "}\n");
821 }
822
823 std::string getFragmentShaderSource() override
824 {
825 return std::string(
826 "#version 300 es\n"
827 "precision highp float;\n"
828 "uniform highp sampler3D tex3D;\n"
829 "in vec2 texcoord;\n"
830 "out vec4 fragColor;\n"
831 "void main()\n"
832 "{\n"
833 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
834 "}\n");
835 }
836
837 void SetUp() override
838 {
839 TexCoordDrawTest::SetUp();
840
841 glGenTextures(1, &mTexture3D);
842
843 setUpProgram();
844
845 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
846 ASSERT_NE(-1, mTexture3DUniformLocation);
847 }
848
849 void TearDown() override
850 {
851 glDeleteTextures(1, &mTexture3D);
852 TexCoordDrawTest::TearDown();
853 }
854
855 GLuint mTexture3D;
856 GLint mTexture3DUniformLocation;
857};
858
Olli Etuaho1a679902016-01-14 12:21:47 +0200859class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
860{
861 protected:
862 ShadowSamplerPlusSampler3DTestES3()
863 : TexCoordDrawTest(),
864 mTextureShadow(0),
865 mTexture3D(0),
866 mTextureShadowUniformLocation(-1),
867 mTexture3DUniformLocation(-1),
868 mDepthRefUniformLocation(-1)
869 {
870 }
871
872 std::string getVertexShaderSource() override
873 {
874 return std::string(
875 "#version 300 es\n"
876 "out vec2 texcoord;\n"
877 "in vec4 position;\n"
878 "void main()\n"
879 "{\n"
880 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
881 " texcoord = (position.xy * 0.5) + 0.5;\n"
882 "}\n");
883 }
884
885 std::string getFragmentShaderSource() override
886 {
887 return std::string(
888 "#version 300 es\n"
889 "precision highp float;\n"
890 "uniform highp sampler2DShadow tex2DShadow;\n"
891 "uniform highp sampler3D tex3D;\n"
892 "in vec2 texcoord;\n"
893 "uniform float depthRef;\n"
894 "out vec4 fragColor;\n"
895 "void main()\n"
896 "{\n"
897 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
898 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
899 "}\n");
900 }
901
902 void SetUp() override
903 {
904 TexCoordDrawTest::SetUp();
905
906 glGenTextures(1, &mTexture3D);
907
908 glGenTextures(1, &mTextureShadow);
909 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
910 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
911
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300912 setUpProgram();
913
Olli Etuaho1a679902016-01-14 12:21:47 +0200914 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
915 ASSERT_NE(-1, mTextureShadowUniformLocation);
916 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
917 ASSERT_NE(-1, mTexture3DUniformLocation);
918 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
919 ASSERT_NE(-1, mDepthRefUniformLocation);
920 }
921
922 void TearDown() override
923 {
924 glDeleteTextures(1, &mTextureShadow);
925 glDeleteTextures(1, &mTexture3D);
926 TexCoordDrawTest::TearDown();
927 }
928
929 GLuint mTextureShadow;
930 GLuint mTexture3D;
931 GLint mTextureShadowUniformLocation;
932 GLint mTexture3DUniformLocation;
933 GLint mDepthRefUniformLocation;
934};
935
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200936class SamplerTypeMixTestES3 : public TexCoordDrawTest
937{
938 protected:
939 SamplerTypeMixTestES3()
940 : TexCoordDrawTest(),
941 mTexture2D(0),
942 mTextureCube(0),
943 mTexture2DShadow(0),
944 mTextureCubeShadow(0),
945 mTexture2DUniformLocation(-1),
946 mTextureCubeUniformLocation(-1),
947 mTexture2DShadowUniformLocation(-1),
948 mTextureCubeShadowUniformLocation(-1),
949 mDepthRefUniformLocation(-1)
950 {
951 }
952
953 std::string getVertexShaderSource() override
954 {
955 return std::string(
956 "#version 300 es\n"
957 "out vec2 texcoord;\n"
958 "in vec4 position;\n"
959 "void main()\n"
960 "{\n"
961 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
962 " texcoord = (position.xy * 0.5) + 0.5;\n"
963 "}\n");
964 }
965
966 std::string getFragmentShaderSource() override
967 {
968 return std::string(
969 "#version 300 es\n"
970 "precision highp float;\n"
971 "uniform highp sampler2D tex2D;\n"
972 "uniform highp samplerCube texCube;\n"
973 "uniform highp sampler2DShadow tex2DShadow;\n"
974 "uniform highp samplerCubeShadow texCubeShadow;\n"
975 "in vec2 texcoord;\n"
976 "uniform float depthRef;\n"
977 "out vec4 fragColor;\n"
978 "void main()\n"
979 "{\n"
980 " fragColor = texture(tex2D, texcoord);\n"
981 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
982 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
983 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
984 "0.125);\n"
985 "}\n");
986 }
987
988 void SetUp() override
989 {
990 TexCoordDrawTest::SetUp();
991
992 glGenTextures(1, &mTexture2D);
993 glGenTextures(1, &mTextureCube);
994
995 glGenTextures(1, &mTexture2DShadow);
996 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
997 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
998
999 glGenTextures(1, &mTextureCubeShadow);
1000 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1001 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1002
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001003 setUpProgram();
1004
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001005 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1006 ASSERT_NE(-1, mTexture2DUniformLocation);
1007 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1008 ASSERT_NE(-1, mTextureCubeUniformLocation);
1009 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1010 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1011 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1012 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1013 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1014 ASSERT_NE(-1, mDepthRefUniformLocation);
1015
1016 ASSERT_GL_NO_ERROR();
1017 }
1018
1019 void TearDown() override
1020 {
1021 glDeleteTextures(1, &mTexture2D);
1022 glDeleteTextures(1, &mTextureCube);
1023 glDeleteTextures(1, &mTexture2DShadow);
1024 glDeleteTextures(1, &mTextureCubeShadow);
1025 TexCoordDrawTest::TearDown();
1026 }
1027
1028 GLuint mTexture2D;
1029 GLuint mTextureCube;
1030 GLuint mTexture2DShadow;
1031 GLuint mTextureCubeShadow;
1032 GLint mTexture2DUniformLocation;
1033 GLint mTextureCubeUniformLocation;
1034 GLint mTexture2DShadowUniformLocation;
1035 GLint mTextureCubeShadowUniformLocation;
1036 GLint mDepthRefUniformLocation;
1037};
1038
Olli Etuaho96963162016-03-21 11:54:33 +02001039class SamplerInStructTest : public Texture2DTest
1040{
1041 protected:
1042 SamplerInStructTest() : Texture2DTest() {}
1043
1044 const char *getTextureUniformName() override { return "us.tex"; }
1045
1046 std::string getFragmentShaderSource() override
1047 {
1048 return std::string(
1049 "precision highp float;\n"
1050 "struct S\n"
1051 "{\n"
1052 " vec4 a;\n"
1053 " highp sampler2D tex;\n"
1054 "};\n"
1055 "uniform S us;\n"
1056 "varying vec2 texcoord;\n"
1057 "void main()\n"
1058 "{\n"
1059 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1060 "}\n");
1061 }
1062
1063 void runSamplerInStructTest()
1064 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001065 setUpProgram();
1066
Olli Etuaho96963162016-03-21 11:54:33 +02001067 glActiveTexture(GL_TEXTURE0);
1068 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001069 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1070 &GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001071 drawQuad(mProgram, "position", 0.5f);
Olli Etuahoa314b612016-03-10 16:43:00 +02001072 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001073 }
1074};
1075
1076class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1077{
1078 protected:
1079 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1080
1081 std::string getFragmentShaderSource() override
1082 {
1083 return std::string(
1084 "precision highp float;\n"
1085 "struct S\n"
1086 "{\n"
1087 " vec4 a;\n"
1088 " highp sampler2D tex;\n"
1089 "};\n"
1090 "uniform S us;\n"
1091 "varying vec2 texcoord;\n"
1092 "vec4 sampleFrom(S s) {\n"
1093 " return texture2D(s.tex, texcoord + s.a.x);\n"
1094 "}\n"
1095 "void main()\n"
1096 "{\n"
1097 " gl_FragColor = sampleFrom(us);\n"
1098 "}\n");
1099 }
1100};
1101
1102class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1103{
1104 protected:
1105 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1106
1107 const char *getTextureUniformName() override { return "us[0].tex"; }
1108
1109 std::string getFragmentShaderSource() override
1110 {
1111 return std::string(
1112 "precision highp float;\n"
1113 "struct S\n"
1114 "{\n"
1115 " vec4 a;\n"
1116 " highp sampler2D tex;\n"
1117 "};\n"
1118 "uniform S us[1];\n"
1119 "varying vec2 texcoord;\n"
1120 "vec4 sampleFrom(S s) {\n"
1121 " return texture2D(s.tex, texcoord + s.a.x);\n"
1122 "}\n"
1123 "void main()\n"
1124 "{\n"
1125 " gl_FragColor = sampleFrom(us[0]);\n"
1126 "}\n");
1127 }
1128};
1129
1130class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1131{
1132 protected:
1133 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1134
1135 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1136
1137 std::string getFragmentShaderSource() override
1138 {
1139 return std::string(
1140 "precision highp float;\n"
1141 "struct SUB\n"
1142 "{\n"
1143 " vec4 a;\n"
1144 " highp sampler2D tex;\n"
1145 "};\n"
1146 "struct S\n"
1147 "{\n"
1148 " SUB sub;\n"
1149 "};\n"
1150 "uniform S us[1];\n"
1151 "varying vec2 texcoord;\n"
1152 "vec4 sampleFrom(SUB s) {\n"
1153 " return texture2D(s.tex, texcoord + s.a.x);\n"
1154 "}\n"
1155 "void main()\n"
1156 "{\n"
1157 " gl_FragColor = sampleFrom(us[0].sub);\n"
1158 "}\n");
1159 }
1160};
1161
1162class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1163{
1164 protected:
1165 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1166
1167 std::string getFragmentShaderSource() override
1168 {
1169 return std::string(
1170 "precision highp float;\n"
1171 "struct S\n"
1172 "{\n"
1173 " vec4 a;\n"
1174 " highp sampler2D tex;\n"
1175 "};\n"
1176 "uniform S us;\n"
1177 "uniform float us_tex;\n"
1178 "varying vec2 texcoord;\n"
1179 "void main()\n"
1180 "{\n"
1181 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1182 "}\n");
1183 }
1184};
1185
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001186TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001187{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001188 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001189 EXPECT_GL_ERROR(GL_NO_ERROR);
1190
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001191 setUpProgram();
1192
Jamie Madillf67115c2014-04-22 13:14:05 -04001193 const GLubyte *pixels[20] = { 0 };
1194 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1195 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1196}
Geoff Langc41e42d2014-04-28 10:58:16 -04001197
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001198TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001199{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001200 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001201 EXPECT_GL_ERROR(GL_NO_ERROR);
1202
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001203 setUpProgram();
1204
Geoff Langc41e42d2014-04-28 10:58:16 -04001205 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001206 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001207 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001208 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001209
1210 const GLubyte *pixel[4] = { 0 };
1211
1212 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1213 EXPECT_GL_NO_ERROR();
1214
1215 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1216 EXPECT_GL_NO_ERROR();
1217
1218 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1219 EXPECT_GL_NO_ERROR();
1220}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001221
1222// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001223TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001224{
1225 glActiveTexture(GL_TEXTURE0);
1226 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1227 glActiveTexture(GL_TEXTURE1);
1228 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1229 EXPECT_GL_ERROR(GL_NO_ERROR);
1230
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001231 glUseProgram(mProgram);
1232 glUniform1i(mTexture2DUniformLocation, 0);
1233 glUniform1i(mTextureCubeUniformLocation, 1);
1234 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001235 EXPECT_GL_NO_ERROR();
1236}
Jamie Madill9aca0592014-10-06 16:26:59 -04001237
Olli Etuaho53a2da12016-01-11 15:43:32 +02001238// Test drawing with two texture types accessed from the same shader and check that the result of
1239// drawing is correct.
1240TEST_P(TextureCubeTest, CubeMapDraw)
1241{
1242 GLubyte texData[4];
1243 texData[0] = 0;
1244 texData[1] = 60;
1245 texData[2] = 0;
1246 texData[3] = 255;
1247
1248 glActiveTexture(GL_TEXTURE0);
1249 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1250 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1251
1252 glActiveTexture(GL_TEXTURE1);
1253 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1254 texData[1] = 120;
1255 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1256 texData);
1257 EXPECT_GL_ERROR(GL_NO_ERROR);
1258
1259 glUseProgram(mProgram);
1260 glUniform1i(mTexture2DUniformLocation, 0);
1261 glUniform1i(mTextureCubeUniformLocation, 1);
1262 drawQuad(mProgram, "position", 0.5f);
1263 EXPECT_GL_NO_ERROR();
1264
1265 int px = getWindowWidth() - 1;
1266 int py = 0;
1267 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1268}
1269
Olli Etuaho4644a202016-01-12 15:12:53 +02001270TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1271{
1272 glActiveTexture(GL_TEXTURE0);
1273 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1274 GLubyte texData[4];
1275 texData[0] = 0;
1276 texData[1] = 128;
1277 texData[2] = 0;
1278 texData[3] = 255;
1279 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1280 glUseProgram(mProgram);
1281 glUniform1i(mTexture2DUniformLocation, 0);
1282 drawQuad(mProgram, "position", 0.5f);
1283 EXPECT_GL_NO_ERROR();
1284
1285 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1286}
1287
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001288// Test drawing with two textures passed to the shader in a sampler array.
1289TEST_P(SamplerArrayTest, SamplerArrayDraw)
1290{
1291 testSamplerArrayDraw();
1292}
1293
1294// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1295// user-defined function in the shader.
1296TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1297{
1298 testSamplerArrayDraw();
1299}
1300
Jamie Madill9aca0592014-10-06 16:26:59 -04001301// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001302TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001303{
1304 int px = getWindowWidth() / 2;
1305 int py = getWindowHeight() / 2;
1306
1307 glActiveTexture(GL_TEXTURE0);
1308 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1309
Olli Etuahoa314b612016-03-10 16:43:00 +02001310 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001311
Olli Etuahoa314b612016-03-10 16:43:00 +02001312 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1315 glGenerateMipmap(GL_TEXTURE_2D);
1316
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001317 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001318 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001319 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1320 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001321 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001322 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001323
Olli Etuahoa314b612016-03-10 16:43:00 +02001324 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001325
Olli Etuahoa314b612016-03-10 16:43:00 +02001326 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1327 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001328 glGenerateMipmap(GL_TEXTURE_2D);
1329
Olli Etuahoa314b612016-03-10 16:43:00 +02001330 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001331
Olli Etuahoa314b612016-03-10 16:43:00 +02001332 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1333 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001334 glGenerateMipmap(GL_TEXTURE_2D);
1335
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001336 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001337
1338 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001339 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001340}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001341
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001342// Test creating a FBO with a cube map render target, to test an ANGLE bug
1343// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001344TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001345{
1346 GLuint fbo;
1347 glGenFramebuffers(1, &fbo);
1348 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1349
1350 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1351 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1352
Corentin Wallez322653b2015-06-17 18:33:56 +02001353 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001354
1355 glDeleteFramebuffers(1, &fbo);
1356
1357 EXPECT_GL_NO_ERROR();
1358}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001359
1360// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001361TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001362{
1363 int width = getWindowWidth();
1364 int height = getWindowHeight();
1365
1366 GLuint tex2D;
1367 glGenTextures(1, &tex2D);
1368 glActiveTexture(GL_TEXTURE0);
1369 glBindTexture(GL_TEXTURE_2D, tex2D);
1370
1371 // Fill with red
1372 std::vector<GLubyte> pixels(3 * 16 * 16);
1373 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1374 {
1375 pixels[pixelId * 3 + 0] = 255;
1376 pixels[pixelId * 3 + 1] = 0;
1377 pixels[pixelId * 3 + 2] = 0;
1378 }
1379
1380 // ANGLE internally uses RGBA as the DirectX format for RGB images
1381 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1382 // The data is kept in a CPU-side image and the image is marked as dirty.
1383 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1384
1385 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1386 // glTexSubImage2D should take into account that the image is dirty.
1387 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1390
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001391 setUpProgram();
1392
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001393 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001394 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001395 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001396 glDeleteTextures(1, &tex2D);
1397 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001398 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001399
1400 // Validate that the region of the texture without data has an alpha of 1.0
1401 GLubyte pixel[4];
1402 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1403 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001404}
1405
1406// 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 +02001407TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001408{
1409 if (extensionEnabled("NV_pixel_buffer_object"))
1410 {
1411 int width = getWindowWidth();
1412 int height = getWindowHeight();
1413
1414 GLuint tex2D;
1415 glGenTextures(1, &tex2D);
1416 glActiveTexture(GL_TEXTURE0);
1417 glBindTexture(GL_TEXTURE_2D, tex2D);
1418
1419 // Fill with red
1420 std::vector<GLubyte> pixels(3 * 16 * 16);
1421 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1422 {
1423 pixels[pixelId * 3 + 0] = 255;
1424 pixels[pixelId * 3 + 1] = 0;
1425 pixels[pixelId * 3 + 2] = 0;
1426 }
1427
1428 // Read 16x16 region from red backbuffer to PBO
1429 GLuint pbo;
1430 glGenBuffers(1, &pbo);
1431 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1432 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1433
1434 // ANGLE internally uses RGBA as the DirectX format for RGB images
1435 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1436 // The data is kept in a CPU-side image and the image is marked as dirty.
1437 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1438
1439 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1440 // glTexSubImage2D should take into account that the image is dirty.
1441 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1442 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1443 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1444
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001445 setUpProgram();
1446
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001447 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001448 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001449 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001450 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001451 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001452 EXPECT_GL_NO_ERROR();
1453 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1454 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1455 }
1456}
Jamie Madillbc393df2015-01-29 13:46:07 -05001457
1458// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001459TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001460{
1461 testFloatCopySubImage(1, 1);
1462}
1463
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001464TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001465{
1466 testFloatCopySubImage(2, 1);
1467}
1468
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001469TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001470{
1471 testFloatCopySubImage(2, 2);
1472}
1473
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001474TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001475{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001476 if (IsIntel() && IsLinux())
1477 {
1478 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1479 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1480 return;
1481 }
1482
Jamie Madillbc393df2015-01-29 13:46:07 -05001483 testFloatCopySubImage(3, 1);
1484}
1485
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001486TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001487{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001488 if (IsIntel() && IsLinux())
1489 {
1490 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1491 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1492 return;
1493 }
1494
Jamie Madillbc393df2015-01-29 13:46:07 -05001495 testFloatCopySubImage(3, 2);
1496}
1497
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001498TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001499{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001500 if (IsIntel() && IsLinux())
1501 {
1502 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1503 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1504 return;
1505 }
1506
Austin Kinrossd544cc92016-01-11 15:26:42 -08001507 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001508 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001509 {
1510 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1511 return;
1512 }
1513
Jamie Madillbc393df2015-01-29 13:46:07 -05001514 testFloatCopySubImage(3, 3);
1515}
1516
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001517TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001518{
1519 testFloatCopySubImage(4, 1);
1520}
1521
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001522TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001523{
1524 testFloatCopySubImage(4, 2);
1525}
1526
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001527TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001528{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001529 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001530 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001531 {
1532 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1533 return;
1534 }
1535
Jamie Madillbc393df2015-01-29 13:46:07 -05001536 testFloatCopySubImage(4, 3);
1537}
1538
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001539TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001540{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001541 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001542 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001543 {
1544 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1545 return;
1546 }
1547
Jamie Madillbc393df2015-01-29 13:46:07 -05001548 testFloatCopySubImage(4, 4);
1549}
Austin Kinross07285142015-03-26 11:36:16 -07001550
1551// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1552// 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 +02001553TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001554{
1555 const int npotTexSize = 5;
1556 const int potTexSize = 4; // Should be less than npotTexSize
1557 GLuint tex2D;
1558
1559 if (extensionEnabled("GL_OES_texture_npot"))
1560 {
1561 // This test isn't applicable if texture_npot is enabled
1562 return;
1563 }
1564
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001565 setUpProgram();
1566
Austin Kinross07285142015-03-26 11:36:16 -07001567 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1568
Austin Kinross5faa15b2016-01-11 13:32:48 -08001569 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1570 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1571
Austin Kinross07285142015-03-26 11:36:16 -07001572 glActiveTexture(GL_TEXTURE0);
1573 glGenTextures(1, &tex2D);
1574 glBindTexture(GL_TEXTURE_2D, tex2D);
1575
1576 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1577 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1578 {
1579 pixels[pixelId] = 64;
1580 }
1581
1582 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1583 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1584
1585 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1586 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1587 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1588
1589 // Check that an NPOT texture on level 0 succeeds
1590 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1591 EXPECT_GL_NO_ERROR();
1592
1593 // Check that generateMipmap fails on NPOT
1594 glGenerateMipmap(GL_TEXTURE_2D);
1595 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1596
1597 // Check that nothing is drawn if filtering is not correct for NPOT
1598 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1600 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1601 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1602 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001603 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001604 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1605
1606 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1610 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001611 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001612 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1613
1614 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1616 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001617 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001618 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1619
1620 // Check that glTexImage2D for POT texture succeeds
1621 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1622 EXPECT_GL_NO_ERROR();
1623
1624 // Check that generateMipmap for an POT texture succeeds
1625 glGenerateMipmap(GL_TEXTURE_2D);
1626 EXPECT_GL_NO_ERROR();
1627
1628 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1629 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1630 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1631 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1632 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1633 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001634 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001635 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1636 EXPECT_GL_NO_ERROR();
1637}
Jamie Madillfa05f602015-05-07 13:47:11 -04001638
Austin Kinross08528e12015-10-07 16:24:40 -07001639// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1640// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001641TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001642{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001643 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1644 // 1278)
1645 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1646 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1647 {
1648 std::cout << "Test disabled on OpenGL." << std::endl;
1649 return;
1650 }
1651
Austin Kinross08528e12015-10-07 16:24:40 -07001652 glActiveTexture(GL_TEXTURE0);
1653 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1654
1655 // Create an 8x8 (i.e. power-of-two) texture.
1656 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1659 glGenerateMipmap(GL_TEXTURE_2D);
1660
1661 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1662 // This should always work, even if GL_OES_texture_npot isn't active.
1663 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1664
1665 EXPECT_GL_NO_ERROR();
1666}
1667
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001668// Test to check that texture completeness is determined correctly when the texture base level is
1669// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1670TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1671{
1672 glActiveTexture(GL_TEXTURE0);
1673 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001674
1675 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
1676 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1677 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1678 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1679 texDataGreen.data());
1680 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1681 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001682 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1683 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1684 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1685
1686 EXPECT_GL_NO_ERROR();
1687
1688 drawQuad(mProgram, "position", 0.5f);
1689
Olli Etuahoa314b612016-03-10 16:43:00 +02001690 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1691}
1692
1693// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1694// have images defined.
1695TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
1696{
1697 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1698 {
1699 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
1700 std::cout << "Test skipped on AMD OpenGL." << std::endl;
1701 return;
1702 }
1703 if (IsOSX())
1704 {
1705 // Observed incorrect rendering on OSX.
1706 std::cout << "Test skipped on OSX." << std::endl;
1707 return;
1708 }
1709 glActiveTexture(GL_TEXTURE0);
1710 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1711 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1712 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1713 texDataGreen.data());
1714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1716 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1718
1719 EXPECT_GL_NO_ERROR();
1720
1721 drawQuad(mProgram, "position", 0.5f);
1722
1723 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1724}
1725
Olli Etuahoe8528d82016-05-16 17:50:52 +03001726// Test that drawing works correctly when level 0 is undefined and base level is 1.
1727TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
1728{
1729 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1730 {
1731 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
1732 std::cout << "Test skipped on AMD OpenGL." << std::endl;
1733 return;
1734 }
1735 if (IsOSX())
1736 {
1737 // Observed incorrect rendering on OSX.
1738 std::cout << "Test skipped on OSX." << std::endl;
1739 return;
1740 }
1741 glActiveTexture(GL_TEXTURE0);
1742 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1743 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1744 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1745 texDataGreen.data());
1746 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1747 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1748 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1750
1751 EXPECT_GL_NO_ERROR();
1752
1753 // Texture is incomplete.
1754 drawQuad(mProgram, "position", 0.5f);
1755 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
1756
1757 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1758 texDataGreen.data());
1759
1760 // Texture is now complete.
1761 drawQuad(mProgram, "position", 0.5f);
1762 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1763}
1764
Olli Etuahoa314b612016-03-10 16:43:00 +02001765// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1766// dimensions that don't fit the images inside the range.
1767// GLES 3.0.4 section 3.8.13 Texture completeness
1768TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1769{
1770 if (IsOSX())
1771 {
1772 // Observed incorrect rendering on OSX.
1773 std::cout << "Test skipped on OSX." << std::endl;
1774 return;
1775 }
1776 glActiveTexture(GL_TEXTURE0);
1777 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1778 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
1779 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1780 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
1781
1782 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1783 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1784
1785 // Two levels that are initially unused.
1786 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1787 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1788 texDataCyan.data());
1789
1790 // One level that is used - only this level should affect completeness.
1791 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1792 texDataGreen.data());
1793
1794 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1795 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1796
1797 EXPECT_GL_NO_ERROR();
1798
1799 drawQuad(mProgram, "position", 0.5f);
1800
1801 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1802
1803 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1804 {
1805 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1806 // level was changed.
1807 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1808 return;
1809 }
1810
1811 // Switch the level that is being used to the cyan level 2.
1812 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
1813 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1814
1815 EXPECT_GL_NO_ERROR();
1816
1817 drawQuad(mProgram, "position", 0.5f);
1818
1819 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1820}
1821
1822// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1823// have images defined.
1824TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
1825{
1826 if (IsOSX())
1827 {
1828 // Observed incorrect rendering on OSX.
1829 std::cout << "Test skipped on OSX." << std::endl;
1830 return;
1831 }
1832 glActiveTexture(GL_TEXTURE0);
1833 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1834 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1835 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1836 texDataGreen.data());
1837 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1838 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1839 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1840 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1841
1842 EXPECT_GL_NO_ERROR();
1843
1844 drawQuad(mProgram, "position", 0.5f);
1845
1846 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1847}
1848
1849// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1850// dimensions that don't fit the images inside the range.
1851// GLES 3.0.4 section 3.8.13 Texture completeness
1852TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1853{
1854 if (IsOSX())
1855 {
1856 // Observed incorrect rendering on OSX.
1857 std::cout << "Test skipped on OSX." << std::endl;
1858 return;
1859 }
1860 glActiveTexture(GL_TEXTURE0);
1861 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1862 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1863 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1864 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1865
1866 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1867 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1868
1869 // Two levels that are initially unused.
1870 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1871 texDataRed.data());
1872 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1873 texDataCyan.data());
1874
1875 // One level that is used - only this level should affect completeness.
1876 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1877 texDataGreen.data());
1878
1879 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1880 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1881
1882 EXPECT_GL_NO_ERROR();
1883
1884 drawQuad(mProgram, "position", 0.5f);
1885
1886 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1887
1888 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1889 {
1890 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1891 // level was changed.
1892 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1893 return;
1894 }
1895
1896 // Switch the level that is being used to the cyan level 2.
1897 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
1898 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
1899
1900 EXPECT_GL_NO_ERROR();
1901
1902 drawQuad(mProgram, "position", 0.5f);
1903
1904 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1905}
1906
1907// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1908// have images defined.
1909TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
1910{
1911 if (IsOSX())
1912 {
1913 // Observed incorrect rendering on OSX.
1914 std::cout << "Test skipped on OSX." << std::endl;
1915 return;
1916 }
1917 glActiveTexture(GL_TEXTURE0);
1918 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
1919 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1920 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1921 texDataGreen.data());
1922 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1923 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1924 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1925 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1926
1927 EXPECT_GL_NO_ERROR();
1928
1929 drawQuad(mProgram, "position", 0.5f);
1930
1931 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1932}
1933
1934// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1935// dimensions that don't fit the images inside the range.
1936// GLES 3.0.4 section 3.8.13 Texture completeness
1937TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1938{
1939 if (IsOSX())
1940 {
1941 // Observed incorrect rendering on OSX.
1942 std::cout << "Test skipped on OSX." << std::endl;
1943 return;
1944 }
1945 glActiveTexture(GL_TEXTURE0);
1946 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
1947 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1948 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1949 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1950
1951 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1952 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1953
1954 // Two levels that are initially unused.
1955 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1956 texDataRed.data());
1957 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1958 texDataCyan.data());
1959
1960 // One level that is used - only this level should affect completeness.
1961 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1962 texDataGreen.data());
1963
1964 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1965 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1966
1967 EXPECT_GL_NO_ERROR();
1968
1969 drawQuad(mProgram, "position", 0.5f);
1970
1971 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1972
1973 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1974 {
1975 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1976 // level was changed.
1977 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1978 return;
1979 }
1980 if (IsNVIDIA() && (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1981 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE))
1982 {
1983 // NVIDIA was observed drawing color 0,0,0,0 instead of the texture color after the base
1984 // level was changed.
1985 std::cout << "Test partially skipped on NVIDIA OpenGL." << std::endl;
1986 return;
1987 }
1988
1989 // Switch the level that is being used to the cyan level 2.
1990 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
1991 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
1992
1993 EXPECT_GL_NO_ERROR();
1994
1995 drawQuad(mProgram, "position", 0.5f);
1996
1997 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1998}
1999
2000// Test that texture completeness is updated if texture max level changes.
2001// GLES 3.0.4 section 3.8.13 Texture completeness
2002TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2003{
2004 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2005 {
2006 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2007 // the base level.
2008 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2009 return;
2010 }
2011 if (IsOSX())
2012 {
2013 // Observed incorrect rendering on OSX.
2014 std::cout << "Test skipped on OSX." << std::endl;
2015 return;
2016 }
2017
2018 glActiveTexture(GL_TEXTURE0);
2019 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2020 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2021
2022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2024
2025 // A level that is initially unused.
2026 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2027 texDataGreen.data());
2028
2029 // One level that is initially used - only this level should affect completeness.
2030 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2031 texDataGreen.data());
2032
2033 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2034 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2035
2036 EXPECT_GL_NO_ERROR();
2037
2038 drawQuad(mProgram, "position", 0.5f);
2039
2040 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2041
2042 // Switch the max level to level 1. The levels within the used range now have inconsistent
2043 // dimensions and the texture should be incomplete.
2044 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2045
2046 EXPECT_GL_NO_ERROR();
2047
2048 drawQuad(mProgram, "position", 0.5f);
2049
2050 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2051}
2052
2053// Test that 3D texture completeness is updated if texture max level changes.
2054// GLES 3.0.4 section 3.8.13 Texture completeness
2055TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2056{
2057 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2058 {
2059 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2060 // the base level.
2061 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2062 return;
2063 }
2064 if (IsOSX())
2065 {
2066 // Observed incorrect rendering on OSX.
2067 std::cout << "Test skipped on OSX." << std::endl;
2068 return;
2069 }
2070
2071 glActiveTexture(GL_TEXTURE0);
2072 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2073 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2074
2075 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2076 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2077
2078 // A level that is initially unused.
2079 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2080 texDataGreen.data());
2081
2082 // One level that is initially used - only this level should affect completeness.
2083 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2084 texDataGreen.data());
2085
2086 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2087 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2088
2089 EXPECT_GL_NO_ERROR();
2090
2091 drawQuad(mProgram, "position", 0.5f);
2092
2093 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2094
2095 // Switch the max level to level 1. The levels within the used range now have inconsistent
2096 // dimensions and the texture should be incomplete.
2097 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2098
2099 EXPECT_GL_NO_ERROR();
2100
2101 drawQuad(mProgram, "position", 0.5f);
2102
2103 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2104}
2105
2106// Test that texture completeness is updated if texture base level changes.
2107// GLES 3.0.4 section 3.8.13 Texture completeness
2108TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2109{
2110 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2111 {
2112 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2113 // the base level.
2114 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2115 return;
2116 }
2117
2118 glActiveTexture(GL_TEXTURE0);
2119 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2120 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2121
2122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2124
2125 // Two levels that are initially unused.
2126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2127 texDataGreen.data());
2128 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2129 texDataGreen.data());
2130
2131 // One level that is initially used - only this level should affect completeness.
2132 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2133 texDataGreen.data());
2134
2135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2137
2138 EXPECT_GL_NO_ERROR();
2139
2140 drawQuad(mProgram, "position", 0.5f);
2141
2142 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2143
2144 // Switch the base level to level 1. The levels within the used range now have inconsistent
2145 // dimensions and the texture should be incomplete.
2146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2147
2148 EXPECT_GL_NO_ERROR();
2149
2150 drawQuad(mProgram, "position", 0.5f);
2151
2152 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2153}
2154
2155// Test that texture is not complete if base level is greater than max level.
2156// GLES 3.0.4 section 3.8.13 Texture completeness
2157TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2158{
2159 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2160 {
2161 // Intel Windows OpenGL driver crashes if the base level of a non-immutable texture is out
2162 // of range.
2163 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2164 return;
2165 }
2166
2167 glActiveTexture(GL_TEXTURE0);
2168 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2169
2170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2172
2173 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2174
2175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2177
2178 EXPECT_GL_NO_ERROR();
2179
2180 drawQuad(mProgram, "position", 0.5f);
2181
2182 // Texture should be incomplete.
2183 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2184}
2185
2186// Test that immutable texture base level and max level are clamped.
2187// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2188TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2189{
Olli Etuahoa314b612016-03-10 16:43:00 +02002190 glActiveTexture(GL_TEXTURE0);
2191 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2192
2193 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2195
2196 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2197
2198 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2199
2200 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2201 // should be clamped to [base_level, levels - 1].
2202 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2203 // In the case of this test, those rules make the effective base level and max level 0.
2204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2206
2207 EXPECT_GL_NO_ERROR();
2208
2209 drawQuad(mProgram, "position", 0.5f);
2210
2211 // Texture should be complete.
2212 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2213}
2214
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002215// Test that changing base level works when it affects the format of the texture.
2216TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2217{
2218 if (IsNVIDIA() && (isOpenGL() || isGLES()))
2219 {
2220 // Observed rendering corruption on NVIDIA OpenGL.
2221 std::cout << "Test skipped on NVIDIA OpenGL." << std::endl;
2222 return;
2223 }
2224 if (IsIntel() && isOpenGL())
2225 {
2226 // Observed incorrect rendering on Intel OpenGL.
2227 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2228 return;
2229 }
2230 if (IsAMD() && isOpenGL())
2231 {
2232 // Observed incorrect rendering on AMD OpenGL.
2233 std::cout << "Test skipped on AMD OpenGL." << std::endl;
2234 return;
2235 }
2236
2237 glActiveTexture(GL_TEXTURE0);
2238 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2239 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2240 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2241
2242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2243 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2244
2245 // RGBA8 level that's initially unused.
2246 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2247 texDataCyan.data());
2248
2249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2251
2252 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2253 // format. It reads green channel data from the green and alpha channels of texDataGreen
2254 // (this is a bit hacky but works).
2255 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2256
2257 EXPECT_GL_NO_ERROR();
2258
2259 drawQuad(mProgram, "position", 0.5f);
2260
2261 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2262
2263 // Switch the texture to use the cyan level 0 with the RGBA format.
2264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2266
2267 EXPECT_GL_NO_ERROR();
2268
2269 drawQuad(mProgram, "position", 0.5f);
2270
2271 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2272}
2273
Olli Etuahoa314b612016-03-10 16:43:00 +02002274// Test that setting a texture image works when base level is out of range.
2275TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2276{
2277 glActiveTexture(GL_TEXTURE0);
2278 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2279
2280 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2281 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2282
2283 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2284 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2285
2286 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2287
2288 EXPECT_GL_NO_ERROR();
2289
2290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2291
2292 drawQuad(mProgram, "position", 0.5f);
2293
2294 // Texture should be complete.
2295 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002296}
2297
Jamie Madill2453dbc2015-07-14 11:35:42 -04002298// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
2299// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
2300// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002301TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002302{
2303 std::vector<GLubyte> pixelData;
2304 for (size_t count = 0; count < 5000; count++)
2305 {
2306 pixelData.push_back(0u);
2307 pixelData.push_back(255u);
2308 pixelData.push_back(0u);
2309 }
2310
2311 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002312 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002313 glUniform1i(mTextureArrayLocation, 0);
2314
2315 // The first draw worked correctly.
2316 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
2317
2318 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2319 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2320 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2321 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002322 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002323 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002324
2325 // The dimension of the respecification must match the original exactly to trigger the bug.
2326 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 +02002327 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002328 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002329
2330 ASSERT_GL_NO_ERROR();
2331}
2332
Olli Etuaho1a679902016-01-14 12:21:47 +02002333// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2334// This test is needed especially to confirm that sampler registers get assigned correctly on
2335// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2336TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2337{
2338 glActiveTexture(GL_TEXTURE0);
2339 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2340 GLubyte texData[4];
2341 texData[0] = 0;
2342 texData[1] = 60;
2343 texData[2] = 0;
2344 texData[3] = 255;
2345 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2346
2347 glActiveTexture(GL_TEXTURE1);
2348 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2349 GLfloat depthTexData[1];
2350 depthTexData[0] = 0.5f;
2351 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2352 depthTexData);
2353
2354 glUseProgram(mProgram);
2355 glUniform1f(mDepthRefUniformLocation, 0.3f);
2356 glUniform1i(mTexture3DUniformLocation, 0);
2357 glUniform1i(mTextureShadowUniformLocation, 1);
2358
2359 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2360 drawQuad(mProgram, "position", 0.5f);
2361 EXPECT_GL_NO_ERROR();
2362 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2363 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2364
2365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2366 drawQuad(mProgram, "position", 0.5f);
2367 EXPECT_GL_NO_ERROR();
2368 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2369 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2370}
2371
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002372// Test multiple different sampler types in the same shader.
2373// This test makes sure that even if sampler / texture registers get grouped together based on type
2374// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2375// still has the right register index information for each ESSL sampler.
2376// The tested ESSL samplers have the following types in D3D11 HLSL:
2377// sampler2D: Texture2D + SamplerState
2378// samplerCube: TextureCube + SamplerState
2379// sampler2DShadow: Texture2D + SamplerComparisonState
2380// samplerCubeShadow: TextureCube + SamplerComparisonState
2381TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2382{
2383 glActiveTexture(GL_TEXTURE0);
2384 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2385 GLubyte texData[4];
2386 texData[0] = 0;
2387 texData[1] = 0;
2388 texData[2] = 120;
2389 texData[3] = 255;
2390 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2391
2392 glActiveTexture(GL_TEXTURE1);
2393 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2394 texData[0] = 0;
2395 texData[1] = 90;
2396 texData[2] = 0;
2397 texData[3] = 255;
2398 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2399 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2400 texData);
2401
2402 glActiveTexture(GL_TEXTURE2);
2403 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2405 GLfloat depthTexData[1];
2406 depthTexData[0] = 0.5f;
2407 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2408 depthTexData);
2409
2410 glActiveTexture(GL_TEXTURE3);
2411 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2412 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2413 depthTexData[0] = 0.2f;
2414 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2415 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2416 depthTexData);
2417
2418 EXPECT_GL_NO_ERROR();
2419
2420 glUseProgram(mProgram);
2421 glUniform1f(mDepthRefUniformLocation, 0.3f);
2422 glUniform1i(mTexture2DUniformLocation, 0);
2423 glUniform1i(mTextureCubeUniformLocation, 1);
2424 glUniform1i(mTexture2DShadowUniformLocation, 2);
2425 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2426
2427 drawQuad(mProgram, "position", 0.5f);
2428 EXPECT_GL_NO_ERROR();
2429 // The shader writes:
2430 // <texture 2d color> +
2431 // <cube map color> +
2432 // 0.25 * <comparison result (1.0)> +
2433 // 0.125 * <comparison result (0.0)>
2434 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2435}
2436
Olli Etuahobce743a2016-01-15 17:18:28 +02002437// Test different base levels on textures accessed through the same sampler array.
2438// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2439TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2440{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002441 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02002442 {
2443 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
2444 return;
2445 }
2446 glActiveTexture(GL_TEXTURE0);
2447 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2448 GLsizei size = 64;
2449 for (GLint level = 0; level < 7; ++level)
2450 {
2451 ASSERT_LT(0, size);
2452 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2453 nullptr);
2454 size = size / 2;
2455 }
2456 ASSERT_EQ(0, size);
2457 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2458
2459 glActiveTexture(GL_TEXTURE1);
2460 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2461 size = 128;
2462 for (GLint level = 0; level < 8; ++level)
2463 {
2464 ASSERT_LT(0, size);
2465 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2466 nullptr);
2467 size = size / 2;
2468 }
2469 ASSERT_EQ(0, size);
2470 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2471 EXPECT_GL_NO_ERROR();
2472
2473 glUseProgram(mProgram);
2474 glUniform1i(mTexture0Location, 0);
2475 glUniform1i(mTexture1Location, 1);
2476
2477 drawQuad(mProgram, "position", 0.5f);
2478 EXPECT_GL_NO_ERROR();
2479 // Red channel: width of level 1 of texture A: 32.
2480 // Green channel: width of level 3 of texture B: 16.
2481 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2482}
2483
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002484// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2485// ES 3.0.4 table 3.24
2486TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2487{
2488 glActiveTexture(GL_TEXTURE0);
2489 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2490 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2491 EXPECT_GL_NO_ERROR();
2492
2493 drawQuad(mProgram, "position", 0.5f);
2494
2495 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2496}
2497
2498// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2499// ES 3.0.4 table 3.24
2500TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
2501{
2502 glActiveTexture(GL_TEXTURE0);
2503 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2504 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2505 EXPECT_GL_NO_ERROR();
2506
2507 drawQuad(mProgram, "position", 0.5f);
2508
2509 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2510}
2511
2512// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2513// ES 3.0.4 table 3.24
2514TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
2515{
2516 if (extensionEnabled("GL_OES_texture_float"))
2517 {
2518 glActiveTexture(GL_TEXTURE0);
2519 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2520 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
2521 EXPECT_GL_NO_ERROR();
2522
2523 drawQuad(mProgram, "position", 0.5f);
2524
2525 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2526 }
2527}
2528
2529// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2530// ES 3.0.4 table 3.24
2531TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
2532{
2533 if (extensionEnabled("GL_OES_texture_half_float"))
2534 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002535 if (IsNVIDIA() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002536 {
2537 std::cout << "Test skipped on NVIDIA" << std::endl;
2538 return;
2539 }
2540 glActiveTexture(GL_TEXTURE0);
2541 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2542 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
2543 nullptr);
2544 EXPECT_GL_NO_ERROR();
2545
2546 drawQuad(mProgram, "position", 0.5f);
2547
2548 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2549 }
2550}
2551
2552// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2553// ES 3.0.4 table 3.24
2554TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
2555{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002556 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002557 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002558 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002559 return;
2560 }
2561 glActiveTexture(GL_TEXTURE0);
2562 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2563 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
2564 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2566 EXPECT_GL_NO_ERROR();
2567
2568 drawQuad(mProgram, "position", 0.5f);
2569
2570 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2571}
2572
2573// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2574// ES 3.0.4 table 3.24
2575TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
2576{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002577 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002578 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002579 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002580 return;
2581 }
2582 glActiveTexture(GL_TEXTURE0);
2583 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2584
2585 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
2586 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2587 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2588 EXPECT_GL_NO_ERROR();
2589
2590 drawQuad(mProgram, "position", 0.5f);
2591
2592 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2593}
2594
2595// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2596// ES 3.0.4 table 3.24
2597TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
2598{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002599 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002600 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002601 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002602 return;
2603 }
2604 glActiveTexture(GL_TEXTURE0);
2605 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2606 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
2607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2609 EXPECT_GL_NO_ERROR();
2610
2611 drawQuad(mProgram, "position", 0.5f);
2612
2613 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2614}
2615
2616// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2617// ES 3.0.4 table 3.24
2618TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
2619{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002620 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002621 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002622 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002623 return;
2624 }
2625 glActiveTexture(GL_TEXTURE0);
2626 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2627 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
2628 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2629 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2630 EXPECT_GL_NO_ERROR();
2631
2632 drawQuad(mProgram, "position", 0.5f);
2633
2634 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2635}
2636
2637// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2638// ES 3.0.4 table 3.24
2639TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
2640{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002641 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002642 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002643 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002644 return;
2645 }
2646 glActiveTexture(GL_TEXTURE0);
2647 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2648 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
2649 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2650 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2651 EXPECT_GL_NO_ERROR();
2652
2653 drawQuad(mProgram, "position", 0.5f);
2654
2655 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2656}
2657
2658// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2659// ES 3.0.4 table 3.24
2660TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
2661{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002662 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002663 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002664 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002665 return;
2666 }
2667 glActiveTexture(GL_TEXTURE0);
2668 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2669 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
2670 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2671 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2672 EXPECT_GL_NO_ERROR();
2673
2674 drawQuad(mProgram, "position", 0.5f);
2675
2676 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2677}
2678
2679// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2680// ES 3.0.4 table 3.24
2681TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
2682{
2683 glActiveTexture(GL_TEXTURE0);
2684 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2685 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
2686 EXPECT_GL_NO_ERROR();
2687
2688 drawQuad(mProgram, "position", 0.5f);
2689
2690 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2691}
2692
2693// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2694// ES 3.0.4 table 3.24
2695TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
2696{
2697 glActiveTexture(GL_TEXTURE0);
2698 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2699 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
2700 nullptr);
2701 EXPECT_GL_NO_ERROR();
2702
2703 drawQuad(mProgram, "position", 0.5f);
2704
2705 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2706}
2707
2708// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2709// ES 3.0.4 table 3.24
2710TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
2711{
2712 glActiveTexture(GL_TEXTURE0);
2713 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2714 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
2715 EXPECT_GL_NO_ERROR();
2716
2717 drawQuad(mProgram, "position", 0.5f);
2718
2719 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2720}
2721
2722// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2723// ES 3.0.4 table 3.24
2724TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
2725{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002726 if (IsIntel() && IsLinux())
2727 {
2728 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2729 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2730 return;
2731 }
2732
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002733 glActiveTexture(GL_TEXTURE0);
2734 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2735 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2736 EXPECT_GL_NO_ERROR();
2737
2738 drawQuad(mProgram, "position", 0.5f);
2739
2740 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2741}
2742
Olli Etuaho96963162016-03-21 11:54:33 +02002743// Use a sampler in a uniform struct.
2744TEST_P(SamplerInStructTest, SamplerInStruct)
2745{
2746 runSamplerInStructTest();
2747}
2748
2749// Use a sampler in a uniform struct that's passed as a function parameter.
2750TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2751{
2752 runSamplerInStructTest();
2753}
2754
2755// Use a sampler in a uniform struct array with a struct from the array passed as a function
2756// parameter.
2757TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2758{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002759 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2760 {
2761 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2762 return;
2763 }
Olli Etuaho96963162016-03-21 11:54:33 +02002764 runSamplerInStructTest();
2765}
2766
2767// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2768// parameter.
2769TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2770{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002771 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2772 {
2773 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2774 return;
2775 }
Olli Etuaho96963162016-03-21 11:54:33 +02002776 runSamplerInStructTest();
2777}
2778
2779// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2780// similarly named uniform.
2781TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2782{
2783 runSamplerInStructTest();
2784}
2785
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002786class TextureLimitsTest : public ANGLETest
2787{
2788 protected:
2789 struct RGBA8
2790 {
2791 uint8_t R, G, B, A;
2792 };
2793
2794 TextureLimitsTest()
2795 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2796 {
2797 setWindowWidth(128);
2798 setWindowHeight(128);
2799 setConfigRedBits(8);
2800 setConfigGreenBits(8);
2801 setConfigBlueBits(8);
2802 setConfigAlphaBits(8);
2803 }
2804
2805 ~TextureLimitsTest()
2806 {
2807 if (mProgram != 0)
2808 {
2809 glDeleteProgram(mProgram);
2810 mProgram = 0;
2811
2812 if (!mTextures.empty())
2813 {
2814 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2815 }
2816 }
2817 }
2818
2819 void SetUp() override
2820 {
2821 ANGLETest::SetUp();
2822
2823 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2824 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2825 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2826
2827 ASSERT_GL_NO_ERROR();
2828 }
2829
2830 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2831 GLint vertexTextureCount,
2832 GLint vertexActiveTextureCount,
2833 const std::string &fragPrefix,
2834 GLint fragmentTextureCount,
2835 GLint fragmentActiveTextureCount)
2836 {
2837 std::stringstream vertexShaderStr;
2838 vertexShaderStr << "attribute vec2 position;\n"
2839 << "varying vec4 color;\n"
2840 << "varying vec2 texCoord;\n";
2841
2842 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2843 {
2844 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2845 }
2846
2847 vertexShaderStr << "void main() {\n"
2848 << " gl_Position = vec4(position, 0, 1);\n"
2849 << " texCoord = (position * 0.5) + 0.5;\n"
2850 << " color = vec4(0);\n";
2851
2852 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2853 {
2854 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2855 << ", texCoord);\n";
2856 }
2857
2858 vertexShaderStr << "}";
2859
2860 std::stringstream fragmentShaderStr;
2861 fragmentShaderStr << "varying mediump vec4 color;\n"
2862 << "varying mediump vec2 texCoord;\n";
2863
2864 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2865 {
2866 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2867 }
2868
2869 fragmentShaderStr << "void main() {\n"
2870 << " gl_FragColor = color;\n";
2871
2872 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2873 {
2874 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2875 << ", texCoord);\n";
2876 }
2877
2878 fragmentShaderStr << "}";
2879
2880 const std::string &vertexShaderSource = vertexShaderStr.str();
2881 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2882
2883 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2884 }
2885
2886 RGBA8 getPixel(GLint texIndex)
2887 {
2888 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2889 0, 255u};
2890 return pixel;
2891 }
2892
2893 void initTextures(GLint tex2DCount, GLint texCubeCount)
2894 {
2895 GLint totalCount = tex2DCount + texCubeCount;
2896 mTextures.assign(totalCount, 0);
2897 glGenTextures(totalCount, &mTextures[0]);
2898 ASSERT_GL_NO_ERROR();
2899
2900 std::vector<RGBA8> texData(16 * 16);
2901
2902 GLint texIndex = 0;
2903 for (; texIndex < tex2DCount; ++texIndex)
2904 {
2905 texData.assign(texData.size(), getPixel(texIndex));
2906 glActiveTexture(GL_TEXTURE0 + texIndex);
2907 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2908 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2909 &texData[0]);
2910 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2911 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2912 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2913 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2914 }
2915
2916 ASSERT_GL_NO_ERROR();
2917
2918 for (; texIndex < texCubeCount; ++texIndex)
2919 {
2920 texData.assign(texData.size(), getPixel(texIndex));
2921 glActiveTexture(GL_TEXTURE0 + texIndex);
2922 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2923 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2924 GL_UNSIGNED_BYTE, &texData[0]);
2925 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2926 GL_UNSIGNED_BYTE, &texData[0]);
2927 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2928 GL_UNSIGNED_BYTE, &texData[0]);
2929 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2930 GL_UNSIGNED_BYTE, &texData[0]);
2931 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2932 GL_UNSIGNED_BYTE, &texData[0]);
2933 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2934 GL_UNSIGNED_BYTE, &texData[0]);
2935 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2936 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2937 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2938 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2939 }
2940
2941 ASSERT_GL_NO_ERROR();
2942 }
2943
2944 void testWithTextures(GLint vertexTextureCount,
2945 const std::string &vertexTexturePrefix,
2946 GLint fragmentTextureCount,
2947 const std::string &fragmentTexturePrefix)
2948 {
2949 // Generate textures
2950 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2951
2952 glUseProgram(mProgram);
2953 RGBA8 expectedSum = {0};
2954 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2955 {
2956 std::stringstream uniformNameStr;
2957 uniformNameStr << vertexTexturePrefix << texIndex;
2958 const std::string &uniformName = uniformNameStr.str();
2959 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2960 ASSERT_NE(-1, location);
2961
2962 glUniform1i(location, texIndex);
2963 RGBA8 contribution = getPixel(texIndex);
2964 expectedSum.R += contribution.R;
2965 expectedSum.G += contribution.G;
2966 }
2967
2968 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2969 {
2970 std::stringstream uniformNameStr;
2971 uniformNameStr << fragmentTexturePrefix << texIndex;
2972 const std::string &uniformName = uniformNameStr.str();
2973 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2974 ASSERT_NE(-1, location);
2975
2976 glUniform1i(location, texIndex + vertexTextureCount);
2977 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
2978 expectedSum.R += contribution.R;
2979 expectedSum.G += contribution.G;
2980 }
2981
2982 ASSERT_GE(256u, expectedSum.G);
2983
2984 drawQuad(mProgram, "position", 0.5f);
2985 ASSERT_GL_NO_ERROR();
2986 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
2987 }
2988
2989 GLuint mProgram;
2990 std::vector<GLuint> mTextures;
2991 GLint mMaxVertexTextures;
2992 GLint mMaxFragmentTextures;
2993 GLint mMaxCombinedTextures;
2994};
2995
2996// Test rendering with the maximum vertex texture units.
2997TEST_P(TextureLimitsTest, MaxVertexTextures)
2998{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04002999 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003000 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003001 {
3002 std::cout << "Test skipped on Intel." << std::endl;
3003 return;
3004 }
3005
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003006 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
3007 ASSERT_NE(0u, mProgram);
3008 ASSERT_GL_NO_ERROR();
3009
3010 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3011}
3012
3013// Test rendering with the maximum fragment texture units.
3014TEST_P(TextureLimitsTest, MaxFragmentTextures)
3015{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003016 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003017 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003018 {
3019 std::cout << "Test skipped on Intel." << std::endl;
3020 return;
3021 }
3022
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003023 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
3024 ASSERT_NE(0u, mProgram);
3025 ASSERT_GL_NO_ERROR();
3026
3027 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
3028}
3029
3030// Test rendering with maximum combined texture units.
3031TEST_P(TextureLimitsTest, MaxCombinedTextures)
3032{
Jamie Madill412f17d2015-09-25 08:43:54 -04003033 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003034 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04003035 {
3036 std::cout << "Test skipped on Intel." << std::endl;
3037 return;
3038 }
3039
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003040 GLint vertexTextures = mMaxVertexTextures;
3041
3042 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
3043 {
3044 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
3045 }
3046
3047 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
3048 mMaxFragmentTextures, mMaxFragmentTextures);
3049 ASSERT_NE(0u, mProgram);
3050 ASSERT_GL_NO_ERROR();
3051
3052 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
3053}
3054
3055// Negative test for exceeding the number of vertex textures
3056TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
3057{
3058 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
3059 0);
3060 ASSERT_EQ(0u, mProgram);
3061}
3062
3063// Negative test for exceeding the number of fragment textures
3064TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
3065{
3066 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
3067 mMaxFragmentTextures + 1);
3068 ASSERT_EQ(0u, mProgram);
3069}
3070
3071// Test active vertex textures under the limit, but excessive textures specified.
3072TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
3073{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003074 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003075 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003076 {
3077 std::cout << "Test skipped on Intel." << std::endl;
3078 return;
3079 }
3080
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003081 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
3082 ASSERT_NE(0u, mProgram);
3083 ASSERT_GL_NO_ERROR();
3084
3085 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3086}
3087
3088// Test active fragment textures under the limit, but excessive textures specified.
3089TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
3090{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003091 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003092 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003093 {
3094 std::cout << "Test skipped on Intel." << std::endl;
3095 return;
3096 }
3097
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003098 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
3099 mMaxFragmentTextures);
3100 ASSERT_NE(0u, mProgram);
3101 ASSERT_GL_NO_ERROR();
3102
3103 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
3104}
3105
3106// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003107// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003108TEST_P(TextureLimitsTest, TextureTypeConflict)
3109{
3110 const std::string &vertexShader =
3111 "attribute vec2 position;\n"
3112 "varying float color;\n"
3113 "uniform sampler2D tex2D;\n"
3114 "uniform samplerCube texCube;\n"
3115 "void main() {\n"
3116 " gl_Position = vec4(position, 0, 1);\n"
3117 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3118 " color = texture2D(tex2D, texCoord).x;\n"
3119 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
3120 "}";
3121 const std::string &fragmentShader =
3122 "varying mediump float color;\n"
3123 "void main() {\n"
3124 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3125 "}";
3126
3127 mProgram = CompileProgram(vertexShader, fragmentShader);
3128 ASSERT_NE(0u, mProgram);
3129
3130 initTextures(1, 0);
3131
3132 glUseProgram(mProgram);
3133 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3134 ASSERT_NE(-1, tex2DLocation);
3135 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
3136 ASSERT_NE(-1, texCubeLocation);
3137
3138 glUniform1i(tex2DLocation, 0);
3139 glUniform1i(texCubeLocation, 0);
3140 ASSERT_GL_NO_ERROR();
3141
3142 drawQuad(mProgram, "position", 0.5f);
3143 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3144}
3145
3146// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003147// TODO(jmadill): Possibly adjust the test according to the spec:
3148// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
3149// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003150TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
3151{
3152 const std::string &vertexShader =
3153 "attribute vec2 position;\n"
3154 "varying float color;\n"
3155 "uniform sampler2D tex2D;\n"
3156 "void main() {\n"
3157 " gl_Position = vec4(position, 0, 1);\n"
3158 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3159 " color = texture2D(tex2D, texCoord).x;\n"
3160 "}";
3161 const std::string &fragmentShader =
3162 "varying mediump float color;\n"
3163 "void main() {\n"
3164 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3165 "}";
3166
3167 mProgram = CompileProgram(vertexShader, fragmentShader);
3168 ASSERT_NE(0u, mProgram);
3169
3170 glUseProgram(mProgram);
3171 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3172 ASSERT_NE(-1, tex2DLocation);
3173
3174 glUniform1i(tex2DLocation, mMaxCombinedTextures);
3175 ASSERT_GL_NO_ERROR();
3176
3177 drawQuad(mProgram, "position", 0.5f);
3178 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3179}
3180
Vincent Lang25ab4512016-05-13 18:13:59 +02003181class Texture2DNorm16TestES3 : public Texture2DTestES3
3182{
3183 protected:
3184 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
3185
3186 void SetUp() override
3187 {
3188 Texture2DTestES3::SetUp();
3189
3190 glActiveTexture(GL_TEXTURE0);
3191 glGenTextures(3, mTextures);
3192 glGenFramebuffers(1, &mFBO);
3193 glGenRenderbuffers(1, &mRenderbuffer);
3194
3195 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
3196 {
3197 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
3198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3199 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3200 }
3201
3202 glBindTexture(GL_TEXTURE_2D, 0);
3203
3204 ASSERT_GL_NO_ERROR();
3205 }
3206
3207 void TearDown() override
3208 {
3209 glDeleteTextures(3, mTextures);
3210 glDeleteFramebuffers(1, &mFBO);
3211 glDeleteRenderbuffers(1, &mRenderbuffer);
3212
3213 Texture2DTestES3::TearDown();
3214 }
3215
3216 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
3217 {
3218 GLushort pixelValue = type == GL_SHORT ? 0x7FFF : 0x6A35;
3219 GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
3220
3221 setUpProgram();
3222
3223 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
3224 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
3225 0);
3226
3227 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
3228 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
3229
3230 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
3231 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
3232
3233 EXPECT_GL_NO_ERROR();
3234
3235 drawQuad(mProgram, "position", 0.5f);
3236
3237 GLColor16 expectedValue = imageData;
3238 if (type == GL_SHORT)
3239 {
3240 // sampled as signed value; then stored as unsigned value
3241 expectedValue = GLColor16::white;
3242 }
3243
3244 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
3245
3246 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3247
3248 ASSERT_GL_NO_ERROR();
3249 }
3250
3251 void testNorm16Render(GLint internalformat, GLenum format, GLenum type)
3252 {
3253 GLushort pixelValue = 0x6A35;
3254 GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
3255
3256 setUpProgram();
3257
3258 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
3259 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, nullptr);
3260
3261 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
3262 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
3263 0);
3264
3265 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
3266 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
3267
3268 EXPECT_GL_NO_ERROR();
3269
3270 drawQuad(mProgram, "position", 0.5f);
3271
3272 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, imageData));
3273
3274 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
3275 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
3276 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3277 mRenderbuffer);
3278 glBindRenderbuffer(GL_RENDERBUFFER, 0);
3279 EXPECT_GL_NO_ERROR();
3280
3281 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
3282 glClear(GL_COLOR_BUFFER_BIT);
3283
3284 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
3285
3286 GLColor16 expectedValue = GLColor16::white;
3287 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
3288
3289 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3290
3291 ASSERT_GL_NO_ERROR();
3292 }
3293
3294 GLuint mTextures[3];
3295 GLuint mFBO;
3296 GLuint mRenderbuffer;
3297};
3298
3299// Test texture formats enabled by the GL_EXT_texture_norm16 extension.
3300TEST_P(Texture2DNorm16TestES3, TextureNorm16Test)
3301{
3302 if (!extensionEnabled("GL_EXT_texture_norm16"))
3303 {
3304 std::cout << "Test skipped due to missing GL_EXT_texture_norm16." << std::endl;
3305 return;
3306 }
3307
3308 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
3309 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
3310 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
3311 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
3312 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
3313 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
3314 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
3315 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
3316
3317 testNorm16Render(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
3318 testNorm16Render(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
3319 testNorm16Render(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
3320}
3321
Olli Etuaho95faa232016-06-07 14:01:53 -07003322// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
3323// GLES 3.0.4 section 3.8.3.
3324TEST_P(Texture2DTestES3, UnpackSkipImages2D)
3325{
3326 if (IsIntel() && isOpenGL())
3327 {
3328 std::cout << "Test skipped on Intel OpenGL." << std::endl;
3329 return;
3330 }
3331
3332 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3333 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3334 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3335 ASSERT_GL_NO_ERROR();
3336
3337 // SKIP_IMAGES should not have an effect on uploading 2D textures
3338 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
3339 ASSERT_GL_NO_ERROR();
3340
3341 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
3342
3343 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3344 pixelsGreen.data());
3345 ASSERT_GL_NO_ERROR();
3346
3347 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
3348 pixelsGreen.data());
3349 ASSERT_GL_NO_ERROR();
3350
3351 glUseProgram(mProgram);
3352 drawQuad(mProgram, "position", 0.5f);
3353 ASSERT_GL_NO_ERROR();
3354
3355 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3356}
3357
Olli Etuaho989cac32016-06-08 16:18:49 -07003358// Test that skip defined in unpack parameters is taken into account when determining whether
3359// unpacking source extends outside unpack buffer bounds.
3360TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
3361{
3362 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3365 ASSERT_GL_NO_ERROR();
3366
3367 GLBuffer buf;
3368 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
3369 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
3370 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
3371 GL_DYNAMIC_COPY);
3372 ASSERT_GL_NO_ERROR();
3373
3374 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3375 ASSERT_GL_NO_ERROR();
3376
3377 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
3378 ASSERT_GL_NO_ERROR();
3379
3380 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3381 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3382
3383 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3384 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
3385 ASSERT_GL_NO_ERROR();
3386
3387 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3388 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3389}
3390
Jamie Madillfa05f602015-05-07 13:47:11 -04003391// 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 +02003392// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05003393ANGLE_INSTANTIATE_TEST(Texture2DTest,
3394 ES2_D3D9(),
3395 ES2_D3D11(),
3396 ES2_D3D11_FL9_3(),
3397 ES2_OPENGL(),
3398 ES2_OPENGLES());
3399ANGLE_INSTANTIATE_TEST(TextureCubeTest,
3400 ES2_D3D9(),
3401 ES2_D3D11(),
3402 ES2_D3D11_FL9_3(),
3403 ES2_OPENGL(),
3404 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003405ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
3406 ES2_D3D9(),
3407 ES2_D3D11(),
3408 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003409 ES2_OPENGL(),
3410 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003411ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
3412 ES2_D3D9(),
3413 ES2_D3D11(),
3414 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003415 ES2_OPENGL(),
3416 ES2_OPENGLES());
3417ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
3418 ES2_D3D9(),
3419 ES2_D3D11(),
3420 ES2_D3D11_FL9_3(),
3421 ES2_OPENGL(),
3422 ES2_OPENGLES());
3423ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
3424 ES2_D3D9(),
3425 ES2_D3D11(),
3426 ES2_D3D11_FL9_3(),
3427 ES2_OPENGL(),
3428 ES2_OPENGLES());
3429ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahoa314b612016-03-10 16:43:00 +02003430ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003431ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3432ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
3433 ES3_D3D11(),
3434 ES3_OPENGL(),
3435 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003436ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
3437 ES3_D3D11(),
3438 ES3_OPENGL(),
3439 ES3_OPENGLES());
3440ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3441ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02003442ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02003443ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
3444 ES2_D3D11(),
3445 ES2_D3D11_FL9_3(),
3446 ES2_D3D9(),
3447 ES2_OPENGL(),
3448 ES2_OPENGLES());
3449ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
3450 ES2_D3D11(),
3451 ES2_D3D11_FL9_3(),
3452 ES2_D3D9(),
3453 ES2_OPENGL(),
3454 ES2_OPENGLES());
3455ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
3456 ES2_D3D11(),
3457 ES2_D3D11_FL9_3(),
3458 ES2_D3D9(),
3459 ES2_OPENGL(),
3460 ES2_OPENGLES());
3461ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
3462 ES2_D3D11(),
3463 ES2_D3D11_FL9_3(),
3464 ES2_D3D9(),
3465 ES2_OPENGL(),
3466 ES2_OPENGLES());
3467ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
3468 ES2_D3D11(),
3469 ES2_D3D11_FL9_3(),
3470 ES2_D3D9(),
3471 ES2_OPENGL(),
3472 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003473ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Vincent Lang25ab4512016-05-13 18:13:59 +02003474ANGLE_INSTANTIATE_TEST(Texture2DNorm16TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04003475
3476} // namespace