blob: d1944749ca8febb9568866113bd7550178cb9e2e [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
Cody Northrop74e816b2020-03-26 17:40:25 -06001451class ETC1CompressedTextureTest : public Texture2DTest
1452{
1453 protected:
1454 ETC1CompressedTextureTest() : Texture2DTest() {}
1455
1456 void testSetUp() override
1457 {
1458 TexCoordDrawTest::testSetUp();
1459 glGenTextures(1, &mTexture2D);
1460 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1461 EXPECT_GL_NO_ERROR();
1462
1463 setUpProgram();
1464 }
1465
1466 void testTearDown() override { Texture2DTest::testTearDown(); }
1467};
1468
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001469TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001470{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001471 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001472 EXPECT_GL_ERROR(GL_NO_ERROR);
1473
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001474 setUpProgram();
1475
Jamie Madill50cf2be2018-06-15 09:46:57 -04001476 const GLubyte *pixels[20] = {0};
Jamie Madillf67115c2014-04-22 13:14:05 -04001477 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1478 EXPECT_GL_ERROR(GL_INVALID_VALUE);
Geoff Langc51642b2016-11-14 16:18:26 -05001479
Jamie Madillb8149072019-04-30 16:14:44 -04001480 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
Geoff Langc51642b2016-11-14 16:18:26 -05001481 {
1482 // Create a 1-level immutable texture.
1483 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1484
1485 // Try calling sub image on the second level.
1486 glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1487 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1488 }
Jamie Madillf67115c2014-04-22 13:14:05 -04001489}
Geoff Langc41e42d2014-04-28 10:58:16 -04001490
John Bauman18319182016-09-28 14:22:27 -07001491// Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
1492TEST_P(Texture2DTest, QueryBinding)
1493{
1494 glBindTexture(GL_TEXTURE_2D, 0);
1495 EXPECT_GL_ERROR(GL_NO_ERROR);
1496
1497 GLint textureBinding;
1498 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1499 EXPECT_GL_NO_ERROR();
1500 EXPECT_EQ(0, textureBinding);
1501
1502 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
Jamie Madillb8149072019-04-30 16:14:44 -04001503 if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1504 IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
John Bauman18319182016-09-28 14:22:27 -07001505 {
1506 EXPECT_GL_NO_ERROR();
1507 EXPECT_EQ(0, textureBinding);
1508 }
1509 else
1510 {
1511 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1512 }
1513}
1514
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001515TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001516{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001517 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001518 EXPECT_GL_ERROR(GL_NO_ERROR);
1519
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001520 setUpProgram();
1521
Geoff Langc41e42d2014-04-28 10:58:16 -04001522 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001523 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001524 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001525 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001526
Jamie Madill50cf2be2018-06-15 09:46:57 -04001527 const GLubyte *pixel[4] = {0};
Geoff Langc41e42d2014-04-28 10:58:16 -04001528
1529 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1530 EXPECT_GL_NO_ERROR();
1531
1532 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1533 EXPECT_GL_NO_ERROR();
1534
1535 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1536 EXPECT_GL_NO_ERROR();
1537}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001538
1539// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001540TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001541{
1542 glActiveTexture(GL_TEXTURE0);
1543 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1544 glActiveTexture(GL_TEXTURE1);
1545 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1546 EXPECT_GL_ERROR(GL_NO_ERROR);
1547
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001548 glUseProgram(mProgram);
1549 glUniform1i(mTexture2DUniformLocation, 0);
1550 glUniform1i(mTextureCubeUniformLocation, 1);
1551 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001552 EXPECT_GL_NO_ERROR();
1553}
Jamie Madill9aca0592014-10-06 16:26:59 -04001554
Olli Etuaho53a2da12016-01-11 15:43:32 +02001555// Test drawing with two texture types accessed from the same shader and check that the result of
1556// drawing is correct.
1557TEST_P(TextureCubeTest, CubeMapDraw)
1558{
1559 GLubyte texData[4];
1560 texData[0] = 0;
1561 texData[1] = 60;
1562 texData[2] = 0;
1563 texData[3] = 255;
1564
1565 glActiveTexture(GL_TEXTURE0);
1566 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1567 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1568
1569 glActiveTexture(GL_TEXTURE1);
1570 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1571 texData[1] = 120;
1572 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1573 texData);
1574 EXPECT_GL_ERROR(GL_NO_ERROR);
1575
1576 glUseProgram(mProgram);
1577 glUniform1i(mTexture2DUniformLocation, 0);
1578 glUniform1i(mTextureCubeUniformLocation, 1);
1579 drawQuad(mProgram, "position", 0.5f);
1580 EXPECT_GL_NO_ERROR();
1581
1582 int px = getWindowWidth() - 1;
1583 int py = 0;
1584 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1585}
1586
Olli Etuaho4644a202016-01-12 15:12:53 +02001587TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1588{
1589 glActiveTexture(GL_TEXTURE0);
1590 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1591 GLubyte texData[4];
1592 texData[0] = 0;
1593 texData[1] = 128;
1594 texData[2] = 0;
1595 texData[3] = 255;
1596 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1597 glUseProgram(mProgram);
1598 glUniform1i(mTexture2DUniformLocation, 0);
1599 drawQuad(mProgram, "position", 0.5f);
1600 EXPECT_GL_NO_ERROR();
1601
1602 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1603}
1604
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001605// Test drawing with two textures passed to the shader in a sampler array.
1606TEST_P(SamplerArrayTest, SamplerArrayDraw)
1607{
1608 testSamplerArrayDraw();
1609}
1610
1611// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1612// user-defined function in the shader.
1613TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1614{
Shahbaz Youssefi0864a7a2018-11-07 15:50:15 -05001615 // TODO: Diagnose and fix. http://anglebug.com/2955
1616 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1617
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001618 testSamplerArrayDraw();
1619}
1620
Jamie Madill9aca0592014-10-06 16:26:59 -04001621// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001622TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001623{
1624 int px = getWindowWidth() / 2;
1625 int py = getWindowHeight() / 2;
1626
1627 glActiveTexture(GL_TEXTURE0);
1628 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1629
Olli Etuahoa314b612016-03-10 16:43:00 +02001630 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001631
Olli Etuahoa314b612016-03-10 16:43:00 +02001632 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001633 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1634 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1635 glGenerateMipmap(GL_TEXTURE_2D);
1636
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001637 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001638 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001639 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1640 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001641 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001642 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001643
Olli Etuahoa314b612016-03-10 16:43:00 +02001644 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001645
Olli Etuahoa314b612016-03-10 16:43:00 +02001646 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1647 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001648 glGenerateMipmap(GL_TEXTURE_2D);
1649
Olli Etuahoa314b612016-03-10 16:43:00 +02001650 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001651
Olli Etuahoa314b612016-03-10 16:43:00 +02001652 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1653 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001654 glGenerateMipmap(GL_TEXTURE_2D);
1655
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001656 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001657
1658 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001659 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001660}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001661
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001662// Test creating a FBO with a cube map render target, to test an ANGLE bug
1663// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001664TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001665{
Michael Spangd8506c72019-01-29 15:35:09 -05001666 // http://anglebug.com/3145
1667 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1668
Shahbaz Youssefi0c128e12019-03-25 23:50:14 -04001669 // http://anglebug.com/2822
1670 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1671
Jamie Madill3f3b3582018-09-14 10:38:44 -04001672 GLFramebuffer fbo;
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001673 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1674
1675 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Jamie Madill50cf2be2018-06-15 09:46:57 -04001676 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1677 mTextureCube, 0);
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001678
Corentin Wallez322653b2015-06-17 18:33:56 +02001679 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001680 EXPECT_GL_NO_ERROR();
Jamie Madill3f3b3582018-09-14 10:38:44 -04001681
1682 // Test clearing the six mip faces individually.
1683 std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
1684 GLColor::yellow, GLColor::cyan, GLColor::magenta}};
1685
1686 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1687 {
1688 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1689 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1690
1691 Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
1692 glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
1693 glClear(GL_COLOR_BUFFER_BIT);
1694
1695 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
1696 }
1697
1698 // Iterate the faces again to make sure the colors haven't changed.
1699 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1700 {
1701 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1702 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1703 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
1704 << "face color " << faceIndex << " shouldn't change";
1705 }
1706}
1707
1708// Tests clearing a cube map with a scissor enabled.
1709TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
1710{
1711 // TODO(jie.a.chen): Diagnose and fix. http://anglebug.com/2822
1712 ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
1713
Michael Spangd8506c72019-01-29 15:35:09 -05001714 // http://anglebug.com/3145
1715 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1716
Jamie Madill3f3b3582018-09-14 10:38:44 -04001717 constexpr size_t kSize = 16;
1718
1719 GLFramebuffer fbo;
1720 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1721 glViewport(0, 0, kSize, kSize);
1722
1723 GLTexture texcube;
1724 glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
1725 for (GLenum face = 0; face < 6; face++)
1726 {
1727 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
1728 GL_UNSIGNED_BYTE, nullptr);
1729 }
1730 ASSERT_GL_NO_ERROR();
1731
1732 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1733 texcube, 0);
1734
1735 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1736 ASSERT_GL_NO_ERROR();
1737
1738 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1739 glClear(GL_COLOR_BUFFER_BIT);
1740 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1741
1742 glEnable(GL_SCISSOR_TEST);
1743 glScissor(kSize / 2, 0, kSize / 2, kSize);
1744 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1745 glClear(GL_COLOR_BUFFER_BIT);
1746
1747 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1748 EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
1749
1750 ASSERT_GL_NO_ERROR();
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001751}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001752
Jamie Madill50cf2be2018-06-15 09:46:57 -04001753// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
1754// default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001755TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001756{
Jamie Madillb8149072019-04-30 16:14:44 -04001757 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1758 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -04001759
Jamie Madill50cf2be2018-06-15 09:46:57 -04001760 int width = getWindowWidth();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001761 int height = getWindowHeight();
1762
1763 GLuint tex2D;
1764 glGenTextures(1, &tex2D);
1765 glActiveTexture(GL_TEXTURE0);
1766 glBindTexture(GL_TEXTURE_2D, tex2D);
1767
1768 // Fill with red
1769 std::vector<GLubyte> pixels(3 * 16 * 16);
1770 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1771 {
1772 pixels[pixelId * 3 + 0] = 255;
1773 pixels[pixelId * 3 + 1] = 0;
1774 pixels[pixelId * 3 + 2] = 0;
1775 }
1776
1777 // ANGLE internally uses RGBA as the DirectX format for RGB images
Jamie Madill50cf2be2018-06-15 09:46:57 -04001778 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1779 // 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 -04001780 if (getClientMajorVersion() >= 3)
1781 {
1782 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1783 }
1784 else
1785 {
1786 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1787 }
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001788
1789 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1790 // glTexSubImage2D should take into account that the image is dirty.
1791 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1794
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001795 setUpProgram();
1796
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001797 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001798 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001799 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001800 glDeleteTextures(1, &tex2D);
1801 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001802 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001803
1804 // Validate that the region of the texture without data has an alpha of 1.0
Jamie Madill05b35b22017-10-03 09:01:44 -04001805 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
1806 EXPECT_EQ(255, pixel.A);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001807}
1808
Jamie Madill50cf2be2018-06-15 09:46:57 -04001809// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
1810// initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001811TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001812{
Jamie Madillfc3ec572019-11-27 21:43:22 +00001813 // http://anglebug.com/4126
1814 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
1815
1816 if (getClientMajorVersion() < 3)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001817 {
Jamie Madillfc3ec572019-11-27 21:43:22 +00001818 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1819 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001820 }
Jamie Madillfc3ec572019-11-27 21:43:22 +00001821
1822 const int width = getWindowWidth();
1823 const int height = getWindowHeight();
1824 const size_t pixelCount = width * height;
1825 const int componentCount = 3;
1826
1827 GLuint tex2D;
1828 glGenTextures(1, &tex2D);
1829 glActiveTexture(GL_TEXTURE0);
1830 glBindTexture(GL_TEXTURE_2D, tex2D);
1831
1832 // Fill with red
1833 std::vector<GLubyte> pixels(componentCount * pixelCount);
1834 for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
1835 {
1836 pixels[pixelId * componentCount + 0] = 255;
1837 pixels[pixelId * componentCount + 1] = 0;
1838 pixels[pixelId * componentCount + 2] = 0;
1839 }
1840
1841 // Read 16x16 region from red backbuffer to PBO
1842 GLuint pbo;
1843 glGenBuffers(1, &pbo);
1844 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1845 glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
1846 GL_STATIC_DRAW);
1847
1848 // ANGLE internally uses RGBA as the DirectX format for RGB images
1849 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1850 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
1851 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
1852
1853 // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
1854 // untouched. glTexSubImage2D should take into account that the image is dirty.
1855 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
1856 nullptr);
1857 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1858 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1859
1860 setUpProgram();
1861
1862 glUseProgram(mProgram);
1863 glUniform1i(mTexture2DUniformLocation, 0);
1864 drawQuad(mProgram, "position", 0.5f);
1865 glDeleteTextures(1, &tex2D);
1866 glDeleteBuffers(1, &pbo);
1867 EXPECT_GL_NO_ERROR();
1868 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1869 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1870}
1871
1872// Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
1873// and drawing with the texture
1874// Pseudo code for the follow test:
1875// 1. Upload PBO to mTexture2D
1876// 2. Delete PBO
1877// 3. Draw with otherTexture (x5)
1878// 4. Draw with mTexture2D
1879// 5. Validate color output
1880TEST_P(Texture2DTest, PBOWithMultipleDraws)
1881{
1882 if (getClientMajorVersion() < 3)
1883 {
1884 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1885 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
1886 }
1887
1888 const GLuint width = getWindowWidth();
1889 const GLuint height = getWindowHeight();
1890 const GLuint windowPixelCount = width * height;
1891 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
1892 std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
1893
1894 // Create secondary draw that does not use mTexture
1895 const char *vertexShaderSource = getVertexShaderSource();
1896 const char *fragmentShaderSource = getFragmentShaderSource();
1897 ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
1898
1899 GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
1900 ASSERT_NE(-1, uniformLoc);
1901 glUseProgram(0);
1902
1903 // Create secondary Texture to draw with
1904 GLTexture otherTexture;
1905 glActiveTexture(GL_TEXTURE0);
1906 glBindTexture(GL_TEXTURE_2D, otherTexture);
1907 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1908 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1909 pixelsRed.data());
1910 ASSERT_GL_NO_ERROR();
1911
1912 // Setup primary Texture
1913 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1914 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1915 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1916 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1917 ASSERT_GL_NO_ERROR();
1918
1919 // Setup PBO
1920 GLuint pbo = 0;
1921 glGenBuffers(1, &pbo);
1922 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1923 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
1924 GL_STATIC_DRAW);
1925 ASSERT_GL_NO_ERROR();
1926
1927 // Write PBO to mTexture
1928 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1929 ASSERT_GL_NO_ERROR();
1930 // Delete PBO as ANGLE should be properly handling refcount of this buffer
1931 glDeleteBuffers(1, &pbo);
1932 pixelsGreen.clear();
1933
1934 // Do 5 draws not involving primary texture that the PBO updated
1935 glUseProgram(otherProgram);
1936 glUniform1i(uniformLoc, 0);
1937 glBindTexture(GL_TEXTURE_2D, otherTexture);
1938 drawQuad(otherProgram, "position", 0.5f);
1939 glBindTexture(GL_TEXTURE_2D, 0);
1940 glUseProgram(0);
1941
1942 glUseProgram(otherProgram);
1943 glUniform1i(uniformLoc, 0);
1944 glBindTexture(GL_TEXTURE_2D, otherTexture);
1945 drawQuad(otherProgram, "position", 0.5f);
1946 glBindTexture(GL_TEXTURE_2D, 0);
1947 glUseProgram(0);
1948
1949 glUseProgram(otherProgram);
1950 glUniform1i(uniformLoc, 0);
1951 glBindTexture(GL_TEXTURE_2D, otherTexture);
1952 drawQuad(otherProgram, "position", 0.5f);
1953 glBindTexture(GL_TEXTURE_2D, 0);
1954 glUseProgram(0);
1955
1956 glUseProgram(otherProgram);
1957 glUniform1i(uniformLoc, 0);
1958 glBindTexture(GL_TEXTURE_2D, otherTexture);
1959 drawQuad(otherProgram, "position", 0.5f);
1960 glBindTexture(GL_TEXTURE_2D, 0);
1961 glUseProgram(0);
1962 ASSERT_GL_NO_ERROR();
1963
1964 std::vector<GLColor> output(windowPixelCount, GLColor::black);
1965 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1966 output.data());
1967 EXPECT_EQ(pixelsRed, output);
1968
1969 setUpProgram();
1970 // Draw using PBO updated texture
1971 glUseProgram(mProgram);
1972 glUniform1i(mTexture2DUniformLocation, 0);
1973 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1974 drawQuad(mProgram, "position", 0.5f);
1975 ASSERT_GL_NO_ERROR();
1976
1977 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
1978 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1979 actual.data());
1980 // Value should be green as it was updated during PBO transfer to mTexture
1981 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
1982 EXPECT_EQ(expected, actual);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001983}
Jamie Madillbc393df2015-01-29 13:46:07 -05001984
Mohan Maiya6caa2652019-09-11 08:06:13 -07001985// Tests CopySubImage for float formats
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001986TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001987{
1988 testFloatCopySubImage(1, 1);
1989}
1990
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001991TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001992{
1993 testFloatCopySubImage(2, 1);
1994}
1995
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001996TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001997{
1998 testFloatCopySubImage(2, 2);
1999}
2000
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002001TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002002{
2003 testFloatCopySubImage(3, 1);
2004}
2005
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002006TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002007{
2008 testFloatCopySubImage(3, 2);
2009}
2010
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002011TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002012{
Yunchao He9550c602018-02-13 14:47:05 +08002013 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
Mohan Maiya6caa2652019-09-11 08:06:13 -07002014 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002015
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(3, 3);
2020}
2021
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002022TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002023{
2024 testFloatCopySubImage(4, 1);
2025}
2026
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002027TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002028{
2029 testFloatCopySubImage(4, 2);
2030}
2031
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002032TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002033{
Yunchao He9550c602018-02-13 14:47:05 +08002034 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2035 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002036
Jamie Madillbc393df2015-01-29 13:46:07 -05002037 testFloatCopySubImage(4, 3);
2038}
2039
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002040TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05002041{
Yunchao He9550c602018-02-13 14:47:05 +08002042 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2043 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002044
Jamie Madillbc393df2015-01-29 13:46:07 -05002045 testFloatCopySubImage(4, 4);
2046}
Austin Kinross07285142015-03-26 11:36:16 -07002047
Jamie Madill50cf2be2018-06-15 09:46:57 -04002048// Port of
2049// https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
2050// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
2051// handles GL_ALPHA
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002052TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07002053{
2054 const int npotTexSize = 5;
Jamie Madill50cf2be2018-06-15 09:46:57 -04002055 const int potTexSize = 4; // Should be less than npotTexSize
Austin Kinross07285142015-03-26 11:36:16 -07002056 GLuint tex2D;
2057
Jamie Madillb8149072019-04-30 16:14:44 -04002058 if (IsGLExtensionEnabled("GL_OES_texture_npot"))
Austin Kinross07285142015-03-26 11:36:16 -07002059 {
2060 // This test isn't applicable if texture_npot is enabled
2061 return;
2062 }
2063
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002064 setUpProgram();
2065
Austin Kinross07285142015-03-26 11:36:16 -07002066 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2067
Austin Kinross5faa15b2016-01-11 13:32:48 -08002068 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
2069 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2070
Austin Kinross07285142015-03-26 11:36:16 -07002071 glActiveTexture(GL_TEXTURE0);
2072 glGenTextures(1, &tex2D);
2073 glBindTexture(GL_TEXTURE_2D, tex2D);
2074
Till Rathmannc1551dc2018-08-15 17:04:49 +02002075 const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
Austin Kinross07285142015-03-26 11:36:16 -07002076
2077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2079
2080 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
Jamie Madill50cf2be2018-06-15 09:46:57 -04002081 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2082 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002083 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2084
2085 // Check that an NPOT texture on level 0 succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002086 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2087 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002088 EXPECT_GL_NO_ERROR();
2089
2090 // Check that generateMipmap fails on NPOT
2091 glGenerateMipmap(GL_TEXTURE_2D);
2092 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2093
2094 // Check that nothing is drawn if filtering is not correct for NPOT
2095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2096 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2097 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2098 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2099 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002100 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002101 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2102
2103 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
2104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
2107 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002108 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002109 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2110
2111 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
2112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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
2117 // Check that glTexImage2D for POT texture succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002118 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
2119 pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002120 EXPECT_GL_NO_ERROR();
2121
2122 // Check that generateMipmap for an POT texture succeeds
2123 glGenerateMipmap(GL_TEXTURE_2D);
2124 EXPECT_GL_NO_ERROR();
2125
2126 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
2127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2131 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002132 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002133 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2134 EXPECT_GL_NO_ERROR();
2135}
Jamie Madillfa05f602015-05-07 13:47:11 -04002136
Austin Kinross08528e12015-10-07 16:24:40 -07002137// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
2138// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002139TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07002140{
2141 glActiveTexture(GL_TEXTURE0);
2142 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2143
2144 // Create an 8x8 (i.e. power-of-two) texture.
2145 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2148 glGenerateMipmap(GL_TEXTURE_2D);
2149
2150 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
2151 // This should always work, even if GL_OES_texture_npot isn't active.
Geoff Langfb052642017-10-24 13:42:09 -04002152 std::array<GLColor, 3 * 3> data;
2153 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
Austin Kinross08528e12015-10-07 16:24:40 -07002154
2155 EXPECT_GL_NO_ERROR();
2156}
2157
Geoff Lang3702d8c2019-04-08 13:44:06 -04002158// Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
2159// TextureImpl and the texture is synced before being used in a draw call.
2160TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
2161{
2162 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
Yuly Novikove6b23e42019-04-10 17:19:15 -04002163 // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
2164 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
Yuly Novikovbd4ff472019-07-19 22:08:17 +00002165 // D3D Debug device reports an error. http://anglebug.com/3501
2166 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
Cody Northrop988f7172019-09-30 15:52:37 -06002167 // TODO(cnorthrop): Needs triage on Vulkan backend. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06002168 ANGLE_SKIP_TEST_IF(IsVulkan());
Geoff Lang3702d8c2019-04-08 13:44:06 -04002169
2170 // The workaround in the GL backend required to trigger this bug generates driver warning
2171 // messages.
2172 ScopedIgnorePlatformMessages ignoreMessages;
2173
2174 setUpProgram();
2175 glUseProgram(mProgram);
2176 glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
2177
2178 GLTexture dest;
2179 glBindTexture(GL_TEXTURE_2D, dest);
2180
2181 GLTexture source;
2182 glBindTexture(GL_TEXTURE_2D, source);
2183
2184 // Put data in mip 0 and 1
2185 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2186 GLColor::red.data());
2187 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2188 GLColor::green.data());
2189
2190 // Disable mipmapping so source is complete
2191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2193
2194 // Force the dirty bits to be synchronized in source
2195 drawQuad(mProgram, "position", 1.0f);
2196
2197 // Copy from mip 1 of the source. In the GL backend this internally sets the base level to mip
2198 // 1 and sets a dirty bit.
2199 glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
2200 GL_FALSE, GL_FALSE);
2201
2202 // Draw again, assertions are generated if the texture has internal dirty bits at draw time
2203 drawQuad(mProgram, "position", 1.0f);
2204}
2205
Geoff Lang6f691fb2019-04-25 11:01:52 -04002206// This test case changes the base level of a texture that's attached to a framebuffer, clears every
2207// level to green, and then samples the texture when rendering. Test is taken from
2208// https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
2209TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
2210{
Cody Northropd192e932019-09-27 10:27:10 -06002211 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
2212 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
Cody Northropcb16fb52019-08-29 16:53:55 -06002213
Geoff Lang6f691fb2019-04-25 11:01:52 -04002214 setUpProgram();
2215
2216 constexpr GLint width = 8;
2217 constexpr GLint height = 4;
2218
2219 GLTexture texture;
2220 glBindTexture(GL_TEXTURE_2D, texture);
2221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2225
2226 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
2227 GLint level = 0;
2228 GLint levelW = width;
2229 GLint levelH = height;
2230 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2231 nullptr);
2232 while (levelW > 1 || levelH > 1)
2233 {
2234 ++level;
2235 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
2236 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
2237 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2238 nullptr);
2239 }
2240
2241 // Clear each level of the texture using an FBO. Change the base level to match the level used
2242 // for the FBO on each iteration.
2243 GLFramebuffer fbo;
2244 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2245 level = 0;
2246 levelW = width;
2247 levelH = height;
2248 while (levelW > 1 || levelH > 1)
2249 {
2250 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
2251 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
2252
2253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
2254 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
2255
2256 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2257 EXPECT_GL_NO_ERROR();
2258
2259 glClearColor(0, 1, 0, 1);
2260 glClear(GL_COLOR_BUFFER_BIT);
2261
2262 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2263
2264 ++level;
2265 }
2266
2267 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2268 glViewport(0, 0, 16, 16);
2269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2270
2271 drawQuad(mProgram, "position", 0.5f);
2272
2273 EXPECT_GL_NO_ERROR();
2274 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2275}
2276
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002277// Test to check that texture completeness is determined correctly when the texture base level is
2278// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
2279TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
2280{
2281 glActiveTexture(GL_TEXTURE0);
2282 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02002283
2284 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
2285 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2286 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2287 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2288 texDataGreen.data());
2289 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2290 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002291 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2292 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2293 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2294
2295 EXPECT_GL_NO_ERROR();
2296
2297 drawQuad(mProgram, "position", 0.5f);
2298
Olli Etuahoa314b612016-03-10 16:43:00 +02002299 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2300}
2301
2302// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2303// have images defined.
2304TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
2305{
Yunchao He9550c602018-02-13 14:47:05 +08002306 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2307 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2308
Olli Etuahoa314b612016-03-10 16:43:00 +02002309 glActiveTexture(GL_TEXTURE0);
2310 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2311 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2312 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2313 texDataGreen.data());
2314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2317 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2318
2319 EXPECT_GL_NO_ERROR();
2320
2321 drawQuad(mProgram, "position", 0.5f);
2322
2323 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2324}
2325
Olli Etuahoe8528d82016-05-16 17:50:52 +03002326// Test that drawing works correctly when level 0 is undefined and base level is 1.
2327TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
2328{
Yunchao He9550c602018-02-13 14:47:05 +08002329 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2330 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2331
Olli Etuahoe8528d82016-05-16 17:50:52 +03002332 glActiveTexture(GL_TEXTURE0);
2333 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2334 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2335 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2336 texDataGreen.data());
2337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2338 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2339 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2341
2342 EXPECT_GL_NO_ERROR();
2343
2344 // Texture is incomplete.
2345 drawQuad(mProgram, "position", 0.5f);
2346 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2347
2348 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2349 texDataGreen.data());
2350
2351 // Texture is now complete.
2352 drawQuad(mProgram, "position", 0.5f);
2353 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2354}
2355
Olli Etuahoa314b612016-03-10 16:43:00 +02002356// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2357// dimensions that don't fit the images inside the range.
2358// GLES 3.0.4 section 3.8.13 Texture completeness
2359TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2360{
Olli Etuahoa314b612016-03-10 16:43:00 +02002361 glActiveTexture(GL_TEXTURE0);
2362 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2363 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
2364 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2365 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
2366
2367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2368 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2369
2370 // Two levels that are initially unused.
2371 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2372 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2373 texDataCyan.data());
2374
2375 // One level that is used - only this level should affect completeness.
2376 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2377 texDataGreen.data());
2378
2379 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2380 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2381
2382 EXPECT_GL_NO_ERROR();
2383
2384 drawQuad(mProgram, "position", 0.5f);
2385
2386 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2387
Yunchao He2f23f352018-02-11 22:11:37 +08002388 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002389
2390 // Switch the level that is being used to the cyan level 2.
2391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2393
2394 EXPECT_GL_NO_ERROR();
2395
2396 drawQuad(mProgram, "position", 0.5f);
2397
2398 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2399}
2400
2401// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2402// have images defined.
2403TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
2404{
Olli Etuahoa314b612016-03-10 16:43:00 +02002405 glActiveTexture(GL_TEXTURE0);
2406 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2407 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2408 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2409 texDataGreen.data());
2410 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2411 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2412 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2413 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2414
2415 EXPECT_GL_NO_ERROR();
2416
2417 drawQuad(mProgram, "position", 0.5f);
2418
2419 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2420}
2421
2422// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2423// dimensions that don't fit the images inside the range.
2424// GLES 3.0.4 section 3.8.13 Texture completeness
2425TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2426{
Yuly Novikovc5da7992019-06-27 12:57:13 -04002427 // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
2428 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
2429
Olli Etuahoa314b612016-03-10 16:43:00 +02002430 glActiveTexture(GL_TEXTURE0);
2431 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2432 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2433 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2434 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2435
2436 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2437 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2438
2439 // Two levels that are initially unused.
2440 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2441 texDataRed.data());
2442 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2443 texDataCyan.data());
2444
2445 // One level that is used - only this level should affect completeness.
2446 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2447 texDataGreen.data());
2448
2449 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2450 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2451
2452 EXPECT_GL_NO_ERROR();
2453
2454 drawQuad(mProgram, "position", 0.5f);
2455
2456 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2457
Yunchao He2f23f352018-02-11 22:11:37 +08002458 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002459
2460 // Switch the level that is being used to the cyan level 2.
2461 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
2462 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
2463
2464 EXPECT_GL_NO_ERROR();
2465
2466 drawQuad(mProgram, "position", 0.5f);
2467
2468 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2469}
2470
2471// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2472// have images defined.
2473TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
2474{
Olli Etuahoa314b612016-03-10 16:43:00 +02002475 glActiveTexture(GL_TEXTURE0);
2476 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2477 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2478 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2479 texDataGreen.data());
2480 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2481 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2482 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2483 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2484
2485 EXPECT_GL_NO_ERROR();
2486
2487 drawQuad(mProgram, "position", 0.5f);
2488
2489 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2490}
2491
2492// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2493// dimensions that don't fit the images inside the range.
2494// GLES 3.0.4 section 3.8.13 Texture completeness
2495TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2496{
Corentin Wallez566c2e32019-08-28 18:37:58 +02002497 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2498 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2499
Olli Etuahoa314b612016-03-10 16:43:00 +02002500 glActiveTexture(GL_TEXTURE0);
2501 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
2502 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2503 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2504 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2505
2506 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2507 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2508
2509 // Two levels that are initially unused.
2510 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2511 texDataRed.data());
2512 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2513 texDataCyan.data());
2514
2515 // One level that is used - only this level should affect completeness.
2516 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2517 texDataGreen.data());
2518
2519 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2520 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2521
2522 EXPECT_GL_NO_ERROR();
2523
2524 drawQuad(mProgram, "position", 0.5f);
2525
2526 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2527
Yunchao He2f23f352018-02-11 22:11:37 +08002528 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2529
Olli Etuahoa314b612016-03-10 16:43:00 +02002530 // Switch the level that is being used to the cyan level 2.
2531 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
2532 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
2533
2534 EXPECT_GL_NO_ERROR();
2535
2536 drawQuad(mProgram, "position", 0.5f);
2537
2538 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2539}
2540
2541// Test that texture completeness is updated if texture max level changes.
2542// GLES 3.0.4 section 3.8.13 Texture completeness
2543TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2544{
Olli Etuahoa314b612016-03-10 16:43:00 +02002545 glActiveTexture(GL_TEXTURE0);
2546 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2547 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2548
2549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2550 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2551
2552 // A level that is initially unused.
2553 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2554 texDataGreen.data());
2555
2556 // One level that is initially used - only this level should affect completeness.
2557 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2558 texDataGreen.data());
2559
2560 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2562
2563 EXPECT_GL_NO_ERROR();
2564
2565 drawQuad(mProgram, "position", 0.5f);
2566
2567 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2568
2569 // Switch the max level to level 1. The levels within the used range now have inconsistent
2570 // dimensions and the texture should be incomplete.
2571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2572
2573 EXPECT_GL_NO_ERROR();
2574
2575 drawQuad(mProgram, "position", 0.5f);
2576
2577 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2578}
2579
2580// Test that 3D texture completeness is updated if texture max level changes.
2581// GLES 3.0.4 section 3.8.13 Texture completeness
2582TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2583{
Olli Etuahoa314b612016-03-10 16:43:00 +02002584 glActiveTexture(GL_TEXTURE0);
2585 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2586 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2587
2588 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2589 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2590
2591 // A level that is initially unused.
2592 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2593 texDataGreen.data());
2594
2595 // One level that is initially used - only this level should affect completeness.
2596 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2597 texDataGreen.data());
2598
2599 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2600 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2601
2602 EXPECT_GL_NO_ERROR();
2603
2604 drawQuad(mProgram, "position", 0.5f);
2605
2606 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2607
2608 // Switch the max level to level 1. The levels within the used range now have inconsistent
2609 // dimensions and the texture should be incomplete.
2610 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2611
2612 EXPECT_GL_NO_ERROR();
2613
2614 drawQuad(mProgram, "position", 0.5f);
2615
2616 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2617}
2618
2619// Test that texture completeness is updated if texture base level changes.
2620// GLES 3.0.4 section 3.8.13 Texture completeness
2621TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2622{
Olli Etuahoa314b612016-03-10 16:43:00 +02002623 glActiveTexture(GL_TEXTURE0);
2624 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2625 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2626
2627 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2628 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2629
2630 // Two levels that are initially unused.
2631 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2632 texDataGreen.data());
2633 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2634 texDataGreen.data());
2635
2636 // One level that is initially used - only this level should affect completeness.
2637 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2638 texDataGreen.data());
2639
2640 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2641 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2642
2643 EXPECT_GL_NO_ERROR();
2644
2645 drawQuad(mProgram, "position", 0.5f);
2646
2647 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2648
2649 // Switch the base level to level 1. The levels within the used range now have inconsistent
2650 // dimensions and the texture should be incomplete.
2651 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2652
2653 EXPECT_GL_NO_ERROR();
2654
2655 drawQuad(mProgram, "position", 0.5f);
2656
2657 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2658}
2659
2660// Test that texture is not complete if base level is greater than max level.
2661// GLES 3.0.4 section 3.8.13 Texture completeness
2662TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2663{
Olli Etuahoa314b612016-03-10 16:43:00 +02002664 glActiveTexture(GL_TEXTURE0);
2665 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2666
2667 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2668 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2669
2670 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2671
2672 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2674
2675 EXPECT_GL_NO_ERROR();
2676
2677 drawQuad(mProgram, "position", 0.5f);
2678
2679 // Texture should be incomplete.
2680 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2681}
2682
2683// Test that immutable texture base level and max level are clamped.
2684// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2685TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2686{
Olli Etuahoa314b612016-03-10 16:43:00 +02002687 glActiveTexture(GL_TEXTURE0);
2688 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2689
2690 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2691 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2692
2693 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2694
2695 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2696
2697 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2698 // should be clamped to [base_level, levels - 1].
2699 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2700 // In the case of this test, those rules make the effective base level and max level 0.
2701 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2702 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2703
2704 EXPECT_GL_NO_ERROR();
2705
2706 drawQuad(mProgram, "position", 0.5f);
2707
2708 // Texture should be complete.
2709 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2710}
2711
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002712// Test that changing base level works when it affects the format of the texture.
2713TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2714{
Corentin Wallez7f00d332019-08-28 15:19:16 +02002715 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2716 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2717
Yunchao He8e5ba8b2018-02-05 17:52:27 +08002718 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
Yunchao He9550c602018-02-13 14:47:05 +08002719
2720 // Observed incorrect rendering on AMD OpenGL.
2721 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002722
2723 glActiveTexture(GL_TEXTURE0);
2724 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2725 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2726 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2727
2728 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2729 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2730
2731 // RGBA8 level that's initially unused.
2732 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2733 texDataCyan.data());
2734
2735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2737
2738 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2739 // format. It reads green channel data from the green and alpha channels of texDataGreen
2740 // (this is a bit hacky but works).
2741 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2742
2743 EXPECT_GL_NO_ERROR();
2744
2745 drawQuad(mProgram, "position", 0.5f);
2746
2747 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2748
2749 // Switch the texture to use the cyan level 0 with the RGBA format.
2750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2752
2753 EXPECT_GL_NO_ERROR();
2754
2755 drawQuad(mProgram, "position", 0.5f);
2756
2757 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2758}
2759
Olli Etuahoa314b612016-03-10 16:43:00 +02002760// Test that setting a texture image works when base level is out of range.
2761TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2762{
2763 glActiveTexture(GL_TEXTURE0);
2764 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2765
2766 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2767 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2768
2769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2771
2772 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2773
2774 EXPECT_GL_NO_ERROR();
2775
2776 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2777
2778 drawQuad(mProgram, "position", 0.5f);
2779
2780 // Texture should be complete.
2781 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002782}
2783
Jamie Madill50cf2be2018-06-15 09:46:57 -04002784// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
2785// RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
2786// with these formats does not work as expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002787TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002788{
2789 std::vector<GLubyte> pixelData;
2790 for (size_t count = 0; count < 5000; count++)
2791 {
2792 pixelData.push_back(0u);
2793 pixelData.push_back(255u);
2794 pixelData.push_back(0u);
2795 }
2796
2797 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002798 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002799 glUniform1i(mTextureArrayLocation, 0);
2800
2801 // The first draw worked correctly.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002802 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2803 &pixelData[0]);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002804
2805 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2806 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2807 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2808 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002809 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002810 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002811
2812 // The dimension of the respecification must match the original exactly to trigger the bug.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002813 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2814 &pixelData[0]);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002815 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002816 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002817
2818 ASSERT_GL_NO_ERROR();
2819}
2820
Olli Etuaho1a679902016-01-14 12:21:47 +02002821// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2822// This test is needed especially to confirm that sampler registers get assigned correctly on
2823// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2824TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2825{
2826 glActiveTexture(GL_TEXTURE0);
2827 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2828 GLubyte texData[4];
2829 texData[0] = 0;
2830 texData[1] = 60;
2831 texData[2] = 0;
2832 texData[3] = 255;
2833 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2834
2835 glActiveTexture(GL_TEXTURE1);
2836 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2837 GLfloat depthTexData[1];
2838 depthTexData[0] = 0.5f;
2839 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2840 depthTexData);
2841
2842 glUseProgram(mProgram);
2843 glUniform1f(mDepthRefUniformLocation, 0.3f);
2844 glUniform1i(mTexture3DUniformLocation, 0);
2845 glUniform1i(mTextureShadowUniformLocation, 1);
2846
2847 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2848 drawQuad(mProgram, "position", 0.5f);
2849 EXPECT_GL_NO_ERROR();
2850 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2851 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2852
2853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2854 drawQuad(mProgram, "position", 0.5f);
2855 EXPECT_GL_NO_ERROR();
2856 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2857 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2858}
2859
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002860// Test multiple different sampler types in the same shader.
2861// This test makes sure that even if sampler / texture registers get grouped together based on type
2862// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2863// still has the right register index information for each ESSL sampler.
2864// The tested ESSL samplers have the following types in D3D11 HLSL:
2865// sampler2D: Texture2D + SamplerState
2866// samplerCube: TextureCube + SamplerState
2867// sampler2DShadow: Texture2D + SamplerComparisonState
2868// samplerCubeShadow: TextureCube + SamplerComparisonState
2869TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2870{
2871 glActiveTexture(GL_TEXTURE0);
2872 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2873 GLubyte texData[4];
2874 texData[0] = 0;
2875 texData[1] = 0;
2876 texData[2] = 120;
2877 texData[3] = 255;
2878 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2879
2880 glActiveTexture(GL_TEXTURE1);
2881 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2882 texData[0] = 0;
2883 texData[1] = 90;
2884 texData[2] = 0;
2885 texData[3] = 255;
2886 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2887 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2888 texData);
2889
2890 glActiveTexture(GL_TEXTURE2);
2891 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2893 GLfloat depthTexData[1];
2894 depthTexData[0] = 0.5f;
2895 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2896 depthTexData);
2897
2898 glActiveTexture(GL_TEXTURE3);
2899 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2900 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2901 depthTexData[0] = 0.2f;
2902 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2903 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2904 depthTexData);
2905
Tobin Ehlisbbf0ce22019-10-11 06:55:36 -06002906 // http://anglebug.com/3949: TODO: Add a DS texture case
2907
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002908 EXPECT_GL_NO_ERROR();
2909
2910 glUseProgram(mProgram);
2911 glUniform1f(mDepthRefUniformLocation, 0.3f);
2912 glUniform1i(mTexture2DUniformLocation, 0);
2913 glUniform1i(mTextureCubeUniformLocation, 1);
2914 glUniform1i(mTexture2DShadowUniformLocation, 2);
2915 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2916
2917 drawQuad(mProgram, "position", 0.5f);
2918 EXPECT_GL_NO_ERROR();
2919 // The shader writes:
2920 // <texture 2d color> +
2921 // <cube map color> +
2922 // 0.25 * <comparison result (1.0)> +
2923 // 0.125 * <comparison result (0.0)>
2924 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2925}
2926
Olli Etuahobce743a2016-01-15 17:18:28 +02002927// Test different base levels on textures accessed through the same sampler array.
2928// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2929TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2930{
Yunchao He9550c602018-02-13 14:47:05 +08002931 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
2932
Jamie Madill788fa362020-02-10 14:07:12 -05002933 // http://anglebug.com/4391
2934 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
2935
Olli Etuahobce743a2016-01-15 17:18:28 +02002936 glActiveTexture(GL_TEXTURE0);
2937 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2938 GLsizei size = 64;
2939 for (GLint level = 0; level < 7; ++level)
2940 {
2941 ASSERT_LT(0, size);
2942 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2943 nullptr);
2944 size = size / 2;
2945 }
2946 ASSERT_EQ(0, size);
2947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2948
2949 glActiveTexture(GL_TEXTURE1);
2950 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2951 size = 128;
2952 for (GLint level = 0; level < 8; ++level)
2953 {
2954 ASSERT_LT(0, size);
2955 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2956 nullptr);
2957 size = size / 2;
2958 }
2959 ASSERT_EQ(0, size);
2960 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2961 EXPECT_GL_NO_ERROR();
2962
2963 glUseProgram(mProgram);
2964 glUniform1i(mTexture0Location, 0);
2965 glUniform1i(mTexture1Location, 1);
2966
Olli Etuaho5804dc82018-04-13 14:11:46 +03002967 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
Olli Etuahobce743a2016-01-15 17:18:28 +02002968 EXPECT_GL_NO_ERROR();
2969 // Red channel: width of level 1 of texture A: 32.
2970 // Green channel: width of level 3 of texture B: 16.
2971 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2972}
2973
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002974// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2975// ES 3.0.4 table 3.24
2976TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2977{
2978 glActiveTexture(GL_TEXTURE0);
2979 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2980 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2981 EXPECT_GL_NO_ERROR();
2982
2983 drawQuad(mProgram, "position", 0.5f);
2984
2985 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2986}
2987
2988// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2989// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05002990TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002991{
Luc Ferron5164b792018-03-06 09:10:12 -05002992 setUpProgram();
2993
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002994 glActiveTexture(GL_TEXTURE0);
2995 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2996 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2997 EXPECT_GL_NO_ERROR();
2998
2999 drawQuad(mProgram, "position", 0.5f);
3000
3001 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3002}
3003
Luc Ferron5164b792018-03-06 09:10:12 -05003004// Validate that every component of the pixel will be equal to the luminance value we've set
3005// and that the alpha channel will be 1 (or 255 to be exact).
3006TEST_P(Texture2DTest, TextureLuminanceRGBSame)
3007{
3008 setUpProgram();
3009
3010 glActiveTexture(GL_TEXTURE0);
3011 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3012 uint8_t pixel = 50;
3013 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
3014 EXPECT_GL_NO_ERROR();
3015
3016 drawQuad(mProgram, "position", 0.5f);
3017
3018 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
3019}
3020
3021// Validate that every component of the pixel will be equal to the luminance value we've set
3022// and that the alpha channel will be the second component.
3023TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
3024{
3025 setUpProgram();
3026
3027 glActiveTexture(GL_TEXTURE0);
3028 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3029 uint8_t pixel[] = {50, 25};
3030 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
3031 GL_UNSIGNED_BYTE, pixel);
3032 EXPECT_GL_NO_ERROR();
3033
3034 drawQuad(mProgram, "position", 0.5f);
3035
3036 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
3037}
3038
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003039// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3040// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003041TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003042{
Jamie Madillb8149072019-04-30 16:14:44 -04003043 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003044 ANGLE_SKIP_TEST_IF(IsD3D9());
3045 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferron5164b792018-03-06 09:10:12 -05003046
3047 setUpProgram();
3048
Luc Ferrond8c632c2018-04-10 12:31:44 -04003049 glActiveTexture(GL_TEXTURE0);
3050 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3051 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
3052 EXPECT_GL_NO_ERROR();
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003053
Luc Ferrond8c632c2018-04-10 12:31:44 -04003054 drawQuad(mProgram, "position", 0.5f);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003055
Luc Ferrond8c632c2018-04-10 12:31:44 -04003056 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003057}
3058
3059// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3060// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003061TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003062{
Jamie Madillb8149072019-04-30 16:14:44 -04003063 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003064 ANGLE_SKIP_TEST_IF(IsD3D9());
3065 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferrond8c632c2018-04-10 12:31:44 -04003066 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
3067 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
Luc Ferron5164b792018-03-06 09:10:12 -05003068
Luc Ferrond8c632c2018-04-10 12:31:44 -04003069 setUpProgram();
Luc Ferron5164b792018-03-06 09:10:12 -05003070
Luc Ferrond8c632c2018-04-10 12:31:44 -04003071 glActiveTexture(GL_TEXTURE0);
3072 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3073 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
3074 EXPECT_GL_NO_ERROR();
Yunchao He9550c602018-02-13 14:47:05 +08003075
Luc Ferrond8c632c2018-04-10 12:31:44 -04003076 drawQuad(mProgram, "position", 0.5f);
Yuly Novikovafcec832016-06-21 22:19:51 -04003077
Luc Ferrond8c632c2018-04-10 12:31:44 -04003078 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003079}
3080
3081// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3082// ES 3.0.4 table 3.24
3083TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
3084{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003085 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3086
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003087 glActiveTexture(GL_TEXTURE0);
3088 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3089 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
3090 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3092 EXPECT_GL_NO_ERROR();
3093
3094 drawQuad(mProgram, "position", 0.5f);
3095
3096 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3097}
3098
3099// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3100// ES 3.0.4 table 3.24
3101TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
3102{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003103 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3104
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003105 glActiveTexture(GL_TEXTURE0);
3106 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3107
3108 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
3109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3111 EXPECT_GL_NO_ERROR();
3112
3113 drawQuad(mProgram, "position", 0.5f);
3114
3115 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3116}
3117
3118// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3119// ES 3.0.4 table 3.24
3120TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
3121{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003122 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3123
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003124 glActiveTexture(GL_TEXTURE0);
3125 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
3127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3129 EXPECT_GL_NO_ERROR();
3130
3131 drawQuad(mProgram, "position", 0.5f);
3132
3133 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3134}
3135
3136// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3137// ES 3.0.4 table 3.24
3138TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
3139{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003140 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3141
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003142 glActiveTexture(GL_TEXTURE0);
3143 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3144 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
3145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3147 EXPECT_GL_NO_ERROR();
3148
3149 drawQuad(mProgram, "position", 0.5f);
3150
3151 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3152}
3153
3154// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3155// ES 3.0.4 table 3.24
3156TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
3157{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003158 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3159
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003160 glActiveTexture(GL_TEXTURE0);
3161 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3162 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
3163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3165 EXPECT_GL_NO_ERROR();
3166
3167 drawQuad(mProgram, "position", 0.5f);
3168
3169 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3170}
3171
3172// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3173// ES 3.0.4 table 3.24
3174TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
3175{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003176 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3177
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003178 glActiveTexture(GL_TEXTURE0);
3179 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3180 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
3181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3183 EXPECT_GL_NO_ERROR();
3184
3185 drawQuad(mProgram, "position", 0.5f);
3186
3187 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3188}
3189
3190// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3191// ES 3.0.4 table 3.24
3192TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
3193{
3194 glActiveTexture(GL_TEXTURE0);
3195 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3196 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, 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, TextureRGB9E5ImplicitAlpha1)
3207{
3208 glActiveTexture(GL_TEXTURE0);
3209 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3210 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
3211 nullptr);
3212 EXPECT_GL_NO_ERROR();
3213
3214 drawQuad(mProgram, "position", 0.5f);
3215
3216 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3217}
3218
3219// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3220// ES 3.0.4 table 3.24
3221TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
3222{
Geoff Lang2a19c592019-08-23 14:10:24 -04003223 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3224 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003225
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003226 glActiveTexture(GL_TEXTURE0);
3227 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3228 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
3229 EXPECT_GL_NO_ERROR();
3230
3231 drawQuad(mProgram, "position", 0.5f);
3232
3233 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3234}
3235
3236// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3237// ES 3.0.4 table 3.24
3238TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
3239{
Geoff Lang2a19c592019-08-23 14:10:24 -04003240 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3241 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003242
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003243 glActiveTexture(GL_TEXTURE0);
3244 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3245 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
3246 EXPECT_GL_NO_ERROR();
3247
3248 drawQuad(mProgram, "position", 0.5f);
3249
3250 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3251}
3252
Olli Etuaho96963162016-03-21 11:54:33 +02003253// Use a sampler in a uniform struct.
3254TEST_P(SamplerInStructTest, SamplerInStruct)
3255{
3256 runSamplerInStructTest();
3257}
3258
3259// Use a sampler in a uniform struct that's passed as a function parameter.
3260TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
3261{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003262 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3263 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Geoff Lang8fcdf6e2016-09-16 10:45:30 -04003264
Olli Etuaho96963162016-03-21 11:54:33 +02003265 runSamplerInStructTest();
3266}
3267
3268// Use a sampler in a uniform struct array with a struct from the array passed as a function
3269// parameter.
3270TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
3271{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003272 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3273 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003274
Olli Etuaho96963162016-03-21 11:54:33 +02003275 runSamplerInStructTest();
3276}
3277
3278// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
3279// parameter.
3280TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
3281{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003282 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3283 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003284
Olli Etuaho96963162016-03-21 11:54:33 +02003285 runSamplerInStructTest();
3286}
3287
3288// Make sure that there isn't a name conflict between sampler extracted from a struct and a
3289// similarly named uniform.
3290TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
3291{
3292 runSamplerInStructTest();
3293}
3294
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003295// GL_EXT_texture_filter_anisotropic
3296class TextureAnisotropyTest : public Texture2DTest
3297{
3298 protected:
3299 void uploadTexture()
3300 {
3301 glActiveTexture(GL_TEXTURE0);
3302 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3303 GLColor texDataRed[1] = {GLColor::red};
3304 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
3305 EXPECT_GL_NO_ERROR();
3306 }
3307};
3308
3309// Tests that setting anisotropic filtering doesn't cause failures at draw time.
3310TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
3311{
Jamie Madillb8149072019-04-30 16:14:44 -04003312 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003313
3314 setUpProgram();
3315
3316 uploadTexture();
3317
3318 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3319 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3320 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
3321 EXPECT_GL_NO_ERROR();
3322
3323 drawQuad(mProgram, "position", 0.5f);
3324
3325 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3326 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3327 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
3328}
3329
Till Rathmannb8543632018-10-02 19:46:14 +02003330// GL_OES_texture_border_clamp
3331class TextureBorderClampTest : public Texture2DTest
3332{
3333 protected:
3334 TextureBorderClampTest() : Texture2DTest() {}
3335
Jamie Madill35cd7332018-12-02 12:03:33 -05003336 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003337 {
3338 return
3339 R"(precision highp float;
3340 attribute vec4 position;
3341 varying vec2 texcoord;
3342
3343 void main()
3344 {
3345 gl_Position = vec4(position.xy, 0.0, 1.0);
3346 // texcoords in [-0.5, 1.5]
3347 texcoord = (position.xy) + 0.5;
3348 })";
3349 }
3350
3351 void uploadTexture()
3352 {
3353 glActiveTexture(GL_TEXTURE0);
3354 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3355 std::vector<GLColor> texDataRed(1, GLColor::red);
3356 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3357 texDataRed.data());
3358 EXPECT_GL_NO_ERROR();
3359 }
3360};
3361
3362// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3363// GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
3364TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
3365{
Jamie Madillb8149072019-04-30 16:14:44 -04003366 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003367
3368 setUpProgram();
3369
3370 uploadTexture();
3371
3372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3376 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3377 EXPECT_GL_NO_ERROR();
3378
3379 drawQuad(mProgram, "position", 0.5f);
3380
3381 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3382 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3383 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3384}
3385
3386// Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
3387TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
3388{
Jamie Madillb8149072019-04-30 16:14:44 -04003389 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003390
3391 glActiveTexture(GL_TEXTURE0);
3392 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3393
3394 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3395
3396 GLint colorFixedPoint[4] = {0};
3397 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3398 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3399 std::numeric_limits<GLint>::max()};
3400 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3401 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3402 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3403 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3404
3405 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3406 std::numeric_limits<GLint>::max()};
3407 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3408
3409 GLfloat color[4] = {0.0f};
3410 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
3411 EXPECT_EQ(color[0], kFloatBlue.R);
3412 EXPECT_EQ(color[1], kFloatBlue.G);
3413 EXPECT_EQ(color[2], kFloatBlue.B);
3414 EXPECT_EQ(color[3], kFloatBlue.A);
3415}
3416
3417// Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
3418TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
3419{
Jamie Madillb8149072019-04-30 16:14:44 -04003420 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003421
3422 glActiveTexture(GL_TEXTURE0);
3423 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3424
3425 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
3426 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3427
3428 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3429 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3430
3431 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3432 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3433
3434 GLint colorInt[4] = {0};
3435 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
3436 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3437
3438 if (getClientMajorVersion() < 3)
3439 {
3440 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3441 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3442 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3443 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3444
3445 GLuint colorUInt[4] = {0};
3446 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3447 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3448 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3449 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3450
3451 GLSampler sampler;
3452 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3453 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3454 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3455 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3456
3457 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3458 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3459 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3460 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3461 }
3462}
3463
3464class TextureBorderClampTestES3 : public TextureBorderClampTest
3465{
3466 protected:
3467 TextureBorderClampTestES3() : TextureBorderClampTest() {}
3468};
3469
3470// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3471// GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
3472TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
3473{
Jamie Madillb8149072019-04-30 16:14:44 -04003474 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003475
3476 setUpProgram();
3477
3478 uploadTexture();
3479
3480 GLSampler sampler;
3481 glBindSampler(0, sampler);
3482 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3483 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3484 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3485 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3486 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3487 EXPECT_GL_NO_ERROR();
3488
3489 drawQuad(mProgram, "position", 0.5f);
3490
3491 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3492 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3493 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3494}
3495
3496// Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
3497TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
3498{
Jamie Madillb8149072019-04-30 16:14:44 -04003499 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003500
3501 glActiveTexture(GL_TEXTURE0);
3502
3503 GLSampler sampler;
3504 glBindSampler(0, sampler);
3505
3506 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3507
3508 GLint colorFixedPoint[4] = {0};
3509 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3510 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3511 std::numeric_limits<GLint>::max()};
3512 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3513 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3514 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3515 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3516
3517 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3518 std::numeric_limits<GLint>::max()};
3519 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3520
3521 GLfloat color[4] = {0.0f};
3522 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
3523 EXPECT_EQ(color[0], kFloatBlue.R);
3524 EXPECT_EQ(color[1], kFloatBlue.G);
3525 EXPECT_EQ(color[2], kFloatBlue.B);
3526 EXPECT_EQ(color[3], kFloatBlue.A);
3527
3528 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
3529 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
3530 GLint colorInt[4] = {0};
3531 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3532 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
3533 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
3534 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
3535 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
3536
3537 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
3538 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
3539 GLuint colorUInt[4] = {0};
3540 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3541 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
3542 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
3543 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
3544 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
3545
3546 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3547
3548 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
3549 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
3550 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3551 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
3552 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
3553 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
3554 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
3555
3556 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
3557 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
3558 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3559 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
3560 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
3561 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
3562 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
3563}
3564
3565// Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
3566TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
3567{
Jamie Madillb8149072019-04-30 16:14:44 -04003568 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003569
3570 glActiveTexture(GL_TEXTURE0);
3571
3572 GLSampler sampler;
3573 glBindSampler(0, sampler);
3574
3575 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
3576 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3577
3578 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3579 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3580}
3581
3582class TextureBorderClampIntegerTestES3 : public Texture2DTest
3583{
3584 protected:
3585 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
3586
Jamie Madill35cd7332018-12-02 12:03:33 -05003587 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003588 {
3589 return
3590 R"(#version 300 es
3591 out vec2 texcoord;
3592 in vec4 position;
3593
3594 void main()
3595 {
3596 gl_Position = vec4(position.xy, 0.0, 1.0);
3597 // texcoords in [-0.5, 1.5]
3598 texcoord = (position.xy) + 0.5;
3599 })";
3600 }
3601
Jamie Madillba319ba2018-12-29 10:29:33 -05003602 const char *getFragmentShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003603 {
Jamie Madill35cd7332018-12-02 12:03:33 -05003604 if (isUnsignedIntTest)
3605 {
3606 return "#version 300 es\n"
3607 "precision highp float;\n"
3608 "uniform highp usampler2D tex;\n"
3609 "in vec2 texcoord;\n"
3610 "out vec4 fragColor;\n"
Till Rathmannb8543632018-10-02 19:46:14 +02003611
Jamie Madill35cd7332018-12-02 12:03:33 -05003612 "void main()\n"
3613 "{\n"
3614 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3615 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3616 "fragColor = (texture(tex, texcoord).r == 150u)"
3617 " ? green : red;\n"
3618 "}\n";
3619 }
3620 else
3621 {
3622 return "#version 300 es\n"
3623 "precision highp float;\n"
3624 "uniform highp isampler2D tex;\n"
3625 "in vec2 texcoord;\n"
3626 "out vec4 fragColor;\n"
3627
3628 "void main()\n"
3629 "{\n"
3630 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3631 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3632 "fragColor = (texture(tex, texcoord).r == -50)"
3633 " ? green : red;\n"
3634 "}\n";
3635 }
Till Rathmannb8543632018-10-02 19:46:14 +02003636 }
3637
3638 void uploadTexture()
3639 {
3640 glActiveTexture(GL_TEXTURE0);
3641 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3642 if (isUnsignedIntTest)
3643 {
3644 std::vector<GLubyte> texData(4, 100);
3645 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
3646 texData.data());
3647 }
3648 else
3649 {
3650 std::vector<GLbyte> texData(4, 100);
3651 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
3652 texData.data());
3653 }
3654 EXPECT_GL_NO_ERROR();
3655 }
3656
3657 bool isUnsignedIntTest;
3658};
3659
3660// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3661// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3662TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
3663{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003664 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3665 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3666
Jamie Madillb8149072019-04-30 16:14:44 -04003667 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003668
3669 setUpProgram();
3670
3671 uploadTexture();
3672
3673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3674 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3677
3678 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3679 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3680
3681 EXPECT_GL_NO_ERROR();
3682
3683 drawQuad(mProgram, "position", 0.5f);
3684
3685 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3686 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3687 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3688}
3689
3690// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3691// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3692TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
3693{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003694 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3695 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3696
Jamie Madillb8149072019-04-30 16:14:44 -04003697 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003698
3699 setUpProgram();
3700
3701 uploadTexture();
3702
3703 GLSampler sampler;
3704 glBindSampler(0, sampler);
3705 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3706 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3707 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3708 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3709
3710 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3711 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3712
3713 EXPECT_GL_NO_ERROR();
3714
3715 drawQuad(mProgram, "position", 0.5f);
3716
3717 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3718 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3719 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3720}
3721
3722// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3723// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
3724TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
3725{
Jamie Madillb8149072019-04-30 16:14:44 -04003726 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003727
3728 isUnsignedIntTest = true;
3729
3730 setUpProgram();
3731
3732 uploadTexture();
3733
3734 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3738
3739 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3740 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3741
3742 EXPECT_GL_NO_ERROR();
3743
3744 drawQuad(mProgram, "position", 0.5f);
3745
3746 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3747 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3748 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3749}
3750
3751// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3752// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
3753// glSamplerParameterIuivOES).
3754TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
3755{
Jamie Madillb8149072019-04-30 16:14:44 -04003756 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003757
3758 isUnsignedIntTest = true;
3759
3760 setUpProgram();
3761
3762 uploadTexture();
3763
3764 GLSampler sampler;
3765 glBindSampler(0, sampler);
3766 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3767 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3768 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3769 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3770
3771 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3772 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3773
3774 EXPECT_GL_NO_ERROR();
3775
3776 drawQuad(mProgram, "position", 0.5f);
3777
3778 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3779 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3780 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3781}
3782
3783// ~GL_OES_texture_border_clamp
3784
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003785class TextureLimitsTest : public ANGLETest
3786{
3787 protected:
3788 struct RGBA8
3789 {
3790 uint8_t R, G, B, A;
3791 };
3792
3793 TextureLimitsTest()
3794 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
3795 {
3796 setWindowWidth(128);
3797 setWindowHeight(128);
3798 setConfigRedBits(8);
3799 setConfigGreenBits(8);
3800 setConfigBlueBits(8);
3801 setConfigAlphaBits(8);
3802 }
3803
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003804 void testSetUp() override
Jamie Madill0fdb9562018-09-17 17:18:43 -04003805 {
Jamie Madill0fdb9562018-09-17 17:18:43 -04003806 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
3807 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
3808 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
3809
3810 ASSERT_GL_NO_ERROR();
3811 }
3812
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003813 void testTearDown() override
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003814 {
3815 if (mProgram != 0)
3816 {
3817 glDeleteProgram(mProgram);
3818 mProgram = 0;
3819
3820 if (!mTextures.empty())
3821 {
3822 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
3823 }
3824 }
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003825 }
3826
3827 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
3828 GLint vertexTextureCount,
3829 GLint vertexActiveTextureCount,
3830 const std::string &fragPrefix,
3831 GLint fragmentTextureCount,
3832 GLint fragmentActiveTextureCount)
3833 {
3834 std::stringstream vertexShaderStr;
3835 vertexShaderStr << "attribute vec2 position;\n"
3836 << "varying vec4 color;\n"
3837 << "varying vec2 texCoord;\n";
3838
3839 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
3840 {
3841 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
3842 }
3843
3844 vertexShaderStr << "void main() {\n"
3845 << " gl_Position = vec4(position, 0, 1);\n"
3846 << " texCoord = (position * 0.5) + 0.5;\n"
3847 << " color = vec4(0);\n";
3848
3849 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
3850 {
3851 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
3852 << ", texCoord);\n";
3853 }
3854
3855 vertexShaderStr << "}";
3856
3857 std::stringstream fragmentShaderStr;
3858 fragmentShaderStr << "varying mediump vec4 color;\n"
3859 << "varying mediump vec2 texCoord;\n";
3860
3861 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
3862 {
3863 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
3864 }
3865
3866 fragmentShaderStr << "void main() {\n"
3867 << " gl_FragColor = color;\n";
3868
3869 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
3870 {
3871 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
3872 << ", texCoord);\n";
3873 }
3874
3875 fragmentShaderStr << "}";
3876
3877 const std::string &vertexShaderSource = vertexShaderStr.str();
3878 const std::string &fragmentShaderSource = fragmentShaderStr.str();
3879
Jamie Madill35cd7332018-12-02 12:03:33 -05003880 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003881 }
3882
3883 RGBA8 getPixel(GLint texIndex)
3884 {
3885 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
3886 0, 255u};
3887 return pixel;
3888 }
3889
3890 void initTextures(GLint tex2DCount, GLint texCubeCount)
3891 {
3892 GLint totalCount = tex2DCount + texCubeCount;
3893 mTextures.assign(totalCount, 0);
3894 glGenTextures(totalCount, &mTextures[0]);
3895 ASSERT_GL_NO_ERROR();
3896
3897 std::vector<RGBA8> texData(16 * 16);
3898
3899 GLint texIndex = 0;
3900 for (; texIndex < tex2DCount; ++texIndex)
3901 {
3902 texData.assign(texData.size(), getPixel(texIndex));
3903 glActiveTexture(GL_TEXTURE0 + texIndex);
3904 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
3905 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3906 &texData[0]);
3907 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3908 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3909 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3910 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3911 }
3912
3913 ASSERT_GL_NO_ERROR();
3914
3915 for (; texIndex < texCubeCount; ++texIndex)
3916 {
3917 texData.assign(texData.size(), getPixel(texIndex));
3918 glActiveTexture(GL_TEXTURE0 + texIndex);
3919 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
3920 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3921 GL_UNSIGNED_BYTE, &texData[0]);
3922 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3923 GL_UNSIGNED_BYTE, &texData[0]);
3924 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3925 GL_UNSIGNED_BYTE, &texData[0]);
3926 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3927 GL_UNSIGNED_BYTE, &texData[0]);
3928 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3929 GL_UNSIGNED_BYTE, &texData[0]);
3930 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3931 GL_UNSIGNED_BYTE, &texData[0]);
3932 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3933 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3934 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3935 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3936 }
3937
3938 ASSERT_GL_NO_ERROR();
3939 }
3940
3941 void testWithTextures(GLint vertexTextureCount,
3942 const std::string &vertexTexturePrefix,
3943 GLint fragmentTextureCount,
3944 const std::string &fragmentTexturePrefix)
3945 {
3946 // Generate textures
3947 initTextures(vertexTextureCount + fragmentTextureCount, 0);
3948
3949 glUseProgram(mProgram);
3950 RGBA8 expectedSum = {0};
3951 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
3952 {
3953 std::stringstream uniformNameStr;
3954 uniformNameStr << vertexTexturePrefix << texIndex;
3955 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003956 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003957 ASSERT_NE(-1, location);
3958
3959 glUniform1i(location, texIndex);
3960 RGBA8 contribution = getPixel(texIndex);
3961 expectedSum.R += contribution.R;
3962 expectedSum.G += contribution.G;
3963 }
3964
3965 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
3966 {
3967 std::stringstream uniformNameStr;
3968 uniformNameStr << fragmentTexturePrefix << texIndex;
3969 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003970 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003971 ASSERT_NE(-1, location);
3972
3973 glUniform1i(location, texIndex + vertexTextureCount);
3974 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
3975 expectedSum.R += contribution.R;
3976 expectedSum.G += contribution.G;
3977 }
3978
3979 ASSERT_GE(256u, expectedSum.G);
3980
3981 drawQuad(mProgram, "position", 0.5f);
3982 ASSERT_GL_NO_ERROR();
3983 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
3984 }
3985
3986 GLuint mProgram;
3987 std::vector<GLuint> mTextures;
3988 GLint mMaxVertexTextures;
3989 GLint mMaxFragmentTextures;
3990 GLint mMaxCombinedTextures;
3991};
3992
3993// Test rendering with the maximum vertex texture units.
3994TEST_P(TextureLimitsTest, MaxVertexTextures)
3995{
3996 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
3997 ASSERT_NE(0u, mProgram);
3998 ASSERT_GL_NO_ERROR();
3999
4000 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4001}
4002
4003// Test rendering with the maximum fragment texture units.
4004TEST_P(TextureLimitsTest, MaxFragmentTextures)
4005{
4006 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
4007 ASSERT_NE(0u, mProgram);
4008 ASSERT_GL_NO_ERROR();
4009
4010 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
4011}
4012
4013// Test rendering with maximum combined texture units.
4014TEST_P(TextureLimitsTest, MaxCombinedTextures)
4015{
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004016 // TODO(timvp): http://anglebug.com/3570
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004017 // max per-stage sampled image bindings count (32) exceeds device
4018 // maxPerStageDescriptorSampledImages limit (16)
Shahbaz Youssefi57f7b692020-06-05 00:45:01 -04004019 ANGLE_SKIP_TEST_IF(isSwiftshader());
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004020
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004021 GLint vertexTextures = mMaxVertexTextures;
4022
4023 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
4024 {
4025 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
4026 }
4027
4028 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
4029 mMaxFragmentTextures, mMaxFragmentTextures);
4030 ASSERT_NE(0u, mProgram);
4031 ASSERT_GL_NO_ERROR();
4032
4033 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
4034}
4035
4036// Negative test for exceeding the number of vertex textures
4037TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
4038{
4039 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
4040 0);
4041 ASSERT_EQ(0u, mProgram);
4042}
4043
4044// Negative test for exceeding the number of fragment textures
4045TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
4046{
4047 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
4048 mMaxFragmentTextures + 1);
4049 ASSERT_EQ(0u, mProgram);
4050}
4051
4052// Test active vertex textures under the limit, but excessive textures specified.
4053TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
4054{
4055 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
4056 ASSERT_NE(0u, mProgram);
4057 ASSERT_GL_NO_ERROR();
4058
4059 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4060}
4061
4062// Test active fragment textures under the limit, but excessive textures specified.
4063TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
4064{
4065 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
4066 mMaxFragmentTextures);
4067 ASSERT_NE(0u, mProgram);
4068 ASSERT_GL_NO_ERROR();
4069
4070 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
4071}
4072
4073// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02004074// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004075TEST_P(TextureLimitsTest, TextureTypeConflict)
4076{
Jamie Madill35cd7332018-12-02 12:03:33 -05004077 constexpr char kVS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004078 "attribute vec2 position;\n"
4079 "varying float color;\n"
4080 "uniform sampler2D tex2D;\n"
4081 "uniform samplerCube texCube;\n"
4082 "void main() {\n"
4083 " gl_Position = vec4(position, 0, 1);\n"
4084 " vec2 texCoord = (position * 0.5) + 0.5;\n"
4085 " color = texture2D(tex2D, texCoord).x;\n"
4086 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
4087 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05004088 constexpr char kFS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004089 "varying mediump float color;\n"
4090 "void main() {\n"
4091 " gl_FragColor = vec4(color, 0, 0, 1);\n"
4092 "}";
4093
Jamie Madill35cd7332018-12-02 12:03:33 -05004094 mProgram = CompileProgram(kVS, kFS);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004095 ASSERT_NE(0u, mProgram);
4096
4097 initTextures(1, 0);
4098
4099 glUseProgram(mProgram);
4100 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
4101 ASSERT_NE(-1, tex2DLocation);
4102 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
4103 ASSERT_NE(-1, texCubeLocation);
4104
4105 glUniform1i(tex2DLocation, 0);
4106 glUniform1i(texCubeLocation, 0);
4107 ASSERT_GL_NO_ERROR();
4108
4109 drawQuad(mProgram, "position", 0.5f);
4110 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4111}
4112
Vincent Lang25ab4512016-05-13 18:13:59 +02004113class Texture2DNorm16TestES3 : public Texture2DTestES3
4114{
4115 protected:
4116 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
4117
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004118 void testSetUp() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004119 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004120 Texture2DTestES3::testSetUp();
Vincent Lang25ab4512016-05-13 18:13:59 +02004121
4122 glActiveTexture(GL_TEXTURE0);
4123 glGenTextures(3, mTextures);
4124 glGenFramebuffers(1, &mFBO);
4125 glGenRenderbuffers(1, &mRenderbuffer);
4126
4127 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
4128 {
4129 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
4130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4132 }
4133
4134 glBindTexture(GL_TEXTURE_2D, 0);
4135
4136 ASSERT_GL_NO_ERROR();
4137 }
4138
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004139 void testTearDown() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004140 {
4141 glDeleteTextures(3, mTextures);
4142 glDeleteFramebuffers(1, &mFBO);
4143 glDeleteRenderbuffers(1, &mRenderbuffer);
4144
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004145 Texture2DTestES3::testTearDown();
Vincent Lang25ab4512016-05-13 18:13:59 +02004146 }
4147
4148 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
4149 {
shrekshao81ee4d22019-12-04 17:05:11 -08004150 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4151 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4152 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4153
Geoff Langf607c602016-09-21 11:46:48 -04004154 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
4155 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004156
4157 setUpProgram();
4158
4159 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4160 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
4161 0);
4162
4163 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
4164 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
4165
4166 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Geoff Langf607c602016-09-21 11:46:48 -04004167 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004168
4169 EXPECT_GL_NO_ERROR();
4170
4171 drawQuad(mProgram, "position", 0.5f);
4172
Geoff Langf607c602016-09-21 11:46:48 -04004173 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
Vincent Lang25ab4512016-05-13 18:13:59 +02004174
Jamie Madill50cf2be2018-06-15 09:46:57 -04004175 EXPECT_PIXEL_COLOR_EQ(0, 0,
4176 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
4177 expectedValue, expectedValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004178
4179 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4180
4181 ASSERT_GL_NO_ERROR();
4182 }
4183
shrekshao81ee4d22019-12-04 17:05:11 -08004184 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
4185 GLuint y,
4186 GLuint width,
4187 GLuint height,
4188 GLint packRowLength,
4189 GLint packAlignment,
4190 GLint packSkipPixels,
4191 GLint packSkipRows,
4192 GLenum type,
4193 GLColor16UI color)
Vincent Lang25ab4512016-05-13 18:13:59 +02004194 {
shrekshao81ee4d22019-12-04 17:05:11 -08004195 // PACK modes debugging
4196 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
4197 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
4198
4199 GLuint l = packRowLength == 0 ? width : packRowLength;
4200 const GLint &a = packAlignment;
4201
4202 // According to
4203 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4204 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
4205 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
4206 if (static_cast<GLuint>(packRowLength) < width)
4207 {
4208 componentCount += width * n * s - k;
4209 }
4210
4211 // Populate the pixels array with random dirty value
4212 constexpr GLushort kDirtyValue = 0x1234;
4213 std::vector<GLushort> pixels(componentCount, kDirtyValue);
4214 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
4215
4216 EXPECT_GL_NO_ERROR();
4217
4218 GLushort *pixelRowStart = pixels.data();
4219 pixelRowStart += n * packSkipPixels + k * packSkipRows;
4220
4221 std::vector<bool> modifiedPixels(componentCount, false);
4222
4223 char errorInfo[200];
4224
4225 for (GLuint y = 0; y < height; ++y)
4226 {
4227 GLushort *curPixel = pixelRowStart;
4228 for (GLuint x = 0, len = (y == height - 1) ? width : std::min(l, width); x < len; ++x)
4229 {
4230 snprintf(errorInfo, sizeof(errorInfo),
4231 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
4232 "skipPixels: %d, skipRows: %d\n",
4233 width, height, x, y, packRowLength, packAlignment, packSkipPixels,
4234 packSkipRows);
4235 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
4236 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
4237 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
4238 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
4239
4240 std::ptrdiff_t diff = curPixel - pixels.data();
4241 modifiedPixels[diff + 0] = true;
4242 modifiedPixels[diff + 1] = true;
4243 modifiedPixels[diff + 2] = true;
4244 modifiedPixels[diff + 3] = true;
4245
4246 curPixel += n;
4247 }
4248 pixelRowStart += k;
4249 }
4250
4251 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
4252 {
4253 if (!modifiedPixels[i])
4254 {
4255 EXPECT_EQ(pixels[i], kDirtyValue);
4256 }
4257 }
4258 }
4259
4260 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
4261 {
4262 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4263 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4264 // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
4265 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
4266 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4267
Jamie Madill50cf2be2018-06-15 09:46:57 -04004268 GLushort pixelValue = 0x6A35;
Geoff Langf607c602016-09-21 11:46:48 -04004269 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
shrekshao81ee4d22019-12-04 17:05:11 -08004270 GLColor16UI color = SliceFormatColor16UI(
4271 format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
4272 // Size of drawing viewport
4273 constexpr GLint width = 8, height = 8;
Vincent Lang25ab4512016-05-13 18:13:59 +02004274
4275 setUpProgram();
4276
4277 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
shrekshao81ee4d22019-12-04 17:05:11 -08004278 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
Vincent Lang25ab4512016-05-13 18:13:59 +02004279
4280 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4281 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4282 0);
4283
4284 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
Geoff Langf607c602016-09-21 11:46:48 -04004285 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
shrekshao81ee4d22019-12-04 17:05:11 -08004286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Vincent Lang25ab4512016-05-13 18:13:59 +02004288
4289 EXPECT_GL_NO_ERROR();
4290
4291 drawQuad(mProgram, "position", 0.5f);
4292
shrekshao81ee4d22019-12-04 17:05:11 -08004293 // ReadPixels against different width, height, pixel pack mode combinations to test
4294 // workaround of pixels rearrangement
4295
4296 // {x, y, width, height}
4297 std::vector<std::array<GLint, 4>> areas = {
4298 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
4299 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
4300
4301 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
4302
4303 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
4304 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
4305 };
4306
4307 // Put default settings at the last
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01004308 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
4309 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
shrekshao81ee4d22019-12-04 17:05:11 -08004310 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
4311 {3, 1}, {20, 20}, {0, 0}};
4312
4313 // Restore pixel pack modes later
4314 GLint restorePackAlignment;
4315 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
4316 GLint restorePackRowLength;
4317 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
4318 GLint restorePackSkipPixels;
4319 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
4320 GLint restorePackSkipRows;
4321 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
4322
4323 // Variable symbols are based on:
4324 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4325 for (const auto &skipped : paramsPackSkipPixelsAndRows)
4326 {
4327 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
4328 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
4329 for (GLint a : paramsPackAlignment)
4330 {
4331 glPixelStorei(GL_PACK_ALIGNMENT, a);
4332 for (GLint l : paramsPackRowLength)
4333 {
4334 glPixelStorei(GL_PACK_ROW_LENGTH, l);
4335
4336 for (const auto &area : areas)
4337 {
4338 ASSERT(area[0] + area[2] <= width);
4339 ASSERT(area[1] + area[3] <= height);
4340 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
4341 area[3], l, a, skipped[0],
4342 skipped[1], type, color);
4343 }
4344 }
4345 }
4346 }
4347
4348 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
4349 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
4350 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
4351 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
Vincent Lang25ab4512016-05-13 18:13:59 +02004352
4353 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4354 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4355 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4356 mRenderbuffer);
4357 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4358 EXPECT_GL_NO_ERROR();
4359
4360 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4361 glClear(GL_COLOR_BUFFER_BIT);
4362
shrekshaofb1c2fe2019-11-13 11:10:39 -08004363 EXPECT_PIXEL_16UI_COLOR(
4364 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
shrekshaoe33c1582019-11-06 16:55:29 -08004365
4366 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Vincent Lang25ab4512016-05-13 18:13:59 +02004367 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4368
shrekshaoe33c1582019-11-06 16:55:29 -08004369 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4370 0);
shrekshaofb1c2fe2019-11-13 11:10:39 -08004371 EXPECT_PIXEL_16UI_COLOR(
4372 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004373
4374 ASSERT_GL_NO_ERROR();
shrekshaofb1c2fe2019-11-13 11:10:39 -08004375
4376 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Vincent Lang25ab4512016-05-13 18:13:59 +02004377 }
4378
4379 GLuint mTextures[3];
4380 GLuint mFBO;
4381 GLuint mRenderbuffer;
4382};
4383
shrekshao81ee4d22019-12-04 17:05:11 -08004384TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
Vincent Lang25ab4512016-05-13 18:13:59 +02004385{
Vincent Lang25ab4512016-05-13 18:13:59 +02004386 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
shrekshao81ee4d22019-12-04 17:05:11 -08004387}
Vincent Lang25ab4512016-05-13 18:13:59 +02004388
shrekshao81ee4d22019-12-04 17:05:11 -08004389TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
4390{
4391 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
4392}
4393
4394TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
4395{
4396 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4397}
4398
4399TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
4400{
4401 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
4402}
4403
4404TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
4405{
4406 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4407 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4408
4409 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
4410}
4411
4412TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
4413{
4414 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4415 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4416
4417 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
4418}
4419
4420TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
4421{
4422 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4423}
4424
4425TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
4426{
4427 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
4428}
4429
4430TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
4431{
4432 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
4433}
4434
4435TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
4436{
4437 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4438}
4439
4440TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
4441{
4442 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
Vincent Lang25ab4512016-05-13 18:13:59 +02004443}
4444
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004445class Texture2DRGTest : public Texture2DTest
4446{
4447 protected:
4448 Texture2DRGTest()
4449 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4450 {}
4451
4452 void testSetUp() override
4453 {
4454 Texture2DTest::testSetUp();
4455
4456 glActiveTexture(GL_TEXTURE0);
4457 glGenTextures(1, &mRenderableTexture);
4458 glGenTextures(1, &mTestTexture);
4459 glGenFramebuffers(1, &mFBO);
4460 glGenRenderbuffers(1, &mRenderbuffer);
4461
4462 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004463 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4464 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004465 glBindTexture(GL_TEXTURE_2D, mTestTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004466 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4467 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004468
4469 glBindTexture(GL_TEXTURE_2D, 0);
4470
4471 setUpProgram();
4472 glUseProgram(mProgram);
4473 glUniform1i(mTexture2DUniformLocation, 0);
4474
4475 ASSERT_GL_NO_ERROR();
4476 }
4477
4478 void testTearDown() override
4479 {
4480 glDeleteTextures(1, &mRenderableTexture);
4481 glDeleteTextures(1, &mTestTexture);
4482 glDeleteFramebuffers(1, &mFBO);
4483 glDeleteRenderbuffers(1, &mRenderbuffer);
4484
4485 Texture2DTest::testTearDown();
4486 }
4487
4488 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
4489 {
4490 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4491 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4492
4493 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4494 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4495 mRenderableTexture, 0);
4496
4497 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4498 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
4499
4500 EXPECT_GL_NO_ERROR();
4501 }
4502
4503 void testRGTexture(GLColor expectedColor)
4504 {
4505 drawQuad(mProgram, "position", 0.5f);
4506
4507 EXPECT_GL_NO_ERROR();
4508 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
4509 }
4510
4511 void testRGRender(GLenum internalformat, GLenum format)
4512 {
4513 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4514 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4515 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4516 mRenderbuffer);
4517 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4518 EXPECT_GL_NO_ERROR();
4519
4520 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4521 glClear(GL_COLOR_BUFFER_BIT);
4522
4523 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4524
4525 ASSERT_GL_NO_ERROR();
4526 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
4527 }
4528
4529 GLuint mRenderableTexture;
4530 GLuint mTestTexture;
4531 GLuint mFBO;
4532 GLuint mRenderbuffer;
4533};
4534
4535// Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
4536TEST_P(Texture2DRGTest, TextureRGUNormTest)
4537{
4538 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4539
4540 GLubyte pixelValue = 0xab;
4541 GLubyte imageData[] = {pixelValue, pixelValue};
4542
4543 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
4544 testRGTexture(
4545 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4546 testRGRender(GL_R8_EXT, GL_RED_EXT);
4547
4548 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
4549 testRGTexture(
4550 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4551 testRGRender(GL_RG8_EXT, GL_RG_EXT);
4552}
4553
4554// Test float texture formats enabled by the GL_EXT_texture_rg extension.
4555TEST_P(Texture2DRGTest, TextureRGFloatTest)
4556{
4557 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4558 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4559
4560 GLfloat pixelValue = 0.54321;
4561 GLfloat imageData[] = {pixelValue, pixelValue};
4562
4563 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
4564 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4565
4566 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
4567 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4568
4569 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
4570 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4571}
4572
4573// Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
Mohan Maiya6caa2652019-09-11 08:06:13 -07004574TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004575{
4576 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4577 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4578
4579 GLfloat pixelValueFloat = 0.543f;
4580 GLhalf pixelValue = 0x3858;
4581 GLhalf imageData[] = {pixelValue, pixelValue};
4582
4583 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
4584 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4585
4586 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
4587 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4588
4589 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
4590 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4591}
4592
Mohan Maiya6caa2652019-09-11 08:06:13 -07004593class Texture2DFloatTest : public Texture2DTest
4594{
4595 protected:
4596 Texture2DFloatTest()
4597 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4598 {}
4599
4600 void testSetUp() override
4601 {
4602 Texture2DTest::testSetUp();
4603
4604 glActiveTexture(GL_TEXTURE0);
4605 glGenTextures(1, &mRenderableTexture);
4606 glGenTextures(1, &mTestTexture);
4607 glGenFramebuffers(1, &mFBO);
4608 glGenRenderbuffers(1, &mRenderbuffer);
4609
4610 setUpProgram();
4611 glUseProgram(mProgram);
4612 glUniform1i(mTexture2DUniformLocation, 0);
4613
4614 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4615 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4616
4617 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4618 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4619 mRenderableTexture, 0);
4620
4621 ASSERT_GL_NO_ERROR();
4622 }
4623
4624 void testTearDown() override
4625 {
4626 glDeleteTextures(1, &mRenderableTexture);
4627 glDeleteTextures(1, &mTestTexture);
4628 glDeleteFramebuffers(1, &mFBO);
4629 glDeleteRenderbuffers(1, &mRenderbuffer);
4630
4631 Texture2DTest::testTearDown();
4632 }
4633
4634 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
4635 {
4636 constexpr GLfloat imageDataFloat[] = {
4637 0.2f,
4638 0.3f,
4639 0.4f,
4640 0.5f,
4641 };
4642 constexpr GLhalf imageDataHalf[] = {
4643 0x3266,
4644 0x34CD,
4645 0x3666,
4646 0x3800,
4647 };
4648 GLColor expectedValue;
4649 for (int i = 0; i < 4; i++)
4650 {
4651 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
4652 }
4653
4654 const GLvoid *imageData;
4655 switch (type)
4656 {
4657 case GL_FLOAT:
4658 imageData = imageDataFloat;
4659 break;
4660 case GL_HALF_FLOAT:
4661 case GL_HALF_FLOAT_OES:
4662 imageData = imageDataHalf;
4663 break;
4664 default:
4665 imageData = nullptr;
4666 }
4667 ASSERT(imageData != nullptr);
4668
4669 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4670 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
4671
4672 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4674
4675 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4676 drawQuad(mProgram, "position", 0.5f);
4677
4678 EXPECT_GL_NO_ERROR();
4679 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
4680 }
4681
4682 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
4683 {
4684 int numComponents;
4685 switch (format)
4686 {
4687 case GL_RGBA:
4688 numComponents = 4;
4689 break;
4690 case GL_RGB:
4691 numComponents = 3;
4692 break;
4693 case GL_LUMINANCE_ALPHA:
4694 numComponents = 2;
4695 break;
4696 case GL_LUMINANCE:
4697 case GL_ALPHA:
4698 numComponents = 1;
4699 break;
4700 default:
4701 numComponents = 0;
4702 }
4703 ASSERT(numComponents > 0);
4704
4705 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
4706 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
4707
4708 GLfloat imageDataFloat[16];
4709 GLhalf imageDataHalf[16];
4710 for (int i = 0; i < 4; i++)
4711 {
4712 for (int c = 0; c < numComponents; c++)
4713 {
4714 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
4715 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
4716 }
4717 }
4718
4719 const GLvoid *imageData;
4720 switch (type)
4721 {
4722 case GL_FLOAT:
4723 imageData = imageDataFloat;
4724 break;
4725 case GL_HALF_FLOAT:
4726 case GL_HALF_FLOAT_OES:
4727 imageData = imageDataHalf;
4728 break;
4729 default:
4730 imageData = nullptr;
4731 }
4732 ASSERT(imageData != nullptr);
4733
4734 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4735 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
4736
4737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4738 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4739
4740 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4741 drawQuad(mProgram, "position", 0.5f);
4742
4743 EXPECT_GL_NO_ERROR();
4744 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
4745 // should expect the final value to be gray (halfway in-between)
4746 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
4747 kPixelTolerance);
4748 }
4749
4750 bool performFloatTextureRender(GLenum internalFormat,
4751 GLenum renderBufferFormat,
4752 GLenum format,
4753 GLenum type)
4754 {
4755 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4756 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
4757 glBindTexture(GL_TEXTURE_2D, 0);
4758
4759 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4760 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
4761 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4762 mRenderbuffer);
4763 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4764 EXPECT_GL_NO_ERROR();
4765
4766 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
4767 {
4768 return false;
4769 }
4770
4771 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4772
4773 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4774 glClear(GL_COLOR_BUFFER_BIT);
4775
4776 EXPECT_GL_NO_ERROR();
4777 return true;
4778 }
4779
4780 GLuint mRenderableTexture;
4781 GLuint mTestTexture;
4782 GLuint mFBO;
4783 GLuint mRenderbuffer;
4784};
4785
4786class Texture2DFloatTestES3 : public Texture2DFloatTest
4787{
4788 protected:
4789 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
4790 {
4791 bool framebufferComplete =
4792 performFloatTextureRender(internalFormat, internalFormat, format, type);
4793 EXPECT_TRUE(framebufferComplete);
4794 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4795 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4796 kPixelTolerance32F);
4797 }
4798};
4799
4800class Texture2DFloatTestES2 : public Texture2DFloatTest
4801{
4802 protected:
4803 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
4804 {
4805 bool framebufferComplete =
4806 performFloatTextureRender(format, renderBufferFormat, format, type);
4807
4808 if (!framebufferComplete)
4809 {
4810 return false;
4811 }
4812
4813 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4814 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4815 kPixelTolerance32F);
4816 return true;
4817 }
4818};
4819
4820// Test texture sampling for ES3 float texture formats
4821TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
4822{
4823 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4824 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
4825}
4826
4827// Test texture sampling for ES2 float texture formats
4828TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
4829{
4830 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4831 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
4832 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
4833}
4834
4835// Test texture sampling for ES3 half float texture formats
4836TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
4837{
4838 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4839 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4840}
4841
4842// Test texture sampling for ES2 half float texture formats
4843TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
4844{
4845 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4846 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4847 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4848}
4849
4850// Test texture sampling for legacy GLES 2.0 float texture formats in ES3
4851TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
4852{
4853 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4854
4855 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4856 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4857 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4858
4859 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4860 {
4861 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4862 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4863 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4864 }
4865}
4866
4867// Test texture sampling for legacy GLES 2.0 float texture formats in ES2
4868TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
4869{
4870 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4871
4872 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4873 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4874 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4875}
4876
4877// Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
4878TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
4879{
4880 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4881
4882 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4883 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4884 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4885
4886 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4887 {
4888 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4889 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4890 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4891 }
4892}
4893// Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
4894TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
4895{
4896 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4897
4898 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4899 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4900 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4901}
4902
4903// Test linear sampling for ES3 32F formats
4904TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
4905{
4906 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4907
4908 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4909 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
4910}
4911// Test linear sampling for ES2 32F formats
4912TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
4913{
4914 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4915
4916 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4917
4918 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
4919}
4920
4921// Test linear sampling for ES3 16F formats
4922TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
4923{
4924 // Half float formats must be linearly filterable in GLES 3.0 core
4925 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4926 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4927}
4928// Test linear sampling for ES2 16F formats
4929TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
4930{
4931 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4932 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4933 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4934}
4935
4936// Test linear sampling for legacy GLES 2.0 32F formats in ES3
4937TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
4938{
4939 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4940 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4941
4942 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4943 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4944 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4945
4946 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4947 {
4948 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4949 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4950 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4951 }
4952}
4953// Test linear sampling for legacy GLES 2.0 32F formats in ES2
4954TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
4955{
4956 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4957 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4958
4959 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4960 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4961 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4962}
4963
4964// Test linear sampling for legacy GLES 2.0 16F formats in ES3
4965TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
4966{
4967 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4968 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4969
4970 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4971 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4972 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4973
4974 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4975 {
4976 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4977 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4978 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4979 }
4980}
4981// Test linear sampling for legacy GLES 2.0 16F formats in ES2
4982TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
4983{
4984 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4985 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4986
4987 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4988 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4989 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4990}
4991
4992// Test color-renderability for ES3 float and half float textures
4993TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
4994{
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07004995 // http://anglebug.com/4092
4996 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07004997 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
4998 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
4999
5000 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
5001 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
5002 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
5003
5004 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
5005 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
5006 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
5007
5008 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
5009}
5010
5011// Test color-renderability for ES2 half float textures
5012TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
5013{
5014 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
5015 // require a specific one
5016 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
Zhenyao Mo20bb47d2019-09-16 12:55:30 -07005017 // https://crbug.com/1003971
5018 ANGLE_SKIP_TEST_IF(IsOzone());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005019 // http://anglebug.com/4092
5020 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07005021
5022 bool atLeastOneSupported = false;
5023
5024 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
5025 IsGLExtensionEnabled("GL_OES_texture_half_float"))
5026 {
5027 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
5028 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
5029 }
5030 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
5031 {
5032 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
5033
5034 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
5035 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
5036 EXPECT_TRUE(rgbaSupported);
5037 atLeastOneSupported |= rgbaSupported;
5038 }
5039
5040 EXPECT_TRUE(atLeastOneSupported);
5041}
5042
Olli Etuaho95faa232016-06-07 14:01:53 -07005043// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
5044// GLES 3.0.4 section 3.8.3.
5045TEST_P(Texture2DTestES3, UnpackSkipImages2D)
5046{
Yuly Novikovd18c0482019-04-04 19:56:43 -04005047 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
5048 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Olli Etuaho95faa232016-06-07 14:01:53 -07005049
5050 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5051 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5052 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5053 ASSERT_GL_NO_ERROR();
5054
5055 // SKIP_IMAGES should not have an effect on uploading 2D textures
5056 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
5057 ASSERT_GL_NO_ERROR();
5058
5059 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5060
5061 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5062 pixelsGreen.data());
5063 ASSERT_GL_NO_ERROR();
5064
5065 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
5066 pixelsGreen.data());
5067 ASSERT_GL_NO_ERROR();
5068
5069 glUseProgram(mProgram);
5070 drawQuad(mProgram, "position", 0.5f);
5071 ASSERT_GL_NO_ERROR();
5072
5073 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5074}
5075
Olli Etuaho989cac32016-06-08 16:18:49 -07005076// Test that skip defined in unpack parameters is taken into account when determining whether
5077// unpacking source extends outside unpack buffer bounds.
5078TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
5079{
5080 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5081 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5082 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5083 ASSERT_GL_NO_ERROR();
5084
5085 GLBuffer buf;
5086 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5087 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5088 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5089 GL_DYNAMIC_COPY);
5090 ASSERT_GL_NO_ERROR();
5091
5092 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5093 ASSERT_GL_NO_ERROR();
5094
5095 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
5096 ASSERT_GL_NO_ERROR();
5097
5098 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5099 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5100
5101 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
5102 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
5103 ASSERT_GL_NO_ERROR();
5104
5105 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5106 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5107}
5108
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005109// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
5110TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
5111{
Yunchao He9550c602018-02-13 14:47:05 +08005112 ANGLE_SKIP_TEST_IF(IsD3D11());
5113
5114 // Incorrect rendering results seen on OSX AMD.
5115 ANGLE_SKIP_TEST_IF(IsOSX() && IsAMD());
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005116
5117 const GLuint width = 8u;
5118 const GLuint height = 8u;
5119 const GLuint unpackRowLength = 5u;
5120 const GLuint unpackSkipPixels = 1u;
5121
5122 setWindowWidth(width);
5123 setWindowHeight(height);
5124
5125 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5128 ASSERT_GL_NO_ERROR();
5129
5130 GLBuffer buf;
5131 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5132 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
5133 GLColor::green);
5134
5135 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
5136 {
5137 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
5138 }
5139
5140 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5141 GL_DYNAMIC_COPY);
5142 ASSERT_GL_NO_ERROR();
5143
5144 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
5145 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
5146 ASSERT_GL_NO_ERROR();
5147
5148 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5149 ASSERT_GL_NO_ERROR();
5150
5151 glUseProgram(mProgram);
5152 drawQuad(mProgram, "position", 0.5f);
5153 ASSERT_GL_NO_ERROR();
5154
5155 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
5156 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
5157 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
5158 actual.data());
5159 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
5160 EXPECT_EQ(expected, actual);
5161}
5162
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005163template <typename T>
5164T UNorm(double value)
5165{
5166 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
5167}
5168
5169// Test rendering a depth texture with mipmaps.
5170TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
5171{
Zhenyao Moe520d7c2017-01-13 13:46:49 -08005172 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
5173 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
Jiawei Shaoaf0f31d2018-09-27 15:42:31 +08005174 // http://anglebug.com/1706
5175 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Corentin Walleze731d8a2016-09-07 10:56:25 -04005176
Jamie Madill24980272019-04-03 09:03:51 -04005177 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
5178 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
5179
Cody Northrop988f7172019-09-30 15:52:37 -06005180 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005181 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
5182
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005183 const int size = getWindowWidth();
5184
5185 auto dim = [size](int level) { return size >> level; };
Jamie Madill14718762016-09-06 15:56:54 -04005186 int levels = gl::log2(size);
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005187
5188 glActiveTexture(GL_TEXTURE0);
5189 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5190 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
5191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5193 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5195 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5196 ASSERT_GL_NO_ERROR();
5197
5198 glUseProgram(mProgram);
5199 glUniform1i(mTexture2DUniformLocation, 0);
5200
5201 std::vector<unsigned char> expected;
5202
5203 for (int level = 0; level < levels; ++level)
5204 {
5205 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
5206 expected.push_back(UNorm<unsigned char>(value));
5207
5208 int levelDim = dim(level);
5209
5210 ASSERT_GT(levelDim, 0);
5211
5212 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
5213 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
5214 GL_UNSIGNED_INT, initData.data());
5215 }
5216 ASSERT_GL_NO_ERROR();
5217
5218 for (int level = 0; level < levels; ++level)
5219 {
5220 glViewport(0, 0, dim(level), dim(level));
5221 drawQuad(mProgram, "position", 0.5f);
5222 GLColor actual = ReadColor(0, 0);
5223 EXPECT_NEAR(expected[level], actual.R, 10u);
5224 }
5225
5226 ASSERT_GL_NO_ERROR();
5227}
5228
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005229class Texture2DDepthTest : public Texture2DTest
5230{
5231 protected:
5232 Texture2DDepthTest() : Texture2DTest() {}
5233
5234 const char *getVertexShaderSource() override
5235 {
5236 return "attribute vec4 vPosition;\n"
5237 "void main() {\n"
5238 " gl_Position = vPosition;\n"
5239 "}\n";
5240 }
5241
5242 const char *getFragmentShaderSource() override
5243 {
5244 return "precision mediump float;\n"
5245 "uniform sampler2D ShadowMap;"
5246 "void main() {\n"
5247 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
5248 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
5249 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
5250 " } else {"
5251 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
5252 " }"
5253 "}\n";
5254 }
5255
5256 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
5257 {
5258 EXPECT_GL_NO_ERROR();
5259
5260 GLTexture tex;
5261 glBindTexture(GL_TEXTURE_2D, tex);
5262 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
5263
5264 return (glGetError() == GL_NO_ERROR);
5265 }
5266
5267 void testBehavior(bool useSizedComponent)
5268 {
5269 int w = getWindowWidth();
5270 int h = getWindowHeight();
5271 GLuint format = GL_DEPTH_COMPONENT;
5272 GLuint internalFormat = GL_DEPTH_COMPONENT;
5273
5274 if (useSizedComponent)
5275 {
5276 internalFormat = GL_DEPTH_COMPONENT24;
5277 }
5278
5279 GLFramebuffer fbo;
5280 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5281 ASSERT_GL_NO_ERROR();
5282
5283 GLTexture depthTexture;
5284 glBindTexture(GL_TEXTURE_2D, depthTexture);
5285 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5288 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5289
5290 TexCoordDrawTest::setUpProgram();
5291 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
5292 ASSERT_NE(-1, shadowMapLocation);
5293
5294 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
5295 ASSERT_NE(-1, positionLocation);
5296
5297 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
5298 glBindTexture(GL_TEXTURE_2D, depthTexture);
5299 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
5300 ASSERT_GL_NO_ERROR();
5301
5302 // try adding a color buffer.
5303 GLuint colorTex = 0;
5304 glGenTextures(1, &colorTex);
5305 glBindTexture(GL_TEXTURE_2D, colorTex);
5306 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5307 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5308 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5310 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5311 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
5312 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
5313 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5314 ASSERT_GL_NO_ERROR();
5315
5316 glViewport(0, 0, w, h);
5317 // Fill depthTexture with 0.75
5318 glClearDepthf(0.75);
5319 glClear(GL_DEPTH_BUFFER_BIT);
5320
5321 // Revert to normal framebuffer to test depth shader
5322 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5323 glViewport(0, 0, w, h);
5324 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5325 glClearDepthf(0.0f);
5326 ASSERT_GL_NO_ERROR();
5327
5328 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
5329 ASSERT_GL_NO_ERROR();
5330
5331 glActiveTexture(GL_TEXTURE0);
5332 glBindTexture(GL_TEXTURE_2D, depthTexture);
5333
5334 glUseProgram(mProgram);
5335 ASSERT_GL_NO_ERROR();
5336
5337 glUniform1i(shadowMapLocation, 0);
5338
5339 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
5340
5341 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
5342 ASSERT_GL_NO_ERROR();
5343 glEnableVertexAttribArray(positionLocation);
5344 ASSERT_GL_NO_ERROR();
5345 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5346 ASSERT_GL_NO_ERROR();
5347
5348 GLuint pixels[1];
5349 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
5350 ASSERT_GL_NO_ERROR();
5351
5352 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
5353 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
5354 // is in all the color components. Multiple implementations implement a workaround that
5355 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
5356 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
5357 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
5358 // depending on if it sees the texture sample in only the RED component.
5359 if (useSizedComponent)
5360 {
5361 ASSERT_NE(pixels[0], 0xff0000ff);
5362 }
5363 else
5364 {
5365 ASSERT_EQ(pixels[0], 0xff0000ff);
5366 }
5367
5368 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5369 glDeleteProgram(mProgram);
5370 }
5371};
5372
5373// Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
5374TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
5375{
5376 ANGLE_SKIP_TEST_IF(IsD3D11());
5377 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
Tobin Ehlis7af26762019-10-23 16:18:57 -06005378 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
5379 !IsGLExtensionEnabled("GL_OES_depth_texture"));
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005380 // http://anglebug.com/4092
5381 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01005382 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005383
5384 // When the depth texture is specified with unsized internalformat implementations follow
5385 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
5386 testBehavior(false);
5387}
5388
5389// Test depth texture compatibility with GLES3 using sized internalformat.
5390TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
5391{
5392 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
5393
5394 testBehavior(true);
5395}
5396
Jamie Madill7ffdda92016-09-08 13:26:51 -04005397// Tests unpacking into the unsized GL_ALPHA format.
5398TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
5399{
Jamie Madill7ffdda92016-09-08 13:26:51 -04005400 // Initialize the texure.
5401 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5402 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
5403 GL_UNSIGNED_BYTE, nullptr);
5404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5406
5407 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
5408
5409 // Pull in the color data from the unpack buffer.
Jamie Madill2e600342016-09-19 13:56:40 -04005410 GLBuffer unpackBuffer;
Jamie Madill7ffdda92016-09-08 13:26:51 -04005411 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5412 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5413 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
5414 GL_STATIC_DRAW);
5415
5416 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
5417 GL_UNSIGNED_BYTE, nullptr);
5418
5419 // Clear to a weird color to make sure we're drawing something.
5420 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
5421 glClear(GL_COLOR_BUFFER_BIT);
5422
5423 // Draw with the alpha texture and verify.
5424 drawQuad(mProgram, "position", 0.5f);
Jamie Madill7ffdda92016-09-08 13:26:51 -04005425
5426 ASSERT_GL_NO_ERROR();
5427 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
5428}
5429
Jamie Madill2e600342016-09-19 13:56:40 -04005430// Ensure stale unpack data doesn't propagate in D3D11.
5431TEST_P(Texture2DTestES3, StaleUnpackData)
5432{
5433 // Init unpack buffer.
5434 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
5435 std::vector<GLColor> pixels(pixelCount, GLColor::red);
5436
5437 GLBuffer unpackBuffer;
5438 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5439 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5440 GLsizei bufferSize = pixelCount * sizeof(GLColor);
5441 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
5442
5443 // Create from unpack buffer.
5444 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5445 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
5446 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5447 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5448 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5449
5450 drawQuad(mProgram, "position", 0.5f);
5451
5452 ASSERT_GL_NO_ERROR();
5453 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5454
5455 // Fill unpack with green, recreating buffer.
5456 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
5457 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
5458 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
5459
5460 // Reinit texture with green.
5461 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
5462 GL_UNSIGNED_BYTE, nullptr);
5463
5464 drawQuad(mProgram, "position", 0.5f);
5465
5466 ASSERT_GL_NO_ERROR();
5467 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5468}
5469
Geoff Langfb7685f2017-11-13 11:44:11 -05005470// Ensure that texture parameters passed as floats that are converted to ints are rounded before
5471// validating they are less than 0.
5472TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
5473{
5474 GLTexture texture;
5475 glBindTexture(GL_TEXTURE_2D, texture);
5476
5477 // Use a negative number that will round to zero when converted to an integer
5478 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
5479 // "Validation of values performed by state-setting commands is performed after conversion,
5480 // unless specified otherwise for a specific command."
5481 GLfloat param = -7.30157126e-07f;
5482 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
5483 EXPECT_GL_NO_ERROR();
5484
5485 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
5486 EXPECT_GL_NO_ERROR();
5487}
5488
Jamie Madillf097e232016-11-05 00:44:15 -04005489// This test covers a D3D format redefinition bug for 3D textures. The base level format was not
5490// being properly checked, and the texture storage of the previous texture format was persisting.
5491// This would result in an ASSERT in debug and incorrect rendering in release.
5492// See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
5493TEST_P(Texture3DTestES3, FormatRedefinitionBug)
5494{
5495 GLTexture tex;
5496 glBindTexture(GL_TEXTURE_3D, tex.get());
5497 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5498
5499 GLFramebuffer framebuffer;
5500 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
5501 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
5502
5503 glCheckFramebufferStatus(GL_FRAMEBUFFER);
5504
5505 std::vector<uint8_t> pixelData(100, 0);
5506
5507 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
5508 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
5509 pixelData.data());
5510
5511 ASSERT_GL_NO_ERROR();
5512}
5513
Corentin Wallezd2627992017-04-28 17:17:03 -04005514// Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
5515TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
5516{
5517 // 2D tests
5518 {
5519 GLTexture tex;
5520 glBindTexture(GL_TEXTURE_2D, tex.get());
5521
5522 GLBuffer pbo;
5523 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5524
5525 // Test OOB
5526 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
5527 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 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, nullptr, GL_STATIC_DRAW);
5532 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5533 ASSERT_GL_NO_ERROR();
5534 }
5535
5536 // 3D tests
5537 {
5538 GLTexture tex;
5539 glBindTexture(GL_TEXTURE_3D, tex.get());
5540
5541 GLBuffer pbo;
5542 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5543
5544 // Test OOB
5545 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
5546 GL_STATIC_DRAW);
5547 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5548 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5549
5550 // Test OOB
5551 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
5552 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5553 ASSERT_GL_NO_ERROR();
5554 }
5555}
5556
Jamie Madill3ed60422017-09-07 11:32:52 -04005557// Tests behaviour with a single texture and multiple sampler objects.
5558TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
5559{
5560 GLint maxTextureUnits = 0;
5561 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
5562 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
5563
5564 constexpr int kSize = 16;
5565
5566 // Make a single-level texture, fill it with red.
5567 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
5568 GLTexture tex;
5569 glBindTexture(GL_TEXTURE_2D, tex);
5570 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5571 redColors.data());
5572 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5573 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5574
5575 // Simple sanity check.
5576 draw2DTexturedQuad(0.5f, 1.0f, true);
5577 ASSERT_GL_NO_ERROR();
5578 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5579
5580 // Bind texture to unit 1 with a sampler object making it incomplete.
5581 GLSampler sampler;
5582 glBindSampler(0, sampler);
5583 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5584 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5585
5586 // Make a mipmap texture, fill it with blue.
5587 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
5588 GLTexture mipmapTex;
5589 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5590 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5591 blueColors.data());
5592 glGenerateMipmap(GL_TEXTURE_2D);
5593
5594 // Draw with the sampler, expect blue.
5595 draw2DTexturedQuad(0.5f, 1.0f, true);
5596 ASSERT_GL_NO_ERROR();
5597 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5598
5599 // Simple multitexturing program.
Jamie Madill35cd7332018-12-02 12:03:33 -05005600 constexpr char kVS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005601 "#version 300 es\n"
5602 "in vec2 position;\n"
5603 "out vec2 texCoord;\n"
5604 "void main()\n"
5605 "{\n"
5606 " gl_Position = vec4(position, 0, 1);\n"
5607 " texCoord = position * 0.5 + vec2(0.5);\n"
5608 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05005609
5610 constexpr char kFS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005611 "#version 300 es\n"
5612 "precision mediump float;\n"
5613 "in vec2 texCoord;\n"
5614 "uniform sampler2D tex1;\n"
5615 "uniform sampler2D tex2;\n"
5616 "uniform sampler2D tex3;\n"
5617 "uniform sampler2D tex4;\n"
5618 "out vec4 color;\n"
5619 "void main()\n"
5620 "{\n"
5621 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
5622 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
5623 "}";
5624
Jamie Madill35cd7332018-12-02 12:03:33 -05005625 ANGLE_GL_PROGRAM(program, kVS, kFS);
Jamie Madill3ed60422017-09-07 11:32:52 -04005626
5627 std::array<GLint, 4> texLocations = {
5628 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
5629 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
5630 for (GLint location : texLocations)
5631 {
5632 ASSERT_NE(-1, location);
5633 }
5634
5635 // Init the uniform data.
5636 glUseProgram(program);
5637 for (GLint location = 0; location < 4; ++location)
5638 {
5639 glUniform1i(texLocations[location], location);
5640 }
5641
5642 // Initialize four samplers
5643 GLSampler samplers[4];
5644
5645 // 0: non-mipped.
5646 glBindSampler(0, samplers[0]);
5647 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5648 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5649
5650 // 1: mipped.
5651 glBindSampler(1, samplers[1]);
5652 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5653 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5654
5655 // 2: non-mipped.
5656 glBindSampler(2, samplers[2]);
5657 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5658 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5659
5660 // 3: mipped.
5661 glBindSampler(3, samplers[3]);
5662 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5663 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5664
5665 // Bind two blue mipped textures and two single layer textures, should all draw.
5666 glActiveTexture(GL_TEXTURE0);
5667 glBindTexture(GL_TEXTURE_2D, tex);
5668
5669 glActiveTexture(GL_TEXTURE1);
5670 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5671
5672 glActiveTexture(GL_TEXTURE2);
5673 glBindTexture(GL_TEXTURE_2D, tex);
5674
5675 glActiveTexture(GL_TEXTURE3);
5676 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5677
5678 ASSERT_GL_NO_ERROR();
5679
5680 drawQuad(program, "position", 0.5f);
5681 ASSERT_GL_NO_ERROR();
5682 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
5683
5684 // Bind four single layer textures, two should be incomplete.
5685 glActiveTexture(GL_TEXTURE1);
5686 glBindTexture(GL_TEXTURE_2D, tex);
5687
5688 glActiveTexture(GL_TEXTURE3);
5689 glBindTexture(GL_TEXTURE_2D, tex);
5690
5691 drawQuad(program, "position", 0.5f);
5692 ASSERT_GL_NO_ERROR();
5693 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
5694}
5695
Martin Radev7e2c0d32017-09-15 14:25:42 +03005696// The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
5697// always at level 0 instead of the base level resulting in an incomplete texture if the faces at
5698// level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
5699// level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
5700// samples the cubemap using a direction vector (1,1,1).
5701TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
5702{
Yunchao He2f23f352018-02-11 22:11:37 +08005703 // Check http://anglebug.com/2155.
5704 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
5705
Jamie Madill35cd7332018-12-02 12:03:33 -05005706 constexpr char kVS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005707 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005708 precision mediump float;
5709 in vec3 pos;
5710 void main() {
5711 gl_Position = vec4(pos, 1.0);
5712 })";
Martin Radev7e2c0d32017-09-15 14:25:42 +03005713
Jamie Madill35cd7332018-12-02 12:03:33 -05005714 constexpr char kFS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005715 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005716 precision mediump float;
5717 out vec4 color;
5718 uniform samplerCube uTex;
5719 void main(){
5720 color = texture(uTex, vec3(1.0));
5721 })";
Jamie Madill35cd7332018-12-02 12:03:33 -05005722
5723 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev7e2c0d32017-09-15 14:25:42 +03005724 glUseProgram(program);
5725
5726 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
5727 glActiveTexture(GL_TEXTURE0);
5728
5729 GLTexture cubeTex;
5730 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
5731
5732 const int kFaceWidth = 1;
5733 const int kFaceHeight = 1;
5734 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
5735 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5736 GL_UNSIGNED_BYTE, texData.data());
5737 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5738 GL_UNSIGNED_BYTE, texData.data());
5739 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5740 GL_UNSIGNED_BYTE, texData.data());
5741 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5742 GL_UNSIGNED_BYTE, texData.data());
5743 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5744 GL_UNSIGNED_BYTE, texData.data());
5745 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5746 GL_UNSIGNED_BYTE, texData.data());
5747 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5748 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5749 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
5750 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
5751 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
5752 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
5753
5754 drawQuad(program, "pos", 0.5f, 1.0f, true);
5755 ASSERT_GL_NO_ERROR();
5756
5757 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5758}
5759
Jiawei Shao3c43b4d2018-02-23 11:08:28 +08005760// Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
5761TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
5762{
5763 GLuint texture = create2DTexture();
5764
5765 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
5766 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5767
5768 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
5769 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5770
5771 glDeleteTextures(1, &texture);
5772 EXPECT_GL_NO_ERROR();
5773}
5774
Olli Etuaho023371b2018-04-24 17:43:32 +03005775// Test setting base level after calling generateMipmap on a LUMA texture.
5776// Covers http://anglebug.com/2498
5777TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
5778{
5779 glActiveTexture(GL_TEXTURE0);
5780 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5781
5782 constexpr const GLsizei kWidth = 8;
5783 constexpr const GLsizei kHeight = 8;
5784 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
5785 whiteData.fill(255u);
5786
5787 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
5788 GL_UNSIGNED_BYTE, whiteData.data());
5789 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
5790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5791 glGenerateMipmap(GL_TEXTURE_2D);
5792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5793 EXPECT_GL_NO_ERROR();
5794
5795 drawQuad(mProgram, "position", 0.5f);
5796 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5797}
5798
Till Rathmannc1551dc2018-08-15 17:04:49 +02005799// Covers a bug in the D3D11 backend: http://anglebug.com/2772
5800// When using a sampler the texture was created as if it has mipmaps,
5801// regardless what you specified in GL_TEXTURE_MIN_FILTER via
5802// glSamplerParameteri() -- mistakenly the default value
5803// GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
5804// evaluated.
5805// If you didn't provide mipmaps and didn't let the driver generate them
5806// this led to not sampling your texture data when minification occurred.
5807TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
5808{
Jamie Madill35cd7332018-12-02 12:03:33 -05005809 constexpr char kVS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005810 "#version 300 es\n"
5811 "out vec2 texcoord;\n"
5812 "in vec4 position;\n"
5813 "void main()\n"
5814 "{\n"
5815 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
5816 " texcoord = (position.xy * 0.5) + 0.5;\n"
5817 "}\n";
5818
Jamie Madill35cd7332018-12-02 12:03:33 -05005819 constexpr char kFS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005820 "#version 300 es\n"
5821 "precision highp float;\n"
5822 "uniform highp sampler2D tex;\n"
5823 "in vec2 texcoord;\n"
5824 "out vec4 fragColor;\n"
5825 "void main()\n"
5826 "{\n"
5827 " fragColor = texture(tex, texcoord);\n"
5828 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -05005829
5830 ANGLE_GL_PROGRAM(program, kVS, kFS);
Till Rathmannc1551dc2018-08-15 17:04:49 +02005831
5832 GLSampler sampler;
5833 glBindSampler(0, sampler);
5834 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5835 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5836
5837 glActiveTexture(GL_TEXTURE0);
5838 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5839
5840 const GLsizei texWidth = getWindowWidth();
5841 const GLsizei texHeight = getWindowHeight();
5842 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
5843
5844 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5845 whiteData.data());
5846 EXPECT_GL_NO_ERROR();
5847
5848 drawQuad(program, "position", 0.5f);
5849 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
5850}
5851
Anders Leinof6cbe442019-04-18 15:32:07 +03005852// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5853// texture is output.
5854TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
5855{
Yuly Novikovd2683452019-05-23 16:11:19 -04005856 // http://anglebug.com/3478
5857 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5858
Anders Leinof6cbe442019-04-18 15:32:07 +03005859 glActiveTexture(GL_TEXTURE0);
5860 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5861 int width = getWindowWidth();
5862 int height = getWindowHeight();
5863 GLColor color = GLColor::green;
5864 std::vector<GLColor> pixels(width * height, color);
5865 GLint baseLevel = 1;
5866 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5867 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5868 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5869 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5870 GL_UNSIGNED_BYTE, pixels.data());
5871
5872 setUpProgram();
5873 glUseProgram(mProgram);
5874 glUniform1i(mTexture2DUniformLocation, 0);
5875 drawQuad(mProgram, "position", 0.5f);
5876
5877 EXPECT_GL_NO_ERROR();
5878 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5879 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5880}
5881
Anders Leino60cc7512019-05-06 09:25:27 +03005882// Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
5883// the texture is output.
5884TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
5885{
5886 // All output checks returned black, rather than the texture color.
5887 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
5888
5889 glActiveTexture(GL_TEXTURE0);
5890
5891 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5892 GLint baseLevel = 1;
5893 int width = getWindowWidth();
5894 int height = getWindowHeight();
5895 GLColor color = GLColor::green;
5896 std::vector<GLColor> pixels(width * height, color);
5897 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5898 {
5899 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
5900 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5901 EXPECT_GL_NO_ERROR();
5902 }
5903 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
5904 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5905 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5906
5907 glUseProgram(mProgram);
5908 glUniform1i(mTextureCubeUniformLocation, 0);
5909 drawQuad(mProgram, "position", 0.5f);
5910
5911 EXPECT_GL_NO_ERROR();
5912 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5913 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
5914 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
5915 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5916}
5917
Anders Leinoe4452442019-05-09 13:29:49 +03005918// This test sets up a cube map with four distincly colored MIP levels.
5919// The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
5920// the corners of the screen.
5921TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
5922{
5923 glActiveTexture(GL_TEXTURE0);
5924
5925 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5926 int width = getWindowWidth();
5927 int height = getWindowHeight();
5928 ASSERT_EQ(width, height);
5929 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
5930 for (GLint level = 0; level < 4; level++)
5931 {
5932 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5933 {
5934 int levelWidth = (2 * width) >> level;
5935 int levelHeight = (2 * height) >> level;
5936 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
5937 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
5938 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5939 EXPECT_GL_NO_ERROR();
5940 }
5941 }
5942 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5943 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5944 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
5945
5946 glUseProgram(mProgram);
5947 glUniform1i(mTextureCubeUniformLocation, 0);
5948 drawQuad(mProgram, "position", 0.5f);
5949
5950 ASSERT_GL_NO_ERROR();
5951 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
5952 EXPECT_EQ(ReadColor(0, 0).R, 0);
5953 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
5954 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
5955 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
5956}
5957
Anders Leino1b6aded2019-05-20 12:56:34 +03005958// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5959// texture is output.
5960TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
5961{
Jamie Madill29ac2742019-05-28 15:53:00 -04005962 // Fails on AMD: http://crbug.com/967796
Jamie Madill06055b52019-05-29 14:31:42 -04005963 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
Jamie Madill29ac2742019-05-28 15:53:00 -04005964
Anders Leino1b6aded2019-05-20 12:56:34 +03005965 glActiveTexture(GL_TEXTURE0);
5966 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5967 int width = getWindowWidth();
5968 int height = getWindowHeight();
5969 GLColor color = GLColor::green;
5970 std::vector<GLColor> pixels(width * height, color);
5971 GLint baseLevel = 1;
5972 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5973 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5974 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5975 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5976 GL_UNSIGNED_BYTE, pixels.data());
5977
5978 setUpProgram();
5979 glUseProgram(mProgram);
5980 glUniform1i(mTexture2DUniformLocation, 0);
5981 drawQuad(mProgram, "position", 0.5f);
5982
5983 EXPECT_GL_NO_ERROR();
5984 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5985 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5986}
5987
Anders Leino69d04932019-05-20 14:04:13 +03005988// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5989// texture is output.
5990TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
5991{
5992 glActiveTexture(GL_TEXTURE0);
5993 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
5994 int width = getWindowWidth();
5995 int height = getWindowHeight();
5996 int depth = 2;
5997 GLColor color = GLColor::green;
5998 std::vector<GLColor> pixels(width * height * depth, color);
5999 GLint baseLevel = 1;
6000 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
6001 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
6002 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
6003 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6004 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6005
6006 drawQuad(mProgram, "position", 0.5f);
6007
6008 EXPECT_GL_NO_ERROR();
6009 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6010 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6011}
6012
Anders Leino262e2822019-05-20 14:24:40 +03006013// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
6014// texture is output.
6015TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
6016{
6017 glActiveTexture(GL_TEXTURE0);
6018 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6019 int width = getWindowWidth();
6020 int height = getWindowHeight();
6021 int depth = 2;
6022 GLColor color = GLColor::green;
6023 std::vector<GLColor> pixels(width * height * depth, color);
6024 GLint baseLevel = 1;
6025 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
6026 GL_UNSIGNED_BYTE, pixels.data());
6027 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6028 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6029 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6030
6031 drawQuad(mProgram, "position", 0.5f);
6032
6033 EXPECT_GL_NO_ERROR();
6034 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6035 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6036}
6037
Jamie Madillfc3ec572019-11-27 21:43:22 +00006038// Test that uses glCompressedTexSubImage2D combined with a PBO
6039TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
6040{
6041 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6042 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6043 // http://anglebug.com/4115
6044 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
6045 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
6046
6047 if (getClientMajorVersion() < 3)
6048 {
6049 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
6050 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
6051 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
6052 }
6053
6054 const GLuint width = 4u;
6055 const GLuint height = 4u;
6056
6057 setWindowWidth(width);
6058 setWindowHeight(height);
6059
6060 // Setup primary Texture
6061 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6063 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6064
6065 if (getClientMajorVersion() < 3)
6066 {
6067 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6068 }
6069 else
6070 {
6071 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6072 }
6073 ASSERT_GL_NO_ERROR();
6074
6075 // Setup PBO and fill it with a red
6076 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
6077 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
6078 ASSERT_GL_NO_ERROR();
6079
6080 // Write PBO to mTexture
6081 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
6082 width * height / 2u, nullptr);
6083 ASSERT_GL_NO_ERROR();
6084
6085 setUpProgram();
6086 // Draw using PBO updated texture
6087 glUseProgram(mProgram);
6088 glUniform1i(mTexture2DUniformLocation, 0);
6089 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6090 drawQuad(mProgram, "position", 0.5f);
6091 ASSERT_GL_NO_ERROR();
6092
6093 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6094 ASSERT_GL_NO_ERROR();
6095}
6096
Cody Northrop74e816b2020-03-26 17:40:25 -06006097// Test using ETC1_RGB8 with subimage updates
6098TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
6099{
6100 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6101 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6102
6103 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
6104 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
6105 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6106
6107 const GLuint width = 4u;
6108 const GLuint height = 4u;
6109
6110 setWindowWidth(width);
6111 setWindowHeight(height);
6112
6113 // Setup primary Texture
6114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6116
6117 if (getClientMajorVersion() < 3)
6118 {
6119 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6120 }
6121 else
6122 {
6123 glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6124 }
6125 ASSERT_GL_NO_ERROR();
6126
6127 // Populate a subimage of the texture
6128 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6129 width * height / 2u, kCompressedImageETC2);
6130 ASSERT_GL_NO_ERROR();
6131
6132 // Render and ensure we get red
6133 glUseProgram(mProgram);
6134 drawQuad(mProgram, "position", 0.5f);
6135 ASSERT_GL_NO_ERROR();
6136
6137 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6138 ASSERT_GL_NO_ERROR();
6139}
6140
Ian Elliotteba008a2020-05-05 10:46:21 -06006141// Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
6142// MAX_LEVEL and draw. This used to cause Vulkan validation errors.
6143TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
6144{
6145 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6146 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6147
6148 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
6149 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6150
6151 const GLuint width = 4u;
6152 const GLuint height = 4u;
6153
6154 setWindowWidth(width);
6155 setWindowHeight(height);
6156
6157 // Setup primary Texture
6158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6160
6161 if (getClientMajorVersion() < 3)
6162 {
6163 glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6164 }
6165 else
6166 {
6167 glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6168 }
6169 ASSERT_GL_NO_ERROR();
6170
6171 // Populate a subimage of the texture
6172 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6173 width * height / 2u, kCompressedImageETC2);
6174 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
6175 width * height / 2u, kCompressedImageETC2);
6176 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
6177 width * height / 2u, kCompressedImageETC2);
6178 ASSERT_GL_NO_ERROR();
6179
6180 // Set MAX_LEVEL to 2 (the highest level)
6181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6182
6183 // Render and ensure we get red
6184 glUseProgram(mProgram);
6185 drawQuad(mProgram, "position", 0.5f);
6186 ASSERT_GL_NO_ERROR();
6187 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6188 ASSERT_GL_NO_ERROR();
6189
6190 // Decrease MAX_LEVEL to 0, render, and ensure we still get red
6191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6192 drawQuad(mProgram, "position", 0.5f);
6193 ASSERT_GL_NO_ERROR();
6194 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6195 ASSERT_GL_NO_ERROR();
6196
6197 // Increase MAX_LEVEL back to 2, render, and ensure we still get red
6198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6199 drawQuad(mProgram, "position", 0.5f);
6200 ASSERT_GL_NO_ERROR();
6201 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6202 ASSERT_GL_NO_ERROR();
6203}
6204
Jamie Madill50cf2be2018-06-15 09:46:57 -04006205// Use this to select which configurations (e.g. which renderer, which GLES major version) these
6206// tests should be run against.
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006207ANGLE_INSTANTIATE_TEST_ES2(Texture2DTest);
6208ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
6209ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
6210ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
6211ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
6212ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
6213ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3);
6214ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
6215ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
6216ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
6217ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
6218ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
6219ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
6220ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
6221ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
6222ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
6223ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
6224ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
6225ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
6226ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
6227ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
6228ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
6229ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
6230ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
6231ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
6232ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DRGTest);
6233ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
6234ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
6235ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
6236ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
6237ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
6238ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
6239ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
6240ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
6241ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
6242ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
Jamie Madillfc3ec572019-11-27 21:43:22 +00006243ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
Cody Northrop74e816b2020-03-26 17:40:25 -06006244ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
Jamie Madillfa05f602015-05-07 13:47:11 -04006245
Jamie Madill7ffdda92016-09-08 13:26:51 -04006246} // anonymous namespace