blob: 46d866b18ab521e7c1f81214d356a7a3acb0718f [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Jamie Madill14718762016-09-06 15:56:54 -04007#include "common/mathutil.h"
Corentin Wallezd3970de2015-05-14 11:07:48 -04008#include "test_utils/ANGLETest.h"
Olli Etuaho989cac32016-06-08 16:18:49 -07009#include "test_utils/gl_raii.h"
Jamie Madillf67115c2014-04-22 13:14:05 -040010
Jamie Madillfa05f602015-05-07 13:47:11 -040011using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070012
Jamie Madillfa05f602015-05-07 13:47:11 -040013namespace
14{
15
Mohan Maiya6caa2652019-09-11 08:06:13 -070016constexpr GLuint kPixelTolerance = 1u;
17constexpr GLfloat kPixelTolerance32F = 0.01f;
Mohan Maiya8f1169e2019-06-27 15:32:32 -070018
Jamie Madillfc3ec572019-11-27 21:43:22 +000019// Single compressed ETC2 block of source pixels all set red
20constexpr uint8_t kCompressedImageETC2[] = {0x7E, 0x80, 0x04, 0x7F, 0x00, 0x07, 0xE0, 0x00};
21
Vincent Lang25ab4512016-05-13 18:13:59 +020022// Take a pixel, and reset the components not covered by the format to default
Geoff Langf607c602016-09-21 11:46:48 -040023// values. In particular, the default value for the alpha component is 255
Vincent Lang25ab4512016-05-13 18:13:59 +020024// (1.0 as unsigned normalized fixed point value).
Mohan Maiya6caa2652019-09-11 08:06:13 -070025// For legacy formats, the components may be reordered to match the color that
26// would be created if a pixel of that format was initialized from the given color
Geoff Langf607c602016-09-21 11:46:48 -040027GLColor SliceFormatColor(GLenum format, GLColor full)
Vincent Lang25ab4512016-05-13 18:13:59 +020028{
29 switch (format)
30 {
31 case GL_RED:
Geoff Langf607c602016-09-21 11:46:48 -040032 return GLColor(full.R, 0, 0, 255u);
Vincent Lang25ab4512016-05-13 18:13:59 +020033 case GL_RG:
Geoff Langf607c602016-09-21 11:46:48 -040034 return GLColor(full.R, full.G, 0, 255u);
Vincent Lang25ab4512016-05-13 18:13:59 +020035 case GL_RGB:
Geoff Langf607c602016-09-21 11:46:48 -040036 return GLColor(full.R, full.G, full.B, 255u);
Vincent Lang25ab4512016-05-13 18:13:59 +020037 case GL_RGBA:
38 return full;
Mohan Maiya6caa2652019-09-11 08:06:13 -070039 case GL_LUMINANCE:
40 return GLColor(full.R, full.R, full.R, 255u);
41 case GL_ALPHA:
42 return GLColor(0, 0, 0, full.R);
43 case GL_LUMINANCE_ALPHA:
44 return GLColor(full.R, full.R, full.R, full.G);
Vincent Lang25ab4512016-05-13 18:13:59 +020045 default:
Jamie Madille1faacb2016-12-13 12:42:14 -050046 EXPECT_TRUE(false);
Geoff Langf607c602016-09-21 11:46:48 -040047 return GLColor::white;
Vincent Lang25ab4512016-05-13 18:13:59 +020048 }
Vincent Lang25ab4512016-05-13 18:13:59 +020049}
50
shrekshaofb1c2fe2019-11-13 11:10:39 -080051GLColor16UI SliceFormatColor16UI(GLenum format, GLColor16UI full)
52{
53 switch (format)
54 {
55 case GL_RED:
56 return GLColor16UI(full.R, 0, 0, 0xFFFF);
57 case GL_RG:
58 return GLColor16UI(full.R, full.G, 0, 0xFFFF);
59 case GL_RGB:
60 return GLColor16UI(full.R, full.G, full.B, 0xFFFF);
61 case GL_RGBA:
62 return full;
63 case GL_LUMINANCE:
64 return GLColor16UI(full.R, full.R, full.R, 0xFFFF);
65 case GL_ALPHA:
66 return GLColor16UI(0, 0, 0, full.R);
67 case GL_LUMINANCE_ALPHA:
68 return GLColor16UI(full.R, full.R, full.R, full.G);
69 default:
70 EXPECT_TRUE(false);
71 return GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
72 }
73}
74
Mohan Maiya6caa2652019-09-11 08:06:13 -070075// As above, for 32F colors
76GLColor32F SliceFormatColor32F(GLenum format, GLColor32F full)
77{
78 switch (format)
79 {
80 case GL_RED:
81 return GLColor32F(full.R, 0.0f, 0.0f, 1.0f);
82 case GL_RG:
83 return GLColor32F(full.R, full.G, 0.0f, 1.0f);
84 case GL_RGB:
85 return GLColor32F(full.R, full.G, full.B, 1.0f);
86 case GL_RGBA:
87 return full;
88 case GL_LUMINANCE:
89 return GLColor32F(full.R, full.R, full.R, 1.0f);
90 case GL_ALPHA:
91 return GLColor32F(0.0f, 0.0f, 0.0f, full.R);
92 case GL_LUMINANCE_ALPHA:
93 return GLColor32F(full.R, full.R, full.R, full.G);
94 default:
95 EXPECT_TRUE(false);
96 return GLColor32F(1.0f, 1.0f, 1.0f, 1.0f);
97 }
98}
99
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200100class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -0400101{
Jamie Madillbc393df2015-01-29 13:46:07 -0500102 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200103 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -0400104 {
105 setWindowWidth(128);
106 setWindowHeight(128);
107 setConfigRedBits(8);
108 setConfigGreenBits(8);
109 setConfigBlueBits(8);
110 setConfigAlphaBits(8);
111 }
112
Jamie Madill35cd7332018-12-02 12:03:33 -0500113 virtual const char *getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -0400114 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500115 return R"(precision highp float;
116attribute vec4 position;
117varying vec2 texcoord;
Geoff Langc41e42d2014-04-28 10:58:16 -0400118
Jamie Madill35cd7332018-12-02 12:03:33 -0500119void main()
120{
121 gl_Position = vec4(position.xy, 0.0, 1.0);
122 texcoord = (position.xy * 0.5) + 0.5;
123})";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200124 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400125
Jamie Madill35cd7332018-12-02 12:03:33 -0500126 virtual const char *getFragmentShaderSource() = 0;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200127
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300128 virtual void setUpProgram()
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200129 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500130 const char *vertexShaderSource = getVertexShaderSource();
131 const char *fragmentShaderSource = getFragmentShaderSource();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200132
133 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
134 ASSERT_NE(0u, mProgram);
135 ASSERT_GL_NO_ERROR();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300136 }
137
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400138 void testSetUp() override { setUpFramebuffer(); }
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200139
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400140 void testTearDown() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200141 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200142 glBindFramebuffer(GL_FRAMEBUFFER, 0);
143 glDeleteFramebuffers(1, &mFramebuffer);
144 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200145 glDeleteProgram(mProgram);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200146 }
147
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200148 void setUpFramebuffer()
149 {
150 // We use an FBO to work around an issue where the default framebuffer applies SRGB
151 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
152 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
153 // section 4.4 says that the format of the default framebuffer is entirely up to the window
154 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
155 // SRGB conversion like desktop GL does.
156 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
157 glGenFramebuffers(1, &mFramebuffer);
158 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
159
160 glGenTextures(1, &mFramebufferColorTexture);
161 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
162 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
163 GL_UNSIGNED_BYTE, nullptr);
164 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
165 mFramebufferColorTexture, 0);
166 ASSERT_GL_NO_ERROR();
167 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
168 glBindTexture(GL_TEXTURE_2D, 0);
169 }
170
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200171 // Returns the created texture ID.
172 GLuint create2DTexture()
173 {
174 GLuint texture2D;
175 glGenTextures(1, &texture2D);
176 glBindTexture(GL_TEXTURE_2D, texture2D);
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800177 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200178 EXPECT_GL_NO_ERROR();
179 return texture2D;
180 }
181
182 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200183 GLuint mFramebuffer;
184
185 private:
186 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200187};
188
189class Texture2DTest : public TexCoordDrawTest
190{
191 protected:
192 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
193
Jamie Madill35cd7332018-12-02 12:03:33 -0500194 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200195 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500196 return R"(precision highp float;
197uniform sampler2D tex;
198varying vec2 texcoord;
Geoff Langc41e42d2014-04-28 10:58:16 -0400199
Jamie Madill35cd7332018-12-02 12:03:33 -0500200void main()
201{
202 gl_FragColor = texture2D(tex, texcoord);
203})";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200204 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400205
Olli Etuaho96963162016-03-21 11:54:33 +0200206 virtual const char *getTextureUniformName() { return "tex"; }
207
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300208 void setUpProgram() override
209 {
210 TexCoordDrawTest::setUpProgram();
211 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
212 ASSERT_NE(-1, mTexture2DUniformLocation);
213 }
214
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400215 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200216 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400217 TexCoordDrawTest::testSetUp();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200218 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400219
Jamie Madill9aca0592014-10-06 16:26:59 -0400220 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -0400221 }
222
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400223 void testTearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400224 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400225 glDeleteTextures(1, &mTexture2D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400226 TexCoordDrawTest::testTearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400227 }
228
Jamie Madillbc393df2015-01-29 13:46:07 -0500229 // Tests CopyTexSubImage with floating point textures of various formats.
230 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
231 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300232 setUpProgram();
233
Martin Radev1be913c2016-07-11 17:59:16 +0300234 if (getClientMajorVersion() < 3)
Geoff Langfbfa47c2015-03-31 11:26:00 -0400235 {
Jamie Madillb8149072019-04-30 16:14:44 -0400236 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
237 !IsGLExtensionEnabled("GL_OES_texture_float"));
Geoff Langc4e93662017-05-01 10:45:59 -0400238
Yunchao He9550c602018-02-13 14:47:05 +0800239 ANGLE_SKIP_TEST_IF((sourceImageChannels < 3 || destImageChannels < 3) &&
Jamie Madillb8149072019-04-30 16:14:44 -0400240 !IsGLExtensionEnabled("GL_EXT_texture_rg"));
Geoff Langfbfa47c2015-03-31 11:26:00 -0400241
Yunchao He9550c602018-02-13 14:47:05 +0800242 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
Jamie Madillb8149072019-04-30 16:14:44 -0400243 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
Geoff Lang677bb6f2017-04-05 12:40:40 -0400244
Yunchao He9550c602018-02-13 14:47:05 +0800245 ANGLE_SKIP_TEST_IF(destImageChannels == 4 &&
Jamie Madillb8149072019-04-30 16:14:44 -0400246 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"));
Geoff Lang677bb6f2017-04-05 12:40:40 -0400247
Yunchao He9550c602018-02-13 14:47:05 +0800248 ANGLE_SKIP_TEST_IF(destImageChannels <= 2);
Geoff Lang677bb6f2017-04-05 12:40:40 -0400249 }
250 else
251 {
Jamie Madillb8149072019-04-30 16:14:44 -0400252 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_color_buffer_float"));
Geoff Lang677bb6f2017-04-05 12:40:40 -0400253
Yunchao He9550c602018-02-13 14:47:05 +0800254 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
Jamie Madillb8149072019-04-30 16:14:44 -0400255 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
Geoff Langfbfa47c2015-03-31 11:26:00 -0400256 }
257
Jamie Madill50cf2be2018-06-15 09:46:57 -0400258 // clang-format off
Jamie Madillbc393df2015-01-29 13:46:07 -0500259 GLfloat sourceImageData[4][16] =
260 {
261 { // R
262 1.0f,
263 0.0f,
264 0.0f,
265 1.0f
266 },
267 { // RG
268 1.0f, 0.0f,
269 0.0f, 1.0f,
270 0.0f, 0.0f,
271 1.0f, 1.0f
272 },
273 { // RGB
274 1.0f, 0.0f, 0.0f,
275 0.0f, 1.0f, 0.0f,
276 0.0f, 0.0f, 1.0f,
277 1.0f, 1.0f, 0.0f
278 },
279 { // RGBA
280 1.0f, 0.0f, 0.0f, 1.0f,
281 0.0f, 1.0f, 0.0f, 1.0f,
282 0.0f, 0.0f, 1.0f, 1.0f,
283 1.0f, 1.0f, 0.0f, 1.0f
284 },
285 };
Jamie Madill50cf2be2018-06-15 09:46:57 -0400286 // clang-format on
Jamie Madillbc393df2015-01-29 13:46:07 -0500287
Jamie Madill50cf2be2018-06-15 09:46:57 -0400288 GLenum imageFormats[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500289 GL_R32F,
290 GL_RG32F,
291 GL_RGB32F,
292 GL_RGBA32F,
Jamie Madillbc393df2015-01-29 13:46:07 -0500293 };
294
Jamie Madill50cf2be2018-06-15 09:46:57 -0400295 GLenum sourceUnsizedFormats[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500296 GL_RED,
297 GL_RG,
298 GL_RGB,
299 GL_RGBA,
Jamie Madillbc393df2015-01-29 13:46:07 -0500300 };
301
302 GLuint textures[2];
303
304 glGenTextures(2, textures);
305
Jamie Madill50cf2be2018-06-15 09:46:57 -0400306 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
307 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
Jamie Madillbc393df2015-01-29 13:46:07 -0500308 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
Jamie Madill50cf2be2018-06-15 09:46:57 -0400309 GLenum destImageFormat = imageFormats[destImageChannels - 1];
Jamie Madillbc393df2015-01-29 13:46:07 -0500310
311 glBindTexture(GL_TEXTURE_2D, textures[0]);
Geoff Langc4e93662017-05-01 10:45:59 -0400312 if (getClientMajorVersion() >= 3)
313 {
314 glTexStorage2D(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
315 }
316 else
317 {
318 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
319 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500320 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
321 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
322 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
323
Jamie Madillb8149072019-04-30 16:14:44 -0400324 if (sourceImageChannels < 3 && !IsGLExtensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500325 {
326 // This is not supported
327 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
328 }
329 else
330 {
331 ASSERT_GL_NO_ERROR();
332 }
333
334 GLuint fbo;
335 glGenFramebuffers(1, &fbo);
336 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
337 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
338
339 glBindTexture(GL_TEXTURE_2D, textures[1]);
Geoff Langc4e93662017-05-01 10:45:59 -0400340 if (getClientMajorVersion() >= 3)
341 {
342 glTexStorage2D(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
343 }
344 else
345 {
346 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
347 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500348 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350
351 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
352 ASSERT_GL_NO_ERROR();
353
354 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200355 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500356
357 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
358
Olli Etuahoa314b612016-03-10 16:43:00 +0200359 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Jamie Madillbc393df2015-01-29 13:46:07 -0500360 if (testImageChannels > 1)
361 {
362 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
363 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
364 if (testImageChannels > 2)
365 {
366 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
367 }
368 }
369
370 glDeleteFramebuffers(1, &fbo);
371 glDeleteTextures(2, textures);
372
373 ASSERT_GL_NO_ERROR();
374 }
375
Jamie Madilld4cfa572014-07-08 10:00:32 -0400376 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400377 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400378};
379
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200380class Texture2DTestES3 : public Texture2DTest
381{
382 protected:
383 Texture2DTestES3() : Texture2DTest() {}
384
Jamie Madill35cd7332018-12-02 12:03:33 -0500385 const char *getVertexShaderSource() override
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200386 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500387 return "#version 300 es\n"
388 "out vec2 texcoord;\n"
389 "in vec4 position;\n"
390 "void main()\n"
391 "{\n"
392 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
393 " texcoord = (position.xy * 0.5) + 0.5;\n"
394 "}\n";
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200395 }
396
Jamie Madill35cd7332018-12-02 12:03:33 -0500397 const char *getFragmentShaderSource() override
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200398 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500399 return "#version 300 es\n"
400 "precision highp float;\n"
401 "uniform highp sampler2D tex;\n"
402 "in vec2 texcoord;\n"
403 "out vec4 fragColor;\n"
404 "void main()\n"
405 "{\n"
406 " fragColor = texture(tex, texcoord);\n"
407 "}\n";
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200408 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300409
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400410 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300411 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400412 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300413 setUpProgram();
414 }
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200415};
416
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200417class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
418{
419 protected:
420 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
421
Jamie Madill35cd7332018-12-02 12:03:33 -0500422 const char *getVertexShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200423 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500424 return "#version 300 es\n"
425 "out vec2 texcoord;\n"
426 "in vec4 position;\n"
427 "void main()\n"
428 "{\n"
429 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
430 " texcoord = (position.xy * 0.5) + 0.5;\n"
431 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200432 }
433
Jamie Madill35cd7332018-12-02 12:03:33 -0500434 const char *getFragmentShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200435 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500436 return "#version 300 es\n"
437 "precision highp float;\n"
438 "uniform highp isampler2D tex;\n"
439 "in vec2 texcoord;\n"
440 "out vec4 fragColor;\n"
441 "void main()\n"
442 "{\n"
443 " vec4 green = vec4(0, 1, 0, 1);\n"
444 " vec4 black = vec4(0, 0, 0, 0);\n"
445 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
446 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200447 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300448
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400449 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300450 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400451 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300452 setUpProgram();
453 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200454};
455
456class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
457{
458 protected:
459 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
460
Jamie Madill35cd7332018-12-02 12:03:33 -0500461 const char *getVertexShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200462 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500463 return "#version 300 es\n"
464 "out vec2 texcoord;\n"
465 "in vec4 position;\n"
466 "void main()\n"
467 "{\n"
468 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
469 " texcoord = (position.xy * 0.5) + 0.5;\n"
470 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200471 }
472
Jamie Madill35cd7332018-12-02 12:03:33 -0500473 const char *getFragmentShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200474 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500475 return "#version 300 es\n"
476 "precision highp float;\n"
477 "uniform highp usampler2D tex;\n"
478 "in vec2 texcoord;\n"
479 "out vec4 fragColor;\n"
480 "void main()\n"
481 "{\n"
482 " vec4 green = vec4(0, 1, 0, 1);\n"
483 " vec4 black = vec4(0, 0, 0, 0);\n"
484 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
485 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200486 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300487
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400488 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300489 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400490 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300491 setUpProgram();
492 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200493};
494
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200495class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400496{
497 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200498 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
499
Jamie Madill35cd7332018-12-02 12:03:33 -0500500 const char *getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400501 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300502 return
503 R"(precision highp float;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200504 attribute vec4 position;
505 varying vec2 texcoord;
506
507 uniform vec2 drawScale;
508
509 void main()
510 {
511 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
512 texcoord = (position.xy * 0.5) + 0.5;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300513 })";
Jamie Madill2453dbc2015-07-14 11:35:42 -0400514 }
515
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400516 void testSetUp() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400517 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400518 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300519
520 setUpProgram();
521
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200522 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
523 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400524
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200525 glUseProgram(mProgram);
526 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
527 glUseProgram(0);
528 ASSERT_GL_NO_ERROR();
529 }
530
531 GLint mDrawScaleUniformLocation;
532};
533
Olli Etuaho4644a202016-01-12 15:12:53 +0200534class Sampler2DAsFunctionParameterTest : public Texture2DTest
535{
536 protected:
537 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
538
Jamie Madill35cd7332018-12-02 12:03:33 -0500539 const char *getFragmentShaderSource() override
Olli Etuaho4644a202016-01-12 15:12:53 +0200540 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300541 return
542 R"(precision highp float;
Olli Etuaho4644a202016-01-12 15:12:53 +0200543 uniform sampler2D tex;
544 varying vec2 texcoord;
545
546 vec4 computeFragColor(sampler2D aTex)
547 {
548 return texture2D(aTex, texcoord);
549 }
550
551 void main()
552 {
553 gl_FragColor = computeFragColor(tex);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300554 })";
Olli Etuaho4644a202016-01-12 15:12:53 +0200555 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300556
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400557 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300558 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400559 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300560 setUpProgram();
561 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200562};
563
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200564class TextureCubeTest : public TexCoordDrawTest
565{
566 protected:
567 TextureCubeTest()
568 : TexCoordDrawTest(),
569 mTexture2D(0),
570 mTextureCube(0),
571 mTexture2DUniformLocation(-1),
572 mTextureCubeUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500573 {}
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200574
Jamie Madill35cd7332018-12-02 12:03:33 -0500575 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200576 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300577 return
578 R"(precision highp float;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200579 uniform sampler2D tex2D;
580 uniform samplerCube texCube;
581 varying vec2 texcoord;
582
583 void main()
584 {
585 gl_FragColor = texture2D(tex2D, texcoord);
586 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300587 })";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200588 }
589
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400590 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200591 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400592 TexCoordDrawTest::testSetUp();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200593
594 glGenTextures(1, &mTextureCube);
595 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Geoff Langc4e93662017-05-01 10:45:59 -0400596 for (GLenum face = 0; face < 6; face++)
597 {
598 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
599 GL_UNSIGNED_BYTE, nullptr);
600 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200601 EXPECT_GL_NO_ERROR();
602
603 mTexture2D = create2DTexture();
604
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300605 setUpProgram();
606
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200607 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
608 ASSERT_NE(-1, mTexture2DUniformLocation);
609 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
610 ASSERT_NE(-1, mTextureCubeUniformLocation);
611 }
612
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400613 void testTearDown() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200614 {
615 glDeleteTextures(1, &mTextureCube);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400616 TexCoordDrawTest::testTearDown();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200617 }
618
619 GLuint mTexture2D;
620 GLuint mTextureCube;
621 GLint mTexture2DUniformLocation;
622 GLint mTextureCubeUniformLocation;
623};
624
Martin Radev7e2c0d32017-09-15 14:25:42 +0300625class TextureCubeTestES3 : public ANGLETest
626{
627 protected:
628 TextureCubeTestES3() {}
629};
630
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200631class SamplerArrayTest : public TexCoordDrawTest
632{
633 protected:
634 SamplerArrayTest()
635 : TexCoordDrawTest(),
636 mTexture2DA(0),
637 mTexture2DB(0),
638 mTexture0UniformLocation(-1),
639 mTexture1UniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500640 {}
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200641
Jamie Madill35cd7332018-12-02 12:03:33 -0500642 const char *getFragmentShaderSource() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200643 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300644 return
645 R"(precision mediump float;
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200646 uniform highp sampler2D tex2DArray[2];
647 varying vec2 texcoord;
648 void main()
649 {
650 gl_FragColor = texture2D(tex2DArray[0], texcoord);
651 gl_FragColor += texture2D(tex2DArray[1], texcoord);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300652 })";
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200653 }
654
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400655 void testSetUp() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200656 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400657 TexCoordDrawTest::testSetUp();
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200658
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300659 setUpProgram();
660
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200661 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
662 ASSERT_NE(-1, mTexture0UniformLocation);
663 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
664 ASSERT_NE(-1, mTexture1UniformLocation);
665
666 mTexture2DA = create2DTexture();
667 mTexture2DB = create2DTexture();
668 ASSERT_GL_NO_ERROR();
669 }
670
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400671 void testTearDown() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200672 {
673 glDeleteTextures(1, &mTexture2DA);
674 glDeleteTextures(1, &mTexture2DB);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400675 TexCoordDrawTest::testTearDown();
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200676 }
677
678 void testSamplerArrayDraw()
679 {
680 GLubyte texData[4];
681 texData[0] = 0;
682 texData[1] = 60;
683 texData[2] = 0;
684 texData[3] = 255;
685
686 glActiveTexture(GL_TEXTURE0);
687 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
688 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
689
690 texData[1] = 120;
691 glActiveTexture(GL_TEXTURE1);
692 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
693 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
694 EXPECT_GL_ERROR(GL_NO_ERROR);
695
696 glUseProgram(mProgram);
697 glUniform1i(mTexture0UniformLocation, 0);
698 glUniform1i(mTexture1UniformLocation, 1);
699 drawQuad(mProgram, "position", 0.5f);
700 EXPECT_GL_NO_ERROR();
701
702 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
703 }
704
705 GLuint mTexture2DA;
706 GLuint mTexture2DB;
707 GLint mTexture0UniformLocation;
708 GLint mTexture1UniformLocation;
709};
710
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200711class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
712{
713 protected:
714 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
715
Jamie Madill35cd7332018-12-02 12:03:33 -0500716 const char *getFragmentShaderSource() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200717 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300718 return
719 R"(precision mediump float;
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200720 uniform highp sampler2D tex2DArray[2];
721 varying vec2 texcoord;
722
723 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
724 {
725 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
726 }
727
728 void main()
729 {
730 gl_FragColor = computeFragColor(tex2DArray);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300731 })";
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200732 }
733};
734
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200735class Texture2DArrayTestES3 : public TexCoordDrawTest
736{
737 protected:
738 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
739
Jamie Madill35cd7332018-12-02 12:03:33 -0500740 const char *getVertexShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200741 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500742 return "#version 300 es\n"
743 "out vec2 texcoord;\n"
744 "in vec4 position;\n"
745 "void main()\n"
746 "{\n"
747 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
748 " texcoord = (position.xy * 0.5) + 0.5;\n"
749 "}\n";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200750 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400751
Jamie Madill35cd7332018-12-02 12:03:33 -0500752 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200753 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500754 return "#version 300 es\n"
755 "precision highp float;\n"
756 "uniform highp sampler2DArray tex2DArray;\n"
757 "in vec2 texcoord;\n"
758 "out vec4 fragColor;\n"
759 "void main()\n"
760 "{\n"
761 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
762 "}\n";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200763 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400764
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400765 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200766 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400767 TexCoordDrawTest::testSetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400768
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300769 setUpProgram();
770
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200771 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400772 ASSERT_NE(-1, mTextureArrayLocation);
773
774 glGenTextures(1, &m2DArrayTexture);
775 ASSERT_GL_NO_ERROR();
776 }
777
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400778 void testTearDown() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400779 {
780 glDeleteTextures(1, &m2DArrayTexture);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400781 TexCoordDrawTest::testTearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400782 }
783
784 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400785 GLint mTextureArrayLocation;
786};
787
Olli Etuahobce743a2016-01-15 17:18:28 +0200788class TextureSizeTextureArrayTest : public TexCoordDrawTest
789{
790 protected:
791 TextureSizeTextureArrayTest()
792 : TexCoordDrawTest(),
793 mTexture2DA(0),
794 mTexture2DB(0),
795 mTexture0Location(-1),
796 mTexture1Location(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500797 {}
Olli Etuahobce743a2016-01-15 17:18:28 +0200798
Jamie Madill35cd7332018-12-02 12:03:33 -0500799 const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
Olli Etuahobce743a2016-01-15 17:18:28 +0200800
Jamie Madill35cd7332018-12-02 12:03:33 -0500801 const char *getFragmentShaderSource() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200802 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500803 return "#version 300 es\n"
804 "precision highp float;\n"
805 "uniform highp sampler2D tex2DArray[2];\n"
806 "out vec4 fragColor;\n"
807 "void main()\n"
808 "{\n"
809 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
810 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
811 " fragColor = vec4(red, green, 0.0, 1.0);\n"
812 "}\n";
Olli Etuahobce743a2016-01-15 17:18:28 +0200813 }
814
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400815 void testSetUp() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200816 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400817 TexCoordDrawTest::testSetUp();
Olli Etuahobce743a2016-01-15 17:18:28 +0200818
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300819 setUpProgram();
820
Olli Etuahobce743a2016-01-15 17:18:28 +0200821 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
822 ASSERT_NE(-1, mTexture0Location);
823 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
824 ASSERT_NE(-1, mTexture1Location);
825
826 mTexture2DA = create2DTexture();
827 mTexture2DB = create2DTexture();
828 ASSERT_GL_NO_ERROR();
829 }
830
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400831 void testTearDown() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200832 {
833 glDeleteTextures(1, &mTexture2DA);
834 glDeleteTextures(1, &mTexture2DB);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400835 TexCoordDrawTest::testTearDown();
Olli Etuahobce743a2016-01-15 17:18:28 +0200836 }
837
838 GLuint mTexture2DA;
839 GLuint mTexture2DB;
840 GLint mTexture0Location;
841 GLint mTexture1Location;
842};
843
Olli Etuahoa314b612016-03-10 16:43:00 +0200844class Texture3DTestES3 : public TexCoordDrawTest
845{
846 protected:
847 Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
848
Jamie Madill35cd7332018-12-02 12:03:33 -0500849 const char *getVertexShaderSource() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200850 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500851 return "#version 300 es\n"
852 "out vec2 texcoord;\n"
853 "in vec4 position;\n"
854 "void main()\n"
855 "{\n"
856 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
857 " texcoord = (position.xy * 0.5) + 0.5;\n"
858 "}\n";
Olli Etuahoa314b612016-03-10 16:43:00 +0200859 }
860
Jamie Madill35cd7332018-12-02 12:03:33 -0500861 const char *getFragmentShaderSource() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200862 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500863 return "#version 300 es\n"
864 "precision highp float;\n"
865 "uniform highp sampler3D tex3D;\n"
866 "in vec2 texcoord;\n"
867 "out vec4 fragColor;\n"
868 "void main()\n"
869 "{\n"
870 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
871 "}\n";
Olli Etuahoa314b612016-03-10 16:43:00 +0200872 }
873
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400874 void testSetUp() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200875 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400876 TexCoordDrawTest::testSetUp();
Olli Etuahoa314b612016-03-10 16:43:00 +0200877
878 glGenTextures(1, &mTexture3D);
879
880 setUpProgram();
881
882 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
883 ASSERT_NE(-1, mTexture3DUniformLocation);
884 }
885
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400886 void testTearDown() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200887 {
888 glDeleteTextures(1, &mTexture3D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400889 TexCoordDrawTest::testTearDown();
Olli Etuahoa314b612016-03-10 16:43:00 +0200890 }
891
892 GLuint mTexture3D;
893 GLint mTexture3DUniformLocation;
894};
895
Olli Etuaho1a679902016-01-14 12:21:47 +0200896class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
897{
898 protected:
899 ShadowSamplerPlusSampler3DTestES3()
900 : TexCoordDrawTest(),
901 mTextureShadow(0),
902 mTexture3D(0),
903 mTextureShadowUniformLocation(-1),
904 mTexture3DUniformLocation(-1),
905 mDepthRefUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500906 {}
Olli Etuaho1a679902016-01-14 12:21:47 +0200907
Jamie Madill35cd7332018-12-02 12:03:33 -0500908 const char *getVertexShaderSource() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200909 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500910 return "#version 300 es\n"
911 "out vec2 texcoord;\n"
912 "in vec4 position;\n"
913 "void main()\n"
914 "{\n"
915 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
916 " texcoord = (position.xy * 0.5) + 0.5;\n"
917 "}\n";
Olli Etuaho1a679902016-01-14 12:21:47 +0200918 }
919
Jamie Madill35cd7332018-12-02 12:03:33 -0500920 const char *getFragmentShaderSource() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200921 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500922 return "#version 300 es\n"
923 "precision highp float;\n"
924 "uniform highp sampler2DShadow tex2DShadow;\n"
925 "uniform highp sampler3D tex3D;\n"
926 "in vec2 texcoord;\n"
927 "uniform float depthRef;\n"
928 "out vec4 fragColor;\n"
929 "void main()\n"
930 "{\n"
931 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
932 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
933 "}\n";
Olli Etuaho1a679902016-01-14 12:21:47 +0200934 }
935
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400936 void testSetUp() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200937 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400938 TexCoordDrawTest::testSetUp();
Olli Etuaho1a679902016-01-14 12:21:47 +0200939
940 glGenTextures(1, &mTexture3D);
941
942 glGenTextures(1, &mTextureShadow);
943 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
944 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
945
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300946 setUpProgram();
947
Olli Etuaho1a679902016-01-14 12:21:47 +0200948 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
949 ASSERT_NE(-1, mTextureShadowUniformLocation);
950 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
951 ASSERT_NE(-1, mTexture3DUniformLocation);
952 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
953 ASSERT_NE(-1, mDepthRefUniformLocation);
954 }
955
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400956 void testTearDown() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200957 {
958 glDeleteTextures(1, &mTextureShadow);
959 glDeleteTextures(1, &mTexture3D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400960 TexCoordDrawTest::testTearDown();
Olli Etuaho1a679902016-01-14 12:21:47 +0200961 }
962
963 GLuint mTextureShadow;
964 GLuint mTexture3D;
965 GLint mTextureShadowUniformLocation;
966 GLint mTexture3DUniformLocation;
967 GLint mDepthRefUniformLocation;
968};
969
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200970class SamplerTypeMixTestES3 : public TexCoordDrawTest
971{
972 protected:
973 SamplerTypeMixTestES3()
974 : TexCoordDrawTest(),
975 mTexture2D(0),
976 mTextureCube(0),
977 mTexture2DShadow(0),
978 mTextureCubeShadow(0),
979 mTexture2DUniformLocation(-1),
980 mTextureCubeUniformLocation(-1),
981 mTexture2DShadowUniformLocation(-1),
982 mTextureCubeShadowUniformLocation(-1),
983 mDepthRefUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500984 {}
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200985
Jamie Madill35cd7332018-12-02 12:03:33 -0500986 const char *getVertexShaderSource() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200987 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500988 return "#version 300 es\n"
989 "out vec2 texcoord;\n"
990 "in vec4 position;\n"
991 "void main()\n"
992 "{\n"
993 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
994 " texcoord = (position.xy * 0.5) + 0.5;\n"
995 "}\n";
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200996 }
997
Jamie Madill35cd7332018-12-02 12:03:33 -0500998 const char *getFragmentShaderSource() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200999 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001000 return "#version 300 es\n"
1001 "precision highp float;\n"
1002 "uniform highp sampler2D tex2D;\n"
1003 "uniform highp samplerCube texCube;\n"
1004 "uniform highp sampler2DShadow tex2DShadow;\n"
1005 "uniform highp samplerCubeShadow texCubeShadow;\n"
1006 "in vec2 texcoord;\n"
1007 "uniform float depthRef;\n"
1008 "out vec4 fragColor;\n"
1009 "void main()\n"
1010 "{\n"
1011 " fragColor = texture(tex2D, texcoord);\n"
1012 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1013 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1014 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1015 "0.125);\n"
1016 "}\n";
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001017 }
1018
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001019 void testSetUp() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001020 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001021 TexCoordDrawTest::testSetUp();
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001022
1023 glGenTextures(1, &mTexture2D);
1024 glGenTextures(1, &mTextureCube);
1025
1026 glGenTextures(1, &mTexture2DShadow);
1027 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1029
1030 glGenTextures(1, &mTextureCubeShadow);
1031 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1032 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1033
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001034 setUpProgram();
1035
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001036 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1037 ASSERT_NE(-1, mTexture2DUniformLocation);
1038 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1039 ASSERT_NE(-1, mTextureCubeUniformLocation);
1040 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1041 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1042 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1043 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1044 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1045 ASSERT_NE(-1, mDepthRefUniformLocation);
1046
1047 ASSERT_GL_NO_ERROR();
1048 }
1049
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001050 void testTearDown() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001051 {
1052 glDeleteTextures(1, &mTexture2D);
1053 glDeleteTextures(1, &mTextureCube);
1054 glDeleteTextures(1, &mTexture2DShadow);
1055 glDeleteTextures(1, &mTextureCubeShadow);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001056 TexCoordDrawTest::testTearDown();
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001057 }
1058
1059 GLuint mTexture2D;
1060 GLuint mTextureCube;
1061 GLuint mTexture2DShadow;
1062 GLuint mTextureCubeShadow;
1063 GLint mTexture2DUniformLocation;
1064 GLint mTextureCubeUniformLocation;
1065 GLint mTexture2DShadowUniformLocation;
1066 GLint mTextureCubeShadowUniformLocation;
1067 GLint mDepthRefUniformLocation;
1068};
1069
Olli Etuaho96963162016-03-21 11:54:33 +02001070class SamplerInStructTest : public Texture2DTest
1071{
1072 protected:
1073 SamplerInStructTest() : Texture2DTest() {}
1074
1075 const char *getTextureUniformName() override { return "us.tex"; }
1076
Jamie Madill35cd7332018-12-02 12:03:33 -05001077 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001078 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001079 return "precision highp float;\n"
1080 "struct S\n"
1081 "{\n"
1082 " vec4 a;\n"
1083 " highp sampler2D tex;\n"
1084 "};\n"
1085 "uniform S us;\n"
1086 "varying vec2 texcoord;\n"
1087 "void main()\n"
1088 "{\n"
1089 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1090 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001091 }
1092
1093 void runSamplerInStructTest()
1094 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001095 setUpProgram();
1096
Olli Etuaho96963162016-03-21 11:54:33 +02001097 glActiveTexture(GL_TEXTURE0);
1098 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001099 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1100 &GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001101 drawQuad(mProgram, "position", 0.5f);
Olli Etuahoa314b612016-03-10 16:43:00 +02001102 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001103 }
1104};
1105
1106class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1107{
1108 protected:
1109 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1110
Jamie Madill35cd7332018-12-02 12:03:33 -05001111 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001112 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001113 return "precision highp float;\n"
1114 "struct S\n"
1115 "{\n"
1116 " vec4 a;\n"
1117 " highp sampler2D tex;\n"
1118 "};\n"
1119 "uniform S us;\n"
1120 "varying vec2 texcoord;\n"
1121 "vec4 sampleFrom(S s) {\n"
1122 " return texture2D(s.tex, texcoord + s.a.x);\n"
1123 "}\n"
1124 "void main()\n"
1125 "{\n"
1126 " gl_FragColor = sampleFrom(us);\n"
1127 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001128 }
1129};
1130
1131class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1132{
1133 protected:
1134 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1135
1136 const char *getTextureUniformName() override { return "us[0].tex"; }
1137
Jamie Madill35cd7332018-12-02 12:03:33 -05001138 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001139 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001140 return "precision highp float;\n"
1141 "struct S\n"
1142 "{\n"
1143 " vec4 a;\n"
1144 " highp sampler2D tex;\n"
1145 "};\n"
1146 "uniform S us[1];\n"
1147 "varying vec2 texcoord;\n"
1148 "vec4 sampleFrom(S s) {\n"
1149 " return texture2D(s.tex, texcoord + s.a.x);\n"
1150 "}\n"
1151 "void main()\n"
1152 "{\n"
1153 " gl_FragColor = sampleFrom(us[0]);\n"
1154 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001155 }
1156};
1157
1158class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1159{
1160 protected:
1161 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1162
1163 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1164
Jamie Madill35cd7332018-12-02 12:03:33 -05001165 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001166 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001167 return "precision highp float;\n"
1168 "struct SUB\n"
1169 "{\n"
1170 " vec4 a;\n"
1171 " highp sampler2D tex;\n"
1172 "};\n"
1173 "struct S\n"
1174 "{\n"
1175 " SUB sub;\n"
1176 "};\n"
1177 "uniform S us[1];\n"
1178 "varying vec2 texcoord;\n"
1179 "vec4 sampleFrom(SUB s) {\n"
1180 " return texture2D(s.tex, texcoord + s.a.x);\n"
1181 "}\n"
1182 "void main()\n"
1183 "{\n"
1184 " gl_FragColor = sampleFrom(us[0].sub);\n"
1185 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001186 }
1187};
1188
1189class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1190{
1191 protected:
1192 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1193
Jamie Madill35cd7332018-12-02 12:03:33 -05001194 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001195 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001196 return "precision highp float;\n"
1197 "struct S\n"
1198 "{\n"
1199 " vec4 a;\n"
1200 " highp sampler2D tex;\n"
1201 "};\n"
1202 "uniform S us;\n"
1203 "uniform float us_tex;\n"
1204 "varying vec2 texcoord;\n"
1205 "void main()\n"
1206 "{\n"
1207 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1208 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001209 }
1210};
1211
Anders Leinof6cbe442019-04-18 15:32:07 +03001212class Texture2DIntegerTestES3 : public Texture2DTest
1213{
1214 protected:
1215 Texture2DIntegerTestES3() : Texture2DTest() {}
1216
1217 const char *getVertexShaderSource() override
1218 {
1219 return "#version 300 es\n"
1220 "out vec2 texcoord;\n"
1221 "in vec4 position;\n"
1222 "void main()\n"
1223 "{\n"
1224 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1225 " texcoord = (position.xy * 0.5) + 0.5;\n"
1226 "}\n";
1227 }
1228
1229 const char *getFragmentShaderSource() override
1230 {
1231 return "#version 300 es\n"
1232 "precision highp float;\n"
1233 "precision highp usampler2D;\n"
1234 "uniform usampler2D tex;\n"
1235 "in vec2 texcoord;\n"
1236 "out vec4 fragColor;\n"
1237 "void main()\n"
1238 "{\n"
Anders Leino8224a582019-05-20 12:39:29 +03001239 " fragColor = vec4(texture(tex, texcoord))/255.0;\n"
Anders Leinof6cbe442019-04-18 15:32:07 +03001240 "}\n";
1241 }
1242};
1243
Anders Leino60cc7512019-05-06 09:25:27 +03001244class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1245{
1246 protected:
1247 TextureCubeIntegerTestES3()
1248 : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1249 {}
1250
1251 const char *getVertexShaderSource() override
1252 {
1253 return "#version 300 es\n"
1254 "out vec2 texcoord;\n"
1255 "in vec4 position;\n"
1256 "void main()\n"
1257 "{\n"
1258 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1259 " texcoord = 0.5*position.xy;\n"
1260 "}\n";
1261 }
1262
1263 const char *getFragmentShaderSource() override
1264 {
1265 return "#version 300 es\n"
1266 "precision highp float;\n"
1267 "precision highp usamplerCube;\n"
1268 "uniform usamplerCube texCube;\n"
1269 "in vec2 texcoord;\n"
1270 "out vec4 fragColor;\n"
1271 "void main()\n"
1272 "{\n"
1273 " fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1274 "}\n";
1275 }
1276
1277 void testSetUp() override
1278 {
1279 TexCoordDrawTest::testSetUp();
1280 glGenTextures(1, &mTextureCube);
1281 setUpProgram();
1282
1283 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1284 ASSERT_NE(-1, mTextureCubeUniformLocation);
1285 }
1286
1287 void testTearDown() override
1288 {
1289 glDeleteTextures(1, &mTextureCube);
1290 TexCoordDrawTest::testTearDown();
1291 }
1292
1293 GLuint mTextureCube;
1294 GLint mTextureCubeUniformLocation;
1295};
1296
Anders Leinoe4452442019-05-09 13:29:49 +03001297class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1298{
1299 protected:
1300 TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1301
1302 const char *getVertexShaderSource() override
1303 {
1304 return "#version 300 es\n"
1305 "out vec2 texcoord;\n"
1306 "in vec4 position;\n"
1307 "void main()\n"
1308 "{\n"
1309 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1310 " texcoord = position.xy;\n"
1311 "}\n";
1312 }
1313
1314 const char *getFragmentShaderSource() override
1315 {
1316 return "#version 300 es\n"
1317 "precision highp float;\n"
1318 "precision highp usamplerCube;\n"
1319 "uniform usamplerCube texCube;\n"
1320 "in vec2 texcoord;\n"
1321 "out vec4 fragColor;\n"
1322 "void main()\n"
1323 "{\n"
1324 " fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1325 "}\n";
1326 }
1327};
1328
Anders Leino1b6aded2019-05-20 12:56:34 +03001329class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1330{
1331 protected:
1332 Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1333
1334 const char *getVertexShaderSource() override
1335 {
1336 return "#version 300 es\n"
1337 "out vec2 texcoord;\n"
1338 "in vec4 position;\n"
1339 "void main()\n"
1340 "{\n"
1341 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1342 " texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1343 "}\n";
1344 }
1345
1346 const char *getFragmentShaderSource() override
1347 {
1348 return "#version 300 es\n"
1349 "precision highp float;\n"
1350 "precision highp usampler2D;\n"
1351 "uniform usampler2D tex;\n"
1352 "in vec2 texcoord;\n"
1353 "out vec4 fragColor;\n"
1354 "void main()\n"
1355 "{\n"
1356 " fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1357 "0.0))/255.0;\n"
1358 "}\n";
1359 }
1360};
1361
Anders Leino69d04932019-05-20 14:04:13 +03001362class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1363{
1364 protected:
1365 Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1366
1367 const char *getVertexShaderSource() override
1368 {
1369 return "#version 300 es\n"
1370 "out vec2 texcoord;\n"
1371 "in vec4 position;\n"
1372 "void main()\n"
1373 "{\n"
1374 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1375 " texcoord = (position.xy * 0.5) + 0.5;\n"
1376 "}\n";
1377 }
1378
1379 const char *getFragmentShaderSource() override
1380 {
1381 return "#version 300 es\n"
1382 "precision highp float;\n"
1383 "uniform highp usampler2DArray tex2DArray;\n"
1384 "in vec2 texcoord;\n"
1385 "out vec4 fragColor;\n"
1386 "void main()\n"
1387 "{\n"
1388 " fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
1389 "0.0)))/255.0;\n"
1390 "}\n";
1391 }
1392};
1393
Anders Leino262e2822019-05-20 14:24:40 +03001394class Texture3DIntegerTestES3 : public Texture3DTestES3
1395{
1396 protected:
1397 Texture3DIntegerTestES3() : Texture3DTestES3() {}
1398
1399 const char *getVertexShaderSource() override
1400 {
1401 return "#version 300 es\n"
1402 "out vec2 texcoord;\n"
1403 "in vec4 position;\n"
1404 "void main()\n"
1405 "{\n"
1406 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1407 " texcoord = (position.xy * 0.5) + 0.5;\n"
1408 "}\n";
1409 }
1410
1411 const char *getFragmentShaderSource() override
1412 {
1413 return "#version 300 es\n"
1414 "precision highp float;\n"
1415 "uniform highp usampler3D tex3D;\n"
1416 "in vec2 texcoord;\n"
1417 "out vec4 fragColor;\n"
1418 "void main()\n"
1419 "{\n"
1420 " fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1421 "}\n";
1422 }
1423};
1424
Jamie Madillfc3ec572019-11-27 21:43:22 +00001425class PBOCompressedTextureTest : public Texture2DTest
1426{
1427 protected:
1428 PBOCompressedTextureTest() : Texture2DTest() {}
1429
1430 void testSetUp() override
1431 {
1432 TexCoordDrawTest::testSetUp();
1433 glGenTextures(1, &mTexture2D);
1434 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1435 EXPECT_GL_NO_ERROR();
1436
1437 setUpProgram();
1438
1439 glGenBuffers(1, &mPBO);
1440 }
1441
1442 void testTearDown() override
1443 {
1444 glDeleteBuffers(1, &mPBO);
1445 Texture2DTest::testTearDown();
1446 }
1447
1448 GLuint mPBO;
1449};
1450
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001451TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001452{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001453 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001454 EXPECT_GL_ERROR(GL_NO_ERROR);
1455
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001456 setUpProgram();
1457
Jamie Madill50cf2be2018-06-15 09:46:57 -04001458 const GLubyte *pixels[20] = {0};
Jamie Madillf67115c2014-04-22 13:14:05 -04001459 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1460 EXPECT_GL_ERROR(GL_INVALID_VALUE);
Geoff Langc51642b2016-11-14 16:18:26 -05001461
Jamie Madillb8149072019-04-30 16:14:44 -04001462 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
Geoff Langc51642b2016-11-14 16:18:26 -05001463 {
1464 // Create a 1-level immutable texture.
1465 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1466
1467 // Try calling sub image on the second level.
1468 glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1469 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1470 }
Jamie Madillf67115c2014-04-22 13:14:05 -04001471}
Geoff Langc41e42d2014-04-28 10:58:16 -04001472
John Bauman18319182016-09-28 14:22:27 -07001473// Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
1474TEST_P(Texture2DTest, QueryBinding)
1475{
1476 glBindTexture(GL_TEXTURE_2D, 0);
1477 EXPECT_GL_ERROR(GL_NO_ERROR);
1478
1479 GLint textureBinding;
1480 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1481 EXPECT_GL_NO_ERROR();
1482 EXPECT_EQ(0, textureBinding);
1483
1484 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
Jamie Madillb8149072019-04-30 16:14:44 -04001485 if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1486 IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
John Bauman18319182016-09-28 14:22:27 -07001487 {
1488 EXPECT_GL_NO_ERROR();
1489 EXPECT_EQ(0, textureBinding);
1490 }
1491 else
1492 {
1493 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1494 }
1495}
1496
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001497TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001498{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001499 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001500 EXPECT_GL_ERROR(GL_NO_ERROR);
1501
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001502 setUpProgram();
1503
Geoff Langc41e42d2014-04-28 10:58:16 -04001504 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001505 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001506 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001507 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001508
Jamie Madill50cf2be2018-06-15 09:46:57 -04001509 const GLubyte *pixel[4] = {0};
Geoff Langc41e42d2014-04-28 10:58:16 -04001510
1511 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1512 EXPECT_GL_NO_ERROR();
1513
1514 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1515 EXPECT_GL_NO_ERROR();
1516
1517 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1518 EXPECT_GL_NO_ERROR();
1519}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001520
1521// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001522TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001523{
1524 glActiveTexture(GL_TEXTURE0);
1525 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1526 glActiveTexture(GL_TEXTURE1);
1527 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1528 EXPECT_GL_ERROR(GL_NO_ERROR);
1529
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001530 glUseProgram(mProgram);
1531 glUniform1i(mTexture2DUniformLocation, 0);
1532 glUniform1i(mTextureCubeUniformLocation, 1);
1533 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001534 EXPECT_GL_NO_ERROR();
1535}
Jamie Madill9aca0592014-10-06 16:26:59 -04001536
Olli Etuaho53a2da12016-01-11 15:43:32 +02001537// Test drawing with two texture types accessed from the same shader and check that the result of
1538// drawing is correct.
1539TEST_P(TextureCubeTest, CubeMapDraw)
1540{
1541 GLubyte texData[4];
1542 texData[0] = 0;
1543 texData[1] = 60;
1544 texData[2] = 0;
1545 texData[3] = 255;
1546
1547 glActiveTexture(GL_TEXTURE0);
1548 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1549 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1550
1551 glActiveTexture(GL_TEXTURE1);
1552 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1553 texData[1] = 120;
1554 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1555 texData);
1556 EXPECT_GL_ERROR(GL_NO_ERROR);
1557
1558 glUseProgram(mProgram);
1559 glUniform1i(mTexture2DUniformLocation, 0);
1560 glUniform1i(mTextureCubeUniformLocation, 1);
1561 drawQuad(mProgram, "position", 0.5f);
1562 EXPECT_GL_NO_ERROR();
1563
1564 int px = getWindowWidth() - 1;
1565 int py = 0;
1566 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1567}
1568
Olli Etuaho4644a202016-01-12 15:12:53 +02001569TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1570{
1571 glActiveTexture(GL_TEXTURE0);
1572 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1573 GLubyte texData[4];
1574 texData[0] = 0;
1575 texData[1] = 128;
1576 texData[2] = 0;
1577 texData[3] = 255;
1578 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1579 glUseProgram(mProgram);
1580 glUniform1i(mTexture2DUniformLocation, 0);
1581 drawQuad(mProgram, "position", 0.5f);
1582 EXPECT_GL_NO_ERROR();
1583
1584 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1585}
1586
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001587// Test drawing with two textures passed to the shader in a sampler array.
1588TEST_P(SamplerArrayTest, SamplerArrayDraw)
1589{
1590 testSamplerArrayDraw();
1591}
1592
1593// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1594// user-defined function in the shader.
1595TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1596{
Shahbaz Youssefi0864a7a2018-11-07 15:50:15 -05001597 // TODO: Diagnose and fix. http://anglebug.com/2955
1598 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1599
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001600 testSamplerArrayDraw();
1601}
1602
Jamie Madill9aca0592014-10-06 16:26:59 -04001603// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001604TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001605{
1606 int px = getWindowWidth() / 2;
1607 int py = getWindowHeight() / 2;
1608
1609 glActiveTexture(GL_TEXTURE0);
1610 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1611
Olli Etuahoa314b612016-03-10 16:43:00 +02001612 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001613
Olli Etuahoa314b612016-03-10 16:43:00 +02001614 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1617 glGenerateMipmap(GL_TEXTURE_2D);
1618
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001619 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001620 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001621 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1622 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001623 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001624 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001625
Olli Etuahoa314b612016-03-10 16:43:00 +02001626 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001627
Olli Etuahoa314b612016-03-10 16:43:00 +02001628 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1629 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001630 glGenerateMipmap(GL_TEXTURE_2D);
1631
Olli Etuahoa314b612016-03-10 16:43:00 +02001632 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001633
Olli Etuahoa314b612016-03-10 16:43:00 +02001634 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1635 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001636 glGenerateMipmap(GL_TEXTURE_2D);
1637
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001638 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001639
1640 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001641 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001642}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001643
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001644// Test creating a FBO with a cube map render target, to test an ANGLE bug
1645// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001646TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001647{
Michael Spangd8506c72019-01-29 15:35:09 -05001648 // http://anglebug.com/3145
1649 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1650
Shahbaz Youssefi0c128e12019-03-25 23:50:14 -04001651 // http://anglebug.com/2822
1652 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1653
Jamie Madill3f3b3582018-09-14 10:38:44 -04001654 GLFramebuffer fbo;
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001655 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1656
1657 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Jamie Madill50cf2be2018-06-15 09:46:57 -04001658 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1659 mTextureCube, 0);
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001660
Corentin Wallez322653b2015-06-17 18:33:56 +02001661 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001662 EXPECT_GL_NO_ERROR();
Jamie Madill3f3b3582018-09-14 10:38:44 -04001663
1664 // Test clearing the six mip faces individually.
1665 std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
1666 GLColor::yellow, GLColor::cyan, GLColor::magenta}};
1667
1668 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1669 {
1670 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1671 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1672
1673 Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
1674 glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
1675 glClear(GL_COLOR_BUFFER_BIT);
1676
1677 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
1678 }
1679
1680 // Iterate the faces again to make sure the colors haven't changed.
1681 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1682 {
1683 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1684 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1685 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
1686 << "face color " << faceIndex << " shouldn't change";
1687 }
1688}
1689
1690// Tests clearing a cube map with a scissor enabled.
1691TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
1692{
1693 // TODO(jie.a.chen): Diagnose and fix. http://anglebug.com/2822
1694 ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
1695
Michael Spangd8506c72019-01-29 15:35:09 -05001696 // http://anglebug.com/3145
1697 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1698
Jamie Madill3f3b3582018-09-14 10:38:44 -04001699 constexpr size_t kSize = 16;
1700
1701 GLFramebuffer fbo;
1702 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1703 glViewport(0, 0, kSize, kSize);
1704
1705 GLTexture texcube;
1706 glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
1707 for (GLenum face = 0; face < 6; face++)
1708 {
1709 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
1710 GL_UNSIGNED_BYTE, nullptr);
1711 }
1712 ASSERT_GL_NO_ERROR();
1713
1714 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1715 texcube, 0);
1716
1717 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1718 ASSERT_GL_NO_ERROR();
1719
1720 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1721 glClear(GL_COLOR_BUFFER_BIT);
1722 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1723
1724 glEnable(GL_SCISSOR_TEST);
1725 glScissor(kSize / 2, 0, kSize / 2, kSize);
1726 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1727 glClear(GL_COLOR_BUFFER_BIT);
1728
1729 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1730 EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
1731
1732 ASSERT_GL_NO_ERROR();
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001733}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001734
Jamie Madill50cf2be2018-06-15 09:46:57 -04001735// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
1736// default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001737TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001738{
Jamie Madillb8149072019-04-30 16:14:44 -04001739 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1740 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -04001741
Jamie Madill50cf2be2018-06-15 09:46:57 -04001742 int width = getWindowWidth();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001743 int height = getWindowHeight();
1744
1745 GLuint tex2D;
1746 glGenTextures(1, &tex2D);
1747 glActiveTexture(GL_TEXTURE0);
1748 glBindTexture(GL_TEXTURE_2D, tex2D);
1749
1750 // Fill with red
1751 std::vector<GLubyte> pixels(3 * 16 * 16);
1752 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1753 {
1754 pixels[pixelId * 3 + 0] = 255;
1755 pixels[pixelId * 3 + 1] = 0;
1756 pixels[pixelId * 3 + 2] = 0;
1757 }
1758
1759 // ANGLE internally uses RGBA as the DirectX format for RGB images
Jamie Madill50cf2be2018-06-15 09:46:57 -04001760 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1761 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
Geoff Langc4e93662017-05-01 10:45:59 -04001762 if (getClientMajorVersion() >= 3)
1763 {
1764 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1765 }
1766 else
1767 {
1768 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1769 }
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001770
1771 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1772 // glTexSubImage2D should take into account that the image is dirty.
1773 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1774 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1775 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1776
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001777 setUpProgram();
1778
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001779 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001780 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001781 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001782 glDeleteTextures(1, &tex2D);
1783 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001784 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001785
1786 // Validate that the region of the texture without data has an alpha of 1.0
Jamie Madill05b35b22017-10-03 09:01:44 -04001787 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
1788 EXPECT_EQ(255, pixel.A);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001789}
1790
Jamie Madill50cf2be2018-06-15 09:46:57 -04001791// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
1792// initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001793TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001794{
Jamie Madillfc3ec572019-11-27 21:43:22 +00001795 // http://anglebug.com/4126
1796 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
1797
1798 if (getClientMajorVersion() < 3)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001799 {
Jamie Madillfc3ec572019-11-27 21:43:22 +00001800 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1801 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001802 }
Jamie Madillfc3ec572019-11-27 21:43:22 +00001803
1804 const int width = getWindowWidth();
1805 const int height = getWindowHeight();
1806 const size_t pixelCount = width * height;
1807 const int componentCount = 3;
1808
1809 GLuint tex2D;
1810 glGenTextures(1, &tex2D);
1811 glActiveTexture(GL_TEXTURE0);
1812 glBindTexture(GL_TEXTURE_2D, tex2D);
1813
1814 // Fill with red
1815 std::vector<GLubyte> pixels(componentCount * pixelCount);
1816 for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
1817 {
1818 pixels[pixelId * componentCount + 0] = 255;
1819 pixels[pixelId * componentCount + 1] = 0;
1820 pixels[pixelId * componentCount + 2] = 0;
1821 }
1822
1823 // Read 16x16 region from red backbuffer to PBO
1824 GLuint pbo;
1825 glGenBuffers(1, &pbo);
1826 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1827 glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
1828 GL_STATIC_DRAW);
1829
1830 // ANGLE internally uses RGBA as the DirectX format for RGB images
1831 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1832 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
1833 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
1834
1835 // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
1836 // untouched. glTexSubImage2D should take into account that the image is dirty.
1837 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
1838 nullptr);
1839 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1840 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1841
1842 setUpProgram();
1843
1844 glUseProgram(mProgram);
1845 glUniform1i(mTexture2DUniformLocation, 0);
1846 drawQuad(mProgram, "position", 0.5f);
1847 glDeleteTextures(1, &tex2D);
1848 glDeleteBuffers(1, &pbo);
1849 EXPECT_GL_NO_ERROR();
1850 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1851 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1852}
1853
1854// Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
1855// and drawing with the texture
1856// Pseudo code for the follow test:
1857// 1. Upload PBO to mTexture2D
1858// 2. Delete PBO
1859// 3. Draw with otherTexture (x5)
1860// 4. Draw with mTexture2D
1861// 5. Validate color output
1862TEST_P(Texture2DTest, PBOWithMultipleDraws)
1863{
1864 if (getClientMajorVersion() < 3)
1865 {
1866 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1867 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
1868 }
1869
1870 const GLuint width = getWindowWidth();
1871 const GLuint height = getWindowHeight();
1872 const GLuint windowPixelCount = width * height;
1873 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
1874 std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
1875
1876 // Create secondary draw that does not use mTexture
1877 const char *vertexShaderSource = getVertexShaderSource();
1878 const char *fragmentShaderSource = getFragmentShaderSource();
1879 ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
1880
1881 GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
1882 ASSERT_NE(-1, uniformLoc);
1883 glUseProgram(0);
1884
1885 // Create secondary Texture to draw with
1886 GLTexture otherTexture;
1887 glActiveTexture(GL_TEXTURE0);
1888 glBindTexture(GL_TEXTURE_2D, otherTexture);
1889 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1890 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1891 pixelsRed.data());
1892 ASSERT_GL_NO_ERROR();
1893
1894 // Setup primary Texture
1895 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1896 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1898 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1899 ASSERT_GL_NO_ERROR();
1900
1901 // Setup PBO
1902 GLuint pbo = 0;
1903 glGenBuffers(1, &pbo);
1904 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1905 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
1906 GL_STATIC_DRAW);
1907 ASSERT_GL_NO_ERROR();
1908
1909 // Write PBO to mTexture
1910 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1911 ASSERT_GL_NO_ERROR();
1912 // Delete PBO as ANGLE should be properly handling refcount of this buffer
1913 glDeleteBuffers(1, &pbo);
1914 pixelsGreen.clear();
1915
1916 // Do 5 draws not involving primary texture that the PBO updated
1917 glUseProgram(otherProgram);
1918 glUniform1i(uniformLoc, 0);
1919 glBindTexture(GL_TEXTURE_2D, otherTexture);
1920 drawQuad(otherProgram, "position", 0.5f);
1921 glBindTexture(GL_TEXTURE_2D, 0);
1922 glUseProgram(0);
1923
1924 glUseProgram(otherProgram);
1925 glUniform1i(uniformLoc, 0);
1926 glBindTexture(GL_TEXTURE_2D, otherTexture);
1927 drawQuad(otherProgram, "position", 0.5f);
1928 glBindTexture(GL_TEXTURE_2D, 0);
1929 glUseProgram(0);
1930
1931 glUseProgram(otherProgram);
1932 glUniform1i(uniformLoc, 0);
1933 glBindTexture(GL_TEXTURE_2D, otherTexture);
1934 drawQuad(otherProgram, "position", 0.5f);
1935 glBindTexture(GL_TEXTURE_2D, 0);
1936 glUseProgram(0);
1937
1938 glUseProgram(otherProgram);
1939 glUniform1i(uniformLoc, 0);
1940 glBindTexture(GL_TEXTURE_2D, otherTexture);
1941 drawQuad(otherProgram, "position", 0.5f);
1942 glBindTexture(GL_TEXTURE_2D, 0);
1943 glUseProgram(0);
1944 ASSERT_GL_NO_ERROR();
1945
1946 std::vector<GLColor> output(windowPixelCount, GLColor::black);
1947 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1948 output.data());
1949 EXPECT_EQ(pixelsRed, output);
1950
1951 setUpProgram();
1952 // Draw using PBO updated texture
1953 glUseProgram(mProgram);
1954 glUniform1i(mTexture2DUniformLocation, 0);
1955 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1956 drawQuad(mProgram, "position", 0.5f);
1957 ASSERT_GL_NO_ERROR();
1958
1959 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
1960 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1961 actual.data());
1962 // Value should be green as it was updated during PBO transfer to mTexture
1963 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
1964 EXPECT_EQ(expected, actual);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001965}
Jamie Madillbc393df2015-01-29 13:46:07 -05001966
Mohan Maiya6caa2652019-09-11 08:06:13 -07001967// Tests CopySubImage for float formats
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001968TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001969{
1970 testFloatCopySubImage(1, 1);
1971}
1972
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001973TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001974{
1975 testFloatCopySubImage(2, 1);
1976}
1977
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001978TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001979{
1980 testFloatCopySubImage(2, 2);
1981}
1982
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001983TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001984{
1985 testFloatCopySubImage(3, 1);
1986}
1987
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001988TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001989{
1990 testFloatCopySubImage(3, 2);
1991}
1992
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001993TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001994{
Yunchao He9550c602018-02-13 14:47:05 +08001995 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
Mohan Maiya6caa2652019-09-11 08:06:13 -07001996 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001997
Yunchao He9550c602018-02-13 14:47:05 +08001998 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
1999 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002000
Jamie Madillbc393df2015-01-29 13:46:07 -05002001 testFloatCopySubImage(3, 3);
2002}
2003
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002004TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002005{
2006 testFloatCopySubImage(4, 1);
2007}
2008
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002009TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002010{
2011 testFloatCopySubImage(4, 2);
2012}
2013
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002014TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002015{
Yunchao He9550c602018-02-13 14:47:05 +08002016 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2017 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002018
Jamie Madillbc393df2015-01-29 13:46:07 -05002019 testFloatCopySubImage(4, 3);
2020}
2021
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002022TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05002023{
Yunchao He9550c602018-02-13 14:47:05 +08002024 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2025 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002026
Jamie Madillbc393df2015-01-29 13:46:07 -05002027 testFloatCopySubImage(4, 4);
2028}
Austin Kinross07285142015-03-26 11:36:16 -07002029
Jamie Madill50cf2be2018-06-15 09:46:57 -04002030// Port of
2031// https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
2032// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
2033// handles GL_ALPHA
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002034TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07002035{
2036 const int npotTexSize = 5;
Jamie Madill50cf2be2018-06-15 09:46:57 -04002037 const int potTexSize = 4; // Should be less than npotTexSize
Austin Kinross07285142015-03-26 11:36:16 -07002038 GLuint tex2D;
2039
Jamie Madillb8149072019-04-30 16:14:44 -04002040 if (IsGLExtensionEnabled("GL_OES_texture_npot"))
Austin Kinross07285142015-03-26 11:36:16 -07002041 {
2042 // This test isn't applicable if texture_npot is enabled
2043 return;
2044 }
2045
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002046 setUpProgram();
2047
Austin Kinross07285142015-03-26 11:36:16 -07002048 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2049
Austin Kinross5faa15b2016-01-11 13:32:48 -08002050 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
2051 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2052
Austin Kinross07285142015-03-26 11:36:16 -07002053 glActiveTexture(GL_TEXTURE0);
2054 glGenTextures(1, &tex2D);
2055 glBindTexture(GL_TEXTURE_2D, tex2D);
2056
Till Rathmannc1551dc2018-08-15 17:04:49 +02002057 const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
Austin Kinross07285142015-03-26 11:36:16 -07002058
2059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2061
2062 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
Jamie Madill50cf2be2018-06-15 09:46:57 -04002063 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2064 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002065 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2066
2067 // Check that an NPOT texture on level 0 succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002068 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2069 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002070 EXPECT_GL_NO_ERROR();
2071
2072 // Check that generateMipmap fails on NPOT
2073 glGenerateMipmap(GL_TEXTURE_2D);
2074 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2075
2076 // Check that nothing is drawn if filtering is not correct for NPOT
2077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2080 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2081 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002082 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002083 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2084
2085 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
2086 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2087 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2088 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
2089 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002090 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002091 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2092
2093 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
2094 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2095 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002096 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002097 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2098
2099 // Check that glTexImage2D for POT texture succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002100 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
2101 pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002102 EXPECT_GL_NO_ERROR();
2103
2104 // Check that generateMipmap for an POT texture succeeds
2105 glGenerateMipmap(GL_TEXTURE_2D);
2106 EXPECT_GL_NO_ERROR();
2107
2108 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
2109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2113 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002114 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002115 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2116 EXPECT_GL_NO_ERROR();
2117}
Jamie Madillfa05f602015-05-07 13:47:11 -04002118
Austin Kinross08528e12015-10-07 16:24:40 -07002119// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
2120// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002121TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07002122{
2123 glActiveTexture(GL_TEXTURE0);
2124 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2125
2126 // Create an 8x8 (i.e. power-of-two) texture.
2127 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2130 glGenerateMipmap(GL_TEXTURE_2D);
2131
2132 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
2133 // This should always work, even if GL_OES_texture_npot isn't active.
Geoff Langfb052642017-10-24 13:42:09 -04002134 std::array<GLColor, 3 * 3> data;
2135 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
Austin Kinross08528e12015-10-07 16:24:40 -07002136
2137 EXPECT_GL_NO_ERROR();
2138}
2139
Geoff Lang3702d8c2019-04-08 13:44:06 -04002140// Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
2141// TextureImpl and the texture is synced before being used in a draw call.
2142TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
2143{
2144 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
Yuly Novikove6b23e42019-04-10 17:19:15 -04002145 // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
2146 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
Yuly Novikovbd4ff472019-07-19 22:08:17 +00002147 // D3D Debug device reports an error. http://anglebug.com/3501
2148 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
Cody Northrop988f7172019-09-30 15:52:37 -06002149 // TODO(cnorthrop): Needs triage on Vulkan backend. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06002150 ANGLE_SKIP_TEST_IF(IsVulkan());
Geoff Lang3702d8c2019-04-08 13:44:06 -04002151
2152 // The workaround in the GL backend required to trigger this bug generates driver warning
2153 // messages.
2154 ScopedIgnorePlatformMessages ignoreMessages;
2155
2156 setUpProgram();
2157 glUseProgram(mProgram);
2158 glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
2159
2160 GLTexture dest;
2161 glBindTexture(GL_TEXTURE_2D, dest);
2162
2163 GLTexture source;
2164 glBindTexture(GL_TEXTURE_2D, source);
2165
2166 // Put data in mip 0 and 1
2167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2168 GLColor::red.data());
2169 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2170 GLColor::green.data());
2171
2172 // Disable mipmapping so source is complete
2173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2175
2176 // Force the dirty bits to be synchronized in source
2177 drawQuad(mProgram, "position", 1.0f);
2178
2179 // Copy from mip 1 of the source. In the GL backend this internally sets the base level to mip
2180 // 1 and sets a dirty bit.
2181 glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
2182 GL_FALSE, GL_FALSE);
2183
2184 // Draw again, assertions are generated if the texture has internal dirty bits at draw time
2185 drawQuad(mProgram, "position", 1.0f);
2186}
2187
Geoff Lang6f691fb2019-04-25 11:01:52 -04002188// This test case changes the base level of a texture that's attached to a framebuffer, clears every
2189// level to green, and then samples the texture when rendering. Test is taken from
2190// https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
2191TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
2192{
2193 // TODO(geofflang): Investigate on D3D11. http://anglebug.com/2291
2194 ANGLE_SKIP_TEST_IF(IsD3D11());
2195
Cody Northropd192e932019-09-27 10:27:10 -06002196 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
2197 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
Cody Northropcb16fb52019-08-29 16:53:55 -06002198
Geoff Lang6f691fb2019-04-25 11:01:52 -04002199 setUpProgram();
2200
2201 constexpr GLint width = 8;
2202 constexpr GLint height = 4;
2203
2204 GLTexture texture;
2205 glBindTexture(GL_TEXTURE_2D, texture);
2206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2208 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2209 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2210
2211 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
2212 GLint level = 0;
2213 GLint levelW = width;
2214 GLint levelH = height;
2215 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2216 nullptr);
2217 while (levelW > 1 || levelH > 1)
2218 {
2219 ++level;
2220 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
2221 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
2222 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2223 nullptr);
2224 }
2225
2226 // Clear each level of the texture using an FBO. Change the base level to match the level used
2227 // for the FBO on each iteration.
2228 GLFramebuffer fbo;
2229 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2230 level = 0;
2231 levelW = width;
2232 levelH = height;
2233 while (levelW > 1 || levelH > 1)
2234 {
2235 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
2236 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
2237
2238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
2239 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
2240
2241 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2242 EXPECT_GL_NO_ERROR();
2243
2244 glClearColor(0, 1, 0, 1);
2245 glClear(GL_COLOR_BUFFER_BIT);
2246
2247 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2248
2249 ++level;
2250 }
2251
2252 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2253 glViewport(0, 0, 16, 16);
2254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2255
2256 drawQuad(mProgram, "position", 0.5f);
2257
2258 EXPECT_GL_NO_ERROR();
2259 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2260}
2261
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002262// Test to check that texture completeness is determined correctly when the texture base level is
2263// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
2264TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
2265{
2266 glActiveTexture(GL_TEXTURE0);
2267 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02002268
2269 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
2270 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2271 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2272 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2273 texDataGreen.data());
2274 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2275 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2277 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2278 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2279
2280 EXPECT_GL_NO_ERROR();
2281
2282 drawQuad(mProgram, "position", 0.5f);
2283
Olli Etuahoa314b612016-03-10 16:43:00 +02002284 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2285}
2286
2287// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2288// have images defined.
2289TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
2290{
Yunchao He9550c602018-02-13 14:47:05 +08002291 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2292 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2293
Olli Etuahoa314b612016-03-10 16:43:00 +02002294 glActiveTexture(GL_TEXTURE0);
2295 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2296 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2297 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2298 texDataGreen.data());
2299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2303
2304 EXPECT_GL_NO_ERROR();
2305
2306 drawQuad(mProgram, "position", 0.5f);
2307
2308 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2309}
2310
Olli Etuahoe8528d82016-05-16 17:50:52 +03002311// Test that drawing works correctly when level 0 is undefined and base level is 1.
2312TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
2313{
Yunchao He9550c602018-02-13 14:47:05 +08002314 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2315 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2316
Olli Etuahoe8528d82016-05-16 17:50:52 +03002317 glActiveTexture(GL_TEXTURE0);
2318 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2319 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2320 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2321 texDataGreen.data());
2322 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2323 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2324 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2325 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2326
2327 EXPECT_GL_NO_ERROR();
2328
2329 // Texture is incomplete.
2330 drawQuad(mProgram, "position", 0.5f);
2331 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2332
2333 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2334 texDataGreen.data());
2335
2336 // Texture is now complete.
2337 drawQuad(mProgram, "position", 0.5f);
2338 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2339}
2340
Olli Etuahoa314b612016-03-10 16:43:00 +02002341// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2342// dimensions that don't fit the images inside the range.
2343// GLES 3.0.4 section 3.8.13 Texture completeness
2344TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2345{
Olli Etuahoa314b612016-03-10 16:43:00 +02002346 glActiveTexture(GL_TEXTURE0);
2347 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2348 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
2349 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2350 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
2351
2352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2354
2355 // Two levels that are initially unused.
2356 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2357 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2358 texDataCyan.data());
2359
2360 // One level that is used - only this level should affect completeness.
2361 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2362 texDataGreen.data());
2363
2364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2366
2367 EXPECT_GL_NO_ERROR();
2368
2369 drawQuad(mProgram, "position", 0.5f);
2370
2371 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2372
Yunchao He2f23f352018-02-11 22:11:37 +08002373 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002374
2375 // Switch the level that is being used to the cyan level 2.
2376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2378
2379 EXPECT_GL_NO_ERROR();
2380
2381 drawQuad(mProgram, "position", 0.5f);
2382
2383 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2384}
2385
2386// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2387// have images defined.
2388TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
2389{
Olli Etuahoa314b612016-03-10 16:43:00 +02002390 glActiveTexture(GL_TEXTURE0);
2391 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2392 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2393 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2394 texDataGreen.data());
2395 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2396 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2397 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2398 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2399
2400 EXPECT_GL_NO_ERROR();
2401
2402 drawQuad(mProgram, "position", 0.5f);
2403
2404 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2405}
2406
2407// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2408// dimensions that don't fit the images inside the range.
2409// GLES 3.0.4 section 3.8.13 Texture completeness
2410TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2411{
Yuly Novikovc5da7992019-06-27 12:57:13 -04002412 // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
2413 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
2414
Olli Etuahoa314b612016-03-10 16:43:00 +02002415 glActiveTexture(GL_TEXTURE0);
2416 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2417 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2418 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2419 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2420
2421 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2422 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2423
2424 // Two levels that are initially unused.
2425 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2426 texDataRed.data());
2427 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2428 texDataCyan.data());
2429
2430 // One level that is used - only this level should affect completeness.
2431 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2432 texDataGreen.data());
2433
2434 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2435 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2436
2437 EXPECT_GL_NO_ERROR();
2438
2439 drawQuad(mProgram, "position", 0.5f);
2440
2441 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2442
Yunchao He2f23f352018-02-11 22:11:37 +08002443 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002444
2445 // Switch the level that is being used to the cyan level 2.
2446 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
2447 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
2448
2449 EXPECT_GL_NO_ERROR();
2450
2451 drawQuad(mProgram, "position", 0.5f);
2452
2453 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2454}
2455
2456// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2457// have images defined.
2458TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
2459{
Olli Etuahoa314b612016-03-10 16:43:00 +02002460 glActiveTexture(GL_TEXTURE0);
2461 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2462 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2463 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2464 texDataGreen.data());
2465 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2466 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2467 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2468 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2469
2470 EXPECT_GL_NO_ERROR();
2471
2472 drawQuad(mProgram, "position", 0.5f);
2473
2474 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2475}
2476
2477// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2478// dimensions that don't fit the images inside the range.
2479// GLES 3.0.4 section 3.8.13 Texture completeness
2480TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2481{
Corentin Wallez566c2e32019-08-28 18:37:58 +02002482 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2483 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2484
Olli Etuahoa314b612016-03-10 16:43:00 +02002485 glActiveTexture(GL_TEXTURE0);
2486 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
2487 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2488 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2489 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2490
2491 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2492 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2493
2494 // Two levels that are initially unused.
2495 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2496 texDataRed.data());
2497 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2498 texDataCyan.data());
2499
2500 // One level that is used - only this level should affect completeness.
2501 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2502 texDataGreen.data());
2503
2504 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2505 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2506
2507 EXPECT_GL_NO_ERROR();
2508
2509 drawQuad(mProgram, "position", 0.5f);
2510
2511 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2512
Yunchao He2f23f352018-02-11 22:11:37 +08002513 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2514
Olli Etuahoa314b612016-03-10 16:43:00 +02002515 // Switch the level that is being used to the cyan level 2.
2516 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
2517 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
2518
2519 EXPECT_GL_NO_ERROR();
2520
2521 drawQuad(mProgram, "position", 0.5f);
2522
2523 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2524}
2525
2526// Test that texture completeness is updated if texture max level changes.
2527// GLES 3.0.4 section 3.8.13 Texture completeness
2528TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2529{
Olli Etuahoa314b612016-03-10 16:43:00 +02002530 glActiveTexture(GL_TEXTURE0);
2531 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2532 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2533
2534 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2535 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2536
2537 // A level that is initially unused.
2538 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2539 texDataGreen.data());
2540
2541 // One level that is initially used - only this level should affect completeness.
2542 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2543 texDataGreen.data());
2544
2545 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2546 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2547
2548 EXPECT_GL_NO_ERROR();
2549
2550 drawQuad(mProgram, "position", 0.5f);
2551
2552 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2553
2554 // Switch the max level to level 1. The levels within the used range now have inconsistent
2555 // dimensions and the texture should be incomplete.
2556 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2557
2558 EXPECT_GL_NO_ERROR();
2559
2560 drawQuad(mProgram, "position", 0.5f);
2561
2562 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2563}
2564
2565// Test that 3D texture completeness is updated if texture max level changes.
2566// GLES 3.0.4 section 3.8.13 Texture completeness
2567TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2568{
Olli Etuahoa314b612016-03-10 16:43:00 +02002569 glActiveTexture(GL_TEXTURE0);
2570 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2571 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2572
2573 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2574 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2575
2576 // A level that is initially unused.
2577 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2578 texDataGreen.data());
2579
2580 // One level that is initially used - only this level should affect completeness.
2581 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2582 texDataGreen.data());
2583
2584 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2585 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2586
2587 EXPECT_GL_NO_ERROR();
2588
2589 drawQuad(mProgram, "position", 0.5f);
2590
2591 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2592
2593 // Switch the max level to level 1. The levels within the used range now have inconsistent
2594 // dimensions and the texture should be incomplete.
2595 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2596
2597 EXPECT_GL_NO_ERROR();
2598
2599 drawQuad(mProgram, "position", 0.5f);
2600
2601 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2602}
2603
2604// Test that texture completeness is updated if texture base level changes.
2605// GLES 3.0.4 section 3.8.13 Texture completeness
2606TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2607{
Olli Etuahoa314b612016-03-10 16:43:00 +02002608 glActiveTexture(GL_TEXTURE0);
2609 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2610 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2611
2612 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2613 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2614
2615 // Two levels that are initially unused.
2616 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2617 texDataGreen.data());
2618 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2619 texDataGreen.data());
2620
2621 // One level that is initially used - only this level should affect completeness.
2622 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2623 texDataGreen.data());
2624
2625 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2626 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2627
2628 EXPECT_GL_NO_ERROR();
2629
2630 drawQuad(mProgram, "position", 0.5f);
2631
2632 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2633
2634 // Switch the base level to level 1. The levels within the used range now have inconsistent
2635 // dimensions and the texture should be incomplete.
2636 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2637
2638 EXPECT_GL_NO_ERROR();
2639
2640 drawQuad(mProgram, "position", 0.5f);
2641
2642 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2643}
2644
2645// Test that texture is not complete if base level is greater than max level.
2646// GLES 3.0.4 section 3.8.13 Texture completeness
2647TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2648{
Olli Etuahoa314b612016-03-10 16:43:00 +02002649 glActiveTexture(GL_TEXTURE0);
2650 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2651
2652 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2653 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2654
2655 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2656
2657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2659
2660 EXPECT_GL_NO_ERROR();
2661
2662 drawQuad(mProgram, "position", 0.5f);
2663
2664 // Texture should be incomplete.
2665 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2666}
2667
2668// Test that immutable texture base level and max level are clamped.
2669// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2670TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2671{
Olli Etuahoa314b612016-03-10 16:43:00 +02002672 glActiveTexture(GL_TEXTURE0);
2673 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2674
2675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2677
2678 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2679
2680 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2681
2682 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2683 // should be clamped to [base_level, levels - 1].
2684 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2685 // In the case of this test, those rules make the effective base level and max level 0.
2686 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2687 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2688
2689 EXPECT_GL_NO_ERROR();
2690
2691 drawQuad(mProgram, "position", 0.5f);
2692
2693 // Texture should be complete.
2694 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2695}
2696
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002697// Test that changing base level works when it affects the format of the texture.
2698TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2699{
Corentin Wallez7f00d332019-08-28 15:19:16 +02002700 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2701 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2702
Yunchao He8e5ba8b2018-02-05 17:52:27 +08002703 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
Yunchao He9550c602018-02-13 14:47:05 +08002704
2705 // Observed incorrect rendering on AMD OpenGL.
2706 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002707
2708 glActiveTexture(GL_TEXTURE0);
2709 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2710 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2711 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2712
2713 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2715
2716 // RGBA8 level that's initially unused.
2717 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2718 texDataCyan.data());
2719
2720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2722
2723 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2724 // format. It reads green channel data from the green and alpha channels of texDataGreen
2725 // (this is a bit hacky but works).
2726 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2727
2728 EXPECT_GL_NO_ERROR();
2729
2730 drawQuad(mProgram, "position", 0.5f);
2731
2732 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2733
2734 // Switch the texture to use the cyan level 0 with the RGBA format.
2735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2737
2738 EXPECT_GL_NO_ERROR();
2739
2740 drawQuad(mProgram, "position", 0.5f);
2741
2742 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2743}
2744
Olli Etuahoa314b612016-03-10 16:43:00 +02002745// Test that setting a texture image works when base level is out of range.
2746TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2747{
2748 glActiveTexture(GL_TEXTURE0);
2749 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2750
2751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2752 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2753
2754 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2755 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2756
2757 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2758
2759 EXPECT_GL_NO_ERROR();
2760
2761 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2762
2763 drawQuad(mProgram, "position", 0.5f);
2764
2765 // Texture should be complete.
2766 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002767}
2768
Jamie Madill50cf2be2018-06-15 09:46:57 -04002769// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
2770// RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
2771// with these formats does not work as expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002772TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002773{
2774 std::vector<GLubyte> pixelData;
2775 for (size_t count = 0; count < 5000; count++)
2776 {
2777 pixelData.push_back(0u);
2778 pixelData.push_back(255u);
2779 pixelData.push_back(0u);
2780 }
2781
2782 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002783 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002784 glUniform1i(mTextureArrayLocation, 0);
2785
2786 // The first draw worked correctly.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002787 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2788 &pixelData[0]);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002789
2790 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2791 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2792 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2793 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002794 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002795 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002796
2797 // The dimension of the respecification must match the original exactly to trigger the bug.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002798 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2799 &pixelData[0]);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002800 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002801 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002802
2803 ASSERT_GL_NO_ERROR();
2804}
2805
Olli Etuaho1a679902016-01-14 12:21:47 +02002806// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2807// This test is needed especially to confirm that sampler registers get assigned correctly on
2808// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2809TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2810{
2811 glActiveTexture(GL_TEXTURE0);
2812 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2813 GLubyte texData[4];
2814 texData[0] = 0;
2815 texData[1] = 60;
2816 texData[2] = 0;
2817 texData[3] = 255;
2818 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2819
2820 glActiveTexture(GL_TEXTURE1);
2821 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2822 GLfloat depthTexData[1];
2823 depthTexData[0] = 0.5f;
2824 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2825 depthTexData);
2826
2827 glUseProgram(mProgram);
2828 glUniform1f(mDepthRefUniformLocation, 0.3f);
2829 glUniform1i(mTexture3DUniformLocation, 0);
2830 glUniform1i(mTextureShadowUniformLocation, 1);
2831
2832 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2833 drawQuad(mProgram, "position", 0.5f);
2834 EXPECT_GL_NO_ERROR();
2835 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2836 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2837
2838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2839 drawQuad(mProgram, "position", 0.5f);
2840 EXPECT_GL_NO_ERROR();
2841 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2842 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2843}
2844
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002845// Test multiple different sampler types in the same shader.
2846// This test makes sure that even if sampler / texture registers get grouped together based on type
2847// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2848// still has the right register index information for each ESSL sampler.
2849// The tested ESSL samplers have the following types in D3D11 HLSL:
2850// sampler2D: Texture2D + SamplerState
2851// samplerCube: TextureCube + SamplerState
2852// sampler2DShadow: Texture2D + SamplerComparisonState
2853// samplerCubeShadow: TextureCube + SamplerComparisonState
2854TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2855{
2856 glActiveTexture(GL_TEXTURE0);
2857 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2858 GLubyte texData[4];
2859 texData[0] = 0;
2860 texData[1] = 0;
2861 texData[2] = 120;
2862 texData[3] = 255;
2863 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2864
2865 glActiveTexture(GL_TEXTURE1);
2866 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2867 texData[0] = 0;
2868 texData[1] = 90;
2869 texData[2] = 0;
2870 texData[3] = 255;
2871 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2872 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2873 texData);
2874
2875 glActiveTexture(GL_TEXTURE2);
2876 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2877 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2878 GLfloat depthTexData[1];
2879 depthTexData[0] = 0.5f;
2880 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2881 depthTexData);
2882
2883 glActiveTexture(GL_TEXTURE3);
2884 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2885 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2886 depthTexData[0] = 0.2f;
2887 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2888 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2889 depthTexData);
2890
Tobin Ehlisbbf0ce22019-10-11 06:55:36 -06002891 // http://anglebug.com/3949: TODO: Add a DS texture case
2892
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002893 EXPECT_GL_NO_ERROR();
2894
2895 glUseProgram(mProgram);
2896 glUniform1f(mDepthRefUniformLocation, 0.3f);
2897 glUniform1i(mTexture2DUniformLocation, 0);
2898 glUniform1i(mTextureCubeUniformLocation, 1);
2899 glUniform1i(mTexture2DShadowUniformLocation, 2);
2900 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2901
2902 drawQuad(mProgram, "position", 0.5f);
2903 EXPECT_GL_NO_ERROR();
2904 // The shader writes:
2905 // <texture 2d color> +
2906 // <cube map color> +
2907 // 0.25 * <comparison result (1.0)> +
2908 // 0.125 * <comparison result (0.0)>
2909 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2910}
2911
Olli Etuahobce743a2016-01-15 17:18:28 +02002912// Test different base levels on textures accessed through the same sampler array.
2913// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2914TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2915{
Yunchao He9550c602018-02-13 14:47:05 +08002916 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
2917
Jamie Madill788fa362020-02-10 14:07:12 -05002918 // http://anglebug.com/4391
2919 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
2920
Olli Etuahobce743a2016-01-15 17:18:28 +02002921 glActiveTexture(GL_TEXTURE0);
2922 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2923 GLsizei size = 64;
2924 for (GLint level = 0; level < 7; ++level)
2925 {
2926 ASSERT_LT(0, size);
2927 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2928 nullptr);
2929 size = size / 2;
2930 }
2931 ASSERT_EQ(0, size);
2932 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2933
2934 glActiveTexture(GL_TEXTURE1);
2935 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2936 size = 128;
2937 for (GLint level = 0; level < 8; ++level)
2938 {
2939 ASSERT_LT(0, size);
2940 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2941 nullptr);
2942 size = size / 2;
2943 }
2944 ASSERT_EQ(0, size);
2945 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2946 EXPECT_GL_NO_ERROR();
2947
2948 glUseProgram(mProgram);
2949 glUniform1i(mTexture0Location, 0);
2950 glUniform1i(mTexture1Location, 1);
2951
Olli Etuaho5804dc82018-04-13 14:11:46 +03002952 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
Olli Etuahobce743a2016-01-15 17:18:28 +02002953 EXPECT_GL_NO_ERROR();
2954 // Red channel: width of level 1 of texture A: 32.
2955 // Green channel: width of level 3 of texture B: 16.
2956 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2957}
2958
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002959// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2960// ES 3.0.4 table 3.24
2961TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2962{
2963 glActiveTexture(GL_TEXTURE0);
2964 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2965 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2966 EXPECT_GL_NO_ERROR();
2967
2968 drawQuad(mProgram, "position", 0.5f);
2969
2970 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2971}
2972
2973// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2974// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05002975TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002976{
Luc Ferron5164b792018-03-06 09:10:12 -05002977 setUpProgram();
2978
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002979 glActiveTexture(GL_TEXTURE0);
2980 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2981 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2982 EXPECT_GL_NO_ERROR();
2983
2984 drawQuad(mProgram, "position", 0.5f);
2985
2986 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2987}
2988
Luc Ferron5164b792018-03-06 09:10:12 -05002989// Validate that every component of the pixel will be equal to the luminance value we've set
2990// and that the alpha channel will be 1 (or 255 to be exact).
2991TEST_P(Texture2DTest, TextureLuminanceRGBSame)
2992{
2993 setUpProgram();
2994
2995 glActiveTexture(GL_TEXTURE0);
2996 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2997 uint8_t pixel = 50;
2998 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
2999 EXPECT_GL_NO_ERROR();
3000
3001 drawQuad(mProgram, "position", 0.5f);
3002
3003 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
3004}
3005
3006// Validate that every component of the pixel will be equal to the luminance value we've set
3007// and that the alpha channel will be the second component.
3008TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
3009{
3010 setUpProgram();
3011
3012 glActiveTexture(GL_TEXTURE0);
3013 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3014 uint8_t pixel[] = {50, 25};
3015 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
3016 GL_UNSIGNED_BYTE, pixel);
3017 EXPECT_GL_NO_ERROR();
3018
3019 drawQuad(mProgram, "position", 0.5f);
3020
3021 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
3022}
3023
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003024// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3025// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003026TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003027{
Jamie Madillb8149072019-04-30 16:14:44 -04003028 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003029 ANGLE_SKIP_TEST_IF(IsD3D9());
3030 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferron5164b792018-03-06 09:10:12 -05003031
3032 setUpProgram();
3033
Luc Ferrond8c632c2018-04-10 12:31:44 -04003034 glActiveTexture(GL_TEXTURE0);
3035 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3036 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
3037 EXPECT_GL_NO_ERROR();
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003038
Luc Ferrond8c632c2018-04-10 12:31:44 -04003039 drawQuad(mProgram, "position", 0.5f);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003040
Luc Ferrond8c632c2018-04-10 12:31:44 -04003041 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003042}
3043
3044// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3045// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003046TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003047{
Jamie Madillb8149072019-04-30 16:14:44 -04003048 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003049 ANGLE_SKIP_TEST_IF(IsD3D9());
3050 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferrond8c632c2018-04-10 12:31:44 -04003051 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
3052 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
Luc Ferron5164b792018-03-06 09:10:12 -05003053
Luc Ferrond8c632c2018-04-10 12:31:44 -04003054 setUpProgram();
Luc Ferron5164b792018-03-06 09:10:12 -05003055
Luc Ferrond8c632c2018-04-10 12:31:44 -04003056 glActiveTexture(GL_TEXTURE0);
3057 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3058 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
3059 EXPECT_GL_NO_ERROR();
Yunchao He9550c602018-02-13 14:47:05 +08003060
Luc Ferrond8c632c2018-04-10 12:31:44 -04003061 drawQuad(mProgram, "position", 0.5f);
Yuly Novikovafcec832016-06-21 22:19:51 -04003062
Luc Ferrond8c632c2018-04-10 12:31:44 -04003063 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003064}
3065
3066// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3067// ES 3.0.4 table 3.24
3068TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
3069{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003070 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3071
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003072 glActiveTexture(GL_TEXTURE0);
3073 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3074 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
3075 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3076 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3077 EXPECT_GL_NO_ERROR();
3078
3079 drawQuad(mProgram, "position", 0.5f);
3080
3081 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3082}
3083
3084// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3085// ES 3.0.4 table 3.24
3086TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
3087{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003088 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3089
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003090 glActiveTexture(GL_TEXTURE0);
3091 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3092
3093 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
3094 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3096 EXPECT_GL_NO_ERROR();
3097
3098 drawQuad(mProgram, "position", 0.5f);
3099
3100 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3101}
3102
3103// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3104// ES 3.0.4 table 3.24
3105TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
3106{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003107 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3108
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003109 glActiveTexture(GL_TEXTURE0);
3110 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3111 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
3112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3114 EXPECT_GL_NO_ERROR();
3115
3116 drawQuad(mProgram, "position", 0.5f);
3117
3118 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3119}
3120
3121// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3122// ES 3.0.4 table 3.24
3123TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
3124{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003125 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3126
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003127 glActiveTexture(GL_TEXTURE0);
3128 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3129 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
3130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3132 EXPECT_GL_NO_ERROR();
3133
3134 drawQuad(mProgram, "position", 0.5f);
3135
3136 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3137}
3138
3139// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3140// ES 3.0.4 table 3.24
3141TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
3142{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003143 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3144
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003145 glActiveTexture(GL_TEXTURE0);
3146 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3147 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
3148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3150 EXPECT_GL_NO_ERROR();
3151
3152 drawQuad(mProgram, "position", 0.5f);
3153
3154 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3155}
3156
3157// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3158// ES 3.0.4 table 3.24
3159TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
3160{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003161 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3162
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003163 glActiveTexture(GL_TEXTURE0);
3164 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3165 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
3166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3168 EXPECT_GL_NO_ERROR();
3169
3170 drawQuad(mProgram, "position", 0.5f);
3171
3172 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3173}
3174
3175// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3176// ES 3.0.4 table 3.24
3177TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
3178{
3179 glActiveTexture(GL_TEXTURE0);
3180 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3181 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
3182 EXPECT_GL_NO_ERROR();
3183
3184 drawQuad(mProgram, "position", 0.5f);
3185
3186 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3187}
3188
3189// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3190// ES 3.0.4 table 3.24
3191TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
3192{
3193 glActiveTexture(GL_TEXTURE0);
3194 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3195 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
3196 nullptr);
3197 EXPECT_GL_NO_ERROR();
3198
3199 drawQuad(mProgram, "position", 0.5f);
3200
3201 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3202}
3203
3204// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3205// ES 3.0.4 table 3.24
3206TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
3207{
Geoff Lang2a19c592019-08-23 14:10:24 -04003208 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3209 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003210
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003211 glActiveTexture(GL_TEXTURE0);
3212 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3213 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
3214 EXPECT_GL_NO_ERROR();
3215
3216 drawQuad(mProgram, "position", 0.5f);
3217
3218 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3219}
3220
3221// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3222// ES 3.0.4 table 3.24
3223TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
3224{
Geoff Lang2a19c592019-08-23 14:10:24 -04003225 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3226 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003227
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003228 glActiveTexture(GL_TEXTURE0);
3229 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3230 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
3231 EXPECT_GL_NO_ERROR();
3232
3233 drawQuad(mProgram, "position", 0.5f);
3234
3235 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3236}
3237
Olli Etuaho96963162016-03-21 11:54:33 +02003238// Use a sampler in a uniform struct.
3239TEST_P(SamplerInStructTest, SamplerInStruct)
3240{
3241 runSamplerInStructTest();
3242}
3243
3244// Use a sampler in a uniform struct that's passed as a function parameter.
3245TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
3246{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003247 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3248 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Geoff Lang8fcdf6e2016-09-16 10:45:30 -04003249
Olli Etuaho96963162016-03-21 11:54:33 +02003250 runSamplerInStructTest();
3251}
3252
3253// Use a sampler in a uniform struct array with a struct from the array passed as a function
3254// parameter.
3255TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
3256{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003257 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3258 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003259
Olli Etuaho96963162016-03-21 11:54:33 +02003260 runSamplerInStructTest();
3261}
3262
3263// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
3264// parameter.
3265TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
3266{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003267 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3268 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003269
Olli Etuaho96963162016-03-21 11:54:33 +02003270 runSamplerInStructTest();
3271}
3272
3273// Make sure that there isn't a name conflict between sampler extracted from a struct and a
3274// similarly named uniform.
3275TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
3276{
3277 runSamplerInStructTest();
3278}
3279
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003280// GL_EXT_texture_filter_anisotropic
3281class TextureAnisotropyTest : public Texture2DTest
3282{
3283 protected:
3284 void uploadTexture()
3285 {
3286 glActiveTexture(GL_TEXTURE0);
3287 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3288 GLColor texDataRed[1] = {GLColor::red};
3289 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
3290 EXPECT_GL_NO_ERROR();
3291 }
3292};
3293
3294// Tests that setting anisotropic filtering doesn't cause failures at draw time.
3295TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
3296{
Jamie Madillb8149072019-04-30 16:14:44 -04003297 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003298
3299 setUpProgram();
3300
3301 uploadTexture();
3302
3303 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3304 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3305 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
3306 EXPECT_GL_NO_ERROR();
3307
3308 drawQuad(mProgram, "position", 0.5f);
3309
3310 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3311 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3312 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
3313}
3314
Till Rathmannb8543632018-10-02 19:46:14 +02003315// GL_OES_texture_border_clamp
3316class TextureBorderClampTest : public Texture2DTest
3317{
3318 protected:
3319 TextureBorderClampTest() : Texture2DTest() {}
3320
Jamie Madill35cd7332018-12-02 12:03:33 -05003321 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003322 {
3323 return
3324 R"(precision highp float;
3325 attribute vec4 position;
3326 varying vec2 texcoord;
3327
3328 void main()
3329 {
3330 gl_Position = vec4(position.xy, 0.0, 1.0);
3331 // texcoords in [-0.5, 1.5]
3332 texcoord = (position.xy) + 0.5;
3333 })";
3334 }
3335
3336 void uploadTexture()
3337 {
3338 glActiveTexture(GL_TEXTURE0);
3339 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3340 std::vector<GLColor> texDataRed(1, GLColor::red);
3341 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3342 texDataRed.data());
3343 EXPECT_GL_NO_ERROR();
3344 }
3345};
3346
3347// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3348// GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
3349TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
3350{
Jamie Madillb8149072019-04-30 16:14:44 -04003351 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003352
3353 setUpProgram();
3354
3355 uploadTexture();
3356
3357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3358 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3359 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3361 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3362 EXPECT_GL_NO_ERROR();
3363
3364 drawQuad(mProgram, "position", 0.5f);
3365
3366 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3367 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3368 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3369}
3370
3371// Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
3372TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
3373{
Jamie Madillb8149072019-04-30 16:14:44 -04003374 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003375
3376 glActiveTexture(GL_TEXTURE0);
3377 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3378
3379 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3380
3381 GLint colorFixedPoint[4] = {0};
3382 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3383 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3384 std::numeric_limits<GLint>::max()};
3385 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3386 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3387 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3388 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3389
3390 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3391 std::numeric_limits<GLint>::max()};
3392 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3393
3394 GLfloat color[4] = {0.0f};
3395 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
3396 EXPECT_EQ(color[0], kFloatBlue.R);
3397 EXPECT_EQ(color[1], kFloatBlue.G);
3398 EXPECT_EQ(color[2], kFloatBlue.B);
3399 EXPECT_EQ(color[3], kFloatBlue.A);
3400}
3401
3402// Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
3403TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
3404{
Jamie Madillb8149072019-04-30 16:14:44 -04003405 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003406
3407 glActiveTexture(GL_TEXTURE0);
3408 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3409
3410 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
3411 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3412
3413 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3414 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3415
3416 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3417 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3418
3419 GLint colorInt[4] = {0};
3420 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
3421 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3422
3423 if (getClientMajorVersion() < 3)
3424 {
3425 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3426 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3427 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3428 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3429
3430 GLuint colorUInt[4] = {0};
3431 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3432 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3433 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3434 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3435
3436 GLSampler sampler;
3437 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3438 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3439 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3440 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3441
3442 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3443 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3444 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3445 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3446 }
3447}
3448
3449class TextureBorderClampTestES3 : public TextureBorderClampTest
3450{
3451 protected:
3452 TextureBorderClampTestES3() : TextureBorderClampTest() {}
3453};
3454
3455// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3456// GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
3457TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
3458{
Jamie Madillb8149072019-04-30 16:14:44 -04003459 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003460
3461 setUpProgram();
3462
3463 uploadTexture();
3464
3465 GLSampler sampler;
3466 glBindSampler(0, sampler);
3467 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3468 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3469 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3470 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3471 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3472 EXPECT_GL_NO_ERROR();
3473
3474 drawQuad(mProgram, "position", 0.5f);
3475
3476 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3477 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3478 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3479}
3480
3481// Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
3482TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
3483{
Jamie Madillb8149072019-04-30 16:14:44 -04003484 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003485
3486 glActiveTexture(GL_TEXTURE0);
3487
3488 GLSampler sampler;
3489 glBindSampler(0, sampler);
3490
3491 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3492
3493 GLint colorFixedPoint[4] = {0};
3494 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3495 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3496 std::numeric_limits<GLint>::max()};
3497 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3498 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3499 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3500 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3501
3502 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3503 std::numeric_limits<GLint>::max()};
3504 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3505
3506 GLfloat color[4] = {0.0f};
3507 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
3508 EXPECT_EQ(color[0], kFloatBlue.R);
3509 EXPECT_EQ(color[1], kFloatBlue.G);
3510 EXPECT_EQ(color[2], kFloatBlue.B);
3511 EXPECT_EQ(color[3], kFloatBlue.A);
3512
3513 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
3514 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
3515 GLint colorInt[4] = {0};
3516 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3517 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
3518 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
3519 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
3520 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
3521
3522 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
3523 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
3524 GLuint colorUInt[4] = {0};
3525 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3526 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
3527 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
3528 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
3529 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
3530
3531 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3532
3533 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
3534 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
3535 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3536 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
3537 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
3538 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
3539 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
3540
3541 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
3542 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
3543 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3544 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
3545 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
3546 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
3547 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
3548}
3549
3550// Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
3551TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
3552{
Jamie Madillb8149072019-04-30 16:14:44 -04003553 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003554
3555 glActiveTexture(GL_TEXTURE0);
3556
3557 GLSampler sampler;
3558 glBindSampler(0, sampler);
3559
3560 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
3561 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3562
3563 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3564 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3565}
3566
3567class TextureBorderClampIntegerTestES3 : public Texture2DTest
3568{
3569 protected:
3570 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
3571
Jamie Madill35cd7332018-12-02 12:03:33 -05003572 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003573 {
3574 return
3575 R"(#version 300 es
3576 out vec2 texcoord;
3577 in vec4 position;
3578
3579 void main()
3580 {
3581 gl_Position = vec4(position.xy, 0.0, 1.0);
3582 // texcoords in [-0.5, 1.5]
3583 texcoord = (position.xy) + 0.5;
3584 })";
3585 }
3586
Jamie Madillba319ba2018-12-29 10:29:33 -05003587 const char *getFragmentShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003588 {
Jamie Madill35cd7332018-12-02 12:03:33 -05003589 if (isUnsignedIntTest)
3590 {
3591 return "#version 300 es\n"
3592 "precision highp float;\n"
3593 "uniform highp usampler2D tex;\n"
3594 "in vec2 texcoord;\n"
3595 "out vec4 fragColor;\n"
Till Rathmannb8543632018-10-02 19:46:14 +02003596
Jamie Madill35cd7332018-12-02 12:03:33 -05003597 "void main()\n"
3598 "{\n"
3599 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3600 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3601 "fragColor = (texture(tex, texcoord).r == 150u)"
3602 " ? green : red;\n"
3603 "}\n";
3604 }
3605 else
3606 {
3607 return "#version 300 es\n"
3608 "precision highp float;\n"
3609 "uniform highp isampler2D tex;\n"
3610 "in vec2 texcoord;\n"
3611 "out vec4 fragColor;\n"
3612
3613 "void main()\n"
3614 "{\n"
3615 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3616 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3617 "fragColor = (texture(tex, texcoord).r == -50)"
3618 " ? green : red;\n"
3619 "}\n";
3620 }
Till Rathmannb8543632018-10-02 19:46:14 +02003621 }
3622
3623 void uploadTexture()
3624 {
3625 glActiveTexture(GL_TEXTURE0);
3626 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3627 if (isUnsignedIntTest)
3628 {
3629 std::vector<GLubyte> texData(4, 100);
3630 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
3631 texData.data());
3632 }
3633 else
3634 {
3635 std::vector<GLbyte> texData(4, 100);
3636 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
3637 texData.data());
3638 }
3639 EXPECT_GL_NO_ERROR();
3640 }
3641
3642 bool isUnsignedIntTest;
3643};
3644
3645// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3646// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3647TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
3648{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003649 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3650 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3651
Jamie Madillb8149072019-04-30 16:14:44 -04003652 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003653
3654 setUpProgram();
3655
3656 uploadTexture();
3657
3658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3659 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3660 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3661 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3662
3663 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3664 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3665
3666 EXPECT_GL_NO_ERROR();
3667
3668 drawQuad(mProgram, "position", 0.5f);
3669
3670 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3671 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3672 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3673}
3674
3675// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3676// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3677TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
3678{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003679 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3680 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3681
Jamie Madillb8149072019-04-30 16:14:44 -04003682 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003683
3684 setUpProgram();
3685
3686 uploadTexture();
3687
3688 GLSampler sampler;
3689 glBindSampler(0, sampler);
3690 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3691 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3692 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3693 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3694
3695 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3696 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3697
3698 EXPECT_GL_NO_ERROR();
3699
3700 drawQuad(mProgram, "position", 0.5f);
3701
3702 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3703 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3704 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3705}
3706
3707// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3708// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
3709TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
3710{
Jamie Madillb8149072019-04-30 16:14:44 -04003711 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003712
3713 isUnsignedIntTest = true;
3714
3715 setUpProgram();
3716
3717 uploadTexture();
3718
3719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3722 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3723
3724 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3725 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3726
3727 EXPECT_GL_NO_ERROR();
3728
3729 drawQuad(mProgram, "position", 0.5f);
3730
3731 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3732 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3733 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3734}
3735
3736// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3737// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
3738// glSamplerParameterIuivOES).
3739TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
3740{
Jamie Madillb8149072019-04-30 16:14:44 -04003741 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003742
3743 isUnsignedIntTest = true;
3744
3745 setUpProgram();
3746
3747 uploadTexture();
3748
3749 GLSampler sampler;
3750 glBindSampler(0, sampler);
3751 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3752 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3753 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3754 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3755
3756 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3757 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3758
3759 EXPECT_GL_NO_ERROR();
3760
3761 drawQuad(mProgram, "position", 0.5f);
3762
3763 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3764 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3765 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3766}
3767
3768// ~GL_OES_texture_border_clamp
3769
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003770class TextureLimitsTest : public ANGLETest
3771{
3772 protected:
3773 struct RGBA8
3774 {
3775 uint8_t R, G, B, A;
3776 };
3777
3778 TextureLimitsTest()
3779 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
3780 {
3781 setWindowWidth(128);
3782 setWindowHeight(128);
3783 setConfigRedBits(8);
3784 setConfigGreenBits(8);
3785 setConfigBlueBits(8);
3786 setConfigAlphaBits(8);
3787 }
3788
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003789 void testSetUp() override
Jamie Madill0fdb9562018-09-17 17:18:43 -04003790 {
Jamie Madill0fdb9562018-09-17 17:18:43 -04003791 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
3792 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
3793 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
3794
3795 ASSERT_GL_NO_ERROR();
3796 }
3797
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003798 void testTearDown() override
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003799 {
3800 if (mProgram != 0)
3801 {
3802 glDeleteProgram(mProgram);
3803 mProgram = 0;
3804
3805 if (!mTextures.empty())
3806 {
3807 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
3808 }
3809 }
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003810 }
3811
3812 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
3813 GLint vertexTextureCount,
3814 GLint vertexActiveTextureCount,
3815 const std::string &fragPrefix,
3816 GLint fragmentTextureCount,
3817 GLint fragmentActiveTextureCount)
3818 {
3819 std::stringstream vertexShaderStr;
3820 vertexShaderStr << "attribute vec2 position;\n"
3821 << "varying vec4 color;\n"
3822 << "varying vec2 texCoord;\n";
3823
3824 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
3825 {
3826 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
3827 }
3828
3829 vertexShaderStr << "void main() {\n"
3830 << " gl_Position = vec4(position, 0, 1);\n"
3831 << " texCoord = (position * 0.5) + 0.5;\n"
3832 << " color = vec4(0);\n";
3833
3834 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
3835 {
3836 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
3837 << ", texCoord);\n";
3838 }
3839
3840 vertexShaderStr << "}";
3841
3842 std::stringstream fragmentShaderStr;
3843 fragmentShaderStr << "varying mediump vec4 color;\n"
3844 << "varying mediump vec2 texCoord;\n";
3845
3846 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
3847 {
3848 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
3849 }
3850
3851 fragmentShaderStr << "void main() {\n"
3852 << " gl_FragColor = color;\n";
3853
3854 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
3855 {
3856 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
3857 << ", texCoord);\n";
3858 }
3859
3860 fragmentShaderStr << "}";
3861
3862 const std::string &vertexShaderSource = vertexShaderStr.str();
3863 const std::string &fragmentShaderSource = fragmentShaderStr.str();
3864
Jamie Madill35cd7332018-12-02 12:03:33 -05003865 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003866 }
3867
3868 RGBA8 getPixel(GLint texIndex)
3869 {
3870 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
3871 0, 255u};
3872 return pixel;
3873 }
3874
3875 void initTextures(GLint tex2DCount, GLint texCubeCount)
3876 {
3877 GLint totalCount = tex2DCount + texCubeCount;
3878 mTextures.assign(totalCount, 0);
3879 glGenTextures(totalCount, &mTextures[0]);
3880 ASSERT_GL_NO_ERROR();
3881
3882 std::vector<RGBA8> texData(16 * 16);
3883
3884 GLint texIndex = 0;
3885 for (; texIndex < tex2DCount; ++texIndex)
3886 {
3887 texData.assign(texData.size(), getPixel(texIndex));
3888 glActiveTexture(GL_TEXTURE0 + texIndex);
3889 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
3890 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3891 &texData[0]);
3892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3893 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3894 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3895 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3896 }
3897
3898 ASSERT_GL_NO_ERROR();
3899
3900 for (; texIndex < texCubeCount; ++texIndex)
3901 {
3902 texData.assign(texData.size(), getPixel(texIndex));
3903 glActiveTexture(GL_TEXTURE0 + texIndex);
3904 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
3905 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3906 GL_UNSIGNED_BYTE, &texData[0]);
3907 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3908 GL_UNSIGNED_BYTE, &texData[0]);
3909 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3910 GL_UNSIGNED_BYTE, &texData[0]);
3911 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3912 GL_UNSIGNED_BYTE, &texData[0]);
3913 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3914 GL_UNSIGNED_BYTE, &texData[0]);
3915 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3916 GL_UNSIGNED_BYTE, &texData[0]);
3917 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3918 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3919 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3920 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3921 }
3922
3923 ASSERT_GL_NO_ERROR();
3924 }
3925
3926 void testWithTextures(GLint vertexTextureCount,
3927 const std::string &vertexTexturePrefix,
3928 GLint fragmentTextureCount,
3929 const std::string &fragmentTexturePrefix)
3930 {
3931 // Generate textures
3932 initTextures(vertexTextureCount + fragmentTextureCount, 0);
3933
3934 glUseProgram(mProgram);
3935 RGBA8 expectedSum = {0};
3936 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
3937 {
3938 std::stringstream uniformNameStr;
3939 uniformNameStr << vertexTexturePrefix << texIndex;
3940 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003941 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003942 ASSERT_NE(-1, location);
3943
3944 glUniform1i(location, texIndex);
3945 RGBA8 contribution = getPixel(texIndex);
3946 expectedSum.R += contribution.R;
3947 expectedSum.G += contribution.G;
3948 }
3949
3950 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
3951 {
3952 std::stringstream uniformNameStr;
3953 uniformNameStr << fragmentTexturePrefix << texIndex;
3954 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003955 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003956 ASSERT_NE(-1, location);
3957
3958 glUniform1i(location, texIndex + vertexTextureCount);
3959 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
3960 expectedSum.R += contribution.R;
3961 expectedSum.G += contribution.G;
3962 }
3963
3964 ASSERT_GE(256u, expectedSum.G);
3965
3966 drawQuad(mProgram, "position", 0.5f);
3967 ASSERT_GL_NO_ERROR();
3968 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
3969 }
3970
3971 GLuint mProgram;
3972 std::vector<GLuint> mTextures;
3973 GLint mMaxVertexTextures;
3974 GLint mMaxFragmentTextures;
3975 GLint mMaxCombinedTextures;
3976};
3977
3978// Test rendering with the maximum vertex texture units.
3979TEST_P(TextureLimitsTest, MaxVertexTextures)
3980{
3981 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
3982 ASSERT_NE(0u, mProgram);
3983 ASSERT_GL_NO_ERROR();
3984
3985 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3986}
3987
3988// Test rendering with the maximum fragment texture units.
3989TEST_P(TextureLimitsTest, MaxFragmentTextures)
3990{
3991 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
3992 ASSERT_NE(0u, mProgram);
3993 ASSERT_GL_NO_ERROR();
3994
3995 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
3996}
3997
3998// Test rendering with maximum combined texture units.
3999TEST_P(TextureLimitsTest, MaxCombinedTextures)
4000{
4001 GLint vertexTextures = mMaxVertexTextures;
4002
4003 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
4004 {
4005 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
4006 }
4007
4008 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
4009 mMaxFragmentTextures, mMaxFragmentTextures);
4010 ASSERT_NE(0u, mProgram);
4011 ASSERT_GL_NO_ERROR();
4012
4013 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
4014}
4015
4016// Negative test for exceeding the number of vertex textures
4017TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
4018{
4019 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
4020 0);
4021 ASSERT_EQ(0u, mProgram);
4022}
4023
4024// Negative test for exceeding the number of fragment textures
4025TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
4026{
4027 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
4028 mMaxFragmentTextures + 1);
4029 ASSERT_EQ(0u, mProgram);
4030}
4031
4032// Test active vertex textures under the limit, but excessive textures specified.
4033TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
4034{
4035 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
4036 ASSERT_NE(0u, mProgram);
4037 ASSERT_GL_NO_ERROR();
4038
4039 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4040}
4041
4042// Test active fragment textures under the limit, but excessive textures specified.
4043TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
4044{
4045 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
4046 mMaxFragmentTextures);
4047 ASSERT_NE(0u, mProgram);
4048 ASSERT_GL_NO_ERROR();
4049
4050 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
4051}
4052
4053// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02004054// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004055TEST_P(TextureLimitsTest, TextureTypeConflict)
4056{
Jamie Madill35cd7332018-12-02 12:03:33 -05004057 constexpr char kVS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004058 "attribute vec2 position;\n"
4059 "varying float color;\n"
4060 "uniform sampler2D tex2D;\n"
4061 "uniform samplerCube texCube;\n"
4062 "void main() {\n"
4063 " gl_Position = vec4(position, 0, 1);\n"
4064 " vec2 texCoord = (position * 0.5) + 0.5;\n"
4065 " color = texture2D(tex2D, texCoord).x;\n"
4066 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
4067 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05004068 constexpr char kFS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004069 "varying mediump float color;\n"
4070 "void main() {\n"
4071 " gl_FragColor = vec4(color, 0, 0, 1);\n"
4072 "}";
4073
Jamie Madill35cd7332018-12-02 12:03:33 -05004074 mProgram = CompileProgram(kVS, kFS);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004075 ASSERT_NE(0u, mProgram);
4076
4077 initTextures(1, 0);
4078
4079 glUseProgram(mProgram);
4080 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
4081 ASSERT_NE(-1, tex2DLocation);
4082 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
4083 ASSERT_NE(-1, texCubeLocation);
4084
4085 glUniform1i(tex2DLocation, 0);
4086 glUniform1i(texCubeLocation, 0);
4087 ASSERT_GL_NO_ERROR();
4088
4089 drawQuad(mProgram, "position", 0.5f);
4090 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4091}
4092
Vincent Lang25ab4512016-05-13 18:13:59 +02004093class Texture2DNorm16TestES3 : public Texture2DTestES3
4094{
4095 protected:
4096 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
4097
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004098 void testSetUp() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004099 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004100 Texture2DTestES3::testSetUp();
Vincent Lang25ab4512016-05-13 18:13:59 +02004101
4102 glActiveTexture(GL_TEXTURE0);
4103 glGenTextures(3, mTextures);
4104 glGenFramebuffers(1, &mFBO);
4105 glGenRenderbuffers(1, &mRenderbuffer);
4106
4107 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
4108 {
4109 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
4110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4112 }
4113
4114 glBindTexture(GL_TEXTURE_2D, 0);
4115
4116 ASSERT_GL_NO_ERROR();
4117 }
4118
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004119 void testTearDown() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004120 {
4121 glDeleteTextures(3, mTextures);
4122 glDeleteFramebuffers(1, &mFBO);
4123 glDeleteRenderbuffers(1, &mRenderbuffer);
4124
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004125 Texture2DTestES3::testTearDown();
Vincent Lang25ab4512016-05-13 18:13:59 +02004126 }
4127
4128 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
4129 {
shrekshao81ee4d22019-12-04 17:05:11 -08004130 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4131 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4132 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4133
Geoff Langf607c602016-09-21 11:46:48 -04004134 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
4135 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004136
4137 setUpProgram();
4138
4139 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4140 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
4141 0);
4142
4143 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
4144 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
4145
4146 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Geoff Langf607c602016-09-21 11:46:48 -04004147 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004148
4149 EXPECT_GL_NO_ERROR();
4150
4151 drawQuad(mProgram, "position", 0.5f);
4152
Geoff Langf607c602016-09-21 11:46:48 -04004153 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
Vincent Lang25ab4512016-05-13 18:13:59 +02004154
Jamie Madill50cf2be2018-06-15 09:46:57 -04004155 EXPECT_PIXEL_COLOR_EQ(0, 0,
4156 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
4157 expectedValue, expectedValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004158
4159 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4160
4161 ASSERT_GL_NO_ERROR();
4162 }
4163
shrekshao81ee4d22019-12-04 17:05:11 -08004164 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
4165 GLuint y,
4166 GLuint width,
4167 GLuint height,
4168 GLint packRowLength,
4169 GLint packAlignment,
4170 GLint packSkipPixels,
4171 GLint packSkipRows,
4172 GLenum type,
4173 GLColor16UI color)
Vincent Lang25ab4512016-05-13 18:13:59 +02004174 {
shrekshao81ee4d22019-12-04 17:05:11 -08004175 // PACK modes debugging
4176 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
4177 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
4178
4179 GLuint l = packRowLength == 0 ? width : packRowLength;
4180 const GLint &a = packAlignment;
4181
4182 // According to
4183 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4184 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
4185 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
4186 if (static_cast<GLuint>(packRowLength) < width)
4187 {
4188 componentCount += width * n * s - k;
4189 }
4190
4191 // Populate the pixels array with random dirty value
4192 constexpr GLushort kDirtyValue = 0x1234;
4193 std::vector<GLushort> pixels(componentCount, kDirtyValue);
4194 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
4195
4196 EXPECT_GL_NO_ERROR();
4197
4198 GLushort *pixelRowStart = pixels.data();
4199 pixelRowStart += n * packSkipPixels + k * packSkipRows;
4200
4201 std::vector<bool> modifiedPixels(componentCount, false);
4202
4203 char errorInfo[200];
4204
4205 for (GLuint y = 0; y < height; ++y)
4206 {
4207 GLushort *curPixel = pixelRowStart;
4208 for (GLuint x = 0, len = (y == height - 1) ? width : std::min(l, width); x < len; ++x)
4209 {
4210 snprintf(errorInfo, sizeof(errorInfo),
4211 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
4212 "skipPixels: %d, skipRows: %d\n",
4213 width, height, x, y, packRowLength, packAlignment, packSkipPixels,
4214 packSkipRows);
4215 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
4216 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
4217 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
4218 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
4219
4220 std::ptrdiff_t diff = curPixel - pixels.data();
4221 modifiedPixels[diff + 0] = true;
4222 modifiedPixels[diff + 1] = true;
4223 modifiedPixels[diff + 2] = true;
4224 modifiedPixels[diff + 3] = true;
4225
4226 curPixel += n;
4227 }
4228 pixelRowStart += k;
4229 }
4230
4231 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
4232 {
4233 if (!modifiedPixels[i])
4234 {
4235 EXPECT_EQ(pixels[i], kDirtyValue);
4236 }
4237 }
4238 }
4239
4240 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
4241 {
4242 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4243 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4244 // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
4245 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
4246 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4247
Jamie Madill50cf2be2018-06-15 09:46:57 -04004248 GLushort pixelValue = 0x6A35;
Geoff Langf607c602016-09-21 11:46:48 -04004249 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
shrekshao81ee4d22019-12-04 17:05:11 -08004250 GLColor16UI color = SliceFormatColor16UI(
4251 format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
4252 // Size of drawing viewport
4253 constexpr GLint width = 8, height = 8;
Vincent Lang25ab4512016-05-13 18:13:59 +02004254
4255 setUpProgram();
4256
4257 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
shrekshao81ee4d22019-12-04 17:05:11 -08004258 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
Vincent Lang25ab4512016-05-13 18:13:59 +02004259
4260 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4261 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4262 0);
4263
4264 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
Geoff Langf607c602016-09-21 11:46:48 -04004265 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
shrekshao81ee4d22019-12-04 17:05:11 -08004266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Vincent Lang25ab4512016-05-13 18:13:59 +02004268
4269 EXPECT_GL_NO_ERROR();
4270
4271 drawQuad(mProgram, "position", 0.5f);
4272
shrekshao81ee4d22019-12-04 17:05:11 -08004273 // ReadPixels against different width, height, pixel pack mode combinations to test
4274 // workaround of pixels rearrangement
4275
4276 // {x, y, width, height}
4277 std::vector<std::array<GLint, 4>> areas = {
4278 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
4279 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
4280
4281 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
4282
4283 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
4284 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
4285 };
4286
4287 // Put default settings at the last
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01004288 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
4289 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
shrekshao81ee4d22019-12-04 17:05:11 -08004290 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
4291 {3, 1}, {20, 20}, {0, 0}};
4292
4293 // Restore pixel pack modes later
4294 GLint restorePackAlignment;
4295 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
4296 GLint restorePackRowLength;
4297 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
4298 GLint restorePackSkipPixels;
4299 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
4300 GLint restorePackSkipRows;
4301 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
4302
4303 // Variable symbols are based on:
4304 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4305 for (const auto &skipped : paramsPackSkipPixelsAndRows)
4306 {
4307 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
4308 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
4309 for (GLint a : paramsPackAlignment)
4310 {
4311 glPixelStorei(GL_PACK_ALIGNMENT, a);
4312 for (GLint l : paramsPackRowLength)
4313 {
4314 glPixelStorei(GL_PACK_ROW_LENGTH, l);
4315
4316 for (const auto &area : areas)
4317 {
4318 ASSERT(area[0] + area[2] <= width);
4319 ASSERT(area[1] + area[3] <= height);
4320 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
4321 area[3], l, a, skipped[0],
4322 skipped[1], type, color);
4323 }
4324 }
4325 }
4326 }
4327
4328 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
4329 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
4330 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
4331 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
Vincent Lang25ab4512016-05-13 18:13:59 +02004332
4333 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4334 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4335 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4336 mRenderbuffer);
4337 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4338 EXPECT_GL_NO_ERROR();
4339
4340 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4341 glClear(GL_COLOR_BUFFER_BIT);
4342
shrekshaofb1c2fe2019-11-13 11:10:39 -08004343 EXPECT_PIXEL_16UI_COLOR(
4344 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
shrekshaoe33c1582019-11-06 16:55:29 -08004345
4346 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Vincent Lang25ab4512016-05-13 18:13:59 +02004347 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4348
shrekshaoe33c1582019-11-06 16:55:29 -08004349 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4350 0);
shrekshaofb1c2fe2019-11-13 11:10:39 -08004351 EXPECT_PIXEL_16UI_COLOR(
4352 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004353
4354 ASSERT_GL_NO_ERROR();
shrekshaofb1c2fe2019-11-13 11:10:39 -08004355
4356 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Vincent Lang25ab4512016-05-13 18:13:59 +02004357 }
4358
4359 GLuint mTextures[3];
4360 GLuint mFBO;
4361 GLuint mRenderbuffer;
4362};
4363
shrekshao81ee4d22019-12-04 17:05:11 -08004364TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
Vincent Lang25ab4512016-05-13 18:13:59 +02004365{
Vincent Lang25ab4512016-05-13 18:13:59 +02004366 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
shrekshao81ee4d22019-12-04 17:05:11 -08004367}
Vincent Lang25ab4512016-05-13 18:13:59 +02004368
shrekshao81ee4d22019-12-04 17:05:11 -08004369TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
4370{
4371 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
4372}
4373
4374TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
4375{
4376 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4377}
4378
4379TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
4380{
4381 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
4382}
4383
4384TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
4385{
4386 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4387 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4388
4389 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
4390}
4391
4392TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
4393{
4394 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4395 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4396
4397 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
4398}
4399
4400TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
4401{
4402 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4403}
4404
4405TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
4406{
4407 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
4408}
4409
4410TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
4411{
4412 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
4413}
4414
4415TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
4416{
4417 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4418}
4419
4420TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
4421{
4422 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
Vincent Lang25ab4512016-05-13 18:13:59 +02004423}
4424
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004425class Texture2DRGTest : public Texture2DTest
4426{
4427 protected:
4428 Texture2DRGTest()
4429 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4430 {}
4431
4432 void testSetUp() override
4433 {
4434 Texture2DTest::testSetUp();
4435
4436 glActiveTexture(GL_TEXTURE0);
4437 glGenTextures(1, &mRenderableTexture);
4438 glGenTextures(1, &mTestTexture);
4439 glGenFramebuffers(1, &mFBO);
4440 glGenRenderbuffers(1, &mRenderbuffer);
4441
4442 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004443 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4444 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004445 glBindTexture(GL_TEXTURE_2D, mTestTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004446 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4447 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004448
4449 glBindTexture(GL_TEXTURE_2D, 0);
4450
4451 setUpProgram();
4452 glUseProgram(mProgram);
4453 glUniform1i(mTexture2DUniformLocation, 0);
4454
4455 ASSERT_GL_NO_ERROR();
4456 }
4457
4458 void testTearDown() override
4459 {
4460 glDeleteTextures(1, &mRenderableTexture);
4461 glDeleteTextures(1, &mTestTexture);
4462 glDeleteFramebuffers(1, &mFBO);
4463 glDeleteRenderbuffers(1, &mRenderbuffer);
4464
4465 Texture2DTest::testTearDown();
4466 }
4467
4468 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
4469 {
4470 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4471 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4472
4473 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4474 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4475 mRenderableTexture, 0);
4476
4477 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4478 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
4479
4480 EXPECT_GL_NO_ERROR();
4481 }
4482
4483 void testRGTexture(GLColor expectedColor)
4484 {
4485 drawQuad(mProgram, "position", 0.5f);
4486
4487 EXPECT_GL_NO_ERROR();
4488 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
4489 }
4490
4491 void testRGRender(GLenum internalformat, GLenum format)
4492 {
4493 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4494 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4495 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4496 mRenderbuffer);
4497 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4498 EXPECT_GL_NO_ERROR();
4499
4500 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4501 glClear(GL_COLOR_BUFFER_BIT);
4502
4503 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4504
4505 ASSERT_GL_NO_ERROR();
4506 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
4507 }
4508
4509 GLuint mRenderableTexture;
4510 GLuint mTestTexture;
4511 GLuint mFBO;
4512 GLuint mRenderbuffer;
4513};
4514
4515// Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
4516TEST_P(Texture2DRGTest, TextureRGUNormTest)
4517{
4518 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4519
4520 GLubyte pixelValue = 0xab;
4521 GLubyte imageData[] = {pixelValue, pixelValue};
4522
4523 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
4524 testRGTexture(
4525 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4526 testRGRender(GL_R8_EXT, GL_RED_EXT);
4527
4528 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
4529 testRGTexture(
4530 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4531 testRGRender(GL_RG8_EXT, GL_RG_EXT);
4532}
4533
4534// Test float texture formats enabled by the GL_EXT_texture_rg extension.
4535TEST_P(Texture2DRGTest, TextureRGFloatTest)
4536{
4537 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4538 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4539
4540 GLfloat pixelValue = 0.54321;
4541 GLfloat imageData[] = {pixelValue, pixelValue};
4542
4543 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
4544 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4545
4546 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
4547 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4548
4549 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
4550 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4551}
4552
4553// Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
Mohan Maiya6caa2652019-09-11 08:06:13 -07004554TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004555{
4556 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4557 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4558
4559 GLfloat pixelValueFloat = 0.543f;
4560 GLhalf pixelValue = 0x3858;
4561 GLhalf imageData[] = {pixelValue, pixelValue};
4562
4563 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
4564 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4565
4566 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
4567 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4568
4569 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
4570 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4571}
4572
Mohan Maiya6caa2652019-09-11 08:06:13 -07004573class Texture2DFloatTest : public Texture2DTest
4574{
4575 protected:
4576 Texture2DFloatTest()
4577 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4578 {}
4579
4580 void testSetUp() override
4581 {
4582 Texture2DTest::testSetUp();
4583
4584 glActiveTexture(GL_TEXTURE0);
4585 glGenTextures(1, &mRenderableTexture);
4586 glGenTextures(1, &mTestTexture);
4587 glGenFramebuffers(1, &mFBO);
4588 glGenRenderbuffers(1, &mRenderbuffer);
4589
4590 setUpProgram();
4591 glUseProgram(mProgram);
4592 glUniform1i(mTexture2DUniformLocation, 0);
4593
4594 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4595 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4596
4597 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4598 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4599 mRenderableTexture, 0);
4600
4601 ASSERT_GL_NO_ERROR();
4602 }
4603
4604 void testTearDown() override
4605 {
4606 glDeleteTextures(1, &mRenderableTexture);
4607 glDeleteTextures(1, &mTestTexture);
4608 glDeleteFramebuffers(1, &mFBO);
4609 glDeleteRenderbuffers(1, &mRenderbuffer);
4610
4611 Texture2DTest::testTearDown();
4612 }
4613
4614 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
4615 {
4616 constexpr GLfloat imageDataFloat[] = {
4617 0.2f,
4618 0.3f,
4619 0.4f,
4620 0.5f,
4621 };
4622 constexpr GLhalf imageDataHalf[] = {
4623 0x3266,
4624 0x34CD,
4625 0x3666,
4626 0x3800,
4627 };
4628 GLColor expectedValue;
4629 for (int i = 0; i < 4; i++)
4630 {
4631 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
4632 }
4633
4634 const GLvoid *imageData;
4635 switch (type)
4636 {
4637 case GL_FLOAT:
4638 imageData = imageDataFloat;
4639 break;
4640 case GL_HALF_FLOAT:
4641 case GL_HALF_FLOAT_OES:
4642 imageData = imageDataHalf;
4643 break;
4644 default:
4645 imageData = nullptr;
4646 }
4647 ASSERT(imageData != nullptr);
4648
4649 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4650 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
4651
4652 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4653 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4654
4655 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4656 drawQuad(mProgram, "position", 0.5f);
4657
4658 EXPECT_GL_NO_ERROR();
4659 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
4660 }
4661
4662 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
4663 {
4664 int numComponents;
4665 switch (format)
4666 {
4667 case GL_RGBA:
4668 numComponents = 4;
4669 break;
4670 case GL_RGB:
4671 numComponents = 3;
4672 break;
4673 case GL_LUMINANCE_ALPHA:
4674 numComponents = 2;
4675 break;
4676 case GL_LUMINANCE:
4677 case GL_ALPHA:
4678 numComponents = 1;
4679 break;
4680 default:
4681 numComponents = 0;
4682 }
4683 ASSERT(numComponents > 0);
4684
4685 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
4686 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
4687
4688 GLfloat imageDataFloat[16];
4689 GLhalf imageDataHalf[16];
4690 for (int i = 0; i < 4; i++)
4691 {
4692 for (int c = 0; c < numComponents; c++)
4693 {
4694 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
4695 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
4696 }
4697 }
4698
4699 const GLvoid *imageData;
4700 switch (type)
4701 {
4702 case GL_FLOAT:
4703 imageData = imageDataFloat;
4704 break;
4705 case GL_HALF_FLOAT:
4706 case GL_HALF_FLOAT_OES:
4707 imageData = imageDataHalf;
4708 break;
4709 default:
4710 imageData = nullptr;
4711 }
4712 ASSERT(imageData != nullptr);
4713
4714 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4715 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
4716
4717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4719
4720 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4721 drawQuad(mProgram, "position", 0.5f);
4722
4723 EXPECT_GL_NO_ERROR();
4724 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
4725 // should expect the final value to be gray (halfway in-between)
4726 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
4727 kPixelTolerance);
4728 }
4729
4730 bool performFloatTextureRender(GLenum internalFormat,
4731 GLenum renderBufferFormat,
4732 GLenum format,
4733 GLenum type)
4734 {
4735 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4736 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
4737 glBindTexture(GL_TEXTURE_2D, 0);
4738
4739 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4740 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
4741 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4742 mRenderbuffer);
4743 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4744 EXPECT_GL_NO_ERROR();
4745
4746 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
4747 {
4748 return false;
4749 }
4750
4751 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4752
4753 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4754 glClear(GL_COLOR_BUFFER_BIT);
4755
4756 EXPECT_GL_NO_ERROR();
4757 return true;
4758 }
4759
4760 GLuint mRenderableTexture;
4761 GLuint mTestTexture;
4762 GLuint mFBO;
4763 GLuint mRenderbuffer;
4764};
4765
4766class Texture2DFloatTestES3 : public Texture2DFloatTest
4767{
4768 protected:
4769 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
4770 {
4771 bool framebufferComplete =
4772 performFloatTextureRender(internalFormat, internalFormat, format, type);
4773 EXPECT_TRUE(framebufferComplete);
4774 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4775 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4776 kPixelTolerance32F);
4777 }
4778};
4779
4780class Texture2DFloatTestES2 : public Texture2DFloatTest
4781{
4782 protected:
4783 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
4784 {
4785 bool framebufferComplete =
4786 performFloatTextureRender(format, renderBufferFormat, format, type);
4787
4788 if (!framebufferComplete)
4789 {
4790 return false;
4791 }
4792
4793 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4794 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4795 kPixelTolerance32F);
4796 return true;
4797 }
4798};
4799
4800// Test texture sampling for ES3 float texture formats
4801TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
4802{
4803 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4804 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
4805}
4806
4807// Test texture sampling for ES2 float texture formats
4808TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
4809{
4810 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4811 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
4812 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
4813}
4814
4815// Test texture sampling for ES3 half float texture formats
4816TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
4817{
4818 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4819 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4820}
4821
4822// Test texture sampling for ES2 half float texture formats
4823TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
4824{
4825 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4826 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4827 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4828}
4829
4830// Test texture sampling for legacy GLES 2.0 float texture formats in ES3
4831TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
4832{
4833 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4834
4835 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4836 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4837 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4838
4839 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4840 {
4841 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4842 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4843 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4844 }
4845}
4846
4847// Test texture sampling for legacy GLES 2.0 float texture formats in ES2
4848TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
4849{
4850 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4851
4852 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4853 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4854 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4855}
4856
4857// Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
4858TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
4859{
4860 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4861
4862 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4863 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4864 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4865
4866 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4867 {
4868 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4869 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4870 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4871 }
4872}
4873// Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
4874TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
4875{
4876 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4877
4878 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4879 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4880 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4881}
4882
4883// Test linear sampling for ES3 32F formats
4884TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
4885{
4886 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4887
4888 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4889 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
4890}
4891// Test linear sampling for ES2 32F formats
4892TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
4893{
4894 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4895
4896 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4897
4898 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
4899}
4900
4901// Test linear sampling for ES3 16F formats
4902TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
4903{
4904 // Half float formats must be linearly filterable in GLES 3.0 core
4905 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4906 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4907}
4908// Test linear sampling for ES2 16F formats
4909TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
4910{
4911 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4912 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4913 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4914}
4915
4916// Test linear sampling for legacy GLES 2.0 32F formats in ES3
4917TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
4918{
4919 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4920 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4921
4922 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4923 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4924 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4925
4926 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4927 {
4928 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4929 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4930 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4931 }
4932}
4933// Test linear sampling for legacy GLES 2.0 32F formats in ES2
4934TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
4935{
4936 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4937 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4938
4939 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4940 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4941 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4942}
4943
4944// Test linear sampling for legacy GLES 2.0 16F formats in ES3
4945TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
4946{
4947 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4948 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4949
4950 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4951 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4952 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4953
4954 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4955 {
4956 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4957 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4958 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4959 }
4960}
4961// Test linear sampling for legacy GLES 2.0 16F formats in ES2
4962TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
4963{
4964 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4965 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4966
4967 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4968 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4969 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4970}
4971
4972// Test color-renderability for ES3 float and half float textures
4973TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
4974{
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07004975 // http://anglebug.com/4092
4976 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07004977 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
4978 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
4979
4980 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
4981 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
4982 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4983
4984 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
4985 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
4986 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4987
4988 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
4989}
4990
4991// Test color-renderability for ES2 half float textures
4992TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
4993{
4994 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
4995 // require a specific one
4996 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
Zhenyao Mo20bb47d2019-09-16 12:55:30 -07004997 // https://crbug.com/1003971
4998 ANGLE_SKIP_TEST_IF(IsOzone());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07004999 // http://anglebug.com/4092
5000 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07005001
5002 bool atLeastOneSupported = false;
5003
5004 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
5005 IsGLExtensionEnabled("GL_OES_texture_half_float"))
5006 {
5007 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
5008 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
5009 }
5010 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
5011 {
5012 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
5013
5014 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
5015 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
5016 EXPECT_TRUE(rgbaSupported);
5017 atLeastOneSupported |= rgbaSupported;
5018 }
5019
5020 EXPECT_TRUE(atLeastOneSupported);
5021}
5022
Olli Etuaho95faa232016-06-07 14:01:53 -07005023// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
5024// GLES 3.0.4 section 3.8.3.
5025TEST_P(Texture2DTestES3, UnpackSkipImages2D)
5026{
Yuly Novikovd18c0482019-04-04 19:56:43 -04005027 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
5028 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Olli Etuaho95faa232016-06-07 14:01:53 -07005029
5030 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5031 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5032 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5033 ASSERT_GL_NO_ERROR();
5034
5035 // SKIP_IMAGES should not have an effect on uploading 2D textures
5036 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
5037 ASSERT_GL_NO_ERROR();
5038
5039 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5040
5041 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5042 pixelsGreen.data());
5043 ASSERT_GL_NO_ERROR();
5044
5045 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
5046 pixelsGreen.data());
5047 ASSERT_GL_NO_ERROR();
5048
5049 glUseProgram(mProgram);
5050 drawQuad(mProgram, "position", 0.5f);
5051 ASSERT_GL_NO_ERROR();
5052
5053 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5054}
5055
Olli Etuaho989cac32016-06-08 16:18:49 -07005056// Test that skip defined in unpack parameters is taken into account when determining whether
5057// unpacking source extends outside unpack buffer bounds.
5058TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
5059{
5060 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5063 ASSERT_GL_NO_ERROR();
5064
5065 GLBuffer buf;
5066 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5067 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5068 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5069 GL_DYNAMIC_COPY);
5070 ASSERT_GL_NO_ERROR();
5071
5072 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5073 ASSERT_GL_NO_ERROR();
5074
5075 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
5076 ASSERT_GL_NO_ERROR();
5077
5078 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5079 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5080
5081 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
5082 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
5083 ASSERT_GL_NO_ERROR();
5084
5085 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5086 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5087}
5088
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005089// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
5090TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
5091{
Yunchao He9550c602018-02-13 14:47:05 +08005092 ANGLE_SKIP_TEST_IF(IsD3D11());
5093
5094 // Incorrect rendering results seen on OSX AMD.
5095 ANGLE_SKIP_TEST_IF(IsOSX() && IsAMD());
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005096
5097 const GLuint width = 8u;
5098 const GLuint height = 8u;
5099 const GLuint unpackRowLength = 5u;
5100 const GLuint unpackSkipPixels = 1u;
5101
5102 setWindowWidth(width);
5103 setWindowHeight(height);
5104
5105 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5108 ASSERT_GL_NO_ERROR();
5109
5110 GLBuffer buf;
5111 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5112 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
5113 GLColor::green);
5114
5115 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
5116 {
5117 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
5118 }
5119
5120 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5121 GL_DYNAMIC_COPY);
5122 ASSERT_GL_NO_ERROR();
5123
5124 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
5125 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
5126 ASSERT_GL_NO_ERROR();
5127
5128 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5129 ASSERT_GL_NO_ERROR();
5130
5131 glUseProgram(mProgram);
5132 drawQuad(mProgram, "position", 0.5f);
5133 ASSERT_GL_NO_ERROR();
5134
5135 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
5136 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
5137 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
5138 actual.data());
5139 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
5140 EXPECT_EQ(expected, actual);
5141}
5142
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005143template <typename T>
5144T UNorm(double value)
5145{
5146 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
5147}
5148
5149// Test rendering a depth texture with mipmaps.
5150TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
5151{
Zhenyao Moe520d7c2017-01-13 13:46:49 -08005152 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
5153 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
Jiawei Shaoaf0f31d2018-09-27 15:42:31 +08005154 // http://anglebug.com/1706
5155 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Corentin Walleze731d8a2016-09-07 10:56:25 -04005156
Jamie Madill24980272019-04-03 09:03:51 -04005157 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
5158 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
5159
Cody Northrop988f7172019-09-30 15:52:37 -06005160 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005161 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
5162
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005163 const int size = getWindowWidth();
5164
5165 auto dim = [size](int level) { return size >> level; };
Jamie Madill14718762016-09-06 15:56:54 -04005166 int levels = gl::log2(size);
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005167
5168 glActiveTexture(GL_TEXTURE0);
5169 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5170 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
5171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5175 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5176 ASSERT_GL_NO_ERROR();
5177
5178 glUseProgram(mProgram);
5179 glUniform1i(mTexture2DUniformLocation, 0);
5180
5181 std::vector<unsigned char> expected;
5182
5183 for (int level = 0; level < levels; ++level)
5184 {
5185 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
5186 expected.push_back(UNorm<unsigned char>(value));
5187
5188 int levelDim = dim(level);
5189
5190 ASSERT_GT(levelDim, 0);
5191
5192 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
5193 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
5194 GL_UNSIGNED_INT, initData.data());
5195 }
5196 ASSERT_GL_NO_ERROR();
5197
5198 for (int level = 0; level < levels; ++level)
5199 {
5200 glViewport(0, 0, dim(level), dim(level));
5201 drawQuad(mProgram, "position", 0.5f);
5202 GLColor actual = ReadColor(0, 0);
5203 EXPECT_NEAR(expected[level], actual.R, 10u);
5204 }
5205
5206 ASSERT_GL_NO_ERROR();
5207}
5208
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005209class Texture2DDepthTest : public Texture2DTest
5210{
5211 protected:
5212 Texture2DDepthTest() : Texture2DTest() {}
5213
5214 const char *getVertexShaderSource() override
5215 {
5216 return "attribute vec4 vPosition;\n"
5217 "void main() {\n"
5218 " gl_Position = vPosition;\n"
5219 "}\n";
5220 }
5221
5222 const char *getFragmentShaderSource() override
5223 {
5224 return "precision mediump float;\n"
5225 "uniform sampler2D ShadowMap;"
5226 "void main() {\n"
5227 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
5228 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
5229 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
5230 " } else {"
5231 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
5232 " }"
5233 "}\n";
5234 }
5235
5236 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
5237 {
5238 EXPECT_GL_NO_ERROR();
5239
5240 GLTexture tex;
5241 glBindTexture(GL_TEXTURE_2D, tex);
5242 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
5243
5244 return (glGetError() == GL_NO_ERROR);
5245 }
5246
5247 void testBehavior(bool useSizedComponent)
5248 {
5249 int w = getWindowWidth();
5250 int h = getWindowHeight();
5251 GLuint format = GL_DEPTH_COMPONENT;
5252 GLuint internalFormat = GL_DEPTH_COMPONENT;
5253
5254 if (useSizedComponent)
5255 {
5256 internalFormat = GL_DEPTH_COMPONENT24;
5257 }
5258
5259 GLFramebuffer fbo;
5260 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5261 ASSERT_GL_NO_ERROR();
5262
5263 GLTexture depthTexture;
5264 glBindTexture(GL_TEXTURE_2D, depthTexture);
5265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5268 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5269
5270 TexCoordDrawTest::setUpProgram();
5271 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
5272 ASSERT_NE(-1, shadowMapLocation);
5273
5274 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
5275 ASSERT_NE(-1, positionLocation);
5276
5277 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
5278 glBindTexture(GL_TEXTURE_2D, depthTexture);
5279 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
5280 ASSERT_GL_NO_ERROR();
5281
5282 // try adding a color buffer.
5283 GLuint colorTex = 0;
5284 glGenTextures(1, &colorTex);
5285 glBindTexture(GL_TEXTURE_2D, colorTex);
5286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5288 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5289 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5290 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5291 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
5292 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
5293 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5294 ASSERT_GL_NO_ERROR();
5295
5296 glViewport(0, 0, w, h);
5297 // Fill depthTexture with 0.75
5298 glClearDepthf(0.75);
5299 glClear(GL_DEPTH_BUFFER_BIT);
5300
5301 // Revert to normal framebuffer to test depth shader
5302 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5303 glViewport(0, 0, w, h);
5304 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5305 glClearDepthf(0.0f);
5306 ASSERT_GL_NO_ERROR();
5307
5308 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
5309 ASSERT_GL_NO_ERROR();
5310
5311 glActiveTexture(GL_TEXTURE0);
5312 glBindTexture(GL_TEXTURE_2D, depthTexture);
5313
5314 glUseProgram(mProgram);
5315 ASSERT_GL_NO_ERROR();
5316
5317 glUniform1i(shadowMapLocation, 0);
5318
5319 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
5320
5321 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
5322 ASSERT_GL_NO_ERROR();
5323 glEnableVertexAttribArray(positionLocation);
5324 ASSERT_GL_NO_ERROR();
5325 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5326 ASSERT_GL_NO_ERROR();
5327
5328 GLuint pixels[1];
5329 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
5330 ASSERT_GL_NO_ERROR();
5331
5332 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
5333 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
5334 // is in all the color components. Multiple implementations implement a workaround that
5335 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
5336 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
5337 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
5338 // depending on if it sees the texture sample in only the RED component.
5339 if (useSizedComponent)
5340 {
5341 ASSERT_NE(pixels[0], 0xff0000ff);
5342 }
5343 else
5344 {
5345 ASSERT_EQ(pixels[0], 0xff0000ff);
5346 }
5347
5348 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5349 glDeleteProgram(mProgram);
5350 }
5351};
5352
5353// Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
5354TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
5355{
5356 ANGLE_SKIP_TEST_IF(IsD3D11());
5357 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
Tobin Ehlis7af26762019-10-23 16:18:57 -06005358 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
5359 !IsGLExtensionEnabled("GL_OES_depth_texture"));
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005360 // http://anglebug.com/4092
5361 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01005362 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005363
5364 // When the depth texture is specified with unsized internalformat implementations follow
5365 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
5366 testBehavior(false);
5367}
5368
5369// Test depth texture compatibility with GLES3 using sized internalformat.
5370TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
5371{
5372 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
5373
5374 testBehavior(true);
5375}
5376
Jamie Madill7ffdda92016-09-08 13:26:51 -04005377// Tests unpacking into the unsized GL_ALPHA format.
5378TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
5379{
Jamie Madill7ffdda92016-09-08 13:26:51 -04005380 // Initialize the texure.
5381 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5382 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
5383 GL_UNSIGNED_BYTE, nullptr);
5384 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5385 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5386
5387 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
5388
5389 // Pull in the color data from the unpack buffer.
Jamie Madill2e600342016-09-19 13:56:40 -04005390 GLBuffer unpackBuffer;
Jamie Madill7ffdda92016-09-08 13:26:51 -04005391 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5392 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5393 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
5394 GL_STATIC_DRAW);
5395
5396 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
5397 GL_UNSIGNED_BYTE, nullptr);
5398
5399 // Clear to a weird color to make sure we're drawing something.
5400 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
5401 glClear(GL_COLOR_BUFFER_BIT);
5402
5403 // Draw with the alpha texture and verify.
5404 drawQuad(mProgram, "position", 0.5f);
Jamie Madill7ffdda92016-09-08 13:26:51 -04005405
5406 ASSERT_GL_NO_ERROR();
5407 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
5408}
5409
Jamie Madill2e600342016-09-19 13:56:40 -04005410// Ensure stale unpack data doesn't propagate in D3D11.
5411TEST_P(Texture2DTestES3, StaleUnpackData)
5412{
5413 // Init unpack buffer.
5414 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
5415 std::vector<GLColor> pixels(pixelCount, GLColor::red);
5416
5417 GLBuffer unpackBuffer;
5418 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5419 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5420 GLsizei bufferSize = pixelCount * sizeof(GLColor);
5421 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
5422
5423 // Create from unpack buffer.
5424 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5425 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
5426 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5427 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5428 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5429
5430 drawQuad(mProgram, "position", 0.5f);
5431
5432 ASSERT_GL_NO_ERROR();
5433 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5434
5435 // Fill unpack with green, recreating buffer.
5436 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
5437 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
5438 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
5439
5440 // Reinit texture with green.
5441 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
5442 GL_UNSIGNED_BYTE, nullptr);
5443
5444 drawQuad(mProgram, "position", 0.5f);
5445
5446 ASSERT_GL_NO_ERROR();
5447 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5448}
5449
Geoff Langfb7685f2017-11-13 11:44:11 -05005450// Ensure that texture parameters passed as floats that are converted to ints are rounded before
5451// validating they are less than 0.
5452TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
5453{
5454 GLTexture texture;
5455 glBindTexture(GL_TEXTURE_2D, texture);
5456
5457 // Use a negative number that will round to zero when converted to an integer
5458 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
5459 // "Validation of values performed by state-setting commands is performed after conversion,
5460 // unless specified otherwise for a specific command."
5461 GLfloat param = -7.30157126e-07f;
5462 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
5463 EXPECT_GL_NO_ERROR();
5464
5465 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
5466 EXPECT_GL_NO_ERROR();
5467}
5468
Jamie Madillf097e232016-11-05 00:44:15 -04005469// This test covers a D3D format redefinition bug for 3D textures. The base level format was not
5470// being properly checked, and the texture storage of the previous texture format was persisting.
5471// This would result in an ASSERT in debug and incorrect rendering in release.
5472// See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
5473TEST_P(Texture3DTestES3, FormatRedefinitionBug)
5474{
5475 GLTexture tex;
5476 glBindTexture(GL_TEXTURE_3D, tex.get());
5477 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5478
5479 GLFramebuffer framebuffer;
5480 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
5481 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
5482
5483 glCheckFramebufferStatus(GL_FRAMEBUFFER);
5484
5485 std::vector<uint8_t> pixelData(100, 0);
5486
5487 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
5488 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
5489 pixelData.data());
5490
5491 ASSERT_GL_NO_ERROR();
5492}
5493
Corentin Wallezd2627992017-04-28 17:17:03 -04005494// Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
5495TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
5496{
5497 // 2D tests
5498 {
5499 GLTexture tex;
5500 glBindTexture(GL_TEXTURE_2D, tex.get());
5501
5502 GLBuffer pbo;
5503 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5504
5505 // Test OOB
5506 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
5507 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5508 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5509
5510 // Test OOB
5511 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
5512 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5513 ASSERT_GL_NO_ERROR();
5514 }
5515
5516 // 3D tests
5517 {
5518 GLTexture tex;
5519 glBindTexture(GL_TEXTURE_3D, tex.get());
5520
5521 GLBuffer pbo;
5522 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5523
5524 // Test OOB
5525 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
5526 GL_STATIC_DRAW);
5527 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5528 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5529
5530 // Test OOB
5531 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
5532 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5533 ASSERT_GL_NO_ERROR();
5534 }
5535}
5536
Jamie Madill3ed60422017-09-07 11:32:52 -04005537// Tests behaviour with a single texture and multiple sampler objects.
5538TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
5539{
5540 GLint maxTextureUnits = 0;
5541 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
5542 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
5543
5544 constexpr int kSize = 16;
5545
5546 // Make a single-level texture, fill it with red.
5547 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
5548 GLTexture tex;
5549 glBindTexture(GL_TEXTURE_2D, tex);
5550 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5551 redColors.data());
5552 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5553 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5554
5555 // Simple sanity check.
5556 draw2DTexturedQuad(0.5f, 1.0f, true);
5557 ASSERT_GL_NO_ERROR();
5558 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5559
5560 // Bind texture to unit 1 with a sampler object making it incomplete.
5561 GLSampler sampler;
5562 glBindSampler(0, sampler);
5563 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5564 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5565
5566 // Make a mipmap texture, fill it with blue.
5567 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
5568 GLTexture mipmapTex;
5569 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5570 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5571 blueColors.data());
5572 glGenerateMipmap(GL_TEXTURE_2D);
5573
5574 // Draw with the sampler, expect blue.
5575 draw2DTexturedQuad(0.5f, 1.0f, true);
5576 ASSERT_GL_NO_ERROR();
5577 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5578
5579 // Simple multitexturing program.
Jamie Madill35cd7332018-12-02 12:03:33 -05005580 constexpr char kVS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005581 "#version 300 es\n"
5582 "in vec2 position;\n"
5583 "out vec2 texCoord;\n"
5584 "void main()\n"
5585 "{\n"
5586 " gl_Position = vec4(position, 0, 1);\n"
5587 " texCoord = position * 0.5 + vec2(0.5);\n"
5588 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05005589
5590 constexpr char kFS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005591 "#version 300 es\n"
5592 "precision mediump float;\n"
5593 "in vec2 texCoord;\n"
5594 "uniform sampler2D tex1;\n"
5595 "uniform sampler2D tex2;\n"
5596 "uniform sampler2D tex3;\n"
5597 "uniform sampler2D tex4;\n"
5598 "out vec4 color;\n"
5599 "void main()\n"
5600 "{\n"
5601 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
5602 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
5603 "}";
5604
Jamie Madill35cd7332018-12-02 12:03:33 -05005605 ANGLE_GL_PROGRAM(program, kVS, kFS);
Jamie Madill3ed60422017-09-07 11:32:52 -04005606
5607 std::array<GLint, 4> texLocations = {
5608 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
5609 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
5610 for (GLint location : texLocations)
5611 {
5612 ASSERT_NE(-1, location);
5613 }
5614
5615 // Init the uniform data.
5616 glUseProgram(program);
5617 for (GLint location = 0; location < 4; ++location)
5618 {
5619 glUniform1i(texLocations[location], location);
5620 }
5621
5622 // Initialize four samplers
5623 GLSampler samplers[4];
5624
5625 // 0: non-mipped.
5626 glBindSampler(0, samplers[0]);
5627 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5628 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5629
5630 // 1: mipped.
5631 glBindSampler(1, samplers[1]);
5632 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5633 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5634
5635 // 2: non-mipped.
5636 glBindSampler(2, samplers[2]);
5637 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5638 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5639
5640 // 3: mipped.
5641 glBindSampler(3, samplers[3]);
5642 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5643 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5644
5645 // Bind two blue mipped textures and two single layer textures, should all draw.
5646 glActiveTexture(GL_TEXTURE0);
5647 glBindTexture(GL_TEXTURE_2D, tex);
5648
5649 glActiveTexture(GL_TEXTURE1);
5650 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5651
5652 glActiveTexture(GL_TEXTURE2);
5653 glBindTexture(GL_TEXTURE_2D, tex);
5654
5655 glActiveTexture(GL_TEXTURE3);
5656 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5657
5658 ASSERT_GL_NO_ERROR();
5659
5660 drawQuad(program, "position", 0.5f);
5661 ASSERT_GL_NO_ERROR();
5662 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
5663
5664 // Bind four single layer textures, two should be incomplete.
5665 glActiveTexture(GL_TEXTURE1);
5666 glBindTexture(GL_TEXTURE_2D, tex);
5667
5668 glActiveTexture(GL_TEXTURE3);
5669 glBindTexture(GL_TEXTURE_2D, tex);
5670
5671 drawQuad(program, "position", 0.5f);
5672 ASSERT_GL_NO_ERROR();
5673 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
5674}
5675
Martin Radev7e2c0d32017-09-15 14:25:42 +03005676// The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
5677// always at level 0 instead of the base level resulting in an incomplete texture if the faces at
5678// level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
5679// level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
5680// samples the cubemap using a direction vector (1,1,1).
5681TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
5682{
Yunchao He2f23f352018-02-11 22:11:37 +08005683 // Check http://anglebug.com/2155.
5684 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
5685
Jamie Madill35cd7332018-12-02 12:03:33 -05005686 constexpr char kVS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005687 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005688 precision mediump float;
5689 in vec3 pos;
5690 void main() {
5691 gl_Position = vec4(pos, 1.0);
5692 })";
Martin Radev7e2c0d32017-09-15 14:25:42 +03005693
Jamie Madill35cd7332018-12-02 12:03:33 -05005694 constexpr char kFS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005695 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005696 precision mediump float;
5697 out vec4 color;
5698 uniform samplerCube uTex;
5699 void main(){
5700 color = texture(uTex, vec3(1.0));
5701 })";
Jamie Madill35cd7332018-12-02 12:03:33 -05005702
5703 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev7e2c0d32017-09-15 14:25:42 +03005704 glUseProgram(program);
5705
5706 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
5707 glActiveTexture(GL_TEXTURE0);
5708
5709 GLTexture cubeTex;
5710 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
5711
5712 const int kFaceWidth = 1;
5713 const int kFaceHeight = 1;
5714 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
5715 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5716 GL_UNSIGNED_BYTE, texData.data());
5717 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5718 GL_UNSIGNED_BYTE, texData.data());
5719 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5720 GL_UNSIGNED_BYTE, texData.data());
5721 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5722 GL_UNSIGNED_BYTE, texData.data());
5723 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5724 GL_UNSIGNED_BYTE, texData.data());
5725 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5726 GL_UNSIGNED_BYTE, texData.data());
5727 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5728 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5729 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
5730 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
5731 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
5732 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
5733
5734 drawQuad(program, "pos", 0.5f, 1.0f, true);
5735 ASSERT_GL_NO_ERROR();
5736
5737 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5738}
5739
Jiawei Shao3c43b4d2018-02-23 11:08:28 +08005740// Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
5741TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
5742{
5743 GLuint texture = create2DTexture();
5744
5745 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
5746 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5747
5748 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
5749 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5750
5751 glDeleteTextures(1, &texture);
5752 EXPECT_GL_NO_ERROR();
5753}
5754
Olli Etuaho023371b2018-04-24 17:43:32 +03005755// Test setting base level after calling generateMipmap on a LUMA texture.
5756// Covers http://anglebug.com/2498
5757TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
5758{
5759 glActiveTexture(GL_TEXTURE0);
5760 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5761
5762 constexpr const GLsizei kWidth = 8;
5763 constexpr const GLsizei kHeight = 8;
5764 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
5765 whiteData.fill(255u);
5766
5767 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
5768 GL_UNSIGNED_BYTE, whiteData.data());
5769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
5770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5771 glGenerateMipmap(GL_TEXTURE_2D);
5772 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5773 EXPECT_GL_NO_ERROR();
5774
5775 drawQuad(mProgram, "position", 0.5f);
5776 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5777}
5778
Till Rathmannc1551dc2018-08-15 17:04:49 +02005779// Covers a bug in the D3D11 backend: http://anglebug.com/2772
5780// When using a sampler the texture was created as if it has mipmaps,
5781// regardless what you specified in GL_TEXTURE_MIN_FILTER via
5782// glSamplerParameteri() -- mistakenly the default value
5783// GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
5784// evaluated.
5785// If you didn't provide mipmaps and didn't let the driver generate them
5786// this led to not sampling your texture data when minification occurred.
5787TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
5788{
Cody Northrop988f7172019-09-30 15:52:37 -06005789 // TODO: Triage this failure on Vulkan: http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005790 ANGLE_SKIP_TEST_IF(IsVulkan());
5791
Jamie Madill35cd7332018-12-02 12:03:33 -05005792 constexpr char kVS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005793 "#version 300 es\n"
5794 "out vec2 texcoord;\n"
5795 "in vec4 position;\n"
5796 "void main()\n"
5797 "{\n"
5798 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
5799 " texcoord = (position.xy * 0.5) + 0.5;\n"
5800 "}\n";
5801
Jamie Madill35cd7332018-12-02 12:03:33 -05005802 constexpr char kFS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005803 "#version 300 es\n"
5804 "precision highp float;\n"
5805 "uniform highp sampler2D tex;\n"
5806 "in vec2 texcoord;\n"
5807 "out vec4 fragColor;\n"
5808 "void main()\n"
5809 "{\n"
5810 " fragColor = texture(tex, texcoord);\n"
5811 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -05005812
5813 ANGLE_GL_PROGRAM(program, kVS, kFS);
Till Rathmannc1551dc2018-08-15 17:04:49 +02005814
5815 GLSampler sampler;
5816 glBindSampler(0, sampler);
5817 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5818 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5819
5820 glActiveTexture(GL_TEXTURE0);
5821 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5822
5823 const GLsizei texWidth = getWindowWidth();
5824 const GLsizei texHeight = getWindowHeight();
5825 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
5826
5827 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5828 whiteData.data());
5829 EXPECT_GL_NO_ERROR();
5830
5831 drawQuad(program, "position", 0.5f);
5832 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
5833}
5834
Anders Leinof6cbe442019-04-18 15:32:07 +03005835// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5836// texture is output.
5837TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
5838{
Yuly Novikovd2683452019-05-23 16:11:19 -04005839 // http://anglebug.com/3478
5840 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5841
Anders Leinof6cbe442019-04-18 15:32:07 +03005842 glActiveTexture(GL_TEXTURE0);
5843 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5844 int width = getWindowWidth();
5845 int height = getWindowHeight();
5846 GLColor color = GLColor::green;
5847 std::vector<GLColor> pixels(width * height, color);
5848 GLint baseLevel = 1;
5849 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5850 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5851 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5852 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5853 GL_UNSIGNED_BYTE, pixels.data());
5854
5855 setUpProgram();
5856 glUseProgram(mProgram);
5857 glUniform1i(mTexture2DUniformLocation, 0);
5858 drawQuad(mProgram, "position", 0.5f);
5859
5860 EXPECT_GL_NO_ERROR();
5861 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5862 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5863}
5864
Anders Leino60cc7512019-05-06 09:25:27 +03005865// Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
5866// the texture is output.
5867TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
5868{
5869 // All output checks returned black, rather than the texture color.
5870 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
5871
5872 glActiveTexture(GL_TEXTURE0);
5873
5874 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5875 GLint baseLevel = 1;
5876 int width = getWindowWidth();
5877 int height = getWindowHeight();
5878 GLColor color = GLColor::green;
5879 std::vector<GLColor> pixels(width * height, color);
5880 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5881 {
5882 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
5883 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5884 EXPECT_GL_NO_ERROR();
5885 }
5886 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
5887 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5888 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5889
5890 glUseProgram(mProgram);
5891 glUniform1i(mTextureCubeUniformLocation, 0);
5892 drawQuad(mProgram, "position", 0.5f);
5893
5894 EXPECT_GL_NO_ERROR();
5895 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5896 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
5897 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
5898 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5899}
5900
Anders Leinoe4452442019-05-09 13:29:49 +03005901// This test sets up a cube map with four distincly colored MIP levels.
5902// The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
5903// the corners of the screen.
5904TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
5905{
5906 glActiveTexture(GL_TEXTURE0);
5907
5908 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5909 int width = getWindowWidth();
5910 int height = getWindowHeight();
5911 ASSERT_EQ(width, height);
5912 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
5913 for (GLint level = 0; level < 4; level++)
5914 {
5915 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5916 {
5917 int levelWidth = (2 * width) >> level;
5918 int levelHeight = (2 * height) >> level;
5919 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
5920 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
5921 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5922 EXPECT_GL_NO_ERROR();
5923 }
5924 }
5925 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5926 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5927 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
5928
5929 glUseProgram(mProgram);
5930 glUniform1i(mTextureCubeUniformLocation, 0);
5931 drawQuad(mProgram, "position", 0.5f);
5932
5933 ASSERT_GL_NO_ERROR();
5934 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
5935 EXPECT_EQ(ReadColor(0, 0).R, 0);
5936 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
5937 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
5938 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
5939}
5940
Anders Leino1b6aded2019-05-20 12:56:34 +03005941// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5942// texture is output.
5943TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
5944{
Jamie Madill29ac2742019-05-28 15:53:00 -04005945 // Fails on AMD: http://crbug.com/967796
Jamie Madill06055b52019-05-29 14:31:42 -04005946 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
Jamie Madill29ac2742019-05-28 15:53:00 -04005947
Anders Leino1b6aded2019-05-20 12:56:34 +03005948 glActiveTexture(GL_TEXTURE0);
5949 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5950 int width = getWindowWidth();
5951 int height = getWindowHeight();
5952 GLColor color = GLColor::green;
5953 std::vector<GLColor> pixels(width * height, color);
5954 GLint baseLevel = 1;
5955 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5956 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5957 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5958 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5959 GL_UNSIGNED_BYTE, pixels.data());
5960
5961 setUpProgram();
5962 glUseProgram(mProgram);
5963 glUniform1i(mTexture2DUniformLocation, 0);
5964 drawQuad(mProgram, "position", 0.5f);
5965
5966 EXPECT_GL_NO_ERROR();
5967 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5968 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5969}
5970
Anders Leino69d04932019-05-20 14:04:13 +03005971// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5972// texture is output.
5973TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
5974{
5975 glActiveTexture(GL_TEXTURE0);
5976 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
5977 int width = getWindowWidth();
5978 int height = getWindowHeight();
5979 int depth = 2;
5980 GLColor color = GLColor::green;
5981 std::vector<GLColor> pixels(width * height * depth, color);
5982 GLint baseLevel = 1;
5983 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
5984 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5985 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
5986 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5987 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5988
5989 drawQuad(mProgram, "position", 0.5f);
5990
5991 EXPECT_GL_NO_ERROR();
5992 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5993 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5994}
5995
Anders Leino262e2822019-05-20 14:24:40 +03005996// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
5997// texture is output.
5998TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
5999{
6000 glActiveTexture(GL_TEXTURE0);
6001 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6002 int width = getWindowWidth();
6003 int height = getWindowHeight();
6004 int depth = 2;
6005 GLColor color = GLColor::green;
6006 std::vector<GLColor> pixels(width * height * depth, color);
6007 GLint baseLevel = 1;
6008 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
6009 GL_UNSIGNED_BYTE, pixels.data());
6010 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6011 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6012 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6013
6014 drawQuad(mProgram, "position", 0.5f);
6015
6016 EXPECT_GL_NO_ERROR();
6017 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6018 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6019}
6020
Jamie Madillfc3ec572019-11-27 21:43:22 +00006021// Test that uses glCompressedTexSubImage2D combined with a PBO
6022TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
6023{
6024 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6025 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6026 // http://anglebug.com/4115
6027 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
6028 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
6029
6030 if (getClientMajorVersion() < 3)
6031 {
6032 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
6033 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
6034 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
6035 }
6036
6037 const GLuint width = 4u;
6038 const GLuint height = 4u;
6039
6040 setWindowWidth(width);
6041 setWindowHeight(height);
6042
6043 // Setup primary Texture
6044 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6045 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6046 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6047
6048 if (getClientMajorVersion() < 3)
6049 {
6050 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6051 }
6052 else
6053 {
6054 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6055 }
6056 ASSERT_GL_NO_ERROR();
6057
6058 // Setup PBO and fill it with a red
6059 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
6060 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
6061 ASSERT_GL_NO_ERROR();
6062
6063 // Write PBO to mTexture
6064 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
6065 width * height / 2u, nullptr);
6066 ASSERT_GL_NO_ERROR();
6067
6068 setUpProgram();
6069 // Draw using PBO updated texture
6070 glUseProgram(mProgram);
6071 glUniform1i(mTexture2DUniformLocation, 0);
6072 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6073 drawQuad(mProgram, "position", 0.5f);
6074 ASSERT_GL_NO_ERROR();
6075
6076 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6077 ASSERT_GL_NO_ERROR();
6078}
6079
Jamie Madill50cf2be2018-06-15 09:46:57 -04006080// Use this to select which configurations (e.g. which renderer, which GLES major version) these
6081// tests should be run against.
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006082ANGLE_INSTANTIATE_TEST_ES2(Texture2DTest);
6083ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
6084ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
6085ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
6086ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
6087ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
6088ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3);
6089ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
6090ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
6091ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
6092ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
6093ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
6094ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
6095ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
6096ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
6097ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
6098ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
6099ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
6100ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
6101ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
6102ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
6103ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
6104ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
6105ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
6106ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
6107ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DRGTest);
6108ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
6109ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
6110ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
6111ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
6112ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
6113ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
6114ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
6115ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
6116ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
6117ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
Jamie Madillfc3ec572019-11-27 21:43:22 +00006118ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
Jamie Madillfa05f602015-05-07 13:47:11 -04006119
Jamie Madill7ffdda92016-09-08 13:26:51 -04006120} // anonymous namespace