blob: 07ea2481b33a1fac2b1eb793bea4bae788877fd1 [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
4017 // Currently only fails on SwiftShader but we don't have an IsSwiftShader().
4018 // max per-stage sampled image bindings count (32) exceeds device
4019 // maxPerStageDescriptorSampledImages limit (16)
4020 ANGLE_SKIP_TEST_IF(IsVulkan());
4021
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004022 GLint vertexTextures = mMaxVertexTextures;
4023
4024 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
4025 {
4026 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
4027 }
4028
4029 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
4030 mMaxFragmentTextures, mMaxFragmentTextures);
4031 ASSERT_NE(0u, mProgram);
4032 ASSERT_GL_NO_ERROR();
4033
4034 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
4035}
4036
4037// Negative test for exceeding the number of vertex textures
4038TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
4039{
4040 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
4041 0);
4042 ASSERT_EQ(0u, mProgram);
4043}
4044
4045// Negative test for exceeding the number of fragment textures
4046TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
4047{
4048 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
4049 mMaxFragmentTextures + 1);
4050 ASSERT_EQ(0u, mProgram);
4051}
4052
4053// Test active vertex textures under the limit, but excessive textures specified.
4054TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
4055{
4056 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
4057 ASSERT_NE(0u, mProgram);
4058 ASSERT_GL_NO_ERROR();
4059
4060 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4061}
4062
4063// Test active fragment textures under the limit, but excessive textures specified.
4064TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
4065{
4066 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
4067 mMaxFragmentTextures);
4068 ASSERT_NE(0u, mProgram);
4069 ASSERT_GL_NO_ERROR();
4070
4071 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
4072}
4073
4074// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02004075// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004076TEST_P(TextureLimitsTest, TextureTypeConflict)
4077{
Jamie Madill35cd7332018-12-02 12:03:33 -05004078 constexpr char kVS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004079 "attribute vec2 position;\n"
4080 "varying float color;\n"
4081 "uniform sampler2D tex2D;\n"
4082 "uniform samplerCube texCube;\n"
4083 "void main() {\n"
4084 " gl_Position = vec4(position, 0, 1);\n"
4085 " vec2 texCoord = (position * 0.5) + 0.5;\n"
4086 " color = texture2D(tex2D, texCoord).x;\n"
4087 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
4088 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05004089 constexpr char kFS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004090 "varying mediump float color;\n"
4091 "void main() {\n"
4092 " gl_FragColor = vec4(color, 0, 0, 1);\n"
4093 "}";
4094
Jamie Madill35cd7332018-12-02 12:03:33 -05004095 mProgram = CompileProgram(kVS, kFS);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004096 ASSERT_NE(0u, mProgram);
4097
4098 initTextures(1, 0);
4099
4100 glUseProgram(mProgram);
4101 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
4102 ASSERT_NE(-1, tex2DLocation);
4103 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
4104 ASSERT_NE(-1, texCubeLocation);
4105
4106 glUniform1i(tex2DLocation, 0);
4107 glUniform1i(texCubeLocation, 0);
4108 ASSERT_GL_NO_ERROR();
4109
4110 drawQuad(mProgram, "position", 0.5f);
4111 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4112}
4113
Vincent Lang25ab4512016-05-13 18:13:59 +02004114class Texture2DNorm16TestES3 : public Texture2DTestES3
4115{
4116 protected:
4117 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
4118
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004119 void testSetUp() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004120 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004121 Texture2DTestES3::testSetUp();
Vincent Lang25ab4512016-05-13 18:13:59 +02004122
4123 glActiveTexture(GL_TEXTURE0);
4124 glGenTextures(3, mTextures);
4125 glGenFramebuffers(1, &mFBO);
4126 glGenRenderbuffers(1, &mRenderbuffer);
4127
4128 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
4129 {
4130 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
4131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4133 }
4134
4135 glBindTexture(GL_TEXTURE_2D, 0);
4136
4137 ASSERT_GL_NO_ERROR();
4138 }
4139
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004140 void testTearDown() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004141 {
4142 glDeleteTextures(3, mTextures);
4143 glDeleteFramebuffers(1, &mFBO);
4144 glDeleteRenderbuffers(1, &mRenderbuffer);
4145
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004146 Texture2DTestES3::testTearDown();
Vincent Lang25ab4512016-05-13 18:13:59 +02004147 }
4148
4149 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
4150 {
shrekshao81ee4d22019-12-04 17:05:11 -08004151 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4152 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4153 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4154
Geoff Langf607c602016-09-21 11:46:48 -04004155 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
4156 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004157
4158 setUpProgram();
4159
4160 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4161 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
4162 0);
4163
4164 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
4165 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
4166
4167 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Geoff Langf607c602016-09-21 11:46:48 -04004168 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004169
4170 EXPECT_GL_NO_ERROR();
4171
4172 drawQuad(mProgram, "position", 0.5f);
4173
Geoff Langf607c602016-09-21 11:46:48 -04004174 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
Vincent Lang25ab4512016-05-13 18:13:59 +02004175
Jamie Madill50cf2be2018-06-15 09:46:57 -04004176 EXPECT_PIXEL_COLOR_EQ(0, 0,
4177 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
4178 expectedValue, expectedValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004179
4180 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4181
4182 ASSERT_GL_NO_ERROR();
4183 }
4184
shrekshao81ee4d22019-12-04 17:05:11 -08004185 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
4186 GLuint y,
4187 GLuint width,
4188 GLuint height,
4189 GLint packRowLength,
4190 GLint packAlignment,
4191 GLint packSkipPixels,
4192 GLint packSkipRows,
4193 GLenum type,
4194 GLColor16UI color)
Vincent Lang25ab4512016-05-13 18:13:59 +02004195 {
shrekshao81ee4d22019-12-04 17:05:11 -08004196 // PACK modes debugging
4197 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
4198 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
4199
4200 GLuint l = packRowLength == 0 ? width : packRowLength;
4201 const GLint &a = packAlignment;
4202
4203 // According to
4204 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4205 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
4206 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
4207 if (static_cast<GLuint>(packRowLength) < width)
4208 {
4209 componentCount += width * n * s - k;
4210 }
4211
4212 // Populate the pixels array with random dirty value
4213 constexpr GLushort kDirtyValue = 0x1234;
4214 std::vector<GLushort> pixels(componentCount, kDirtyValue);
4215 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
4216
4217 EXPECT_GL_NO_ERROR();
4218
4219 GLushort *pixelRowStart = pixels.data();
4220 pixelRowStart += n * packSkipPixels + k * packSkipRows;
4221
4222 std::vector<bool> modifiedPixels(componentCount, false);
4223
4224 char errorInfo[200];
4225
4226 for (GLuint y = 0; y < height; ++y)
4227 {
4228 GLushort *curPixel = pixelRowStart;
4229 for (GLuint x = 0, len = (y == height - 1) ? width : std::min(l, width); x < len; ++x)
4230 {
4231 snprintf(errorInfo, sizeof(errorInfo),
4232 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
4233 "skipPixels: %d, skipRows: %d\n",
4234 width, height, x, y, packRowLength, packAlignment, packSkipPixels,
4235 packSkipRows);
4236 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
4237 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
4238 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
4239 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
4240
4241 std::ptrdiff_t diff = curPixel - pixels.data();
4242 modifiedPixels[diff + 0] = true;
4243 modifiedPixels[diff + 1] = true;
4244 modifiedPixels[diff + 2] = true;
4245 modifiedPixels[diff + 3] = true;
4246
4247 curPixel += n;
4248 }
4249 pixelRowStart += k;
4250 }
4251
4252 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
4253 {
4254 if (!modifiedPixels[i])
4255 {
4256 EXPECT_EQ(pixels[i], kDirtyValue);
4257 }
4258 }
4259 }
4260
4261 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
4262 {
4263 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4264 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4265 // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
4266 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
4267 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4268
Jamie Madill50cf2be2018-06-15 09:46:57 -04004269 GLushort pixelValue = 0x6A35;
Geoff Langf607c602016-09-21 11:46:48 -04004270 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
shrekshao81ee4d22019-12-04 17:05:11 -08004271 GLColor16UI color = SliceFormatColor16UI(
4272 format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
4273 // Size of drawing viewport
4274 constexpr GLint width = 8, height = 8;
Vincent Lang25ab4512016-05-13 18:13:59 +02004275
4276 setUpProgram();
4277
4278 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
shrekshao81ee4d22019-12-04 17:05:11 -08004279 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
Vincent Lang25ab4512016-05-13 18:13:59 +02004280
4281 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4282 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4283 0);
4284
4285 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
Geoff Langf607c602016-09-21 11:46:48 -04004286 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
shrekshao81ee4d22019-12-04 17:05:11 -08004287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4288 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Vincent Lang25ab4512016-05-13 18:13:59 +02004289
4290 EXPECT_GL_NO_ERROR();
4291
4292 drawQuad(mProgram, "position", 0.5f);
4293
shrekshao81ee4d22019-12-04 17:05:11 -08004294 // ReadPixels against different width, height, pixel pack mode combinations to test
4295 // workaround of pixels rearrangement
4296
4297 // {x, y, width, height}
4298 std::vector<std::array<GLint, 4>> areas = {
4299 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
4300 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
4301
4302 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
4303
4304 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
4305 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
4306 };
4307
4308 // Put default settings at the last
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01004309 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
4310 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
shrekshao81ee4d22019-12-04 17:05:11 -08004311 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
4312 {3, 1}, {20, 20}, {0, 0}};
4313
4314 // Restore pixel pack modes later
4315 GLint restorePackAlignment;
4316 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
4317 GLint restorePackRowLength;
4318 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
4319 GLint restorePackSkipPixels;
4320 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
4321 GLint restorePackSkipRows;
4322 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
4323
4324 // Variable symbols are based on:
4325 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4326 for (const auto &skipped : paramsPackSkipPixelsAndRows)
4327 {
4328 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
4329 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
4330 for (GLint a : paramsPackAlignment)
4331 {
4332 glPixelStorei(GL_PACK_ALIGNMENT, a);
4333 for (GLint l : paramsPackRowLength)
4334 {
4335 glPixelStorei(GL_PACK_ROW_LENGTH, l);
4336
4337 for (const auto &area : areas)
4338 {
4339 ASSERT(area[0] + area[2] <= width);
4340 ASSERT(area[1] + area[3] <= height);
4341 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
4342 area[3], l, a, skipped[0],
4343 skipped[1], type, color);
4344 }
4345 }
4346 }
4347 }
4348
4349 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
4350 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
4351 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
4352 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
Vincent Lang25ab4512016-05-13 18:13:59 +02004353
4354 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4355 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4356 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4357 mRenderbuffer);
4358 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4359 EXPECT_GL_NO_ERROR();
4360
4361 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4362 glClear(GL_COLOR_BUFFER_BIT);
4363
shrekshaofb1c2fe2019-11-13 11:10:39 -08004364 EXPECT_PIXEL_16UI_COLOR(
4365 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
shrekshaoe33c1582019-11-06 16:55:29 -08004366
4367 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Vincent Lang25ab4512016-05-13 18:13:59 +02004368 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4369
shrekshaoe33c1582019-11-06 16:55:29 -08004370 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4371 0);
shrekshaofb1c2fe2019-11-13 11:10:39 -08004372 EXPECT_PIXEL_16UI_COLOR(
4373 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004374
4375 ASSERT_GL_NO_ERROR();
shrekshaofb1c2fe2019-11-13 11:10:39 -08004376
4377 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Vincent Lang25ab4512016-05-13 18:13:59 +02004378 }
4379
4380 GLuint mTextures[3];
4381 GLuint mFBO;
4382 GLuint mRenderbuffer;
4383};
4384
shrekshao81ee4d22019-12-04 17:05:11 -08004385TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
Vincent Lang25ab4512016-05-13 18:13:59 +02004386{
Vincent Lang25ab4512016-05-13 18:13:59 +02004387 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
shrekshao81ee4d22019-12-04 17:05:11 -08004388}
Vincent Lang25ab4512016-05-13 18:13:59 +02004389
shrekshao81ee4d22019-12-04 17:05:11 -08004390TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
4391{
4392 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
4393}
4394
4395TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
4396{
4397 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4398}
4399
4400TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
4401{
4402 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
4403}
4404
4405TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
4406{
4407 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4408 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4409
4410 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
4411}
4412
4413TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
4414{
4415 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4416 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4417
4418 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
4419}
4420
4421TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
4422{
4423 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4424}
4425
4426TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
4427{
4428 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
4429}
4430
4431TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
4432{
4433 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
4434}
4435
4436TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
4437{
4438 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4439}
4440
4441TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
4442{
4443 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
Vincent Lang25ab4512016-05-13 18:13:59 +02004444}
4445
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004446class Texture2DRGTest : public Texture2DTest
4447{
4448 protected:
4449 Texture2DRGTest()
4450 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4451 {}
4452
4453 void testSetUp() override
4454 {
4455 Texture2DTest::testSetUp();
4456
4457 glActiveTexture(GL_TEXTURE0);
4458 glGenTextures(1, &mRenderableTexture);
4459 glGenTextures(1, &mTestTexture);
4460 glGenFramebuffers(1, &mFBO);
4461 glGenRenderbuffers(1, &mRenderbuffer);
4462
4463 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004464 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4465 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004466 glBindTexture(GL_TEXTURE_2D, mTestTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004467 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4468 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004469
4470 glBindTexture(GL_TEXTURE_2D, 0);
4471
4472 setUpProgram();
4473 glUseProgram(mProgram);
4474 glUniform1i(mTexture2DUniformLocation, 0);
4475
4476 ASSERT_GL_NO_ERROR();
4477 }
4478
4479 void testTearDown() override
4480 {
4481 glDeleteTextures(1, &mRenderableTexture);
4482 glDeleteTextures(1, &mTestTexture);
4483 glDeleteFramebuffers(1, &mFBO);
4484 glDeleteRenderbuffers(1, &mRenderbuffer);
4485
4486 Texture2DTest::testTearDown();
4487 }
4488
4489 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
4490 {
4491 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4492 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4493
4494 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4495 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4496 mRenderableTexture, 0);
4497
4498 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4499 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
4500
4501 EXPECT_GL_NO_ERROR();
4502 }
4503
4504 void testRGTexture(GLColor expectedColor)
4505 {
4506 drawQuad(mProgram, "position", 0.5f);
4507
4508 EXPECT_GL_NO_ERROR();
4509 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
4510 }
4511
4512 void testRGRender(GLenum internalformat, GLenum format)
4513 {
4514 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4515 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4516 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4517 mRenderbuffer);
4518 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4519 EXPECT_GL_NO_ERROR();
4520
4521 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4522 glClear(GL_COLOR_BUFFER_BIT);
4523
4524 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4525
4526 ASSERT_GL_NO_ERROR();
4527 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
4528 }
4529
4530 GLuint mRenderableTexture;
4531 GLuint mTestTexture;
4532 GLuint mFBO;
4533 GLuint mRenderbuffer;
4534};
4535
4536// Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
4537TEST_P(Texture2DRGTest, TextureRGUNormTest)
4538{
4539 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4540
4541 GLubyte pixelValue = 0xab;
4542 GLubyte imageData[] = {pixelValue, pixelValue};
4543
4544 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
4545 testRGTexture(
4546 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4547 testRGRender(GL_R8_EXT, GL_RED_EXT);
4548
4549 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
4550 testRGTexture(
4551 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4552 testRGRender(GL_RG8_EXT, GL_RG_EXT);
4553}
4554
4555// Test float texture formats enabled by the GL_EXT_texture_rg extension.
4556TEST_P(Texture2DRGTest, TextureRGFloatTest)
4557{
4558 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4559 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4560
4561 GLfloat pixelValue = 0.54321;
4562 GLfloat imageData[] = {pixelValue, pixelValue};
4563
4564 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
4565 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4566
4567 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
4568 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4569
4570 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
4571 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4572}
4573
4574// Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
Mohan Maiya6caa2652019-09-11 08:06:13 -07004575TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004576{
4577 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4578 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4579
4580 GLfloat pixelValueFloat = 0.543f;
4581 GLhalf pixelValue = 0x3858;
4582 GLhalf imageData[] = {pixelValue, pixelValue};
4583
4584 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
4585 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4586
4587 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
4588 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4589
4590 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
4591 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4592}
4593
Mohan Maiya6caa2652019-09-11 08:06:13 -07004594class Texture2DFloatTest : public Texture2DTest
4595{
4596 protected:
4597 Texture2DFloatTest()
4598 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4599 {}
4600
4601 void testSetUp() override
4602 {
4603 Texture2DTest::testSetUp();
4604
4605 glActiveTexture(GL_TEXTURE0);
4606 glGenTextures(1, &mRenderableTexture);
4607 glGenTextures(1, &mTestTexture);
4608 glGenFramebuffers(1, &mFBO);
4609 glGenRenderbuffers(1, &mRenderbuffer);
4610
4611 setUpProgram();
4612 glUseProgram(mProgram);
4613 glUniform1i(mTexture2DUniformLocation, 0);
4614
4615 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4616 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4617
4618 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4619 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4620 mRenderableTexture, 0);
4621
4622 ASSERT_GL_NO_ERROR();
4623 }
4624
4625 void testTearDown() override
4626 {
4627 glDeleteTextures(1, &mRenderableTexture);
4628 glDeleteTextures(1, &mTestTexture);
4629 glDeleteFramebuffers(1, &mFBO);
4630 glDeleteRenderbuffers(1, &mRenderbuffer);
4631
4632 Texture2DTest::testTearDown();
4633 }
4634
4635 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
4636 {
4637 constexpr GLfloat imageDataFloat[] = {
4638 0.2f,
4639 0.3f,
4640 0.4f,
4641 0.5f,
4642 };
4643 constexpr GLhalf imageDataHalf[] = {
4644 0x3266,
4645 0x34CD,
4646 0x3666,
4647 0x3800,
4648 };
4649 GLColor expectedValue;
4650 for (int i = 0; i < 4; i++)
4651 {
4652 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
4653 }
4654
4655 const GLvoid *imageData;
4656 switch (type)
4657 {
4658 case GL_FLOAT:
4659 imageData = imageDataFloat;
4660 break;
4661 case GL_HALF_FLOAT:
4662 case GL_HALF_FLOAT_OES:
4663 imageData = imageDataHalf;
4664 break;
4665 default:
4666 imageData = nullptr;
4667 }
4668 ASSERT(imageData != nullptr);
4669
4670 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4671 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
4672
4673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4674 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4675
4676 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4677 drawQuad(mProgram, "position", 0.5f);
4678
4679 EXPECT_GL_NO_ERROR();
4680 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
4681 }
4682
4683 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
4684 {
4685 int numComponents;
4686 switch (format)
4687 {
4688 case GL_RGBA:
4689 numComponents = 4;
4690 break;
4691 case GL_RGB:
4692 numComponents = 3;
4693 break;
4694 case GL_LUMINANCE_ALPHA:
4695 numComponents = 2;
4696 break;
4697 case GL_LUMINANCE:
4698 case GL_ALPHA:
4699 numComponents = 1;
4700 break;
4701 default:
4702 numComponents = 0;
4703 }
4704 ASSERT(numComponents > 0);
4705
4706 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
4707 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
4708
4709 GLfloat imageDataFloat[16];
4710 GLhalf imageDataHalf[16];
4711 for (int i = 0; i < 4; i++)
4712 {
4713 for (int c = 0; c < numComponents; c++)
4714 {
4715 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
4716 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
4717 }
4718 }
4719
4720 const GLvoid *imageData;
4721 switch (type)
4722 {
4723 case GL_FLOAT:
4724 imageData = imageDataFloat;
4725 break;
4726 case GL_HALF_FLOAT:
4727 case GL_HALF_FLOAT_OES:
4728 imageData = imageDataHalf;
4729 break;
4730 default:
4731 imageData = nullptr;
4732 }
4733 ASSERT(imageData != nullptr);
4734
4735 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4736 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
4737
4738 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4739 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4740
4741 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4742 drawQuad(mProgram, "position", 0.5f);
4743
4744 EXPECT_GL_NO_ERROR();
4745 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
4746 // should expect the final value to be gray (halfway in-between)
4747 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
4748 kPixelTolerance);
4749 }
4750
4751 bool performFloatTextureRender(GLenum internalFormat,
4752 GLenum renderBufferFormat,
4753 GLenum format,
4754 GLenum type)
4755 {
4756 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4757 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
4758 glBindTexture(GL_TEXTURE_2D, 0);
4759
4760 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4761 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
4762 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4763 mRenderbuffer);
4764 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4765 EXPECT_GL_NO_ERROR();
4766
4767 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
4768 {
4769 return false;
4770 }
4771
4772 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4773
4774 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4775 glClear(GL_COLOR_BUFFER_BIT);
4776
4777 EXPECT_GL_NO_ERROR();
4778 return true;
4779 }
4780
4781 GLuint mRenderableTexture;
4782 GLuint mTestTexture;
4783 GLuint mFBO;
4784 GLuint mRenderbuffer;
4785};
4786
4787class Texture2DFloatTestES3 : public Texture2DFloatTest
4788{
4789 protected:
4790 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
4791 {
4792 bool framebufferComplete =
4793 performFloatTextureRender(internalFormat, internalFormat, format, type);
4794 EXPECT_TRUE(framebufferComplete);
4795 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4796 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4797 kPixelTolerance32F);
4798 }
4799};
4800
4801class Texture2DFloatTestES2 : public Texture2DFloatTest
4802{
4803 protected:
4804 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
4805 {
4806 bool framebufferComplete =
4807 performFloatTextureRender(format, renderBufferFormat, format, type);
4808
4809 if (!framebufferComplete)
4810 {
4811 return false;
4812 }
4813
4814 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4815 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4816 kPixelTolerance32F);
4817 return true;
4818 }
4819};
4820
4821// Test texture sampling for ES3 float texture formats
4822TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
4823{
4824 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4825 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
4826}
4827
4828// Test texture sampling for ES2 float texture formats
4829TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
4830{
4831 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4832 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
4833 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
4834}
4835
4836// Test texture sampling for ES3 half float texture formats
4837TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
4838{
4839 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4840 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4841}
4842
4843// Test texture sampling for ES2 half float texture formats
4844TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
4845{
4846 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4847 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4848 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4849}
4850
4851// Test texture sampling for legacy GLES 2.0 float texture formats in ES3
4852TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
4853{
4854 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4855
4856 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4857 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4858 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4859
4860 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4861 {
4862 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4863 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4864 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4865 }
4866}
4867
4868// Test texture sampling for legacy GLES 2.0 float texture formats in ES2
4869TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
4870{
4871 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4872
4873 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4874 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4875 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4876}
4877
4878// Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
4879TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
4880{
4881 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4882
4883 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4884 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4885 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4886
4887 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4888 {
4889 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4890 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4891 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4892 }
4893}
4894// Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
4895TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
4896{
4897 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4898
4899 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4900 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4901 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4902}
4903
4904// Test linear sampling for ES3 32F formats
4905TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
4906{
4907 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4908
4909 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4910 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
4911}
4912// Test linear sampling for ES2 32F formats
4913TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
4914{
4915 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4916
4917 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4918
4919 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
4920}
4921
4922// Test linear sampling for ES3 16F formats
4923TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
4924{
4925 // Half float formats must be linearly filterable in GLES 3.0 core
4926 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4927 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4928}
4929// Test linear sampling for ES2 16F formats
4930TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
4931{
4932 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4933 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4934 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4935}
4936
4937// Test linear sampling for legacy GLES 2.0 32F formats in ES3
4938TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
4939{
4940 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4941 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4942
4943 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4944 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4945 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4946
4947 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4948 {
4949 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4950 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4951 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4952 }
4953}
4954// Test linear sampling for legacy GLES 2.0 32F formats in ES2
4955TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
4956{
4957 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4958 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4959
4960 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4961 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4962 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4963}
4964
4965// Test linear sampling for legacy GLES 2.0 16F formats in ES3
4966TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
4967{
4968 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4969 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4970
4971 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4972 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4973 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4974
4975 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4976 {
4977 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4978 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4979 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4980 }
4981}
4982// Test linear sampling for legacy GLES 2.0 16F formats in ES2
4983TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
4984{
4985 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4986 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4987
4988 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4989 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4990 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4991}
4992
4993// Test color-renderability for ES3 float and half float textures
4994TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
4995{
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07004996 // http://anglebug.com/4092
4997 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07004998 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
4999 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
5000
5001 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
5002 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
5003 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
5004
5005 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
5006 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
5007 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
5008
5009 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
5010}
5011
5012// Test color-renderability for ES2 half float textures
5013TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
5014{
5015 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
5016 // require a specific one
5017 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
Zhenyao Mo20bb47d2019-09-16 12:55:30 -07005018 // https://crbug.com/1003971
5019 ANGLE_SKIP_TEST_IF(IsOzone());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005020 // http://anglebug.com/4092
5021 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07005022
5023 bool atLeastOneSupported = false;
5024
5025 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
5026 IsGLExtensionEnabled("GL_OES_texture_half_float"))
5027 {
5028 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
5029 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
5030 }
5031 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
5032 {
5033 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
5034
5035 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
5036 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
5037 EXPECT_TRUE(rgbaSupported);
5038 atLeastOneSupported |= rgbaSupported;
5039 }
5040
5041 EXPECT_TRUE(atLeastOneSupported);
5042}
5043
Olli Etuaho95faa232016-06-07 14:01:53 -07005044// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
5045// GLES 3.0.4 section 3.8.3.
5046TEST_P(Texture2DTestES3, UnpackSkipImages2D)
5047{
Yuly Novikovd18c0482019-04-04 19:56:43 -04005048 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
5049 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Olli Etuaho95faa232016-06-07 14:01:53 -07005050
5051 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5052 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5053 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5054 ASSERT_GL_NO_ERROR();
5055
5056 // SKIP_IMAGES should not have an effect on uploading 2D textures
5057 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
5058 ASSERT_GL_NO_ERROR();
5059
5060 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5061
5062 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5063 pixelsGreen.data());
5064 ASSERT_GL_NO_ERROR();
5065
5066 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
5067 pixelsGreen.data());
5068 ASSERT_GL_NO_ERROR();
5069
5070 glUseProgram(mProgram);
5071 drawQuad(mProgram, "position", 0.5f);
5072 ASSERT_GL_NO_ERROR();
5073
5074 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5075}
5076
Olli Etuaho989cac32016-06-08 16:18:49 -07005077// Test that skip defined in unpack parameters is taken into account when determining whether
5078// unpacking source extends outside unpack buffer bounds.
5079TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
5080{
5081 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5082 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5083 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5084 ASSERT_GL_NO_ERROR();
5085
5086 GLBuffer buf;
5087 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5088 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5089 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5090 GL_DYNAMIC_COPY);
5091 ASSERT_GL_NO_ERROR();
5092
5093 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5094 ASSERT_GL_NO_ERROR();
5095
5096 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
5097 ASSERT_GL_NO_ERROR();
5098
5099 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5100 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5101
5102 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
5103 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
5104 ASSERT_GL_NO_ERROR();
5105
5106 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5107 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5108}
5109
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005110// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
5111TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
5112{
Yunchao He9550c602018-02-13 14:47:05 +08005113 ANGLE_SKIP_TEST_IF(IsD3D11());
5114
5115 // Incorrect rendering results seen on OSX AMD.
5116 ANGLE_SKIP_TEST_IF(IsOSX() && IsAMD());
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005117
5118 const GLuint width = 8u;
5119 const GLuint height = 8u;
5120 const GLuint unpackRowLength = 5u;
5121 const GLuint unpackSkipPixels = 1u;
5122
5123 setWindowWidth(width);
5124 setWindowHeight(height);
5125
5126 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5129 ASSERT_GL_NO_ERROR();
5130
5131 GLBuffer buf;
5132 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5133 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
5134 GLColor::green);
5135
5136 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
5137 {
5138 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
5139 }
5140
5141 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5142 GL_DYNAMIC_COPY);
5143 ASSERT_GL_NO_ERROR();
5144
5145 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
5146 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
5147 ASSERT_GL_NO_ERROR();
5148
5149 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5150 ASSERT_GL_NO_ERROR();
5151
5152 glUseProgram(mProgram);
5153 drawQuad(mProgram, "position", 0.5f);
5154 ASSERT_GL_NO_ERROR();
5155
5156 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
5157 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
5158 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
5159 actual.data());
5160 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
5161 EXPECT_EQ(expected, actual);
5162}
5163
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005164template <typename T>
5165T UNorm(double value)
5166{
5167 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
5168}
5169
5170// Test rendering a depth texture with mipmaps.
5171TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
5172{
Zhenyao Moe520d7c2017-01-13 13:46:49 -08005173 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
5174 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
Jiawei Shaoaf0f31d2018-09-27 15:42:31 +08005175 // http://anglebug.com/1706
5176 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Corentin Walleze731d8a2016-09-07 10:56:25 -04005177
Jamie Madill24980272019-04-03 09:03:51 -04005178 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
5179 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
5180
Cody Northrop988f7172019-09-30 15:52:37 -06005181 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005182 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
5183
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005184 const int size = getWindowWidth();
5185
5186 auto dim = [size](int level) { return size >> level; };
Jamie Madill14718762016-09-06 15:56:54 -04005187 int levels = gl::log2(size);
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005188
5189 glActiveTexture(GL_TEXTURE0);
5190 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5191 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
5192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5193 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5196 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5197 ASSERT_GL_NO_ERROR();
5198
5199 glUseProgram(mProgram);
5200 glUniform1i(mTexture2DUniformLocation, 0);
5201
5202 std::vector<unsigned char> expected;
5203
5204 for (int level = 0; level < levels; ++level)
5205 {
5206 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
5207 expected.push_back(UNorm<unsigned char>(value));
5208
5209 int levelDim = dim(level);
5210
5211 ASSERT_GT(levelDim, 0);
5212
5213 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
5214 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
5215 GL_UNSIGNED_INT, initData.data());
5216 }
5217 ASSERT_GL_NO_ERROR();
5218
5219 for (int level = 0; level < levels; ++level)
5220 {
5221 glViewport(0, 0, dim(level), dim(level));
5222 drawQuad(mProgram, "position", 0.5f);
5223 GLColor actual = ReadColor(0, 0);
5224 EXPECT_NEAR(expected[level], actual.R, 10u);
5225 }
5226
5227 ASSERT_GL_NO_ERROR();
5228}
5229
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005230class Texture2DDepthTest : public Texture2DTest
5231{
5232 protected:
5233 Texture2DDepthTest() : Texture2DTest() {}
5234
5235 const char *getVertexShaderSource() override
5236 {
5237 return "attribute vec4 vPosition;\n"
5238 "void main() {\n"
5239 " gl_Position = vPosition;\n"
5240 "}\n";
5241 }
5242
5243 const char *getFragmentShaderSource() override
5244 {
5245 return "precision mediump float;\n"
5246 "uniform sampler2D ShadowMap;"
5247 "void main() {\n"
5248 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
5249 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
5250 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
5251 " } else {"
5252 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
5253 " }"
5254 "}\n";
5255 }
5256
5257 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
5258 {
5259 EXPECT_GL_NO_ERROR();
5260
5261 GLTexture tex;
5262 glBindTexture(GL_TEXTURE_2D, tex);
5263 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
5264
5265 return (glGetError() == GL_NO_ERROR);
5266 }
5267
5268 void testBehavior(bool useSizedComponent)
5269 {
5270 int w = getWindowWidth();
5271 int h = getWindowHeight();
5272 GLuint format = GL_DEPTH_COMPONENT;
5273 GLuint internalFormat = GL_DEPTH_COMPONENT;
5274
5275 if (useSizedComponent)
5276 {
5277 internalFormat = GL_DEPTH_COMPONENT24;
5278 }
5279
5280 GLFramebuffer fbo;
5281 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5282 ASSERT_GL_NO_ERROR();
5283
5284 GLTexture depthTexture;
5285 glBindTexture(GL_TEXTURE_2D, depthTexture);
5286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5288 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5289 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5290
5291 TexCoordDrawTest::setUpProgram();
5292 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
5293 ASSERT_NE(-1, shadowMapLocation);
5294
5295 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
5296 ASSERT_NE(-1, positionLocation);
5297
5298 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
5299 glBindTexture(GL_TEXTURE_2D, depthTexture);
5300 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
5301 ASSERT_GL_NO_ERROR();
5302
5303 // try adding a color buffer.
5304 GLuint colorTex = 0;
5305 glGenTextures(1, &colorTex);
5306 glBindTexture(GL_TEXTURE_2D, colorTex);
5307 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5308 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5310 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5311 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5312 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
5313 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
5314 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5315 ASSERT_GL_NO_ERROR();
5316
5317 glViewport(0, 0, w, h);
5318 // Fill depthTexture with 0.75
5319 glClearDepthf(0.75);
5320 glClear(GL_DEPTH_BUFFER_BIT);
5321
5322 // Revert to normal framebuffer to test depth shader
5323 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5324 glViewport(0, 0, w, h);
5325 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5326 glClearDepthf(0.0f);
5327 ASSERT_GL_NO_ERROR();
5328
5329 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
5330 ASSERT_GL_NO_ERROR();
5331
5332 glActiveTexture(GL_TEXTURE0);
5333 glBindTexture(GL_TEXTURE_2D, depthTexture);
5334
5335 glUseProgram(mProgram);
5336 ASSERT_GL_NO_ERROR();
5337
5338 glUniform1i(shadowMapLocation, 0);
5339
5340 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
5341
5342 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
5343 ASSERT_GL_NO_ERROR();
5344 glEnableVertexAttribArray(positionLocation);
5345 ASSERT_GL_NO_ERROR();
5346 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5347 ASSERT_GL_NO_ERROR();
5348
5349 GLuint pixels[1];
5350 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
5351 ASSERT_GL_NO_ERROR();
5352
5353 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
5354 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
5355 // is in all the color components. Multiple implementations implement a workaround that
5356 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
5357 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
5358 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
5359 // depending on if it sees the texture sample in only the RED component.
5360 if (useSizedComponent)
5361 {
5362 ASSERT_NE(pixels[0], 0xff0000ff);
5363 }
5364 else
5365 {
5366 ASSERT_EQ(pixels[0], 0xff0000ff);
5367 }
5368
5369 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5370 glDeleteProgram(mProgram);
5371 }
5372};
5373
5374// Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
5375TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
5376{
5377 ANGLE_SKIP_TEST_IF(IsD3D11());
5378 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
Tobin Ehlis7af26762019-10-23 16:18:57 -06005379 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
5380 !IsGLExtensionEnabled("GL_OES_depth_texture"));
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005381 // http://anglebug.com/4092
5382 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01005383 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005384
5385 // When the depth texture is specified with unsized internalformat implementations follow
5386 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
5387 testBehavior(false);
5388}
5389
5390// Test depth texture compatibility with GLES3 using sized internalformat.
5391TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
5392{
5393 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
5394
5395 testBehavior(true);
5396}
5397
Jamie Madill7ffdda92016-09-08 13:26:51 -04005398// Tests unpacking into the unsized GL_ALPHA format.
5399TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
5400{
Jamie Madill7ffdda92016-09-08 13:26:51 -04005401 // Initialize the texure.
5402 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5403 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
5404 GL_UNSIGNED_BYTE, nullptr);
5405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5406 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5407
5408 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
5409
5410 // Pull in the color data from the unpack buffer.
Jamie Madill2e600342016-09-19 13:56:40 -04005411 GLBuffer unpackBuffer;
Jamie Madill7ffdda92016-09-08 13:26:51 -04005412 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5413 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5414 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
5415 GL_STATIC_DRAW);
5416
5417 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
5418 GL_UNSIGNED_BYTE, nullptr);
5419
5420 // Clear to a weird color to make sure we're drawing something.
5421 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
5422 glClear(GL_COLOR_BUFFER_BIT);
5423
5424 // Draw with the alpha texture and verify.
5425 drawQuad(mProgram, "position", 0.5f);
Jamie Madill7ffdda92016-09-08 13:26:51 -04005426
5427 ASSERT_GL_NO_ERROR();
5428 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
5429}
5430
Jamie Madill2e600342016-09-19 13:56:40 -04005431// Ensure stale unpack data doesn't propagate in D3D11.
5432TEST_P(Texture2DTestES3, StaleUnpackData)
5433{
5434 // Init unpack buffer.
5435 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
5436 std::vector<GLColor> pixels(pixelCount, GLColor::red);
5437
5438 GLBuffer unpackBuffer;
5439 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5440 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5441 GLsizei bufferSize = pixelCount * sizeof(GLColor);
5442 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
5443
5444 // Create from unpack buffer.
5445 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5446 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
5447 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5448 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5449 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5450
5451 drawQuad(mProgram, "position", 0.5f);
5452
5453 ASSERT_GL_NO_ERROR();
5454 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5455
5456 // Fill unpack with green, recreating buffer.
5457 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
5458 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
5459 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
5460
5461 // Reinit texture with green.
5462 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
5463 GL_UNSIGNED_BYTE, nullptr);
5464
5465 drawQuad(mProgram, "position", 0.5f);
5466
5467 ASSERT_GL_NO_ERROR();
5468 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5469}
5470
Geoff Langfb7685f2017-11-13 11:44:11 -05005471// Ensure that texture parameters passed as floats that are converted to ints are rounded before
5472// validating they are less than 0.
5473TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
5474{
5475 GLTexture texture;
5476 glBindTexture(GL_TEXTURE_2D, texture);
5477
5478 // Use a negative number that will round to zero when converted to an integer
5479 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
5480 // "Validation of values performed by state-setting commands is performed after conversion,
5481 // unless specified otherwise for a specific command."
5482 GLfloat param = -7.30157126e-07f;
5483 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
5484 EXPECT_GL_NO_ERROR();
5485
5486 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
5487 EXPECT_GL_NO_ERROR();
5488}
5489
Jamie Madillf097e232016-11-05 00:44:15 -04005490// This test covers a D3D format redefinition bug for 3D textures. The base level format was not
5491// being properly checked, and the texture storage of the previous texture format was persisting.
5492// This would result in an ASSERT in debug and incorrect rendering in release.
5493// See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
5494TEST_P(Texture3DTestES3, FormatRedefinitionBug)
5495{
5496 GLTexture tex;
5497 glBindTexture(GL_TEXTURE_3D, tex.get());
5498 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5499
5500 GLFramebuffer framebuffer;
5501 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
5502 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
5503
5504 glCheckFramebufferStatus(GL_FRAMEBUFFER);
5505
5506 std::vector<uint8_t> pixelData(100, 0);
5507
5508 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
5509 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
5510 pixelData.data());
5511
5512 ASSERT_GL_NO_ERROR();
5513}
5514
Corentin Wallezd2627992017-04-28 17:17:03 -04005515// Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
5516TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
5517{
5518 // 2D tests
5519 {
5520 GLTexture tex;
5521 glBindTexture(GL_TEXTURE_2D, tex.get());
5522
5523 GLBuffer pbo;
5524 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5525
5526 // Test OOB
5527 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
5528 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5529 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5530
5531 // Test OOB
5532 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
5533 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5534 ASSERT_GL_NO_ERROR();
5535 }
5536
5537 // 3D tests
5538 {
5539 GLTexture tex;
5540 glBindTexture(GL_TEXTURE_3D, tex.get());
5541
5542 GLBuffer pbo;
5543 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5544
5545 // Test OOB
5546 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
5547 GL_STATIC_DRAW);
5548 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5549 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5550
5551 // Test OOB
5552 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
5553 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5554 ASSERT_GL_NO_ERROR();
5555 }
5556}
5557
Jamie Madill3ed60422017-09-07 11:32:52 -04005558// Tests behaviour with a single texture and multiple sampler objects.
5559TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
5560{
5561 GLint maxTextureUnits = 0;
5562 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
5563 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
5564
5565 constexpr int kSize = 16;
5566
5567 // Make a single-level texture, fill it with red.
5568 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
5569 GLTexture tex;
5570 glBindTexture(GL_TEXTURE_2D, tex);
5571 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5572 redColors.data());
5573 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5574 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5575
5576 // Simple sanity check.
5577 draw2DTexturedQuad(0.5f, 1.0f, true);
5578 ASSERT_GL_NO_ERROR();
5579 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5580
5581 // Bind texture to unit 1 with a sampler object making it incomplete.
5582 GLSampler sampler;
5583 glBindSampler(0, sampler);
5584 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5585 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5586
5587 // Make a mipmap texture, fill it with blue.
5588 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
5589 GLTexture mipmapTex;
5590 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5591 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5592 blueColors.data());
5593 glGenerateMipmap(GL_TEXTURE_2D);
5594
5595 // Draw with the sampler, expect blue.
5596 draw2DTexturedQuad(0.5f, 1.0f, true);
5597 ASSERT_GL_NO_ERROR();
5598 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5599
5600 // Simple multitexturing program.
Jamie Madill35cd7332018-12-02 12:03:33 -05005601 constexpr char kVS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005602 "#version 300 es\n"
5603 "in vec2 position;\n"
5604 "out vec2 texCoord;\n"
5605 "void main()\n"
5606 "{\n"
5607 " gl_Position = vec4(position, 0, 1);\n"
5608 " texCoord = position * 0.5 + vec2(0.5);\n"
5609 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05005610
5611 constexpr char kFS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005612 "#version 300 es\n"
5613 "precision mediump float;\n"
5614 "in vec2 texCoord;\n"
5615 "uniform sampler2D tex1;\n"
5616 "uniform sampler2D tex2;\n"
5617 "uniform sampler2D tex3;\n"
5618 "uniform sampler2D tex4;\n"
5619 "out vec4 color;\n"
5620 "void main()\n"
5621 "{\n"
5622 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
5623 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
5624 "}";
5625
Jamie Madill35cd7332018-12-02 12:03:33 -05005626 ANGLE_GL_PROGRAM(program, kVS, kFS);
Jamie Madill3ed60422017-09-07 11:32:52 -04005627
5628 std::array<GLint, 4> texLocations = {
5629 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
5630 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
5631 for (GLint location : texLocations)
5632 {
5633 ASSERT_NE(-1, location);
5634 }
5635
5636 // Init the uniform data.
5637 glUseProgram(program);
5638 for (GLint location = 0; location < 4; ++location)
5639 {
5640 glUniform1i(texLocations[location], location);
5641 }
5642
5643 // Initialize four samplers
5644 GLSampler samplers[4];
5645
5646 // 0: non-mipped.
5647 glBindSampler(0, samplers[0]);
5648 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5649 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5650
5651 // 1: mipped.
5652 glBindSampler(1, samplers[1]);
5653 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5654 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5655
5656 // 2: non-mipped.
5657 glBindSampler(2, samplers[2]);
5658 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5659 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5660
5661 // 3: mipped.
5662 glBindSampler(3, samplers[3]);
5663 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5664 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5665
5666 // Bind two blue mipped textures and two single layer textures, should all draw.
5667 glActiveTexture(GL_TEXTURE0);
5668 glBindTexture(GL_TEXTURE_2D, tex);
5669
5670 glActiveTexture(GL_TEXTURE1);
5671 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5672
5673 glActiveTexture(GL_TEXTURE2);
5674 glBindTexture(GL_TEXTURE_2D, tex);
5675
5676 glActiveTexture(GL_TEXTURE3);
5677 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5678
5679 ASSERT_GL_NO_ERROR();
5680
5681 drawQuad(program, "position", 0.5f);
5682 ASSERT_GL_NO_ERROR();
5683 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
5684
5685 // Bind four single layer textures, two should be incomplete.
5686 glActiveTexture(GL_TEXTURE1);
5687 glBindTexture(GL_TEXTURE_2D, tex);
5688
5689 glActiveTexture(GL_TEXTURE3);
5690 glBindTexture(GL_TEXTURE_2D, tex);
5691
5692 drawQuad(program, "position", 0.5f);
5693 ASSERT_GL_NO_ERROR();
5694 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
5695}
5696
Martin Radev7e2c0d32017-09-15 14:25:42 +03005697// The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
5698// always at level 0 instead of the base level resulting in an incomplete texture if the faces at
5699// level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
5700// level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
5701// samples the cubemap using a direction vector (1,1,1).
5702TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
5703{
Yunchao He2f23f352018-02-11 22:11:37 +08005704 // Check http://anglebug.com/2155.
5705 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
5706
Jamie Madill35cd7332018-12-02 12:03:33 -05005707 constexpr char kVS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005708 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005709 precision mediump float;
5710 in vec3 pos;
5711 void main() {
5712 gl_Position = vec4(pos, 1.0);
5713 })";
Martin Radev7e2c0d32017-09-15 14:25:42 +03005714
Jamie Madill35cd7332018-12-02 12:03:33 -05005715 constexpr char kFS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005716 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005717 precision mediump float;
5718 out vec4 color;
5719 uniform samplerCube uTex;
5720 void main(){
5721 color = texture(uTex, vec3(1.0));
5722 })";
Jamie Madill35cd7332018-12-02 12:03:33 -05005723
5724 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev7e2c0d32017-09-15 14:25:42 +03005725 glUseProgram(program);
5726
5727 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
5728 glActiveTexture(GL_TEXTURE0);
5729
5730 GLTexture cubeTex;
5731 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
5732
5733 const int kFaceWidth = 1;
5734 const int kFaceHeight = 1;
5735 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
5736 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5737 GL_UNSIGNED_BYTE, texData.data());
5738 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5739 GL_UNSIGNED_BYTE, texData.data());
5740 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5741 GL_UNSIGNED_BYTE, texData.data());
5742 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5743 GL_UNSIGNED_BYTE, texData.data());
5744 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5745 GL_UNSIGNED_BYTE, texData.data());
5746 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5747 GL_UNSIGNED_BYTE, texData.data());
5748 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5749 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5750 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
5751 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
5752 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
5753 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
5754
5755 drawQuad(program, "pos", 0.5f, 1.0f, true);
5756 ASSERT_GL_NO_ERROR();
5757
5758 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5759}
5760
Jiawei Shao3c43b4d2018-02-23 11:08:28 +08005761// Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
5762TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
5763{
5764 GLuint texture = create2DTexture();
5765
5766 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
5767 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5768
5769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
5770 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5771
5772 glDeleteTextures(1, &texture);
5773 EXPECT_GL_NO_ERROR();
5774}
5775
Olli Etuaho023371b2018-04-24 17:43:32 +03005776// Test setting base level after calling generateMipmap on a LUMA texture.
5777// Covers http://anglebug.com/2498
5778TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
5779{
5780 glActiveTexture(GL_TEXTURE0);
5781 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5782
5783 constexpr const GLsizei kWidth = 8;
5784 constexpr const GLsizei kHeight = 8;
5785 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
5786 whiteData.fill(255u);
5787
5788 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
5789 GL_UNSIGNED_BYTE, whiteData.data());
5790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
5791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5792 glGenerateMipmap(GL_TEXTURE_2D);
5793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5794 EXPECT_GL_NO_ERROR();
5795
5796 drawQuad(mProgram, "position", 0.5f);
5797 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5798}
5799
Till Rathmannc1551dc2018-08-15 17:04:49 +02005800// Covers a bug in the D3D11 backend: http://anglebug.com/2772
5801// When using a sampler the texture was created as if it has mipmaps,
5802// regardless what you specified in GL_TEXTURE_MIN_FILTER via
5803// glSamplerParameteri() -- mistakenly the default value
5804// GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
5805// evaluated.
5806// If you didn't provide mipmaps and didn't let the driver generate them
5807// this led to not sampling your texture data when minification occurred.
5808TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
5809{
Cody Northrop988f7172019-09-30 15:52:37 -06005810 // TODO: Triage this failure on Vulkan: http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005811 ANGLE_SKIP_TEST_IF(IsVulkan());
5812
Jamie Madill35cd7332018-12-02 12:03:33 -05005813 constexpr char kVS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005814 "#version 300 es\n"
5815 "out vec2 texcoord;\n"
5816 "in vec4 position;\n"
5817 "void main()\n"
5818 "{\n"
5819 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
5820 " texcoord = (position.xy * 0.5) + 0.5;\n"
5821 "}\n";
5822
Jamie Madill35cd7332018-12-02 12:03:33 -05005823 constexpr char kFS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005824 "#version 300 es\n"
5825 "precision highp float;\n"
5826 "uniform highp sampler2D tex;\n"
5827 "in vec2 texcoord;\n"
5828 "out vec4 fragColor;\n"
5829 "void main()\n"
5830 "{\n"
5831 " fragColor = texture(tex, texcoord);\n"
5832 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -05005833
5834 ANGLE_GL_PROGRAM(program, kVS, kFS);
Till Rathmannc1551dc2018-08-15 17:04:49 +02005835
5836 GLSampler sampler;
5837 glBindSampler(0, sampler);
5838 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5839 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5840
5841 glActiveTexture(GL_TEXTURE0);
5842 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5843
5844 const GLsizei texWidth = getWindowWidth();
5845 const GLsizei texHeight = getWindowHeight();
5846 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
5847
5848 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5849 whiteData.data());
5850 EXPECT_GL_NO_ERROR();
5851
5852 drawQuad(program, "position", 0.5f);
5853 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
5854}
5855
Anders Leinof6cbe442019-04-18 15:32:07 +03005856// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5857// texture is output.
5858TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
5859{
Yuly Novikovd2683452019-05-23 16:11:19 -04005860 // http://anglebug.com/3478
5861 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5862
Anders Leinof6cbe442019-04-18 15:32:07 +03005863 glActiveTexture(GL_TEXTURE0);
5864 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5865 int width = getWindowWidth();
5866 int height = getWindowHeight();
5867 GLColor color = GLColor::green;
5868 std::vector<GLColor> pixels(width * height, color);
5869 GLint baseLevel = 1;
5870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5871 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5872 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5873 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5874 GL_UNSIGNED_BYTE, pixels.data());
5875
5876 setUpProgram();
5877 glUseProgram(mProgram);
5878 glUniform1i(mTexture2DUniformLocation, 0);
5879 drawQuad(mProgram, "position", 0.5f);
5880
5881 EXPECT_GL_NO_ERROR();
5882 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5883 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5884}
5885
Anders Leino60cc7512019-05-06 09:25:27 +03005886// Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
5887// the texture is output.
5888TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
5889{
5890 // All output checks returned black, rather than the texture color.
5891 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
5892
5893 glActiveTexture(GL_TEXTURE0);
5894
5895 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5896 GLint baseLevel = 1;
5897 int width = getWindowWidth();
5898 int height = getWindowHeight();
5899 GLColor color = GLColor::green;
5900 std::vector<GLColor> pixels(width * height, color);
5901 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5902 {
5903 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
5904 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5905 EXPECT_GL_NO_ERROR();
5906 }
5907 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
5908 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5909 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5910
5911 glUseProgram(mProgram);
5912 glUniform1i(mTextureCubeUniformLocation, 0);
5913 drawQuad(mProgram, "position", 0.5f);
5914
5915 EXPECT_GL_NO_ERROR();
5916 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5917 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
5918 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
5919 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5920}
5921
Anders Leinoe4452442019-05-09 13:29:49 +03005922// This test sets up a cube map with four distincly colored MIP levels.
5923// The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
5924// the corners of the screen.
5925TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
5926{
5927 glActiveTexture(GL_TEXTURE0);
5928
5929 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5930 int width = getWindowWidth();
5931 int height = getWindowHeight();
5932 ASSERT_EQ(width, height);
5933 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
5934 for (GLint level = 0; level < 4; level++)
5935 {
5936 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5937 {
5938 int levelWidth = (2 * width) >> level;
5939 int levelHeight = (2 * height) >> level;
5940 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
5941 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
5942 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5943 EXPECT_GL_NO_ERROR();
5944 }
5945 }
5946 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5947 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5948 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
5949
5950 glUseProgram(mProgram);
5951 glUniform1i(mTextureCubeUniformLocation, 0);
5952 drawQuad(mProgram, "position", 0.5f);
5953
5954 ASSERT_GL_NO_ERROR();
5955 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
5956 EXPECT_EQ(ReadColor(0, 0).R, 0);
5957 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
5958 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
5959 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
5960}
5961
Anders Leino1b6aded2019-05-20 12:56:34 +03005962// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5963// texture is output.
5964TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
5965{
Jamie Madill29ac2742019-05-28 15:53:00 -04005966 // Fails on AMD: http://crbug.com/967796
Jamie Madill06055b52019-05-29 14:31:42 -04005967 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
Jamie Madill29ac2742019-05-28 15:53:00 -04005968
Anders Leino1b6aded2019-05-20 12:56:34 +03005969 glActiveTexture(GL_TEXTURE0);
5970 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5971 int width = getWindowWidth();
5972 int height = getWindowHeight();
5973 GLColor color = GLColor::green;
5974 std::vector<GLColor> pixels(width * height, color);
5975 GLint baseLevel = 1;
5976 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5977 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5979 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5980 GL_UNSIGNED_BYTE, pixels.data());
5981
5982 setUpProgram();
5983 glUseProgram(mProgram);
5984 glUniform1i(mTexture2DUniformLocation, 0);
5985 drawQuad(mProgram, "position", 0.5f);
5986
5987 EXPECT_GL_NO_ERROR();
5988 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5989 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5990}
5991
Anders Leino69d04932019-05-20 14:04:13 +03005992// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5993// texture is output.
5994TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
5995{
5996 glActiveTexture(GL_TEXTURE0);
5997 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
5998 int width = getWindowWidth();
5999 int height = getWindowHeight();
6000 int depth = 2;
6001 GLColor color = GLColor::green;
6002 std::vector<GLColor> pixels(width * height * depth, color);
6003 GLint baseLevel = 1;
6004 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
6005 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
6006 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
6007 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6008 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6009
6010 drawQuad(mProgram, "position", 0.5f);
6011
6012 EXPECT_GL_NO_ERROR();
6013 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6014 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6015}
6016
Anders Leino262e2822019-05-20 14:24:40 +03006017// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
6018// texture is output.
6019TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
6020{
6021 glActiveTexture(GL_TEXTURE0);
6022 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6023 int width = getWindowWidth();
6024 int height = getWindowHeight();
6025 int depth = 2;
6026 GLColor color = GLColor::green;
6027 std::vector<GLColor> pixels(width * height * depth, color);
6028 GLint baseLevel = 1;
6029 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
6030 GL_UNSIGNED_BYTE, pixels.data());
6031 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6032 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6033 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6034
6035 drawQuad(mProgram, "position", 0.5f);
6036
6037 EXPECT_GL_NO_ERROR();
6038 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6039 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6040}
6041
Jamie Madillfc3ec572019-11-27 21:43:22 +00006042// Test that uses glCompressedTexSubImage2D combined with a PBO
6043TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
6044{
6045 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6046 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6047 // http://anglebug.com/4115
6048 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
6049 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
6050
6051 if (getClientMajorVersion() < 3)
6052 {
6053 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
6054 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
6055 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
6056 }
6057
6058 const GLuint width = 4u;
6059 const GLuint height = 4u;
6060
6061 setWindowWidth(width);
6062 setWindowHeight(height);
6063
6064 // Setup primary Texture
6065 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6066 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6067 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6068
6069 if (getClientMajorVersion() < 3)
6070 {
6071 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6072 }
6073 else
6074 {
6075 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6076 }
6077 ASSERT_GL_NO_ERROR();
6078
6079 // Setup PBO and fill it with a red
6080 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
6081 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
6082 ASSERT_GL_NO_ERROR();
6083
6084 // Write PBO to mTexture
6085 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
6086 width * height / 2u, nullptr);
6087 ASSERT_GL_NO_ERROR();
6088
6089 setUpProgram();
6090 // Draw using PBO updated texture
6091 glUseProgram(mProgram);
6092 glUniform1i(mTexture2DUniformLocation, 0);
6093 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6094 drawQuad(mProgram, "position", 0.5f);
6095 ASSERT_GL_NO_ERROR();
6096
6097 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6098 ASSERT_GL_NO_ERROR();
6099}
6100
Cody Northrop74e816b2020-03-26 17:40:25 -06006101// Test using ETC1_RGB8 with subimage updates
6102TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
6103{
6104 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6105 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6106
6107 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
6108 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
6109 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6110
6111 const GLuint width = 4u;
6112 const GLuint height = 4u;
6113
6114 setWindowWidth(width);
6115 setWindowHeight(height);
6116
6117 // Setup primary Texture
6118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6120
6121 if (getClientMajorVersion() < 3)
6122 {
6123 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6124 }
6125 else
6126 {
6127 glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6128 }
6129 ASSERT_GL_NO_ERROR();
6130
6131 // Populate a subimage of the texture
6132 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6133 width * height / 2u, kCompressedImageETC2);
6134 ASSERT_GL_NO_ERROR();
6135
6136 // Render and ensure we get red
6137 glUseProgram(mProgram);
6138 drawQuad(mProgram, "position", 0.5f);
6139 ASSERT_GL_NO_ERROR();
6140
6141 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6142 ASSERT_GL_NO_ERROR();
6143}
6144
Ian Elliotteba008a2020-05-05 10:46:21 -06006145// Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
6146// MAX_LEVEL and draw. This used to cause Vulkan validation errors.
6147TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
6148{
6149 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6150 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6151
6152 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
6153 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6154
6155 const GLuint width = 4u;
6156 const GLuint height = 4u;
6157
6158 setWindowWidth(width);
6159 setWindowHeight(height);
6160
6161 // Setup primary Texture
6162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6164
6165 if (getClientMajorVersion() < 3)
6166 {
6167 glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6168 }
6169 else
6170 {
6171 glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6172 }
6173 ASSERT_GL_NO_ERROR();
6174
6175 // Populate a subimage of the texture
6176 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6177 width * height / 2u, kCompressedImageETC2);
6178 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
6179 width * height / 2u, kCompressedImageETC2);
6180 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
6181 width * height / 2u, kCompressedImageETC2);
6182 ASSERT_GL_NO_ERROR();
6183
6184 // Set MAX_LEVEL to 2 (the highest level)
6185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6186
6187 // Render and ensure we get red
6188 glUseProgram(mProgram);
6189 drawQuad(mProgram, "position", 0.5f);
6190 ASSERT_GL_NO_ERROR();
6191 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6192 ASSERT_GL_NO_ERROR();
6193
6194 // Decrease MAX_LEVEL to 0, render, and ensure we still get red
6195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6196 drawQuad(mProgram, "position", 0.5f);
6197 ASSERT_GL_NO_ERROR();
6198 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6199 ASSERT_GL_NO_ERROR();
6200
6201 // Increase MAX_LEVEL back to 2, render, and ensure we still get red
6202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6203 drawQuad(mProgram, "position", 0.5f);
6204 ASSERT_GL_NO_ERROR();
6205 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6206 ASSERT_GL_NO_ERROR();
6207}
6208
Jamie Madill50cf2be2018-06-15 09:46:57 -04006209// Use this to select which configurations (e.g. which renderer, which GLES major version) these
6210// tests should be run against.
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006211ANGLE_INSTANTIATE_TEST_ES2(Texture2DTest);
6212ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
6213ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
6214ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
6215ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
6216ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
6217ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3);
6218ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
6219ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
6220ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
6221ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
6222ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
6223ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
6224ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
6225ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
6226ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
6227ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
6228ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
6229ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
6230ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
6231ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
6232ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
6233ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
6234ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
6235ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
6236ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DRGTest);
6237ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
6238ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
6239ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
6240ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
6241ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
6242ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
6243ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
6244ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
6245ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
6246ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
Jamie Madillfc3ec572019-11-27 21:43:22 +00006247ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
Cody Northrop74e816b2020-03-26 17:40:25 -06006248ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
Jamie Madillfa05f602015-05-07 13:47:11 -04006249
Jamie Madill7ffdda92016-09-08 13:26:51 -04006250} // anonymous namespace