blob: f9b71445f1ebd3bb604d47e1a6a8428fd5f35ff8 [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
Shahbaz Youssefidbb18b52020-06-05 15:23:17 -0400417class Texture2DBaseMaxTestES3 : public ANGLETest
418{
419 protected:
420 static constexpr size_t kMip0Size = 8;
421 static constexpr uint32_t kMipCount = 4;
422
423 Texture2DBaseMaxTestES3() : ANGLETest(), mTextureLocation(0), mLodLocation(0)
424 {
425 setWindowWidth(128);
426 setWindowHeight(128);
427 setConfigRedBits(8);
428 setConfigGreenBits(8);
429 setConfigBlueBits(8);
430 setConfigAlphaBits(8);
431 }
432
433 static constexpr size_t getMipDataSize(size_t mip0Size, size_t mip)
434 {
435 ASSERT(mip0Size % (1ull << mip) == 0);
436 return mip0Size * mip0Size / (1ull << (2 * mip));
437 }
438
439 static constexpr size_t getTotalMipDataSize(size_t mip0Size)
440 {
441 size_t totalCount = 0;
442 for (size_t mip = 0; mip < kMipCount; ++mip)
443 {
444 totalCount += getMipDataSize(mip0Size, mip);
445 }
446 return totalCount;
447 }
448
449 static constexpr size_t getMipDataOffset(size_t mip0Size, size_t mip)
450 {
451 // This calculates:
452 //
453 // mip == 0: 0
454 // o.w.: sum(0, mip-1) getMipDataSize(i)
455 //
456 // The above can be calculated simply as:
457 //
458 // (mip0 >> (kMipCount-1))^2 * (0x55555555 & ((1 << (2*mip)) - 1))
459 // \__________ ___________/ \_______________ ________________/
460 // \/ \/
461 // last mip size sum(0, mip-1) (4^i)
462 //
463 // But let's loop explicitly for clarity.
464 size_t offset = 0;
465 for (size_t m = 0; m < mip; ++m)
466 {
467 offset += getMipDataSize(mip0Size, m);
468 }
469 return offset;
470 }
471
472 void fillMipData(GLColor *data, size_t mip0Size, const GLColor mipColors[kMipCount])
473 {
474 for (size_t mip = 0; mip < kMipCount; ++mip)
475 {
476 size_t offset = getMipDataOffset(mip0Size, mip);
477 size_t size = getMipDataSize(mip0Size, mip);
478 std::fill(data + offset, data + offset + size, mipColors[mip]);
479 }
480 }
481
482 void initTest()
483 {
484 // Set up program to sample from specific lod level.
485 constexpr char kVS[] = R"(#version 300 es
486out vec2 texCoord;
487in vec4 position;
488void main()
489{
490 gl_Position = vec4(position.xy, 0.0, 1.0);
491 texCoord = position.xy * 0.5 + 0.5;
492})";
493
494 constexpr char kFS[] = R"(#version 300 es
495precision mediump float;
496out vec4 fragColor;
497in vec2 texCoord;
498uniform float lod;
499uniform sampler2D s;
500void main()
501{
502 fragColor = textureLod(s, texCoord, lod);
503})";
504
505 mProgram.makeRaster(kVS, kFS);
506 ASSERT(mProgram.valid());
507
508 glUseProgram(mProgram);
509
510 mTextureLocation = glGetUniformLocation(mProgram, "s");
511 ASSERT_NE(-1, mTextureLocation);
512
513 mLodLocation = glGetUniformLocation(mProgram, "lod");
514 ASSERT_NE(-1, mLodLocation);
515
516 // Set up texture with a handful of lods.
517 glActiveTexture(GL_TEXTURE0);
518 glBindTexture(GL_TEXTURE_2D, mTexture);
519
520 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
521 fillMipData(mipData.data(), kMip0Size, kMipColors);
522
523 for (size_t mip = 0; mip < kMipCount; ++mip)
524 {
525 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0,
526 GL_RGBA, GL_UNSIGNED_BYTE,
527 mipData.data() + getMipDataOffset(kMip0Size, mip));
528 }
529
530 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
531 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
532
533 EXPECT_GL_NO_ERROR();
534 }
535
536 void setLodUniform(uint32_t lod) { glUniform1f(mLodLocation, lod); }
537
538 GLProgram mProgram;
539 GLTexture mTexture;
540 GLint mTextureLocation;
541 GLint mLodLocation;
542
543 const GLColor kMipColors[kMipCount] = {
544 GLColor::red,
545 GLColor::green,
546 GLColor::blue,
547 GLColor::magenta,
548 };
549};
550
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200551class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
552{
553 protected:
554 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
555
Jamie Madill35cd7332018-12-02 12:03:33 -0500556 const char *getVertexShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200557 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500558 return "#version 300 es\n"
559 "out vec2 texcoord;\n"
560 "in vec4 position;\n"
561 "void main()\n"
562 "{\n"
563 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
564 " texcoord = (position.xy * 0.5) + 0.5;\n"
565 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200566 }
567
Jamie Madill35cd7332018-12-02 12:03:33 -0500568 const char *getFragmentShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200569 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500570 return "#version 300 es\n"
571 "precision highp float;\n"
572 "uniform highp isampler2D tex;\n"
573 "in vec2 texcoord;\n"
574 "out vec4 fragColor;\n"
575 "void main()\n"
576 "{\n"
577 " vec4 green = vec4(0, 1, 0, 1);\n"
578 " vec4 black = vec4(0, 0, 0, 0);\n"
579 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
580 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200581 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300582
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400583 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300584 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400585 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300586 setUpProgram();
587 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200588};
589
590class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
591{
592 protected:
593 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
594
Jamie Madill35cd7332018-12-02 12:03:33 -0500595 const char *getVertexShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200596 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500597 return "#version 300 es\n"
598 "out vec2 texcoord;\n"
599 "in vec4 position;\n"
600 "void main()\n"
601 "{\n"
602 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
603 " texcoord = (position.xy * 0.5) + 0.5;\n"
604 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200605 }
606
Jamie Madill35cd7332018-12-02 12:03:33 -0500607 const char *getFragmentShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200608 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500609 return "#version 300 es\n"
610 "precision highp float;\n"
611 "uniform highp usampler2D tex;\n"
612 "in vec2 texcoord;\n"
613 "out vec4 fragColor;\n"
614 "void main()\n"
615 "{\n"
616 " vec4 green = vec4(0, 1, 0, 1);\n"
617 " vec4 black = vec4(0, 0, 0, 0);\n"
618 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
619 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200620 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300621
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400622 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300623 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400624 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300625 setUpProgram();
626 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200627};
628
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200629class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400630{
631 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200632 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
633
Jamie Madill35cd7332018-12-02 12:03:33 -0500634 const char *getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400635 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300636 return
637 R"(precision highp float;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200638 attribute vec4 position;
639 varying vec2 texcoord;
640
641 uniform vec2 drawScale;
642
643 void main()
644 {
645 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
646 texcoord = (position.xy * 0.5) + 0.5;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300647 })";
Jamie Madill2453dbc2015-07-14 11:35:42 -0400648 }
649
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400650 void testSetUp() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400651 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400652 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300653
654 setUpProgram();
655
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200656 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
657 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400658
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200659 glUseProgram(mProgram);
660 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
661 glUseProgram(0);
662 ASSERT_GL_NO_ERROR();
663 }
664
665 GLint mDrawScaleUniformLocation;
666};
667
Olli Etuaho4644a202016-01-12 15:12:53 +0200668class Sampler2DAsFunctionParameterTest : public Texture2DTest
669{
670 protected:
671 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
672
Jamie Madill35cd7332018-12-02 12:03:33 -0500673 const char *getFragmentShaderSource() override
Olli Etuaho4644a202016-01-12 15:12:53 +0200674 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300675 return
676 R"(precision highp float;
Olli Etuaho4644a202016-01-12 15:12:53 +0200677 uniform sampler2D tex;
678 varying vec2 texcoord;
679
680 vec4 computeFragColor(sampler2D aTex)
681 {
682 return texture2D(aTex, texcoord);
683 }
684
685 void main()
686 {
687 gl_FragColor = computeFragColor(tex);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300688 })";
Olli Etuaho4644a202016-01-12 15:12:53 +0200689 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300690
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400691 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300692 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400693 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300694 setUpProgram();
695 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200696};
697
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200698class TextureCubeTest : public TexCoordDrawTest
699{
700 protected:
701 TextureCubeTest()
702 : TexCoordDrawTest(),
703 mTexture2D(0),
704 mTextureCube(0),
705 mTexture2DUniformLocation(-1),
706 mTextureCubeUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500707 {}
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200708
Jamie Madill35cd7332018-12-02 12:03:33 -0500709 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200710 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300711 return
712 R"(precision highp float;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200713 uniform sampler2D tex2D;
714 uniform samplerCube texCube;
715 varying vec2 texcoord;
716
717 void main()
718 {
719 gl_FragColor = texture2D(tex2D, texcoord);
720 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300721 })";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200722 }
723
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400724 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200725 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400726 TexCoordDrawTest::testSetUp();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200727
728 glGenTextures(1, &mTextureCube);
729 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Geoff Langc4e93662017-05-01 10:45:59 -0400730 for (GLenum face = 0; face < 6; face++)
731 {
732 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
733 GL_UNSIGNED_BYTE, nullptr);
734 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200735 EXPECT_GL_NO_ERROR();
736
737 mTexture2D = create2DTexture();
738
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300739 setUpProgram();
740
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200741 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
742 ASSERT_NE(-1, mTexture2DUniformLocation);
743 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
744 ASSERT_NE(-1, mTextureCubeUniformLocation);
745 }
746
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400747 void testTearDown() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200748 {
749 glDeleteTextures(1, &mTextureCube);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400750 TexCoordDrawTest::testTearDown();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200751 }
752
753 GLuint mTexture2D;
754 GLuint mTextureCube;
755 GLint mTexture2DUniformLocation;
756 GLint mTextureCubeUniformLocation;
757};
758
Martin Radev7e2c0d32017-09-15 14:25:42 +0300759class TextureCubeTestES3 : public ANGLETest
760{
761 protected:
762 TextureCubeTestES3() {}
763};
764
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200765class SamplerArrayTest : public TexCoordDrawTest
766{
767 protected:
768 SamplerArrayTest()
769 : TexCoordDrawTest(),
770 mTexture2DA(0),
771 mTexture2DB(0),
772 mTexture0UniformLocation(-1),
773 mTexture1UniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500774 {}
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200775
Jamie Madill35cd7332018-12-02 12:03:33 -0500776 const char *getFragmentShaderSource() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200777 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300778 return
779 R"(precision mediump float;
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200780 uniform highp sampler2D tex2DArray[2];
781 varying vec2 texcoord;
782 void main()
783 {
784 gl_FragColor = texture2D(tex2DArray[0], texcoord);
785 gl_FragColor += texture2D(tex2DArray[1], texcoord);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300786 })";
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200787 }
788
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400789 void testSetUp() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200790 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400791 TexCoordDrawTest::testSetUp();
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200792
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300793 setUpProgram();
794
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200795 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
796 ASSERT_NE(-1, mTexture0UniformLocation);
797 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
798 ASSERT_NE(-1, mTexture1UniformLocation);
799
800 mTexture2DA = create2DTexture();
801 mTexture2DB = create2DTexture();
802 ASSERT_GL_NO_ERROR();
803 }
804
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400805 void testTearDown() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200806 {
807 glDeleteTextures(1, &mTexture2DA);
808 glDeleteTextures(1, &mTexture2DB);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400809 TexCoordDrawTest::testTearDown();
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200810 }
811
812 void testSamplerArrayDraw()
813 {
814 GLubyte texData[4];
815 texData[0] = 0;
816 texData[1] = 60;
817 texData[2] = 0;
818 texData[3] = 255;
819
820 glActiveTexture(GL_TEXTURE0);
821 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
822 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
823
824 texData[1] = 120;
825 glActiveTexture(GL_TEXTURE1);
826 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
827 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
828 EXPECT_GL_ERROR(GL_NO_ERROR);
829
830 glUseProgram(mProgram);
831 glUniform1i(mTexture0UniformLocation, 0);
832 glUniform1i(mTexture1UniformLocation, 1);
833 drawQuad(mProgram, "position", 0.5f);
834 EXPECT_GL_NO_ERROR();
835
836 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
837 }
838
839 GLuint mTexture2DA;
840 GLuint mTexture2DB;
841 GLint mTexture0UniformLocation;
842 GLint mTexture1UniformLocation;
843};
844
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200845class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
846{
847 protected:
848 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
849
Jamie Madill35cd7332018-12-02 12:03:33 -0500850 const char *getFragmentShaderSource() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200851 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300852 return
853 R"(precision mediump float;
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200854 uniform highp sampler2D tex2DArray[2];
855 varying vec2 texcoord;
856
857 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
858 {
859 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
860 }
861
862 void main()
863 {
864 gl_FragColor = computeFragColor(tex2DArray);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300865 })";
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200866 }
867};
868
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200869class Texture2DArrayTestES3 : public TexCoordDrawTest
870{
871 protected:
872 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
873
Jamie Madill35cd7332018-12-02 12:03:33 -0500874 const char *getVertexShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200875 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500876 return "#version 300 es\n"
877 "out vec2 texcoord;\n"
878 "in vec4 position;\n"
879 "void main()\n"
880 "{\n"
881 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
882 " texcoord = (position.xy * 0.5) + 0.5;\n"
883 "}\n";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200884 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400885
Jamie Madill35cd7332018-12-02 12:03:33 -0500886 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200887 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500888 return "#version 300 es\n"
889 "precision highp float;\n"
890 "uniform highp sampler2DArray tex2DArray;\n"
891 "in vec2 texcoord;\n"
892 "out vec4 fragColor;\n"
893 "void main()\n"
894 "{\n"
895 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
896 "}\n";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200897 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400898
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400899 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200900 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400901 TexCoordDrawTest::testSetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400902
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300903 setUpProgram();
904
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200905 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400906 ASSERT_NE(-1, mTextureArrayLocation);
907
908 glGenTextures(1, &m2DArrayTexture);
909 ASSERT_GL_NO_ERROR();
910 }
911
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400912 void testTearDown() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400913 {
914 glDeleteTextures(1, &m2DArrayTexture);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400915 TexCoordDrawTest::testTearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400916 }
917
918 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400919 GLint mTextureArrayLocation;
920};
921
Olli Etuahobce743a2016-01-15 17:18:28 +0200922class TextureSizeTextureArrayTest : public TexCoordDrawTest
923{
924 protected:
925 TextureSizeTextureArrayTest()
926 : TexCoordDrawTest(),
927 mTexture2DA(0),
928 mTexture2DB(0),
929 mTexture0Location(-1),
930 mTexture1Location(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500931 {}
Olli Etuahobce743a2016-01-15 17:18:28 +0200932
Jamie Madill35cd7332018-12-02 12:03:33 -0500933 const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
Olli Etuahobce743a2016-01-15 17:18:28 +0200934
Jamie Madill35cd7332018-12-02 12:03:33 -0500935 const char *getFragmentShaderSource() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200936 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500937 return "#version 300 es\n"
938 "precision highp float;\n"
939 "uniform highp sampler2D tex2DArray[2];\n"
940 "out vec4 fragColor;\n"
941 "void main()\n"
942 "{\n"
943 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
944 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
945 " fragColor = vec4(red, green, 0.0, 1.0);\n"
946 "}\n";
Olli Etuahobce743a2016-01-15 17:18:28 +0200947 }
948
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400949 void testSetUp() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200950 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400951 TexCoordDrawTest::testSetUp();
Olli Etuahobce743a2016-01-15 17:18:28 +0200952
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300953 setUpProgram();
954
Olli Etuahobce743a2016-01-15 17:18:28 +0200955 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
956 ASSERT_NE(-1, mTexture0Location);
957 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
958 ASSERT_NE(-1, mTexture1Location);
959
960 mTexture2DA = create2DTexture();
961 mTexture2DB = create2DTexture();
962 ASSERT_GL_NO_ERROR();
963 }
964
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400965 void testTearDown() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200966 {
967 glDeleteTextures(1, &mTexture2DA);
968 glDeleteTextures(1, &mTexture2DB);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400969 TexCoordDrawTest::testTearDown();
Olli Etuahobce743a2016-01-15 17:18:28 +0200970 }
971
972 GLuint mTexture2DA;
973 GLuint mTexture2DB;
974 GLint mTexture0Location;
975 GLint mTexture1Location;
976};
977
Olli Etuahoa314b612016-03-10 16:43:00 +0200978class Texture3DTestES3 : public TexCoordDrawTest
979{
980 protected:
981 Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
982
Jamie Madill35cd7332018-12-02 12:03:33 -0500983 const char *getVertexShaderSource() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200984 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500985 return "#version 300 es\n"
986 "out vec2 texcoord;\n"
987 "in vec4 position;\n"
988 "void main()\n"
989 "{\n"
990 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
991 " texcoord = (position.xy * 0.5) + 0.5;\n"
992 "}\n";
Olli Etuahoa314b612016-03-10 16:43:00 +0200993 }
994
Jamie Madill35cd7332018-12-02 12:03:33 -0500995 const char *getFragmentShaderSource() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200996 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500997 return "#version 300 es\n"
998 "precision highp float;\n"
999 "uniform highp sampler3D tex3D;\n"
1000 "in vec2 texcoord;\n"
1001 "out vec4 fragColor;\n"
1002 "void main()\n"
1003 "{\n"
1004 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
1005 "}\n";
Olli Etuahoa314b612016-03-10 16:43:00 +02001006 }
1007
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001008 void testSetUp() override
Olli Etuahoa314b612016-03-10 16:43:00 +02001009 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001010 TexCoordDrawTest::testSetUp();
Olli Etuahoa314b612016-03-10 16:43:00 +02001011
1012 glGenTextures(1, &mTexture3D);
1013
1014 setUpProgram();
1015
1016 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1017 ASSERT_NE(-1, mTexture3DUniformLocation);
1018 }
1019
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001020 void testTearDown() override
Olli Etuahoa314b612016-03-10 16:43:00 +02001021 {
1022 glDeleteTextures(1, &mTexture3D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001023 TexCoordDrawTest::testTearDown();
Olli Etuahoa314b612016-03-10 16:43:00 +02001024 }
1025
1026 GLuint mTexture3D;
1027 GLint mTexture3DUniformLocation;
1028};
1029
Olli Etuaho1a679902016-01-14 12:21:47 +02001030class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
1031{
1032 protected:
1033 ShadowSamplerPlusSampler3DTestES3()
1034 : TexCoordDrawTest(),
1035 mTextureShadow(0),
1036 mTexture3D(0),
1037 mTextureShadowUniformLocation(-1),
1038 mTexture3DUniformLocation(-1),
1039 mDepthRefUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -05001040 {}
Olli Etuaho1a679902016-01-14 12:21:47 +02001041
Jamie Madill35cd7332018-12-02 12:03:33 -05001042 const char *getVertexShaderSource() override
Olli Etuaho1a679902016-01-14 12:21:47 +02001043 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001044 return "#version 300 es\n"
1045 "out vec2 texcoord;\n"
1046 "in vec4 position;\n"
1047 "void main()\n"
1048 "{\n"
1049 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1050 " texcoord = (position.xy * 0.5) + 0.5;\n"
1051 "}\n";
Olli Etuaho1a679902016-01-14 12:21:47 +02001052 }
1053
Jamie Madill35cd7332018-12-02 12:03:33 -05001054 const char *getFragmentShaderSource() override
Olli Etuaho1a679902016-01-14 12:21:47 +02001055 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001056 return "#version 300 es\n"
1057 "precision highp float;\n"
1058 "uniform highp sampler2DShadow tex2DShadow;\n"
1059 "uniform highp sampler3D tex3D;\n"
1060 "in vec2 texcoord;\n"
1061 "uniform float depthRef;\n"
1062 "out vec4 fragColor;\n"
1063 "void main()\n"
1064 "{\n"
1065 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
1066 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
1067 "}\n";
Olli Etuaho1a679902016-01-14 12:21:47 +02001068 }
1069
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001070 void testSetUp() override
Olli Etuaho1a679902016-01-14 12:21:47 +02001071 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001072 TexCoordDrawTest::testSetUp();
Olli Etuaho1a679902016-01-14 12:21:47 +02001073
1074 glGenTextures(1, &mTexture3D);
1075
1076 glGenTextures(1, &mTextureShadow);
1077 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
1078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1079
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001080 setUpProgram();
1081
Olli Etuaho1a679902016-01-14 12:21:47 +02001082 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1083 ASSERT_NE(-1, mTextureShadowUniformLocation);
1084 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
1085 ASSERT_NE(-1, mTexture3DUniformLocation);
1086 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1087 ASSERT_NE(-1, mDepthRefUniformLocation);
1088 }
1089
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001090 void testTearDown() override
Olli Etuaho1a679902016-01-14 12:21:47 +02001091 {
1092 glDeleteTextures(1, &mTextureShadow);
1093 glDeleteTextures(1, &mTexture3D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001094 TexCoordDrawTest::testTearDown();
Olli Etuaho1a679902016-01-14 12:21:47 +02001095 }
1096
1097 GLuint mTextureShadow;
1098 GLuint mTexture3D;
1099 GLint mTextureShadowUniformLocation;
1100 GLint mTexture3DUniformLocation;
1101 GLint mDepthRefUniformLocation;
1102};
1103
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001104class SamplerTypeMixTestES3 : public TexCoordDrawTest
1105{
1106 protected:
1107 SamplerTypeMixTestES3()
1108 : TexCoordDrawTest(),
1109 mTexture2D(0),
1110 mTextureCube(0),
1111 mTexture2DShadow(0),
1112 mTextureCubeShadow(0),
1113 mTexture2DUniformLocation(-1),
1114 mTextureCubeUniformLocation(-1),
1115 mTexture2DShadowUniformLocation(-1),
1116 mTextureCubeShadowUniformLocation(-1),
1117 mDepthRefUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -05001118 {}
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001119
Jamie Madill35cd7332018-12-02 12:03:33 -05001120 const char *getVertexShaderSource() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001121 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001122 return "#version 300 es\n"
1123 "out vec2 texcoord;\n"
1124 "in vec4 position;\n"
1125 "void main()\n"
1126 "{\n"
1127 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1128 " texcoord = (position.xy * 0.5) + 0.5;\n"
1129 "}\n";
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001130 }
1131
Jamie Madill35cd7332018-12-02 12:03:33 -05001132 const char *getFragmentShaderSource() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001133 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001134 return "#version 300 es\n"
1135 "precision highp float;\n"
1136 "uniform highp sampler2D tex2D;\n"
1137 "uniform highp samplerCube texCube;\n"
1138 "uniform highp sampler2DShadow tex2DShadow;\n"
1139 "uniform highp samplerCubeShadow texCubeShadow;\n"
1140 "in vec2 texcoord;\n"
1141 "uniform float depthRef;\n"
1142 "out vec4 fragColor;\n"
1143 "void main()\n"
1144 "{\n"
1145 " fragColor = texture(tex2D, texcoord);\n"
1146 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1147 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1148 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1149 "0.125);\n"
1150 "}\n";
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001151 }
1152
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001153 void testSetUp() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001154 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001155 TexCoordDrawTest::testSetUp();
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001156
1157 glGenTextures(1, &mTexture2D);
1158 glGenTextures(1, &mTextureCube);
1159
1160 glGenTextures(1, &mTexture2DShadow);
1161 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1163
1164 glGenTextures(1, &mTextureCubeShadow);
1165 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1166 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1167
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001168 setUpProgram();
1169
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001170 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1171 ASSERT_NE(-1, mTexture2DUniformLocation);
1172 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1173 ASSERT_NE(-1, mTextureCubeUniformLocation);
1174 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1175 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1176 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1177 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1178 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1179 ASSERT_NE(-1, mDepthRefUniformLocation);
1180
1181 ASSERT_GL_NO_ERROR();
1182 }
1183
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001184 void testTearDown() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001185 {
1186 glDeleteTextures(1, &mTexture2D);
1187 glDeleteTextures(1, &mTextureCube);
1188 glDeleteTextures(1, &mTexture2DShadow);
1189 glDeleteTextures(1, &mTextureCubeShadow);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001190 TexCoordDrawTest::testTearDown();
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001191 }
1192
1193 GLuint mTexture2D;
1194 GLuint mTextureCube;
1195 GLuint mTexture2DShadow;
1196 GLuint mTextureCubeShadow;
1197 GLint mTexture2DUniformLocation;
1198 GLint mTextureCubeUniformLocation;
1199 GLint mTexture2DShadowUniformLocation;
1200 GLint mTextureCubeShadowUniformLocation;
1201 GLint mDepthRefUniformLocation;
1202};
1203
Olli Etuaho96963162016-03-21 11:54:33 +02001204class SamplerInStructTest : public Texture2DTest
1205{
1206 protected:
1207 SamplerInStructTest() : Texture2DTest() {}
1208
1209 const char *getTextureUniformName() override { return "us.tex"; }
1210
Jamie Madill35cd7332018-12-02 12:03:33 -05001211 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001212 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001213 return "precision highp float;\n"
1214 "struct S\n"
1215 "{\n"
1216 " vec4 a;\n"
1217 " highp sampler2D tex;\n"
1218 "};\n"
1219 "uniform S us;\n"
1220 "varying vec2 texcoord;\n"
1221 "void main()\n"
1222 "{\n"
1223 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1224 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001225 }
1226
1227 void runSamplerInStructTest()
1228 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001229 setUpProgram();
1230
Olli Etuaho96963162016-03-21 11:54:33 +02001231 glActiveTexture(GL_TEXTURE0);
1232 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001233 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1234 &GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001235 drawQuad(mProgram, "position", 0.5f);
Olli Etuahoa314b612016-03-10 16:43:00 +02001236 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001237 }
1238};
1239
1240class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1241{
1242 protected:
1243 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1244
Jamie Madill35cd7332018-12-02 12:03:33 -05001245 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001246 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001247 return "precision highp float;\n"
1248 "struct S\n"
1249 "{\n"
1250 " vec4 a;\n"
1251 " highp sampler2D tex;\n"
1252 "};\n"
1253 "uniform S us;\n"
1254 "varying vec2 texcoord;\n"
1255 "vec4 sampleFrom(S s) {\n"
1256 " return texture2D(s.tex, texcoord + s.a.x);\n"
1257 "}\n"
1258 "void main()\n"
1259 "{\n"
1260 " gl_FragColor = sampleFrom(us);\n"
1261 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001262 }
1263};
1264
1265class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1266{
1267 protected:
1268 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1269
1270 const char *getTextureUniformName() override { return "us[0].tex"; }
1271
Jamie Madill35cd7332018-12-02 12:03:33 -05001272 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001273 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001274 return "precision highp float;\n"
1275 "struct S\n"
1276 "{\n"
1277 " vec4 a;\n"
1278 " highp sampler2D tex;\n"
1279 "};\n"
1280 "uniform S us[1];\n"
1281 "varying vec2 texcoord;\n"
1282 "vec4 sampleFrom(S s) {\n"
1283 " return texture2D(s.tex, texcoord + s.a.x);\n"
1284 "}\n"
1285 "void main()\n"
1286 "{\n"
1287 " gl_FragColor = sampleFrom(us[0]);\n"
1288 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001289 }
1290};
1291
1292class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1293{
1294 protected:
1295 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1296
1297 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1298
Jamie Madill35cd7332018-12-02 12:03:33 -05001299 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001300 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001301 return "precision highp float;\n"
1302 "struct SUB\n"
1303 "{\n"
1304 " vec4 a;\n"
1305 " highp sampler2D tex;\n"
1306 "};\n"
1307 "struct S\n"
1308 "{\n"
1309 " SUB sub;\n"
1310 "};\n"
1311 "uniform S us[1];\n"
1312 "varying vec2 texcoord;\n"
1313 "vec4 sampleFrom(SUB s) {\n"
1314 " return texture2D(s.tex, texcoord + s.a.x);\n"
1315 "}\n"
1316 "void main()\n"
1317 "{\n"
1318 " gl_FragColor = sampleFrom(us[0].sub);\n"
1319 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001320 }
1321};
1322
1323class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1324{
1325 protected:
1326 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1327
Jamie Madill35cd7332018-12-02 12:03:33 -05001328 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001329 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001330 return "precision highp float;\n"
1331 "struct S\n"
1332 "{\n"
1333 " vec4 a;\n"
1334 " highp sampler2D tex;\n"
1335 "};\n"
1336 "uniform S us;\n"
1337 "uniform float us_tex;\n"
1338 "varying vec2 texcoord;\n"
1339 "void main()\n"
1340 "{\n"
1341 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1342 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001343 }
1344};
1345
Anders Leinof6cbe442019-04-18 15:32:07 +03001346class Texture2DIntegerTestES3 : public Texture2DTest
1347{
1348 protected:
1349 Texture2DIntegerTestES3() : Texture2DTest() {}
1350
1351 const char *getVertexShaderSource() override
1352 {
1353 return "#version 300 es\n"
1354 "out vec2 texcoord;\n"
1355 "in vec4 position;\n"
1356 "void main()\n"
1357 "{\n"
1358 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1359 " texcoord = (position.xy * 0.5) + 0.5;\n"
1360 "}\n";
1361 }
1362
1363 const char *getFragmentShaderSource() override
1364 {
1365 return "#version 300 es\n"
1366 "precision highp float;\n"
1367 "precision highp usampler2D;\n"
1368 "uniform usampler2D tex;\n"
1369 "in vec2 texcoord;\n"
1370 "out vec4 fragColor;\n"
1371 "void main()\n"
1372 "{\n"
Anders Leino8224a582019-05-20 12:39:29 +03001373 " fragColor = vec4(texture(tex, texcoord))/255.0;\n"
Anders Leinof6cbe442019-04-18 15:32:07 +03001374 "}\n";
1375 }
1376};
1377
Anders Leino60cc7512019-05-06 09:25:27 +03001378class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1379{
1380 protected:
1381 TextureCubeIntegerTestES3()
1382 : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1383 {}
1384
1385 const char *getVertexShaderSource() override
1386 {
1387 return "#version 300 es\n"
1388 "out vec2 texcoord;\n"
1389 "in vec4 position;\n"
1390 "void main()\n"
1391 "{\n"
1392 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1393 " texcoord = 0.5*position.xy;\n"
1394 "}\n";
1395 }
1396
1397 const char *getFragmentShaderSource() override
1398 {
1399 return "#version 300 es\n"
1400 "precision highp float;\n"
1401 "precision highp usamplerCube;\n"
1402 "uniform usamplerCube texCube;\n"
1403 "in vec2 texcoord;\n"
1404 "out vec4 fragColor;\n"
1405 "void main()\n"
1406 "{\n"
1407 " fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1408 "}\n";
1409 }
1410
1411 void testSetUp() override
1412 {
1413 TexCoordDrawTest::testSetUp();
1414 glGenTextures(1, &mTextureCube);
1415 setUpProgram();
1416
1417 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1418 ASSERT_NE(-1, mTextureCubeUniformLocation);
1419 }
1420
1421 void testTearDown() override
1422 {
1423 glDeleteTextures(1, &mTextureCube);
1424 TexCoordDrawTest::testTearDown();
1425 }
1426
1427 GLuint mTextureCube;
1428 GLint mTextureCubeUniformLocation;
1429};
1430
Anders Leinoe4452442019-05-09 13:29:49 +03001431class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1432{
1433 protected:
1434 TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1435
1436 const char *getVertexShaderSource() override
1437 {
1438 return "#version 300 es\n"
1439 "out vec2 texcoord;\n"
1440 "in vec4 position;\n"
1441 "void main()\n"
1442 "{\n"
1443 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1444 " texcoord = position.xy;\n"
1445 "}\n";
1446 }
1447
1448 const char *getFragmentShaderSource() override
1449 {
1450 return "#version 300 es\n"
1451 "precision highp float;\n"
1452 "precision highp usamplerCube;\n"
1453 "uniform usamplerCube texCube;\n"
1454 "in vec2 texcoord;\n"
1455 "out vec4 fragColor;\n"
1456 "void main()\n"
1457 "{\n"
1458 " fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1459 "}\n";
1460 }
1461};
1462
Anders Leino1b6aded2019-05-20 12:56:34 +03001463class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1464{
1465 protected:
1466 Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1467
1468 const char *getVertexShaderSource() override
1469 {
1470 return "#version 300 es\n"
1471 "out vec2 texcoord;\n"
1472 "in vec4 position;\n"
1473 "void main()\n"
1474 "{\n"
1475 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1476 " texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1477 "}\n";
1478 }
1479
1480 const char *getFragmentShaderSource() override
1481 {
1482 return "#version 300 es\n"
1483 "precision highp float;\n"
1484 "precision highp usampler2D;\n"
1485 "uniform usampler2D tex;\n"
1486 "in vec2 texcoord;\n"
1487 "out vec4 fragColor;\n"
1488 "void main()\n"
1489 "{\n"
1490 " fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1491 "0.0))/255.0;\n"
1492 "}\n";
1493 }
1494};
1495
Anders Leino69d04932019-05-20 14:04:13 +03001496class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1497{
1498 protected:
1499 Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1500
1501 const char *getVertexShaderSource() override
1502 {
1503 return "#version 300 es\n"
1504 "out vec2 texcoord;\n"
1505 "in vec4 position;\n"
1506 "void main()\n"
1507 "{\n"
1508 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1509 " texcoord = (position.xy * 0.5) + 0.5;\n"
1510 "}\n";
1511 }
1512
1513 const char *getFragmentShaderSource() override
1514 {
1515 return "#version 300 es\n"
1516 "precision highp float;\n"
1517 "uniform highp usampler2DArray tex2DArray;\n"
1518 "in vec2 texcoord;\n"
1519 "out vec4 fragColor;\n"
1520 "void main()\n"
1521 "{\n"
1522 " fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
1523 "0.0)))/255.0;\n"
1524 "}\n";
1525 }
1526};
1527
Anders Leino262e2822019-05-20 14:24:40 +03001528class Texture3DIntegerTestES3 : public Texture3DTestES3
1529{
1530 protected:
1531 Texture3DIntegerTestES3() : Texture3DTestES3() {}
1532
1533 const char *getVertexShaderSource() override
1534 {
1535 return "#version 300 es\n"
1536 "out vec2 texcoord;\n"
1537 "in vec4 position;\n"
1538 "void main()\n"
1539 "{\n"
1540 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1541 " texcoord = (position.xy * 0.5) + 0.5;\n"
1542 "}\n";
1543 }
1544
1545 const char *getFragmentShaderSource() override
1546 {
1547 return "#version 300 es\n"
1548 "precision highp float;\n"
1549 "uniform highp usampler3D tex3D;\n"
1550 "in vec2 texcoord;\n"
1551 "out vec4 fragColor;\n"
1552 "void main()\n"
1553 "{\n"
1554 " fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1555 "}\n";
1556 }
1557};
1558
Jamie Madillfc3ec572019-11-27 21:43:22 +00001559class PBOCompressedTextureTest : public Texture2DTest
1560{
1561 protected:
1562 PBOCompressedTextureTest() : Texture2DTest() {}
1563
1564 void testSetUp() override
1565 {
1566 TexCoordDrawTest::testSetUp();
1567 glGenTextures(1, &mTexture2D);
1568 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1569 EXPECT_GL_NO_ERROR();
1570
1571 setUpProgram();
1572
1573 glGenBuffers(1, &mPBO);
1574 }
1575
1576 void testTearDown() override
1577 {
1578 glDeleteBuffers(1, &mPBO);
1579 Texture2DTest::testTearDown();
1580 }
1581
1582 GLuint mPBO;
1583};
1584
Cody Northrop74e816b2020-03-26 17:40:25 -06001585class ETC1CompressedTextureTest : public Texture2DTest
1586{
1587 protected:
1588 ETC1CompressedTextureTest() : Texture2DTest() {}
1589
1590 void testSetUp() override
1591 {
1592 TexCoordDrawTest::testSetUp();
1593 glGenTextures(1, &mTexture2D);
1594 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1595 EXPECT_GL_NO_ERROR();
1596
1597 setUpProgram();
1598 }
1599
1600 void testTearDown() override { Texture2DTest::testTearDown(); }
1601};
1602
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001603TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001604{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001605 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001606 EXPECT_GL_ERROR(GL_NO_ERROR);
1607
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001608 setUpProgram();
1609
Jamie Madill50cf2be2018-06-15 09:46:57 -04001610 const GLubyte *pixels[20] = {0};
Jamie Madillf67115c2014-04-22 13:14:05 -04001611 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1612 EXPECT_GL_ERROR(GL_INVALID_VALUE);
Geoff Langc51642b2016-11-14 16:18:26 -05001613
Jamie Madillb8149072019-04-30 16:14:44 -04001614 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
Geoff Langc51642b2016-11-14 16:18:26 -05001615 {
1616 // Create a 1-level immutable texture.
1617 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1618
1619 // Try calling sub image on the second level.
1620 glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1621 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1622 }
Jamie Madillf67115c2014-04-22 13:14:05 -04001623}
Geoff Langc41e42d2014-04-28 10:58:16 -04001624
John Bauman18319182016-09-28 14:22:27 -07001625// Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
1626TEST_P(Texture2DTest, QueryBinding)
1627{
1628 glBindTexture(GL_TEXTURE_2D, 0);
1629 EXPECT_GL_ERROR(GL_NO_ERROR);
1630
1631 GLint textureBinding;
1632 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1633 EXPECT_GL_NO_ERROR();
1634 EXPECT_EQ(0, textureBinding);
1635
1636 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
Jamie Madillb8149072019-04-30 16:14:44 -04001637 if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1638 IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
John Bauman18319182016-09-28 14:22:27 -07001639 {
1640 EXPECT_GL_NO_ERROR();
1641 EXPECT_EQ(0, textureBinding);
1642 }
1643 else
1644 {
1645 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1646 }
1647}
1648
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001649TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001650{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001651 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001652 EXPECT_GL_ERROR(GL_NO_ERROR);
1653
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001654 setUpProgram();
1655
Geoff Langc41e42d2014-04-28 10:58:16 -04001656 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001657 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001658 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001659 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001660
Jamie Madill50cf2be2018-06-15 09:46:57 -04001661 const GLubyte *pixel[4] = {0};
Geoff Langc41e42d2014-04-28 10:58:16 -04001662
1663 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1664 EXPECT_GL_NO_ERROR();
1665
1666 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1667 EXPECT_GL_NO_ERROR();
1668
1669 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1670 EXPECT_GL_NO_ERROR();
1671}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001672
1673// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001674TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001675{
1676 glActiveTexture(GL_TEXTURE0);
1677 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1678 glActiveTexture(GL_TEXTURE1);
1679 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1680 EXPECT_GL_ERROR(GL_NO_ERROR);
1681
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001682 glUseProgram(mProgram);
1683 glUniform1i(mTexture2DUniformLocation, 0);
1684 glUniform1i(mTextureCubeUniformLocation, 1);
1685 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001686 EXPECT_GL_NO_ERROR();
1687}
Jamie Madill9aca0592014-10-06 16:26:59 -04001688
Olli Etuaho53a2da12016-01-11 15:43:32 +02001689// Test drawing with two texture types accessed from the same shader and check that the result of
1690// drawing is correct.
1691TEST_P(TextureCubeTest, CubeMapDraw)
1692{
1693 GLubyte texData[4];
1694 texData[0] = 0;
1695 texData[1] = 60;
1696 texData[2] = 0;
1697 texData[3] = 255;
1698
1699 glActiveTexture(GL_TEXTURE0);
1700 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1701 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1702
1703 glActiveTexture(GL_TEXTURE1);
1704 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1705 texData[1] = 120;
1706 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1707 texData);
1708 EXPECT_GL_ERROR(GL_NO_ERROR);
1709
1710 glUseProgram(mProgram);
1711 glUniform1i(mTexture2DUniformLocation, 0);
1712 glUniform1i(mTextureCubeUniformLocation, 1);
1713 drawQuad(mProgram, "position", 0.5f);
1714 EXPECT_GL_NO_ERROR();
1715
1716 int px = getWindowWidth() - 1;
1717 int py = 0;
1718 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1719}
1720
Olli Etuaho4644a202016-01-12 15:12:53 +02001721TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1722{
1723 glActiveTexture(GL_TEXTURE0);
1724 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1725 GLubyte texData[4];
1726 texData[0] = 0;
1727 texData[1] = 128;
1728 texData[2] = 0;
1729 texData[3] = 255;
1730 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1731 glUseProgram(mProgram);
1732 glUniform1i(mTexture2DUniformLocation, 0);
1733 drawQuad(mProgram, "position", 0.5f);
1734 EXPECT_GL_NO_ERROR();
1735
1736 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1737}
1738
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001739// Test drawing with two textures passed to the shader in a sampler array.
1740TEST_P(SamplerArrayTest, SamplerArrayDraw)
1741{
1742 testSamplerArrayDraw();
1743}
1744
1745// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1746// user-defined function in the shader.
1747TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1748{
Shahbaz Youssefi0864a7a2018-11-07 15:50:15 -05001749 // TODO: Diagnose and fix. http://anglebug.com/2955
1750 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1751
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001752 testSamplerArrayDraw();
1753}
1754
Jamie Madill9aca0592014-10-06 16:26:59 -04001755// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001756TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001757{
1758 int px = getWindowWidth() / 2;
1759 int py = getWindowHeight() / 2;
1760
1761 glActiveTexture(GL_TEXTURE0);
1762 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1763
Olli Etuahoa314b612016-03-10 16:43:00 +02001764 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001765
Olli Etuahoa314b612016-03-10 16:43:00 +02001766 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001767 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1768 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1769 glGenerateMipmap(GL_TEXTURE_2D);
1770
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001771 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001772 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001773 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1774 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001775 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001776 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001777
Olli Etuahoa314b612016-03-10 16:43:00 +02001778 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001779
Olli Etuahoa314b612016-03-10 16:43:00 +02001780 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1781 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001782 glGenerateMipmap(GL_TEXTURE_2D);
1783
Olli Etuahoa314b612016-03-10 16:43:00 +02001784 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001785
Olli Etuahoa314b612016-03-10 16:43:00 +02001786 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1787 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001788 glGenerateMipmap(GL_TEXTURE_2D);
1789
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001790 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001791
1792 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001793 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001794}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001795
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001796// Test creating a FBO with a cube map render target, to test an ANGLE bug
1797// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001798TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001799{
Michael Spangd8506c72019-01-29 15:35:09 -05001800 // http://anglebug.com/3145
1801 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1802
Shahbaz Youssefi0c128e12019-03-25 23:50:14 -04001803 // http://anglebug.com/2822
1804 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1805
Jamie Madill3f3b3582018-09-14 10:38:44 -04001806 GLFramebuffer fbo;
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001807 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1808
1809 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Jamie Madill50cf2be2018-06-15 09:46:57 -04001810 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1811 mTextureCube, 0);
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001812
Corentin Wallez322653b2015-06-17 18:33:56 +02001813 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001814 EXPECT_GL_NO_ERROR();
Jamie Madill3f3b3582018-09-14 10:38:44 -04001815
1816 // Test clearing the six mip faces individually.
1817 std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
1818 GLColor::yellow, GLColor::cyan, GLColor::magenta}};
1819
1820 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1821 {
1822 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1823 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1824
1825 Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
1826 glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
1827 glClear(GL_COLOR_BUFFER_BIT);
1828
1829 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
1830 }
1831
1832 // Iterate the faces again to make sure the colors haven't changed.
1833 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1834 {
1835 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1836 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1837 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
1838 << "face color " << faceIndex << " shouldn't change";
1839 }
1840}
1841
1842// Tests clearing a cube map with a scissor enabled.
1843TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
1844{
1845 // TODO(jie.a.chen): Diagnose and fix. http://anglebug.com/2822
1846 ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
1847
Michael Spangd8506c72019-01-29 15:35:09 -05001848 // http://anglebug.com/3145
1849 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1850
Jamie Madill3f3b3582018-09-14 10:38:44 -04001851 constexpr size_t kSize = 16;
1852
1853 GLFramebuffer fbo;
1854 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1855 glViewport(0, 0, kSize, kSize);
1856
1857 GLTexture texcube;
1858 glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
1859 for (GLenum face = 0; face < 6; face++)
1860 {
1861 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
1862 GL_UNSIGNED_BYTE, nullptr);
1863 }
1864 ASSERT_GL_NO_ERROR();
1865
1866 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1867 texcube, 0);
1868
1869 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1870 ASSERT_GL_NO_ERROR();
1871
1872 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1873 glClear(GL_COLOR_BUFFER_BIT);
1874 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1875
1876 glEnable(GL_SCISSOR_TEST);
1877 glScissor(kSize / 2, 0, kSize / 2, kSize);
1878 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1879 glClear(GL_COLOR_BUFFER_BIT);
1880
1881 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1882 EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
1883
1884 ASSERT_GL_NO_ERROR();
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001885}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001886
Jamie Madill50cf2be2018-06-15 09:46:57 -04001887// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
1888// default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001889TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001890{
Jamie Madillb8149072019-04-30 16:14:44 -04001891 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1892 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -04001893
Jamie Madill50cf2be2018-06-15 09:46:57 -04001894 int width = getWindowWidth();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001895 int height = getWindowHeight();
1896
1897 GLuint tex2D;
1898 glGenTextures(1, &tex2D);
1899 glActiveTexture(GL_TEXTURE0);
1900 glBindTexture(GL_TEXTURE_2D, tex2D);
1901
1902 // Fill with red
1903 std::vector<GLubyte> pixels(3 * 16 * 16);
1904 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1905 {
1906 pixels[pixelId * 3 + 0] = 255;
1907 pixels[pixelId * 3 + 1] = 0;
1908 pixels[pixelId * 3 + 2] = 0;
1909 }
1910
1911 // ANGLE internally uses RGBA as the DirectX format for RGB images
Jamie Madill50cf2be2018-06-15 09:46:57 -04001912 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1913 // 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 -04001914 if (getClientMajorVersion() >= 3)
1915 {
1916 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1917 }
1918 else
1919 {
1920 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1921 }
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001922
1923 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1924 // glTexSubImage2D should take into account that the image is dirty.
1925 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1926 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1927 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1928
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001929 setUpProgram();
1930
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001931 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001932 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001933 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001934 glDeleteTextures(1, &tex2D);
1935 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001936 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001937
1938 // Validate that the region of the texture without data has an alpha of 1.0
Jamie Madill05b35b22017-10-03 09:01:44 -04001939 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
1940 EXPECT_EQ(255, pixel.A);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001941}
1942
Jamie Madill50cf2be2018-06-15 09:46:57 -04001943// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
1944// initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001945TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001946{
Jamie Madillfc3ec572019-11-27 21:43:22 +00001947 // http://anglebug.com/4126
1948 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
1949
1950 if (getClientMajorVersion() < 3)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001951 {
Jamie Madillfc3ec572019-11-27 21:43:22 +00001952 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1953 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001954 }
Jamie Madillfc3ec572019-11-27 21:43:22 +00001955
1956 const int width = getWindowWidth();
1957 const int height = getWindowHeight();
1958 const size_t pixelCount = width * height;
1959 const int componentCount = 3;
1960
1961 GLuint tex2D;
1962 glGenTextures(1, &tex2D);
1963 glActiveTexture(GL_TEXTURE0);
1964 glBindTexture(GL_TEXTURE_2D, tex2D);
1965
1966 // Fill with red
1967 std::vector<GLubyte> pixels(componentCount * pixelCount);
1968 for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
1969 {
1970 pixels[pixelId * componentCount + 0] = 255;
1971 pixels[pixelId * componentCount + 1] = 0;
1972 pixels[pixelId * componentCount + 2] = 0;
1973 }
1974
1975 // Read 16x16 region from red backbuffer to PBO
1976 GLuint pbo;
1977 glGenBuffers(1, &pbo);
1978 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1979 glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
1980 GL_STATIC_DRAW);
1981
1982 // ANGLE internally uses RGBA as the DirectX format for RGB images
1983 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1984 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
1985 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
1986
1987 // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
1988 // untouched. glTexSubImage2D should take into account that the image is dirty.
1989 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
1990 nullptr);
1991 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1992 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1993
1994 setUpProgram();
1995
1996 glUseProgram(mProgram);
1997 glUniform1i(mTexture2DUniformLocation, 0);
1998 drawQuad(mProgram, "position", 0.5f);
1999 glDeleteTextures(1, &tex2D);
2000 glDeleteBuffers(1, &pbo);
2001 EXPECT_GL_NO_ERROR();
2002 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
2003 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
2004}
2005
2006// Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
2007// and drawing with the texture
2008// Pseudo code for the follow test:
2009// 1. Upload PBO to mTexture2D
2010// 2. Delete PBO
2011// 3. Draw with otherTexture (x5)
2012// 4. Draw with mTexture2D
2013// 5. Validate color output
2014TEST_P(Texture2DTest, PBOWithMultipleDraws)
2015{
2016 if (getClientMajorVersion() < 3)
2017 {
2018 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
2019 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
2020 }
2021
2022 const GLuint width = getWindowWidth();
2023 const GLuint height = getWindowHeight();
2024 const GLuint windowPixelCount = width * height;
2025 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
2026 std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
2027
2028 // Create secondary draw that does not use mTexture
2029 const char *vertexShaderSource = getVertexShaderSource();
2030 const char *fragmentShaderSource = getFragmentShaderSource();
2031 ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
2032
2033 GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
2034 ASSERT_NE(-1, uniformLoc);
2035 glUseProgram(0);
2036
2037 // Create secondary Texture to draw with
2038 GLTexture otherTexture;
2039 glActiveTexture(GL_TEXTURE0);
2040 glBindTexture(GL_TEXTURE_2D, otherTexture);
2041 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2042 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
2043 pixelsRed.data());
2044 ASSERT_GL_NO_ERROR();
2045
2046 // Setup primary Texture
2047 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2048 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2049 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2050 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2051 ASSERT_GL_NO_ERROR();
2052
2053 // Setup PBO
2054 GLuint pbo = 0;
2055 glGenBuffers(1, &pbo);
2056 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
2057 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
2058 GL_STATIC_DRAW);
2059 ASSERT_GL_NO_ERROR();
2060
2061 // Write PBO to mTexture
2062 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2063 ASSERT_GL_NO_ERROR();
2064 // Delete PBO as ANGLE should be properly handling refcount of this buffer
2065 glDeleteBuffers(1, &pbo);
2066 pixelsGreen.clear();
2067
2068 // Do 5 draws not involving primary texture that the PBO updated
2069 glUseProgram(otherProgram);
2070 glUniform1i(uniformLoc, 0);
2071 glBindTexture(GL_TEXTURE_2D, otherTexture);
2072 drawQuad(otherProgram, "position", 0.5f);
2073 glBindTexture(GL_TEXTURE_2D, 0);
2074 glUseProgram(0);
2075
2076 glUseProgram(otherProgram);
2077 glUniform1i(uniformLoc, 0);
2078 glBindTexture(GL_TEXTURE_2D, otherTexture);
2079 drawQuad(otherProgram, "position", 0.5f);
2080 glBindTexture(GL_TEXTURE_2D, 0);
2081 glUseProgram(0);
2082
2083 glUseProgram(otherProgram);
2084 glUniform1i(uniformLoc, 0);
2085 glBindTexture(GL_TEXTURE_2D, otherTexture);
2086 drawQuad(otherProgram, "position", 0.5f);
2087 glBindTexture(GL_TEXTURE_2D, 0);
2088 glUseProgram(0);
2089
2090 glUseProgram(otherProgram);
2091 glUniform1i(uniformLoc, 0);
2092 glBindTexture(GL_TEXTURE_2D, otherTexture);
2093 drawQuad(otherProgram, "position", 0.5f);
2094 glBindTexture(GL_TEXTURE_2D, 0);
2095 glUseProgram(0);
2096 ASSERT_GL_NO_ERROR();
2097
2098 std::vector<GLColor> output(windowPixelCount, GLColor::black);
2099 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2100 output.data());
2101 EXPECT_EQ(pixelsRed, output);
2102
2103 setUpProgram();
2104 // Draw using PBO updated texture
2105 glUseProgram(mProgram);
2106 glUniform1i(mTexture2DUniformLocation, 0);
2107 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2108 drawQuad(mProgram, "position", 0.5f);
2109 ASSERT_GL_NO_ERROR();
2110
2111 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
2112 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2113 actual.data());
2114 // Value should be green as it was updated during PBO transfer to mTexture
2115 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
2116 EXPECT_EQ(expected, actual);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00002117}
Jamie Madillbc393df2015-01-29 13:46:07 -05002118
Mohan Maiya6caa2652019-09-11 08:06:13 -07002119// Tests CopySubImage for float formats
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002120TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002121{
2122 testFloatCopySubImage(1, 1);
2123}
2124
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002125TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002126{
2127 testFloatCopySubImage(2, 1);
2128}
2129
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002130TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002131{
2132 testFloatCopySubImage(2, 2);
2133}
2134
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002135TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002136{
2137 testFloatCopySubImage(3, 1);
2138}
2139
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002140TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002141{
2142 testFloatCopySubImage(3, 2);
2143}
2144
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002145TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002146{
Yunchao He9550c602018-02-13 14:47:05 +08002147 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
Mohan Maiya6caa2652019-09-11 08:06:13 -07002148 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002149
Yunchao He9550c602018-02-13 14:47:05 +08002150 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2151 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002152
Jamie Madillbc393df2015-01-29 13:46:07 -05002153 testFloatCopySubImage(3, 3);
2154}
2155
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002156TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002157{
2158 testFloatCopySubImage(4, 1);
2159}
2160
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002161TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002162{
2163 testFloatCopySubImage(4, 2);
2164}
2165
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002166TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002167{
Yunchao He9550c602018-02-13 14:47:05 +08002168 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2169 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002170
Jamie Madillbc393df2015-01-29 13:46:07 -05002171 testFloatCopySubImage(4, 3);
2172}
2173
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002174TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05002175{
Yunchao He9550c602018-02-13 14:47:05 +08002176 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2177 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002178
Jamie Madillbc393df2015-01-29 13:46:07 -05002179 testFloatCopySubImage(4, 4);
2180}
Austin Kinross07285142015-03-26 11:36:16 -07002181
Jamie Madill50cf2be2018-06-15 09:46:57 -04002182// Port of
2183// https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
2184// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
2185// handles GL_ALPHA
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002186TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07002187{
2188 const int npotTexSize = 5;
Jamie Madill50cf2be2018-06-15 09:46:57 -04002189 const int potTexSize = 4; // Should be less than npotTexSize
Austin Kinross07285142015-03-26 11:36:16 -07002190 GLuint tex2D;
2191
Jamie Madillb8149072019-04-30 16:14:44 -04002192 if (IsGLExtensionEnabled("GL_OES_texture_npot"))
Austin Kinross07285142015-03-26 11:36:16 -07002193 {
2194 // This test isn't applicable if texture_npot is enabled
2195 return;
2196 }
2197
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002198 setUpProgram();
2199
Austin Kinross07285142015-03-26 11:36:16 -07002200 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2201
Austin Kinross5faa15b2016-01-11 13:32:48 -08002202 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
2203 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2204
Austin Kinross07285142015-03-26 11:36:16 -07002205 glActiveTexture(GL_TEXTURE0);
2206 glGenTextures(1, &tex2D);
2207 glBindTexture(GL_TEXTURE_2D, tex2D);
2208
Till Rathmannc1551dc2018-08-15 17:04:49 +02002209 const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
Austin Kinross07285142015-03-26 11:36:16 -07002210
2211 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2213
2214 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
Jamie Madill50cf2be2018-06-15 09:46:57 -04002215 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2216 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002217 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2218
2219 // Check that an NPOT texture on level 0 succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002220 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2221 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002222 EXPECT_GL_NO_ERROR();
2223
2224 // Check that generateMipmap fails on NPOT
2225 glGenerateMipmap(GL_TEXTURE_2D);
2226 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2227
2228 // Check that nothing is drawn if filtering is not correct for NPOT
2229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2233 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002234 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002235 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2236
2237 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
2238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
2241 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002242 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002243 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2244
2245 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
2246 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2247 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002248 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002249 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2250
2251 // Check that glTexImage2D for POT texture succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002252 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
2253 pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002254 EXPECT_GL_NO_ERROR();
2255
2256 // Check that generateMipmap for an POT texture succeeds
2257 glGenerateMipmap(GL_TEXTURE_2D);
2258 EXPECT_GL_NO_ERROR();
2259
2260 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
2261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2265 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002266 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002267 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2268 EXPECT_GL_NO_ERROR();
2269}
Jamie Madillfa05f602015-05-07 13:47:11 -04002270
Austin Kinross08528e12015-10-07 16:24:40 -07002271// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
2272// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002273TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07002274{
2275 glActiveTexture(GL_TEXTURE0);
2276 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2277
2278 // Create an 8x8 (i.e. power-of-two) texture.
2279 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2280 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2281 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2282 glGenerateMipmap(GL_TEXTURE_2D);
2283
2284 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
2285 // This should always work, even if GL_OES_texture_npot isn't active.
Geoff Langfb052642017-10-24 13:42:09 -04002286 std::array<GLColor, 3 * 3> data;
2287 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
Austin Kinross08528e12015-10-07 16:24:40 -07002288
2289 EXPECT_GL_NO_ERROR();
2290}
2291
Geoff Lang3702d8c2019-04-08 13:44:06 -04002292// Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
2293// TextureImpl and the texture is synced before being used in a draw call.
2294TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
2295{
2296 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
Yuly Novikove6b23e42019-04-10 17:19:15 -04002297 // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
2298 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
Yuly Novikovbd4ff472019-07-19 22:08:17 +00002299 // D3D Debug device reports an error. http://anglebug.com/3501
2300 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
Cody Northrop988f7172019-09-30 15:52:37 -06002301 // TODO(cnorthrop): Needs triage on Vulkan backend. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06002302 ANGLE_SKIP_TEST_IF(IsVulkan());
Geoff Lang3702d8c2019-04-08 13:44:06 -04002303
2304 // The workaround in the GL backend required to trigger this bug generates driver warning
2305 // messages.
2306 ScopedIgnorePlatformMessages ignoreMessages;
2307
2308 setUpProgram();
2309 glUseProgram(mProgram);
2310 glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
2311
2312 GLTexture dest;
2313 glBindTexture(GL_TEXTURE_2D, dest);
2314
2315 GLTexture source;
2316 glBindTexture(GL_TEXTURE_2D, source);
2317
2318 // Put data in mip 0 and 1
2319 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2320 GLColor::red.data());
2321 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2322 GLColor::green.data());
2323
2324 // Disable mipmapping so source is complete
2325 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2326 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2327
2328 // Force the dirty bits to be synchronized in source
2329 drawQuad(mProgram, "position", 1.0f);
2330
2331 // Copy from mip 1 of the source. In the GL backend this internally sets the base level to mip
2332 // 1 and sets a dirty bit.
2333 glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
2334 GL_FALSE, GL_FALSE);
2335
2336 // Draw again, assertions are generated if the texture has internal dirty bits at draw time
2337 drawQuad(mProgram, "position", 1.0f);
2338}
2339
Geoff Lang6f691fb2019-04-25 11:01:52 -04002340// This test case changes the base level of a texture that's attached to a framebuffer, clears every
2341// level to green, and then samples the texture when rendering. Test is taken from
2342// https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
2343TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
2344{
Cody Northropd192e932019-09-27 10:27:10 -06002345 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
2346 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
Cody Northropcb16fb52019-08-29 16:53:55 -06002347
Geoff Lang6f691fb2019-04-25 11:01:52 -04002348 setUpProgram();
2349
2350 constexpr GLint width = 8;
2351 constexpr GLint height = 4;
2352
2353 GLTexture texture;
2354 glBindTexture(GL_TEXTURE_2D, texture);
2355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2356 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2358 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2359
2360 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
2361 GLint level = 0;
2362 GLint levelW = width;
2363 GLint levelH = height;
2364 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2365 nullptr);
2366 while (levelW > 1 || levelH > 1)
2367 {
2368 ++level;
2369 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
2370 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
2371 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2372 nullptr);
2373 }
2374
2375 // Clear each level of the texture using an FBO. Change the base level to match the level used
2376 // for the FBO on each iteration.
2377 GLFramebuffer fbo;
2378 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2379 level = 0;
2380 levelW = width;
2381 levelH = height;
2382 while (levelW > 1 || levelH > 1)
2383 {
2384 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
2385 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
2386
2387 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
2388 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
2389
2390 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2391 EXPECT_GL_NO_ERROR();
2392
2393 glClearColor(0, 1, 0, 1);
2394 glClear(GL_COLOR_BUFFER_BIT);
2395
2396 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2397
2398 ++level;
2399 }
2400
2401 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2402 glViewport(0, 0, 16, 16);
2403 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2404
2405 drawQuad(mProgram, "position", 0.5f);
2406
2407 EXPECT_GL_NO_ERROR();
2408 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2409}
2410
Shahbaz Youssefidbb18b52020-06-05 15:23:17 -04002411// Test that changing the base level of a texture after redefining a level outside the mip-chain
2412// preserves the other mips' data.
2413TEST_P(Texture2DBaseMaxTestES3, ExtendMipChainAfterRedefine)
2414{
2415 // Affected by two bugs:
2416 // - http://anglebug.com/4695
2417 // - http://anglebug.com/4696
2418 ANGLE_SKIP_TEST_IF(IsVulkan());
2419
2420 // http://anglebug.com/4699
2421 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
2422
2423 GLFramebuffer framebuffer;
2424 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2425
2426 GLTexture texture;
2427 glBindTexture(GL_TEXTURE_2D, texture);
2428
2429 std::array<GLColor, getTotalMipDataSize(kMip0Size)> mipData;
2430 fillMipData(mipData.data(), kMip0Size, kMipColors);
2431
2432 for (size_t mip = 1; mip < kMipCount; ++mip)
2433 {
2434 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, kMip0Size >> mip, kMip0Size >> mip, 0, GL_RGBA,
2435 GL_UNSIGNED_BYTE, mipData.data() + getMipDataOffset(kMip0Size, mip));
2436 }
2437
2438 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2439 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
2440 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2441
2442 // Mip 1 is green. Verify this.
2443 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2444
2445 // Add mip 0 and rebase the mip chain.
2446 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kMip0Size, kMip0Size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2447 mipData.data() + getMipDataOffset(kMip0Size, 0));
2448 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2449
2450 // Mip 1 should still be green.
2451 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[1]);
2452
2453 // Verify the other mips too.
2454 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
2455 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2456 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[2]);
2457
2458 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
2459 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2460 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[3]);
2461
2462 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2463 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2464
2465 // Mip 0 data seems to have disappeared in this configuration! http://anglebug.com/4698
2466 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && IsLinux());
2467
2468 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[0]);
2469}
2470
2471// Test that changing the base level of a texture multiple times preserves the data.
2472TEST_P(Texture2DBaseMaxTestES3, PingPongBaseLevel)
2473{
2474 // http://anglebug.com/4701
2475 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
2476
2477 initTest();
2478
2479 // Ping pong a few times.
2480 for (uint32_t tries = 0; tries < 2; ++tries)
2481 {
2482 // Rebase to different mips and verify mips.
2483 for (uint32_t base = 0; base < kMipCount; ++base)
2484 {
2485 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
2486 for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
2487 {
2488 setLodUniform(lod);
2489 drawQuad(mProgram, "position", 0.5f);
2490 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
2491 }
2492 }
2493
2494 // Rebase backwards and verify mips.
2495 for (uint32_t base = kMipCount - 2; base > 0; --base)
2496 {
2497 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base);
2498 for (uint32_t lod = 0; lod < kMipCount - base; ++lod)
2499 {
2500 setLodUniform(lod);
2501 drawQuad(mProgram, "position", 0.5f);
2502 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[base + lod]);
2503 }
2504 }
2505 }
2506}
2507
2508// Test that glTexSubImage2D after incompatibly redefining a mip level correctly applies the update
2509// after the redefine data.
2510TEST_P(Texture2DBaseMaxTestES3, SubImageAfterRedefine)
2511{
2512 initTest();
2513
2514 // Test that all mips have the expected data initially (this makes sure the texture image is
2515 // created already).
2516 for (uint32_t lod = 0; lod < kMipCount; ++lod)
2517 {
2518 setLodUniform(lod);
2519 drawQuad(mProgram, "position", 0.5f);
2520 EXPECT_PIXEL_COLOR_EQ(0, 0, kMipColors[lod]);
2521 }
2522
2523 // Redefine every level, followed by a glTexSubImage2D
2524 const GLColor kNewMipColors[kMipCount] = {
2525 GLColor::yellow,
2526 GLColor::cyan,
2527 GLColor(127, 0, 0, 255),
2528 GLColor(0, 127, 0, 255),
2529 };
2530 std::array<GLColor, getTotalMipDataSize(kMip0Size * 2)> newMipData;
2531 fillMipData(newMipData.data(), kMip0Size * 2, kNewMipColors);
2532
2533 const GLColor kSubImageMipColors[kMipCount] = {
2534 GLColor(0, 0, 127, 255),
2535 GLColor(127, 127, 0, 255),
2536 GLColor(0, 127, 127, 255),
2537 GLColor(127, 0, 127, 255),
2538 };
2539 std::array<GLColor, getTotalMipDataSize(kMip0Size)> subImageMipData;
2540 fillMipData(subImageMipData.data(), kMip0Size, kSubImageMipColors);
2541
2542 for (size_t mip = 0; mip < kMipCount; ++mip)
2543 {
2544 // Redefine the level.
2545 size_t newMipSize = (kMip0Size * 2) >> mip;
2546 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, newMipSize, newMipSize, 0, GL_RGBA,
2547 GL_UNSIGNED_BYTE, newMipData.data() + getMipDataOffset(kMip0Size * 2, mip));
2548
2549 // Immediately follow that with a subimage update.
2550 glTexSubImage2D(GL_TEXTURE_2D, mip, 0, 0, kMip0Size >> mip, kMip0Size >> mip, GL_RGBA,
2551 GL_UNSIGNED_BYTE,
2552 subImageMipData.data() + getMipDataOffset(kMip0Size, mip));
2553 }
2554 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kMipCount - 1);
2555
2556 // Test that the texture looks as expected.
2557 const int w = getWindowWidth() - 1;
2558 const int h = getWindowHeight() - 1;
2559 for (uint32_t lod = 0; lod < kMipCount; ++lod)
2560 {
2561 setLodUniform(lod);
2562 drawQuad(mProgram, "position", 0.5f);
2563 EXPECT_PIXEL_COLOR_EQ(0, 0, kSubImageMipColors[lod]);
2564 EXPECT_PIXEL_COLOR_EQ(w, 0, kNewMipColors[lod]);
2565 EXPECT_PIXEL_COLOR_EQ(0, h, kNewMipColors[lod]);
2566 EXPECT_PIXEL_COLOR_EQ(w, h, kNewMipColors[lod]);
2567 }
2568}
2569
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002570// Test to check that texture completeness is determined correctly when the texture base level is
2571// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
2572TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
2573{
2574 glActiveTexture(GL_TEXTURE0);
2575 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02002576
2577 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
2578 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2579 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2580 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2581 texDataGreen.data());
2582 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2583 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2586 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2587
2588 EXPECT_GL_NO_ERROR();
2589
2590 drawQuad(mProgram, "position", 0.5f);
2591
Olli Etuahoa314b612016-03-10 16:43:00 +02002592 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2593}
2594
2595// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2596// have images defined.
2597TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
2598{
Yunchao He9550c602018-02-13 14:47:05 +08002599 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2600 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2601
Olli Etuahoa314b612016-03-10 16:43:00 +02002602 glActiveTexture(GL_TEXTURE0);
2603 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2604 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2605 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2606 texDataGreen.data());
2607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2610 glTexParameteri(GL_TEXTURE_2D, 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::green);
2617}
2618
Olli Etuahoe8528d82016-05-16 17:50:52 +03002619// Test that drawing works correctly when level 0 is undefined and base level is 1.
2620TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
2621{
Yunchao He9550c602018-02-13 14:47:05 +08002622 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2623 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2624
Olli Etuahoe8528d82016-05-16 17:50:52 +03002625 glActiveTexture(GL_TEXTURE0);
2626 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2627 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2628 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2629 texDataGreen.data());
2630 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2631 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2632 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2633 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2634
2635 EXPECT_GL_NO_ERROR();
2636
2637 // Texture is incomplete.
2638 drawQuad(mProgram, "position", 0.5f);
2639 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2640
2641 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2642 texDataGreen.data());
2643
2644 // Texture is now complete.
2645 drawQuad(mProgram, "position", 0.5f);
2646 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2647}
2648
Olli Etuahoa314b612016-03-10 16:43:00 +02002649// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2650// dimensions that don't fit the images inside the range.
2651// GLES 3.0.4 section 3.8.13 Texture completeness
2652TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2653{
Olli Etuahoa314b612016-03-10 16:43:00 +02002654 glActiveTexture(GL_TEXTURE0);
2655 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2656 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
2657 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2658 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
2659
2660 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2661 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2662
2663 // Two levels that are initially unused.
2664 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2665 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2666 texDataCyan.data());
2667
2668 // One level that is used - only this level should affect completeness.
2669 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2670 texDataGreen.data());
2671
2672 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2674
2675 EXPECT_GL_NO_ERROR();
2676
2677 drawQuad(mProgram, "position", 0.5f);
2678
2679 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2680
Yunchao He2f23f352018-02-11 22:11:37 +08002681 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002682
2683 // Switch the level that is being used to the cyan level 2.
2684 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2685 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2686
2687 EXPECT_GL_NO_ERROR();
2688
2689 drawQuad(mProgram, "position", 0.5f);
2690
2691 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2692}
2693
2694// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2695// have images defined.
2696TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
2697{
Olli Etuahoa314b612016-03-10 16:43:00 +02002698 glActiveTexture(GL_TEXTURE0);
2699 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2700 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2701 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2702 texDataGreen.data());
2703 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2704 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2705 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2706 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2707
2708 EXPECT_GL_NO_ERROR();
2709
2710 drawQuad(mProgram, "position", 0.5f);
2711
2712 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2713}
2714
2715// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2716// dimensions that don't fit the images inside the range.
2717// GLES 3.0.4 section 3.8.13 Texture completeness
2718TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2719{
Yuly Novikovc5da7992019-06-27 12:57:13 -04002720 // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
2721 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
2722
Olli Etuahoa314b612016-03-10 16:43:00 +02002723 glActiveTexture(GL_TEXTURE0);
2724 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2725 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2726 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2727 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2728
2729 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2730 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2731
2732 // Two levels that are initially unused.
2733 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2734 texDataRed.data());
2735 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2736 texDataCyan.data());
2737
2738 // One level that is used - only this level should affect completeness.
2739 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2740 texDataGreen.data());
2741
2742 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2743 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2744
2745 EXPECT_GL_NO_ERROR();
2746
2747 drawQuad(mProgram, "position", 0.5f);
2748
2749 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2750
Yunchao He2f23f352018-02-11 22:11:37 +08002751 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002752
2753 // Switch the level that is being used to the cyan level 2.
2754 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
2755 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
2756
2757 EXPECT_GL_NO_ERROR();
2758
2759 drawQuad(mProgram, "position", 0.5f);
2760
2761 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2762}
2763
2764// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2765// have images defined.
2766TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
2767{
Olli Etuahoa314b612016-03-10 16:43:00 +02002768 glActiveTexture(GL_TEXTURE0);
2769 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2770 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2771 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2772 texDataGreen.data());
2773 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2774 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2775 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2776 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2777
2778 EXPECT_GL_NO_ERROR();
2779
2780 drawQuad(mProgram, "position", 0.5f);
2781
2782 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2783}
2784
2785// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2786// dimensions that don't fit the images inside the range.
2787// GLES 3.0.4 section 3.8.13 Texture completeness
2788TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2789{
Corentin Wallez566c2e32019-08-28 18:37:58 +02002790 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2791 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2792
Olli Etuahoa314b612016-03-10 16:43:00 +02002793 glActiveTexture(GL_TEXTURE0);
2794 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
2795 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2796 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2797 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2798
2799 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2800 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2801
2802 // Two levels that are initially unused.
2803 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2804 texDataRed.data());
2805 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2806 texDataCyan.data());
2807
2808 // One level that is used - only this level should affect completeness.
2809 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2810 texDataGreen.data());
2811
2812 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2813 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2814
2815 EXPECT_GL_NO_ERROR();
2816
2817 drawQuad(mProgram, "position", 0.5f);
2818
2819 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2820
Yunchao He2f23f352018-02-11 22:11:37 +08002821 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2822
Olli Etuahoa314b612016-03-10 16:43:00 +02002823 // Switch the level that is being used to the cyan level 2.
2824 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
2825 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
2826
2827 EXPECT_GL_NO_ERROR();
2828
2829 drawQuad(mProgram, "position", 0.5f);
2830
2831 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2832}
2833
2834// Test that texture completeness is updated if texture max level changes.
2835// GLES 3.0.4 section 3.8.13 Texture completeness
2836TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2837{
Olli Etuahoa314b612016-03-10 16:43:00 +02002838 glActiveTexture(GL_TEXTURE0);
2839 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2840 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2841
2842 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2843 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2844
2845 // A level that is initially unused.
2846 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2847 texDataGreen.data());
2848
2849 // One level that is initially used - only this level should affect completeness.
2850 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2851 texDataGreen.data());
2852
2853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2854 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2855
2856 EXPECT_GL_NO_ERROR();
2857
2858 drawQuad(mProgram, "position", 0.5f);
2859
2860 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2861
2862 // Switch the max level to level 1. The levels within the used range now have inconsistent
2863 // dimensions and the texture should be incomplete.
2864 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2865
2866 EXPECT_GL_NO_ERROR();
2867
2868 drawQuad(mProgram, "position", 0.5f);
2869
2870 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2871}
2872
2873// Test that 3D texture completeness is updated if texture max level changes.
2874// GLES 3.0.4 section 3.8.13 Texture completeness
2875TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2876{
Olli Etuahoa314b612016-03-10 16:43:00 +02002877 glActiveTexture(GL_TEXTURE0);
2878 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2879 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2880
2881 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2882 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2883
2884 // A level that is initially unused.
2885 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2886 texDataGreen.data());
2887
2888 // One level that is initially used - only this level should affect completeness.
2889 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2890 texDataGreen.data());
2891
2892 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2893 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2894
2895 EXPECT_GL_NO_ERROR();
2896
2897 drawQuad(mProgram, "position", 0.5f);
2898
2899 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2900
2901 // Switch the max level to level 1. The levels within the used range now have inconsistent
2902 // dimensions and the texture should be incomplete.
2903 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2904
2905 EXPECT_GL_NO_ERROR();
2906
2907 drawQuad(mProgram, "position", 0.5f);
2908
2909 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2910}
2911
2912// Test that texture completeness is updated if texture base level changes.
2913// GLES 3.0.4 section 3.8.13 Texture completeness
2914TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2915{
Olli Etuahoa314b612016-03-10 16:43:00 +02002916 glActiveTexture(GL_TEXTURE0);
2917 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2918 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2919
2920 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2921 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2922
2923 // Two levels that are initially unused.
2924 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2925 texDataGreen.data());
2926 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2927 texDataGreen.data());
2928
2929 // One level that is initially used - only this level should affect completeness.
2930 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2931 texDataGreen.data());
2932
2933 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2935
2936 EXPECT_GL_NO_ERROR();
2937
2938 drawQuad(mProgram, "position", 0.5f);
2939
2940 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2941
2942 // Switch the base level to level 1. The levels within the used range now have inconsistent
2943 // dimensions and the texture should be incomplete.
2944 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2945
2946 EXPECT_GL_NO_ERROR();
2947
2948 drawQuad(mProgram, "position", 0.5f);
2949
2950 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2951}
2952
2953// Test that texture is not complete if base level is greater than max level.
2954// GLES 3.0.4 section 3.8.13 Texture completeness
2955TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2956{
Olli Etuahoa314b612016-03-10 16:43:00 +02002957 glActiveTexture(GL_TEXTURE0);
2958 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2959
2960 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2961 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2962
2963 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2964
2965 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2967
2968 EXPECT_GL_NO_ERROR();
2969
2970 drawQuad(mProgram, "position", 0.5f);
2971
2972 // Texture should be incomplete.
2973 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2974}
2975
2976// Test that immutable texture base level and max level are clamped.
2977// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2978TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2979{
Olli Etuahoa314b612016-03-10 16:43:00 +02002980 glActiveTexture(GL_TEXTURE0);
2981 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2982
2983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2984 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2985
2986 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2987
2988 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2989
2990 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2991 // should be clamped to [base_level, levels - 1].
2992 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2993 // In the case of this test, those rules make the effective base level and max level 0.
2994 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2995 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2996
2997 EXPECT_GL_NO_ERROR();
2998
2999 drawQuad(mProgram, "position", 0.5f);
3000
3001 // Texture should be complete.
3002 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3003}
3004
Olli Etuaho87fc71c2016-05-11 14:25:21 +03003005// Test that changing base level works when it affects the format of the texture.
3006TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
3007{
Corentin Wallez7f00d332019-08-28 15:19:16 +02003008 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
3009 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
3010
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003011 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
Yunchao He9550c602018-02-13 14:47:05 +08003012
3013 // Observed incorrect rendering on AMD OpenGL.
3014 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
Olli Etuaho87fc71c2016-05-11 14:25:21 +03003015
3016 glActiveTexture(GL_TEXTURE0);
3017 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3018 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
3019 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
3020
3021 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
3023
3024 // RGBA8 level that's initially unused.
3025 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3026 texDataCyan.data());
3027
3028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3030
3031 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
3032 // format. It reads green channel data from the green and alpha channels of texDataGreen
3033 // (this is a bit hacky but works).
3034 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
3035
3036 EXPECT_GL_NO_ERROR();
3037
3038 drawQuad(mProgram, "position", 0.5f);
3039
3040 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3041
3042 // Switch the texture to use the cyan level 0 with the RGBA format.
3043 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3044 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
3045
3046 EXPECT_GL_NO_ERROR();
3047
3048 drawQuad(mProgram, "position", 0.5f);
3049
3050 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
3051}
3052
Olli Etuahoa314b612016-03-10 16:43:00 +02003053// Test that setting a texture image works when base level is out of range.
3054TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
3055{
3056 glActiveTexture(GL_TEXTURE0);
3057 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3058
3059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3061
3062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
3063 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
3064
3065 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
3066
3067 EXPECT_GL_NO_ERROR();
3068
3069 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3070
3071 drawQuad(mProgram, "position", 0.5f);
3072
3073 // Texture should be complete.
3074 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02003075}
3076
Jamie Madill50cf2be2018-06-15 09:46:57 -04003077// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
3078// RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
3079// with these formats does not work as expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003080TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04003081{
3082 std::vector<GLubyte> pixelData;
3083 for (size_t count = 0; count < 5000; count++)
3084 {
3085 pixelData.push_back(0u);
3086 pixelData.push_back(255u);
3087 pixelData.push_back(0u);
3088 }
3089
3090 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003091 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04003092 glUniform1i(mTextureArrayLocation, 0);
3093
3094 // The first draw worked correctly.
Jamie Madill50cf2be2018-06-15 09:46:57 -04003095 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
3096 &pixelData[0]);
Jamie Madill2453dbc2015-07-14 11:35:42 -04003097
3098 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3099 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3100 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
3101 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003102 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02003103 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04003104
3105 // The dimension of the respecification must match the original exactly to trigger the bug.
Jamie Madill50cf2be2018-06-15 09:46:57 -04003106 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
3107 &pixelData[0]);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02003108 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02003109 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04003110
3111 ASSERT_GL_NO_ERROR();
3112}
3113
Olli Etuaho1a679902016-01-14 12:21:47 +02003114// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
3115// This test is needed especially to confirm that sampler registers get assigned correctly on
3116// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
3117TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
3118{
3119 glActiveTexture(GL_TEXTURE0);
3120 glBindTexture(GL_TEXTURE_3D, mTexture3D);
3121 GLubyte texData[4];
3122 texData[0] = 0;
3123 texData[1] = 60;
3124 texData[2] = 0;
3125 texData[3] = 255;
3126 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
3127
3128 glActiveTexture(GL_TEXTURE1);
3129 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
3130 GLfloat depthTexData[1];
3131 depthTexData[0] = 0.5f;
3132 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
3133 depthTexData);
3134
3135 glUseProgram(mProgram);
3136 glUniform1f(mDepthRefUniformLocation, 0.3f);
3137 glUniform1i(mTexture3DUniformLocation, 0);
3138 glUniform1i(mTextureShadowUniformLocation, 1);
3139
3140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
3141 drawQuad(mProgram, "position", 0.5f);
3142 EXPECT_GL_NO_ERROR();
3143 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
3144 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
3145
3146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
3147 drawQuad(mProgram, "position", 0.5f);
3148 EXPECT_GL_NO_ERROR();
3149 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
3150 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
3151}
3152
Olli Etuahoc8c99a02016-01-14 16:47:22 +02003153// Test multiple different sampler types in the same shader.
3154// This test makes sure that even if sampler / texture registers get grouped together based on type
3155// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
3156// still has the right register index information for each ESSL sampler.
3157// The tested ESSL samplers have the following types in D3D11 HLSL:
3158// sampler2D: Texture2D + SamplerState
3159// samplerCube: TextureCube + SamplerState
3160// sampler2DShadow: Texture2D + SamplerComparisonState
3161// samplerCubeShadow: TextureCube + SamplerComparisonState
3162TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
3163{
3164 glActiveTexture(GL_TEXTURE0);
3165 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3166 GLubyte texData[4];
3167 texData[0] = 0;
3168 texData[1] = 0;
3169 texData[2] = 120;
3170 texData[3] = 255;
3171 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
3172
3173 glActiveTexture(GL_TEXTURE1);
3174 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
3175 texData[0] = 0;
3176 texData[1] = 90;
3177 texData[2] = 0;
3178 texData[3] = 255;
3179 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
3180 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
3181 texData);
3182
3183 glActiveTexture(GL_TEXTURE2);
3184 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
3185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
3186 GLfloat depthTexData[1];
3187 depthTexData[0] = 0.5f;
3188 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
3189 depthTexData);
3190
3191 glActiveTexture(GL_TEXTURE3);
3192 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
3193 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
3194 depthTexData[0] = 0.2f;
3195 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
3196 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
3197 depthTexData);
3198
Tobin Ehlisbbf0ce22019-10-11 06:55:36 -06003199 // http://anglebug.com/3949: TODO: Add a DS texture case
3200
Olli Etuahoc8c99a02016-01-14 16:47:22 +02003201 EXPECT_GL_NO_ERROR();
3202
3203 glUseProgram(mProgram);
3204 glUniform1f(mDepthRefUniformLocation, 0.3f);
3205 glUniform1i(mTexture2DUniformLocation, 0);
3206 glUniform1i(mTextureCubeUniformLocation, 1);
3207 glUniform1i(mTexture2DShadowUniformLocation, 2);
3208 glUniform1i(mTextureCubeShadowUniformLocation, 3);
3209
3210 drawQuad(mProgram, "position", 0.5f);
3211 EXPECT_GL_NO_ERROR();
3212 // The shader writes:
3213 // <texture 2d color> +
3214 // <cube map color> +
3215 // 0.25 * <comparison result (1.0)> +
3216 // 0.125 * <comparison result (0.0)>
3217 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
3218}
3219
Olli Etuahobce743a2016-01-15 17:18:28 +02003220// Test different base levels on textures accessed through the same sampler array.
3221// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
3222TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
3223{
Yunchao He9550c602018-02-13 14:47:05 +08003224 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
3225
Jamie Madill788fa362020-02-10 14:07:12 -05003226 // http://anglebug.com/4391
3227 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
3228
Olli Etuahobce743a2016-01-15 17:18:28 +02003229 glActiveTexture(GL_TEXTURE0);
3230 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
3231 GLsizei size = 64;
3232 for (GLint level = 0; level < 7; ++level)
3233 {
3234 ASSERT_LT(0, size);
3235 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3236 nullptr);
3237 size = size / 2;
3238 }
3239 ASSERT_EQ(0, size);
3240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3241
3242 glActiveTexture(GL_TEXTURE1);
3243 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
3244 size = 128;
3245 for (GLint level = 0; level < 8; ++level)
3246 {
3247 ASSERT_LT(0, size);
3248 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3249 nullptr);
3250 size = size / 2;
3251 }
3252 ASSERT_EQ(0, size);
3253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
3254 EXPECT_GL_NO_ERROR();
3255
3256 glUseProgram(mProgram);
3257 glUniform1i(mTexture0Location, 0);
3258 glUniform1i(mTexture1Location, 1);
3259
Olli Etuaho5804dc82018-04-13 14:11:46 +03003260 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
Olli Etuahobce743a2016-01-15 17:18:28 +02003261 EXPECT_GL_NO_ERROR();
3262 // Red channel: width of level 1 of texture A: 32.
3263 // Green channel: width of level 3 of texture B: 16.
3264 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
3265}
3266
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003267// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3268// ES 3.0.4 table 3.24
3269TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
3270{
3271 glActiveTexture(GL_TEXTURE0);
3272 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3273 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
3274 EXPECT_GL_NO_ERROR();
3275
3276 drawQuad(mProgram, "position", 0.5f);
3277
3278 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3279}
3280
3281// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3282// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003283TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003284{
Luc Ferron5164b792018-03-06 09:10:12 -05003285 setUpProgram();
3286
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003287 glActiveTexture(GL_TEXTURE0);
3288 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3289 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
3290 EXPECT_GL_NO_ERROR();
3291
3292 drawQuad(mProgram, "position", 0.5f);
3293
3294 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3295}
3296
Luc Ferron5164b792018-03-06 09:10:12 -05003297// Validate that every component of the pixel will be equal to the luminance value we've set
3298// and that the alpha channel will be 1 (or 255 to be exact).
3299TEST_P(Texture2DTest, TextureLuminanceRGBSame)
3300{
3301 setUpProgram();
3302
3303 glActiveTexture(GL_TEXTURE0);
3304 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3305 uint8_t pixel = 50;
3306 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
3307 EXPECT_GL_NO_ERROR();
3308
3309 drawQuad(mProgram, "position", 0.5f);
3310
3311 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
3312}
3313
3314// Validate that every component of the pixel will be equal to the luminance value we've set
3315// and that the alpha channel will be the second component.
3316TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
3317{
3318 setUpProgram();
3319
3320 glActiveTexture(GL_TEXTURE0);
3321 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3322 uint8_t pixel[] = {50, 25};
3323 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
3324 GL_UNSIGNED_BYTE, pixel);
3325 EXPECT_GL_NO_ERROR();
3326
3327 drawQuad(mProgram, "position", 0.5f);
3328
3329 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
3330}
3331
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003332// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3333// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003334TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003335{
Jamie Madillb8149072019-04-30 16:14:44 -04003336 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003337 ANGLE_SKIP_TEST_IF(IsD3D9());
3338 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferron5164b792018-03-06 09:10:12 -05003339
3340 setUpProgram();
3341
Luc Ferrond8c632c2018-04-10 12:31:44 -04003342 glActiveTexture(GL_TEXTURE0);
3343 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3344 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
3345 EXPECT_GL_NO_ERROR();
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003346
Luc Ferrond8c632c2018-04-10 12:31:44 -04003347 drawQuad(mProgram, "position", 0.5f);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003348
Luc Ferrond8c632c2018-04-10 12:31:44 -04003349 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003350}
3351
3352// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3353// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003354TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003355{
Jamie Madillb8149072019-04-30 16:14:44 -04003356 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003357 ANGLE_SKIP_TEST_IF(IsD3D9());
3358 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferrond8c632c2018-04-10 12:31:44 -04003359 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
3360 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
Luc Ferron5164b792018-03-06 09:10:12 -05003361
Luc Ferrond8c632c2018-04-10 12:31:44 -04003362 setUpProgram();
Luc Ferron5164b792018-03-06 09:10:12 -05003363
Luc Ferrond8c632c2018-04-10 12:31:44 -04003364 glActiveTexture(GL_TEXTURE0);
3365 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3366 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
3367 EXPECT_GL_NO_ERROR();
Yunchao He9550c602018-02-13 14:47:05 +08003368
Luc Ferrond8c632c2018-04-10 12:31:44 -04003369 drawQuad(mProgram, "position", 0.5f);
Yuly Novikovafcec832016-06-21 22:19:51 -04003370
Luc Ferrond8c632c2018-04-10 12:31:44 -04003371 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003372}
3373
3374// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3375// ES 3.0.4 table 3.24
3376TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
3377{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003378 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3379
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003380 glActiveTexture(GL_TEXTURE0);
3381 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3382 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
3383 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3384 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3385 EXPECT_GL_NO_ERROR();
3386
3387 drawQuad(mProgram, "position", 0.5f);
3388
3389 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3390}
3391
3392// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3393// ES 3.0.4 table 3.24
3394TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
3395{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003396 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3397
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003398 glActiveTexture(GL_TEXTURE0);
3399 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3400
3401 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
3402 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3403 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3404 EXPECT_GL_NO_ERROR();
3405
3406 drawQuad(mProgram, "position", 0.5f);
3407
3408 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3409}
3410
3411// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3412// ES 3.0.4 table 3.24
3413TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
3414{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003415 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3416
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003417 glActiveTexture(GL_TEXTURE0);
3418 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3419 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
3420 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3421 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3422 EXPECT_GL_NO_ERROR();
3423
3424 drawQuad(mProgram, "position", 0.5f);
3425
3426 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3427}
3428
3429// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3430// ES 3.0.4 table 3.24
3431TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
3432{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003433 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3434
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003435 glActiveTexture(GL_TEXTURE0);
3436 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3437 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
3438 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3439 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3440 EXPECT_GL_NO_ERROR();
3441
3442 drawQuad(mProgram, "position", 0.5f);
3443
3444 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3445}
3446
3447// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3448// ES 3.0.4 table 3.24
3449TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
3450{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003451 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3452
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003453 glActiveTexture(GL_TEXTURE0);
3454 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3455 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
3456 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3457 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3458 EXPECT_GL_NO_ERROR();
3459
3460 drawQuad(mProgram, "position", 0.5f);
3461
3462 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3463}
3464
3465// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3466// ES 3.0.4 table 3.24
3467TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
3468{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003469 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3470
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003471 glActiveTexture(GL_TEXTURE0);
3472 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3473 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
3474 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3475 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3476 EXPECT_GL_NO_ERROR();
3477
3478 drawQuad(mProgram, "position", 0.5f);
3479
3480 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3481}
3482
3483// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3484// ES 3.0.4 table 3.24
3485TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
3486{
3487 glActiveTexture(GL_TEXTURE0);
3488 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3489 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
3490 EXPECT_GL_NO_ERROR();
3491
3492 drawQuad(mProgram, "position", 0.5f);
3493
3494 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3495}
3496
3497// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3498// ES 3.0.4 table 3.24
3499TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
3500{
3501 glActiveTexture(GL_TEXTURE0);
3502 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3503 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
3504 nullptr);
3505 EXPECT_GL_NO_ERROR();
3506
3507 drawQuad(mProgram, "position", 0.5f);
3508
3509 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3510}
3511
3512// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3513// ES 3.0.4 table 3.24
3514TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
3515{
Geoff Lang2a19c592019-08-23 14:10:24 -04003516 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3517 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003518
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003519 glActiveTexture(GL_TEXTURE0);
3520 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3521 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
3522 EXPECT_GL_NO_ERROR();
3523
3524 drawQuad(mProgram, "position", 0.5f);
3525
3526 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3527}
3528
3529// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3530// ES 3.0.4 table 3.24
3531TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
3532{
Geoff Lang2a19c592019-08-23 14:10:24 -04003533 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3534 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003535
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003536 glActiveTexture(GL_TEXTURE0);
3537 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3538 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
3539 EXPECT_GL_NO_ERROR();
3540
3541 drawQuad(mProgram, "position", 0.5f);
3542
3543 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3544}
3545
Olli Etuaho96963162016-03-21 11:54:33 +02003546// Use a sampler in a uniform struct.
3547TEST_P(SamplerInStructTest, SamplerInStruct)
3548{
3549 runSamplerInStructTest();
3550}
3551
3552// Use a sampler in a uniform struct that's passed as a function parameter.
3553TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
3554{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003555 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3556 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Geoff Lang8fcdf6e2016-09-16 10:45:30 -04003557
Olli Etuaho96963162016-03-21 11:54:33 +02003558 runSamplerInStructTest();
3559}
3560
3561// Use a sampler in a uniform struct array with a struct from the array passed as a function
3562// parameter.
3563TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
3564{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003565 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3566 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003567
Olli Etuaho96963162016-03-21 11:54:33 +02003568 runSamplerInStructTest();
3569}
3570
3571// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
3572// parameter.
3573TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
3574{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003575 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3576 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003577
Olli Etuaho96963162016-03-21 11:54:33 +02003578 runSamplerInStructTest();
3579}
3580
3581// Make sure that there isn't a name conflict between sampler extracted from a struct and a
3582// similarly named uniform.
3583TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
3584{
3585 runSamplerInStructTest();
3586}
3587
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003588// GL_EXT_texture_filter_anisotropic
3589class TextureAnisotropyTest : public Texture2DTest
3590{
3591 protected:
3592 void uploadTexture()
3593 {
3594 glActiveTexture(GL_TEXTURE0);
3595 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3596 GLColor texDataRed[1] = {GLColor::red};
3597 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
3598 EXPECT_GL_NO_ERROR();
3599 }
3600};
3601
3602// Tests that setting anisotropic filtering doesn't cause failures at draw time.
3603TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
3604{
Jamie Madillb8149072019-04-30 16:14:44 -04003605 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003606
3607 setUpProgram();
3608
3609 uploadTexture();
3610
3611 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3612 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3613 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
3614 EXPECT_GL_NO_ERROR();
3615
3616 drawQuad(mProgram, "position", 0.5f);
3617
3618 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3619 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3620 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
3621}
3622
Till Rathmannb8543632018-10-02 19:46:14 +02003623// GL_OES_texture_border_clamp
3624class TextureBorderClampTest : public Texture2DTest
3625{
3626 protected:
3627 TextureBorderClampTest() : Texture2DTest() {}
3628
Jamie Madill35cd7332018-12-02 12:03:33 -05003629 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003630 {
3631 return
3632 R"(precision highp float;
3633 attribute vec4 position;
3634 varying vec2 texcoord;
3635
3636 void main()
3637 {
3638 gl_Position = vec4(position.xy, 0.0, 1.0);
3639 // texcoords in [-0.5, 1.5]
3640 texcoord = (position.xy) + 0.5;
3641 })";
3642 }
3643
3644 void uploadTexture()
3645 {
3646 glActiveTexture(GL_TEXTURE0);
3647 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3648 std::vector<GLColor> texDataRed(1, GLColor::red);
3649 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3650 texDataRed.data());
3651 EXPECT_GL_NO_ERROR();
3652 }
3653};
3654
3655// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3656// GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
3657TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
3658{
Jamie Madillb8149072019-04-30 16:14:44 -04003659 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003660
3661 setUpProgram();
3662
3663 uploadTexture();
3664
3665 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3666 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3667 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3668 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3669 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3670 EXPECT_GL_NO_ERROR();
3671
3672 drawQuad(mProgram, "position", 0.5f);
3673
3674 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3675 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3676 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3677}
3678
3679// Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
3680TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
3681{
Jamie Madillb8149072019-04-30 16:14:44 -04003682 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003683
3684 glActiveTexture(GL_TEXTURE0);
3685 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3686
3687 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3688
3689 GLint colorFixedPoint[4] = {0};
3690 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3691 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3692 std::numeric_limits<GLint>::max()};
3693 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3694 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3695 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3696 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3697
3698 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3699 std::numeric_limits<GLint>::max()};
3700 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3701
3702 GLfloat color[4] = {0.0f};
3703 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
3704 EXPECT_EQ(color[0], kFloatBlue.R);
3705 EXPECT_EQ(color[1], kFloatBlue.G);
3706 EXPECT_EQ(color[2], kFloatBlue.B);
3707 EXPECT_EQ(color[3], kFloatBlue.A);
3708}
3709
3710// Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
3711TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
3712{
Jamie Madillb8149072019-04-30 16:14:44 -04003713 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003714
3715 glActiveTexture(GL_TEXTURE0);
3716 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3717
3718 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
3719 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3720
3721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3722 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3723
3724 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3725 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3726
3727 GLint colorInt[4] = {0};
3728 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
3729 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3730
3731 if (getClientMajorVersion() < 3)
3732 {
3733 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3734 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3735 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3736 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3737
3738 GLuint colorUInt[4] = {0};
3739 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3740 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3741 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3742 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3743
3744 GLSampler sampler;
3745 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3746 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3747 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3748 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3749
3750 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3751 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3752 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3753 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3754 }
3755}
3756
3757class TextureBorderClampTestES3 : public TextureBorderClampTest
3758{
3759 protected:
3760 TextureBorderClampTestES3() : TextureBorderClampTest() {}
3761};
3762
3763// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3764// GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
3765TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
3766{
Jamie Madillb8149072019-04-30 16:14:44 -04003767 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003768
3769 setUpProgram();
3770
3771 uploadTexture();
3772
3773 GLSampler sampler;
3774 glBindSampler(0, sampler);
3775 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3776 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3777 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3778 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3779 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3780 EXPECT_GL_NO_ERROR();
3781
3782 drawQuad(mProgram, "position", 0.5f);
3783
3784 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3785 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3786 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3787}
3788
3789// Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
3790TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
3791{
Jamie Madillb8149072019-04-30 16:14:44 -04003792 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003793
3794 glActiveTexture(GL_TEXTURE0);
3795
3796 GLSampler sampler;
3797 glBindSampler(0, sampler);
3798
3799 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3800
3801 GLint colorFixedPoint[4] = {0};
3802 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3803 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3804 std::numeric_limits<GLint>::max()};
3805 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3806 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3807 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3808 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3809
3810 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3811 std::numeric_limits<GLint>::max()};
3812 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3813
3814 GLfloat color[4] = {0.0f};
3815 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
3816 EXPECT_EQ(color[0], kFloatBlue.R);
3817 EXPECT_EQ(color[1], kFloatBlue.G);
3818 EXPECT_EQ(color[2], kFloatBlue.B);
3819 EXPECT_EQ(color[3], kFloatBlue.A);
3820
3821 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
3822 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
3823 GLint colorInt[4] = {0};
3824 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3825 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
3826 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
3827 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
3828 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
3829
3830 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
3831 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
3832 GLuint colorUInt[4] = {0};
3833 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3834 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
3835 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
3836 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
3837 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
3838
3839 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3840
3841 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
3842 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
3843 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3844 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
3845 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
3846 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
3847 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
3848
3849 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
3850 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
3851 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3852 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
3853 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
3854 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
3855 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
3856}
3857
3858// Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
3859TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
3860{
Jamie Madillb8149072019-04-30 16:14:44 -04003861 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003862
3863 glActiveTexture(GL_TEXTURE0);
3864
3865 GLSampler sampler;
3866 glBindSampler(0, sampler);
3867
3868 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
3869 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3870
3871 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3872 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3873}
3874
3875class TextureBorderClampIntegerTestES3 : public Texture2DTest
3876{
3877 protected:
3878 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
3879
Jamie Madill35cd7332018-12-02 12:03:33 -05003880 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003881 {
3882 return
3883 R"(#version 300 es
3884 out vec2 texcoord;
3885 in vec4 position;
3886
3887 void main()
3888 {
3889 gl_Position = vec4(position.xy, 0.0, 1.0);
3890 // texcoords in [-0.5, 1.5]
3891 texcoord = (position.xy) + 0.5;
3892 })";
3893 }
3894
Jamie Madillba319ba2018-12-29 10:29:33 -05003895 const char *getFragmentShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003896 {
Jamie Madill35cd7332018-12-02 12:03:33 -05003897 if (isUnsignedIntTest)
3898 {
3899 return "#version 300 es\n"
3900 "precision highp float;\n"
3901 "uniform highp usampler2D tex;\n"
3902 "in vec2 texcoord;\n"
3903 "out vec4 fragColor;\n"
Till Rathmannb8543632018-10-02 19:46:14 +02003904
Jamie Madill35cd7332018-12-02 12:03:33 -05003905 "void main()\n"
3906 "{\n"
3907 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3908 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3909 "fragColor = (texture(tex, texcoord).r == 150u)"
3910 " ? green : red;\n"
3911 "}\n";
3912 }
3913 else
3914 {
3915 return "#version 300 es\n"
3916 "precision highp float;\n"
3917 "uniform highp isampler2D tex;\n"
3918 "in vec2 texcoord;\n"
3919 "out vec4 fragColor;\n"
3920
3921 "void main()\n"
3922 "{\n"
3923 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3924 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3925 "fragColor = (texture(tex, texcoord).r == -50)"
3926 " ? green : red;\n"
3927 "}\n";
3928 }
Till Rathmannb8543632018-10-02 19:46:14 +02003929 }
3930
3931 void uploadTexture()
3932 {
3933 glActiveTexture(GL_TEXTURE0);
3934 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3935 if (isUnsignedIntTest)
3936 {
3937 std::vector<GLubyte> texData(4, 100);
3938 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
3939 texData.data());
3940 }
3941 else
3942 {
3943 std::vector<GLbyte> texData(4, 100);
3944 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
3945 texData.data());
3946 }
3947 EXPECT_GL_NO_ERROR();
3948 }
3949
3950 bool isUnsignedIntTest;
3951};
3952
3953// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3954// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3955TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
3956{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003957 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3958 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3959
Jamie Madillb8149072019-04-30 16:14:44 -04003960 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003961
3962 setUpProgram();
3963
3964 uploadTexture();
3965
3966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3967 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3968 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3969 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3970
3971 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3972 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3973
3974 EXPECT_GL_NO_ERROR();
3975
3976 drawQuad(mProgram, "position", 0.5f);
3977
3978 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3979 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3980 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3981}
3982
3983// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3984// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3985TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
3986{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003987 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3988 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3989
Jamie Madillb8149072019-04-30 16:14:44 -04003990 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003991
3992 setUpProgram();
3993
3994 uploadTexture();
3995
3996 GLSampler sampler;
3997 glBindSampler(0, sampler);
3998 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3999 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
4000 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4001 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4002
4003 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
4004 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
4005
4006 EXPECT_GL_NO_ERROR();
4007
4008 drawQuad(mProgram, "position", 0.5f);
4009
4010 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
4011 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4012 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
4013}
4014
4015// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
4016// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
4017TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
4018{
Jamie Madillb8149072019-04-30 16:14:44 -04004019 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02004020
4021 isUnsignedIntTest = true;
4022
4023 setUpProgram();
4024
4025 uploadTexture();
4026
4027 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
4028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
4029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4030 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4031
4032 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
4033 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
4034
4035 EXPECT_GL_NO_ERROR();
4036
4037 drawQuad(mProgram, "position", 0.5f);
4038
4039 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
4040 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4041 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
4042}
4043
4044// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
4045// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
4046// glSamplerParameterIuivOES).
4047TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
4048{
Jamie Madillb8149072019-04-30 16:14:44 -04004049 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02004050
4051 isUnsignedIntTest = true;
4052
4053 setUpProgram();
4054
4055 uploadTexture();
4056
4057 GLSampler sampler;
4058 glBindSampler(0, sampler);
4059 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
4060 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
4061 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4062 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4063
4064 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
4065 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
4066
4067 EXPECT_GL_NO_ERROR();
4068
4069 drawQuad(mProgram, "position", 0.5f);
4070
4071 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
4072 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4073 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
4074}
4075
4076// ~GL_OES_texture_border_clamp
4077
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004078class TextureLimitsTest : public ANGLETest
4079{
4080 protected:
4081 struct RGBA8
4082 {
4083 uint8_t R, G, B, A;
4084 };
4085
4086 TextureLimitsTest()
4087 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
4088 {
4089 setWindowWidth(128);
4090 setWindowHeight(128);
4091 setConfigRedBits(8);
4092 setConfigGreenBits(8);
4093 setConfigBlueBits(8);
4094 setConfigAlphaBits(8);
4095 }
4096
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004097 void testSetUp() override
Jamie Madill0fdb9562018-09-17 17:18:43 -04004098 {
Jamie Madill0fdb9562018-09-17 17:18:43 -04004099 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
4100 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
4101 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
4102
4103 ASSERT_GL_NO_ERROR();
4104 }
4105
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004106 void testTearDown() override
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004107 {
4108 if (mProgram != 0)
4109 {
4110 glDeleteProgram(mProgram);
4111 mProgram = 0;
4112
4113 if (!mTextures.empty())
4114 {
4115 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
4116 }
4117 }
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004118 }
4119
4120 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
4121 GLint vertexTextureCount,
4122 GLint vertexActiveTextureCount,
4123 const std::string &fragPrefix,
4124 GLint fragmentTextureCount,
4125 GLint fragmentActiveTextureCount)
4126 {
4127 std::stringstream vertexShaderStr;
4128 vertexShaderStr << "attribute vec2 position;\n"
4129 << "varying vec4 color;\n"
4130 << "varying vec2 texCoord;\n";
4131
4132 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
4133 {
4134 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
4135 }
4136
4137 vertexShaderStr << "void main() {\n"
4138 << " gl_Position = vec4(position, 0, 1);\n"
4139 << " texCoord = (position * 0.5) + 0.5;\n"
4140 << " color = vec4(0);\n";
4141
4142 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
4143 {
4144 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
4145 << ", texCoord);\n";
4146 }
4147
4148 vertexShaderStr << "}";
4149
4150 std::stringstream fragmentShaderStr;
4151 fragmentShaderStr << "varying mediump vec4 color;\n"
4152 << "varying mediump vec2 texCoord;\n";
4153
4154 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
4155 {
4156 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
4157 }
4158
4159 fragmentShaderStr << "void main() {\n"
4160 << " gl_FragColor = color;\n";
4161
4162 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
4163 {
4164 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
4165 << ", texCoord);\n";
4166 }
4167
4168 fragmentShaderStr << "}";
4169
4170 const std::string &vertexShaderSource = vertexShaderStr.str();
4171 const std::string &fragmentShaderSource = fragmentShaderStr.str();
4172
Jamie Madill35cd7332018-12-02 12:03:33 -05004173 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004174 }
4175
4176 RGBA8 getPixel(GLint texIndex)
4177 {
4178 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
4179 0, 255u};
4180 return pixel;
4181 }
4182
4183 void initTextures(GLint tex2DCount, GLint texCubeCount)
4184 {
4185 GLint totalCount = tex2DCount + texCubeCount;
4186 mTextures.assign(totalCount, 0);
4187 glGenTextures(totalCount, &mTextures[0]);
4188 ASSERT_GL_NO_ERROR();
4189
4190 std::vector<RGBA8> texData(16 * 16);
4191
4192 GLint texIndex = 0;
4193 for (; texIndex < tex2DCount; ++texIndex)
4194 {
4195 texData.assign(texData.size(), getPixel(texIndex));
4196 glActiveTexture(GL_TEXTURE0 + texIndex);
4197 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
4198 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4199 &texData[0]);
4200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4203 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4204 }
4205
4206 ASSERT_GL_NO_ERROR();
4207
4208 for (; texIndex < texCubeCount; ++texIndex)
4209 {
4210 texData.assign(texData.size(), getPixel(texIndex));
4211 glActiveTexture(GL_TEXTURE0 + texIndex);
4212 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
4213 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
4214 GL_UNSIGNED_BYTE, &texData[0]);
4215 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
4216 GL_UNSIGNED_BYTE, &texData[0]);
4217 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
4218 GL_UNSIGNED_BYTE, &texData[0]);
4219 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
4220 GL_UNSIGNED_BYTE, &texData[0]);
4221 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
4222 GL_UNSIGNED_BYTE, &texData[0]);
4223 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
4224 GL_UNSIGNED_BYTE, &texData[0]);
4225 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4226 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4227 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4228 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4229 }
4230
4231 ASSERT_GL_NO_ERROR();
4232 }
4233
4234 void testWithTextures(GLint vertexTextureCount,
4235 const std::string &vertexTexturePrefix,
4236 GLint fragmentTextureCount,
4237 const std::string &fragmentTexturePrefix)
4238 {
4239 // Generate textures
4240 initTextures(vertexTextureCount + fragmentTextureCount, 0);
4241
4242 glUseProgram(mProgram);
4243 RGBA8 expectedSum = {0};
4244 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
4245 {
4246 std::stringstream uniformNameStr;
4247 uniformNameStr << vertexTexturePrefix << texIndex;
4248 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04004249 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004250 ASSERT_NE(-1, location);
4251
4252 glUniform1i(location, texIndex);
4253 RGBA8 contribution = getPixel(texIndex);
4254 expectedSum.R += contribution.R;
4255 expectedSum.G += contribution.G;
4256 }
4257
4258 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
4259 {
4260 std::stringstream uniformNameStr;
4261 uniformNameStr << fragmentTexturePrefix << texIndex;
4262 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04004263 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004264 ASSERT_NE(-1, location);
4265
4266 glUniform1i(location, texIndex + vertexTextureCount);
4267 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
4268 expectedSum.R += contribution.R;
4269 expectedSum.G += contribution.G;
4270 }
4271
4272 ASSERT_GE(256u, expectedSum.G);
4273
4274 drawQuad(mProgram, "position", 0.5f);
4275 ASSERT_GL_NO_ERROR();
4276 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
4277 }
4278
4279 GLuint mProgram;
4280 std::vector<GLuint> mTextures;
4281 GLint mMaxVertexTextures;
4282 GLint mMaxFragmentTextures;
4283 GLint mMaxCombinedTextures;
4284};
4285
4286// Test rendering with the maximum vertex texture units.
4287TEST_P(TextureLimitsTest, MaxVertexTextures)
4288{
4289 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
4290 ASSERT_NE(0u, mProgram);
4291 ASSERT_GL_NO_ERROR();
4292
4293 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4294}
4295
4296// Test rendering with the maximum fragment texture units.
4297TEST_P(TextureLimitsTest, MaxFragmentTextures)
4298{
4299 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
4300 ASSERT_NE(0u, mProgram);
4301 ASSERT_GL_NO_ERROR();
4302
4303 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
4304}
4305
4306// Test rendering with maximum combined texture units.
4307TEST_P(TextureLimitsTest, MaxCombinedTextures)
4308{
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004309 // TODO(timvp): http://anglebug.com/3570
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004310 // max per-stage sampled image bindings count (32) exceeds device
4311 // maxPerStageDescriptorSampledImages limit (16)
Shahbaz Youssefi57f7b692020-06-05 00:45:01 -04004312 ANGLE_SKIP_TEST_IF(isSwiftshader());
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004313
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004314 GLint vertexTextures = mMaxVertexTextures;
4315
4316 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
4317 {
4318 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
4319 }
4320
4321 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
4322 mMaxFragmentTextures, mMaxFragmentTextures);
4323 ASSERT_NE(0u, mProgram);
4324 ASSERT_GL_NO_ERROR();
4325
4326 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
4327}
4328
4329// Negative test for exceeding the number of vertex textures
4330TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
4331{
4332 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
4333 0);
4334 ASSERT_EQ(0u, mProgram);
4335}
4336
4337// Negative test for exceeding the number of fragment textures
4338TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
4339{
4340 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
4341 mMaxFragmentTextures + 1);
4342 ASSERT_EQ(0u, mProgram);
4343}
4344
4345// Test active vertex textures under the limit, but excessive textures specified.
4346TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
4347{
4348 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
4349 ASSERT_NE(0u, mProgram);
4350 ASSERT_GL_NO_ERROR();
4351
4352 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4353}
4354
4355// Test active fragment textures under the limit, but excessive textures specified.
4356TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
4357{
4358 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
4359 mMaxFragmentTextures);
4360 ASSERT_NE(0u, mProgram);
4361 ASSERT_GL_NO_ERROR();
4362
4363 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
4364}
4365
4366// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02004367// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004368TEST_P(TextureLimitsTest, TextureTypeConflict)
4369{
Jamie Madill35cd7332018-12-02 12:03:33 -05004370 constexpr char kVS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004371 "attribute vec2 position;\n"
4372 "varying float color;\n"
4373 "uniform sampler2D tex2D;\n"
4374 "uniform samplerCube texCube;\n"
4375 "void main() {\n"
4376 " gl_Position = vec4(position, 0, 1);\n"
4377 " vec2 texCoord = (position * 0.5) + 0.5;\n"
4378 " color = texture2D(tex2D, texCoord).x;\n"
4379 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
4380 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05004381 constexpr char kFS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004382 "varying mediump float color;\n"
4383 "void main() {\n"
4384 " gl_FragColor = vec4(color, 0, 0, 1);\n"
4385 "}";
4386
Jamie Madill35cd7332018-12-02 12:03:33 -05004387 mProgram = CompileProgram(kVS, kFS);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004388 ASSERT_NE(0u, mProgram);
4389
4390 initTextures(1, 0);
4391
4392 glUseProgram(mProgram);
4393 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
4394 ASSERT_NE(-1, tex2DLocation);
4395 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
4396 ASSERT_NE(-1, texCubeLocation);
4397
4398 glUniform1i(tex2DLocation, 0);
4399 glUniform1i(texCubeLocation, 0);
4400 ASSERT_GL_NO_ERROR();
4401
4402 drawQuad(mProgram, "position", 0.5f);
4403 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4404}
4405
Vincent Lang25ab4512016-05-13 18:13:59 +02004406class Texture2DNorm16TestES3 : public Texture2DTestES3
4407{
4408 protected:
4409 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
4410
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004411 void testSetUp() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004412 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004413 Texture2DTestES3::testSetUp();
Vincent Lang25ab4512016-05-13 18:13:59 +02004414
4415 glActiveTexture(GL_TEXTURE0);
4416 glGenTextures(3, mTextures);
4417 glGenFramebuffers(1, &mFBO);
4418 glGenRenderbuffers(1, &mRenderbuffer);
4419
4420 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
4421 {
4422 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
4423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4425 }
4426
4427 glBindTexture(GL_TEXTURE_2D, 0);
4428
4429 ASSERT_GL_NO_ERROR();
4430 }
4431
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004432 void testTearDown() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004433 {
4434 glDeleteTextures(3, mTextures);
4435 glDeleteFramebuffers(1, &mFBO);
4436 glDeleteRenderbuffers(1, &mRenderbuffer);
4437
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004438 Texture2DTestES3::testTearDown();
Vincent Lang25ab4512016-05-13 18:13:59 +02004439 }
4440
4441 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
4442 {
shrekshao81ee4d22019-12-04 17:05:11 -08004443 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4444 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4445 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4446
Geoff Langf607c602016-09-21 11:46:48 -04004447 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
4448 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004449
4450 setUpProgram();
4451
4452 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4453 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
4454 0);
4455
4456 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
4457 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
4458
4459 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Geoff Langf607c602016-09-21 11:46:48 -04004460 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004461
4462 EXPECT_GL_NO_ERROR();
4463
4464 drawQuad(mProgram, "position", 0.5f);
4465
Geoff Langf607c602016-09-21 11:46:48 -04004466 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
Vincent Lang25ab4512016-05-13 18:13:59 +02004467
Jamie Madill50cf2be2018-06-15 09:46:57 -04004468 EXPECT_PIXEL_COLOR_EQ(0, 0,
4469 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
4470 expectedValue, expectedValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004471
4472 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4473
4474 ASSERT_GL_NO_ERROR();
4475 }
4476
shrekshao81ee4d22019-12-04 17:05:11 -08004477 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
4478 GLuint y,
4479 GLuint width,
4480 GLuint height,
4481 GLint packRowLength,
4482 GLint packAlignment,
4483 GLint packSkipPixels,
4484 GLint packSkipRows,
4485 GLenum type,
4486 GLColor16UI color)
Vincent Lang25ab4512016-05-13 18:13:59 +02004487 {
shrekshao81ee4d22019-12-04 17:05:11 -08004488 // PACK modes debugging
4489 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
4490 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
4491
4492 GLuint l = packRowLength == 0 ? width : packRowLength;
4493 const GLint &a = packAlignment;
4494
4495 // According to
4496 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4497 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
4498 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
4499 if (static_cast<GLuint>(packRowLength) < width)
4500 {
4501 componentCount += width * n * s - k;
4502 }
4503
4504 // Populate the pixels array with random dirty value
4505 constexpr GLushort kDirtyValue = 0x1234;
4506 std::vector<GLushort> pixels(componentCount, kDirtyValue);
4507 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
4508
4509 EXPECT_GL_NO_ERROR();
4510
4511 GLushort *pixelRowStart = pixels.data();
4512 pixelRowStart += n * packSkipPixels + k * packSkipRows;
4513
4514 std::vector<bool> modifiedPixels(componentCount, false);
4515
4516 char errorInfo[200];
4517
4518 for (GLuint y = 0; y < height; ++y)
4519 {
4520 GLushort *curPixel = pixelRowStart;
4521 for (GLuint x = 0, len = (y == height - 1) ? width : std::min(l, width); x < len; ++x)
4522 {
4523 snprintf(errorInfo, sizeof(errorInfo),
4524 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
4525 "skipPixels: %d, skipRows: %d\n",
4526 width, height, x, y, packRowLength, packAlignment, packSkipPixels,
4527 packSkipRows);
4528 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
4529 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
4530 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
4531 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
4532
4533 std::ptrdiff_t diff = curPixel - pixels.data();
4534 modifiedPixels[diff + 0] = true;
4535 modifiedPixels[diff + 1] = true;
4536 modifiedPixels[diff + 2] = true;
4537 modifiedPixels[diff + 3] = true;
4538
4539 curPixel += n;
4540 }
4541 pixelRowStart += k;
4542 }
4543
4544 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
4545 {
4546 if (!modifiedPixels[i])
4547 {
4548 EXPECT_EQ(pixels[i], kDirtyValue);
4549 }
4550 }
4551 }
4552
4553 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
4554 {
4555 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4556 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4557 // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
4558 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
4559 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4560
Jamie Madill50cf2be2018-06-15 09:46:57 -04004561 GLushort pixelValue = 0x6A35;
Geoff Langf607c602016-09-21 11:46:48 -04004562 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
shrekshao81ee4d22019-12-04 17:05:11 -08004563 GLColor16UI color = SliceFormatColor16UI(
4564 format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
4565 // Size of drawing viewport
4566 constexpr GLint width = 8, height = 8;
Vincent Lang25ab4512016-05-13 18:13:59 +02004567
4568 setUpProgram();
4569
4570 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
shrekshao81ee4d22019-12-04 17:05:11 -08004571 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
Vincent Lang25ab4512016-05-13 18:13:59 +02004572
4573 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4574 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4575 0);
4576
4577 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
Geoff Langf607c602016-09-21 11:46:48 -04004578 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
shrekshao81ee4d22019-12-04 17:05:11 -08004579 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4580 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Vincent Lang25ab4512016-05-13 18:13:59 +02004581
4582 EXPECT_GL_NO_ERROR();
4583
4584 drawQuad(mProgram, "position", 0.5f);
4585
shrekshao81ee4d22019-12-04 17:05:11 -08004586 // ReadPixels against different width, height, pixel pack mode combinations to test
4587 // workaround of pixels rearrangement
4588
4589 // {x, y, width, height}
4590 std::vector<std::array<GLint, 4>> areas = {
4591 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
4592 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
4593
4594 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
4595
4596 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
4597 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
4598 };
4599
4600 // Put default settings at the last
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01004601 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
4602 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
shrekshao81ee4d22019-12-04 17:05:11 -08004603 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
4604 {3, 1}, {20, 20}, {0, 0}};
4605
4606 // Restore pixel pack modes later
4607 GLint restorePackAlignment;
4608 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
4609 GLint restorePackRowLength;
4610 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
4611 GLint restorePackSkipPixels;
4612 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
4613 GLint restorePackSkipRows;
4614 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
4615
4616 // Variable symbols are based on:
4617 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4618 for (const auto &skipped : paramsPackSkipPixelsAndRows)
4619 {
4620 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
4621 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
4622 for (GLint a : paramsPackAlignment)
4623 {
4624 glPixelStorei(GL_PACK_ALIGNMENT, a);
4625 for (GLint l : paramsPackRowLength)
4626 {
4627 glPixelStorei(GL_PACK_ROW_LENGTH, l);
4628
4629 for (const auto &area : areas)
4630 {
4631 ASSERT(area[0] + area[2] <= width);
4632 ASSERT(area[1] + area[3] <= height);
4633 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
4634 area[3], l, a, skipped[0],
4635 skipped[1], type, color);
4636 }
4637 }
4638 }
4639 }
4640
4641 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
4642 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
4643 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
4644 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
Vincent Lang25ab4512016-05-13 18:13:59 +02004645
4646 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4647 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4648 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4649 mRenderbuffer);
4650 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4651 EXPECT_GL_NO_ERROR();
4652
4653 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4654 glClear(GL_COLOR_BUFFER_BIT);
4655
shrekshaofb1c2fe2019-11-13 11:10:39 -08004656 EXPECT_PIXEL_16UI_COLOR(
4657 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
shrekshaoe33c1582019-11-06 16:55:29 -08004658
4659 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Vincent Lang25ab4512016-05-13 18:13:59 +02004660 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4661
shrekshaoe33c1582019-11-06 16:55:29 -08004662 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4663 0);
shrekshaofb1c2fe2019-11-13 11:10:39 -08004664 EXPECT_PIXEL_16UI_COLOR(
4665 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004666
4667 ASSERT_GL_NO_ERROR();
shrekshaofb1c2fe2019-11-13 11:10:39 -08004668
4669 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Vincent Lang25ab4512016-05-13 18:13:59 +02004670 }
4671
4672 GLuint mTextures[3];
4673 GLuint mFBO;
4674 GLuint mRenderbuffer;
4675};
4676
shrekshao81ee4d22019-12-04 17:05:11 -08004677TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
Vincent Lang25ab4512016-05-13 18:13:59 +02004678{
Vincent Lang25ab4512016-05-13 18:13:59 +02004679 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
shrekshao81ee4d22019-12-04 17:05:11 -08004680}
Vincent Lang25ab4512016-05-13 18:13:59 +02004681
shrekshao81ee4d22019-12-04 17:05:11 -08004682TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
4683{
4684 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
4685}
4686
4687TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
4688{
4689 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4690}
4691
4692TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
4693{
4694 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
4695}
4696
4697TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
4698{
4699 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4700 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4701
4702 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
4703}
4704
4705TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
4706{
4707 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4708 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4709
4710 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
4711}
4712
4713TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
4714{
4715 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4716}
4717
4718TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
4719{
4720 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
4721}
4722
4723TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
4724{
4725 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
4726}
4727
4728TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
4729{
4730 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4731}
4732
4733TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
4734{
4735 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
Vincent Lang25ab4512016-05-13 18:13:59 +02004736}
4737
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004738class Texture2DRGTest : public Texture2DTest
4739{
4740 protected:
4741 Texture2DRGTest()
4742 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4743 {}
4744
4745 void testSetUp() override
4746 {
4747 Texture2DTest::testSetUp();
4748
4749 glActiveTexture(GL_TEXTURE0);
4750 glGenTextures(1, &mRenderableTexture);
4751 glGenTextures(1, &mTestTexture);
4752 glGenFramebuffers(1, &mFBO);
4753 glGenRenderbuffers(1, &mRenderbuffer);
4754
4755 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004756 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4757 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004758 glBindTexture(GL_TEXTURE_2D, mTestTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004759 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4760 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004761
4762 glBindTexture(GL_TEXTURE_2D, 0);
4763
4764 setUpProgram();
4765 glUseProgram(mProgram);
4766 glUniform1i(mTexture2DUniformLocation, 0);
4767
4768 ASSERT_GL_NO_ERROR();
4769 }
4770
4771 void testTearDown() override
4772 {
4773 glDeleteTextures(1, &mRenderableTexture);
4774 glDeleteTextures(1, &mTestTexture);
4775 glDeleteFramebuffers(1, &mFBO);
4776 glDeleteRenderbuffers(1, &mRenderbuffer);
4777
4778 Texture2DTest::testTearDown();
4779 }
4780
4781 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
4782 {
4783 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4784 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4785
4786 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4787 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4788 mRenderableTexture, 0);
4789
4790 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4791 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
4792
4793 EXPECT_GL_NO_ERROR();
4794 }
4795
4796 void testRGTexture(GLColor expectedColor)
4797 {
4798 drawQuad(mProgram, "position", 0.5f);
4799
4800 EXPECT_GL_NO_ERROR();
4801 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
4802 }
4803
4804 void testRGRender(GLenum internalformat, GLenum format)
4805 {
4806 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4807 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4808 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4809 mRenderbuffer);
4810 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4811 EXPECT_GL_NO_ERROR();
4812
4813 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4814 glClear(GL_COLOR_BUFFER_BIT);
4815
4816 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4817
4818 ASSERT_GL_NO_ERROR();
4819 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
4820 }
4821
4822 GLuint mRenderableTexture;
4823 GLuint mTestTexture;
4824 GLuint mFBO;
4825 GLuint mRenderbuffer;
4826};
4827
4828// Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
4829TEST_P(Texture2DRGTest, TextureRGUNormTest)
4830{
4831 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
James Darpinian336e8912020-05-29 16:09:47 -07004832 // This workaround causes a GL error on Windows AMD, which is likely a driver bug.
4833 // The workaround is not intended to be enabled in this configuration so skip it.
4834 ANGLE_SKIP_TEST_IF(GetParam().eglParameters.emulateCopyTexImage2DFromRenderbuffers &&
4835 IsWindows() && IsAMD());
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004836
4837 GLubyte pixelValue = 0xab;
4838 GLubyte imageData[] = {pixelValue, pixelValue};
4839
4840 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
4841 testRGTexture(
4842 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4843 testRGRender(GL_R8_EXT, GL_RED_EXT);
4844
4845 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
4846 testRGTexture(
4847 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4848 testRGRender(GL_RG8_EXT, GL_RG_EXT);
4849}
4850
4851// Test float texture formats enabled by the GL_EXT_texture_rg extension.
4852TEST_P(Texture2DRGTest, TextureRGFloatTest)
4853{
4854 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4855 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4856
4857 GLfloat pixelValue = 0.54321;
4858 GLfloat imageData[] = {pixelValue, pixelValue};
4859
4860 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
4861 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4862
4863 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
4864 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4865
4866 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
4867 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4868}
4869
4870// Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
Mohan Maiya6caa2652019-09-11 08:06:13 -07004871TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004872{
4873 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4874 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4875
4876 GLfloat pixelValueFloat = 0.543f;
4877 GLhalf pixelValue = 0x3858;
4878 GLhalf imageData[] = {pixelValue, pixelValue};
4879
4880 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
4881 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4882
4883 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
4884 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4885
4886 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
4887 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4888}
4889
Mohan Maiya6caa2652019-09-11 08:06:13 -07004890class Texture2DFloatTest : public Texture2DTest
4891{
4892 protected:
4893 Texture2DFloatTest()
4894 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4895 {}
4896
4897 void testSetUp() override
4898 {
4899 Texture2DTest::testSetUp();
4900
4901 glActiveTexture(GL_TEXTURE0);
4902 glGenTextures(1, &mRenderableTexture);
4903 glGenTextures(1, &mTestTexture);
4904 glGenFramebuffers(1, &mFBO);
4905 glGenRenderbuffers(1, &mRenderbuffer);
4906
4907 setUpProgram();
4908 glUseProgram(mProgram);
4909 glUniform1i(mTexture2DUniformLocation, 0);
4910
4911 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4912 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4913
4914 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4915 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4916 mRenderableTexture, 0);
4917
4918 ASSERT_GL_NO_ERROR();
4919 }
4920
4921 void testTearDown() override
4922 {
4923 glDeleteTextures(1, &mRenderableTexture);
4924 glDeleteTextures(1, &mTestTexture);
4925 glDeleteFramebuffers(1, &mFBO);
4926 glDeleteRenderbuffers(1, &mRenderbuffer);
4927
4928 Texture2DTest::testTearDown();
4929 }
4930
4931 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
4932 {
4933 constexpr GLfloat imageDataFloat[] = {
4934 0.2f,
4935 0.3f,
4936 0.4f,
4937 0.5f,
4938 };
4939 constexpr GLhalf imageDataHalf[] = {
4940 0x3266,
4941 0x34CD,
4942 0x3666,
4943 0x3800,
4944 };
4945 GLColor expectedValue;
4946 for (int i = 0; i < 4; i++)
4947 {
4948 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
4949 }
4950
4951 const GLvoid *imageData;
4952 switch (type)
4953 {
4954 case GL_FLOAT:
4955 imageData = imageDataFloat;
4956 break;
4957 case GL_HALF_FLOAT:
4958 case GL_HALF_FLOAT_OES:
4959 imageData = imageDataHalf;
4960 break;
4961 default:
4962 imageData = nullptr;
4963 }
4964 ASSERT(imageData != nullptr);
4965
4966 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4967 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
4968
4969 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4970 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4971
4972 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4973 drawQuad(mProgram, "position", 0.5f);
4974
4975 EXPECT_GL_NO_ERROR();
4976 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
4977 }
4978
4979 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
4980 {
4981 int numComponents;
4982 switch (format)
4983 {
4984 case GL_RGBA:
4985 numComponents = 4;
4986 break;
4987 case GL_RGB:
4988 numComponents = 3;
4989 break;
4990 case GL_LUMINANCE_ALPHA:
4991 numComponents = 2;
4992 break;
4993 case GL_LUMINANCE:
4994 case GL_ALPHA:
4995 numComponents = 1;
4996 break;
4997 default:
4998 numComponents = 0;
4999 }
5000 ASSERT(numComponents > 0);
5001
5002 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
5003 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
5004
5005 GLfloat imageDataFloat[16];
5006 GLhalf imageDataHalf[16];
5007 for (int i = 0; i < 4; i++)
5008 {
5009 for (int c = 0; c < numComponents; c++)
5010 {
5011 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
5012 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
5013 }
5014 }
5015
5016 const GLvoid *imageData;
5017 switch (type)
5018 {
5019 case GL_FLOAT:
5020 imageData = imageDataFloat;
5021 break;
5022 case GL_HALF_FLOAT:
5023 case GL_HALF_FLOAT_OES:
5024 imageData = imageDataHalf;
5025 break;
5026 default:
5027 imageData = nullptr;
5028 }
5029 ASSERT(imageData != nullptr);
5030
5031 glBindTexture(GL_TEXTURE_2D, mTestTexture);
5032 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
5033
5034 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5035 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5036
5037 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
5038 drawQuad(mProgram, "position", 0.5f);
5039
5040 EXPECT_GL_NO_ERROR();
5041 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
5042 // should expect the final value to be gray (halfway in-between)
5043 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
5044 kPixelTolerance);
5045 }
5046
5047 bool performFloatTextureRender(GLenum internalFormat,
5048 GLenum renderBufferFormat,
5049 GLenum format,
5050 GLenum type)
5051 {
5052 glBindTexture(GL_TEXTURE_2D, mTestTexture);
5053 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
5054 glBindTexture(GL_TEXTURE_2D, 0);
5055
5056 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
5057 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
5058 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
5059 mRenderbuffer);
5060 glBindRenderbuffer(GL_RENDERBUFFER, 0);
5061 EXPECT_GL_NO_ERROR();
5062
5063 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
5064 {
5065 return false;
5066 }
5067
5068 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
5069
5070 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
5071 glClear(GL_COLOR_BUFFER_BIT);
5072
5073 EXPECT_GL_NO_ERROR();
5074 return true;
5075 }
5076
5077 GLuint mRenderableTexture;
5078 GLuint mTestTexture;
5079 GLuint mFBO;
5080 GLuint mRenderbuffer;
5081};
5082
5083class Texture2DFloatTestES3 : public Texture2DFloatTest
5084{
5085 protected:
5086 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
5087 {
5088 bool framebufferComplete =
5089 performFloatTextureRender(internalFormat, internalFormat, format, type);
5090 EXPECT_TRUE(framebufferComplete);
5091 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
5092 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
5093 kPixelTolerance32F);
5094 }
5095};
5096
5097class Texture2DFloatTestES2 : public Texture2DFloatTest
5098{
5099 protected:
5100 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
5101 {
5102 bool framebufferComplete =
5103 performFloatTextureRender(format, renderBufferFormat, format, type);
5104
5105 if (!framebufferComplete)
5106 {
5107 return false;
5108 }
5109
5110 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
5111 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
5112 kPixelTolerance32F);
5113 return true;
5114 }
5115};
5116
5117// Test texture sampling for ES3 float texture formats
5118TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
5119{
5120 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
5121 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
5122}
5123
5124// Test texture sampling for ES2 float texture formats
5125TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
5126{
5127 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5128 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
5129 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
5130}
5131
5132// Test texture sampling for ES3 half float texture formats
5133TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
5134{
5135 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
5136 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
5137}
5138
5139// Test texture sampling for ES2 half float texture formats
5140TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
5141{
5142 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
5143 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
5144 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
5145}
5146
5147// Test texture sampling for legacy GLES 2.0 float texture formats in ES3
5148TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
5149{
5150 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5151
5152 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
5153 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
5154 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
5155
5156 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
5157 {
5158 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
5159 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
5160 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
5161 }
5162}
5163
5164// Test texture sampling for legacy GLES 2.0 float texture formats in ES2
5165TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
5166{
5167 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5168
5169 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
5170 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
5171 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
5172}
5173
5174// Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
5175TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
5176{
5177 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
5178
5179 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
5180 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
5181 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
5182
5183 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
5184 {
5185 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
5186 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
5187 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
5188 }
5189}
5190// Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
5191TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
5192{
5193 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
5194
5195 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
5196 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
5197 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
5198}
5199
5200// Test linear sampling for ES3 32F formats
5201TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
5202{
5203 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
5204
5205 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
5206 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
5207}
5208// Test linear sampling for ES2 32F formats
5209TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
5210{
5211 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
5212
5213 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5214
5215 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
5216}
5217
5218// Test linear sampling for ES3 16F formats
5219TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
5220{
5221 // Half float formats must be linearly filterable in GLES 3.0 core
5222 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
5223 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
5224}
5225// Test linear sampling for ES2 16F formats
5226TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
5227{
5228 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
5229 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
5230 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
5231}
5232
5233// Test linear sampling for legacy GLES 2.0 32F formats in ES3
5234TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
5235{
5236 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5237 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
5238
5239 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
5240 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
5241 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
5242
5243 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
5244 {
5245 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
5246 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
5247 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
5248 }
5249}
5250// Test linear sampling for legacy GLES 2.0 32F formats in ES2
5251TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
5252{
5253 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
5254 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
5255
5256 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
5257 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
5258 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
5259}
5260
5261// Test linear sampling for legacy GLES 2.0 16F formats in ES3
5262TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
5263{
5264 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
5265 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
5266
5267 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
5268 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
5269 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
5270
5271 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
5272 {
5273 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
5274 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
5275 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
5276 }
5277}
5278// Test linear sampling for legacy GLES 2.0 16F formats in ES2
5279TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
5280{
5281 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
5282 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
5283
5284 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
5285 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
5286 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
5287}
5288
5289// Test color-renderability for ES3 float and half float textures
5290TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
5291{
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005292 // http://anglebug.com/4092
5293 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07005294 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
5295 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
5296
5297 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
5298 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
5299 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
5300
5301 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
5302 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
5303 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
5304
5305 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
5306}
5307
5308// Test color-renderability for ES2 half float textures
5309TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
5310{
5311 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
5312 // require a specific one
5313 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
Zhenyao Mo20bb47d2019-09-16 12:55:30 -07005314 // https://crbug.com/1003971
5315 ANGLE_SKIP_TEST_IF(IsOzone());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005316 // http://anglebug.com/4092
5317 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07005318
5319 bool atLeastOneSupported = false;
5320
5321 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
5322 IsGLExtensionEnabled("GL_OES_texture_half_float"))
5323 {
5324 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
5325 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
5326 }
5327 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
5328 {
5329 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
5330
5331 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
5332 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
5333 EXPECT_TRUE(rgbaSupported);
5334 atLeastOneSupported |= rgbaSupported;
5335 }
5336
5337 EXPECT_TRUE(atLeastOneSupported);
5338}
5339
Olli Etuaho95faa232016-06-07 14:01:53 -07005340// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
5341// GLES 3.0.4 section 3.8.3.
5342TEST_P(Texture2DTestES3, UnpackSkipImages2D)
5343{
Yuly Novikovd18c0482019-04-04 19:56:43 -04005344 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
5345 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Olli Etuaho95faa232016-06-07 14:01:53 -07005346
5347 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5348 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5350 ASSERT_GL_NO_ERROR();
5351
5352 // SKIP_IMAGES should not have an effect on uploading 2D textures
5353 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
5354 ASSERT_GL_NO_ERROR();
5355
5356 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5357
5358 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5359 pixelsGreen.data());
5360 ASSERT_GL_NO_ERROR();
5361
5362 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
5363 pixelsGreen.data());
5364 ASSERT_GL_NO_ERROR();
5365
5366 glUseProgram(mProgram);
5367 drawQuad(mProgram, "position", 0.5f);
5368 ASSERT_GL_NO_ERROR();
5369
5370 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5371}
5372
Olli Etuaho989cac32016-06-08 16:18:49 -07005373// Test that skip defined in unpack parameters is taken into account when determining whether
5374// unpacking source extends outside unpack buffer bounds.
5375TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
5376{
5377 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5378 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5379 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5380 ASSERT_GL_NO_ERROR();
5381
5382 GLBuffer buf;
5383 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5384 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5385 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5386 GL_DYNAMIC_COPY);
5387 ASSERT_GL_NO_ERROR();
5388
5389 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5390 ASSERT_GL_NO_ERROR();
5391
5392 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
5393 ASSERT_GL_NO_ERROR();
5394
5395 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5396 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5397
5398 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
5399 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
5400 ASSERT_GL_NO_ERROR();
5401
5402 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5403 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5404}
5405
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005406// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
5407TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
5408{
Yunchao He9550c602018-02-13 14:47:05 +08005409 ANGLE_SKIP_TEST_IF(IsD3D11());
5410
5411 // Incorrect rendering results seen on OSX AMD.
5412 ANGLE_SKIP_TEST_IF(IsOSX() && IsAMD());
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005413
5414 const GLuint width = 8u;
5415 const GLuint height = 8u;
5416 const GLuint unpackRowLength = 5u;
5417 const GLuint unpackSkipPixels = 1u;
5418
5419 setWindowWidth(width);
5420 setWindowHeight(height);
5421
5422 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5425 ASSERT_GL_NO_ERROR();
5426
5427 GLBuffer buf;
5428 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5429 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
5430 GLColor::green);
5431
5432 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
5433 {
5434 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
5435 }
5436
5437 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5438 GL_DYNAMIC_COPY);
5439 ASSERT_GL_NO_ERROR();
5440
5441 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
5442 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
5443 ASSERT_GL_NO_ERROR();
5444
5445 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5446 ASSERT_GL_NO_ERROR();
5447
5448 glUseProgram(mProgram);
5449 drawQuad(mProgram, "position", 0.5f);
5450 ASSERT_GL_NO_ERROR();
5451
5452 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
5453 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
5454 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
5455 actual.data());
5456 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
5457 EXPECT_EQ(expected, actual);
5458}
5459
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005460template <typename T>
5461T UNorm(double value)
5462{
5463 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
5464}
5465
5466// Test rendering a depth texture with mipmaps.
5467TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
5468{
Zhenyao Moe520d7c2017-01-13 13:46:49 -08005469 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
5470 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
Jiawei Shaoaf0f31d2018-09-27 15:42:31 +08005471 // http://anglebug.com/1706
5472 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Corentin Walleze731d8a2016-09-07 10:56:25 -04005473
Jamie Madill24980272019-04-03 09:03:51 -04005474 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
5475 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
5476
Cody Northrop988f7172019-09-30 15:52:37 -06005477 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005478 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
5479
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005480 const int size = getWindowWidth();
5481
5482 auto dim = [size](int level) { return size >> level; };
Jamie Madill14718762016-09-06 15:56:54 -04005483 int levels = gl::log2(size);
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005484
5485 glActiveTexture(GL_TEXTURE0);
5486 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5487 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
5488 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5489 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5490 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5491 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5492 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5493 ASSERT_GL_NO_ERROR();
5494
5495 glUseProgram(mProgram);
5496 glUniform1i(mTexture2DUniformLocation, 0);
5497
5498 std::vector<unsigned char> expected;
5499
5500 for (int level = 0; level < levels; ++level)
5501 {
5502 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
5503 expected.push_back(UNorm<unsigned char>(value));
5504
5505 int levelDim = dim(level);
5506
5507 ASSERT_GT(levelDim, 0);
5508
5509 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
5510 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
5511 GL_UNSIGNED_INT, initData.data());
5512 }
5513 ASSERT_GL_NO_ERROR();
5514
5515 for (int level = 0; level < levels; ++level)
5516 {
5517 glViewport(0, 0, dim(level), dim(level));
5518 drawQuad(mProgram, "position", 0.5f);
5519 GLColor actual = ReadColor(0, 0);
5520 EXPECT_NEAR(expected[level], actual.R, 10u);
5521 }
5522
5523 ASSERT_GL_NO_ERROR();
5524}
5525
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005526class Texture2DDepthTest : public Texture2DTest
5527{
5528 protected:
5529 Texture2DDepthTest() : Texture2DTest() {}
5530
5531 const char *getVertexShaderSource() override
5532 {
5533 return "attribute vec4 vPosition;\n"
5534 "void main() {\n"
5535 " gl_Position = vPosition;\n"
5536 "}\n";
5537 }
5538
5539 const char *getFragmentShaderSource() override
5540 {
5541 return "precision mediump float;\n"
5542 "uniform sampler2D ShadowMap;"
5543 "void main() {\n"
5544 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
5545 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
5546 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
5547 " } else {"
5548 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
5549 " }"
5550 "}\n";
5551 }
5552
5553 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
5554 {
5555 EXPECT_GL_NO_ERROR();
5556
5557 GLTexture tex;
5558 glBindTexture(GL_TEXTURE_2D, tex);
5559 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
5560
5561 return (glGetError() == GL_NO_ERROR);
5562 }
5563
5564 void testBehavior(bool useSizedComponent)
5565 {
5566 int w = getWindowWidth();
5567 int h = getWindowHeight();
5568 GLuint format = GL_DEPTH_COMPONENT;
5569 GLuint internalFormat = GL_DEPTH_COMPONENT;
5570
5571 if (useSizedComponent)
5572 {
5573 internalFormat = GL_DEPTH_COMPONENT24;
5574 }
5575
5576 GLFramebuffer fbo;
5577 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5578 ASSERT_GL_NO_ERROR();
5579
5580 GLTexture depthTexture;
5581 glBindTexture(GL_TEXTURE_2D, depthTexture);
5582 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5583 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5586
5587 TexCoordDrawTest::setUpProgram();
5588 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
5589 ASSERT_NE(-1, shadowMapLocation);
5590
5591 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
5592 ASSERT_NE(-1, positionLocation);
5593
5594 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
5595 glBindTexture(GL_TEXTURE_2D, depthTexture);
5596 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
5597 ASSERT_GL_NO_ERROR();
5598
5599 // try adding a color buffer.
5600 GLuint colorTex = 0;
5601 glGenTextures(1, &colorTex);
5602 glBindTexture(GL_TEXTURE_2D, colorTex);
5603 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5604 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5605 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5606 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5607 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5608 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
5609 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
5610 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5611 ASSERT_GL_NO_ERROR();
5612
5613 glViewport(0, 0, w, h);
5614 // Fill depthTexture with 0.75
5615 glClearDepthf(0.75);
5616 glClear(GL_DEPTH_BUFFER_BIT);
5617
5618 // Revert to normal framebuffer to test depth shader
5619 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5620 glViewport(0, 0, w, h);
5621 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5622 glClearDepthf(0.0f);
5623 ASSERT_GL_NO_ERROR();
5624
5625 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
5626 ASSERT_GL_NO_ERROR();
5627
5628 glActiveTexture(GL_TEXTURE0);
5629 glBindTexture(GL_TEXTURE_2D, depthTexture);
5630
5631 glUseProgram(mProgram);
5632 ASSERT_GL_NO_ERROR();
5633
5634 glUniform1i(shadowMapLocation, 0);
5635
5636 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
5637
5638 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
5639 ASSERT_GL_NO_ERROR();
5640 glEnableVertexAttribArray(positionLocation);
5641 ASSERT_GL_NO_ERROR();
5642 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5643 ASSERT_GL_NO_ERROR();
5644
5645 GLuint pixels[1];
5646 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
5647 ASSERT_GL_NO_ERROR();
5648
5649 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
5650 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
5651 // is in all the color components. Multiple implementations implement a workaround that
5652 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
5653 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
5654 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
5655 // depending on if it sees the texture sample in only the RED component.
5656 if (useSizedComponent)
5657 {
5658 ASSERT_NE(pixels[0], 0xff0000ff);
5659 }
5660 else
5661 {
5662 ASSERT_EQ(pixels[0], 0xff0000ff);
5663 }
5664
5665 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5666 glDeleteProgram(mProgram);
5667 }
5668};
5669
5670// Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
5671TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
5672{
5673 ANGLE_SKIP_TEST_IF(IsD3D11());
5674 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
Tobin Ehlis7af26762019-10-23 16:18:57 -06005675 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
5676 !IsGLExtensionEnabled("GL_OES_depth_texture"));
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005677 // http://anglebug.com/4092
5678 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01005679 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005680
5681 // When the depth texture is specified with unsized internalformat implementations follow
5682 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
5683 testBehavior(false);
5684}
5685
5686// Test depth texture compatibility with GLES3 using sized internalformat.
5687TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
5688{
5689 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
5690
5691 testBehavior(true);
5692}
5693
Jamie Madill7ffdda92016-09-08 13:26:51 -04005694// Tests unpacking into the unsized GL_ALPHA format.
5695TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
5696{
Jamie Madill7ffdda92016-09-08 13:26:51 -04005697 // Initialize the texure.
5698 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5699 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
5700 GL_UNSIGNED_BYTE, nullptr);
5701 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5702 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5703
5704 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
5705
5706 // Pull in the color data from the unpack buffer.
Jamie Madill2e600342016-09-19 13:56:40 -04005707 GLBuffer unpackBuffer;
Jamie Madill7ffdda92016-09-08 13:26:51 -04005708 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5709 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5710 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
5711 GL_STATIC_DRAW);
5712
5713 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
5714 GL_UNSIGNED_BYTE, nullptr);
5715
5716 // Clear to a weird color to make sure we're drawing something.
5717 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
5718 glClear(GL_COLOR_BUFFER_BIT);
5719
5720 // Draw with the alpha texture and verify.
5721 drawQuad(mProgram, "position", 0.5f);
Jamie Madill7ffdda92016-09-08 13:26:51 -04005722
5723 ASSERT_GL_NO_ERROR();
5724 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
5725}
5726
Jamie Madill2e600342016-09-19 13:56:40 -04005727// Ensure stale unpack data doesn't propagate in D3D11.
5728TEST_P(Texture2DTestES3, StaleUnpackData)
5729{
5730 // Init unpack buffer.
5731 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
5732 std::vector<GLColor> pixels(pixelCount, GLColor::red);
5733
5734 GLBuffer unpackBuffer;
5735 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5736 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5737 GLsizei bufferSize = pixelCount * sizeof(GLColor);
5738 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
5739
5740 // Create from unpack buffer.
5741 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5742 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
5743 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5744 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5745 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5746
5747 drawQuad(mProgram, "position", 0.5f);
5748
5749 ASSERT_GL_NO_ERROR();
5750 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5751
5752 // Fill unpack with green, recreating buffer.
5753 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
5754 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
5755 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
5756
5757 // Reinit texture with green.
5758 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
5759 GL_UNSIGNED_BYTE, nullptr);
5760
5761 drawQuad(mProgram, "position", 0.5f);
5762
5763 ASSERT_GL_NO_ERROR();
5764 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5765}
5766
Geoff Langfb7685f2017-11-13 11:44:11 -05005767// Ensure that texture parameters passed as floats that are converted to ints are rounded before
5768// validating they are less than 0.
5769TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
5770{
5771 GLTexture texture;
5772 glBindTexture(GL_TEXTURE_2D, texture);
5773
5774 // Use a negative number that will round to zero when converted to an integer
5775 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
5776 // "Validation of values performed by state-setting commands is performed after conversion,
5777 // unless specified otherwise for a specific command."
5778 GLfloat param = -7.30157126e-07f;
5779 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
5780 EXPECT_GL_NO_ERROR();
5781
5782 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
5783 EXPECT_GL_NO_ERROR();
5784}
5785
Jamie Madillf097e232016-11-05 00:44:15 -04005786// This test covers a D3D format redefinition bug for 3D textures. The base level format was not
5787// being properly checked, and the texture storage of the previous texture format was persisting.
5788// This would result in an ASSERT in debug and incorrect rendering in release.
5789// See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
5790TEST_P(Texture3DTestES3, FormatRedefinitionBug)
5791{
5792 GLTexture tex;
5793 glBindTexture(GL_TEXTURE_3D, tex.get());
5794 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5795
5796 GLFramebuffer framebuffer;
5797 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
5798 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
5799
5800 glCheckFramebufferStatus(GL_FRAMEBUFFER);
5801
5802 std::vector<uint8_t> pixelData(100, 0);
5803
5804 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
5805 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
5806 pixelData.data());
5807
5808 ASSERT_GL_NO_ERROR();
5809}
5810
Corentin Wallezd2627992017-04-28 17:17:03 -04005811// Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
5812TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
5813{
5814 // 2D tests
5815 {
5816 GLTexture tex;
5817 glBindTexture(GL_TEXTURE_2D, tex.get());
5818
5819 GLBuffer pbo;
5820 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5821
5822 // Test OOB
5823 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
5824 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5825 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5826
5827 // Test OOB
5828 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
5829 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5830 ASSERT_GL_NO_ERROR();
5831 }
5832
5833 // 3D tests
5834 {
5835 GLTexture tex;
5836 glBindTexture(GL_TEXTURE_3D, tex.get());
5837
5838 GLBuffer pbo;
5839 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5840
5841 // Test OOB
5842 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
5843 GL_STATIC_DRAW);
5844 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5845 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5846
5847 // Test OOB
5848 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
5849 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5850 ASSERT_GL_NO_ERROR();
5851 }
5852}
5853
Jamie Madill3ed60422017-09-07 11:32:52 -04005854// Tests behaviour with a single texture and multiple sampler objects.
5855TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
5856{
5857 GLint maxTextureUnits = 0;
5858 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
5859 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
5860
5861 constexpr int kSize = 16;
5862
5863 // Make a single-level texture, fill it with red.
5864 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
5865 GLTexture tex;
5866 glBindTexture(GL_TEXTURE_2D, tex);
5867 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5868 redColors.data());
5869 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5871
5872 // Simple sanity check.
5873 draw2DTexturedQuad(0.5f, 1.0f, true);
5874 ASSERT_GL_NO_ERROR();
5875 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5876
5877 // Bind texture to unit 1 with a sampler object making it incomplete.
5878 GLSampler sampler;
5879 glBindSampler(0, sampler);
5880 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5881 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5882
5883 // Make a mipmap texture, fill it with blue.
5884 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
5885 GLTexture mipmapTex;
5886 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5887 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5888 blueColors.data());
5889 glGenerateMipmap(GL_TEXTURE_2D);
5890
5891 // Draw with the sampler, expect blue.
5892 draw2DTexturedQuad(0.5f, 1.0f, true);
5893 ASSERT_GL_NO_ERROR();
5894 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5895
5896 // Simple multitexturing program.
Jamie Madill35cd7332018-12-02 12:03:33 -05005897 constexpr char kVS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005898 "#version 300 es\n"
5899 "in vec2 position;\n"
5900 "out vec2 texCoord;\n"
5901 "void main()\n"
5902 "{\n"
5903 " gl_Position = vec4(position, 0, 1);\n"
5904 " texCoord = position * 0.5 + vec2(0.5);\n"
5905 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05005906
5907 constexpr char kFS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005908 "#version 300 es\n"
5909 "precision mediump float;\n"
5910 "in vec2 texCoord;\n"
5911 "uniform sampler2D tex1;\n"
5912 "uniform sampler2D tex2;\n"
5913 "uniform sampler2D tex3;\n"
5914 "uniform sampler2D tex4;\n"
5915 "out vec4 color;\n"
5916 "void main()\n"
5917 "{\n"
5918 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
5919 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
5920 "}";
5921
Jamie Madill35cd7332018-12-02 12:03:33 -05005922 ANGLE_GL_PROGRAM(program, kVS, kFS);
Jamie Madill3ed60422017-09-07 11:32:52 -04005923
5924 std::array<GLint, 4> texLocations = {
5925 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
5926 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
5927 for (GLint location : texLocations)
5928 {
5929 ASSERT_NE(-1, location);
5930 }
5931
5932 // Init the uniform data.
5933 glUseProgram(program);
5934 for (GLint location = 0; location < 4; ++location)
5935 {
5936 glUniform1i(texLocations[location], location);
5937 }
5938
5939 // Initialize four samplers
5940 GLSampler samplers[4];
5941
5942 // 0: non-mipped.
5943 glBindSampler(0, samplers[0]);
5944 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5945 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5946
5947 // 1: mipped.
5948 glBindSampler(1, samplers[1]);
5949 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5950 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5951
5952 // 2: non-mipped.
5953 glBindSampler(2, samplers[2]);
5954 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5955 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5956
5957 // 3: mipped.
5958 glBindSampler(3, samplers[3]);
5959 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5960 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5961
5962 // Bind two blue mipped textures and two single layer textures, should all draw.
5963 glActiveTexture(GL_TEXTURE0);
5964 glBindTexture(GL_TEXTURE_2D, tex);
5965
5966 glActiveTexture(GL_TEXTURE1);
5967 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5968
5969 glActiveTexture(GL_TEXTURE2);
5970 glBindTexture(GL_TEXTURE_2D, tex);
5971
5972 glActiveTexture(GL_TEXTURE3);
5973 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5974
5975 ASSERT_GL_NO_ERROR();
5976
5977 drawQuad(program, "position", 0.5f);
5978 ASSERT_GL_NO_ERROR();
5979 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
5980
5981 // Bind four single layer textures, two should be incomplete.
5982 glActiveTexture(GL_TEXTURE1);
5983 glBindTexture(GL_TEXTURE_2D, tex);
5984
5985 glActiveTexture(GL_TEXTURE3);
5986 glBindTexture(GL_TEXTURE_2D, tex);
5987
5988 drawQuad(program, "position", 0.5f);
5989 ASSERT_GL_NO_ERROR();
5990 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
5991}
5992
Martin Radev7e2c0d32017-09-15 14:25:42 +03005993// The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
5994// always at level 0 instead of the base level resulting in an incomplete texture if the faces at
5995// level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
5996// level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
5997// samples the cubemap using a direction vector (1,1,1).
5998TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
5999{
Yunchao He2f23f352018-02-11 22:11:37 +08006000 // Check http://anglebug.com/2155.
6001 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
6002
Jamie Madill35cd7332018-12-02 12:03:33 -05006003 constexpr char kVS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03006004 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03006005 precision mediump float;
6006 in vec3 pos;
6007 void main() {
6008 gl_Position = vec4(pos, 1.0);
6009 })";
Martin Radev7e2c0d32017-09-15 14:25:42 +03006010
Jamie Madill35cd7332018-12-02 12:03:33 -05006011 constexpr char kFS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03006012 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03006013 precision mediump float;
6014 out vec4 color;
6015 uniform samplerCube uTex;
6016 void main(){
6017 color = texture(uTex, vec3(1.0));
6018 })";
Jamie Madill35cd7332018-12-02 12:03:33 -05006019
6020 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev7e2c0d32017-09-15 14:25:42 +03006021 glUseProgram(program);
6022
6023 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
6024 glActiveTexture(GL_TEXTURE0);
6025
6026 GLTexture cubeTex;
6027 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
6028
6029 const int kFaceWidth = 1;
6030 const int kFaceHeight = 1;
6031 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
6032 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
6033 GL_UNSIGNED_BYTE, texData.data());
6034 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
6035 GL_UNSIGNED_BYTE, texData.data());
6036 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
6037 GL_UNSIGNED_BYTE, texData.data());
6038 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
6039 GL_UNSIGNED_BYTE, texData.data());
6040 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
6041 GL_UNSIGNED_BYTE, texData.data());
6042 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
6043 GL_UNSIGNED_BYTE, texData.data());
6044 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6045 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6046 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
6047 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
6048 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
6049 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
6050
6051 drawQuad(program, "pos", 0.5f, 1.0f, true);
6052 ASSERT_GL_NO_ERROR();
6053
6054 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
6055}
6056
Jiawei Shao3c43b4d2018-02-23 11:08:28 +08006057// Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
6058TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
6059{
6060 GLuint texture = create2DTexture();
6061
6062 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
6063 EXPECT_GL_ERROR(GL_INVALID_VALUE);
6064
6065 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
6066 EXPECT_GL_ERROR(GL_INVALID_VALUE);
6067
6068 glDeleteTextures(1, &texture);
6069 EXPECT_GL_NO_ERROR();
6070}
6071
Olli Etuaho023371b2018-04-24 17:43:32 +03006072// Test setting base level after calling generateMipmap on a LUMA texture.
6073// Covers http://anglebug.com/2498
6074TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
6075{
6076 glActiveTexture(GL_TEXTURE0);
6077 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6078
6079 constexpr const GLsizei kWidth = 8;
6080 constexpr const GLsizei kHeight = 8;
6081 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
6082 whiteData.fill(255u);
6083
6084 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
6085 GL_UNSIGNED_BYTE, whiteData.data());
6086 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
6087 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6088 glGenerateMipmap(GL_TEXTURE_2D);
6089 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
6090 EXPECT_GL_NO_ERROR();
6091
6092 drawQuad(mProgram, "position", 0.5f);
6093 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
6094}
6095
Till Rathmannc1551dc2018-08-15 17:04:49 +02006096// Covers a bug in the D3D11 backend: http://anglebug.com/2772
6097// When using a sampler the texture was created as if it has mipmaps,
6098// regardless what you specified in GL_TEXTURE_MIN_FILTER via
6099// glSamplerParameteri() -- mistakenly the default value
6100// GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
6101// evaluated.
6102// If you didn't provide mipmaps and didn't let the driver generate them
6103// this led to not sampling your texture data when minification occurred.
6104TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
6105{
Jamie Madill35cd7332018-12-02 12:03:33 -05006106 constexpr char kVS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02006107 "#version 300 es\n"
6108 "out vec2 texcoord;\n"
6109 "in vec4 position;\n"
6110 "void main()\n"
6111 "{\n"
6112 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
6113 " texcoord = (position.xy * 0.5) + 0.5;\n"
6114 "}\n";
6115
Jamie Madill35cd7332018-12-02 12:03:33 -05006116 constexpr char kFS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02006117 "#version 300 es\n"
6118 "precision highp float;\n"
6119 "uniform highp sampler2D tex;\n"
6120 "in vec2 texcoord;\n"
6121 "out vec4 fragColor;\n"
6122 "void main()\n"
6123 "{\n"
6124 " fragColor = texture(tex, texcoord);\n"
6125 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -05006126
6127 ANGLE_GL_PROGRAM(program, kVS, kFS);
Till Rathmannc1551dc2018-08-15 17:04:49 +02006128
6129 GLSampler sampler;
6130 glBindSampler(0, sampler);
6131 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6132 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6133
6134 glActiveTexture(GL_TEXTURE0);
6135 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6136
6137 const GLsizei texWidth = getWindowWidth();
6138 const GLsizei texHeight = getWindowHeight();
6139 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
6140
6141 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6142 whiteData.data());
6143 EXPECT_GL_NO_ERROR();
6144
6145 drawQuad(program, "position", 0.5f);
6146 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
6147}
6148
Anders Leinof6cbe442019-04-18 15:32:07 +03006149// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
6150// texture is output.
6151TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
6152{
Yuly Novikovd2683452019-05-23 16:11:19 -04006153 // http://anglebug.com/3478
6154 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
6155
Anders Leinof6cbe442019-04-18 15:32:07 +03006156 glActiveTexture(GL_TEXTURE0);
6157 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6158 int width = getWindowWidth();
6159 int height = getWindowHeight();
6160 GLColor color = GLColor::green;
6161 std::vector<GLColor> pixels(width * height, color);
6162 GLint baseLevel = 1;
6163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6166 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
6167 GL_UNSIGNED_BYTE, pixels.data());
6168
6169 setUpProgram();
6170 glUseProgram(mProgram);
6171 glUniform1i(mTexture2DUniformLocation, 0);
6172 drawQuad(mProgram, "position", 0.5f);
6173
6174 EXPECT_GL_NO_ERROR();
6175 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6176 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6177}
6178
Anders Leino60cc7512019-05-06 09:25:27 +03006179// Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
6180// the texture is output.
6181TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
6182{
6183 // All output checks returned black, rather than the texture color.
6184 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
6185
6186 glActiveTexture(GL_TEXTURE0);
6187
6188 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
6189 GLint baseLevel = 1;
6190 int width = getWindowWidth();
6191 int height = getWindowHeight();
6192 GLColor color = GLColor::green;
6193 std::vector<GLColor> pixels(width * height, color);
6194 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
6195 {
6196 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
6197 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
6198 EXPECT_GL_NO_ERROR();
6199 }
6200 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
6201 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6202 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6203
6204 glUseProgram(mProgram);
6205 glUniform1i(mTextureCubeUniformLocation, 0);
6206 drawQuad(mProgram, "position", 0.5f);
6207
6208 EXPECT_GL_NO_ERROR();
6209 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6210 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
6211 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
6212 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6213}
6214
Anders Leinoe4452442019-05-09 13:29:49 +03006215// This test sets up a cube map with four distincly colored MIP levels.
6216// The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
6217// the corners of the screen.
6218TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
6219{
6220 glActiveTexture(GL_TEXTURE0);
6221
6222 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
6223 int width = getWindowWidth();
6224 int height = getWindowHeight();
6225 ASSERT_EQ(width, height);
6226 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
6227 for (GLint level = 0; level < 4; level++)
6228 {
6229 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
6230 {
6231 int levelWidth = (2 * width) >> level;
6232 int levelHeight = (2 * height) >> level;
6233 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
6234 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
6235 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
6236 EXPECT_GL_NO_ERROR();
6237 }
6238 }
6239 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
6240 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6241 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
6242
6243 glUseProgram(mProgram);
6244 glUniform1i(mTextureCubeUniformLocation, 0);
6245 drawQuad(mProgram, "position", 0.5f);
6246
6247 ASSERT_GL_NO_ERROR();
6248 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
6249 EXPECT_EQ(ReadColor(0, 0).R, 0);
6250 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
6251 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
6252 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
6253}
6254
Anders Leino1b6aded2019-05-20 12:56:34 +03006255// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
6256// texture is output.
6257TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
6258{
Jamie Madill29ac2742019-05-28 15:53:00 -04006259 // Fails on AMD: http://crbug.com/967796
Jamie Madill06055b52019-05-29 14:31:42 -04006260 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
Jamie Madill29ac2742019-05-28 15:53:00 -04006261
Anders Leino1b6aded2019-05-20 12:56:34 +03006262 glActiveTexture(GL_TEXTURE0);
6263 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6264 int width = getWindowWidth();
6265 int height = getWindowHeight();
6266 GLColor color = GLColor::green;
6267 std::vector<GLColor> pixels(width * height, color);
6268 GLint baseLevel = 1;
6269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6272 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
6273 GL_UNSIGNED_BYTE, pixels.data());
6274
6275 setUpProgram();
6276 glUseProgram(mProgram);
6277 glUniform1i(mTexture2DUniformLocation, 0);
6278 drawQuad(mProgram, "position", 0.5f);
6279
6280 EXPECT_GL_NO_ERROR();
6281 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6282 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6283}
6284
Anders Leino69d04932019-05-20 14:04:13 +03006285// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
6286// texture is output.
6287TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
6288{
6289 glActiveTexture(GL_TEXTURE0);
6290 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6291 int width = getWindowWidth();
6292 int height = getWindowHeight();
6293 int depth = 2;
6294 GLColor color = GLColor::green;
6295 std::vector<GLColor> pixels(width * height * depth, color);
6296 GLint baseLevel = 1;
6297 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
6298 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
6299 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
6300 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6301 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6302
6303 drawQuad(mProgram, "position", 0.5f);
6304
6305 EXPECT_GL_NO_ERROR();
6306 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6307 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6308}
6309
Anders Leino262e2822019-05-20 14:24:40 +03006310// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
6311// texture is output.
6312TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
6313{
6314 glActiveTexture(GL_TEXTURE0);
6315 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6316 int width = getWindowWidth();
6317 int height = getWindowHeight();
6318 int depth = 2;
6319 GLColor color = GLColor::green;
6320 std::vector<GLColor> pixels(width * height * depth, color);
6321 GLint baseLevel = 1;
6322 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
6323 GL_UNSIGNED_BYTE, pixels.data());
6324 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6325 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6326 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6327
6328 drawQuad(mProgram, "position", 0.5f);
6329
6330 EXPECT_GL_NO_ERROR();
6331 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6332 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6333}
6334
Jamie Madillfc3ec572019-11-27 21:43:22 +00006335// Test that uses glCompressedTexSubImage2D combined with a PBO
6336TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
6337{
6338 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6339 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6340 // http://anglebug.com/4115
6341 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
6342 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
6343
6344 if (getClientMajorVersion() < 3)
6345 {
6346 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
6347 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
6348 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
6349 }
6350
6351 const GLuint width = 4u;
6352 const GLuint height = 4u;
6353
6354 setWindowWidth(width);
6355 setWindowHeight(height);
6356
6357 // Setup primary Texture
6358 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6359 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6361
6362 if (getClientMajorVersion() < 3)
6363 {
6364 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6365 }
6366 else
6367 {
6368 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6369 }
6370 ASSERT_GL_NO_ERROR();
6371
6372 // Setup PBO and fill it with a red
6373 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
6374 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
6375 ASSERT_GL_NO_ERROR();
6376
6377 // Write PBO to mTexture
6378 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
6379 width * height / 2u, nullptr);
6380 ASSERT_GL_NO_ERROR();
6381
6382 setUpProgram();
6383 // Draw using PBO updated texture
6384 glUseProgram(mProgram);
6385 glUniform1i(mTexture2DUniformLocation, 0);
6386 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6387 drawQuad(mProgram, "position", 0.5f);
6388 ASSERT_GL_NO_ERROR();
6389
6390 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6391 ASSERT_GL_NO_ERROR();
6392}
6393
Cody Northrop74e816b2020-03-26 17:40:25 -06006394// Test using ETC1_RGB8 with subimage updates
6395TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
6396{
6397 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6398 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6399
6400 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
6401 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
6402 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6403
6404 const GLuint width = 4u;
6405 const GLuint height = 4u;
6406
6407 setWindowWidth(width);
6408 setWindowHeight(height);
6409
6410 // Setup primary Texture
6411 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6412 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6413
6414 if (getClientMajorVersion() < 3)
6415 {
6416 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6417 }
6418 else
6419 {
6420 glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6421 }
6422 ASSERT_GL_NO_ERROR();
6423
6424 // Populate a subimage of the texture
6425 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6426 width * height / 2u, kCompressedImageETC2);
6427 ASSERT_GL_NO_ERROR();
6428
6429 // Render and ensure we get red
6430 glUseProgram(mProgram);
6431 drawQuad(mProgram, "position", 0.5f);
6432 ASSERT_GL_NO_ERROR();
6433
6434 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6435 ASSERT_GL_NO_ERROR();
6436}
6437
Ian Elliotteba008a2020-05-05 10:46:21 -06006438// Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
6439// MAX_LEVEL and draw. This used to cause Vulkan validation errors.
6440TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
6441{
6442 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6443 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6444
6445 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
6446 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6447
6448 const GLuint width = 4u;
6449 const GLuint height = 4u;
6450
6451 setWindowWidth(width);
6452 setWindowHeight(height);
6453
6454 // Setup primary Texture
6455 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6456 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6457
6458 if (getClientMajorVersion() < 3)
6459 {
6460 glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6461 }
6462 else
6463 {
6464 glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6465 }
6466 ASSERT_GL_NO_ERROR();
6467
6468 // Populate a subimage of the texture
6469 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6470 width * height / 2u, kCompressedImageETC2);
6471 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
6472 width * height / 2u, kCompressedImageETC2);
6473 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
6474 width * height / 2u, kCompressedImageETC2);
6475 ASSERT_GL_NO_ERROR();
6476
6477 // Set MAX_LEVEL to 2 (the highest level)
6478 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6479
6480 // Render and ensure we get red
6481 glUseProgram(mProgram);
6482 drawQuad(mProgram, "position", 0.5f);
6483 ASSERT_GL_NO_ERROR();
6484 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6485 ASSERT_GL_NO_ERROR();
6486
6487 // Decrease MAX_LEVEL to 0, render, and ensure we still get red
6488 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6489 drawQuad(mProgram, "position", 0.5f);
6490 ASSERT_GL_NO_ERROR();
6491 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6492 ASSERT_GL_NO_ERROR();
6493
6494 // Increase MAX_LEVEL back to 2, render, and ensure we still get red
6495 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6496 drawQuad(mProgram, "position", 0.5f);
6497 ASSERT_GL_NO_ERROR();
6498 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6499 ASSERT_GL_NO_ERROR();
6500}
6501
Jamie Madill50cf2be2018-06-15 09:46:57 -04006502// Use this to select which configurations (e.g. which renderer, which GLES major version) these
6503// tests should be run against.
James Darpinian336e8912020-05-29 16:09:47 -07006504#define ES2_EMULATE_COPY_TEX_IMAGE() \
6505 WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGL()), \
6506 WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGLES())
6507#define ES3_EMULATE_COPY_TEX_IMAGE() \
6508 WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()), \
6509 WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES())
6510ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ES2_EMULATE_COPY_TEX_IMAGE());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006511ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
6512ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
6513ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
6514ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
6515ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
6516ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3);
Shahbaz Youssefidbb18b52020-06-05 15:23:17 -04006517ANGLE_INSTANTIATE_TEST_ES3(Texture2DBaseMaxTestES3);
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006518ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
6519ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
6520ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
6521ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
6522ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
6523ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
6524ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
6525ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
6526ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
6527ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
6528ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
6529ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
6530ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
6531ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
6532ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
6533ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
6534ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
6535ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
James Darpinian336e8912020-05-29 16:09:47 -07006536ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
6537 ANGLE_ALL_TEST_PLATFORMS_ES2,
6538 ANGLE_ALL_TEST_PLATFORMS_ES3,
6539 ES2_EMULATE_COPY_TEX_IMAGE(),
6540 ES3_EMULATE_COPY_TEX_IMAGE());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006541ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
6542ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
6543ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
6544ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
6545ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
6546ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
6547ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
6548ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
6549ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
6550ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
Jamie Madillfc3ec572019-11-27 21:43:22 +00006551ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
Cody Northrop74e816b2020-03-26 17:40:25 -06006552ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
Jamie Madillfa05f602015-05-07 13:47:11 -04006553
Jamie Madill7ffdda92016-09-08 13:26:51 -04006554} // anonymous namespace