blob: ec3b4da1340b267f4c803fd16f8f9e315a5c6c46 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Jamie Madill14718762016-09-06 15:56:54 -04007#include "common/mathutil.h"
Corentin Wallezd3970de2015-05-14 11:07:48 -04008#include "test_utils/ANGLETest.h"
Olli Etuaho989cac32016-06-08 16:18:49 -07009#include "test_utils/gl_raii.h"
Jamie Madillf67115c2014-04-22 13:14:05 -040010
Jamie Madillfa05f602015-05-07 13:47:11 -040011using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070012
Jamie Madillfa05f602015-05-07 13:47:11 -040013namespace
14{
15
Mohan Maiya6caa2652019-09-11 08:06:13 -070016constexpr GLuint kPixelTolerance = 1u;
17constexpr GLfloat kPixelTolerance32F = 0.01f;
Mohan Maiya8f1169e2019-06-27 15:32:32 -070018
Jamie Madillfc3ec572019-11-27 21:43:22 +000019// Single compressed ETC2 block of source pixels all set red
20constexpr uint8_t kCompressedImageETC2[] = {0x7E, 0x80, 0x04, 0x7F, 0x00, 0x07, 0xE0, 0x00};
21
Vincent Lang25ab4512016-05-13 18:13:59 +020022// Take a pixel, and reset the components not covered by the format to default
Geoff Langf607c602016-09-21 11:46:48 -040023// values. In particular, the default value for the alpha component is 255
Vincent Lang25ab4512016-05-13 18:13:59 +020024// (1.0 as unsigned normalized fixed point value).
Mohan Maiya6caa2652019-09-11 08:06:13 -070025// For legacy formats, the components may be reordered to match the color that
26// would be created if a pixel of that format was initialized from the given color
Geoff Langf607c602016-09-21 11:46:48 -040027GLColor SliceFormatColor(GLenum format, GLColor full)
Vincent Lang25ab4512016-05-13 18:13:59 +020028{
29 switch (format)
30 {
31 case GL_RED:
Geoff Langf607c602016-09-21 11:46:48 -040032 return GLColor(full.R, 0, 0, 255u);
Vincent Lang25ab4512016-05-13 18:13:59 +020033 case GL_RG:
Geoff Langf607c602016-09-21 11:46:48 -040034 return GLColor(full.R, full.G, 0, 255u);
Vincent Lang25ab4512016-05-13 18:13:59 +020035 case GL_RGB:
Geoff Langf607c602016-09-21 11:46:48 -040036 return GLColor(full.R, full.G, full.B, 255u);
Vincent Lang25ab4512016-05-13 18:13:59 +020037 case GL_RGBA:
38 return full;
Mohan Maiya6caa2652019-09-11 08:06:13 -070039 case GL_LUMINANCE:
40 return GLColor(full.R, full.R, full.R, 255u);
41 case GL_ALPHA:
42 return GLColor(0, 0, 0, full.R);
43 case GL_LUMINANCE_ALPHA:
44 return GLColor(full.R, full.R, full.R, full.G);
Vincent Lang25ab4512016-05-13 18:13:59 +020045 default:
Jamie Madille1faacb2016-12-13 12:42:14 -050046 EXPECT_TRUE(false);
Geoff Langf607c602016-09-21 11:46:48 -040047 return GLColor::white;
Vincent Lang25ab4512016-05-13 18:13:59 +020048 }
Vincent Lang25ab4512016-05-13 18:13:59 +020049}
50
shrekshaofb1c2fe2019-11-13 11:10:39 -080051GLColor16UI SliceFormatColor16UI(GLenum format, GLColor16UI full)
52{
53 switch (format)
54 {
55 case GL_RED:
56 return GLColor16UI(full.R, 0, 0, 0xFFFF);
57 case GL_RG:
58 return GLColor16UI(full.R, full.G, 0, 0xFFFF);
59 case GL_RGB:
60 return GLColor16UI(full.R, full.G, full.B, 0xFFFF);
61 case GL_RGBA:
62 return full;
63 case GL_LUMINANCE:
64 return GLColor16UI(full.R, full.R, full.R, 0xFFFF);
65 case GL_ALPHA:
66 return GLColor16UI(0, 0, 0, full.R);
67 case GL_LUMINANCE_ALPHA:
68 return GLColor16UI(full.R, full.R, full.R, full.G);
69 default:
70 EXPECT_TRUE(false);
71 return GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
72 }
73}
74
Mohan Maiya6caa2652019-09-11 08:06:13 -070075// As above, for 32F colors
76GLColor32F SliceFormatColor32F(GLenum format, GLColor32F full)
77{
78 switch (format)
79 {
80 case GL_RED:
81 return GLColor32F(full.R, 0.0f, 0.0f, 1.0f);
82 case GL_RG:
83 return GLColor32F(full.R, full.G, 0.0f, 1.0f);
84 case GL_RGB:
85 return GLColor32F(full.R, full.G, full.B, 1.0f);
86 case GL_RGBA:
87 return full;
88 case GL_LUMINANCE:
89 return GLColor32F(full.R, full.R, full.R, 1.0f);
90 case GL_ALPHA:
91 return GLColor32F(0.0f, 0.0f, 0.0f, full.R);
92 case GL_LUMINANCE_ALPHA:
93 return GLColor32F(full.R, full.R, full.R, full.G);
94 default:
95 EXPECT_TRUE(false);
96 return GLColor32F(1.0f, 1.0f, 1.0f, 1.0f);
97 }
98}
99
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200100class TexCoordDrawTest : public ANGLETest
Jamie Madillf67115c2014-04-22 13:14:05 -0400101{
Jamie Madillbc393df2015-01-29 13:46:07 -0500102 protected:
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200103 TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0)
Jamie Madillf67115c2014-04-22 13:14:05 -0400104 {
105 setWindowWidth(128);
106 setWindowHeight(128);
107 setConfigRedBits(8);
108 setConfigGreenBits(8);
109 setConfigBlueBits(8);
110 setConfigAlphaBits(8);
111 }
112
Jamie Madill35cd7332018-12-02 12:03:33 -0500113 virtual const char *getVertexShaderSource()
Jamie Madillf67115c2014-04-22 13:14:05 -0400114 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500115 return R"(precision highp float;
116attribute vec4 position;
117varying vec2 texcoord;
Geoff Langc41e42d2014-04-28 10:58:16 -0400118
Jamie Madill35cd7332018-12-02 12:03:33 -0500119void main()
120{
121 gl_Position = vec4(position.xy, 0.0, 1.0);
122 texcoord = (position.xy * 0.5) + 0.5;
123})";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200124 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400125
Jamie Madill35cd7332018-12-02 12:03:33 -0500126 virtual const char *getFragmentShaderSource() = 0;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200127
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300128 virtual void setUpProgram()
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200129 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500130 const char *vertexShaderSource = getVertexShaderSource();
131 const char *fragmentShaderSource = getFragmentShaderSource();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200132
133 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
134 ASSERT_NE(0u, mProgram);
135 ASSERT_GL_NO_ERROR();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300136 }
137
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400138 void testSetUp() override { setUpFramebuffer(); }
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200139
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400140 void testTearDown() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200141 {
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200142 glBindFramebuffer(GL_FRAMEBUFFER, 0);
143 glDeleteFramebuffers(1, &mFramebuffer);
144 glDeleteTextures(1, &mFramebufferColorTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200145 glDeleteProgram(mProgram);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200146 }
147
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200148 void setUpFramebuffer()
149 {
150 // We use an FBO to work around an issue where the default framebuffer applies SRGB
151 // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not
152 // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec
153 // section 4.4 says that the format of the default framebuffer is entirely up to the window
154 // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off
155 // SRGB conversion like desktop GL does.
156 // TODO(oetuaho): Get rid of this if the underlying issue is fixed.
157 glGenFramebuffers(1, &mFramebuffer);
158 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
159
160 glGenTextures(1, &mFramebufferColorTexture);
161 glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture);
162 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
163 GL_UNSIGNED_BYTE, nullptr);
164 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
165 mFramebufferColorTexture, 0);
166 ASSERT_GL_NO_ERROR();
167 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
168 glBindTexture(GL_TEXTURE_2D, 0);
169 }
170
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200171 // Returns the created texture ID.
172 GLuint create2DTexture()
173 {
174 GLuint texture2D;
175 glGenTextures(1, &texture2D);
176 glBindTexture(GL_TEXTURE_2D, texture2D);
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800177 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200178 EXPECT_GL_NO_ERROR();
179 return texture2D;
180 }
181
182 GLuint mProgram;
Olli Etuaho51f1c0f2016-01-13 16:16:24 +0200183 GLuint mFramebuffer;
184
185 private:
186 GLuint mFramebufferColorTexture;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200187};
188
189class Texture2DTest : public TexCoordDrawTest
190{
191 protected:
192 Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {}
193
Jamie Madill35cd7332018-12-02 12:03:33 -0500194 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200195 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500196 return R"(precision highp float;
197uniform sampler2D tex;
198varying vec2 texcoord;
Geoff Langc41e42d2014-04-28 10:58:16 -0400199
Jamie Madill35cd7332018-12-02 12:03:33 -0500200void main()
201{
202 gl_FragColor = texture2D(tex, texcoord);
203})";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200204 }
Geoff Langc41e42d2014-04-28 10:58:16 -0400205
Olli Etuaho96963162016-03-21 11:54:33 +0200206 virtual const char *getTextureUniformName() { return "tex"; }
207
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300208 void setUpProgram() override
209 {
210 TexCoordDrawTest::setUpProgram();
211 mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName());
212 ASSERT_NE(-1, mTexture2DUniformLocation);
213 }
214
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400215 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200216 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400217 TexCoordDrawTest::testSetUp();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200218 mTexture2D = create2DTexture();
Jamie Madilld4cfa572014-07-08 10:00:32 -0400219
Jamie Madill9aca0592014-10-06 16:26:59 -0400220 ASSERT_GL_NO_ERROR();
Jamie Madillf67115c2014-04-22 13:14:05 -0400221 }
222
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400223 void testTearDown() override
Jamie Madillf67115c2014-04-22 13:14:05 -0400224 {
Jamie Madilld4cfa572014-07-08 10:00:32 -0400225 glDeleteTextures(1, &mTexture2D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400226 TexCoordDrawTest::testTearDown();
Jamie Madillf67115c2014-04-22 13:14:05 -0400227 }
228
Jamie Madillbc393df2015-01-29 13:46:07 -0500229 // Tests CopyTexSubImage with floating point textures of various formats.
230 void testFloatCopySubImage(int sourceImageChannels, int destImageChannels)
231 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300232 setUpProgram();
233
Martin Radev1be913c2016-07-11 17:59:16 +0300234 if (getClientMajorVersion() < 3)
Geoff Langfbfa47c2015-03-31 11:26:00 -0400235 {
Jamie Madillb8149072019-04-30 16:14:44 -0400236 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
237 !IsGLExtensionEnabled("GL_OES_texture_float"));
Geoff Langc4e93662017-05-01 10:45:59 -0400238
Yunchao He9550c602018-02-13 14:47:05 +0800239 ANGLE_SKIP_TEST_IF((sourceImageChannels < 3 || destImageChannels < 3) &&
Jamie Madillb8149072019-04-30 16:14:44 -0400240 !IsGLExtensionEnabled("GL_EXT_texture_rg"));
Geoff Langfbfa47c2015-03-31 11:26:00 -0400241
Yunchao He9550c602018-02-13 14:47:05 +0800242 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
Jamie Madillb8149072019-04-30 16:14:44 -0400243 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
Geoff Lang677bb6f2017-04-05 12:40:40 -0400244
Yunchao He9550c602018-02-13 14:47:05 +0800245 ANGLE_SKIP_TEST_IF(destImageChannels == 4 &&
Jamie Madillb8149072019-04-30 16:14:44 -0400246 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"));
Geoff Lang677bb6f2017-04-05 12:40:40 -0400247
Yunchao He9550c602018-02-13 14:47:05 +0800248 ANGLE_SKIP_TEST_IF(destImageChannels <= 2);
Geoff Lang677bb6f2017-04-05 12:40:40 -0400249 }
250 else
251 {
Jamie Madillb8149072019-04-30 16:14:44 -0400252 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_color_buffer_float"));
Geoff Lang677bb6f2017-04-05 12:40:40 -0400253
Yunchao He9550c602018-02-13 14:47:05 +0800254 ANGLE_SKIP_TEST_IF(destImageChannels == 3 &&
Jamie Madillb8149072019-04-30 16:14:44 -0400255 !IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"));
Geoff Langfbfa47c2015-03-31 11:26:00 -0400256 }
257
Jamie Madill50cf2be2018-06-15 09:46:57 -0400258 // clang-format off
Jamie Madillbc393df2015-01-29 13:46:07 -0500259 GLfloat sourceImageData[4][16] =
260 {
261 { // R
262 1.0f,
263 0.0f,
264 0.0f,
265 1.0f
266 },
267 { // RG
268 1.0f, 0.0f,
269 0.0f, 1.0f,
270 0.0f, 0.0f,
271 1.0f, 1.0f
272 },
273 { // RGB
274 1.0f, 0.0f, 0.0f,
275 0.0f, 1.0f, 0.0f,
276 0.0f, 0.0f, 1.0f,
277 1.0f, 1.0f, 0.0f
278 },
279 { // RGBA
280 1.0f, 0.0f, 0.0f, 1.0f,
281 0.0f, 1.0f, 0.0f, 1.0f,
282 0.0f, 0.0f, 1.0f, 1.0f,
283 1.0f, 1.0f, 0.0f, 1.0f
284 },
285 };
Jamie Madill50cf2be2018-06-15 09:46:57 -0400286 // clang-format on
Jamie Madillbc393df2015-01-29 13:46:07 -0500287
Jamie Madill50cf2be2018-06-15 09:46:57 -0400288 GLenum imageFormats[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500289 GL_R32F,
290 GL_RG32F,
291 GL_RGB32F,
292 GL_RGBA32F,
Jamie Madillbc393df2015-01-29 13:46:07 -0500293 };
294
Jamie Madill50cf2be2018-06-15 09:46:57 -0400295 GLenum sourceUnsizedFormats[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500296 GL_RED,
297 GL_RG,
298 GL_RGB,
299 GL_RGBA,
Jamie Madillbc393df2015-01-29 13:46:07 -0500300 };
301
302 GLuint textures[2];
303
304 glGenTextures(2, textures);
305
Jamie Madill50cf2be2018-06-15 09:46:57 -0400306 GLfloat *imageData = sourceImageData[sourceImageChannels - 1];
307 GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1];
Jamie Madillbc393df2015-01-29 13:46:07 -0500308 GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1];
Jamie Madill50cf2be2018-06-15 09:46:57 -0400309 GLenum destImageFormat = imageFormats[destImageChannels - 1];
Jamie Madillbc393df2015-01-29 13:46:07 -0500310
311 glBindTexture(GL_TEXTURE_2D, textures[0]);
Geoff Langc4e93662017-05-01 10:45:59 -0400312 if (getClientMajorVersion() >= 3)
313 {
314 glTexStorage2D(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
315 }
316 else
317 {
318 glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2);
319 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500320 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
321 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
322 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData);
323
Jamie Madillb8149072019-04-30 16:14:44 -0400324 if (sourceImageChannels < 3 && !IsGLExtensionEnabled("GL_EXT_texture_rg"))
Jamie Madillbc393df2015-01-29 13:46:07 -0500325 {
326 // This is not supported
327 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
328 }
329 else
330 {
331 ASSERT_GL_NO_ERROR();
332 }
333
334 GLuint fbo;
335 glGenFramebuffers(1, &fbo);
336 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
337 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
338
339 glBindTexture(GL_TEXTURE_2D, textures[1]);
Geoff Langc4e93662017-05-01 10:45:59 -0400340 if (getClientMajorVersion() >= 3)
341 {
342 glTexStorage2D(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
343 }
344 else
345 {
346 glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2);
347 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500348 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350
351 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2);
352 ASSERT_GL_NO_ERROR();
353
354 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200355 drawQuad(mProgram, "position", 0.5f);
Jamie Madillbc393df2015-01-29 13:46:07 -0500356
357 int testImageChannels = std::min(sourceImageChannels, destImageChannels);
358
Olli Etuahoa314b612016-03-10 16:43:00 +0200359 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
Jamie Madillbc393df2015-01-29 13:46:07 -0500360 if (testImageChannels > 1)
361 {
362 EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255);
363 EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255);
364 if (testImageChannels > 2)
365 {
366 EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255);
367 }
368 }
369
370 glDeleteFramebuffers(1, &fbo);
371 glDeleteTextures(2, textures);
372
373 ASSERT_GL_NO_ERROR();
374 }
375
Jamie Madilld4cfa572014-07-08 10:00:32 -0400376 GLuint mTexture2D;
Jamie Madilld4cfa572014-07-08 10:00:32 -0400377 GLint mTexture2DUniformLocation;
Jamie Madillf67115c2014-04-22 13:14:05 -0400378};
379
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200380class Texture2DTestES3 : public Texture2DTest
381{
382 protected:
383 Texture2DTestES3() : Texture2DTest() {}
384
Jamie Madill35cd7332018-12-02 12:03:33 -0500385 const char *getVertexShaderSource() override
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200386 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500387 return "#version 300 es\n"
388 "out vec2 texcoord;\n"
389 "in vec4 position;\n"
390 "void main()\n"
391 "{\n"
392 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
393 " texcoord = (position.xy * 0.5) + 0.5;\n"
394 "}\n";
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200395 }
396
Jamie Madill35cd7332018-12-02 12:03:33 -0500397 const char *getFragmentShaderSource() override
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200398 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500399 return "#version 300 es\n"
400 "precision highp float;\n"
401 "uniform highp sampler2D tex;\n"
402 "in vec2 texcoord;\n"
403 "out vec4 fragColor;\n"
404 "void main()\n"
405 "{\n"
406 " fragColor = texture(tex, texcoord);\n"
407 "}\n";
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200408 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300409
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400410 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300411 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400412 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300413 setUpProgram();
414 }
Olli Etuahoa7416ff2016-01-18 12:22:55 +0200415};
416
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200417class Texture2DIntegerAlpha1TestES3 : public Texture2DTest
418{
419 protected:
420 Texture2DIntegerAlpha1TestES3() : Texture2DTest() {}
421
Jamie Madill35cd7332018-12-02 12:03:33 -0500422 const char *getVertexShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200423 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500424 return "#version 300 es\n"
425 "out vec2 texcoord;\n"
426 "in vec4 position;\n"
427 "void main()\n"
428 "{\n"
429 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
430 " texcoord = (position.xy * 0.5) + 0.5;\n"
431 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200432 }
433
Jamie Madill35cd7332018-12-02 12:03:33 -0500434 const char *getFragmentShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200435 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500436 return "#version 300 es\n"
437 "precision highp float;\n"
438 "uniform highp isampler2D tex;\n"
439 "in vec2 texcoord;\n"
440 "out vec4 fragColor;\n"
441 "void main()\n"
442 "{\n"
443 " vec4 green = vec4(0, 1, 0, 1);\n"
444 " vec4 black = vec4(0, 0, 0, 0);\n"
445 " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n"
446 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200447 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300448
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400449 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300450 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400451 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300452 setUpProgram();
453 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200454};
455
456class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest
457{
458 protected:
459 Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {}
460
Jamie Madill35cd7332018-12-02 12:03:33 -0500461 const char *getVertexShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200462 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500463 return "#version 300 es\n"
464 "out vec2 texcoord;\n"
465 "in vec4 position;\n"
466 "void main()\n"
467 "{\n"
468 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
469 " texcoord = (position.xy * 0.5) + 0.5;\n"
470 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200471 }
472
Jamie Madill35cd7332018-12-02 12:03:33 -0500473 const char *getFragmentShaderSource() override
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200474 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500475 return "#version 300 es\n"
476 "precision highp float;\n"
477 "uniform highp usampler2D tex;\n"
478 "in vec2 texcoord;\n"
479 "out vec4 fragColor;\n"
480 "void main()\n"
481 "{\n"
482 " vec4 green = vec4(0, 1, 0, 1);\n"
483 " vec4 black = vec4(0, 0, 0, 0);\n"
484 " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n"
485 "}\n";
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200486 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300487
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400488 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300489 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400490 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300491 setUpProgram();
492 }
Olli Etuaho6ee394a2016-02-18 13:30:09 +0200493};
494
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200495class Texture2DTestWithDrawScale : public Texture2DTest
Jamie Madill2453dbc2015-07-14 11:35:42 -0400496{
497 protected:
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200498 Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {}
499
Jamie Madill35cd7332018-12-02 12:03:33 -0500500 const char *getVertexShaderSource() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400501 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300502 return
503 R"(precision highp float;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200504 attribute vec4 position;
505 varying vec2 texcoord;
506
507 uniform vec2 drawScale;
508
509 void main()
510 {
511 gl_Position = vec4(position.xy * drawScale, 0.0, 1.0);
512 texcoord = (position.xy * 0.5) + 0.5;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300513 })";
Jamie Madill2453dbc2015-07-14 11:35:42 -0400514 }
515
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400516 void testSetUp() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400517 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400518 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300519
520 setUpProgram();
521
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200522 mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale");
523 ASSERT_NE(-1, mDrawScaleUniformLocation);
Jamie Madill2453dbc2015-07-14 11:35:42 -0400524
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200525 glUseProgram(mProgram);
526 glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f);
527 glUseProgram(0);
528 ASSERT_GL_NO_ERROR();
529 }
530
531 GLint mDrawScaleUniformLocation;
532};
533
Olli Etuaho4644a202016-01-12 15:12:53 +0200534class Sampler2DAsFunctionParameterTest : public Texture2DTest
535{
536 protected:
537 Sampler2DAsFunctionParameterTest() : Texture2DTest() {}
538
Jamie Madill35cd7332018-12-02 12:03:33 -0500539 const char *getFragmentShaderSource() override
Olli Etuaho4644a202016-01-12 15:12:53 +0200540 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300541 return
542 R"(precision highp float;
Olli Etuaho4644a202016-01-12 15:12:53 +0200543 uniform sampler2D tex;
544 varying vec2 texcoord;
545
546 vec4 computeFragColor(sampler2D aTex)
547 {
548 return texture2D(aTex, texcoord);
549 }
550
551 void main()
552 {
553 gl_FragColor = computeFragColor(tex);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300554 })";
Olli Etuaho4644a202016-01-12 15:12:53 +0200555 }
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300556
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400557 void testSetUp() override
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300558 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400559 Texture2DTest::testSetUp();
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300560 setUpProgram();
561 }
Olli Etuaho4644a202016-01-12 15:12:53 +0200562};
563
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200564class TextureCubeTest : public TexCoordDrawTest
565{
566 protected:
567 TextureCubeTest()
568 : TexCoordDrawTest(),
569 mTexture2D(0),
570 mTextureCube(0),
571 mTexture2DUniformLocation(-1),
572 mTextureCubeUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500573 {}
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200574
Jamie Madill35cd7332018-12-02 12:03:33 -0500575 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200576 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300577 return
578 R"(precision highp float;
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200579 uniform sampler2D tex2D;
580 uniform samplerCube texCube;
581 varying vec2 texcoord;
582
583 void main()
584 {
585 gl_FragColor = texture2D(tex2D, texcoord);
586 gl_FragColor += textureCube(texCube, vec3(texcoord, 0));
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300587 })";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200588 }
589
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400590 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200591 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400592 TexCoordDrawTest::testSetUp();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200593
594 glGenTextures(1, &mTextureCube);
595 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Geoff Langc4e93662017-05-01 10:45:59 -0400596 for (GLenum face = 0; face < 6; face++)
597 {
598 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
599 GL_UNSIGNED_BYTE, nullptr);
600 }
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200601 EXPECT_GL_NO_ERROR();
602
603 mTexture2D = create2DTexture();
604
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300605 setUpProgram();
606
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200607 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
608 ASSERT_NE(-1, mTexture2DUniformLocation);
609 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
610 ASSERT_NE(-1, mTextureCubeUniformLocation);
611 }
612
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400613 void testTearDown() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200614 {
615 glDeleteTextures(1, &mTextureCube);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400616 TexCoordDrawTest::testTearDown();
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200617 }
618
619 GLuint mTexture2D;
620 GLuint mTextureCube;
621 GLint mTexture2DUniformLocation;
622 GLint mTextureCubeUniformLocation;
623};
624
Martin Radev7e2c0d32017-09-15 14:25:42 +0300625class TextureCubeTestES3 : public ANGLETest
626{
627 protected:
628 TextureCubeTestES3() {}
629};
630
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200631class SamplerArrayTest : public TexCoordDrawTest
632{
633 protected:
634 SamplerArrayTest()
635 : TexCoordDrawTest(),
636 mTexture2DA(0),
637 mTexture2DB(0),
638 mTexture0UniformLocation(-1),
639 mTexture1UniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500640 {}
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200641
Jamie Madill35cd7332018-12-02 12:03:33 -0500642 const char *getFragmentShaderSource() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200643 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300644 return
645 R"(precision mediump float;
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200646 uniform highp sampler2D tex2DArray[2];
647 varying vec2 texcoord;
648 void main()
649 {
650 gl_FragColor = texture2D(tex2DArray[0], texcoord);
651 gl_FragColor += texture2D(tex2DArray[1], texcoord);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300652 })";
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200653 }
654
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400655 void testSetUp() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200656 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400657 TexCoordDrawTest::testSetUp();
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200658
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300659 setUpProgram();
660
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200661 mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]");
662 ASSERT_NE(-1, mTexture0UniformLocation);
663 mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]");
664 ASSERT_NE(-1, mTexture1UniformLocation);
665
666 mTexture2DA = create2DTexture();
667 mTexture2DB = create2DTexture();
668 ASSERT_GL_NO_ERROR();
669 }
670
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400671 void testTearDown() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200672 {
673 glDeleteTextures(1, &mTexture2DA);
674 glDeleteTextures(1, &mTexture2DB);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400675 TexCoordDrawTest::testTearDown();
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200676 }
677
678 void testSamplerArrayDraw()
679 {
680 GLubyte texData[4];
681 texData[0] = 0;
682 texData[1] = 60;
683 texData[2] = 0;
684 texData[3] = 255;
685
686 glActiveTexture(GL_TEXTURE0);
687 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
688 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
689
690 texData[1] = 120;
691 glActiveTexture(GL_TEXTURE1);
692 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
693 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
694 EXPECT_GL_ERROR(GL_NO_ERROR);
695
696 glUseProgram(mProgram);
697 glUniform1i(mTexture0UniformLocation, 0);
698 glUniform1i(mTexture1UniformLocation, 1);
699 drawQuad(mProgram, "position", 0.5f);
700 EXPECT_GL_NO_ERROR();
701
702 EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2);
703 }
704
705 GLuint mTexture2DA;
706 GLuint mTexture2DB;
707 GLint mTexture0UniformLocation;
708 GLint mTexture1UniformLocation;
709};
710
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200711class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
712{
713 protected:
714 SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {}
715
Jamie Madill35cd7332018-12-02 12:03:33 -0500716 const char *getFragmentShaderSource() override
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200717 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300718 return
719 R"(precision mediump float;
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200720 uniform highp sampler2D tex2DArray[2];
721 varying vec2 texcoord;
722
723 vec4 computeFragColor(highp sampler2D aTex2DArray[2])
724 {
725 return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord);
726 }
727
728 void main()
729 {
730 gl_FragColor = computeFragColor(tex2DArray);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300731 })";
Olli Etuaho2173db3d2016-01-12 13:55:14 +0200732 }
733};
734
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200735class Texture2DArrayTestES3 : public TexCoordDrawTest
736{
737 protected:
738 Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
739
Jamie Madill35cd7332018-12-02 12:03:33 -0500740 const char *getVertexShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200741 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500742 return "#version 300 es\n"
743 "out vec2 texcoord;\n"
744 "in vec4 position;\n"
745 "void main()\n"
746 "{\n"
747 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
748 " texcoord = (position.xy * 0.5) + 0.5;\n"
749 "}\n";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200750 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400751
Jamie Madill35cd7332018-12-02 12:03:33 -0500752 const char *getFragmentShaderSource() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200753 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500754 return "#version 300 es\n"
755 "precision highp float;\n"
756 "uniform highp sampler2DArray tex2DArray;\n"
757 "in vec2 texcoord;\n"
758 "out vec4 fragColor;\n"
759 "void main()\n"
760 "{\n"
761 " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
762 "}\n";
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200763 }
Jamie Madill2453dbc2015-07-14 11:35:42 -0400764
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400765 void testSetUp() override
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200766 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400767 TexCoordDrawTest::testSetUp();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400768
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300769 setUpProgram();
770
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200771 mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
Jamie Madill2453dbc2015-07-14 11:35:42 -0400772 ASSERT_NE(-1, mTextureArrayLocation);
773
774 glGenTextures(1, &m2DArrayTexture);
775 ASSERT_GL_NO_ERROR();
776 }
777
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400778 void testTearDown() override
Jamie Madill2453dbc2015-07-14 11:35:42 -0400779 {
780 glDeleteTextures(1, &m2DArrayTexture);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400781 TexCoordDrawTest::testTearDown();
Jamie Madill2453dbc2015-07-14 11:35:42 -0400782 }
783
784 GLuint m2DArrayTexture;
Jamie Madill2453dbc2015-07-14 11:35:42 -0400785 GLint mTextureArrayLocation;
786};
787
Olli Etuahobce743a2016-01-15 17:18:28 +0200788class TextureSizeTextureArrayTest : public TexCoordDrawTest
789{
790 protected:
791 TextureSizeTextureArrayTest()
792 : TexCoordDrawTest(),
793 mTexture2DA(0),
794 mTexture2DB(0),
795 mTexture0Location(-1),
796 mTexture1Location(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500797 {}
Olli Etuahobce743a2016-01-15 17:18:28 +0200798
Jamie Madill35cd7332018-12-02 12:03:33 -0500799 const char *getVertexShaderSource() override { return essl3_shaders::vs::Simple(); }
Olli Etuahobce743a2016-01-15 17:18:28 +0200800
Jamie Madill35cd7332018-12-02 12:03:33 -0500801 const char *getFragmentShaderSource() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200802 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500803 return "#version 300 es\n"
804 "precision highp float;\n"
805 "uniform highp sampler2D tex2DArray[2];\n"
806 "out vec4 fragColor;\n"
807 "void main()\n"
808 "{\n"
809 " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n"
810 " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n"
811 " fragColor = vec4(red, green, 0.0, 1.0);\n"
812 "}\n";
Olli Etuahobce743a2016-01-15 17:18:28 +0200813 }
814
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400815 void testSetUp() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200816 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400817 TexCoordDrawTest::testSetUp();
Olli Etuahobce743a2016-01-15 17:18:28 +0200818
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300819 setUpProgram();
820
Olli Etuahobce743a2016-01-15 17:18:28 +0200821 mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]");
822 ASSERT_NE(-1, mTexture0Location);
823 mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]");
824 ASSERT_NE(-1, mTexture1Location);
825
826 mTexture2DA = create2DTexture();
827 mTexture2DB = create2DTexture();
828 ASSERT_GL_NO_ERROR();
829 }
830
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400831 void testTearDown() override
Olli Etuahobce743a2016-01-15 17:18:28 +0200832 {
833 glDeleteTextures(1, &mTexture2DA);
834 glDeleteTextures(1, &mTexture2DB);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400835 TexCoordDrawTest::testTearDown();
Olli Etuahobce743a2016-01-15 17:18:28 +0200836 }
837
838 GLuint mTexture2DA;
839 GLuint mTexture2DB;
840 GLint mTexture0Location;
841 GLint mTexture1Location;
842};
843
Olli Etuahoa314b612016-03-10 16:43:00 +0200844class Texture3DTestES3 : public TexCoordDrawTest
845{
846 protected:
847 Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {}
848
Jamie Madill35cd7332018-12-02 12:03:33 -0500849 const char *getVertexShaderSource() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200850 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500851 return "#version 300 es\n"
852 "out vec2 texcoord;\n"
853 "in vec4 position;\n"
854 "void main()\n"
855 "{\n"
856 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
857 " texcoord = (position.xy * 0.5) + 0.5;\n"
858 "}\n";
Olli Etuahoa314b612016-03-10 16:43:00 +0200859 }
860
Jamie Madill35cd7332018-12-02 12:03:33 -0500861 const char *getFragmentShaderSource() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200862 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500863 return "#version 300 es\n"
864 "precision highp float;\n"
865 "uniform highp sampler3D tex3D;\n"
866 "in vec2 texcoord;\n"
867 "out vec4 fragColor;\n"
868 "void main()\n"
869 "{\n"
870 " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n"
871 "}\n";
Olli Etuahoa314b612016-03-10 16:43:00 +0200872 }
873
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400874 void testSetUp() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200875 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400876 TexCoordDrawTest::testSetUp();
Olli Etuahoa314b612016-03-10 16:43:00 +0200877
878 glGenTextures(1, &mTexture3D);
879
880 setUpProgram();
881
882 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
883 ASSERT_NE(-1, mTexture3DUniformLocation);
884 }
885
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400886 void testTearDown() override
Olli Etuahoa314b612016-03-10 16:43:00 +0200887 {
888 glDeleteTextures(1, &mTexture3D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400889 TexCoordDrawTest::testTearDown();
Olli Etuahoa314b612016-03-10 16:43:00 +0200890 }
891
892 GLuint mTexture3D;
893 GLint mTexture3DUniformLocation;
894};
895
Olli Etuaho1a679902016-01-14 12:21:47 +0200896class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest
897{
898 protected:
899 ShadowSamplerPlusSampler3DTestES3()
900 : TexCoordDrawTest(),
901 mTextureShadow(0),
902 mTexture3D(0),
903 mTextureShadowUniformLocation(-1),
904 mTexture3DUniformLocation(-1),
905 mDepthRefUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500906 {}
Olli Etuaho1a679902016-01-14 12:21:47 +0200907
Jamie Madill35cd7332018-12-02 12:03:33 -0500908 const char *getVertexShaderSource() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200909 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500910 return "#version 300 es\n"
911 "out vec2 texcoord;\n"
912 "in vec4 position;\n"
913 "void main()\n"
914 "{\n"
915 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
916 " texcoord = (position.xy * 0.5) + 0.5;\n"
917 "}\n";
Olli Etuaho1a679902016-01-14 12:21:47 +0200918 }
919
Jamie Madill35cd7332018-12-02 12:03:33 -0500920 const char *getFragmentShaderSource() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200921 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500922 return "#version 300 es\n"
923 "precision highp float;\n"
924 "uniform highp sampler2DShadow tex2DShadow;\n"
925 "uniform highp sampler3D tex3D;\n"
926 "in vec2 texcoord;\n"
927 "uniform float depthRef;\n"
928 "out vec4 fragColor;\n"
929 "void main()\n"
930 "{\n"
931 " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n"
932 " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n"
933 "}\n";
Olli Etuaho1a679902016-01-14 12:21:47 +0200934 }
935
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400936 void testSetUp() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200937 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400938 TexCoordDrawTest::testSetUp();
Olli Etuaho1a679902016-01-14 12:21:47 +0200939
940 glGenTextures(1, &mTexture3D);
941
942 glGenTextures(1, &mTextureShadow);
943 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
944 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
945
Olli Etuahoa1c917f2016-04-06 13:50:03 +0300946 setUpProgram();
947
Olli Etuaho1a679902016-01-14 12:21:47 +0200948 mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
949 ASSERT_NE(-1, mTextureShadowUniformLocation);
950 mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D");
951 ASSERT_NE(-1, mTexture3DUniformLocation);
952 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
953 ASSERT_NE(-1, mDepthRefUniformLocation);
954 }
955
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400956 void testTearDown() override
Olli Etuaho1a679902016-01-14 12:21:47 +0200957 {
958 glDeleteTextures(1, &mTextureShadow);
959 glDeleteTextures(1, &mTexture3D);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400960 TexCoordDrawTest::testTearDown();
Olli Etuaho1a679902016-01-14 12:21:47 +0200961 }
962
963 GLuint mTextureShadow;
964 GLuint mTexture3D;
965 GLint mTextureShadowUniformLocation;
966 GLint mTexture3DUniformLocation;
967 GLint mDepthRefUniformLocation;
968};
969
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200970class SamplerTypeMixTestES3 : public TexCoordDrawTest
971{
972 protected:
973 SamplerTypeMixTestES3()
974 : TexCoordDrawTest(),
975 mTexture2D(0),
976 mTextureCube(0),
977 mTexture2DShadow(0),
978 mTextureCubeShadow(0),
979 mTexture2DUniformLocation(-1),
980 mTextureCubeUniformLocation(-1),
981 mTexture2DShadowUniformLocation(-1),
982 mTextureCubeShadowUniformLocation(-1),
983 mDepthRefUniformLocation(-1)
Jamie Madillb980c562018-11-27 11:34:27 -0500984 {}
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200985
Jamie Madill35cd7332018-12-02 12:03:33 -0500986 const char *getVertexShaderSource() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200987 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500988 return "#version 300 es\n"
989 "out vec2 texcoord;\n"
990 "in vec4 position;\n"
991 "void main()\n"
992 "{\n"
993 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
994 " texcoord = (position.xy * 0.5) + 0.5;\n"
995 "}\n";
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200996 }
997
Jamie Madill35cd7332018-12-02 12:03:33 -0500998 const char *getFragmentShaderSource() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +0200999 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001000 return "#version 300 es\n"
1001 "precision highp float;\n"
1002 "uniform highp sampler2D tex2D;\n"
1003 "uniform highp samplerCube texCube;\n"
1004 "uniform highp sampler2DShadow tex2DShadow;\n"
1005 "uniform highp samplerCubeShadow texCubeShadow;\n"
1006 "in vec2 texcoord;\n"
1007 "uniform float depthRef;\n"
1008 "out vec4 fragColor;\n"
1009 "void main()\n"
1010 "{\n"
1011 " fragColor = texture(tex2D, texcoord);\n"
1012 " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n"
1013 " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n"
1014 " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * "
1015 "0.125);\n"
1016 "}\n";
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001017 }
1018
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001019 void testSetUp() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001020 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001021 TexCoordDrawTest::testSetUp();
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001022
1023 glGenTextures(1, &mTexture2D);
1024 glGenTextures(1, &mTextureCube);
1025
1026 glGenTextures(1, &mTexture2DShadow);
1027 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
1028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1029
1030 glGenTextures(1, &mTextureCubeShadow);
1031 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
1032 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1033
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001034 setUpProgram();
1035
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001036 mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D");
1037 ASSERT_NE(-1, mTexture2DUniformLocation);
1038 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1039 ASSERT_NE(-1, mTextureCubeUniformLocation);
1040 mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow");
1041 ASSERT_NE(-1, mTexture2DShadowUniformLocation);
1042 mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow");
1043 ASSERT_NE(-1, mTextureCubeShadowUniformLocation);
1044 mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef");
1045 ASSERT_NE(-1, mDepthRefUniformLocation);
1046
1047 ASSERT_GL_NO_ERROR();
1048 }
1049
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001050 void testTearDown() override
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001051 {
1052 glDeleteTextures(1, &mTexture2D);
1053 glDeleteTextures(1, &mTextureCube);
1054 glDeleteTextures(1, &mTexture2DShadow);
1055 glDeleteTextures(1, &mTextureCubeShadow);
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04001056 TexCoordDrawTest::testTearDown();
Olli Etuahoc8c99a02016-01-14 16:47:22 +02001057 }
1058
1059 GLuint mTexture2D;
1060 GLuint mTextureCube;
1061 GLuint mTexture2DShadow;
1062 GLuint mTextureCubeShadow;
1063 GLint mTexture2DUniformLocation;
1064 GLint mTextureCubeUniformLocation;
1065 GLint mTexture2DShadowUniformLocation;
1066 GLint mTextureCubeShadowUniformLocation;
1067 GLint mDepthRefUniformLocation;
1068};
1069
Olli Etuaho96963162016-03-21 11:54:33 +02001070class SamplerInStructTest : public Texture2DTest
1071{
1072 protected:
1073 SamplerInStructTest() : Texture2DTest() {}
1074
1075 const char *getTextureUniformName() override { return "us.tex"; }
1076
Jamie Madill35cd7332018-12-02 12:03:33 -05001077 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001078 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001079 return "precision highp float;\n"
1080 "struct S\n"
1081 "{\n"
1082 " vec4 a;\n"
1083 " highp sampler2D tex;\n"
1084 "};\n"
1085 "uniform S us;\n"
1086 "varying vec2 texcoord;\n"
1087 "void main()\n"
1088 "{\n"
1089 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n"
1090 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001091 }
1092
1093 void runSamplerInStructTest()
1094 {
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001095 setUpProgram();
1096
Olli Etuaho96963162016-03-21 11:54:33 +02001097 glActiveTexture(GL_TEXTURE0);
1098 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02001099 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1100 &GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001101 drawQuad(mProgram, "position", 0.5f);
Olli Etuahoa314b612016-03-10 16:43:00 +02001102 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuaho96963162016-03-21 11:54:33 +02001103 }
1104};
1105
1106class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest
1107{
1108 protected:
1109 SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {}
1110
Jamie Madill35cd7332018-12-02 12:03:33 -05001111 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001112 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001113 return "precision highp float;\n"
1114 "struct S\n"
1115 "{\n"
1116 " vec4 a;\n"
1117 " highp sampler2D tex;\n"
1118 "};\n"
1119 "uniform S us;\n"
1120 "varying vec2 texcoord;\n"
1121 "vec4 sampleFrom(S s) {\n"
1122 " return texture2D(s.tex, texcoord + s.a.x);\n"
1123 "}\n"
1124 "void main()\n"
1125 "{\n"
1126 " gl_FragColor = sampleFrom(us);\n"
1127 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001128 }
1129};
1130
1131class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest
1132{
1133 protected:
1134 SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {}
1135
1136 const char *getTextureUniformName() override { return "us[0].tex"; }
1137
Jamie Madill35cd7332018-12-02 12:03:33 -05001138 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001139 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001140 return "precision highp float;\n"
1141 "struct S\n"
1142 "{\n"
1143 " vec4 a;\n"
1144 " highp sampler2D tex;\n"
1145 "};\n"
1146 "uniform S us[1];\n"
1147 "varying vec2 texcoord;\n"
1148 "vec4 sampleFrom(S s) {\n"
1149 " return texture2D(s.tex, texcoord + s.a.x);\n"
1150 "}\n"
1151 "void main()\n"
1152 "{\n"
1153 " gl_FragColor = sampleFrom(us[0]);\n"
1154 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001155 }
1156};
1157
1158class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest
1159{
1160 protected:
1161 SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {}
1162
1163 const char *getTextureUniformName() override { return "us[0].sub.tex"; }
1164
Jamie Madill35cd7332018-12-02 12:03:33 -05001165 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001166 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001167 return "precision highp float;\n"
1168 "struct SUB\n"
1169 "{\n"
1170 " vec4 a;\n"
1171 " highp sampler2D tex;\n"
1172 "};\n"
1173 "struct S\n"
1174 "{\n"
1175 " SUB sub;\n"
1176 "};\n"
1177 "uniform S us[1];\n"
1178 "varying vec2 texcoord;\n"
1179 "vec4 sampleFrom(SUB s) {\n"
1180 " return texture2D(s.tex, texcoord + s.a.x);\n"
1181 "}\n"
1182 "void main()\n"
1183 "{\n"
1184 " gl_FragColor = sampleFrom(us[0].sub);\n"
1185 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001186 }
1187};
1188
1189class SamplerInStructAndOtherVariableTest : public SamplerInStructTest
1190{
1191 protected:
1192 SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {}
1193
Jamie Madill35cd7332018-12-02 12:03:33 -05001194 const char *getFragmentShaderSource() override
Olli Etuaho96963162016-03-21 11:54:33 +02001195 {
Jamie Madill35cd7332018-12-02 12:03:33 -05001196 return "precision highp float;\n"
1197 "struct S\n"
1198 "{\n"
1199 " vec4 a;\n"
1200 " highp sampler2D tex;\n"
1201 "};\n"
1202 "uniform S us;\n"
1203 "uniform float us_tex;\n"
1204 "varying vec2 texcoord;\n"
1205 "void main()\n"
1206 "{\n"
1207 " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n"
1208 "}\n";
Olli Etuaho96963162016-03-21 11:54:33 +02001209 }
1210};
1211
Anders Leinof6cbe442019-04-18 15:32:07 +03001212class Texture2DIntegerTestES3 : public Texture2DTest
1213{
1214 protected:
1215 Texture2DIntegerTestES3() : Texture2DTest() {}
1216
1217 const char *getVertexShaderSource() override
1218 {
1219 return "#version 300 es\n"
1220 "out vec2 texcoord;\n"
1221 "in vec4 position;\n"
1222 "void main()\n"
1223 "{\n"
1224 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1225 " texcoord = (position.xy * 0.5) + 0.5;\n"
1226 "}\n";
1227 }
1228
1229 const char *getFragmentShaderSource() override
1230 {
1231 return "#version 300 es\n"
1232 "precision highp float;\n"
1233 "precision highp usampler2D;\n"
1234 "uniform usampler2D tex;\n"
1235 "in vec2 texcoord;\n"
1236 "out vec4 fragColor;\n"
1237 "void main()\n"
1238 "{\n"
Anders Leino8224a582019-05-20 12:39:29 +03001239 " fragColor = vec4(texture(tex, texcoord))/255.0;\n"
Anders Leinof6cbe442019-04-18 15:32:07 +03001240 "}\n";
1241 }
1242};
1243
Anders Leino60cc7512019-05-06 09:25:27 +03001244class TextureCubeIntegerTestES3 : public TexCoordDrawTest
1245{
1246 protected:
1247 TextureCubeIntegerTestES3()
1248 : TexCoordDrawTest(), mTextureCube(0), mTextureCubeUniformLocation(-1)
1249 {}
1250
1251 const char *getVertexShaderSource() override
1252 {
1253 return "#version 300 es\n"
1254 "out vec2 texcoord;\n"
1255 "in vec4 position;\n"
1256 "void main()\n"
1257 "{\n"
1258 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1259 " texcoord = 0.5*position.xy;\n"
1260 "}\n";
1261 }
1262
1263 const char *getFragmentShaderSource() override
1264 {
1265 return "#version 300 es\n"
1266 "precision highp float;\n"
1267 "precision highp usamplerCube;\n"
1268 "uniform usamplerCube texCube;\n"
1269 "in vec2 texcoord;\n"
1270 "out vec4 fragColor;\n"
1271 "void main()\n"
1272 "{\n"
1273 " fragColor = vec4(texture(texCube, vec3(texcoord, 1)))/255.0;\n"
1274 "}\n";
1275 }
1276
1277 void testSetUp() override
1278 {
1279 TexCoordDrawTest::testSetUp();
1280 glGenTextures(1, &mTextureCube);
1281 setUpProgram();
1282
1283 mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube");
1284 ASSERT_NE(-1, mTextureCubeUniformLocation);
1285 }
1286
1287 void testTearDown() override
1288 {
1289 glDeleteTextures(1, &mTextureCube);
1290 TexCoordDrawTest::testTearDown();
1291 }
1292
1293 GLuint mTextureCube;
1294 GLint mTextureCubeUniformLocation;
1295};
1296
Anders Leinoe4452442019-05-09 13:29:49 +03001297class TextureCubeIntegerEdgeTestES3 : public TextureCubeIntegerTestES3
1298{
1299 protected:
1300 TextureCubeIntegerEdgeTestES3() : TextureCubeIntegerTestES3() {}
1301
1302 const char *getVertexShaderSource() override
1303 {
1304 return "#version 300 es\n"
1305 "out vec2 texcoord;\n"
1306 "in vec4 position;\n"
1307 "void main()\n"
1308 "{\n"
1309 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1310 " texcoord = position.xy;\n"
1311 "}\n";
1312 }
1313
1314 const char *getFragmentShaderSource() override
1315 {
1316 return "#version 300 es\n"
1317 "precision highp float;\n"
1318 "precision highp usamplerCube;\n"
1319 "uniform usamplerCube texCube;\n"
1320 "in vec2 texcoord;\n"
1321 "out vec4 fragColor;\n"
1322 "void main()\n"
1323 "{\n"
1324 " fragColor = vec4(texture(texCube, vec3(texcoord, 0)))/255.0;\n"
1325 "}\n";
1326 }
1327};
1328
Anders Leino1b6aded2019-05-20 12:56:34 +03001329class Texture2DIntegerProjectiveOffsetTestES3 : public Texture2DTest
1330{
1331 protected:
1332 Texture2DIntegerProjectiveOffsetTestES3() : Texture2DTest() {}
1333
1334 const char *getVertexShaderSource() override
1335 {
1336 return "#version 300 es\n"
1337 "out vec2 texcoord;\n"
1338 "in vec4 position;\n"
1339 "void main()\n"
1340 "{\n"
1341 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1342 " texcoord = 0.5*position.xy + vec2(0.5, 0.5);\n"
1343 "}\n";
1344 }
1345
1346 const char *getFragmentShaderSource() override
1347 {
1348 return "#version 300 es\n"
1349 "precision highp float;\n"
1350 "precision highp usampler2D;\n"
1351 "uniform usampler2D tex;\n"
1352 "in vec2 texcoord;\n"
1353 "out vec4 fragColor;\n"
1354 "void main()\n"
1355 "{\n"
1356 " fragColor = vec4(textureProjOffset(tex, vec3(texcoord, 1), ivec2(0,0), "
1357 "0.0))/255.0;\n"
1358 "}\n";
1359 }
1360};
1361
Anders Leino69d04932019-05-20 14:04:13 +03001362class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
1363{
1364 protected:
1365 Texture2DArrayIntegerTestES3() : Texture2DArrayTestES3() {}
1366
1367 const char *getVertexShaderSource() override
1368 {
1369 return "#version 300 es\n"
1370 "out vec2 texcoord;\n"
1371 "in vec4 position;\n"
1372 "void main()\n"
1373 "{\n"
1374 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1375 " texcoord = (position.xy * 0.5) + 0.5;\n"
1376 "}\n";
1377 }
1378
1379 const char *getFragmentShaderSource() override
1380 {
1381 return "#version 300 es\n"
1382 "precision highp float;\n"
1383 "uniform highp usampler2DArray tex2DArray;\n"
1384 "in vec2 texcoord;\n"
1385 "out vec4 fragColor;\n"
1386 "void main()\n"
1387 "{\n"
1388 " fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
1389 "0.0)))/255.0;\n"
1390 "}\n";
1391 }
1392};
1393
Anders Leino262e2822019-05-20 14:24:40 +03001394class Texture3DIntegerTestES3 : public Texture3DTestES3
1395{
1396 protected:
1397 Texture3DIntegerTestES3() : Texture3DTestES3() {}
1398
1399 const char *getVertexShaderSource() override
1400 {
1401 return "#version 300 es\n"
1402 "out vec2 texcoord;\n"
1403 "in vec4 position;\n"
1404 "void main()\n"
1405 "{\n"
1406 " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1407 " texcoord = (position.xy * 0.5) + 0.5;\n"
1408 "}\n";
1409 }
1410
1411 const char *getFragmentShaderSource() override
1412 {
1413 return "#version 300 es\n"
1414 "precision highp float;\n"
1415 "uniform highp usampler3D tex3D;\n"
1416 "in vec2 texcoord;\n"
1417 "out vec4 fragColor;\n"
1418 "void main()\n"
1419 "{\n"
1420 " fragColor = vec4(texture(tex3D, vec3(texcoord, 0.0)))/255.0;\n"
1421 "}\n";
1422 }
1423};
1424
Jamie Madillfc3ec572019-11-27 21:43:22 +00001425class PBOCompressedTextureTest : public Texture2DTest
1426{
1427 protected:
1428 PBOCompressedTextureTest() : Texture2DTest() {}
1429
1430 void testSetUp() override
1431 {
1432 TexCoordDrawTest::testSetUp();
1433 glGenTextures(1, &mTexture2D);
1434 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1435 EXPECT_GL_NO_ERROR();
1436
1437 setUpProgram();
1438
1439 glGenBuffers(1, &mPBO);
1440 }
1441
1442 void testTearDown() override
1443 {
1444 glDeleteBuffers(1, &mPBO);
1445 Texture2DTest::testTearDown();
1446 }
1447
1448 GLuint mPBO;
1449};
1450
Cody Northrop74e816b2020-03-26 17:40:25 -06001451class ETC1CompressedTextureTest : public Texture2DTest
1452{
1453 protected:
1454 ETC1CompressedTextureTest() : Texture2DTest() {}
1455
1456 void testSetUp() override
1457 {
1458 TexCoordDrawTest::testSetUp();
1459 glGenTextures(1, &mTexture2D);
1460 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1461 EXPECT_GL_NO_ERROR();
1462
1463 setUpProgram();
1464 }
1465
1466 void testTearDown() override { Texture2DTest::testTearDown(); }
1467};
1468
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001469TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001470{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001471 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001472 EXPECT_GL_ERROR(GL_NO_ERROR);
1473
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001474 setUpProgram();
1475
Jamie Madill50cf2be2018-06-15 09:46:57 -04001476 const GLubyte *pixels[20] = {0};
Jamie Madillf67115c2014-04-22 13:14:05 -04001477 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1478 EXPECT_GL_ERROR(GL_INVALID_VALUE);
Geoff Langc51642b2016-11-14 16:18:26 -05001479
Jamie Madillb8149072019-04-30 16:14:44 -04001480 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
Geoff Langc51642b2016-11-14 16:18:26 -05001481 {
1482 // Create a 1-level immutable texture.
1483 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1484
1485 // Try calling sub image on the second level.
1486 glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1487 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1488 }
Jamie Madillf67115c2014-04-22 13:14:05 -04001489}
Geoff Langc41e42d2014-04-28 10:58:16 -04001490
John Bauman18319182016-09-28 14:22:27 -07001491// Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
1492TEST_P(Texture2DTest, QueryBinding)
1493{
1494 glBindTexture(GL_TEXTURE_2D, 0);
1495 EXPECT_GL_ERROR(GL_NO_ERROR);
1496
1497 GLint textureBinding;
1498 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1499 EXPECT_GL_NO_ERROR();
1500 EXPECT_EQ(0, textureBinding);
1501
1502 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
Jamie Madillb8149072019-04-30 16:14:44 -04001503 if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1504 IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
John Bauman18319182016-09-28 14:22:27 -07001505 {
1506 EXPECT_GL_NO_ERROR();
1507 EXPECT_EQ(0, textureBinding);
1508 }
1509 else
1510 {
1511 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1512 }
1513}
1514
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001515TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001516{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001517 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001518 EXPECT_GL_ERROR(GL_NO_ERROR);
1519
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001520 setUpProgram();
1521
Geoff Langc41e42d2014-04-28 10:58:16 -04001522 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001523 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001524 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001525 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001526
Jamie Madill50cf2be2018-06-15 09:46:57 -04001527 const GLubyte *pixel[4] = {0};
Geoff Langc41e42d2014-04-28 10:58:16 -04001528
1529 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1530 EXPECT_GL_NO_ERROR();
1531
1532 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1533 EXPECT_GL_NO_ERROR();
1534
1535 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1536 EXPECT_GL_NO_ERROR();
1537}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001538
1539// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001540TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001541{
1542 glActiveTexture(GL_TEXTURE0);
1543 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1544 glActiveTexture(GL_TEXTURE1);
1545 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1546 EXPECT_GL_ERROR(GL_NO_ERROR);
1547
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001548 glUseProgram(mProgram);
1549 glUniform1i(mTexture2DUniformLocation, 0);
1550 glUniform1i(mTextureCubeUniformLocation, 1);
1551 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001552 EXPECT_GL_NO_ERROR();
1553}
Jamie Madill9aca0592014-10-06 16:26:59 -04001554
Olli Etuaho53a2da12016-01-11 15:43:32 +02001555// Test drawing with two texture types accessed from the same shader and check that the result of
1556// drawing is correct.
1557TEST_P(TextureCubeTest, CubeMapDraw)
1558{
1559 GLubyte texData[4];
1560 texData[0] = 0;
1561 texData[1] = 60;
1562 texData[2] = 0;
1563 texData[3] = 255;
1564
1565 glActiveTexture(GL_TEXTURE0);
1566 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1567 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1568
1569 glActiveTexture(GL_TEXTURE1);
1570 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1571 texData[1] = 120;
1572 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1573 texData);
1574 EXPECT_GL_ERROR(GL_NO_ERROR);
1575
1576 glUseProgram(mProgram);
1577 glUniform1i(mTexture2DUniformLocation, 0);
1578 glUniform1i(mTextureCubeUniformLocation, 1);
1579 drawQuad(mProgram, "position", 0.5f);
1580 EXPECT_GL_NO_ERROR();
1581
1582 int px = getWindowWidth() - 1;
1583 int py = 0;
1584 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1585}
1586
Olli Etuaho4644a202016-01-12 15:12:53 +02001587TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1588{
1589 glActiveTexture(GL_TEXTURE0);
1590 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1591 GLubyte texData[4];
1592 texData[0] = 0;
1593 texData[1] = 128;
1594 texData[2] = 0;
1595 texData[3] = 255;
1596 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1597 glUseProgram(mProgram);
1598 glUniform1i(mTexture2DUniformLocation, 0);
1599 drawQuad(mProgram, "position", 0.5f);
1600 EXPECT_GL_NO_ERROR();
1601
1602 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1603}
1604
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001605// Test drawing with two textures passed to the shader in a sampler array.
1606TEST_P(SamplerArrayTest, SamplerArrayDraw)
1607{
1608 testSamplerArrayDraw();
1609}
1610
1611// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1612// user-defined function in the shader.
1613TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1614{
Shahbaz Youssefi0864a7a2018-11-07 15:50:15 -05001615 // TODO: Diagnose and fix. http://anglebug.com/2955
1616 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1617
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001618 testSamplerArrayDraw();
1619}
1620
Jamie Madill9aca0592014-10-06 16:26:59 -04001621// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001622TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001623{
1624 int px = getWindowWidth() / 2;
1625 int py = getWindowHeight() / 2;
1626
1627 glActiveTexture(GL_TEXTURE0);
1628 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1629
Olli Etuahoa314b612016-03-10 16:43:00 +02001630 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001631
Olli Etuahoa314b612016-03-10 16:43:00 +02001632 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001633 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1634 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1635 glGenerateMipmap(GL_TEXTURE_2D);
1636
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001637 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001638 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001639 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1640 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001641 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001642 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001643
Olli Etuahoa314b612016-03-10 16:43:00 +02001644 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001645
Olli Etuahoa314b612016-03-10 16:43:00 +02001646 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1647 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001648 glGenerateMipmap(GL_TEXTURE_2D);
1649
Olli Etuahoa314b612016-03-10 16:43:00 +02001650 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001651
Olli Etuahoa314b612016-03-10 16:43:00 +02001652 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1653 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001654 glGenerateMipmap(GL_TEXTURE_2D);
1655
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001656 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001657
1658 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001659 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001660}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001661
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001662// Test creating a FBO with a cube map render target, to test an ANGLE bug
1663// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001664TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001665{
Michael Spangd8506c72019-01-29 15:35:09 -05001666 // http://anglebug.com/3145
1667 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1668
Shahbaz Youssefi0c128e12019-03-25 23:50:14 -04001669 // http://anglebug.com/2822
1670 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1671
Jamie Madill3f3b3582018-09-14 10:38:44 -04001672 GLFramebuffer fbo;
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001673 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1674
1675 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Jamie Madill50cf2be2018-06-15 09:46:57 -04001676 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1677 mTextureCube, 0);
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001678
Corentin Wallez322653b2015-06-17 18:33:56 +02001679 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001680 EXPECT_GL_NO_ERROR();
Jamie Madill3f3b3582018-09-14 10:38:44 -04001681
1682 // Test clearing the six mip faces individually.
1683 std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
1684 GLColor::yellow, GLColor::cyan, GLColor::magenta}};
1685
1686 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1687 {
1688 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1689 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1690
1691 Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
1692 glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
1693 glClear(GL_COLOR_BUFFER_BIT);
1694
1695 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
1696 }
1697
1698 // Iterate the faces again to make sure the colors haven't changed.
1699 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1700 {
1701 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1702 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1703 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
1704 << "face color " << faceIndex << " shouldn't change";
1705 }
1706}
1707
1708// Tests clearing a cube map with a scissor enabled.
1709TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
1710{
1711 // TODO(jie.a.chen): Diagnose and fix. http://anglebug.com/2822
1712 ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
1713
Michael Spangd8506c72019-01-29 15:35:09 -05001714 // http://anglebug.com/3145
1715 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1716
Jamie Madill3f3b3582018-09-14 10:38:44 -04001717 constexpr size_t kSize = 16;
1718
1719 GLFramebuffer fbo;
1720 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1721 glViewport(0, 0, kSize, kSize);
1722
1723 GLTexture texcube;
1724 glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
1725 for (GLenum face = 0; face < 6; face++)
1726 {
1727 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
1728 GL_UNSIGNED_BYTE, nullptr);
1729 }
1730 ASSERT_GL_NO_ERROR();
1731
1732 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1733 texcube, 0);
1734
1735 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1736 ASSERT_GL_NO_ERROR();
1737
1738 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1739 glClear(GL_COLOR_BUFFER_BIT);
1740 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1741
1742 glEnable(GL_SCISSOR_TEST);
1743 glScissor(kSize / 2, 0, kSize / 2, kSize);
1744 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1745 glClear(GL_COLOR_BUFFER_BIT);
1746
1747 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1748 EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
1749
1750 ASSERT_GL_NO_ERROR();
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001751}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001752
Jamie Madill50cf2be2018-06-15 09:46:57 -04001753// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
1754// default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001755TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001756{
Jamie Madillb8149072019-04-30 16:14:44 -04001757 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1758 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -04001759
Jamie Madill50cf2be2018-06-15 09:46:57 -04001760 int width = getWindowWidth();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001761 int height = getWindowHeight();
1762
1763 GLuint tex2D;
1764 glGenTextures(1, &tex2D);
1765 glActiveTexture(GL_TEXTURE0);
1766 glBindTexture(GL_TEXTURE_2D, tex2D);
1767
1768 // Fill with red
1769 std::vector<GLubyte> pixels(3 * 16 * 16);
1770 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1771 {
1772 pixels[pixelId * 3 + 0] = 255;
1773 pixels[pixelId * 3 + 1] = 0;
1774 pixels[pixelId * 3 + 2] = 0;
1775 }
1776
1777 // ANGLE internally uses RGBA as the DirectX format for RGB images
Jamie Madill50cf2be2018-06-15 09:46:57 -04001778 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1779 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
Geoff Langc4e93662017-05-01 10:45:59 -04001780 if (getClientMajorVersion() >= 3)
1781 {
1782 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1783 }
1784 else
1785 {
1786 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1787 }
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001788
1789 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1790 // glTexSubImage2D should take into account that the image is dirty.
1791 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1794
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001795 setUpProgram();
1796
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001797 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001798 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001799 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001800 glDeleteTextures(1, &tex2D);
1801 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001802 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001803
1804 // Validate that the region of the texture without data has an alpha of 1.0
Jamie Madill05b35b22017-10-03 09:01:44 -04001805 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
1806 EXPECT_EQ(255, pixel.A);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001807}
1808
Jamie Madill50cf2be2018-06-15 09:46:57 -04001809// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
1810// initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001811TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001812{
Jamie Madillfc3ec572019-11-27 21:43:22 +00001813 // http://anglebug.com/4126
1814 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
1815
1816 if (getClientMajorVersion() < 3)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001817 {
Jamie Madillfc3ec572019-11-27 21:43:22 +00001818 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1819 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001820 }
Jamie Madillfc3ec572019-11-27 21:43:22 +00001821
1822 const int width = getWindowWidth();
1823 const int height = getWindowHeight();
1824 const size_t pixelCount = width * height;
1825 const int componentCount = 3;
1826
1827 GLuint tex2D;
1828 glGenTextures(1, &tex2D);
1829 glActiveTexture(GL_TEXTURE0);
1830 glBindTexture(GL_TEXTURE_2D, tex2D);
1831
1832 // Fill with red
1833 std::vector<GLubyte> pixels(componentCount * pixelCount);
1834 for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
1835 {
1836 pixels[pixelId * componentCount + 0] = 255;
1837 pixels[pixelId * componentCount + 1] = 0;
1838 pixels[pixelId * componentCount + 2] = 0;
1839 }
1840
1841 // Read 16x16 region from red backbuffer to PBO
1842 GLuint pbo;
1843 glGenBuffers(1, &pbo);
1844 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1845 glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
1846 GL_STATIC_DRAW);
1847
1848 // ANGLE internally uses RGBA as the DirectX format for RGB images
1849 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1850 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
1851 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
1852
1853 // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
1854 // untouched. glTexSubImage2D should take into account that the image is dirty.
1855 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
1856 nullptr);
1857 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1858 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1859
1860 setUpProgram();
1861
1862 glUseProgram(mProgram);
1863 glUniform1i(mTexture2DUniformLocation, 0);
1864 drawQuad(mProgram, "position", 0.5f);
1865 glDeleteTextures(1, &tex2D);
1866 glDeleteBuffers(1, &pbo);
1867 EXPECT_GL_NO_ERROR();
1868 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1869 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1870}
1871
1872// Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
1873// and drawing with the texture
1874// Pseudo code for the follow test:
1875// 1. Upload PBO to mTexture2D
1876// 2. Delete PBO
1877// 3. Draw with otherTexture (x5)
1878// 4. Draw with mTexture2D
1879// 5. Validate color output
1880TEST_P(Texture2DTest, PBOWithMultipleDraws)
1881{
1882 if (getClientMajorVersion() < 3)
1883 {
1884 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1885 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
1886 }
1887
1888 const GLuint width = getWindowWidth();
1889 const GLuint height = getWindowHeight();
1890 const GLuint windowPixelCount = width * height;
1891 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
1892 std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
1893
1894 // Create secondary draw that does not use mTexture
1895 const char *vertexShaderSource = getVertexShaderSource();
1896 const char *fragmentShaderSource = getFragmentShaderSource();
1897 ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
1898
1899 GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
1900 ASSERT_NE(-1, uniformLoc);
1901 glUseProgram(0);
1902
1903 // Create secondary Texture to draw with
1904 GLTexture otherTexture;
1905 glActiveTexture(GL_TEXTURE0);
1906 glBindTexture(GL_TEXTURE_2D, otherTexture);
1907 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1908 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1909 pixelsRed.data());
1910 ASSERT_GL_NO_ERROR();
1911
1912 // Setup primary Texture
1913 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1914 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1915 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1916 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1917 ASSERT_GL_NO_ERROR();
1918
1919 // Setup PBO
1920 GLuint pbo = 0;
1921 glGenBuffers(1, &pbo);
1922 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1923 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
1924 GL_STATIC_DRAW);
1925 ASSERT_GL_NO_ERROR();
1926
1927 // Write PBO to mTexture
1928 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1929 ASSERT_GL_NO_ERROR();
1930 // Delete PBO as ANGLE should be properly handling refcount of this buffer
1931 glDeleteBuffers(1, &pbo);
1932 pixelsGreen.clear();
1933
1934 // Do 5 draws not involving primary texture that the PBO updated
1935 glUseProgram(otherProgram);
1936 glUniform1i(uniformLoc, 0);
1937 glBindTexture(GL_TEXTURE_2D, otherTexture);
1938 drawQuad(otherProgram, "position", 0.5f);
1939 glBindTexture(GL_TEXTURE_2D, 0);
1940 glUseProgram(0);
1941
1942 glUseProgram(otherProgram);
1943 glUniform1i(uniformLoc, 0);
1944 glBindTexture(GL_TEXTURE_2D, otherTexture);
1945 drawQuad(otherProgram, "position", 0.5f);
1946 glBindTexture(GL_TEXTURE_2D, 0);
1947 glUseProgram(0);
1948
1949 glUseProgram(otherProgram);
1950 glUniform1i(uniformLoc, 0);
1951 glBindTexture(GL_TEXTURE_2D, otherTexture);
1952 drawQuad(otherProgram, "position", 0.5f);
1953 glBindTexture(GL_TEXTURE_2D, 0);
1954 glUseProgram(0);
1955
1956 glUseProgram(otherProgram);
1957 glUniform1i(uniformLoc, 0);
1958 glBindTexture(GL_TEXTURE_2D, otherTexture);
1959 drawQuad(otherProgram, "position", 0.5f);
1960 glBindTexture(GL_TEXTURE_2D, 0);
1961 glUseProgram(0);
1962 ASSERT_GL_NO_ERROR();
1963
1964 std::vector<GLColor> output(windowPixelCount, GLColor::black);
1965 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1966 output.data());
1967 EXPECT_EQ(pixelsRed, output);
1968
1969 setUpProgram();
1970 // Draw using PBO updated texture
1971 glUseProgram(mProgram);
1972 glUniform1i(mTexture2DUniformLocation, 0);
1973 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1974 drawQuad(mProgram, "position", 0.5f);
1975 ASSERT_GL_NO_ERROR();
1976
1977 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
1978 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1979 actual.data());
1980 // Value should be green as it was updated during PBO transfer to mTexture
1981 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
1982 EXPECT_EQ(expected, actual);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001983}
Jamie Madillbc393df2015-01-29 13:46:07 -05001984
Mohan Maiya6caa2652019-09-11 08:06:13 -07001985// Tests CopySubImage for float formats
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001986TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001987{
1988 testFloatCopySubImage(1, 1);
1989}
1990
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001991TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001992{
1993 testFloatCopySubImage(2, 1);
1994}
1995
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001996TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001997{
1998 testFloatCopySubImage(2, 2);
1999}
2000
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002001TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002002{
2003 testFloatCopySubImage(3, 1);
2004}
2005
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002006TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002007{
2008 testFloatCopySubImage(3, 2);
2009}
2010
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002011TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002012{
Yunchao He9550c602018-02-13 14:47:05 +08002013 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
Mohan Maiya6caa2652019-09-11 08:06:13 -07002014 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
Corentin Wallez9e3c6152016-03-29 21:58:33 -04002015
Yunchao He9550c602018-02-13 14:47:05 +08002016 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2017 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002018
Jamie Madillbc393df2015-01-29 13:46:07 -05002019 testFloatCopySubImage(3, 3);
2020}
2021
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002022TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002023{
2024 testFloatCopySubImage(4, 1);
2025}
2026
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002027TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002028{
2029 testFloatCopySubImage(4, 2);
2030}
2031
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002032TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002033{
Yunchao He9550c602018-02-13 14:47:05 +08002034 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2035 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002036
Jamie Madillbc393df2015-01-29 13:46:07 -05002037 testFloatCopySubImage(4, 3);
2038}
2039
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002040TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05002041{
Yunchao He9550c602018-02-13 14:47:05 +08002042 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2043 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002044
Jamie Madillbc393df2015-01-29 13:46:07 -05002045 testFloatCopySubImage(4, 4);
2046}
Austin Kinross07285142015-03-26 11:36:16 -07002047
Jamie Madill50cf2be2018-06-15 09:46:57 -04002048// Port of
2049// https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
2050// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
2051// handles GL_ALPHA
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002052TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07002053{
2054 const int npotTexSize = 5;
Jamie Madill50cf2be2018-06-15 09:46:57 -04002055 const int potTexSize = 4; // Should be less than npotTexSize
Austin Kinross07285142015-03-26 11:36:16 -07002056 GLuint tex2D;
2057
Jamie Madillb8149072019-04-30 16:14:44 -04002058 if (IsGLExtensionEnabled("GL_OES_texture_npot"))
Austin Kinross07285142015-03-26 11:36:16 -07002059 {
2060 // This test isn't applicable if texture_npot is enabled
2061 return;
2062 }
2063
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002064 setUpProgram();
2065
Austin Kinross07285142015-03-26 11:36:16 -07002066 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2067
Austin Kinross5faa15b2016-01-11 13:32:48 -08002068 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
2069 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2070
Austin Kinross07285142015-03-26 11:36:16 -07002071 glActiveTexture(GL_TEXTURE0);
2072 glGenTextures(1, &tex2D);
2073 glBindTexture(GL_TEXTURE_2D, tex2D);
2074
Till Rathmannc1551dc2018-08-15 17:04:49 +02002075 const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
Austin Kinross07285142015-03-26 11:36:16 -07002076
2077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2079
2080 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
Jamie Madill50cf2be2018-06-15 09:46:57 -04002081 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2082 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002083 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2084
2085 // Check that an NPOT texture on level 0 succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002086 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2087 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002088 EXPECT_GL_NO_ERROR();
2089
2090 // Check that generateMipmap fails on NPOT
2091 glGenerateMipmap(GL_TEXTURE_2D);
2092 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2093
2094 // Check that nothing is drawn if filtering is not correct for NPOT
2095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2096 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2097 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2098 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2099 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002100 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002101 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2102
2103 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
2104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
2107 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002108 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002109 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2110
2111 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
2112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2113 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002114 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002115 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2116
2117 // Check that glTexImage2D for POT texture succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002118 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
2119 pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002120 EXPECT_GL_NO_ERROR();
2121
2122 // Check that generateMipmap for an POT texture succeeds
2123 glGenerateMipmap(GL_TEXTURE_2D);
2124 EXPECT_GL_NO_ERROR();
2125
2126 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
2127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2131 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002132 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002133 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2134 EXPECT_GL_NO_ERROR();
2135}
Jamie Madillfa05f602015-05-07 13:47:11 -04002136
Austin Kinross08528e12015-10-07 16:24:40 -07002137// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
2138// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002139TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07002140{
2141 glActiveTexture(GL_TEXTURE0);
2142 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2143
2144 // Create an 8x8 (i.e. power-of-two) texture.
2145 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2148 glGenerateMipmap(GL_TEXTURE_2D);
2149
2150 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
2151 // This should always work, even if GL_OES_texture_npot isn't active.
Geoff Langfb052642017-10-24 13:42:09 -04002152 std::array<GLColor, 3 * 3> data;
2153 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
Austin Kinross08528e12015-10-07 16:24:40 -07002154
2155 EXPECT_GL_NO_ERROR();
2156}
2157
Geoff Lang3702d8c2019-04-08 13:44:06 -04002158// Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
2159// TextureImpl and the texture is synced before being used in a draw call.
2160TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
2161{
2162 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
Yuly Novikove6b23e42019-04-10 17:19:15 -04002163 // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
2164 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
Yuly Novikovbd4ff472019-07-19 22:08:17 +00002165 // D3D Debug device reports an error. http://anglebug.com/3501
2166 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
Cody Northrop988f7172019-09-30 15:52:37 -06002167 // TODO(cnorthrop): Needs triage on Vulkan backend. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06002168 ANGLE_SKIP_TEST_IF(IsVulkan());
Geoff Lang3702d8c2019-04-08 13:44:06 -04002169
2170 // The workaround in the GL backend required to trigger this bug generates driver warning
2171 // messages.
2172 ScopedIgnorePlatformMessages ignoreMessages;
2173
2174 setUpProgram();
2175 glUseProgram(mProgram);
2176 glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
2177
2178 GLTexture dest;
2179 glBindTexture(GL_TEXTURE_2D, dest);
2180
2181 GLTexture source;
2182 glBindTexture(GL_TEXTURE_2D, source);
2183
2184 // Put data in mip 0 and 1
2185 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2186 GLColor::red.data());
2187 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2188 GLColor::green.data());
2189
2190 // Disable mipmapping so source is complete
2191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2193
2194 // Force the dirty bits to be synchronized in source
2195 drawQuad(mProgram, "position", 1.0f);
2196
2197 // Copy from mip 1 of the source. In the GL backend this internally sets the base level to mip
2198 // 1 and sets a dirty bit.
2199 glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
2200 GL_FALSE, GL_FALSE);
2201
2202 // Draw again, assertions are generated if the texture has internal dirty bits at draw time
2203 drawQuad(mProgram, "position", 1.0f);
2204}
2205
Geoff Lang6f691fb2019-04-25 11:01:52 -04002206// This test case changes the base level of a texture that's attached to a framebuffer, clears every
2207// level to green, and then samples the texture when rendering. Test is taken from
2208// https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
2209TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
2210{
Cody Northropd192e932019-09-27 10:27:10 -06002211 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
2212 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
Cody Northropcb16fb52019-08-29 16:53:55 -06002213
Geoff Lang6f691fb2019-04-25 11:01:52 -04002214 setUpProgram();
2215
2216 constexpr GLint width = 8;
2217 constexpr GLint height = 4;
2218
2219 GLTexture texture;
2220 glBindTexture(GL_TEXTURE_2D, texture);
2221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2225
2226 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
2227 GLint level = 0;
2228 GLint levelW = width;
2229 GLint levelH = height;
2230 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2231 nullptr);
2232 while (levelW > 1 || levelH > 1)
2233 {
2234 ++level;
2235 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
2236 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
2237 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2238 nullptr);
2239 }
2240
2241 // Clear each level of the texture using an FBO. Change the base level to match the level used
2242 // for the FBO on each iteration.
2243 GLFramebuffer fbo;
2244 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2245 level = 0;
2246 levelW = width;
2247 levelH = height;
2248 while (levelW > 1 || levelH > 1)
2249 {
2250 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
2251 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
2252
2253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
2254 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
2255
2256 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2257 EXPECT_GL_NO_ERROR();
2258
2259 glClearColor(0, 1, 0, 1);
2260 glClear(GL_COLOR_BUFFER_BIT);
2261
2262 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2263
2264 ++level;
2265 }
2266
2267 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2268 glViewport(0, 0, 16, 16);
2269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2270
2271 drawQuad(mProgram, "position", 0.5f);
2272
2273 EXPECT_GL_NO_ERROR();
2274 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2275}
2276
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002277// Test to check that texture completeness is determined correctly when the texture base level is
2278// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
2279TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
2280{
2281 glActiveTexture(GL_TEXTURE0);
2282 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02002283
2284 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
2285 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2286 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2287 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2288 texDataGreen.data());
2289 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2290 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002291 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2292 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2293 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2294
2295 EXPECT_GL_NO_ERROR();
2296
2297 drawQuad(mProgram, "position", 0.5f);
2298
Olli Etuahoa314b612016-03-10 16:43:00 +02002299 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2300}
2301
2302// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2303// have images defined.
2304TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
2305{
Yunchao He9550c602018-02-13 14:47:05 +08002306 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2307 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2308
Olli Etuahoa314b612016-03-10 16:43:00 +02002309 glActiveTexture(GL_TEXTURE0);
2310 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2311 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2312 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2313 texDataGreen.data());
2314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2317 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2318
2319 EXPECT_GL_NO_ERROR();
2320
2321 drawQuad(mProgram, "position", 0.5f);
2322
2323 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2324}
2325
Olli Etuahoe8528d82016-05-16 17:50:52 +03002326// Test that drawing works correctly when level 0 is undefined and base level is 1.
2327TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
2328{
Yunchao He9550c602018-02-13 14:47:05 +08002329 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2330 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2331
Olli Etuahoe8528d82016-05-16 17:50:52 +03002332 glActiveTexture(GL_TEXTURE0);
2333 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2334 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2335 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2336 texDataGreen.data());
2337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2338 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2339 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2341
2342 EXPECT_GL_NO_ERROR();
2343
2344 // Texture is incomplete.
2345 drawQuad(mProgram, "position", 0.5f);
2346 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2347
2348 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2349 texDataGreen.data());
2350
2351 // Texture is now complete.
2352 drawQuad(mProgram, "position", 0.5f);
2353 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2354}
2355
Olli Etuahoa314b612016-03-10 16:43:00 +02002356// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2357// dimensions that don't fit the images inside the range.
2358// GLES 3.0.4 section 3.8.13 Texture completeness
2359TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2360{
Olli Etuahoa314b612016-03-10 16:43:00 +02002361 glActiveTexture(GL_TEXTURE0);
2362 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2363 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
2364 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2365 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
2366
2367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2368 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2369
2370 // Two levels that are initially unused.
2371 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2372 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2373 texDataCyan.data());
2374
2375 // One level that is used - only this level should affect completeness.
2376 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2377 texDataGreen.data());
2378
2379 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2380 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2381
2382 EXPECT_GL_NO_ERROR();
2383
2384 drawQuad(mProgram, "position", 0.5f);
2385
2386 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2387
Yunchao He2f23f352018-02-11 22:11:37 +08002388 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002389
2390 // Switch the level that is being used to the cyan level 2.
2391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2393
2394 EXPECT_GL_NO_ERROR();
2395
2396 drawQuad(mProgram, "position", 0.5f);
2397
2398 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2399}
2400
2401// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2402// have images defined.
2403TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
2404{
Olli Etuahoa314b612016-03-10 16:43:00 +02002405 glActiveTexture(GL_TEXTURE0);
2406 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2407 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2408 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2409 texDataGreen.data());
2410 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2411 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2412 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2413 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2414
2415 EXPECT_GL_NO_ERROR();
2416
2417 drawQuad(mProgram, "position", 0.5f);
2418
2419 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2420}
2421
2422// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2423// dimensions that don't fit the images inside the range.
2424// GLES 3.0.4 section 3.8.13 Texture completeness
2425TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2426{
Yuly Novikovc5da7992019-06-27 12:57:13 -04002427 // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
2428 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
2429
Olli Etuahoa314b612016-03-10 16:43:00 +02002430 glActiveTexture(GL_TEXTURE0);
2431 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2432 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2433 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2434 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2435
2436 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2437 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2438
2439 // Two levels that are initially unused.
2440 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2441 texDataRed.data());
2442 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2443 texDataCyan.data());
2444
2445 // One level that is used - only this level should affect completeness.
2446 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2447 texDataGreen.data());
2448
2449 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2450 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2451
2452 EXPECT_GL_NO_ERROR();
2453
2454 drawQuad(mProgram, "position", 0.5f);
2455
2456 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2457
Yunchao He2f23f352018-02-11 22:11:37 +08002458 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002459
2460 // Switch the level that is being used to the cyan level 2.
2461 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
2462 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
2463
2464 EXPECT_GL_NO_ERROR();
2465
2466 drawQuad(mProgram, "position", 0.5f);
2467
2468 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2469}
2470
2471// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2472// have images defined.
2473TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
2474{
Olli Etuahoa314b612016-03-10 16:43:00 +02002475 glActiveTexture(GL_TEXTURE0);
2476 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2477 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2478 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2479 texDataGreen.data());
2480 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2481 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2482 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2483 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2484
2485 EXPECT_GL_NO_ERROR();
2486
2487 drawQuad(mProgram, "position", 0.5f);
2488
2489 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2490}
2491
2492// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2493// dimensions that don't fit the images inside the range.
2494// GLES 3.0.4 section 3.8.13 Texture completeness
2495TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2496{
Corentin Wallez566c2e32019-08-28 18:37:58 +02002497 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2498 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2499
Olli Etuahoa314b612016-03-10 16:43:00 +02002500 glActiveTexture(GL_TEXTURE0);
2501 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
2502 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2503 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2504 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2505
2506 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2507 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2508
2509 // Two levels that are initially unused.
2510 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2511 texDataRed.data());
2512 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2513 texDataCyan.data());
2514
2515 // One level that is used - only this level should affect completeness.
2516 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2517 texDataGreen.data());
2518
2519 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2520 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2521
2522 EXPECT_GL_NO_ERROR();
2523
2524 drawQuad(mProgram, "position", 0.5f);
2525
2526 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2527
Yunchao He2f23f352018-02-11 22:11:37 +08002528 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2529
Olli Etuahoa314b612016-03-10 16:43:00 +02002530 // Switch the level that is being used to the cyan level 2.
2531 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
2532 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
2533
2534 EXPECT_GL_NO_ERROR();
2535
2536 drawQuad(mProgram, "position", 0.5f);
2537
2538 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2539}
2540
2541// Test that texture completeness is updated if texture max level changes.
2542// GLES 3.0.4 section 3.8.13 Texture completeness
2543TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2544{
Olli Etuahoa314b612016-03-10 16:43:00 +02002545 glActiveTexture(GL_TEXTURE0);
2546 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2547 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2548
2549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2550 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2551
2552 // A level that is initially unused.
2553 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2554 texDataGreen.data());
2555
2556 // One level that is initially used - only this level should affect completeness.
2557 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2558 texDataGreen.data());
2559
2560 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2562
2563 EXPECT_GL_NO_ERROR();
2564
2565 drawQuad(mProgram, "position", 0.5f);
2566
2567 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2568
2569 // Switch the max level to level 1. The levels within the used range now have inconsistent
2570 // dimensions and the texture should be incomplete.
2571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2572
2573 EXPECT_GL_NO_ERROR();
2574
2575 drawQuad(mProgram, "position", 0.5f);
2576
2577 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2578}
2579
2580// Test that 3D texture completeness is updated if texture max level changes.
2581// GLES 3.0.4 section 3.8.13 Texture completeness
2582TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2583{
Olli Etuahoa314b612016-03-10 16:43:00 +02002584 glActiveTexture(GL_TEXTURE0);
2585 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2586 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2587
2588 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2589 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2590
2591 // A level that is initially unused.
2592 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2593 texDataGreen.data());
2594
2595 // One level that is initially used - only this level should affect completeness.
2596 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2597 texDataGreen.data());
2598
2599 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2600 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2601
2602 EXPECT_GL_NO_ERROR();
2603
2604 drawQuad(mProgram, "position", 0.5f);
2605
2606 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2607
2608 // Switch the max level to level 1. The levels within the used range now have inconsistent
2609 // dimensions and the texture should be incomplete.
2610 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2611
2612 EXPECT_GL_NO_ERROR();
2613
2614 drawQuad(mProgram, "position", 0.5f);
2615
2616 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2617}
2618
2619// Test that texture completeness is updated if texture base level changes.
2620// GLES 3.0.4 section 3.8.13 Texture completeness
2621TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2622{
Olli Etuahoa314b612016-03-10 16:43:00 +02002623 glActiveTexture(GL_TEXTURE0);
2624 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2625 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2626
2627 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2628 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2629
2630 // Two levels that are initially unused.
2631 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2632 texDataGreen.data());
2633 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2634 texDataGreen.data());
2635
2636 // One level that is initially used - only this level should affect completeness.
2637 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2638 texDataGreen.data());
2639
2640 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2641 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2642
2643 EXPECT_GL_NO_ERROR();
2644
2645 drawQuad(mProgram, "position", 0.5f);
2646
2647 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2648
2649 // Switch the base level to level 1. The levels within the used range now have inconsistent
2650 // dimensions and the texture should be incomplete.
2651 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2652
2653 EXPECT_GL_NO_ERROR();
2654
2655 drawQuad(mProgram, "position", 0.5f);
2656
2657 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2658}
2659
2660// Test that texture is not complete if base level is greater than max level.
2661// GLES 3.0.4 section 3.8.13 Texture completeness
2662TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2663{
Olli Etuahoa314b612016-03-10 16:43:00 +02002664 glActiveTexture(GL_TEXTURE0);
2665 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2666
2667 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2668 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2669
2670 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2671
2672 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2674
2675 EXPECT_GL_NO_ERROR();
2676
2677 drawQuad(mProgram, "position", 0.5f);
2678
2679 // Texture should be incomplete.
2680 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2681}
2682
2683// Test that immutable texture base level and max level are clamped.
2684// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2685TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2686{
Olli Etuahoa314b612016-03-10 16:43:00 +02002687 glActiveTexture(GL_TEXTURE0);
2688 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2689
2690 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2691 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2692
2693 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2694
2695 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2696
2697 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2698 // should be clamped to [base_level, levels - 1].
2699 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2700 // In the case of this test, those rules make the effective base level and max level 0.
2701 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2702 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2703
2704 EXPECT_GL_NO_ERROR();
2705
2706 drawQuad(mProgram, "position", 0.5f);
2707
2708 // Texture should be complete.
2709 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2710}
2711
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002712// Test that changing base level works when it affects the format of the texture.
2713TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2714{
Corentin Wallez7f00d332019-08-28 15:19:16 +02002715 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2716 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2717
Yunchao He8e5ba8b2018-02-05 17:52:27 +08002718 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
Yunchao He9550c602018-02-13 14:47:05 +08002719
2720 // Observed incorrect rendering on AMD OpenGL.
2721 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002722
2723 glActiveTexture(GL_TEXTURE0);
2724 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2725 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2726 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2727
2728 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2729 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2730
2731 // RGBA8 level that's initially unused.
2732 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2733 texDataCyan.data());
2734
2735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2737
2738 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2739 // format. It reads green channel data from the green and alpha channels of texDataGreen
2740 // (this is a bit hacky but works).
2741 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2742
2743 EXPECT_GL_NO_ERROR();
2744
2745 drawQuad(mProgram, "position", 0.5f);
2746
2747 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2748
2749 // Switch the texture to use the cyan level 0 with the RGBA format.
2750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2752
2753 EXPECT_GL_NO_ERROR();
2754
2755 drawQuad(mProgram, "position", 0.5f);
2756
2757 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2758}
2759
Olli Etuahoa314b612016-03-10 16:43:00 +02002760// Test that setting a texture image works when base level is out of range.
2761TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2762{
2763 glActiveTexture(GL_TEXTURE0);
2764 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2765
2766 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2767 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2768
2769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2771
2772 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2773
2774 EXPECT_GL_NO_ERROR();
2775
2776 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2777
2778 drawQuad(mProgram, "position", 0.5f);
2779
2780 // Texture should be complete.
2781 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002782}
2783
Jamie Madill50cf2be2018-06-15 09:46:57 -04002784// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
2785// RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
2786// with these formats does not work as expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002787TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002788{
2789 std::vector<GLubyte> pixelData;
2790 for (size_t count = 0; count < 5000; count++)
2791 {
2792 pixelData.push_back(0u);
2793 pixelData.push_back(255u);
2794 pixelData.push_back(0u);
2795 }
2796
2797 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002798 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002799 glUniform1i(mTextureArrayLocation, 0);
2800
2801 // The first draw worked correctly.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002802 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2803 &pixelData[0]);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002804
2805 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2806 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2807 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2808 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002809 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002810 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002811
2812 // The dimension of the respecification must match the original exactly to trigger the bug.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002813 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2814 &pixelData[0]);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002815 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002816 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002817
2818 ASSERT_GL_NO_ERROR();
2819}
2820
Olli Etuaho1a679902016-01-14 12:21:47 +02002821// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2822// This test is needed especially to confirm that sampler registers get assigned correctly on
2823// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2824TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2825{
2826 glActiveTexture(GL_TEXTURE0);
2827 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2828 GLubyte texData[4];
2829 texData[0] = 0;
2830 texData[1] = 60;
2831 texData[2] = 0;
2832 texData[3] = 255;
2833 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2834
2835 glActiveTexture(GL_TEXTURE1);
2836 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2837 GLfloat depthTexData[1];
2838 depthTexData[0] = 0.5f;
2839 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2840 depthTexData);
2841
2842 glUseProgram(mProgram);
2843 glUniform1f(mDepthRefUniformLocation, 0.3f);
2844 glUniform1i(mTexture3DUniformLocation, 0);
2845 glUniform1i(mTextureShadowUniformLocation, 1);
2846
2847 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2848 drawQuad(mProgram, "position", 0.5f);
2849 EXPECT_GL_NO_ERROR();
2850 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2851 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2852
2853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2854 drawQuad(mProgram, "position", 0.5f);
2855 EXPECT_GL_NO_ERROR();
2856 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2857 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2858}
2859
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002860// Test multiple different sampler types in the same shader.
2861// This test makes sure that even if sampler / texture registers get grouped together based on type
2862// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2863// still has the right register index information for each ESSL sampler.
2864// The tested ESSL samplers have the following types in D3D11 HLSL:
2865// sampler2D: Texture2D + SamplerState
2866// samplerCube: TextureCube + SamplerState
2867// sampler2DShadow: Texture2D + SamplerComparisonState
2868// samplerCubeShadow: TextureCube + SamplerComparisonState
2869TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2870{
2871 glActiveTexture(GL_TEXTURE0);
2872 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2873 GLubyte texData[4];
2874 texData[0] = 0;
2875 texData[1] = 0;
2876 texData[2] = 120;
2877 texData[3] = 255;
2878 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2879
2880 glActiveTexture(GL_TEXTURE1);
2881 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2882 texData[0] = 0;
2883 texData[1] = 90;
2884 texData[2] = 0;
2885 texData[3] = 255;
2886 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2887 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2888 texData);
2889
2890 glActiveTexture(GL_TEXTURE2);
2891 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2893 GLfloat depthTexData[1];
2894 depthTexData[0] = 0.5f;
2895 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2896 depthTexData);
2897
2898 glActiveTexture(GL_TEXTURE3);
2899 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2900 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2901 depthTexData[0] = 0.2f;
2902 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2903 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2904 depthTexData);
2905
Tobin Ehlisbbf0ce22019-10-11 06:55:36 -06002906 // http://anglebug.com/3949: TODO: Add a DS texture case
2907
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002908 EXPECT_GL_NO_ERROR();
2909
2910 glUseProgram(mProgram);
2911 glUniform1f(mDepthRefUniformLocation, 0.3f);
2912 glUniform1i(mTexture2DUniformLocation, 0);
2913 glUniform1i(mTextureCubeUniformLocation, 1);
2914 glUniform1i(mTexture2DShadowUniformLocation, 2);
2915 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2916
2917 drawQuad(mProgram, "position", 0.5f);
2918 EXPECT_GL_NO_ERROR();
2919 // The shader writes:
2920 // <texture 2d color> +
2921 // <cube map color> +
2922 // 0.25 * <comparison result (1.0)> +
2923 // 0.125 * <comparison result (0.0)>
2924 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2925}
2926
Olli Etuahobce743a2016-01-15 17:18:28 +02002927// Test different base levels on textures accessed through the same sampler array.
2928// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2929TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2930{
Yunchao He9550c602018-02-13 14:47:05 +08002931 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
2932
Jamie Madill788fa362020-02-10 14:07:12 -05002933 // http://anglebug.com/4391
2934 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
2935
Olli Etuahobce743a2016-01-15 17:18:28 +02002936 glActiveTexture(GL_TEXTURE0);
2937 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2938 GLsizei size = 64;
2939 for (GLint level = 0; level < 7; ++level)
2940 {
2941 ASSERT_LT(0, size);
2942 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2943 nullptr);
2944 size = size / 2;
2945 }
2946 ASSERT_EQ(0, size);
2947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2948
2949 glActiveTexture(GL_TEXTURE1);
2950 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2951 size = 128;
2952 for (GLint level = 0; level < 8; ++level)
2953 {
2954 ASSERT_LT(0, size);
2955 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2956 nullptr);
2957 size = size / 2;
2958 }
2959 ASSERT_EQ(0, size);
2960 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2961 EXPECT_GL_NO_ERROR();
2962
2963 glUseProgram(mProgram);
2964 glUniform1i(mTexture0Location, 0);
2965 glUniform1i(mTexture1Location, 1);
2966
Olli Etuaho5804dc82018-04-13 14:11:46 +03002967 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
Olli Etuahobce743a2016-01-15 17:18:28 +02002968 EXPECT_GL_NO_ERROR();
2969 // Red channel: width of level 1 of texture A: 32.
2970 // Green channel: width of level 3 of texture B: 16.
2971 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2972}
2973
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002974// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2975// ES 3.0.4 table 3.24
2976TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2977{
2978 glActiveTexture(GL_TEXTURE0);
2979 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2980 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2981 EXPECT_GL_NO_ERROR();
2982
2983 drawQuad(mProgram, "position", 0.5f);
2984
2985 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2986}
2987
2988// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2989// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05002990TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002991{
Luc Ferron5164b792018-03-06 09:10:12 -05002992 setUpProgram();
2993
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002994 glActiveTexture(GL_TEXTURE0);
2995 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2996 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2997 EXPECT_GL_NO_ERROR();
2998
2999 drawQuad(mProgram, "position", 0.5f);
3000
3001 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3002}
3003
Luc Ferron5164b792018-03-06 09:10:12 -05003004// Validate that every component of the pixel will be equal to the luminance value we've set
3005// and that the alpha channel will be 1 (or 255 to be exact).
3006TEST_P(Texture2DTest, TextureLuminanceRGBSame)
3007{
3008 setUpProgram();
3009
3010 glActiveTexture(GL_TEXTURE0);
3011 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3012 uint8_t pixel = 50;
3013 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
3014 EXPECT_GL_NO_ERROR();
3015
3016 drawQuad(mProgram, "position", 0.5f);
3017
3018 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
3019}
3020
3021// Validate that every component of the pixel will be equal to the luminance value we've set
3022// and that the alpha channel will be the second component.
3023TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
3024{
3025 setUpProgram();
3026
3027 glActiveTexture(GL_TEXTURE0);
3028 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3029 uint8_t pixel[] = {50, 25};
3030 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
3031 GL_UNSIGNED_BYTE, pixel);
3032 EXPECT_GL_NO_ERROR();
3033
3034 drawQuad(mProgram, "position", 0.5f);
3035
3036 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
3037}
3038
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003039// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3040// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003041TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003042{
Jamie Madillb8149072019-04-30 16:14:44 -04003043 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003044 ANGLE_SKIP_TEST_IF(IsD3D9());
3045 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferron5164b792018-03-06 09:10:12 -05003046
3047 setUpProgram();
3048
Luc Ferrond8c632c2018-04-10 12:31:44 -04003049 glActiveTexture(GL_TEXTURE0);
3050 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3051 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
3052 EXPECT_GL_NO_ERROR();
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003053
Luc Ferrond8c632c2018-04-10 12:31:44 -04003054 drawQuad(mProgram, "position", 0.5f);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003055
Luc Ferrond8c632c2018-04-10 12:31:44 -04003056 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003057}
3058
3059// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3060// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003061TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003062{
Jamie Madillb8149072019-04-30 16:14:44 -04003063 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003064 ANGLE_SKIP_TEST_IF(IsD3D9());
3065 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferrond8c632c2018-04-10 12:31:44 -04003066 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
3067 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
Luc Ferron5164b792018-03-06 09:10:12 -05003068
Luc Ferrond8c632c2018-04-10 12:31:44 -04003069 setUpProgram();
Luc Ferron5164b792018-03-06 09:10:12 -05003070
Luc Ferrond8c632c2018-04-10 12:31:44 -04003071 glActiveTexture(GL_TEXTURE0);
3072 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3073 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
3074 EXPECT_GL_NO_ERROR();
Yunchao He9550c602018-02-13 14:47:05 +08003075
Luc Ferrond8c632c2018-04-10 12:31:44 -04003076 drawQuad(mProgram, "position", 0.5f);
Yuly Novikovafcec832016-06-21 22:19:51 -04003077
Luc Ferrond8c632c2018-04-10 12:31:44 -04003078 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003079}
3080
3081// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3082// ES 3.0.4 table 3.24
3083TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
3084{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003085 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3086
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003087 glActiveTexture(GL_TEXTURE0);
3088 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3089 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
3090 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3092 EXPECT_GL_NO_ERROR();
3093
3094 drawQuad(mProgram, "position", 0.5f);
3095
3096 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3097}
3098
3099// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3100// ES 3.0.4 table 3.24
3101TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
3102{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003103 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3104
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003105 glActiveTexture(GL_TEXTURE0);
3106 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3107
3108 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
3109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3111 EXPECT_GL_NO_ERROR();
3112
3113 drawQuad(mProgram, "position", 0.5f);
3114
3115 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3116}
3117
3118// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3119// ES 3.0.4 table 3.24
3120TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
3121{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003122 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3123
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003124 glActiveTexture(GL_TEXTURE0);
3125 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
3127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3129 EXPECT_GL_NO_ERROR();
3130
3131 drawQuad(mProgram, "position", 0.5f);
3132
3133 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3134}
3135
3136// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3137// ES 3.0.4 table 3.24
3138TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
3139{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003140 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3141
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003142 glActiveTexture(GL_TEXTURE0);
3143 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3144 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
3145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3147 EXPECT_GL_NO_ERROR();
3148
3149 drawQuad(mProgram, "position", 0.5f);
3150
3151 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3152}
3153
3154// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3155// ES 3.0.4 table 3.24
3156TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
3157{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003158 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3159
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003160 glActiveTexture(GL_TEXTURE0);
3161 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3162 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
3163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3165 EXPECT_GL_NO_ERROR();
3166
3167 drawQuad(mProgram, "position", 0.5f);
3168
3169 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3170}
3171
3172// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3173// ES 3.0.4 table 3.24
3174TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
3175{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003176 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3177
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003178 glActiveTexture(GL_TEXTURE0);
3179 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3180 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
3181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3183 EXPECT_GL_NO_ERROR();
3184
3185 drawQuad(mProgram, "position", 0.5f);
3186
3187 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3188}
3189
3190// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3191// ES 3.0.4 table 3.24
3192TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
3193{
3194 glActiveTexture(GL_TEXTURE0);
3195 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3196 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
3197 EXPECT_GL_NO_ERROR();
3198
3199 drawQuad(mProgram, "position", 0.5f);
3200
3201 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3202}
3203
3204// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3205// ES 3.0.4 table 3.24
3206TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
3207{
3208 glActiveTexture(GL_TEXTURE0);
3209 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3210 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
3211 nullptr);
3212 EXPECT_GL_NO_ERROR();
3213
3214 drawQuad(mProgram, "position", 0.5f);
3215
3216 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3217}
3218
3219// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3220// ES 3.0.4 table 3.24
3221TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
3222{
Geoff Lang2a19c592019-08-23 14:10:24 -04003223 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3224 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003225
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003226 glActiveTexture(GL_TEXTURE0);
3227 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3228 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
3229 EXPECT_GL_NO_ERROR();
3230
3231 drawQuad(mProgram, "position", 0.5f);
3232
3233 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3234}
3235
3236// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3237// ES 3.0.4 table 3.24
3238TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
3239{
Geoff Lang2a19c592019-08-23 14:10:24 -04003240 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3241 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003242
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003243 glActiveTexture(GL_TEXTURE0);
3244 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3245 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
3246 EXPECT_GL_NO_ERROR();
3247
3248 drawQuad(mProgram, "position", 0.5f);
3249
3250 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3251}
3252
Olli Etuaho96963162016-03-21 11:54:33 +02003253// Use a sampler in a uniform struct.
3254TEST_P(SamplerInStructTest, SamplerInStruct)
3255{
3256 runSamplerInStructTest();
3257}
3258
3259// Use a sampler in a uniform struct that's passed as a function parameter.
3260TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
3261{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003262 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3263 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Geoff Lang8fcdf6e2016-09-16 10:45:30 -04003264
Olli Etuaho96963162016-03-21 11:54:33 +02003265 runSamplerInStructTest();
3266}
3267
3268// Use a sampler in a uniform struct array with a struct from the array passed as a function
3269// parameter.
3270TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
3271{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003272 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3273 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003274
Olli Etuaho96963162016-03-21 11:54:33 +02003275 runSamplerInStructTest();
3276}
3277
3278// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
3279// parameter.
3280TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
3281{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003282 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3283 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003284
Olli Etuaho96963162016-03-21 11:54:33 +02003285 runSamplerInStructTest();
3286}
3287
3288// Make sure that there isn't a name conflict between sampler extracted from a struct and a
3289// similarly named uniform.
3290TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
3291{
3292 runSamplerInStructTest();
3293}
3294
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003295// GL_EXT_texture_filter_anisotropic
3296class TextureAnisotropyTest : public Texture2DTest
3297{
3298 protected:
3299 void uploadTexture()
3300 {
3301 glActiveTexture(GL_TEXTURE0);
3302 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3303 GLColor texDataRed[1] = {GLColor::red};
3304 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
3305 EXPECT_GL_NO_ERROR();
3306 }
3307};
3308
3309// Tests that setting anisotropic filtering doesn't cause failures at draw time.
3310TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
3311{
Jamie Madillb8149072019-04-30 16:14:44 -04003312 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003313
3314 setUpProgram();
3315
3316 uploadTexture();
3317
3318 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3319 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3320 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
3321 EXPECT_GL_NO_ERROR();
3322
3323 drawQuad(mProgram, "position", 0.5f);
3324
3325 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3326 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3327 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
3328}
3329
Till Rathmannb8543632018-10-02 19:46:14 +02003330// GL_OES_texture_border_clamp
3331class TextureBorderClampTest : public Texture2DTest
3332{
3333 protected:
3334 TextureBorderClampTest() : Texture2DTest() {}
3335
Jamie Madill35cd7332018-12-02 12:03:33 -05003336 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003337 {
3338 return
3339 R"(precision highp float;
3340 attribute vec4 position;
3341 varying vec2 texcoord;
3342
3343 void main()
3344 {
3345 gl_Position = vec4(position.xy, 0.0, 1.0);
3346 // texcoords in [-0.5, 1.5]
3347 texcoord = (position.xy) + 0.5;
3348 })";
3349 }
3350
3351 void uploadTexture()
3352 {
3353 glActiveTexture(GL_TEXTURE0);
3354 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3355 std::vector<GLColor> texDataRed(1, GLColor::red);
3356 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3357 texDataRed.data());
3358 EXPECT_GL_NO_ERROR();
3359 }
3360};
3361
3362// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3363// GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
3364TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
3365{
Jamie Madillb8149072019-04-30 16:14:44 -04003366 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003367
3368 setUpProgram();
3369
3370 uploadTexture();
3371
3372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3376 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3377 EXPECT_GL_NO_ERROR();
3378
3379 drawQuad(mProgram, "position", 0.5f);
3380
3381 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3382 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3383 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3384}
3385
3386// Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
3387TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
3388{
Jamie Madillb8149072019-04-30 16:14:44 -04003389 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003390
3391 glActiveTexture(GL_TEXTURE0);
3392 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3393
3394 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3395
3396 GLint colorFixedPoint[4] = {0};
3397 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3398 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3399 std::numeric_limits<GLint>::max()};
3400 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3401 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3402 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3403 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3404
3405 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3406 std::numeric_limits<GLint>::max()};
3407 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3408
3409 GLfloat color[4] = {0.0f};
3410 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
3411 EXPECT_EQ(color[0], kFloatBlue.R);
3412 EXPECT_EQ(color[1], kFloatBlue.G);
3413 EXPECT_EQ(color[2], kFloatBlue.B);
3414 EXPECT_EQ(color[3], kFloatBlue.A);
3415}
3416
3417// Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
3418TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
3419{
Jamie Madillb8149072019-04-30 16:14:44 -04003420 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003421
3422 glActiveTexture(GL_TEXTURE0);
3423 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3424
3425 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
3426 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3427
3428 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3429 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3430
3431 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3432 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3433
3434 GLint colorInt[4] = {0};
3435 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
3436 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3437
3438 if (getClientMajorVersion() < 3)
3439 {
3440 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3441 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3442 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3443 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3444
3445 GLuint colorUInt[4] = {0};
3446 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3447 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3448 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3449 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3450
3451 GLSampler sampler;
3452 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3453 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3454 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3455 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3456
3457 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3458 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3459 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3460 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3461 }
3462}
3463
3464class TextureBorderClampTestES3 : public TextureBorderClampTest
3465{
3466 protected:
3467 TextureBorderClampTestES3() : TextureBorderClampTest() {}
3468};
3469
3470// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3471// GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
3472TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
3473{
Jamie Madillb8149072019-04-30 16:14:44 -04003474 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003475
3476 setUpProgram();
3477
3478 uploadTexture();
3479
3480 GLSampler sampler;
3481 glBindSampler(0, sampler);
3482 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3483 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3484 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3485 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3486 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3487 EXPECT_GL_NO_ERROR();
3488
3489 drawQuad(mProgram, "position", 0.5f);
3490
3491 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3492 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3493 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3494}
3495
3496// Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
3497TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
3498{
Jamie Madillb8149072019-04-30 16:14:44 -04003499 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003500
3501 glActiveTexture(GL_TEXTURE0);
3502
3503 GLSampler sampler;
3504 glBindSampler(0, sampler);
3505
3506 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3507
3508 GLint colorFixedPoint[4] = {0};
3509 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3510 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3511 std::numeric_limits<GLint>::max()};
3512 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3513 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3514 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3515 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3516
3517 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3518 std::numeric_limits<GLint>::max()};
3519 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3520
3521 GLfloat color[4] = {0.0f};
3522 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
3523 EXPECT_EQ(color[0], kFloatBlue.R);
3524 EXPECT_EQ(color[1], kFloatBlue.G);
3525 EXPECT_EQ(color[2], kFloatBlue.B);
3526 EXPECT_EQ(color[3], kFloatBlue.A);
3527
3528 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
3529 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
3530 GLint colorInt[4] = {0};
3531 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3532 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
3533 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
3534 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
3535 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
3536
3537 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
3538 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
3539 GLuint colorUInt[4] = {0};
3540 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3541 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
3542 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
3543 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
3544 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
3545
3546 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3547
3548 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
3549 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
3550 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3551 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
3552 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
3553 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
3554 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
3555
3556 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
3557 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
3558 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3559 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
3560 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
3561 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
3562 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
3563}
3564
3565// Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
3566TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
3567{
Jamie Madillb8149072019-04-30 16:14:44 -04003568 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003569
3570 glActiveTexture(GL_TEXTURE0);
3571
3572 GLSampler sampler;
3573 glBindSampler(0, sampler);
3574
3575 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
3576 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3577
3578 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3579 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3580}
3581
3582class TextureBorderClampIntegerTestES3 : public Texture2DTest
3583{
3584 protected:
3585 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
3586
Jamie Madill35cd7332018-12-02 12:03:33 -05003587 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003588 {
3589 return
3590 R"(#version 300 es
3591 out vec2 texcoord;
3592 in vec4 position;
3593
3594 void main()
3595 {
3596 gl_Position = vec4(position.xy, 0.0, 1.0);
3597 // texcoords in [-0.5, 1.5]
3598 texcoord = (position.xy) + 0.5;
3599 })";
3600 }
3601
Jamie Madillba319ba2018-12-29 10:29:33 -05003602 const char *getFragmentShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003603 {
Jamie Madill35cd7332018-12-02 12:03:33 -05003604 if (isUnsignedIntTest)
3605 {
3606 return "#version 300 es\n"
3607 "precision highp float;\n"
3608 "uniform highp usampler2D tex;\n"
3609 "in vec2 texcoord;\n"
3610 "out vec4 fragColor;\n"
Till Rathmannb8543632018-10-02 19:46:14 +02003611
Jamie Madill35cd7332018-12-02 12:03:33 -05003612 "void main()\n"
3613 "{\n"
3614 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3615 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3616 "fragColor = (texture(tex, texcoord).r == 150u)"
3617 " ? green : red;\n"
3618 "}\n";
3619 }
3620 else
3621 {
3622 return "#version 300 es\n"
3623 "precision highp float;\n"
3624 "uniform highp isampler2D tex;\n"
3625 "in vec2 texcoord;\n"
3626 "out vec4 fragColor;\n"
3627
3628 "void main()\n"
3629 "{\n"
3630 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3631 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3632 "fragColor = (texture(tex, texcoord).r == -50)"
3633 " ? green : red;\n"
3634 "}\n";
3635 }
Till Rathmannb8543632018-10-02 19:46:14 +02003636 }
3637
3638 void uploadTexture()
3639 {
3640 glActiveTexture(GL_TEXTURE0);
3641 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3642 if (isUnsignedIntTest)
3643 {
3644 std::vector<GLubyte> texData(4, 100);
3645 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
3646 texData.data());
3647 }
3648 else
3649 {
3650 std::vector<GLbyte> texData(4, 100);
3651 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
3652 texData.data());
3653 }
3654 EXPECT_GL_NO_ERROR();
3655 }
3656
3657 bool isUnsignedIntTest;
3658};
3659
3660// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3661// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3662TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
3663{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003664 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3665 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3666
Jamie Madillb8149072019-04-30 16:14:44 -04003667 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003668
3669 setUpProgram();
3670
3671 uploadTexture();
3672
3673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3674 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3677
3678 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3679 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3680
3681 EXPECT_GL_NO_ERROR();
3682
3683 drawQuad(mProgram, "position", 0.5f);
3684
3685 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3686 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3687 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3688}
3689
3690// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3691// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3692TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
3693{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003694 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3695 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3696
Jamie Madillb8149072019-04-30 16:14:44 -04003697 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003698
3699 setUpProgram();
3700
3701 uploadTexture();
3702
3703 GLSampler sampler;
3704 glBindSampler(0, sampler);
3705 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3706 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3707 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3708 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3709
3710 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3711 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3712
3713 EXPECT_GL_NO_ERROR();
3714
3715 drawQuad(mProgram, "position", 0.5f);
3716
3717 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3718 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3719 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3720}
3721
3722// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3723// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
3724TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
3725{
Jamie Madillb8149072019-04-30 16:14:44 -04003726 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003727
3728 isUnsignedIntTest = true;
3729
3730 setUpProgram();
3731
3732 uploadTexture();
3733
3734 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3738
3739 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3740 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3741
3742 EXPECT_GL_NO_ERROR();
3743
3744 drawQuad(mProgram, "position", 0.5f);
3745
3746 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3747 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3748 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3749}
3750
3751// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3752// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
3753// glSamplerParameterIuivOES).
3754TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
3755{
Jamie Madillb8149072019-04-30 16:14:44 -04003756 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003757
3758 isUnsignedIntTest = true;
3759
3760 setUpProgram();
3761
3762 uploadTexture();
3763
3764 GLSampler sampler;
3765 glBindSampler(0, sampler);
3766 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3767 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3768 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3769 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3770
3771 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3772 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3773
3774 EXPECT_GL_NO_ERROR();
3775
3776 drawQuad(mProgram, "position", 0.5f);
3777
3778 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3779 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3780 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3781}
3782
3783// ~GL_OES_texture_border_clamp
3784
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003785class TextureLimitsTest : public ANGLETest
3786{
3787 protected:
3788 struct RGBA8
3789 {
3790 uint8_t R, G, B, A;
3791 };
3792
3793 TextureLimitsTest()
3794 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
3795 {
3796 setWindowWidth(128);
3797 setWindowHeight(128);
3798 setConfigRedBits(8);
3799 setConfigGreenBits(8);
3800 setConfigBlueBits(8);
3801 setConfigAlphaBits(8);
3802 }
3803
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003804 void testSetUp() override
Jamie Madill0fdb9562018-09-17 17:18:43 -04003805 {
Jamie Madill0fdb9562018-09-17 17:18:43 -04003806 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
3807 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
3808 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
3809
3810 ASSERT_GL_NO_ERROR();
3811 }
3812
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003813 void testTearDown() override
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003814 {
3815 if (mProgram != 0)
3816 {
3817 glDeleteProgram(mProgram);
3818 mProgram = 0;
3819
3820 if (!mTextures.empty())
3821 {
3822 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
3823 }
3824 }
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003825 }
3826
3827 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
3828 GLint vertexTextureCount,
3829 GLint vertexActiveTextureCount,
3830 const std::string &fragPrefix,
3831 GLint fragmentTextureCount,
3832 GLint fragmentActiveTextureCount)
3833 {
3834 std::stringstream vertexShaderStr;
3835 vertexShaderStr << "attribute vec2 position;\n"
3836 << "varying vec4 color;\n"
3837 << "varying vec2 texCoord;\n";
3838
3839 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
3840 {
3841 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
3842 }
3843
3844 vertexShaderStr << "void main() {\n"
3845 << " gl_Position = vec4(position, 0, 1);\n"
3846 << " texCoord = (position * 0.5) + 0.5;\n"
3847 << " color = vec4(0);\n";
3848
3849 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
3850 {
3851 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
3852 << ", texCoord);\n";
3853 }
3854
3855 vertexShaderStr << "}";
3856
3857 std::stringstream fragmentShaderStr;
3858 fragmentShaderStr << "varying mediump vec4 color;\n"
3859 << "varying mediump vec2 texCoord;\n";
3860
3861 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
3862 {
3863 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
3864 }
3865
3866 fragmentShaderStr << "void main() {\n"
3867 << " gl_FragColor = color;\n";
3868
3869 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
3870 {
3871 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
3872 << ", texCoord);\n";
3873 }
3874
3875 fragmentShaderStr << "}";
3876
3877 const std::string &vertexShaderSource = vertexShaderStr.str();
3878 const std::string &fragmentShaderSource = fragmentShaderStr.str();
3879
Jamie Madill35cd7332018-12-02 12:03:33 -05003880 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003881 }
3882
3883 RGBA8 getPixel(GLint texIndex)
3884 {
3885 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
3886 0, 255u};
3887 return pixel;
3888 }
3889
3890 void initTextures(GLint tex2DCount, GLint texCubeCount)
3891 {
3892 GLint totalCount = tex2DCount + texCubeCount;
3893 mTextures.assign(totalCount, 0);
3894 glGenTextures(totalCount, &mTextures[0]);
3895 ASSERT_GL_NO_ERROR();
3896
3897 std::vector<RGBA8> texData(16 * 16);
3898
3899 GLint texIndex = 0;
3900 for (; texIndex < tex2DCount; ++texIndex)
3901 {
3902 texData.assign(texData.size(), getPixel(texIndex));
3903 glActiveTexture(GL_TEXTURE0 + texIndex);
3904 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
3905 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3906 &texData[0]);
3907 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3908 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3909 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3910 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3911 }
3912
3913 ASSERT_GL_NO_ERROR();
3914
3915 for (; texIndex < texCubeCount; ++texIndex)
3916 {
3917 texData.assign(texData.size(), getPixel(texIndex));
3918 glActiveTexture(GL_TEXTURE0 + texIndex);
3919 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
3920 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3921 GL_UNSIGNED_BYTE, &texData[0]);
3922 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3923 GL_UNSIGNED_BYTE, &texData[0]);
3924 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3925 GL_UNSIGNED_BYTE, &texData[0]);
3926 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3927 GL_UNSIGNED_BYTE, &texData[0]);
3928 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3929 GL_UNSIGNED_BYTE, &texData[0]);
3930 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3931 GL_UNSIGNED_BYTE, &texData[0]);
3932 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3933 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3934 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3935 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3936 }
3937
3938 ASSERT_GL_NO_ERROR();
3939 }
3940
3941 void testWithTextures(GLint vertexTextureCount,
3942 const std::string &vertexTexturePrefix,
3943 GLint fragmentTextureCount,
3944 const std::string &fragmentTexturePrefix)
3945 {
3946 // Generate textures
3947 initTextures(vertexTextureCount + fragmentTextureCount, 0);
3948
3949 glUseProgram(mProgram);
3950 RGBA8 expectedSum = {0};
3951 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
3952 {
3953 std::stringstream uniformNameStr;
3954 uniformNameStr << vertexTexturePrefix << texIndex;
3955 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003956 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003957 ASSERT_NE(-1, location);
3958
3959 glUniform1i(location, texIndex);
3960 RGBA8 contribution = getPixel(texIndex);
3961 expectedSum.R += contribution.R;
3962 expectedSum.G += contribution.G;
3963 }
3964
3965 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
3966 {
3967 std::stringstream uniformNameStr;
3968 uniformNameStr << fragmentTexturePrefix << texIndex;
3969 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003970 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003971 ASSERT_NE(-1, location);
3972
3973 glUniform1i(location, texIndex + vertexTextureCount);
3974 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
3975 expectedSum.R += contribution.R;
3976 expectedSum.G += contribution.G;
3977 }
3978
3979 ASSERT_GE(256u, expectedSum.G);
3980
3981 drawQuad(mProgram, "position", 0.5f);
3982 ASSERT_GL_NO_ERROR();
3983 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
3984 }
3985
3986 GLuint mProgram;
3987 std::vector<GLuint> mTextures;
3988 GLint mMaxVertexTextures;
3989 GLint mMaxFragmentTextures;
3990 GLint mMaxCombinedTextures;
3991};
3992
3993// Test rendering with the maximum vertex texture units.
3994TEST_P(TextureLimitsTest, MaxVertexTextures)
3995{
3996 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
3997 ASSERT_NE(0u, mProgram);
3998 ASSERT_GL_NO_ERROR();
3999
4000 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4001}
4002
4003// Test rendering with the maximum fragment texture units.
4004TEST_P(TextureLimitsTest, MaxFragmentTextures)
4005{
4006 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
4007 ASSERT_NE(0u, mProgram);
4008 ASSERT_GL_NO_ERROR();
4009
4010 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
4011}
4012
4013// Test rendering with maximum combined texture units.
4014TEST_P(TextureLimitsTest, MaxCombinedTextures)
4015{
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004016 // TODO(timvp): http://anglebug.com/3570
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004017 // max per-stage sampled image bindings count (32) exceeds device
4018 // maxPerStageDescriptorSampledImages limit (16)
Shahbaz Youssefi57f7b692020-06-05 00:45:01 -04004019 ANGLE_SKIP_TEST_IF(isSwiftshader());
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004020
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004021 GLint vertexTextures = mMaxVertexTextures;
4022
4023 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
4024 {
4025 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
4026 }
4027
4028 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
4029 mMaxFragmentTextures, mMaxFragmentTextures);
4030 ASSERT_NE(0u, mProgram);
4031 ASSERT_GL_NO_ERROR();
4032
4033 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
4034}
4035
4036// Negative test for exceeding the number of vertex textures
4037TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
4038{
4039 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
4040 0);
4041 ASSERT_EQ(0u, mProgram);
4042}
4043
4044// Negative test for exceeding the number of fragment textures
4045TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
4046{
4047 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
4048 mMaxFragmentTextures + 1);
4049 ASSERT_EQ(0u, mProgram);
4050}
4051
4052// Test active vertex textures under the limit, but excessive textures specified.
4053TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
4054{
4055 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
4056 ASSERT_NE(0u, mProgram);
4057 ASSERT_GL_NO_ERROR();
4058
4059 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4060}
4061
4062// Test active fragment textures under the limit, but excessive textures specified.
4063TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
4064{
4065 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
4066 mMaxFragmentTextures);
4067 ASSERT_NE(0u, mProgram);
4068 ASSERT_GL_NO_ERROR();
4069
4070 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
4071}
4072
4073// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02004074// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004075TEST_P(TextureLimitsTest, TextureTypeConflict)
4076{
Jamie Madill35cd7332018-12-02 12:03:33 -05004077 constexpr char kVS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004078 "attribute vec2 position;\n"
4079 "varying float color;\n"
4080 "uniform sampler2D tex2D;\n"
4081 "uniform samplerCube texCube;\n"
4082 "void main() {\n"
4083 " gl_Position = vec4(position, 0, 1);\n"
4084 " vec2 texCoord = (position * 0.5) + 0.5;\n"
4085 " color = texture2D(tex2D, texCoord).x;\n"
4086 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
4087 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05004088 constexpr char kFS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004089 "varying mediump float color;\n"
4090 "void main() {\n"
4091 " gl_FragColor = vec4(color, 0, 0, 1);\n"
4092 "}";
4093
Jamie Madill35cd7332018-12-02 12:03:33 -05004094 mProgram = CompileProgram(kVS, kFS);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004095 ASSERT_NE(0u, mProgram);
4096
4097 initTextures(1, 0);
4098
4099 glUseProgram(mProgram);
4100 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
4101 ASSERT_NE(-1, tex2DLocation);
4102 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
4103 ASSERT_NE(-1, texCubeLocation);
4104
4105 glUniform1i(tex2DLocation, 0);
4106 glUniform1i(texCubeLocation, 0);
4107 ASSERT_GL_NO_ERROR();
4108
4109 drawQuad(mProgram, "position", 0.5f);
4110 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4111}
4112
Vincent Lang25ab4512016-05-13 18:13:59 +02004113class Texture2DNorm16TestES3 : public Texture2DTestES3
4114{
4115 protected:
4116 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
4117
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004118 void testSetUp() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004119 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004120 Texture2DTestES3::testSetUp();
Vincent Lang25ab4512016-05-13 18:13:59 +02004121
4122 glActiveTexture(GL_TEXTURE0);
4123 glGenTextures(3, mTextures);
4124 glGenFramebuffers(1, &mFBO);
4125 glGenRenderbuffers(1, &mRenderbuffer);
4126
4127 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
4128 {
4129 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
4130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4132 }
4133
4134 glBindTexture(GL_TEXTURE_2D, 0);
4135
4136 ASSERT_GL_NO_ERROR();
4137 }
4138
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004139 void testTearDown() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004140 {
4141 glDeleteTextures(3, mTextures);
4142 glDeleteFramebuffers(1, &mFBO);
4143 glDeleteRenderbuffers(1, &mRenderbuffer);
4144
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004145 Texture2DTestES3::testTearDown();
Vincent Lang25ab4512016-05-13 18:13:59 +02004146 }
4147
4148 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
4149 {
shrekshao81ee4d22019-12-04 17:05:11 -08004150 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4151 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4152 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4153
Geoff Langf607c602016-09-21 11:46:48 -04004154 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
4155 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004156
4157 setUpProgram();
4158
4159 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4160 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
4161 0);
4162
4163 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
4164 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
4165
4166 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Geoff Langf607c602016-09-21 11:46:48 -04004167 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004168
4169 EXPECT_GL_NO_ERROR();
4170
4171 drawQuad(mProgram, "position", 0.5f);
4172
Geoff Langf607c602016-09-21 11:46:48 -04004173 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
Vincent Lang25ab4512016-05-13 18:13:59 +02004174
Jamie Madill50cf2be2018-06-15 09:46:57 -04004175 EXPECT_PIXEL_COLOR_EQ(0, 0,
4176 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
4177 expectedValue, expectedValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004178
4179 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4180
4181 ASSERT_GL_NO_ERROR();
4182 }
4183
shrekshao81ee4d22019-12-04 17:05:11 -08004184 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
4185 GLuint y,
4186 GLuint width,
4187 GLuint height,
4188 GLint packRowLength,
4189 GLint packAlignment,
4190 GLint packSkipPixels,
4191 GLint packSkipRows,
4192 GLenum type,
4193 GLColor16UI color)
Vincent Lang25ab4512016-05-13 18:13:59 +02004194 {
shrekshao81ee4d22019-12-04 17:05:11 -08004195 // PACK modes debugging
4196 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
4197 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
4198
4199 GLuint l = packRowLength == 0 ? width : packRowLength;
4200 const GLint &a = packAlignment;
4201
4202 // According to
4203 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4204 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
4205 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
4206 if (static_cast<GLuint>(packRowLength) < width)
4207 {
4208 componentCount += width * n * s - k;
4209 }
4210
4211 // Populate the pixels array with random dirty value
4212 constexpr GLushort kDirtyValue = 0x1234;
4213 std::vector<GLushort> pixels(componentCount, kDirtyValue);
4214 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
4215
4216 EXPECT_GL_NO_ERROR();
4217
4218 GLushort *pixelRowStart = pixels.data();
4219 pixelRowStart += n * packSkipPixels + k * packSkipRows;
4220
4221 std::vector<bool> modifiedPixels(componentCount, false);
4222
4223 char errorInfo[200];
4224
4225 for (GLuint y = 0; y < height; ++y)
4226 {
4227 GLushort *curPixel = pixelRowStart;
4228 for (GLuint x = 0, len = (y == height - 1) ? width : std::min(l, width); x < len; ++x)
4229 {
4230 snprintf(errorInfo, sizeof(errorInfo),
4231 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
4232 "skipPixels: %d, skipRows: %d\n",
4233 width, height, x, y, packRowLength, packAlignment, packSkipPixels,
4234 packSkipRows);
4235 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
4236 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
4237 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
4238 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
4239
4240 std::ptrdiff_t diff = curPixel - pixels.data();
4241 modifiedPixels[diff + 0] = true;
4242 modifiedPixels[diff + 1] = true;
4243 modifiedPixels[diff + 2] = true;
4244 modifiedPixels[diff + 3] = true;
4245
4246 curPixel += n;
4247 }
4248 pixelRowStart += k;
4249 }
4250
4251 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
4252 {
4253 if (!modifiedPixels[i])
4254 {
4255 EXPECT_EQ(pixels[i], kDirtyValue);
4256 }
4257 }
4258 }
4259
4260 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
4261 {
4262 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4263 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4264 // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
4265 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
4266 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4267
Jamie Madill50cf2be2018-06-15 09:46:57 -04004268 GLushort pixelValue = 0x6A35;
Geoff Langf607c602016-09-21 11:46:48 -04004269 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
shrekshao81ee4d22019-12-04 17:05:11 -08004270 GLColor16UI color = SliceFormatColor16UI(
4271 format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
4272 // Size of drawing viewport
4273 constexpr GLint width = 8, height = 8;
Vincent Lang25ab4512016-05-13 18:13:59 +02004274
4275 setUpProgram();
4276
4277 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
shrekshao81ee4d22019-12-04 17:05:11 -08004278 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
Vincent Lang25ab4512016-05-13 18:13:59 +02004279
4280 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4281 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4282 0);
4283
4284 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
Geoff Langf607c602016-09-21 11:46:48 -04004285 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
shrekshao81ee4d22019-12-04 17:05:11 -08004286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Vincent Lang25ab4512016-05-13 18:13:59 +02004288
4289 EXPECT_GL_NO_ERROR();
4290
4291 drawQuad(mProgram, "position", 0.5f);
4292
shrekshao81ee4d22019-12-04 17:05:11 -08004293 // ReadPixels against different width, height, pixel pack mode combinations to test
4294 // workaround of pixels rearrangement
4295
4296 // {x, y, width, height}
4297 std::vector<std::array<GLint, 4>> areas = {
4298 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
4299 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
4300
4301 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
4302
4303 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
4304 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
4305 };
4306
4307 // Put default settings at the last
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01004308 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
4309 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
shrekshao81ee4d22019-12-04 17:05:11 -08004310 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
4311 {3, 1}, {20, 20}, {0, 0}};
4312
4313 // Restore pixel pack modes later
4314 GLint restorePackAlignment;
4315 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
4316 GLint restorePackRowLength;
4317 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
4318 GLint restorePackSkipPixels;
4319 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
4320 GLint restorePackSkipRows;
4321 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
4322
4323 // Variable symbols are based on:
4324 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4325 for (const auto &skipped : paramsPackSkipPixelsAndRows)
4326 {
4327 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
4328 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
4329 for (GLint a : paramsPackAlignment)
4330 {
4331 glPixelStorei(GL_PACK_ALIGNMENT, a);
4332 for (GLint l : paramsPackRowLength)
4333 {
4334 glPixelStorei(GL_PACK_ROW_LENGTH, l);
4335
4336 for (const auto &area : areas)
4337 {
4338 ASSERT(area[0] + area[2] <= width);
4339 ASSERT(area[1] + area[3] <= height);
4340 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
4341 area[3], l, a, skipped[0],
4342 skipped[1], type, color);
4343 }
4344 }
4345 }
4346 }
4347
4348 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
4349 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
4350 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
4351 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
Vincent Lang25ab4512016-05-13 18:13:59 +02004352
4353 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4354 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4355 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4356 mRenderbuffer);
4357 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4358 EXPECT_GL_NO_ERROR();
4359
4360 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4361 glClear(GL_COLOR_BUFFER_BIT);
4362
shrekshaofb1c2fe2019-11-13 11:10:39 -08004363 EXPECT_PIXEL_16UI_COLOR(
4364 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
shrekshaoe33c1582019-11-06 16:55:29 -08004365
4366 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Vincent Lang25ab4512016-05-13 18:13:59 +02004367 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4368
shrekshaoe33c1582019-11-06 16:55:29 -08004369 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4370 0);
shrekshaofb1c2fe2019-11-13 11:10:39 -08004371 EXPECT_PIXEL_16UI_COLOR(
4372 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004373
4374 ASSERT_GL_NO_ERROR();
shrekshaofb1c2fe2019-11-13 11:10:39 -08004375
4376 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Vincent Lang25ab4512016-05-13 18:13:59 +02004377 }
4378
4379 GLuint mTextures[3];
4380 GLuint mFBO;
4381 GLuint mRenderbuffer;
4382};
4383
shrekshao81ee4d22019-12-04 17:05:11 -08004384TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
Vincent Lang25ab4512016-05-13 18:13:59 +02004385{
Vincent Lang25ab4512016-05-13 18:13:59 +02004386 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
shrekshao81ee4d22019-12-04 17:05:11 -08004387}
Vincent Lang25ab4512016-05-13 18:13:59 +02004388
shrekshao81ee4d22019-12-04 17:05:11 -08004389TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
4390{
4391 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
4392}
4393
4394TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
4395{
4396 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4397}
4398
4399TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
4400{
4401 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
4402}
4403
4404TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
4405{
4406 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4407 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4408
4409 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
4410}
4411
4412TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
4413{
4414 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4415 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4416
4417 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
4418}
4419
4420TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
4421{
4422 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4423}
4424
4425TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
4426{
4427 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
4428}
4429
4430TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
4431{
4432 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
4433}
4434
4435TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
4436{
4437 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4438}
4439
4440TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
4441{
4442 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
Vincent Lang25ab4512016-05-13 18:13:59 +02004443}
4444
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004445class Texture2DRGTest : public Texture2DTest
4446{
4447 protected:
4448 Texture2DRGTest()
4449 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4450 {}
4451
4452 void testSetUp() override
4453 {
4454 Texture2DTest::testSetUp();
4455
4456 glActiveTexture(GL_TEXTURE0);
4457 glGenTextures(1, &mRenderableTexture);
4458 glGenTextures(1, &mTestTexture);
4459 glGenFramebuffers(1, &mFBO);
4460 glGenRenderbuffers(1, &mRenderbuffer);
4461
4462 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004463 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4464 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004465 glBindTexture(GL_TEXTURE_2D, mTestTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004466 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4467 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004468
4469 glBindTexture(GL_TEXTURE_2D, 0);
4470
4471 setUpProgram();
4472 glUseProgram(mProgram);
4473 glUniform1i(mTexture2DUniformLocation, 0);
4474
4475 ASSERT_GL_NO_ERROR();
4476 }
4477
4478 void testTearDown() override
4479 {
4480 glDeleteTextures(1, &mRenderableTexture);
4481 glDeleteTextures(1, &mTestTexture);
4482 glDeleteFramebuffers(1, &mFBO);
4483 glDeleteRenderbuffers(1, &mRenderbuffer);
4484
4485 Texture2DTest::testTearDown();
4486 }
4487
4488 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
4489 {
4490 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4491 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4492
4493 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4494 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4495 mRenderableTexture, 0);
4496
4497 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4498 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
4499
4500 EXPECT_GL_NO_ERROR();
4501 }
4502
4503 void testRGTexture(GLColor expectedColor)
4504 {
4505 drawQuad(mProgram, "position", 0.5f);
4506
4507 EXPECT_GL_NO_ERROR();
4508 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
4509 }
4510
4511 void testRGRender(GLenum internalformat, GLenum format)
4512 {
4513 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4514 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4515 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4516 mRenderbuffer);
4517 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4518 EXPECT_GL_NO_ERROR();
4519
4520 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4521 glClear(GL_COLOR_BUFFER_BIT);
4522
4523 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4524
4525 ASSERT_GL_NO_ERROR();
4526 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
4527 }
4528
4529 GLuint mRenderableTexture;
4530 GLuint mTestTexture;
4531 GLuint mFBO;
4532 GLuint mRenderbuffer;
4533};
4534
4535// Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
4536TEST_P(Texture2DRGTest, TextureRGUNormTest)
4537{
4538 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
James Darpinian336e8912020-05-29 16:09:47 -07004539 // This workaround causes a GL error on Windows AMD, which is likely a driver bug.
4540 // The workaround is not intended to be enabled in this configuration so skip it.
4541 ANGLE_SKIP_TEST_IF(GetParam().eglParameters.emulateCopyTexImage2DFromRenderbuffers &&
4542 IsWindows() && IsAMD());
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004543
4544 GLubyte pixelValue = 0xab;
4545 GLubyte imageData[] = {pixelValue, pixelValue};
4546
4547 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
4548 testRGTexture(
4549 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4550 testRGRender(GL_R8_EXT, GL_RED_EXT);
4551
4552 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
4553 testRGTexture(
4554 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4555 testRGRender(GL_RG8_EXT, GL_RG_EXT);
4556}
4557
4558// Test float texture formats enabled by the GL_EXT_texture_rg extension.
4559TEST_P(Texture2DRGTest, TextureRGFloatTest)
4560{
4561 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4562 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4563
4564 GLfloat pixelValue = 0.54321;
4565 GLfloat imageData[] = {pixelValue, pixelValue};
4566
4567 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
4568 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4569
4570 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
4571 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4572
4573 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
4574 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4575}
4576
4577// Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
Mohan Maiya6caa2652019-09-11 08:06:13 -07004578TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004579{
4580 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4581 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4582
4583 GLfloat pixelValueFloat = 0.543f;
4584 GLhalf pixelValue = 0x3858;
4585 GLhalf imageData[] = {pixelValue, pixelValue};
4586
4587 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
4588 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4589
4590 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
4591 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4592
4593 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
4594 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4595}
4596
Mohan Maiya6caa2652019-09-11 08:06:13 -07004597class Texture2DFloatTest : public Texture2DTest
4598{
4599 protected:
4600 Texture2DFloatTest()
4601 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4602 {}
4603
4604 void testSetUp() override
4605 {
4606 Texture2DTest::testSetUp();
4607
4608 glActiveTexture(GL_TEXTURE0);
4609 glGenTextures(1, &mRenderableTexture);
4610 glGenTextures(1, &mTestTexture);
4611 glGenFramebuffers(1, &mFBO);
4612 glGenRenderbuffers(1, &mRenderbuffer);
4613
4614 setUpProgram();
4615 glUseProgram(mProgram);
4616 glUniform1i(mTexture2DUniformLocation, 0);
4617
4618 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4619 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4620
4621 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4622 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4623 mRenderableTexture, 0);
4624
4625 ASSERT_GL_NO_ERROR();
4626 }
4627
4628 void testTearDown() override
4629 {
4630 glDeleteTextures(1, &mRenderableTexture);
4631 glDeleteTextures(1, &mTestTexture);
4632 glDeleteFramebuffers(1, &mFBO);
4633 glDeleteRenderbuffers(1, &mRenderbuffer);
4634
4635 Texture2DTest::testTearDown();
4636 }
4637
4638 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
4639 {
4640 constexpr GLfloat imageDataFloat[] = {
4641 0.2f,
4642 0.3f,
4643 0.4f,
4644 0.5f,
4645 };
4646 constexpr GLhalf imageDataHalf[] = {
4647 0x3266,
4648 0x34CD,
4649 0x3666,
4650 0x3800,
4651 };
4652 GLColor expectedValue;
4653 for (int i = 0; i < 4; i++)
4654 {
4655 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
4656 }
4657
4658 const GLvoid *imageData;
4659 switch (type)
4660 {
4661 case GL_FLOAT:
4662 imageData = imageDataFloat;
4663 break;
4664 case GL_HALF_FLOAT:
4665 case GL_HALF_FLOAT_OES:
4666 imageData = imageDataHalf;
4667 break;
4668 default:
4669 imageData = nullptr;
4670 }
4671 ASSERT(imageData != nullptr);
4672
4673 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4674 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
4675
4676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4677 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4678
4679 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4680 drawQuad(mProgram, "position", 0.5f);
4681
4682 EXPECT_GL_NO_ERROR();
4683 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
4684 }
4685
4686 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
4687 {
4688 int numComponents;
4689 switch (format)
4690 {
4691 case GL_RGBA:
4692 numComponents = 4;
4693 break;
4694 case GL_RGB:
4695 numComponents = 3;
4696 break;
4697 case GL_LUMINANCE_ALPHA:
4698 numComponents = 2;
4699 break;
4700 case GL_LUMINANCE:
4701 case GL_ALPHA:
4702 numComponents = 1;
4703 break;
4704 default:
4705 numComponents = 0;
4706 }
4707 ASSERT(numComponents > 0);
4708
4709 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
4710 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
4711
4712 GLfloat imageDataFloat[16];
4713 GLhalf imageDataHalf[16];
4714 for (int i = 0; i < 4; i++)
4715 {
4716 for (int c = 0; c < numComponents; c++)
4717 {
4718 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
4719 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
4720 }
4721 }
4722
4723 const GLvoid *imageData;
4724 switch (type)
4725 {
4726 case GL_FLOAT:
4727 imageData = imageDataFloat;
4728 break;
4729 case GL_HALF_FLOAT:
4730 case GL_HALF_FLOAT_OES:
4731 imageData = imageDataHalf;
4732 break;
4733 default:
4734 imageData = nullptr;
4735 }
4736 ASSERT(imageData != nullptr);
4737
4738 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4739 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
4740
4741 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4742 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4743
4744 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4745 drawQuad(mProgram, "position", 0.5f);
4746
4747 EXPECT_GL_NO_ERROR();
4748 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
4749 // should expect the final value to be gray (halfway in-between)
4750 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
4751 kPixelTolerance);
4752 }
4753
4754 bool performFloatTextureRender(GLenum internalFormat,
4755 GLenum renderBufferFormat,
4756 GLenum format,
4757 GLenum type)
4758 {
4759 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4760 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
4761 glBindTexture(GL_TEXTURE_2D, 0);
4762
4763 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4764 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
4765 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4766 mRenderbuffer);
4767 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4768 EXPECT_GL_NO_ERROR();
4769
4770 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
4771 {
4772 return false;
4773 }
4774
4775 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4776
4777 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4778 glClear(GL_COLOR_BUFFER_BIT);
4779
4780 EXPECT_GL_NO_ERROR();
4781 return true;
4782 }
4783
4784 GLuint mRenderableTexture;
4785 GLuint mTestTexture;
4786 GLuint mFBO;
4787 GLuint mRenderbuffer;
4788};
4789
4790class Texture2DFloatTestES3 : public Texture2DFloatTest
4791{
4792 protected:
4793 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
4794 {
4795 bool framebufferComplete =
4796 performFloatTextureRender(internalFormat, internalFormat, format, type);
4797 EXPECT_TRUE(framebufferComplete);
4798 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4799 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4800 kPixelTolerance32F);
4801 }
4802};
4803
4804class Texture2DFloatTestES2 : public Texture2DFloatTest
4805{
4806 protected:
4807 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
4808 {
4809 bool framebufferComplete =
4810 performFloatTextureRender(format, renderBufferFormat, format, type);
4811
4812 if (!framebufferComplete)
4813 {
4814 return false;
4815 }
4816
4817 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4818 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4819 kPixelTolerance32F);
4820 return true;
4821 }
4822};
4823
4824// Test texture sampling for ES3 float texture formats
4825TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
4826{
4827 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4828 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
4829}
4830
4831// Test texture sampling for ES2 float texture formats
4832TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
4833{
4834 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4835 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
4836 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
4837}
4838
4839// Test texture sampling for ES3 half float texture formats
4840TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
4841{
4842 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4843 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4844}
4845
4846// Test texture sampling for ES2 half float texture formats
4847TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
4848{
4849 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4850 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4851 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4852}
4853
4854// Test texture sampling for legacy GLES 2.0 float texture formats in ES3
4855TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
4856{
4857 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4858
4859 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4860 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4861 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4862
4863 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4864 {
4865 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4866 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4867 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4868 }
4869}
4870
4871// Test texture sampling for legacy GLES 2.0 float texture formats in ES2
4872TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
4873{
4874 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4875
4876 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4877 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4878 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4879}
4880
4881// Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
4882TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
4883{
4884 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4885
4886 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4887 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4888 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4889
4890 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4891 {
4892 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4893 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4894 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4895 }
4896}
4897// Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
4898TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
4899{
4900 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4901
4902 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4903 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4904 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4905}
4906
4907// Test linear sampling for ES3 32F formats
4908TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
4909{
4910 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4911
4912 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4913 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
4914}
4915// Test linear sampling for ES2 32F formats
4916TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
4917{
4918 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4919
4920 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4921
4922 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
4923}
4924
4925// Test linear sampling for ES3 16F formats
4926TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
4927{
4928 // Half float formats must be linearly filterable in GLES 3.0 core
4929 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4930 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4931}
4932// Test linear sampling for ES2 16F formats
4933TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
4934{
4935 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4936 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4937 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4938}
4939
4940// Test linear sampling for legacy GLES 2.0 32F formats in ES3
4941TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
4942{
4943 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4944 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4945
4946 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4947 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4948 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4949
4950 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4951 {
4952 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4953 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4954 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4955 }
4956}
4957// Test linear sampling for legacy GLES 2.0 32F formats in ES2
4958TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
4959{
4960 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4961 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4962
4963 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4964 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4965 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4966}
4967
4968// Test linear sampling for legacy GLES 2.0 16F formats in ES3
4969TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
4970{
4971 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4972 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4973
4974 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4975 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4976 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4977
4978 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4979 {
4980 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4981 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4982 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4983 }
4984}
4985// Test linear sampling for legacy GLES 2.0 16F formats in ES2
4986TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
4987{
4988 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4989 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4990
4991 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4992 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4993 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4994}
4995
4996// Test color-renderability for ES3 float and half float textures
4997TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
4998{
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07004999 // http://anglebug.com/4092
5000 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07005001 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
5002 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
5003
5004 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
5005 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
5006 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
5007
5008 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
5009 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
5010 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
5011
5012 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
5013}
5014
5015// Test color-renderability for ES2 half float textures
5016TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
5017{
5018 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
5019 // require a specific one
5020 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
Zhenyao Mo20bb47d2019-09-16 12:55:30 -07005021 // https://crbug.com/1003971
5022 ANGLE_SKIP_TEST_IF(IsOzone());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005023 // http://anglebug.com/4092
5024 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07005025
5026 bool atLeastOneSupported = false;
5027
5028 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
5029 IsGLExtensionEnabled("GL_OES_texture_half_float"))
5030 {
5031 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
5032 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
5033 }
5034 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
5035 {
5036 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
5037
5038 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
5039 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
5040 EXPECT_TRUE(rgbaSupported);
5041 atLeastOneSupported |= rgbaSupported;
5042 }
5043
5044 EXPECT_TRUE(atLeastOneSupported);
5045}
5046
Olli Etuaho95faa232016-06-07 14:01:53 -07005047// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
5048// GLES 3.0.4 section 3.8.3.
5049TEST_P(Texture2DTestES3, UnpackSkipImages2D)
5050{
Yuly Novikovd18c0482019-04-04 19:56:43 -04005051 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
5052 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Olli Etuaho95faa232016-06-07 14:01:53 -07005053
5054 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5055 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5056 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5057 ASSERT_GL_NO_ERROR();
5058
5059 // SKIP_IMAGES should not have an effect on uploading 2D textures
5060 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
5061 ASSERT_GL_NO_ERROR();
5062
5063 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5064
5065 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5066 pixelsGreen.data());
5067 ASSERT_GL_NO_ERROR();
5068
5069 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
5070 pixelsGreen.data());
5071 ASSERT_GL_NO_ERROR();
5072
5073 glUseProgram(mProgram);
5074 drawQuad(mProgram, "position", 0.5f);
5075 ASSERT_GL_NO_ERROR();
5076
5077 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5078}
5079
Olli Etuaho989cac32016-06-08 16:18:49 -07005080// Test that skip defined in unpack parameters is taken into account when determining whether
5081// unpacking source extends outside unpack buffer bounds.
5082TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
5083{
5084 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5085 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5086 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5087 ASSERT_GL_NO_ERROR();
5088
5089 GLBuffer buf;
5090 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5091 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
5092 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5093 GL_DYNAMIC_COPY);
5094 ASSERT_GL_NO_ERROR();
5095
5096 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5097 ASSERT_GL_NO_ERROR();
5098
5099 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
5100 ASSERT_GL_NO_ERROR();
5101
5102 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5103 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5104
5105 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
5106 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
5107 ASSERT_GL_NO_ERROR();
5108
5109 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5110 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5111}
5112
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005113// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
5114TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
5115{
Yunchao He9550c602018-02-13 14:47:05 +08005116 ANGLE_SKIP_TEST_IF(IsD3D11());
5117
5118 // Incorrect rendering results seen on OSX AMD.
5119 ANGLE_SKIP_TEST_IF(IsOSX() && IsAMD());
Olli Etuaho218cf9e2016-05-20 13:55:24 +03005120
5121 const GLuint width = 8u;
5122 const GLuint height = 8u;
5123 const GLuint unpackRowLength = 5u;
5124 const GLuint unpackSkipPixels = 1u;
5125
5126 setWindowWidth(width);
5127 setWindowHeight(height);
5128
5129 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5132 ASSERT_GL_NO_ERROR();
5133
5134 GLBuffer buf;
5135 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
5136 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
5137 GLColor::green);
5138
5139 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
5140 {
5141 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
5142 }
5143
5144 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
5145 GL_DYNAMIC_COPY);
5146 ASSERT_GL_NO_ERROR();
5147
5148 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
5149 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
5150 ASSERT_GL_NO_ERROR();
5151
5152 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
5153 ASSERT_GL_NO_ERROR();
5154
5155 glUseProgram(mProgram);
5156 drawQuad(mProgram, "position", 0.5f);
5157 ASSERT_GL_NO_ERROR();
5158
5159 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
5160 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
5161 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
5162 actual.data());
5163 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
5164 EXPECT_EQ(expected, actual);
5165}
5166
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005167template <typename T>
5168T UNorm(double value)
5169{
5170 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
5171}
5172
5173// Test rendering a depth texture with mipmaps.
5174TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
5175{
Zhenyao Moe520d7c2017-01-13 13:46:49 -08005176 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
5177 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
Jiawei Shaoaf0f31d2018-09-27 15:42:31 +08005178 // http://anglebug.com/1706
5179 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Corentin Walleze731d8a2016-09-07 10:56:25 -04005180
Jamie Madill24980272019-04-03 09:03:51 -04005181 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
5182 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
5183
Cody Northrop988f7172019-09-30 15:52:37 -06005184 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005185 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
5186
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005187 const int size = getWindowWidth();
5188
5189 auto dim = [size](int level) { return size >> level; };
Jamie Madill14718762016-09-06 15:56:54 -04005190 int levels = gl::log2(size);
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04005191
5192 glActiveTexture(GL_TEXTURE0);
5193 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5194 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
5195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5197 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5199 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5200 ASSERT_GL_NO_ERROR();
5201
5202 glUseProgram(mProgram);
5203 glUniform1i(mTexture2DUniformLocation, 0);
5204
5205 std::vector<unsigned char> expected;
5206
5207 for (int level = 0; level < levels; ++level)
5208 {
5209 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
5210 expected.push_back(UNorm<unsigned char>(value));
5211
5212 int levelDim = dim(level);
5213
5214 ASSERT_GT(levelDim, 0);
5215
5216 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
5217 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
5218 GL_UNSIGNED_INT, initData.data());
5219 }
5220 ASSERT_GL_NO_ERROR();
5221
5222 for (int level = 0; level < levels; ++level)
5223 {
5224 glViewport(0, 0, dim(level), dim(level));
5225 drawQuad(mProgram, "position", 0.5f);
5226 GLColor actual = ReadColor(0, 0);
5227 EXPECT_NEAR(expected[level], actual.R, 10u);
5228 }
5229
5230 ASSERT_GL_NO_ERROR();
5231}
5232
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005233class Texture2DDepthTest : public Texture2DTest
5234{
5235 protected:
5236 Texture2DDepthTest() : Texture2DTest() {}
5237
5238 const char *getVertexShaderSource() override
5239 {
5240 return "attribute vec4 vPosition;\n"
5241 "void main() {\n"
5242 " gl_Position = vPosition;\n"
5243 "}\n";
5244 }
5245
5246 const char *getFragmentShaderSource() override
5247 {
5248 return "precision mediump float;\n"
5249 "uniform sampler2D ShadowMap;"
5250 "void main() {\n"
5251 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
5252 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
5253 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
5254 " } else {"
5255 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
5256 " }"
5257 "}\n";
5258 }
5259
5260 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
5261 {
5262 EXPECT_GL_NO_ERROR();
5263
5264 GLTexture tex;
5265 glBindTexture(GL_TEXTURE_2D, tex);
5266 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
5267
5268 return (glGetError() == GL_NO_ERROR);
5269 }
5270
5271 void testBehavior(bool useSizedComponent)
5272 {
5273 int w = getWindowWidth();
5274 int h = getWindowHeight();
5275 GLuint format = GL_DEPTH_COMPONENT;
5276 GLuint internalFormat = GL_DEPTH_COMPONENT;
5277
5278 if (useSizedComponent)
5279 {
5280 internalFormat = GL_DEPTH_COMPONENT24;
5281 }
5282
5283 GLFramebuffer fbo;
5284 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5285 ASSERT_GL_NO_ERROR();
5286
5287 GLTexture depthTexture;
5288 glBindTexture(GL_TEXTURE_2D, depthTexture);
5289 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5291 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5292 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5293
5294 TexCoordDrawTest::setUpProgram();
5295 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
5296 ASSERT_NE(-1, shadowMapLocation);
5297
5298 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
5299 ASSERT_NE(-1, positionLocation);
5300
5301 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
5302 glBindTexture(GL_TEXTURE_2D, depthTexture);
5303 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
5304 ASSERT_GL_NO_ERROR();
5305
5306 // try adding a color buffer.
5307 GLuint colorTex = 0;
5308 glGenTextures(1, &colorTex);
5309 glBindTexture(GL_TEXTURE_2D, colorTex);
5310 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5312 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5314 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5315 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
5316 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
5317 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5318 ASSERT_GL_NO_ERROR();
5319
5320 glViewport(0, 0, w, h);
5321 // Fill depthTexture with 0.75
5322 glClearDepthf(0.75);
5323 glClear(GL_DEPTH_BUFFER_BIT);
5324
5325 // Revert to normal framebuffer to test depth shader
5326 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5327 glViewport(0, 0, w, h);
5328 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5329 glClearDepthf(0.0f);
5330 ASSERT_GL_NO_ERROR();
5331
5332 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
5333 ASSERT_GL_NO_ERROR();
5334
5335 glActiveTexture(GL_TEXTURE0);
5336 glBindTexture(GL_TEXTURE_2D, depthTexture);
5337
5338 glUseProgram(mProgram);
5339 ASSERT_GL_NO_ERROR();
5340
5341 glUniform1i(shadowMapLocation, 0);
5342
5343 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
5344
5345 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
5346 ASSERT_GL_NO_ERROR();
5347 glEnableVertexAttribArray(positionLocation);
5348 ASSERT_GL_NO_ERROR();
5349 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5350 ASSERT_GL_NO_ERROR();
5351
5352 GLuint pixels[1];
5353 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
5354 ASSERT_GL_NO_ERROR();
5355
5356 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
5357 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
5358 // is in all the color components. Multiple implementations implement a workaround that
5359 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
5360 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
5361 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
5362 // depending on if it sees the texture sample in only the RED component.
5363 if (useSizedComponent)
5364 {
5365 ASSERT_NE(pixels[0], 0xff0000ff);
5366 }
5367 else
5368 {
5369 ASSERT_EQ(pixels[0], 0xff0000ff);
5370 }
5371
5372 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5373 glDeleteProgram(mProgram);
5374 }
5375};
5376
5377// Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
5378TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
5379{
5380 ANGLE_SKIP_TEST_IF(IsD3D11());
5381 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
Tobin Ehlis7af26762019-10-23 16:18:57 -06005382 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
5383 !IsGLExtensionEnabled("GL_OES_depth_texture"));
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005384 // http://anglebug.com/4092
5385 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01005386 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005387
5388 // When the depth texture is specified with unsized internalformat implementations follow
5389 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
5390 testBehavior(false);
5391}
5392
5393// Test depth texture compatibility with GLES3 using sized internalformat.
5394TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
5395{
5396 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
5397
5398 testBehavior(true);
5399}
5400
Jamie Madill7ffdda92016-09-08 13:26:51 -04005401// Tests unpacking into the unsized GL_ALPHA format.
5402TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
5403{
Jamie Madill7ffdda92016-09-08 13:26:51 -04005404 // Initialize the texure.
5405 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5406 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
5407 GL_UNSIGNED_BYTE, nullptr);
5408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5410
5411 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
5412
5413 // Pull in the color data from the unpack buffer.
Jamie Madill2e600342016-09-19 13:56:40 -04005414 GLBuffer unpackBuffer;
Jamie Madill7ffdda92016-09-08 13:26:51 -04005415 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5416 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5417 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
5418 GL_STATIC_DRAW);
5419
5420 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
5421 GL_UNSIGNED_BYTE, nullptr);
5422
5423 // Clear to a weird color to make sure we're drawing something.
5424 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
5425 glClear(GL_COLOR_BUFFER_BIT);
5426
5427 // Draw with the alpha texture and verify.
5428 drawQuad(mProgram, "position", 0.5f);
Jamie Madill7ffdda92016-09-08 13:26:51 -04005429
5430 ASSERT_GL_NO_ERROR();
5431 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
5432}
5433
Jamie Madill2e600342016-09-19 13:56:40 -04005434// Ensure stale unpack data doesn't propagate in D3D11.
5435TEST_P(Texture2DTestES3, StaleUnpackData)
5436{
5437 // Init unpack buffer.
5438 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
5439 std::vector<GLColor> pixels(pixelCount, GLColor::red);
5440
5441 GLBuffer unpackBuffer;
5442 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5443 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5444 GLsizei bufferSize = pixelCount * sizeof(GLColor);
5445 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
5446
5447 // Create from unpack buffer.
5448 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5449 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
5450 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5451 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5452 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5453
5454 drawQuad(mProgram, "position", 0.5f);
5455
5456 ASSERT_GL_NO_ERROR();
5457 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5458
5459 // Fill unpack with green, recreating buffer.
5460 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
5461 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
5462 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
5463
5464 // Reinit texture with green.
5465 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
5466 GL_UNSIGNED_BYTE, nullptr);
5467
5468 drawQuad(mProgram, "position", 0.5f);
5469
5470 ASSERT_GL_NO_ERROR();
5471 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5472}
5473
Geoff Langfb7685f2017-11-13 11:44:11 -05005474// Ensure that texture parameters passed as floats that are converted to ints are rounded before
5475// validating they are less than 0.
5476TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
5477{
5478 GLTexture texture;
5479 glBindTexture(GL_TEXTURE_2D, texture);
5480
5481 // Use a negative number that will round to zero when converted to an integer
5482 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
5483 // "Validation of values performed by state-setting commands is performed after conversion,
5484 // unless specified otherwise for a specific command."
5485 GLfloat param = -7.30157126e-07f;
5486 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
5487 EXPECT_GL_NO_ERROR();
5488
5489 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
5490 EXPECT_GL_NO_ERROR();
5491}
5492
Jamie Madillf097e232016-11-05 00:44:15 -04005493// This test covers a D3D format redefinition bug for 3D textures. The base level format was not
5494// being properly checked, and the texture storage of the previous texture format was persisting.
5495// This would result in an ASSERT in debug and incorrect rendering in release.
5496// See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
5497TEST_P(Texture3DTestES3, FormatRedefinitionBug)
5498{
5499 GLTexture tex;
5500 glBindTexture(GL_TEXTURE_3D, tex.get());
5501 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5502
5503 GLFramebuffer framebuffer;
5504 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
5505 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
5506
5507 glCheckFramebufferStatus(GL_FRAMEBUFFER);
5508
5509 std::vector<uint8_t> pixelData(100, 0);
5510
5511 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
5512 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
5513 pixelData.data());
5514
5515 ASSERT_GL_NO_ERROR();
5516}
5517
Corentin Wallezd2627992017-04-28 17:17:03 -04005518// Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
5519TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
5520{
5521 // 2D tests
5522 {
5523 GLTexture tex;
5524 glBindTexture(GL_TEXTURE_2D, tex.get());
5525
5526 GLBuffer pbo;
5527 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5528
5529 // Test OOB
5530 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
5531 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5532 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5533
5534 // Test OOB
5535 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
5536 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5537 ASSERT_GL_NO_ERROR();
5538 }
5539
5540 // 3D tests
5541 {
5542 GLTexture tex;
5543 glBindTexture(GL_TEXTURE_3D, tex.get());
5544
5545 GLBuffer pbo;
5546 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5547
5548 // Test OOB
5549 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
5550 GL_STATIC_DRAW);
5551 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5552 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5553
5554 // Test OOB
5555 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
5556 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5557 ASSERT_GL_NO_ERROR();
5558 }
5559}
5560
Jamie Madill3ed60422017-09-07 11:32:52 -04005561// Tests behaviour with a single texture and multiple sampler objects.
5562TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
5563{
5564 GLint maxTextureUnits = 0;
5565 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
5566 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
5567
5568 constexpr int kSize = 16;
5569
5570 // Make a single-level texture, fill it with red.
5571 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
5572 GLTexture tex;
5573 glBindTexture(GL_TEXTURE_2D, tex);
5574 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5575 redColors.data());
5576 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5577 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5578
5579 // Simple sanity check.
5580 draw2DTexturedQuad(0.5f, 1.0f, true);
5581 ASSERT_GL_NO_ERROR();
5582 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5583
5584 // Bind texture to unit 1 with a sampler object making it incomplete.
5585 GLSampler sampler;
5586 glBindSampler(0, sampler);
5587 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5588 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5589
5590 // Make a mipmap texture, fill it with blue.
5591 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
5592 GLTexture mipmapTex;
5593 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5594 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5595 blueColors.data());
5596 glGenerateMipmap(GL_TEXTURE_2D);
5597
5598 // Draw with the sampler, expect blue.
5599 draw2DTexturedQuad(0.5f, 1.0f, true);
5600 ASSERT_GL_NO_ERROR();
5601 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5602
5603 // Simple multitexturing program.
Jamie Madill35cd7332018-12-02 12:03:33 -05005604 constexpr char kVS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005605 "#version 300 es\n"
5606 "in vec2 position;\n"
5607 "out vec2 texCoord;\n"
5608 "void main()\n"
5609 "{\n"
5610 " gl_Position = vec4(position, 0, 1);\n"
5611 " texCoord = position * 0.5 + vec2(0.5);\n"
5612 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05005613
5614 constexpr char kFS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005615 "#version 300 es\n"
5616 "precision mediump float;\n"
5617 "in vec2 texCoord;\n"
5618 "uniform sampler2D tex1;\n"
5619 "uniform sampler2D tex2;\n"
5620 "uniform sampler2D tex3;\n"
5621 "uniform sampler2D tex4;\n"
5622 "out vec4 color;\n"
5623 "void main()\n"
5624 "{\n"
5625 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
5626 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
5627 "}";
5628
Jamie Madill35cd7332018-12-02 12:03:33 -05005629 ANGLE_GL_PROGRAM(program, kVS, kFS);
Jamie Madill3ed60422017-09-07 11:32:52 -04005630
5631 std::array<GLint, 4> texLocations = {
5632 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
5633 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
5634 for (GLint location : texLocations)
5635 {
5636 ASSERT_NE(-1, location);
5637 }
5638
5639 // Init the uniform data.
5640 glUseProgram(program);
5641 for (GLint location = 0; location < 4; ++location)
5642 {
5643 glUniform1i(texLocations[location], location);
5644 }
5645
5646 // Initialize four samplers
5647 GLSampler samplers[4];
5648
5649 // 0: non-mipped.
5650 glBindSampler(0, samplers[0]);
5651 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5652 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5653
5654 // 1: mipped.
5655 glBindSampler(1, samplers[1]);
5656 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5657 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5658
5659 // 2: non-mipped.
5660 glBindSampler(2, samplers[2]);
5661 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5662 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5663
5664 // 3: mipped.
5665 glBindSampler(3, samplers[3]);
5666 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5667 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5668
5669 // Bind two blue mipped textures and two single layer textures, should all draw.
5670 glActiveTexture(GL_TEXTURE0);
5671 glBindTexture(GL_TEXTURE_2D, tex);
5672
5673 glActiveTexture(GL_TEXTURE1);
5674 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5675
5676 glActiveTexture(GL_TEXTURE2);
5677 glBindTexture(GL_TEXTURE_2D, tex);
5678
5679 glActiveTexture(GL_TEXTURE3);
5680 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5681
5682 ASSERT_GL_NO_ERROR();
5683
5684 drawQuad(program, "position", 0.5f);
5685 ASSERT_GL_NO_ERROR();
5686 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
5687
5688 // Bind four single layer textures, two should be incomplete.
5689 glActiveTexture(GL_TEXTURE1);
5690 glBindTexture(GL_TEXTURE_2D, tex);
5691
5692 glActiveTexture(GL_TEXTURE3);
5693 glBindTexture(GL_TEXTURE_2D, tex);
5694
5695 drawQuad(program, "position", 0.5f);
5696 ASSERT_GL_NO_ERROR();
5697 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
5698}
5699
Martin Radev7e2c0d32017-09-15 14:25:42 +03005700// The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
5701// always at level 0 instead of the base level resulting in an incomplete texture if the faces at
5702// level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
5703// level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
5704// samples the cubemap using a direction vector (1,1,1).
5705TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
5706{
Yunchao He2f23f352018-02-11 22:11:37 +08005707 // Check http://anglebug.com/2155.
5708 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
5709
Jamie Madill35cd7332018-12-02 12:03:33 -05005710 constexpr char kVS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005711 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005712 precision mediump float;
5713 in vec3 pos;
5714 void main() {
5715 gl_Position = vec4(pos, 1.0);
5716 })";
Martin Radev7e2c0d32017-09-15 14:25:42 +03005717
Jamie Madill35cd7332018-12-02 12:03:33 -05005718 constexpr char kFS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005719 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005720 precision mediump float;
5721 out vec4 color;
5722 uniform samplerCube uTex;
5723 void main(){
5724 color = texture(uTex, vec3(1.0));
5725 })";
Jamie Madill35cd7332018-12-02 12:03:33 -05005726
5727 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev7e2c0d32017-09-15 14:25:42 +03005728 glUseProgram(program);
5729
5730 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
5731 glActiveTexture(GL_TEXTURE0);
5732
5733 GLTexture cubeTex;
5734 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
5735
5736 const int kFaceWidth = 1;
5737 const int kFaceHeight = 1;
5738 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
5739 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5740 GL_UNSIGNED_BYTE, texData.data());
5741 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5742 GL_UNSIGNED_BYTE, texData.data());
5743 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5744 GL_UNSIGNED_BYTE, texData.data());
5745 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5746 GL_UNSIGNED_BYTE, texData.data());
5747 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5748 GL_UNSIGNED_BYTE, texData.data());
5749 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5750 GL_UNSIGNED_BYTE, texData.data());
5751 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5752 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5753 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
5754 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
5755 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
5756 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
5757
5758 drawQuad(program, "pos", 0.5f, 1.0f, true);
5759 ASSERT_GL_NO_ERROR();
5760
5761 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5762}
5763
Jiawei Shao3c43b4d2018-02-23 11:08:28 +08005764// Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
5765TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
5766{
5767 GLuint texture = create2DTexture();
5768
5769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
5770 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5771
5772 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
5773 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5774
5775 glDeleteTextures(1, &texture);
5776 EXPECT_GL_NO_ERROR();
5777}
5778
Olli Etuaho023371b2018-04-24 17:43:32 +03005779// Test setting base level after calling generateMipmap on a LUMA texture.
5780// Covers http://anglebug.com/2498
5781TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
5782{
5783 glActiveTexture(GL_TEXTURE0);
5784 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5785
5786 constexpr const GLsizei kWidth = 8;
5787 constexpr const GLsizei kHeight = 8;
5788 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
5789 whiteData.fill(255u);
5790
5791 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
5792 GL_UNSIGNED_BYTE, whiteData.data());
5793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
5794 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5795 glGenerateMipmap(GL_TEXTURE_2D);
5796 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5797 EXPECT_GL_NO_ERROR();
5798
5799 drawQuad(mProgram, "position", 0.5f);
5800 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5801}
5802
Till Rathmannc1551dc2018-08-15 17:04:49 +02005803// Covers a bug in the D3D11 backend: http://anglebug.com/2772
5804// When using a sampler the texture was created as if it has mipmaps,
5805// regardless what you specified in GL_TEXTURE_MIN_FILTER via
5806// glSamplerParameteri() -- mistakenly the default value
5807// GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
5808// evaluated.
5809// If you didn't provide mipmaps and didn't let the driver generate them
5810// this led to not sampling your texture data when minification occurred.
5811TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
5812{
Jamie Madill35cd7332018-12-02 12:03:33 -05005813 constexpr char kVS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005814 "#version 300 es\n"
5815 "out vec2 texcoord;\n"
5816 "in vec4 position;\n"
5817 "void main()\n"
5818 "{\n"
5819 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
5820 " texcoord = (position.xy * 0.5) + 0.5;\n"
5821 "}\n";
5822
Jamie Madill35cd7332018-12-02 12:03:33 -05005823 constexpr char kFS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005824 "#version 300 es\n"
5825 "precision highp float;\n"
5826 "uniform highp sampler2D tex;\n"
5827 "in vec2 texcoord;\n"
5828 "out vec4 fragColor;\n"
5829 "void main()\n"
5830 "{\n"
5831 " fragColor = texture(tex, texcoord);\n"
5832 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -05005833
5834 ANGLE_GL_PROGRAM(program, kVS, kFS);
Till Rathmannc1551dc2018-08-15 17:04:49 +02005835
5836 GLSampler sampler;
5837 glBindSampler(0, sampler);
5838 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5839 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5840
5841 glActiveTexture(GL_TEXTURE0);
5842 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5843
5844 const GLsizei texWidth = getWindowWidth();
5845 const GLsizei texHeight = getWindowHeight();
5846 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
5847
5848 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5849 whiteData.data());
5850 EXPECT_GL_NO_ERROR();
5851
5852 drawQuad(program, "position", 0.5f);
5853 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
5854}
5855
Anders Leinof6cbe442019-04-18 15:32:07 +03005856// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5857// texture is output.
5858TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
5859{
Yuly Novikovd2683452019-05-23 16:11:19 -04005860 // http://anglebug.com/3478
5861 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5862
Anders Leinof6cbe442019-04-18 15:32:07 +03005863 glActiveTexture(GL_TEXTURE0);
5864 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5865 int width = getWindowWidth();
5866 int height = getWindowHeight();
5867 GLColor color = GLColor::green;
5868 std::vector<GLColor> pixels(width * height, color);
5869 GLint baseLevel = 1;
5870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5871 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5872 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5873 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5874 GL_UNSIGNED_BYTE, pixels.data());
5875
5876 setUpProgram();
5877 glUseProgram(mProgram);
5878 glUniform1i(mTexture2DUniformLocation, 0);
5879 drawQuad(mProgram, "position", 0.5f);
5880
5881 EXPECT_GL_NO_ERROR();
5882 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5883 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5884}
5885
Anders Leino60cc7512019-05-06 09:25:27 +03005886// Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
5887// the texture is output.
5888TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
5889{
5890 // All output checks returned black, rather than the texture color.
5891 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
5892
5893 glActiveTexture(GL_TEXTURE0);
5894
5895 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5896 GLint baseLevel = 1;
5897 int width = getWindowWidth();
5898 int height = getWindowHeight();
5899 GLColor color = GLColor::green;
5900 std::vector<GLColor> pixels(width * height, color);
5901 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5902 {
5903 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
5904 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5905 EXPECT_GL_NO_ERROR();
5906 }
5907 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
5908 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5909 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5910
5911 glUseProgram(mProgram);
5912 glUniform1i(mTextureCubeUniformLocation, 0);
5913 drawQuad(mProgram, "position", 0.5f);
5914
5915 EXPECT_GL_NO_ERROR();
5916 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5917 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
5918 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
5919 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5920}
5921
Anders Leinoe4452442019-05-09 13:29:49 +03005922// This test sets up a cube map with four distincly colored MIP levels.
5923// The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
5924// the corners of the screen.
5925TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
5926{
5927 glActiveTexture(GL_TEXTURE0);
5928
5929 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5930 int width = getWindowWidth();
5931 int height = getWindowHeight();
5932 ASSERT_EQ(width, height);
5933 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
5934 for (GLint level = 0; level < 4; level++)
5935 {
5936 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5937 {
5938 int levelWidth = (2 * width) >> level;
5939 int levelHeight = (2 * height) >> level;
5940 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
5941 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
5942 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5943 EXPECT_GL_NO_ERROR();
5944 }
5945 }
5946 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5947 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5948 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
5949
5950 glUseProgram(mProgram);
5951 glUniform1i(mTextureCubeUniformLocation, 0);
5952 drawQuad(mProgram, "position", 0.5f);
5953
5954 ASSERT_GL_NO_ERROR();
5955 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
5956 EXPECT_EQ(ReadColor(0, 0).R, 0);
5957 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
5958 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
5959 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
5960}
5961
Anders Leino1b6aded2019-05-20 12:56:34 +03005962// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5963// texture is output.
5964TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
5965{
Jamie Madill29ac2742019-05-28 15:53:00 -04005966 // Fails on AMD: http://crbug.com/967796
Jamie Madill06055b52019-05-29 14:31:42 -04005967 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
Jamie Madill29ac2742019-05-28 15:53:00 -04005968
Anders Leino1b6aded2019-05-20 12:56:34 +03005969 glActiveTexture(GL_TEXTURE0);
5970 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5971 int width = getWindowWidth();
5972 int height = getWindowHeight();
5973 GLColor color = GLColor::green;
5974 std::vector<GLColor> pixels(width * height, color);
5975 GLint baseLevel = 1;
5976 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5977 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5979 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5980 GL_UNSIGNED_BYTE, pixels.data());
5981
5982 setUpProgram();
5983 glUseProgram(mProgram);
5984 glUniform1i(mTexture2DUniformLocation, 0);
5985 drawQuad(mProgram, "position", 0.5f);
5986
5987 EXPECT_GL_NO_ERROR();
5988 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5989 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5990}
5991
Anders Leino69d04932019-05-20 14:04:13 +03005992// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5993// texture is output.
5994TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
5995{
5996 glActiveTexture(GL_TEXTURE0);
5997 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
5998 int width = getWindowWidth();
5999 int height = getWindowHeight();
6000 int depth = 2;
6001 GLColor color = GLColor::green;
6002 std::vector<GLColor> pixels(width * height * depth, color);
6003 GLint baseLevel = 1;
6004 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
6005 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
6006 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
6007 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6008 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6009
6010 drawQuad(mProgram, "position", 0.5f);
6011
6012 EXPECT_GL_NO_ERROR();
6013 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6014 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6015}
6016
Anders Leino262e2822019-05-20 14:24:40 +03006017// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
6018// texture is output.
6019TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
6020{
6021 glActiveTexture(GL_TEXTURE0);
6022 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6023 int width = getWindowWidth();
6024 int height = getWindowHeight();
6025 int depth = 2;
6026 GLColor color = GLColor::green;
6027 std::vector<GLColor> pixels(width * height * depth, color);
6028 GLint baseLevel = 1;
6029 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
6030 GL_UNSIGNED_BYTE, pixels.data());
6031 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6032 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6033 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6034
6035 drawQuad(mProgram, "position", 0.5f);
6036
6037 EXPECT_GL_NO_ERROR();
6038 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6039 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6040}
6041
Jamie Madillfc3ec572019-11-27 21:43:22 +00006042// Test that uses glCompressedTexSubImage2D combined with a PBO
6043TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
6044{
6045 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6046 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6047 // http://anglebug.com/4115
6048 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
6049 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
6050
6051 if (getClientMajorVersion() < 3)
6052 {
6053 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
6054 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
6055 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
6056 }
6057
6058 const GLuint width = 4u;
6059 const GLuint height = 4u;
6060
6061 setWindowWidth(width);
6062 setWindowHeight(height);
6063
6064 // Setup primary Texture
6065 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6066 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6067 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6068
6069 if (getClientMajorVersion() < 3)
6070 {
6071 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6072 }
6073 else
6074 {
6075 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6076 }
6077 ASSERT_GL_NO_ERROR();
6078
6079 // Setup PBO and fill it with a red
6080 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
6081 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
6082 ASSERT_GL_NO_ERROR();
6083
6084 // Write PBO to mTexture
6085 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
6086 width * height / 2u, nullptr);
6087 ASSERT_GL_NO_ERROR();
6088
6089 setUpProgram();
6090 // Draw using PBO updated texture
6091 glUseProgram(mProgram);
6092 glUniform1i(mTexture2DUniformLocation, 0);
6093 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6094 drawQuad(mProgram, "position", 0.5f);
6095 ASSERT_GL_NO_ERROR();
6096
6097 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6098 ASSERT_GL_NO_ERROR();
6099}
6100
Cody Northrop74e816b2020-03-26 17:40:25 -06006101// Test using ETC1_RGB8 with subimage updates
6102TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
6103{
6104 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6105 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6106
6107 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
6108 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
6109 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6110
6111 const GLuint width = 4u;
6112 const GLuint height = 4u;
6113
6114 setWindowWidth(width);
6115 setWindowHeight(height);
6116
6117 // Setup primary Texture
6118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6120
6121 if (getClientMajorVersion() < 3)
6122 {
6123 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6124 }
6125 else
6126 {
6127 glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6128 }
6129 ASSERT_GL_NO_ERROR();
6130
6131 // Populate a subimage of the texture
6132 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6133 width * height / 2u, kCompressedImageETC2);
6134 ASSERT_GL_NO_ERROR();
6135
6136 // Render and ensure we get red
6137 glUseProgram(mProgram);
6138 drawQuad(mProgram, "position", 0.5f);
6139 ASSERT_GL_NO_ERROR();
6140
6141 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6142 ASSERT_GL_NO_ERROR();
6143}
6144
Ian Elliotteba008a2020-05-05 10:46:21 -06006145// Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
6146// MAX_LEVEL and draw. This used to cause Vulkan validation errors.
6147TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
6148{
6149 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6150 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6151
6152 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
6153 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6154
6155 const GLuint width = 4u;
6156 const GLuint height = 4u;
6157
6158 setWindowWidth(width);
6159 setWindowHeight(height);
6160
6161 // Setup primary Texture
6162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6164
6165 if (getClientMajorVersion() < 3)
6166 {
6167 glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6168 }
6169 else
6170 {
6171 glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6172 }
6173 ASSERT_GL_NO_ERROR();
6174
6175 // Populate a subimage of the texture
6176 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6177 width * height / 2u, kCompressedImageETC2);
6178 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
6179 width * height / 2u, kCompressedImageETC2);
6180 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
6181 width * height / 2u, kCompressedImageETC2);
6182 ASSERT_GL_NO_ERROR();
6183
6184 // Set MAX_LEVEL to 2 (the highest level)
6185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6186
6187 // Render and ensure we get red
6188 glUseProgram(mProgram);
6189 drawQuad(mProgram, "position", 0.5f);
6190 ASSERT_GL_NO_ERROR();
6191 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6192 ASSERT_GL_NO_ERROR();
6193
6194 // Decrease MAX_LEVEL to 0, render, and ensure we still get red
6195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6196 drawQuad(mProgram, "position", 0.5f);
6197 ASSERT_GL_NO_ERROR();
6198 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6199 ASSERT_GL_NO_ERROR();
6200
6201 // Increase MAX_LEVEL back to 2, render, and ensure we still get red
6202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6203 drawQuad(mProgram, "position", 0.5f);
6204 ASSERT_GL_NO_ERROR();
6205 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6206 ASSERT_GL_NO_ERROR();
6207}
6208
Jamie Madill50cf2be2018-06-15 09:46:57 -04006209// Use this to select which configurations (e.g. which renderer, which GLES major version) these
6210// tests should be run against.
James Darpinian336e8912020-05-29 16:09:47 -07006211#define ES2_EMULATE_COPY_TEX_IMAGE() \
6212 WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGL()), \
6213 WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGLES())
6214#define ES3_EMULATE_COPY_TEX_IMAGE() \
6215 WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()), \
6216 WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES())
6217ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ES2_EMULATE_COPY_TEX_IMAGE());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006218ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
6219ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
6220ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
6221ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
6222ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
6223ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3);
6224ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
6225ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
6226ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
6227ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
6228ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
6229ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
6230ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
6231ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
6232ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
6233ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
6234ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
6235ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
6236ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
6237ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
6238ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
6239ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
6240ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
6241ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
James Darpinian336e8912020-05-29 16:09:47 -07006242ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
6243 ANGLE_ALL_TEST_PLATFORMS_ES2,
6244 ANGLE_ALL_TEST_PLATFORMS_ES3,
6245 ES2_EMULATE_COPY_TEX_IMAGE(),
6246 ES3_EMULATE_COPY_TEX_IMAGE());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006247ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
6248ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
6249ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
6250ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
6251ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
6252ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
6253ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
6254ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
6255ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
6256ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
Jamie Madillfc3ec572019-11-27 21:43:22 +00006257ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
Cody Northrop74e816b2020-03-26 17:40:25 -06006258ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
Jamie Madillfa05f602015-05-07 13:47:11 -04006259
Jamie Madill7ffdda92016-09-08 13:26:51 -04006260} // anonymous namespace