blob: 25953596173c3fe397b0a84545c1f729c644d7ae [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04007#include <cmath>
8
Corentin Wallezd3970de2015-05-14 11:07:48 -04009#include "test_utils/ANGLETest.h"
Olli Etuaho989cac32016-06-08 16:18:49 -070010#include "test_utils/gl_raii.h"
Jamie Madillf67115c2014-04-22 13:14:05 -040011
Jamie Madillfa05f602015-05-07 13:47:11 -040012using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070013
Jamie Madillfa05f602015-05-07 13:47:11 -040014namespace
15{
16
Vincent Lang25ab4512016-05-13 18:13:59 +020017// Take a pixel, and reset the components not covered by the format to default
18// values. In particular, the default value for the alpha component is 65535
19// (1.0 as unsigned normalized fixed point value).
20GLColor16 SliceFormatColor16(GLenum format, GLColor16 full)
21{
22 switch (format)
23 {
24 case GL_RED:
25 return GLColor16(full.R, 0, 0, 65535u);
26 case GL_RG:
27 return GLColor16(full.R, full.G, 0, 65535u);
28 case GL_RGB:
29 return GLColor16(full.R, full.G, full.B, 65535u);
30 case GL_RGBA:
31 return full;
32 default:
33 UNREACHABLE();
34 }
35 return GLColor16::white;
36}
37
Olli Etuaho4a8329f2016-01-11 17:12:57 +020038class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -040039{
Jamie Madillbc393df2015-01-29 13:46:07 -050040 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020041 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -040042 {
43 setWindowWidth(128);
44 setWindowHeight(128);
45 setConfigRedBits(8);
46 setConfigGreenBits(8);
47 setConfigBlueBits(8);
48 setConfigAlphaBits(8);
49 }
50
Olli Etuaho4a8329f2016-01-11 17:12:57 +020051 virtual std::string getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -040052 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020053 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -040054 (
55 precision highp float;
56 attribute vec4 position;
57 varying vec2 texcoord;
58
59 void main()
60 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020061 gl_Position = vec4(position.xy, 0.0, 1.0);
Geoff Langc41e42d2014-04-28 10:58:16 -040062 texcoord = (position.xy * 0.5) + 0.5;
63 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +020064 )
Geoff Langc41e42d2014-04-28 10:58:16 -040065 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +020066 }
Geoff Langc41e42d2014-04-28 10:58:16 -040067
Olli Etuaho4a8329f2016-01-11 17:12:57 +020068 virtual std::string getFragmentShaderSource() = 0;
69
Olli Etuahoa1c917f2016-04-06 13:50:03 +030070 virtual void setUpProgram()
Olli Etuaho4a8329f2016-01-11 17:12:57 +020071 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +020072 const std::string vertexShaderSource = getVertexShaderSource();
73 const std::string fragmentShaderSource = getFragmentShaderSource();
74
75 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
76 ASSERT_NE(0u, mProgram);
77 ASSERT_GL_NO_ERROR();
Olli Etuahoa1c917f2016-04-06 13:50:03 +030078 }
79
80 void SetUp() override
81 {
82 ANGLETest::SetUp();
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020083
84 setUpFramebuffer();
Olli Etuaho4a8329f2016-01-11 17:12:57 +020085 }
86
87 void TearDown() override
88 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020089 glBindFramebuffer(GL_FRAMEBUFFER, 0);
90 glDeleteFramebuffers(1, &mFramebuffer);
91 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +020092 glDeleteProgram(mProgram);
93 ANGLETest::TearDown();
94 }
95
Olli Etuaho51f1c0f2016-01-13 16:16:24 +020096 void setUpFramebuffer()
97 {
98 // We use an FBO to work around an issue where the default framebuffer applies SRGB
99 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
100 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
101 // section 4.4 says that the format of the default framebuffer is entirely up to the window
102 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
103 // SRGB conversion like desktop GL does.
104 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
105 glGenFramebuffers(1, &mFramebuffer);
106 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
107
108 glGenTextures(1, &mFramebufferColorTexture);
109 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
110 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
111 GL_UNSIGNED_BYTE, nullptr);
112 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
113 mFramebufferColorTexture, 0);
114 ASSERT_GL_NO_ERROR();
115 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
116 glBindTexture(GL_TEXTURE_2D, 0);
117 }
118
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200119 // Returns the created texture ID.
120 GLuint create2DTexture()
121 {
122 GLuint texture2D;
123 glGenTextures(1, &texture2D);
124 glBindTexture(GL_TEXTURE_2D, texture2D);
125 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
126 EXPECT_GL_NO_ERROR();
127 return texture2D;
128 }
129
130 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200131 GLuint mFramebuffer;
132
133 private:
134 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200135};
136
137class Texture2DTest : public TexCoordDrawTest
138{
139 protected:
140 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
141
142 std::string getFragmentShaderSource() override
143 {
144 return std::string(SHADER_SOURCE
Geoff Langc41e42d2014-04-28 10:58:16 -0400145 (
146 precision highp float;
147 uniform sampler2D tex;
148 varying vec2 texcoord;
149
150 void main()
151 {
152 gl_FragColor = texture2D(tex, texcoord);
153 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200154 )
Geoff Langc41e42d2014-04-28 10:58:16 -0400155 );
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200156 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400157
Olli Etuaho96963162016-03-21 11:54:33 +0200158 virtual const char *getTextureUniformName() { return "tex"; }
159
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300160 void setUpProgram() override
161 {
162 TexCoordDrawTest::setUpProgram();
163 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
164 ASSERT_NE(-1, mTexture2DUniformLocation);
165 }
166
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200167 void SetUp() override
168 {
169 TexCoordDrawTest::SetUp();
170 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400171
Jamie Madill9aca0592014-10-06 16:26:59 -0400172 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -0400173 }
174
Jamie Madillfa05f602015-05-07 13:47:11 -0400175 void TearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400176 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400177 glDeleteTextures(1, &mTexture2D);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200178 TexCoordDrawTest::TearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400179 }
180
Jamie Madillbc393df2015-01-29 13:46:07 -0500181 // Tests CopyTexSubImage with floating point textures of various formats.
182 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
183 {
Geoff Langbde666a2015-04-07 17:17:08 -0400184 // TODO(jmadill): Figure out why this is broken on Intel D3D11
Jamie Madill518b9fa2016-03-02 11:26:02 -0500185 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Geoff Langbde666a2015-04-07 17:17:08 -0400186 {
187 std::cout << "Test skipped on Intel D3D11." << std::endl;
188 return;
189 }
190
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300191 setUpProgram();
192
Martin Radev1be913c2016-07-11 17:59:16 +0300193 if (getClientMajorVersion() < 3)
Geoff Langfbfa47c2015-03-31 11:26:00 -0400194 {
195 if (!extensionEnabled("GL_OES_texture_float"))
196 {
197 std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl;
198 return;
199 }
200
201 if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg"))
202 {
203 std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl;
204 return;
205 }
206 }
207
Jamie Madillbc393df2015-01-29 13:46:07 -0500208 GLfloat sourceImageData[4][16] =
209 {
210 { // R
211 1.0f,
212 0.0f,
213 0.0f,
214 1.0f
215 },
216 { // RG
217 1.0f, 0.0f,
218 0.0f, 1.0f,
219 0.0f, 0.0f,
220 1.0f, 1.0f
221 },
222 { // RGB
223 1.0f, 0.0f, 0.0f,
224 0.0f, 1.0f, 0.0f,
225 0.0f, 0.0f, 1.0f,
226 1.0f, 1.0f, 0.0f
227 },
228 { // RGBA
229 1.0f, 0.0f, 0.0f, 1.0f,
230 0.0f, 1.0f, 0.0f, 1.0f,
231 0.0f, 0.0f, 1.0f, 1.0f,
232 1.0f, 1.0f, 0.0f, 1.0f
233 },
234 };
235
236 GLenum imageFormats[] =
237 {
238 GL_R32F,
239 GL_RG32F,
240 GL_RGB32F,
241 GL_RGBA32F,
242 };
243
244 GLenum sourceUnsizedFormats[] =
245 {
246 GL_RED,
247 GL_RG,
248 GL_RGB,
249 GL_RGBA,
250 };
251
252 GLuint textures[2];
253
254 glGenTextures(2, textures);
255
256 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
257 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
258 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
259 GLenum destImageFormat = imageFormats[destImageChannels - 1];
260
261 glBindTexture(GL_TEXTURE_2D, textures[0]);
262 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
265 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
266
hendrikwb27f79a2015-03-04 11:26:46 -0800267 if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500268 {
269 // This is not supported
270 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
271 }
272 else
273 {
274 ASSERT_GL_NO_ERROR();
275 }
276
277 GLuint fbo;
278 glGenFramebuffers(1, &fbo);
279 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
280 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
281
282 glBindTexture(GL_TEXTURE_2D, textures[1]);
283 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
284 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
285 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
286
287 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
288 ASSERT_GL_NO_ERROR();
289
290 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200291 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500292
293 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
294
Olli Etuahoa314b612016-03-10 16:43:00 +0200295 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Jamie Madillbc393df2015-01-29 13:46:07 -0500296 if (testImageChannels > 1)
297 {
298 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
299 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
300 if (testImageChannels > 2)
301 {
302 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
303 }
304 }
305
306 glDeleteFramebuffers(1, &fbo);
307 glDeleteTextures(2, textures);
308
309 ASSERT_GL_NO_ERROR();
310 }
311
Jamie Madilld4cfa572014-07-08 10:00:32 -0400312 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400313 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400314};
315
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200316class Texture2DTestES3 : public Texture2DTest
317{
318 protected:
319 Texture2DTestES3() : Texture2DTest() {}
320
321 std::string getVertexShaderSource() override
322 {
323 return std::string(
324 "#version 300 es\n"
325 "out vec2 texcoord;\n"
326 "in vec4 position;\n"
327 "void main()\n"
328 "{\n"
329 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
330 " texcoord = (position.xy * 0.5) + 0.5;\n"
331 "}\n");
332 }
333
334 std::string getFragmentShaderSource() override
335 {
336 return std::string(
337 "#version 300 es\n"
338 "precision highp float;\n"
339 "uniform highp sampler2D tex;\n"
340 "in vec2 texcoord;\n"
341 "out vec4 fragColor;\n"
342 "void main()\n"
343 "{\n"
344 " fragColor = texture(tex, texcoord);\n"
345 "}\n");
346 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300347
348 void SetUp() override
349 {
350 Texture2DTest::SetUp();
351 setUpProgram();
352 }
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200353};
354
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200355class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
356{
357 protected:
358 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
359
360 std::string getVertexShaderSource() override
361 {
362 return std::string(
363 "#version 300 es\n"
364 "out vec2 texcoord;\n"
365 "in vec4 position;\n"
366 "void main()\n"
367 "{\n"
368 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
369 " texcoord = (position.xy * 0.5) + 0.5;\n"
370 "}\n");
371 }
372
373 std::string getFragmentShaderSource() override
374 {
375 return std::string(
376 "#version 300 es\n"
377 "precision highp float;\n"
378 "uniform highp isampler2D tex;\n"
379 "in vec2 texcoord;\n"
380 "out vec4 fragColor;\n"
381 "void main()\n"
382 "{\n"
383 " vec4 green = vec4(0, 1, 0, 1);\n"
384 " vec4 black = vec4(0, 0, 0, 0);\n"
385 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
386 "}\n");
387 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300388
389 void SetUp() override
390 {
391 Texture2DTest::SetUp();
392 setUpProgram();
393 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200394};
395
396class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
397{
398 protected:
399 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
400
401 std::string getVertexShaderSource() override
402 {
403 return std::string(
404 "#version 300 es\n"
405 "out vec2 texcoord;\n"
406 "in vec4 position;\n"
407 "void main()\n"
408 "{\n"
409 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
410 " texcoord = (position.xy * 0.5) + 0.5;\n"
411 "}\n");
412 }
413
414 std::string getFragmentShaderSource() override
415 {
416 return std::string(
417 "#version 300 es\n"
418 "precision highp float;\n"
419 "uniform highp usampler2D tex;\n"
420 "in vec2 texcoord;\n"
421 "out vec4 fragColor;\n"
422 "void main()\n"
423 "{\n"
424 " vec4 green = vec4(0, 1, 0, 1);\n"
425 " vec4 black = vec4(0, 0, 0, 0);\n"
426 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
427 "}\n");
428 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300429
430 void SetUp() override
431 {
432 Texture2DTest::SetUp();
433 setUpProgram();
434 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200435};
436
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200437class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400438{
439 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200440 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
441
442 std::string getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400443 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200444 return std::string(SHADER_SOURCE
445 (
446 precision highp float;
447 attribute vec4 position;
448 varying vec2 texcoord;
449
450 uniform vec2 drawScale;
451
452 void main()
453 {
454 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
455 texcoord = (position.xy * 0.5) + 0.5;
456 }
457 )
458 );
Jamie Madill2453dbc2015-07-14 11:35:42 -0400459 }
460
461 void SetUp() override
462 {
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200463 Texture2DTest::SetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300464
465 setUpProgram();
466
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200467 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
468 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400469
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200470 glUseProgram(mProgram);
471 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
472 glUseProgram(0);
473 ASSERT_GL_NO_ERROR();
474 }
475
476 GLint mDrawScaleUniformLocation;
477};
478
Olli Etuaho4644a202016-01-12 15:12:53 +0200479class Sampler2DAsFunctionParameterTest : public Texture2DTest
480{
481 protected:
482 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
483
484 std::string getFragmentShaderSource() override
485 {
486 return std::string(SHADER_SOURCE
487 (
488 precision highp float;
489 uniform sampler2D tex;
490 varying vec2 texcoord;
491
492 vec4 computeFragColor(sampler2D aTex)
493 {
494 return texture2D(aTex, texcoord);
495 }
496
497 void main()
498 {
499 gl_FragColor = computeFragColor(tex);
500 }
501 )
502 );
503 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300504
505 void SetUp() override
506 {
507 Texture2DTest::SetUp();
508 setUpProgram();
509 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200510};
511
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200512class TextureCubeTest : public TexCoordDrawTest
513{
514 protected:
515 TextureCubeTest()
516 : TexCoordDrawTest(),
517 mTexture2D(0),
518 mTextureCube(0),
519 mTexture2DUniformLocation(-1),
520 mTextureCubeUniformLocation(-1)
521 {
522 }
523
524 std::string getFragmentShaderSource() override
525 {
526 return std::string(SHADER_SOURCE
527 (
528 precision highp float;
529 uniform sampler2D tex2D;
530 uniform samplerCube texCube;
531 varying vec2 texcoord;
532
533 void main()
534 {
535 gl_FragColor = texture2D(tex2D, texcoord);
536 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
537 }
538 )
539 );
540 }
541
542 void SetUp() override
543 {
544 TexCoordDrawTest::SetUp();
545
546 glGenTextures(1, &mTextureCube);
547 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
548 glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
549 EXPECT_GL_NO_ERROR();
550
551 mTexture2D = create2DTexture();
552
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300553 setUpProgram();
554
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200555 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
556 ASSERT_NE(-1, mTexture2DUniformLocation);
557 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
558 ASSERT_NE(-1, mTextureCubeUniformLocation);
559 }
560
561 void TearDown() override
562 {
563 glDeleteTextures(1, &mTextureCube);
564 TexCoordDrawTest::TearDown();
565 }
566
567 GLuint mTexture2D;
568 GLuint mTextureCube;
569 GLint mTexture2DUniformLocation;
570 GLint mTextureCubeUniformLocation;
571};
572
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200573class SamplerArrayTest : public TexCoordDrawTest
574{
575 protected:
576 SamplerArrayTest()
577 : TexCoordDrawTest(),
578 mTexture2DA(0),
579 mTexture2DB(0),
580 mTexture0UniformLocation(-1),
581 mTexture1UniformLocation(-1)
582 {
583 }
584
585 std::string getFragmentShaderSource() override
586 {
587 return std::string(SHADER_SOURCE
588 (
589 precision mediump float;
590 uniform highp sampler2D tex2DArray[2];
591 varying vec2 texcoord;
592 void main()
593 {
594 gl_FragColor = texture2D(tex2DArray[0], texcoord);
595 gl_FragColor += texture2D(tex2DArray[1], texcoord);
596 }
597 )
598 );
599 }
600
601 void SetUp() override
602 {
603 TexCoordDrawTest::SetUp();
604
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300605 setUpProgram();
606
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200607 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
608 ASSERT_NE(-1, mTexture0UniformLocation);
609 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
610 ASSERT_NE(-1, mTexture1UniformLocation);
611
612 mTexture2DA = create2DTexture();
613 mTexture2DB = create2DTexture();
614 ASSERT_GL_NO_ERROR();
615 }
616
617 void TearDown() override
618 {
619 glDeleteTextures(1, &mTexture2DA);
620 glDeleteTextures(1, &mTexture2DB);
621 TexCoordDrawTest::TearDown();
622 }
623
624 void testSamplerArrayDraw()
625 {
626 GLubyte texData[4];
627 texData[0] = 0;
628 texData[1] = 60;
629 texData[2] = 0;
630 texData[3] = 255;
631
632 glActiveTexture(GL_TEXTURE0);
633 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
634 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
635
636 texData[1] = 120;
637 glActiveTexture(GL_TEXTURE1);
638 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
639 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
640 EXPECT_GL_ERROR(GL_NO_ERROR);
641
642 glUseProgram(mProgram);
643 glUniform1i(mTexture0UniformLocation, 0);
644 glUniform1i(mTexture1UniformLocation, 1);
645 drawQuad(mProgram, "position", 0.5f);
646 EXPECT_GL_NO_ERROR();
647
648 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
649 }
650
651 GLuint mTexture2DA;
652 GLuint mTexture2DB;
653 GLint mTexture0UniformLocation;
654 GLint mTexture1UniformLocation;
655};
656
657
658class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
659{
660 protected:
661 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
662
663 std::string getFragmentShaderSource() override
664 {
665 return std::string(SHADER_SOURCE
666 (
667 precision mediump float;
668 uniform highp sampler2D tex2DArray[2];
669 varying vec2 texcoord;
670
671 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
672 {
673 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
674 }
675
676 void main()
677 {
678 gl_FragColor = computeFragColor(tex2DArray);
679 }
680 )
681 );
682 }
683};
684
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200685class Texture2DArrayTestES3 : public TexCoordDrawTest
686{
687 protected:
688 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
689
690 std::string getVertexShaderSource() override
691 {
692 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400693 "#version 300 es\n"
694 "out vec2 texcoord;\n"
695 "in vec4 position;\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200696 "void main()\n"
697 "{\n"
698 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
699 " texcoord = (position.xy * 0.5) + 0.5;\n"
700 "}\n");
701 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400702
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200703 std::string getFragmentShaderSource() override
704 {
705 return std::string(
Jamie Madill2453dbc2015-07-14 11:35:42 -0400706 "#version 300 es\n"
707 "precision highp float;\n"
Olli Etuaho183d7e22015-11-20 15:59:09 +0200708 "uniform highp sampler2DArray tex2DArray;\n"
Jamie Madill2453dbc2015-07-14 11:35:42 -0400709 "in vec2 texcoord;\n"
710 "out vec4 fragColor;\n"
711 "void main()\n"
712 "{\n"
713 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200714 "}\n");
715 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400716
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200717 void SetUp() override
718 {
719 TexCoordDrawTest::SetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400720
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300721 setUpProgram();
722
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200723 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400724 ASSERT_NE(-1, mTextureArrayLocation);
725
726 glGenTextures(1, &m2DArrayTexture);
727 ASSERT_GL_NO_ERROR();
728 }
729
730 void TearDown() override
731 {
732 glDeleteTextures(1, &m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200733 TexCoordDrawTest::TearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400734 }
735
736 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400737 GLint mTextureArrayLocation;
738};
739
Olli Etuahobce743a2016-01-15 17:18:28 +0200740class TextureSizeTextureArrayTest : public TexCoordDrawTest
741{
742 protected:
743 TextureSizeTextureArrayTest()
744 : TexCoordDrawTest(),
745 mTexture2DA(0),
746 mTexture2DB(0),
747 mTexture0Location(-1),
748 mTexture1Location(-1)
749 {
750 }
751
752 std::string getVertexShaderSource() override
753 {
754 return std::string(
755 "#version 300 es\n"
756 "in vec4 position;\n"
757 "void main()\n"
758 "{\n"
759 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
760 "}\n");
761 }
762
763 std::string getFragmentShaderSource() override
764 {
765 return std::string(
766 "#version 300 es\n"
767 "precision highp float;\n"
768 "uniform highp sampler2D tex2DArray[2];\n"
769 "out vec4 fragColor;\n"
770 "void main()\n"
771 "{\n"
772 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
773 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
774 " fragColor = vec4(red, green, 0.0, 1.0);\n"
775 "}\n");
776 }
777
778 void SetUp() override
779 {
780 TexCoordDrawTest::SetUp();
781
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300782 setUpProgram();
783
Olli Etuahobce743a2016-01-15 17:18:28 +0200784 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
785 ASSERT_NE(-1, mTexture0Location);
786 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
787 ASSERT_NE(-1, mTexture1Location);
788
789 mTexture2DA = create2DTexture();
790 mTexture2DB = create2DTexture();
791 ASSERT_GL_NO_ERROR();
792 }
793
794 void TearDown() override
795 {
796 glDeleteTextures(1, &mTexture2DA);
797 glDeleteTextures(1, &mTexture2DB);
798 TexCoordDrawTest::TearDown();
799 }
800
801 GLuint mTexture2DA;
802 GLuint mTexture2DB;
803 GLint mTexture0Location;
804 GLint mTexture1Location;
805};
806
Olli Etuahoa314b612016-03-10 16:43:00 +0200807class Texture3DTestES3 : public TexCoordDrawTest
808{
809 protected:
810 Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
811
812 std::string getVertexShaderSource() override
813 {
814 return std::string(
815 "#version 300 es\n"
816 "out vec2 texcoord;\n"
817 "in vec4 position;\n"
818 "void main()\n"
819 "{\n"
820 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
821 " texcoord = (position.xy * 0.5) + 0.5;\n"
822 "}\n");
823 }
824
825 std::string getFragmentShaderSource() override
826 {
827 return std::string(
828 "#version 300 es\n"
829 "precision highp float;\n"
830 "uniform highp sampler3D tex3D;\n"
831 "in vec2 texcoord;\n"
832 "out vec4 fragColor;\n"
833 "void main()\n"
834 "{\n"
835 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
836 "}\n");
837 }
838
839 void SetUp() override
840 {
841 TexCoordDrawTest::SetUp();
842
843 glGenTextures(1, &mTexture3D);
844
845 setUpProgram();
846
847 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
848 ASSERT_NE(-1, mTexture3DUniformLocation);
849 }
850
851 void TearDown() override
852 {
853 glDeleteTextures(1, &mTexture3D);
854 TexCoordDrawTest::TearDown();
855 }
856
857 GLuint mTexture3D;
858 GLint mTexture3DUniformLocation;
859};
860
Olli Etuaho1a679902016-01-14 12:21:47 +0200861class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
862{
863 protected:
864 ShadowSamplerPlusSampler3DTestES3()
865 : TexCoordDrawTest(),
866 mTextureShadow(0),
867 mTexture3D(0),
868 mTextureShadowUniformLocation(-1),
869 mTexture3DUniformLocation(-1),
870 mDepthRefUniformLocation(-1)
871 {
872 }
873
874 std::string getVertexShaderSource() override
875 {
876 return std::string(
877 "#version 300 es\n"
878 "out vec2 texcoord;\n"
879 "in vec4 position;\n"
880 "void main()\n"
881 "{\n"
882 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
883 " texcoord = (position.xy * 0.5) + 0.5;\n"
884 "}\n");
885 }
886
887 std::string getFragmentShaderSource() override
888 {
889 return std::string(
890 "#version 300 es\n"
891 "precision highp float;\n"
892 "uniform highp sampler2DShadow tex2DShadow;\n"
893 "uniform highp sampler3D tex3D;\n"
894 "in vec2 texcoord;\n"
895 "uniform float depthRef;\n"
896 "out vec4 fragColor;\n"
897 "void main()\n"
898 "{\n"
899 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
900 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
901 "}\n");
902 }
903
904 void SetUp() override
905 {
906 TexCoordDrawTest::SetUp();
907
908 glGenTextures(1, &mTexture3D);
909
910 glGenTextures(1, &mTextureShadow);
911 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
912 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
913
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300914 setUpProgram();
915
Olli Etuaho1a679902016-01-14 12:21:47 +0200916 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
917 ASSERT_NE(-1, mTextureShadowUniformLocation);
918 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
919 ASSERT_NE(-1, mTexture3DUniformLocation);
920 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
921 ASSERT_NE(-1, mDepthRefUniformLocation);
922 }
923
924 void TearDown() override
925 {
926 glDeleteTextures(1, &mTextureShadow);
927 glDeleteTextures(1, &mTexture3D);
928 TexCoordDrawTest::TearDown();
929 }
930
931 GLuint mTextureShadow;
932 GLuint mTexture3D;
933 GLint mTextureShadowUniformLocation;
934 GLint mTexture3DUniformLocation;
935 GLint mDepthRefUniformLocation;
936};
937
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200938class SamplerTypeMixTestES3 : public TexCoordDrawTest
939{
940 protected:
941 SamplerTypeMixTestES3()
942 : TexCoordDrawTest(),
943 mTexture2D(0),
944 mTextureCube(0),
945 mTexture2DShadow(0),
946 mTextureCubeShadow(0),
947 mTexture2DUniformLocation(-1),
948 mTextureCubeUniformLocation(-1),
949 mTexture2DShadowUniformLocation(-1),
950 mTextureCubeShadowUniformLocation(-1),
951 mDepthRefUniformLocation(-1)
952 {
953 }
954
955 std::string getVertexShaderSource() override
956 {
957 return std::string(
958 "#version 300 es\n"
959 "out vec2 texcoord;\n"
960 "in vec4 position;\n"
961 "void main()\n"
962 "{\n"
963 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
964 " texcoord = (position.xy * 0.5) + 0.5;\n"
965 "}\n");
966 }
967
968 std::string getFragmentShaderSource() override
969 {
970 return std::string(
971 "#version 300 es\n"
972 "precision highp float;\n"
973 "uniform highp sampler2D tex2D;\n"
974 "uniform highp samplerCube texCube;\n"
975 "uniform highp sampler2DShadow tex2DShadow;\n"
976 "uniform highp samplerCubeShadow texCubeShadow;\n"
977 "in vec2 texcoord;\n"
978 "uniform float depthRef;\n"
979 "out vec4 fragColor;\n"
980 "void main()\n"
981 "{\n"
982 " fragColor = texture(tex2D, texcoord);\n"
983 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
984 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
985 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
986 "0.125);\n"
987 "}\n");
988 }
989
990 void SetUp() override
991 {
992 TexCoordDrawTest::SetUp();
993
994 glGenTextures(1, &mTexture2D);
995 glGenTextures(1, &mTextureCube);
996
997 glGenTextures(1, &mTexture2DShadow);
998 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
999 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1000
1001 glGenTextures(1, &mTextureCubeShadow);
1002 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1003 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1004
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001005 setUpProgram();
1006
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001007 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1008 ASSERT_NE(-1, mTexture2DUniformLocation);
1009 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1010 ASSERT_NE(-1, mTextureCubeUniformLocation);
1011 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1012 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1013 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1014 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1015 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1016 ASSERT_NE(-1, mDepthRefUniformLocation);
1017
1018 ASSERT_GL_NO_ERROR();
1019 }
1020
1021 void TearDown() override
1022 {
1023 glDeleteTextures(1, &mTexture2D);
1024 glDeleteTextures(1, &mTextureCube);
1025 glDeleteTextures(1, &mTexture2DShadow);
1026 glDeleteTextures(1, &mTextureCubeShadow);
1027 TexCoordDrawTest::TearDown();
1028 }
1029
1030 GLuint mTexture2D;
1031 GLuint mTextureCube;
1032 GLuint mTexture2DShadow;
1033 GLuint mTextureCubeShadow;
1034 GLint mTexture2DUniformLocation;
1035 GLint mTextureCubeUniformLocation;
1036 GLint mTexture2DShadowUniformLocation;
1037 GLint mTextureCubeShadowUniformLocation;
1038 GLint mDepthRefUniformLocation;
1039};
1040
Olli Etuaho96963162016-03-21 11:54:33 +02001041class SamplerInStructTest : public Texture2DTest
1042{
1043 protected:
1044 SamplerInStructTest() : Texture2DTest() {}
1045
1046 const char *getTextureUniformName() override { return "us.tex"; }
1047
1048 std::string getFragmentShaderSource() override
1049 {
1050 return std::string(
1051 "precision highp float;\n"
1052 "struct S\n"
1053 "{\n"
1054 " vec4 a;\n"
1055 " highp sampler2D tex;\n"
1056 "};\n"
1057 "uniform S us;\n"
1058 "varying vec2 texcoord;\n"
1059 "void main()\n"
1060 "{\n"
1061 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1062 "}\n");
1063 }
1064
1065 void runSamplerInStructTest()
1066 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001067 setUpProgram();
1068
Olli Etuaho96963162016-03-21 11:54:33 +02001069 glActiveTexture(GL_TEXTURE0);
1070 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001071 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1072 &GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001073 drawQuad(mProgram, "position", 0.5f);
Olli Etuahoa314b612016-03-10 16:43:00 +02001074 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001075 }
1076};
1077
1078class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1079{
1080 protected:
1081 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1082
1083 std::string getFragmentShaderSource() override
1084 {
1085 return std::string(
1086 "precision highp float;\n"
1087 "struct S\n"
1088 "{\n"
1089 " vec4 a;\n"
1090 " highp sampler2D tex;\n"
1091 "};\n"
1092 "uniform S us;\n"
1093 "varying vec2 texcoord;\n"
1094 "vec4 sampleFrom(S s) {\n"
1095 " return texture2D(s.tex, texcoord + s.a.x);\n"
1096 "}\n"
1097 "void main()\n"
1098 "{\n"
1099 " gl_FragColor = sampleFrom(us);\n"
1100 "}\n");
1101 }
1102};
1103
1104class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1105{
1106 protected:
1107 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1108
1109 const char *getTextureUniformName() override { return "us[0].tex"; }
1110
1111 std::string getFragmentShaderSource() override
1112 {
1113 return std::string(
1114 "precision highp float;\n"
1115 "struct S\n"
1116 "{\n"
1117 " vec4 a;\n"
1118 " highp sampler2D tex;\n"
1119 "};\n"
1120 "uniform S us[1];\n"
1121 "varying vec2 texcoord;\n"
1122 "vec4 sampleFrom(S s) {\n"
1123 " return texture2D(s.tex, texcoord + s.a.x);\n"
1124 "}\n"
1125 "void main()\n"
1126 "{\n"
1127 " gl_FragColor = sampleFrom(us[0]);\n"
1128 "}\n");
1129 }
1130};
1131
1132class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1133{
1134 protected:
1135 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1136
1137 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1138
1139 std::string getFragmentShaderSource() override
1140 {
1141 return std::string(
1142 "precision highp float;\n"
1143 "struct SUB\n"
1144 "{\n"
1145 " vec4 a;\n"
1146 " highp sampler2D tex;\n"
1147 "};\n"
1148 "struct S\n"
1149 "{\n"
1150 " SUB sub;\n"
1151 "};\n"
1152 "uniform S us[1];\n"
1153 "varying vec2 texcoord;\n"
1154 "vec4 sampleFrom(SUB s) {\n"
1155 " return texture2D(s.tex, texcoord + s.a.x);\n"
1156 "}\n"
1157 "void main()\n"
1158 "{\n"
1159 " gl_FragColor = sampleFrom(us[0].sub);\n"
1160 "}\n");
1161 }
1162};
1163
1164class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1165{
1166 protected:
1167 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1168
1169 std::string getFragmentShaderSource() override
1170 {
1171 return std::string(
1172 "precision highp float;\n"
1173 "struct S\n"
1174 "{\n"
1175 " vec4 a;\n"
1176 " highp sampler2D tex;\n"
1177 "};\n"
1178 "uniform S us;\n"
1179 "uniform float us_tex;\n"
1180 "varying vec2 texcoord;\n"
1181 "void main()\n"
1182 "{\n"
1183 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1184 "}\n");
1185 }
1186};
1187
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001188TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001189{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001190 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001191 EXPECT_GL_ERROR(GL_NO_ERROR);
1192
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001193 setUpProgram();
1194
Jamie Madillf67115c2014-04-22 13:14:05 -04001195 const GLubyte *pixels[20] = { 0 };
1196 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1197 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1198}
Geoff Langc41e42d2014-04-28 10:58:16 -04001199
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001200TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001201{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001202 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001203 EXPECT_GL_ERROR(GL_NO_ERROR);
1204
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001205 setUpProgram();
1206
Geoff Langc41e42d2014-04-28 10:58:16 -04001207 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001208 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001209 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001210 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001211
1212 const GLubyte *pixel[4] = { 0 };
1213
1214 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1215 EXPECT_GL_NO_ERROR();
1216
1217 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1218 EXPECT_GL_NO_ERROR();
1219
1220 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1221 EXPECT_GL_NO_ERROR();
1222}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001223
1224// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001225TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001226{
1227 glActiveTexture(GL_TEXTURE0);
1228 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1229 glActiveTexture(GL_TEXTURE1);
1230 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1231 EXPECT_GL_ERROR(GL_NO_ERROR);
1232
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001233 glUseProgram(mProgram);
1234 glUniform1i(mTexture2DUniformLocation, 0);
1235 glUniform1i(mTextureCubeUniformLocation, 1);
1236 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001237 EXPECT_GL_NO_ERROR();
1238}
Jamie Madill9aca0592014-10-06 16:26:59 -04001239
Olli Etuaho53a2da12016-01-11 15:43:32 +02001240// Test drawing with two texture types accessed from the same shader and check that the result of
1241// drawing is correct.
1242TEST_P(TextureCubeTest, CubeMapDraw)
1243{
1244 GLubyte texData[4];
1245 texData[0] = 0;
1246 texData[1] = 60;
1247 texData[2] = 0;
1248 texData[3] = 255;
1249
1250 glActiveTexture(GL_TEXTURE0);
1251 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1252 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1253
1254 glActiveTexture(GL_TEXTURE1);
1255 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1256 texData[1] = 120;
1257 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1258 texData);
1259 EXPECT_GL_ERROR(GL_NO_ERROR);
1260
1261 glUseProgram(mProgram);
1262 glUniform1i(mTexture2DUniformLocation, 0);
1263 glUniform1i(mTextureCubeUniformLocation, 1);
1264 drawQuad(mProgram, "position", 0.5f);
1265 EXPECT_GL_NO_ERROR();
1266
1267 int px = getWindowWidth() - 1;
1268 int py = 0;
1269 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1270}
1271
Olli Etuaho4644a202016-01-12 15:12:53 +02001272TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1273{
1274 glActiveTexture(GL_TEXTURE0);
1275 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1276 GLubyte texData[4];
1277 texData[0] = 0;
1278 texData[1] = 128;
1279 texData[2] = 0;
1280 texData[3] = 255;
1281 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1282 glUseProgram(mProgram);
1283 glUniform1i(mTexture2DUniformLocation, 0);
1284 drawQuad(mProgram, "position", 0.5f);
1285 EXPECT_GL_NO_ERROR();
1286
1287 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1288}
1289
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001290// Test drawing with two textures passed to the shader in a sampler array.
1291TEST_P(SamplerArrayTest, SamplerArrayDraw)
1292{
1293 testSamplerArrayDraw();
1294}
1295
1296// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1297// user-defined function in the shader.
1298TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1299{
1300 testSamplerArrayDraw();
1301}
1302
Jamie Madill9aca0592014-10-06 16:26:59 -04001303// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001304TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001305{
1306 int px = getWindowWidth() / 2;
1307 int py = getWindowHeight() / 2;
1308
1309 glActiveTexture(GL_TEXTURE0);
1310 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1311
Olli Etuahoa314b612016-03-10 16:43:00 +02001312 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001313
Olli Etuahoa314b612016-03-10 16:43:00 +02001314 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1317 glGenerateMipmap(GL_TEXTURE_2D);
1318
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001319 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001320 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001321 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1322 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001323 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001324 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001325
Olli Etuahoa314b612016-03-10 16:43:00 +02001326 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001327
Olli Etuahoa314b612016-03-10 16:43:00 +02001328 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1329 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001330 glGenerateMipmap(GL_TEXTURE_2D);
1331
Olli Etuahoa314b612016-03-10 16:43:00 +02001332 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001333
Olli Etuahoa314b612016-03-10 16:43:00 +02001334 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1335 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001336 glGenerateMipmap(GL_TEXTURE_2D);
1337
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001338 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001339
1340 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001341 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001342}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001343
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001344// Test creating a FBO with a cube map render target, to test an ANGLE bug
1345// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001346TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001347{
1348 GLuint fbo;
1349 glGenFramebuffers(1, &fbo);
1350 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1351
1352 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1353 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0);
1354
Corentin Wallez322653b2015-06-17 18:33:56 +02001355 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001356
1357 glDeleteFramebuffers(1, &fbo);
1358
1359 EXPECT_GL_NO_ERROR();
1360}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001361
1362// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001363TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001364{
1365 int width = getWindowWidth();
1366 int height = getWindowHeight();
1367
1368 GLuint tex2D;
1369 glGenTextures(1, &tex2D);
1370 glActiveTexture(GL_TEXTURE0);
1371 glBindTexture(GL_TEXTURE_2D, tex2D);
1372
1373 // Fill with red
1374 std::vector<GLubyte> pixels(3 * 16 * 16);
1375 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1376 {
1377 pixels[pixelId * 3 + 0] = 255;
1378 pixels[pixelId * 3 + 1] = 0;
1379 pixels[pixelId * 3 + 2] = 0;
1380 }
1381
1382 // ANGLE internally uses RGBA as the DirectX format for RGB images
1383 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1384 // The data is kept in a CPU-side image and the image is marked as dirty.
1385 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1386
1387 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1388 // glTexSubImage2D should take into account that the image is dirty.
1389 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1392
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001393 setUpProgram();
1394
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001395 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001396 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001397 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001398 glDeleteTextures(1, &tex2D);
1399 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001400 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001401
1402 // Validate that the region of the texture without data has an alpha of 1.0
1403 GLubyte pixel[4];
1404 glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1405 EXPECT_EQ(pixel[3], 255);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001406}
1407
1408// 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 +02001409TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001410{
1411 if (extensionEnabled("NV_pixel_buffer_object"))
1412 {
1413 int width = getWindowWidth();
1414 int height = getWindowHeight();
1415
1416 GLuint tex2D;
1417 glGenTextures(1, &tex2D);
1418 glActiveTexture(GL_TEXTURE0);
1419 glBindTexture(GL_TEXTURE_2D, tex2D);
1420
1421 // Fill with red
1422 std::vector<GLubyte> pixels(3 * 16 * 16);
1423 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1424 {
1425 pixels[pixelId * 3 + 0] = 255;
1426 pixels[pixelId * 3 + 1] = 0;
1427 pixels[pixelId * 3 + 2] = 0;
1428 }
1429
1430 // Read 16x16 region from red backbuffer to PBO
1431 GLuint pbo;
1432 glGenBuffers(1, &pbo);
1433 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1434 glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW);
1435
1436 // ANGLE internally uses RGBA as the DirectX format for RGB images
1437 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color.
1438 // The data is kept in a CPU-side image and the image is marked as dirty.
1439 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1440
1441 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1442 // glTexSubImage2D should take into account that the image is dirty.
1443 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL);
1444 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1445 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1446
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001447 setUpProgram();
1448
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001449 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001450 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001451 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001452 glDeleteTextures(1, &tex2D);
Olli Etuaho19d48db2016-01-13 14:43:21 +02001453 glDeleteBuffers(1, &pbo);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001454 EXPECT_GL_NO_ERROR();
1455 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1456 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1457 }
1458}
Jamie Madillbc393df2015-01-29 13:46:07 -05001459
1460// See description on testFloatCopySubImage
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001461TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001462{
1463 testFloatCopySubImage(1, 1);
1464}
1465
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001466TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001467{
1468 testFloatCopySubImage(2, 1);
1469}
1470
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001471TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001472{
1473 testFloatCopySubImage(2, 2);
1474}
1475
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001476TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001477{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001478 if (IsIntel() && IsLinux())
1479 {
1480 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1481 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1482 return;
1483 }
1484
Jamie Madillbc393df2015-01-29 13:46:07 -05001485 testFloatCopySubImage(3, 1);
1486}
1487
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001488TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001489{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001490 if (IsIntel() && IsLinux())
1491 {
1492 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1493 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1494 return;
1495 }
1496
Jamie Madillbc393df2015-01-29 13:46:07 -05001497 testFloatCopySubImage(3, 2);
1498}
1499
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001500TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001501{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001502 if (IsIntel() && IsLinux())
1503 {
1504 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
1505 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
1506 return;
1507 }
1508
Austin Kinrossd544cc92016-01-11 15:26:42 -08001509 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001510 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001511 {
1512 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1513 return;
1514 }
1515
Jamie Madillbc393df2015-01-29 13:46:07 -05001516 testFloatCopySubImage(3, 3);
1517}
1518
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001519TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001520{
1521 testFloatCopySubImage(4, 1);
1522}
1523
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001524TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001525{
1526 testFloatCopySubImage(4, 2);
1527}
1528
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001529TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001530{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001531 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001532 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001533 {
1534 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1535 return;
1536 }
1537
Jamie Madillbc393df2015-01-29 13:46:07 -05001538 testFloatCopySubImage(4, 3);
1539}
1540
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001541TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05001542{
Austin Kinrossd544cc92016-01-11 15:26:42 -08001543 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -05001544 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -08001545 {
1546 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
1547 return;
1548 }
1549
Jamie Madillbc393df2015-01-29 13:46:07 -05001550 testFloatCopySubImage(4, 4);
1551}
Austin Kinross07285142015-03-26 11:36:16 -07001552
1553// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
1554// 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 +02001555TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07001556{
1557 const int npotTexSize = 5;
1558 const int potTexSize = 4; // Should be less than npotTexSize
1559 GLuint tex2D;
1560
1561 if (extensionEnabled("GL_OES_texture_npot"))
1562 {
1563 // This test isn't applicable if texture_npot is enabled
1564 return;
1565 }
1566
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001567 setUpProgram();
1568
Austin Kinross07285142015-03-26 11:36:16 -07001569 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1570
Austin Kinross5faa15b2016-01-11 13:32:48 -08001571 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
1572 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1573
Austin Kinross07285142015-03-26 11:36:16 -07001574 glActiveTexture(GL_TEXTURE0);
1575 glGenTextures(1, &tex2D);
1576 glBindTexture(GL_TEXTURE_2D, tex2D);
1577
1578 std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize);
1579 for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId)
1580 {
1581 pixels[pixelId] = 64;
1582 }
1583
1584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1586
1587 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
1588 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1589 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1590
1591 // Check that an NPOT texture on level 0 succeeds
1592 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1593 EXPECT_GL_NO_ERROR();
1594
1595 // Check that generateMipmap fails on NPOT
1596 glGenerateMipmap(GL_TEXTURE_2D);
1597 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1598
1599 // Check that nothing is drawn if filtering is not correct for NPOT
1600 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1601 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1602 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1603 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1604 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001605 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001606 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1607
1608 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
1609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1611 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1612 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001613 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001614 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
1615
1616 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
1617 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1618 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001619 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001620 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1621
1622 // Check that glTexImage2D for POT texture succeeds
1623 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
1624 EXPECT_GL_NO_ERROR();
1625
1626 // Check that generateMipmap for an POT texture succeeds
1627 glGenerateMipmap(GL_TEXTURE_2D);
1628 EXPECT_GL_NO_ERROR();
1629
1630 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
1631 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1632 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1633 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1634 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1635 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001636 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07001637 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
1638 EXPECT_GL_NO_ERROR();
1639}
Jamie Madillfa05f602015-05-07 13:47:11 -04001640
Austin Kinross08528e12015-10-07 16:24:40 -07001641// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
1642// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001643TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07001644{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001645 // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug
1646 // 1278)
1647 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1648 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1649 {
1650 std::cout << "Test disabled on OpenGL." << std::endl;
1651 return;
1652 }
1653
Austin Kinross08528e12015-10-07 16:24:40 -07001654 glActiveTexture(GL_TEXTURE0);
1655 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1656
1657 // Create an 8x8 (i.e. power-of-two) texture.
1658 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1659 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1660 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1661 glGenerateMipmap(GL_TEXTURE_2D);
1662
1663 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
1664 // This should always work, even if GL_OES_texture_npot isn't active.
1665 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1666
1667 EXPECT_GL_NO_ERROR();
1668}
1669
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001670// Test to check that texture completeness is determined correctly when the texture base level is
1671// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
1672TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
1673{
1674 glActiveTexture(GL_TEXTURE0);
1675 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001676
1677 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
1678 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1679 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1680 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1681 texDataGreen.data());
1682 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1683 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02001684 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1685 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1686 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1687
1688 EXPECT_GL_NO_ERROR();
1689
1690 drawQuad(mProgram, "position", 0.5f);
1691
Olli Etuahoa314b612016-03-10 16:43:00 +02001692 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1693}
1694
1695// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1696// have images defined.
1697TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
1698{
1699 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1700 {
1701 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
1702 std::cout << "Test skipped on AMD OpenGL." << std::endl;
1703 return;
1704 }
1705 if (IsOSX())
1706 {
1707 // Observed incorrect rendering on OSX.
1708 std::cout << "Test skipped on OSX." << std::endl;
1709 return;
1710 }
1711 glActiveTexture(GL_TEXTURE0);
1712 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1713 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1714 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1715 texDataGreen.data());
1716 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1720
1721 EXPECT_GL_NO_ERROR();
1722
1723 drawQuad(mProgram, "position", 0.5f);
1724
1725 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1726}
1727
Olli Etuahoe8528d82016-05-16 17:50:52 +03001728// Test that drawing works correctly when level 0 is undefined and base level is 1.
1729TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
1730{
1731 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1732 {
1733 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
1734 std::cout << "Test skipped on AMD OpenGL." << std::endl;
1735 return;
1736 }
1737 if (IsOSX())
1738 {
1739 // Observed incorrect rendering on OSX.
1740 std::cout << "Test skipped on OSX." << std::endl;
1741 return;
1742 }
1743 glActiveTexture(GL_TEXTURE0);
1744 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1745 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1746 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1747 texDataGreen.data());
1748 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1752
1753 EXPECT_GL_NO_ERROR();
1754
1755 // Texture is incomplete.
1756 drawQuad(mProgram, "position", 0.5f);
1757 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
1758
1759 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1760 texDataGreen.data());
1761
1762 // Texture is now complete.
1763 drawQuad(mProgram, "position", 0.5f);
1764 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1765}
1766
Olli Etuahoa314b612016-03-10 16:43:00 +02001767// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1768// dimensions that don't fit the images inside the range.
1769// GLES 3.0.4 section 3.8.13 Texture completeness
1770TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1771{
1772 if (IsOSX())
1773 {
1774 // Observed incorrect rendering on OSX.
1775 std::cout << "Test skipped on OSX." << std::endl;
1776 return;
1777 }
1778 glActiveTexture(GL_TEXTURE0);
1779 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1780 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
1781 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
1782 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
1783
1784 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1785 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1786
1787 // Two levels that are initially unused.
1788 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
1789 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1790 texDataCyan.data());
1791
1792 // One level that is used - only this level should affect completeness.
1793 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1794 texDataGreen.data());
1795
1796 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1797 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1798
1799 EXPECT_GL_NO_ERROR();
1800
1801 drawQuad(mProgram, "position", 0.5f);
1802
1803 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1804
1805 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1806 {
1807 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1808 // level was changed.
1809 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1810 return;
1811 }
1812
1813 // Switch the level that is being used to the cyan level 2.
1814 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
1815 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
1816
1817 EXPECT_GL_NO_ERROR();
1818
1819 drawQuad(mProgram, "position", 0.5f);
1820
1821 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1822}
1823
1824// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1825// have images defined.
1826TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
1827{
1828 if (IsOSX())
1829 {
1830 // Observed incorrect rendering on OSX.
1831 std::cout << "Test skipped on OSX." << std::endl;
1832 return;
1833 }
1834 glActiveTexture(GL_TEXTURE0);
1835 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1836 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1837 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1838 texDataGreen.data());
1839 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1840 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1841 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1842 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1843
1844 EXPECT_GL_NO_ERROR();
1845
1846 drawQuad(mProgram, "position", 0.5f);
1847
1848 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1849}
1850
1851// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1852// dimensions that don't fit the images inside the range.
1853// GLES 3.0.4 section 3.8.13 Texture completeness
1854TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1855{
1856 if (IsOSX())
1857 {
1858 // Observed incorrect rendering on OSX.
1859 std::cout << "Test skipped on OSX." << std::endl;
1860 return;
1861 }
1862 glActiveTexture(GL_TEXTURE0);
1863 glBindTexture(GL_TEXTURE_3D, mTexture3D);
1864 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1865 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1866 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1867
1868 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1869 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1870
1871 // Two levels that are initially unused.
1872 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1873 texDataRed.data());
1874 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1875 texDataCyan.data());
1876
1877 // One level that is used - only this level should affect completeness.
1878 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1879 texDataGreen.data());
1880
1881 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
1882 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
1883
1884 EXPECT_GL_NO_ERROR();
1885
1886 drawQuad(mProgram, "position", 0.5f);
1887
1888 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1889
1890 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1891 {
1892 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1893 // level was changed.
1894 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1895 return;
1896 }
1897
1898 // Switch the level that is being used to the cyan level 2.
1899 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
1900 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
1901
1902 EXPECT_GL_NO_ERROR();
1903
1904 drawQuad(mProgram, "position", 0.5f);
1905
1906 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1907}
1908
1909// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
1910// have images defined.
1911TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
1912{
1913 if (IsOSX())
1914 {
1915 // Observed incorrect rendering on OSX.
1916 std::cout << "Test skipped on OSX." << std::endl;
1917 return;
1918 }
1919 glActiveTexture(GL_TEXTURE0);
1920 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
1921 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1922 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1923 texDataGreen.data());
1924 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1925 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1926 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1927 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1928
1929 EXPECT_GL_NO_ERROR();
1930
1931 drawQuad(mProgram, "position", 0.5f);
1932
1933 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1934}
1935
1936// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
1937// dimensions that don't fit the images inside the range.
1938// GLES 3.0.4 section 3.8.13 Texture completeness
1939TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
1940{
1941 if (IsOSX())
1942 {
1943 // Observed incorrect rendering on OSX.
1944 std::cout << "Test skipped on OSX." << std::endl;
1945 return;
1946 }
1947 glActiveTexture(GL_TEXTURE0);
1948 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
1949 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
1950 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
1951 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
1952
1953 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1954 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1955
1956 // Two levels that are initially unused.
1957 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1958 texDataRed.data());
1959 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1960 texDataCyan.data());
1961
1962 // One level that is used - only this level should affect completeness.
1963 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1964 texDataGreen.data());
1965
1966 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
1967 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
1968
1969 EXPECT_GL_NO_ERROR();
1970
1971 drawQuad(mProgram, "position", 0.5f);
1972
1973 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1974
1975 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1976 {
1977 // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base
1978 // level was changed.
1979 std::cout << "Test partially skipped on Intel OpenGL." << std::endl;
1980 return;
1981 }
1982 if (IsNVIDIA() && (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1983 getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE))
1984 {
1985 // NVIDIA was observed drawing color 0,0,0,0 instead of the texture color after the base
1986 // level was changed.
1987 std::cout << "Test partially skipped on NVIDIA OpenGL." << std::endl;
1988 return;
1989 }
1990
1991 // Switch the level that is being used to the cyan level 2.
1992 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
1993 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
1994
1995 EXPECT_GL_NO_ERROR();
1996
1997 drawQuad(mProgram, "position", 0.5f);
1998
1999 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2000}
2001
2002// Test that texture completeness is updated if texture max level changes.
2003// GLES 3.0.4 section 3.8.13 Texture completeness
2004TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2005{
2006 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2007 {
2008 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2009 // the base level.
2010 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2011 return;
2012 }
2013 if (IsOSX())
2014 {
2015 // Observed incorrect rendering on OSX.
2016 std::cout << "Test skipped on OSX." << std::endl;
2017 return;
2018 }
2019
2020 glActiveTexture(GL_TEXTURE0);
2021 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2022 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2023
2024 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2025 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2026
2027 // A level that is initially unused.
2028 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2029 texDataGreen.data());
2030
2031 // One level that is initially used - only this level should affect completeness.
2032 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2033 texDataGreen.data());
2034
2035 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2036 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2037
2038 EXPECT_GL_NO_ERROR();
2039
2040 drawQuad(mProgram, "position", 0.5f);
2041
2042 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2043
2044 // Switch the max level to level 1. The levels within the used range now have inconsistent
2045 // dimensions and the texture should be incomplete.
2046 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2047
2048 EXPECT_GL_NO_ERROR();
2049
2050 drawQuad(mProgram, "position", 0.5f);
2051
2052 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2053}
2054
2055// Test that 3D texture completeness is updated if texture max level changes.
2056// GLES 3.0.4 section 3.8.13 Texture completeness
2057TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2058{
2059 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2060 {
2061 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2062 // the base level.
2063 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2064 return;
2065 }
2066 if (IsOSX())
2067 {
2068 // Observed incorrect rendering on OSX.
2069 std::cout << "Test skipped on OSX." << std::endl;
2070 return;
2071 }
2072
2073 glActiveTexture(GL_TEXTURE0);
2074 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2075 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2076
2077 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2078 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2079
2080 // A level that is initially unused.
2081 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2082 texDataGreen.data());
2083
2084 // One level that is initially used - only this level should affect completeness.
2085 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2086 texDataGreen.data());
2087
2088 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2089 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2090
2091 EXPECT_GL_NO_ERROR();
2092
2093 drawQuad(mProgram, "position", 0.5f);
2094
2095 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2096
2097 // Switch the max level to level 1. The levels within the used range now have inconsistent
2098 // dimensions and the texture should be incomplete.
2099 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2100
2101 EXPECT_GL_NO_ERROR();
2102
2103 drawQuad(mProgram, "position", 0.5f);
2104
2105 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2106}
2107
2108// Test that texture completeness is updated if texture base level changes.
2109// GLES 3.0.4 section 3.8.13 Texture completeness
2110TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2111{
2112 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2113 {
2114 // Intel was observed having wrong behavior after the texture is made incomplete by changing
2115 // the base level.
2116 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2117 return;
2118 }
2119
2120 glActiveTexture(GL_TEXTURE0);
2121 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2122 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2123
2124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2126
2127 // Two levels that are initially unused.
2128 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2129 texDataGreen.data());
2130 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2131 texDataGreen.data());
2132
2133 // One level that is initially used - only this level should affect completeness.
2134 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2135 texDataGreen.data());
2136
2137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2139
2140 EXPECT_GL_NO_ERROR();
2141
2142 drawQuad(mProgram, "position", 0.5f);
2143
2144 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2145
2146 // Switch the base level to level 1. The levels within the used range now have inconsistent
2147 // dimensions and the texture should be incomplete.
2148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2149
2150 EXPECT_GL_NO_ERROR();
2151
2152 drawQuad(mProgram, "position", 0.5f);
2153
2154 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2155}
2156
2157// Test that texture is not complete if base level is greater than max level.
2158// GLES 3.0.4 section 3.8.13 Texture completeness
2159TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2160{
2161 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2162 {
2163 // Intel Windows OpenGL driver crashes if the base level of a non-immutable texture is out
2164 // of range.
2165 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2166 return;
2167 }
2168
2169 glActiveTexture(GL_TEXTURE0);
2170 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2171
2172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2174
2175 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2176
2177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2179
2180 EXPECT_GL_NO_ERROR();
2181
2182 drawQuad(mProgram, "position", 0.5f);
2183
2184 // Texture should be incomplete.
2185 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2186}
2187
2188// Test that immutable texture base level and max level are clamped.
2189// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2190TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2191{
Olli Etuahoa314b612016-03-10 16:43:00 +02002192 glActiveTexture(GL_TEXTURE0);
2193 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2194
2195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2197
2198 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2199
2200 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2201
2202 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2203 // should be clamped to [base_level, levels - 1].
2204 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2205 // In the case of this test, those rules make the effective base level and max level 0.
2206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2208
2209 EXPECT_GL_NO_ERROR();
2210
2211 drawQuad(mProgram, "position", 0.5f);
2212
2213 // Texture should be complete.
2214 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2215}
2216
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002217// Test that changing base level works when it affects the format of the texture.
2218TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2219{
Corentin Wallezc7f59d02016-06-20 10:12:08 -04002220 if (IsNVIDIA() && IsOpenGL())
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002221 {
2222 // Observed rendering corruption on NVIDIA OpenGL.
2223 std::cout << "Test skipped on NVIDIA OpenGL." << std::endl;
2224 return;
2225 }
Corentin Wallezc7f59d02016-06-20 10:12:08 -04002226 if (IsIntel() && IsDesktopOpenGL())
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002227 {
2228 // Observed incorrect rendering on Intel OpenGL.
2229 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2230 return;
2231 }
Corentin Wallezc7f59d02016-06-20 10:12:08 -04002232 if (IsAMD() && IsDesktopOpenGL())
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002233 {
2234 // Observed incorrect rendering on AMD OpenGL.
2235 std::cout << "Test skipped on AMD OpenGL." << std::endl;
2236 return;
2237 }
2238
2239 glActiveTexture(GL_TEXTURE0);
2240 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2241 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2242 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2243
2244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2246
2247 // RGBA8 level that's initially unused.
2248 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2249 texDataCyan.data());
2250
2251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2253
2254 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2255 // format. It reads green channel data from the green and alpha channels of texDataGreen
2256 // (this is a bit hacky but works).
2257 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2258
2259 EXPECT_GL_NO_ERROR();
2260
2261 drawQuad(mProgram, "position", 0.5f);
2262
2263 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2264
2265 // Switch the texture to use the cyan level 0 with the RGBA format.
2266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2268
2269 EXPECT_GL_NO_ERROR();
2270
2271 drawQuad(mProgram, "position", 0.5f);
2272
2273 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2274}
2275
Olli Etuahoa314b612016-03-10 16:43:00 +02002276// Test that setting a texture image works when base level is out of range.
2277TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2278{
2279 glActiveTexture(GL_TEXTURE0);
2280 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2281
2282 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2283 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2284
2285 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2287
2288 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2289
2290 EXPECT_GL_NO_ERROR();
2291
2292 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2293
2294 drawQuad(mProgram, "position", 0.5f);
2295
2296 // Texture should be complete.
2297 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002298}
2299
Jamie Madill2453dbc2015-07-14 11:35:42 -04002300// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0
2301// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as
2302// expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002303TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002304{
2305 std::vector<GLubyte> pixelData;
2306 for (size_t count = 0; count < 5000; count++)
2307 {
2308 pixelData.push_back(0u);
2309 pixelData.push_back(255u);
2310 pixelData.push_back(0u);
2311 }
2312
2313 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002314 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002315 glUniform1i(mTextureArrayLocation, 0);
2316
2317 // The first draw worked correctly.
2318 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]);
2319
2320 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2321 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2322 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2323 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002324 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002325 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002326
2327 // The dimension of the respecification must match the original exactly to trigger the bug.
2328 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 +02002329 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002330 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002331
2332 ASSERT_GL_NO_ERROR();
2333}
2334
Olli Etuaho1a679902016-01-14 12:21:47 +02002335// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2336// This test is needed especially to confirm that sampler registers get assigned correctly on
2337// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2338TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2339{
2340 glActiveTexture(GL_TEXTURE0);
2341 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2342 GLubyte texData[4];
2343 texData[0] = 0;
2344 texData[1] = 60;
2345 texData[2] = 0;
2346 texData[3] = 255;
2347 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2348
2349 glActiveTexture(GL_TEXTURE1);
2350 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2351 GLfloat depthTexData[1];
2352 depthTexData[0] = 0.5f;
2353 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2354 depthTexData);
2355
2356 glUseProgram(mProgram);
2357 glUniform1f(mDepthRefUniformLocation, 0.3f);
2358 glUniform1i(mTexture3DUniformLocation, 0);
2359 glUniform1i(mTextureShadowUniformLocation, 1);
2360
2361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2362 drawQuad(mProgram, "position", 0.5f);
2363 EXPECT_GL_NO_ERROR();
2364 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2365 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2366
2367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2368 drawQuad(mProgram, "position", 0.5f);
2369 EXPECT_GL_NO_ERROR();
2370 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2371 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2372}
2373
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002374// Test multiple different sampler types in the same shader.
2375// This test makes sure that even if sampler / texture registers get grouped together based on type
2376// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2377// still has the right register index information for each ESSL sampler.
2378// The tested ESSL samplers have the following types in D3D11 HLSL:
2379// sampler2D: Texture2D + SamplerState
2380// samplerCube: TextureCube + SamplerState
2381// sampler2DShadow: Texture2D + SamplerComparisonState
2382// samplerCubeShadow: TextureCube + SamplerComparisonState
2383TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2384{
2385 glActiveTexture(GL_TEXTURE0);
2386 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2387 GLubyte texData[4];
2388 texData[0] = 0;
2389 texData[1] = 0;
2390 texData[2] = 120;
2391 texData[3] = 255;
2392 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2393
2394 glActiveTexture(GL_TEXTURE1);
2395 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2396 texData[0] = 0;
2397 texData[1] = 90;
2398 texData[2] = 0;
2399 texData[3] = 255;
2400 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2401 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2402 texData);
2403
2404 glActiveTexture(GL_TEXTURE2);
2405 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2406 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2407 GLfloat depthTexData[1];
2408 depthTexData[0] = 0.5f;
2409 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2410 depthTexData);
2411
2412 glActiveTexture(GL_TEXTURE3);
2413 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2414 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2415 depthTexData[0] = 0.2f;
2416 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2417 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2418 depthTexData);
2419
2420 EXPECT_GL_NO_ERROR();
2421
2422 glUseProgram(mProgram);
2423 glUniform1f(mDepthRefUniformLocation, 0.3f);
2424 glUniform1i(mTexture2DUniformLocation, 0);
2425 glUniform1i(mTextureCubeUniformLocation, 1);
2426 glUniform1i(mTexture2DShadowUniformLocation, 2);
2427 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2428
2429 drawQuad(mProgram, "position", 0.5f);
2430 EXPECT_GL_NO_ERROR();
2431 // The shader writes:
2432 // <texture 2d color> +
2433 // <cube map color> +
2434 // 0.25 * <comparison result (1.0)> +
2435 // 0.125 * <comparison result (0.0)>
2436 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2437}
2438
Olli Etuahobce743a2016-01-15 17:18:28 +02002439// Test different base levels on textures accessed through the same sampler array.
2440// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2441TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2442{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002443 if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
Olli Etuahobce743a2016-01-15 17:18:28 +02002444 {
2445 std::cout << "Test skipped on Intel and AMD D3D." << std::endl;
2446 return;
2447 }
2448 glActiveTexture(GL_TEXTURE0);
2449 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2450 GLsizei size = 64;
2451 for (GLint level = 0; level < 7; ++level)
2452 {
2453 ASSERT_LT(0, size);
2454 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2455 nullptr);
2456 size = size / 2;
2457 }
2458 ASSERT_EQ(0, size);
2459 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2460
2461 glActiveTexture(GL_TEXTURE1);
2462 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2463 size = 128;
2464 for (GLint level = 0; level < 8; ++level)
2465 {
2466 ASSERT_LT(0, size);
2467 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2468 nullptr);
2469 size = size / 2;
2470 }
2471 ASSERT_EQ(0, size);
2472 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2473 EXPECT_GL_NO_ERROR();
2474
2475 glUseProgram(mProgram);
2476 glUniform1i(mTexture0Location, 0);
2477 glUniform1i(mTexture1Location, 1);
2478
2479 drawQuad(mProgram, "position", 0.5f);
2480 EXPECT_GL_NO_ERROR();
2481 // Red channel: width of level 1 of texture A: 32.
2482 // Green channel: width of level 3 of texture B: 16.
2483 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2484}
2485
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002486// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2487// ES 3.0.4 table 3.24
2488TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2489{
2490 glActiveTexture(GL_TEXTURE0);
2491 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2492 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2493 EXPECT_GL_NO_ERROR();
2494
2495 drawQuad(mProgram, "position", 0.5f);
2496
2497 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2498}
2499
2500// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2501// ES 3.0.4 table 3.24
2502TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
2503{
2504 glActiveTexture(GL_TEXTURE0);
2505 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2506 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2507 EXPECT_GL_NO_ERROR();
2508
2509 drawQuad(mProgram, "position", 0.5f);
2510
2511 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2512}
2513
2514// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2515// ES 3.0.4 table 3.24
2516TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
2517{
2518 if (extensionEnabled("GL_OES_texture_float"))
2519 {
2520 glActiveTexture(GL_TEXTURE0);
2521 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2522 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
2523 EXPECT_GL_NO_ERROR();
2524
2525 drawQuad(mProgram, "position", 0.5f);
2526
2527 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2528 }
2529}
2530
2531// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2532// ES 3.0.4 table 3.24
2533TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1)
2534{
2535 if (extensionEnabled("GL_OES_texture_half_float"))
2536 {
Yuly Novikovafcec832016-06-21 22:19:51 -04002537 if (IsNVIDIA() && IsOpenGLES())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002538 {
2539 std::cout << "Test skipped on NVIDIA" << std::endl;
2540 return;
2541 }
Yuly Novikovafcec832016-06-21 22:19:51 -04002542 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
2543 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2544 {
2545 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2546 return;
2547 }
2548
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002549 glActiveTexture(GL_TEXTURE0);
2550 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2551 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES,
2552 nullptr);
2553 EXPECT_GL_NO_ERROR();
2554
2555 drawQuad(mProgram, "position", 0.5f);
2556
2557 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2558 }
2559}
2560
2561// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2562// ES 3.0.4 table 3.24
2563TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
2564{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002565 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002566 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002567 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002568 return;
2569 }
2570 glActiveTexture(GL_TEXTURE0);
2571 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2572 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
2573 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2574 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2575 EXPECT_GL_NO_ERROR();
2576
2577 drawQuad(mProgram, "position", 0.5f);
2578
2579 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2580}
2581
2582// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2583// ES 3.0.4 table 3.24
2584TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
2585{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002586 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002587 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002588 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002589 return;
2590 }
2591 glActiveTexture(GL_TEXTURE0);
2592 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2593
2594 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
2595 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2596 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2597 EXPECT_GL_NO_ERROR();
2598
2599 drawQuad(mProgram, "position", 0.5f);
2600
2601 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2602}
2603
2604// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2605// ES 3.0.4 table 3.24
2606TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
2607{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002608 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002609 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002610 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002611 return;
2612 }
2613 glActiveTexture(GL_TEXTURE0);
2614 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2615 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
2616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2617 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2618 EXPECT_GL_NO_ERROR();
2619
2620 drawQuad(mProgram, "position", 0.5f);
2621
2622 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2623}
2624
2625// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2626// ES 3.0.4 table 3.24
2627TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
2628{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002629 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002630 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002631 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002632 return;
2633 }
2634 glActiveTexture(GL_TEXTURE0);
2635 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2636 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
2637 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2638 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2639 EXPECT_GL_NO_ERROR();
2640
2641 drawQuad(mProgram, "position", 0.5f);
2642
2643 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2644}
2645
2646// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2647// ES 3.0.4 table 3.24
2648TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
2649{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002650 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002651 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002652 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002653 return;
2654 }
2655 glActiveTexture(GL_TEXTURE0);
2656 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2657 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
2658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2659 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2660 EXPECT_GL_NO_ERROR();
2661
2662 drawQuad(mProgram, "position", 0.5f);
2663
2664 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2665}
2666
2667// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2668// ES 3.0.4 table 3.24
2669TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
2670{
Jamie Madill518b9fa2016-03-02 11:26:02 -05002671 if (IsIntel())
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002672 {
Jamie Madill518b9fa2016-03-02 11:26:02 -05002673 std::cout << "Test disabled on Intel." << std::endl;
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002674 return;
2675 }
2676 glActiveTexture(GL_TEXTURE0);
2677 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2678 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
2679 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2680 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2681 EXPECT_GL_NO_ERROR();
2682
2683 drawQuad(mProgram, "position", 0.5f);
2684
2685 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2686}
2687
2688// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2689// ES 3.0.4 table 3.24
2690TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
2691{
2692 glActiveTexture(GL_TEXTURE0);
2693 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2694 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
2695 EXPECT_GL_NO_ERROR();
2696
2697 drawQuad(mProgram, "position", 0.5f);
2698
2699 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2700}
2701
2702// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2703// ES 3.0.4 table 3.24
2704TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
2705{
2706 glActiveTexture(GL_TEXTURE0);
2707 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2708 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
2709 nullptr);
2710 EXPECT_GL_NO_ERROR();
2711
2712 drawQuad(mProgram, "position", 0.5f);
2713
2714 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2715}
2716
2717// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2718// ES 3.0.4 table 3.24
2719TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
2720{
2721 glActiveTexture(GL_TEXTURE0);
2722 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2723 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
2724 EXPECT_GL_NO_ERROR();
2725
2726 drawQuad(mProgram, "position", 0.5f);
2727
2728 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2729}
2730
2731// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2732// ES 3.0.4 table 3.24
2733TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
2734{
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002735 if (IsIntel() && IsLinux())
2736 {
2737 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
2738 std::cout << "Test disabled on Linux Intel OpenGL." << std::endl;
2739 return;
2740 }
2741
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002742 glActiveTexture(GL_TEXTURE0);
2743 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2744 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
2745 EXPECT_GL_NO_ERROR();
2746
2747 drawQuad(mProgram, "position", 0.5f);
2748
2749 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2750}
2751
Olli Etuaho96963162016-03-21 11:54:33 +02002752// Use a sampler in a uniform struct.
2753TEST_P(SamplerInStructTest, SamplerInStruct)
2754{
2755 runSamplerInStructTest();
2756}
2757
2758// Use a sampler in a uniform struct that's passed as a function parameter.
2759TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
2760{
Yuly Novikovad6c0452016-06-24 22:24:37 -04002761 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
2762 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2763 {
2764 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2765 return;
2766 }
Olli Etuaho96963162016-03-21 11:54:33 +02002767 runSamplerInStructTest();
2768}
2769
2770// Use a sampler in a uniform struct array with a struct from the array passed as a function
2771// parameter.
2772TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
2773{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002774 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2775 {
2776 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2777 return;
2778 }
Yuly Novikovad6c0452016-06-24 22:24:37 -04002779 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
2780 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2781 {
2782 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2783 return;
2784 }
Olli Etuaho96963162016-03-21 11:54:33 +02002785 runSamplerInStructTest();
2786}
2787
2788// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
2789// parameter.
2790TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
2791{
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002792 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
2793 {
2794 std::cout << "Test skipped on Intel OpenGL." << std::endl;
2795 return;
2796 }
Yuly Novikovad6c0452016-06-24 22:24:37 -04002797 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed
2798 if (IsAndroid() && IsAdreno() && IsOpenGLES())
2799 {
2800 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2801 return;
2802 }
Olli Etuaho96963162016-03-21 11:54:33 +02002803 runSamplerInStructTest();
2804}
2805
2806// Make sure that there isn't a name conflict between sampler extracted from a struct and a
2807// similarly named uniform.
2808TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
2809{
2810 runSamplerInStructTest();
2811}
2812
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002813class TextureLimitsTest : public ANGLETest
2814{
2815 protected:
2816 struct RGBA8
2817 {
2818 uint8_t R, G, B, A;
2819 };
2820
2821 TextureLimitsTest()
2822 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
2823 {
2824 setWindowWidth(128);
2825 setWindowHeight(128);
2826 setConfigRedBits(8);
2827 setConfigGreenBits(8);
2828 setConfigBlueBits(8);
2829 setConfigAlphaBits(8);
2830 }
2831
2832 ~TextureLimitsTest()
2833 {
2834 if (mProgram != 0)
2835 {
2836 glDeleteProgram(mProgram);
2837 mProgram = 0;
2838
2839 if (!mTextures.empty())
2840 {
2841 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
2842 }
2843 }
2844 }
2845
2846 void SetUp() override
2847 {
2848 ANGLETest::SetUp();
2849
2850 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
2851 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
2852 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
2853
2854 ASSERT_GL_NO_ERROR();
2855 }
2856
2857 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
2858 GLint vertexTextureCount,
2859 GLint vertexActiveTextureCount,
2860 const std::string &fragPrefix,
2861 GLint fragmentTextureCount,
2862 GLint fragmentActiveTextureCount)
2863 {
2864 std::stringstream vertexShaderStr;
2865 vertexShaderStr << "attribute vec2 position;\n"
2866 << "varying vec4 color;\n"
2867 << "varying vec2 texCoord;\n";
2868
2869 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
2870 {
2871 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
2872 }
2873
2874 vertexShaderStr << "void main() {\n"
2875 << " gl_Position = vec4(position, 0, 1);\n"
2876 << " texCoord = (position * 0.5) + 0.5;\n"
2877 << " color = vec4(0);\n";
2878
2879 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
2880 {
2881 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
2882 << ", texCoord);\n";
2883 }
2884
2885 vertexShaderStr << "}";
2886
2887 std::stringstream fragmentShaderStr;
2888 fragmentShaderStr << "varying mediump vec4 color;\n"
2889 << "varying mediump vec2 texCoord;\n";
2890
2891 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
2892 {
2893 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
2894 }
2895
2896 fragmentShaderStr << "void main() {\n"
2897 << " gl_FragColor = color;\n";
2898
2899 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
2900 {
2901 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
2902 << ", texCoord);\n";
2903 }
2904
2905 fragmentShaderStr << "}";
2906
2907 const std::string &vertexShaderSource = vertexShaderStr.str();
2908 const std::string &fragmentShaderSource = fragmentShaderStr.str();
2909
2910 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
2911 }
2912
2913 RGBA8 getPixel(GLint texIndex)
2914 {
2915 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
2916 0, 255u};
2917 return pixel;
2918 }
2919
2920 void initTextures(GLint tex2DCount, GLint texCubeCount)
2921 {
2922 GLint totalCount = tex2DCount + texCubeCount;
2923 mTextures.assign(totalCount, 0);
2924 glGenTextures(totalCount, &mTextures[0]);
2925 ASSERT_GL_NO_ERROR();
2926
2927 std::vector<RGBA8> texData(16 * 16);
2928
2929 GLint texIndex = 0;
2930 for (; texIndex < tex2DCount; ++texIndex)
2931 {
2932 texData.assign(texData.size(), getPixel(texIndex));
2933 glActiveTexture(GL_TEXTURE0 + texIndex);
2934 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
2935 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2936 &texData[0]);
2937 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2938 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2939 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2940 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2941 }
2942
2943 ASSERT_GL_NO_ERROR();
2944
2945 for (; texIndex < texCubeCount; ++texIndex)
2946 {
2947 texData.assign(texData.size(), getPixel(texIndex));
2948 glActiveTexture(GL_TEXTURE0 + texIndex);
2949 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
2950 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2951 GL_UNSIGNED_BYTE, &texData[0]);
2952 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2953 GL_UNSIGNED_BYTE, &texData[0]);
2954 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2955 GL_UNSIGNED_BYTE, &texData[0]);
2956 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2957 GL_UNSIGNED_BYTE, &texData[0]);
2958 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2959 GL_UNSIGNED_BYTE, &texData[0]);
2960 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
2961 GL_UNSIGNED_BYTE, &texData[0]);
2962 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2963 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2964 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2965 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2966 }
2967
2968 ASSERT_GL_NO_ERROR();
2969 }
2970
2971 void testWithTextures(GLint vertexTextureCount,
2972 const std::string &vertexTexturePrefix,
2973 GLint fragmentTextureCount,
2974 const std::string &fragmentTexturePrefix)
2975 {
2976 // Generate textures
2977 initTextures(vertexTextureCount + fragmentTextureCount, 0);
2978
2979 glUseProgram(mProgram);
2980 RGBA8 expectedSum = {0};
2981 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
2982 {
2983 std::stringstream uniformNameStr;
2984 uniformNameStr << vertexTexturePrefix << texIndex;
2985 const std::string &uniformName = uniformNameStr.str();
2986 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
2987 ASSERT_NE(-1, location);
2988
2989 glUniform1i(location, texIndex);
2990 RGBA8 contribution = getPixel(texIndex);
2991 expectedSum.R += contribution.R;
2992 expectedSum.G += contribution.G;
2993 }
2994
2995 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
2996 {
2997 std::stringstream uniformNameStr;
2998 uniformNameStr << fragmentTexturePrefix << texIndex;
2999 const std::string &uniformName = uniformNameStr.str();
3000 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
3001 ASSERT_NE(-1, location);
3002
3003 glUniform1i(location, texIndex + vertexTextureCount);
3004 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
3005 expectedSum.R += contribution.R;
3006 expectedSum.G += contribution.G;
3007 }
3008
3009 ASSERT_GE(256u, expectedSum.G);
3010
3011 drawQuad(mProgram, "position", 0.5f);
3012 ASSERT_GL_NO_ERROR();
3013 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
3014 }
3015
3016 GLuint mProgram;
3017 std::vector<GLuint> mTextures;
3018 GLint mMaxVertexTextures;
3019 GLint mMaxFragmentTextures;
3020 GLint mMaxCombinedTextures;
3021};
3022
3023// Test rendering with the maximum vertex texture units.
3024TEST_P(TextureLimitsTest, MaxVertexTextures)
3025{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003026 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003027 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003028 {
3029 std::cout << "Test skipped on Intel." << std::endl;
3030 return;
3031 }
3032
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003033 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
3034 ASSERT_NE(0u, mProgram);
3035 ASSERT_GL_NO_ERROR();
3036
3037 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3038}
3039
3040// Test rendering with the maximum fragment texture units.
3041TEST_P(TextureLimitsTest, MaxFragmentTextures)
3042{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003043 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003044 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003045 {
3046 std::cout << "Test skipped on Intel." << std::endl;
3047 return;
3048 }
3049
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003050 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
3051 ASSERT_NE(0u, mProgram);
3052 ASSERT_GL_NO_ERROR();
3053
3054 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
3055}
3056
3057// Test rendering with maximum combined texture units.
3058TEST_P(TextureLimitsTest, MaxCombinedTextures)
3059{
Jamie Madill412f17d2015-09-25 08:43:54 -04003060 // TODO(jmadill): Investigate workaround.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003061 if (IsIntel() && GetParam() == ES2_OPENGL())
Jamie Madill412f17d2015-09-25 08:43:54 -04003062 {
3063 std::cout << "Test skipped on Intel." << std::endl;
3064 return;
3065 }
3066
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003067 GLint vertexTextures = mMaxVertexTextures;
3068
3069 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
3070 {
3071 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
3072 }
3073
3074 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
3075 mMaxFragmentTextures, mMaxFragmentTextures);
3076 ASSERT_NE(0u, mProgram);
3077 ASSERT_GL_NO_ERROR();
3078
3079 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
3080}
3081
3082// Negative test for exceeding the number of vertex textures
3083TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
3084{
3085 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
3086 0);
3087 ASSERT_EQ(0u, mProgram);
3088}
3089
3090// Negative test for exceeding the number of fragment textures
3091TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
3092{
3093 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
3094 mMaxFragmentTextures + 1);
3095 ASSERT_EQ(0u, mProgram);
3096}
3097
3098// Test active vertex textures under the limit, but excessive textures specified.
3099TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
3100{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003101 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003102 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003103 {
3104 std::cout << "Test skipped on Intel." << std::endl;
3105 return;
3106 }
3107
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003108 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
3109 ASSERT_NE(0u, mProgram);
3110 ASSERT_GL_NO_ERROR();
3111
3112 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3113}
3114
3115// Test active fragment textures under the limit, but excessive textures specified.
3116TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
3117{
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003118 // TODO(jmadill): Figure out why this fails on Intel.
Jamie Madill518b9fa2016-03-02 11:26:02 -05003119 if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Jamie Madill1ea9aaa2015-10-07 11:13:55 -04003120 {
3121 std::cout << "Test skipped on Intel." << std::endl;
3122 return;
3123 }
3124
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003125 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
3126 mMaxFragmentTextures);
3127 ASSERT_NE(0u, mProgram);
3128 ASSERT_GL_NO_ERROR();
3129
3130 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
3131}
3132
3133// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003134// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003135TEST_P(TextureLimitsTest, TextureTypeConflict)
3136{
3137 const std::string &vertexShader =
3138 "attribute vec2 position;\n"
3139 "varying float color;\n"
3140 "uniform sampler2D tex2D;\n"
3141 "uniform samplerCube texCube;\n"
3142 "void main() {\n"
3143 " gl_Position = vec4(position, 0, 1);\n"
3144 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3145 " color = texture2D(tex2D, texCoord).x;\n"
3146 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
3147 "}";
3148 const std::string &fragmentShader =
3149 "varying mediump float color;\n"
3150 "void main() {\n"
3151 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3152 "}";
3153
3154 mProgram = CompileProgram(vertexShader, fragmentShader);
3155 ASSERT_NE(0u, mProgram);
3156
3157 initTextures(1, 0);
3158
3159 glUseProgram(mProgram);
3160 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3161 ASSERT_NE(-1, tex2DLocation);
3162 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
3163 ASSERT_NE(-1, texCubeLocation);
3164
3165 glUniform1i(tex2DLocation, 0);
3166 glUniform1i(texCubeLocation, 0);
3167 ASSERT_GL_NO_ERROR();
3168
3169 drawQuad(mProgram, "position", 0.5f);
3170 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3171}
3172
3173// Negative test for rendering with texture outside the valid range.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003174// TODO(jmadill): Possibly adjust the test according to the spec:
3175// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value
3176// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003177TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
3178{
3179 const std::string &vertexShader =
3180 "attribute vec2 position;\n"
3181 "varying float color;\n"
3182 "uniform sampler2D tex2D;\n"
3183 "void main() {\n"
3184 " gl_Position = vec4(position, 0, 1);\n"
3185 " vec2 texCoord = (position * 0.5) + 0.5;\n"
3186 " color = texture2D(tex2D, texCoord).x;\n"
3187 "}";
3188 const std::string &fragmentShader =
3189 "varying mediump float color;\n"
3190 "void main() {\n"
3191 " gl_FragColor = vec4(color, 0, 0, 1);\n"
3192 "}";
3193
3194 mProgram = CompileProgram(vertexShader, fragmentShader);
3195 ASSERT_NE(0u, mProgram);
3196
3197 glUseProgram(mProgram);
3198 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
3199 ASSERT_NE(-1, tex2DLocation);
3200
3201 glUniform1i(tex2DLocation, mMaxCombinedTextures);
3202 ASSERT_GL_NO_ERROR();
3203
3204 drawQuad(mProgram, "position", 0.5f);
3205 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3206}
3207
Vincent Lang25ab4512016-05-13 18:13:59 +02003208class Texture2DNorm16TestES3 : public Texture2DTestES3
3209{
3210 protected:
3211 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
3212
3213 void SetUp() override
3214 {
3215 Texture2DTestES3::SetUp();
3216
3217 glActiveTexture(GL_TEXTURE0);
3218 glGenTextures(3, mTextures);
3219 glGenFramebuffers(1, &mFBO);
3220 glGenRenderbuffers(1, &mRenderbuffer);
3221
3222 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
3223 {
3224 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
3225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3227 }
3228
3229 glBindTexture(GL_TEXTURE_2D, 0);
3230
3231 ASSERT_GL_NO_ERROR();
3232 }
3233
3234 void TearDown() override
3235 {
3236 glDeleteTextures(3, mTextures);
3237 glDeleteFramebuffers(1, &mFBO);
3238 glDeleteRenderbuffers(1, &mRenderbuffer);
3239
3240 Texture2DTestES3::TearDown();
3241 }
3242
3243 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
3244 {
3245 GLushort pixelValue = type == GL_SHORT ? 0x7FFF : 0x6A35;
3246 GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
3247
3248 setUpProgram();
3249
3250 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
3251 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
3252 0);
3253
3254 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
3255 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
3256
3257 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
3258 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
3259
3260 EXPECT_GL_NO_ERROR();
3261
3262 drawQuad(mProgram, "position", 0.5f);
3263
3264 GLColor16 expectedValue = imageData;
3265 if (type == GL_SHORT)
3266 {
3267 // sampled as signed value; then stored as unsigned value
3268 expectedValue = GLColor16::white;
3269 }
3270
3271 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
3272
3273 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3274
3275 ASSERT_GL_NO_ERROR();
3276 }
3277
3278 void testNorm16Render(GLint internalformat, GLenum format, GLenum type)
3279 {
3280 GLushort pixelValue = 0x6A35;
3281 GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
3282
3283 setUpProgram();
3284
3285 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
3286 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, nullptr);
3287
3288 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
3289 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
3290 0);
3291
3292 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
3293 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
3294
3295 EXPECT_GL_NO_ERROR();
3296
3297 drawQuad(mProgram, "position", 0.5f);
3298
3299 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, imageData));
3300
3301 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
3302 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
3303 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3304 mRenderbuffer);
3305 glBindRenderbuffer(GL_RENDERBUFFER, 0);
3306 EXPECT_GL_NO_ERROR();
3307
3308 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
3309 glClear(GL_COLOR_BUFFER_BIT);
3310
3311 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
3312
3313 GLColor16 expectedValue = GLColor16::white;
3314 EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
3315
3316 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3317
3318 ASSERT_GL_NO_ERROR();
3319 }
3320
3321 GLuint mTextures[3];
3322 GLuint mFBO;
3323 GLuint mRenderbuffer;
3324};
3325
3326// Test texture formats enabled by the GL_EXT_texture_norm16 extension.
3327TEST_P(Texture2DNorm16TestES3, TextureNorm16Test)
3328{
3329 if (!extensionEnabled("GL_EXT_texture_norm16"))
3330 {
3331 std::cout << "Test skipped due to missing GL_EXT_texture_norm16." << std::endl;
3332 return;
3333 }
3334
3335 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
3336 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
3337 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
3338 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
3339 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
3340 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
3341 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
3342 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
3343
3344 testNorm16Render(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
3345 testNorm16Render(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
3346 testNorm16Render(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
3347}
3348
Olli Etuaho95faa232016-06-07 14:01:53 -07003349// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
3350// GLES 3.0.4 section 3.8.3.
3351TEST_P(Texture2DTestES3, UnpackSkipImages2D)
3352{
Corentin Wallezc7f59d02016-06-20 10:12:08 -04003353 if (IsIntel() && IsDesktopOpenGL())
Olli Etuaho95faa232016-06-07 14:01:53 -07003354 {
3355 std::cout << "Test skipped on Intel OpenGL." << std::endl;
3356 return;
3357 }
Yuly Novikov3c754192016-06-27 19:36:41 -04003358 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1429 is fixed
3359 if (IsAndroid() && IsAdreno() && IsOpenGLES())
3360 {
3361 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
3362 return;
3363 }
Olli Etuaho95faa232016-06-07 14:01:53 -07003364
3365 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3368 ASSERT_GL_NO_ERROR();
3369
3370 // SKIP_IMAGES should not have an effect on uploading 2D textures
3371 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
3372 ASSERT_GL_NO_ERROR();
3373
3374 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
3375
3376 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3377 pixelsGreen.data());
3378 ASSERT_GL_NO_ERROR();
3379
3380 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
3381 pixelsGreen.data());
3382 ASSERT_GL_NO_ERROR();
3383
3384 glUseProgram(mProgram);
3385 drawQuad(mProgram, "position", 0.5f);
3386 ASSERT_GL_NO_ERROR();
3387
3388 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3389}
3390
Olli Etuaho989cac32016-06-08 16:18:49 -07003391// Test that skip defined in unpack parameters is taken into account when determining whether
3392// unpacking source extends outside unpack buffer bounds.
3393TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
3394{
3395 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3396 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3397 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3398 ASSERT_GL_NO_ERROR();
3399
3400 GLBuffer buf;
3401 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
3402 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
3403 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
3404 GL_DYNAMIC_COPY);
3405 ASSERT_GL_NO_ERROR();
3406
3407 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3408 ASSERT_GL_NO_ERROR();
3409
3410 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
3411 ASSERT_GL_NO_ERROR();
3412
3413 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3414 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3415
3416 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3417 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
3418 ASSERT_GL_NO_ERROR();
3419
3420 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3421 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3422}
3423
Olli Etuaho218cf9e2016-05-20 13:55:24 +03003424// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
3425TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
3426{
3427 if (IsD3D11())
3428 {
3429 std::cout << "Test skipped on D3D." << std::endl;
3430 return;
3431 }
3432 if (IsOSX() && IsAMD())
3433 {
3434 // Incorrect rendering results seen on OSX AMD.
3435 std::cout << "Test skipped on OSX AMD." << std::endl;
3436 return;
3437 }
3438
3439 const GLuint width = 8u;
3440 const GLuint height = 8u;
3441 const GLuint unpackRowLength = 5u;
3442 const GLuint unpackSkipPixels = 1u;
3443
3444 setWindowWidth(width);
3445 setWindowHeight(height);
3446
3447 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3448 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3449 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3450 ASSERT_GL_NO_ERROR();
3451
3452 GLBuffer buf;
3453 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
3454 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
3455 GLColor::green);
3456
3457 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
3458 {
3459 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
3460 }
3461
3462 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
3463 GL_DYNAMIC_COPY);
3464 ASSERT_GL_NO_ERROR();
3465
3466 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
3467 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
3468 ASSERT_GL_NO_ERROR();
3469
3470 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3471 ASSERT_GL_NO_ERROR();
3472
3473 glUseProgram(mProgram);
3474 drawQuad(mProgram, "position", 0.5f);
3475 ASSERT_GL_NO_ERROR();
3476
3477 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
3478 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
3479 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
3480 actual.data());
3481 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
3482 EXPECT_EQ(expected, actual);
3483}
3484
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04003485template <typename T>
3486T UNorm(double value)
3487{
3488 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
3489}
3490
3491// Test rendering a depth texture with mipmaps.
3492TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
3493{
3494 const int size = getWindowWidth();
3495
3496 auto dim = [size](int level) { return size >> level; };
3497 int levels = static_cast<int>(std::log2(size));
3498
3499 glActiveTexture(GL_TEXTURE0);
3500 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3501 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
3502 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3503 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3504 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3505 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3506 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3507 ASSERT_GL_NO_ERROR();
3508
3509 glUseProgram(mProgram);
3510 glUniform1i(mTexture2DUniformLocation, 0);
3511
3512 std::vector<unsigned char> expected;
3513
3514 for (int level = 0; level < levels; ++level)
3515 {
3516 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
3517 expected.push_back(UNorm<unsigned char>(value));
3518
3519 int levelDim = dim(level);
3520
3521 ASSERT_GT(levelDim, 0);
3522
3523 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
3524 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
3525 GL_UNSIGNED_INT, initData.data());
3526 }
3527 ASSERT_GL_NO_ERROR();
3528
3529 for (int level = 0; level < levels; ++level)
3530 {
3531 glViewport(0, 0, dim(level), dim(level));
3532 drawQuad(mProgram, "position", 0.5f);
3533 GLColor actual = ReadColor(0, 0);
3534 EXPECT_NEAR(expected[level], actual.R, 10u);
3535 }
3536
3537 ASSERT_GL_NO_ERROR();
3538}
3539
Jamie Madillfa05f602015-05-07 13:47:11 -04003540// 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 +02003541// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278.
Geoff Lange0cc2a42016-01-20 10:58:17 -05003542ANGLE_INSTANTIATE_TEST(Texture2DTest,
3543 ES2_D3D9(),
3544 ES2_D3D11(),
3545 ES2_D3D11_FL9_3(),
3546 ES2_OPENGL(),
3547 ES2_OPENGLES());
3548ANGLE_INSTANTIATE_TEST(TextureCubeTest,
3549 ES2_D3D9(),
3550 ES2_D3D11(),
3551 ES2_D3D11_FL9_3(),
3552 ES2_OPENGL(),
3553 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003554ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale,
3555 ES2_D3D9(),
3556 ES2_D3D11(),
3557 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003558 ES2_OPENGL(),
3559 ES2_OPENGLES());
Olli Etuaho51f1c0f2016-01-13 16:16:24 +02003560ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest,
3561 ES2_D3D9(),
3562 ES2_D3D11(),
3563 ES2_D3D11_FL9_3(),
Geoff Lange0cc2a42016-01-20 10:58:17 -05003564 ES2_OPENGL(),
3565 ES2_OPENGLES());
3566ANGLE_INSTANTIATE_TEST(SamplerArrayTest,
3567 ES2_D3D9(),
3568 ES2_D3D11(),
3569 ES2_D3D11_FL9_3(),
3570 ES2_OPENGL(),
3571 ES2_OPENGLES());
3572ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest,
3573 ES2_D3D9(),
3574 ES2_D3D11(),
3575 ES2_D3D11_FL9_3(),
3576 ES2_OPENGL(),
3577 ES2_OPENGLES());
3578ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahoa314b612016-03-10 16:43:00 +02003579ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003580ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3581ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3,
3582 ES3_D3D11(),
3583 ES3_OPENGL(),
3584 ES3_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003585ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3,
3586 ES3_D3D11(),
3587 ES3_OPENGL(),
3588 ES3_OPENGLES());
3589ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
3590ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahobce743a2016-01-15 17:18:28 +02003591ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL());
Olli Etuaho96963162016-03-21 11:54:33 +02003592ANGLE_INSTANTIATE_TEST(SamplerInStructTest,
3593 ES2_D3D11(),
3594 ES2_D3D11_FL9_3(),
3595 ES2_D3D9(),
3596 ES2_OPENGL(),
3597 ES2_OPENGLES());
3598ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest,
3599 ES2_D3D11(),
3600 ES2_D3D11_FL9_3(),
3601 ES2_D3D9(),
3602 ES2_OPENGL(),
3603 ES2_OPENGLES());
3604ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest,
3605 ES2_D3D11(),
3606 ES2_D3D11_FL9_3(),
3607 ES2_D3D9(),
3608 ES2_OPENGL(),
3609 ES2_OPENGLES());
3610ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest,
3611 ES2_D3D11(),
3612 ES2_D3D11_FL9_3(),
3613 ES2_D3D9(),
3614 ES2_OPENGL(),
3615 ES2_OPENGLES());
3616ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest,
3617 ES2_D3D11(),
3618 ES2_D3D11_FL9_3(),
3619 ES2_D3D9(),
3620 ES2_OPENGL(),
3621 ES2_OPENGLES());
Geoff Lange0cc2a42016-01-20 10:58:17 -05003622ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
Vincent Lang25ab4512016-05-13 18:13:59 +02003623ANGLE_INSTANTIATE_TEST(Texture2DNorm16TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04003624
3625} // namespace