blob: 57a0976e4b7a10482da1d8a19a5fea412490c3cf [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{
2211 // TODO(geofflang): Investigate on D3D11. http://anglebug.com/2291
2212 ANGLE_SKIP_TEST_IF(IsD3D11());
2213
Cody Northropd192e932019-09-27 10:27:10 -06002214 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
2215 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
Cody Northropcb16fb52019-08-29 16:53:55 -06002216
Geoff Lang6f691fb2019-04-25 11:01:52 -04002217 setUpProgram();
2218
2219 constexpr GLint width = 8;
2220 constexpr GLint height = 4;
2221
2222 GLTexture texture;
2223 glBindTexture(GL_TEXTURE_2D, texture);
2224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2228
2229 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
2230 GLint level = 0;
2231 GLint levelW = width;
2232 GLint levelH = height;
2233 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2234 nullptr);
2235 while (levelW > 1 || levelH > 1)
2236 {
2237 ++level;
2238 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
2239 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
2240 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2241 nullptr);
2242 }
2243
2244 // Clear each level of the texture using an FBO. Change the base level to match the level used
2245 // for the FBO on each iteration.
2246 GLFramebuffer fbo;
2247 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2248 level = 0;
2249 levelW = width;
2250 levelH = height;
2251 while (levelW > 1 || levelH > 1)
2252 {
2253 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
2254 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
2255
2256 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
2257 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
2258
2259 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2260 EXPECT_GL_NO_ERROR();
2261
2262 glClearColor(0, 1, 0, 1);
2263 glClear(GL_COLOR_BUFFER_BIT);
2264
2265 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2266
2267 ++level;
2268 }
2269
2270 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2271 glViewport(0, 0, 16, 16);
2272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2273
2274 drawQuad(mProgram, "position", 0.5f);
2275
2276 EXPECT_GL_NO_ERROR();
2277 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2278}
2279
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002280// Test to check that texture completeness is determined correctly when the texture base level is
2281// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
2282TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
2283{
2284 glActiveTexture(GL_TEXTURE0);
2285 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02002286
2287 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
2288 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2289 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2290 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2291 texDataGreen.data());
2292 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2293 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002294 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2295 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2296 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2297
2298 EXPECT_GL_NO_ERROR();
2299
2300 drawQuad(mProgram, "position", 0.5f);
2301
Olli Etuahoa314b612016-03-10 16:43:00 +02002302 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2303}
2304
2305// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2306// have images defined.
2307TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
2308{
Yunchao He9550c602018-02-13 14:47:05 +08002309 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2310 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2311
Olli Etuahoa314b612016-03-10 16:43:00 +02002312 glActiveTexture(GL_TEXTURE0);
2313 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2314 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2315 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2316 texDataGreen.data());
2317 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2318 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2319 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2320 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2321
2322 EXPECT_GL_NO_ERROR();
2323
2324 drawQuad(mProgram, "position", 0.5f);
2325
2326 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2327}
2328
Olli Etuahoe8528d82016-05-16 17:50:52 +03002329// Test that drawing works correctly when level 0 is undefined and base level is 1.
2330TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
2331{
Yunchao He9550c602018-02-13 14:47:05 +08002332 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2333 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2334
Olli Etuahoe8528d82016-05-16 17:50:52 +03002335 glActiveTexture(GL_TEXTURE0);
2336 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2337 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2338 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2339 texDataGreen.data());
2340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2341 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2342 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2343 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2344
2345 EXPECT_GL_NO_ERROR();
2346
2347 // Texture is incomplete.
2348 drawQuad(mProgram, "position", 0.5f);
2349 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2350
2351 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2352 texDataGreen.data());
2353
2354 // Texture is now complete.
2355 drawQuad(mProgram, "position", 0.5f);
2356 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2357}
2358
Olli Etuahoa314b612016-03-10 16:43:00 +02002359// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2360// dimensions that don't fit the images inside the range.
2361// GLES 3.0.4 section 3.8.13 Texture completeness
2362TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2363{
Olli Etuahoa314b612016-03-10 16:43:00 +02002364 glActiveTexture(GL_TEXTURE0);
2365 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2366 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
2367 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2368 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
2369
2370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2371 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2372
2373 // Two levels that are initially unused.
2374 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2375 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2376 texDataCyan.data());
2377
2378 // One level that is used - only this level should affect completeness.
2379 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2380 texDataGreen.data());
2381
2382 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2383 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2384
2385 EXPECT_GL_NO_ERROR();
2386
2387 drawQuad(mProgram, "position", 0.5f);
2388
2389 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2390
Yunchao He2f23f352018-02-11 22:11:37 +08002391 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002392
2393 // Switch the level that is being used to the cyan level 2.
2394 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2395 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2396
2397 EXPECT_GL_NO_ERROR();
2398
2399 drawQuad(mProgram, "position", 0.5f);
2400
2401 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2402}
2403
2404// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2405// have images defined.
2406TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
2407{
Olli Etuahoa314b612016-03-10 16:43:00 +02002408 glActiveTexture(GL_TEXTURE0);
2409 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2410 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2411 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2412 texDataGreen.data());
2413 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2414 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2415 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2416 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2417
2418 EXPECT_GL_NO_ERROR();
2419
2420 drawQuad(mProgram, "position", 0.5f);
2421
2422 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2423}
2424
2425// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2426// dimensions that don't fit the images inside the range.
2427// GLES 3.0.4 section 3.8.13 Texture completeness
2428TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2429{
Yuly Novikovc5da7992019-06-27 12:57:13 -04002430 // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
2431 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
2432
Olli Etuahoa314b612016-03-10 16:43:00 +02002433 glActiveTexture(GL_TEXTURE0);
2434 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2435 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2436 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2437 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2438
2439 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2440 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2441
2442 // Two levels that are initially unused.
2443 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2444 texDataRed.data());
2445 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2446 texDataCyan.data());
2447
2448 // One level that is used - only this level should affect completeness.
2449 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2450 texDataGreen.data());
2451
2452 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2453 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2454
2455 EXPECT_GL_NO_ERROR();
2456
2457 drawQuad(mProgram, "position", 0.5f);
2458
2459 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2460
Yunchao He2f23f352018-02-11 22:11:37 +08002461 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002462
2463 // Switch the level that is being used to the cyan level 2.
2464 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
2465 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
2466
2467 EXPECT_GL_NO_ERROR();
2468
2469 drawQuad(mProgram, "position", 0.5f);
2470
2471 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2472}
2473
2474// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2475// have images defined.
2476TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
2477{
Olli Etuahoa314b612016-03-10 16:43:00 +02002478 glActiveTexture(GL_TEXTURE0);
2479 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2480 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2481 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2482 texDataGreen.data());
2483 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2484 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2485 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2486 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2487
2488 EXPECT_GL_NO_ERROR();
2489
2490 drawQuad(mProgram, "position", 0.5f);
2491
2492 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2493}
2494
2495// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2496// dimensions that don't fit the images inside the range.
2497// GLES 3.0.4 section 3.8.13 Texture completeness
2498TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2499{
Corentin Wallez566c2e32019-08-28 18:37:58 +02002500 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2501 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2502
Olli Etuahoa314b612016-03-10 16:43:00 +02002503 glActiveTexture(GL_TEXTURE0);
2504 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
2505 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2506 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2507 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2508
2509 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2510 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2511
2512 // Two levels that are initially unused.
2513 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2514 texDataRed.data());
2515 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2516 texDataCyan.data());
2517
2518 // One level that is used - only this level should affect completeness.
2519 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2520 texDataGreen.data());
2521
2522 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2523 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2524
2525 EXPECT_GL_NO_ERROR();
2526
2527 drawQuad(mProgram, "position", 0.5f);
2528
2529 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2530
Yunchao He2f23f352018-02-11 22:11:37 +08002531 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2532
Olli Etuahoa314b612016-03-10 16:43:00 +02002533 // Switch the level that is being used to the cyan level 2.
2534 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
2535 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
2536
2537 EXPECT_GL_NO_ERROR();
2538
2539 drawQuad(mProgram, "position", 0.5f);
2540
2541 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2542}
2543
2544// Test that texture completeness is updated if texture max level changes.
2545// GLES 3.0.4 section 3.8.13 Texture completeness
2546TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2547{
Olli Etuahoa314b612016-03-10 16:43:00 +02002548 glActiveTexture(GL_TEXTURE0);
2549 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2550 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2551
2552 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2553 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2554
2555 // A level that is initially unused.
2556 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2557 texDataGreen.data());
2558
2559 // One level that is initially used - only this level should affect completeness.
2560 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2561 texDataGreen.data());
2562
2563 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2564 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2565
2566 EXPECT_GL_NO_ERROR();
2567
2568 drawQuad(mProgram, "position", 0.5f);
2569
2570 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2571
2572 // Switch the max level to level 1. The levels within the used range now have inconsistent
2573 // dimensions and the texture should be incomplete.
2574 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2575
2576 EXPECT_GL_NO_ERROR();
2577
2578 drawQuad(mProgram, "position", 0.5f);
2579
2580 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2581}
2582
2583// Test that 3D texture completeness is updated if texture max level changes.
2584// GLES 3.0.4 section 3.8.13 Texture completeness
2585TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2586{
Olli Etuahoa314b612016-03-10 16:43:00 +02002587 glActiveTexture(GL_TEXTURE0);
2588 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2589 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2590
2591 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2592 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2593
2594 // A level that is initially unused.
2595 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2596 texDataGreen.data());
2597
2598 // One level that is initially used - only this level should affect completeness.
2599 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2600 texDataGreen.data());
2601
2602 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2603 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2604
2605 EXPECT_GL_NO_ERROR();
2606
2607 drawQuad(mProgram, "position", 0.5f);
2608
2609 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2610
2611 // Switch the max level to level 1. The levels within the used range now have inconsistent
2612 // dimensions and the texture should be incomplete.
2613 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2614
2615 EXPECT_GL_NO_ERROR();
2616
2617 drawQuad(mProgram, "position", 0.5f);
2618
2619 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2620}
2621
2622// Test that texture completeness is updated if texture base level changes.
2623// GLES 3.0.4 section 3.8.13 Texture completeness
2624TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2625{
Olli Etuahoa314b612016-03-10 16:43:00 +02002626 glActiveTexture(GL_TEXTURE0);
2627 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2628 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2629
2630 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2631 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2632
2633 // Two levels that are initially unused.
2634 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2635 texDataGreen.data());
2636 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2637 texDataGreen.data());
2638
2639 // One level that is initially used - only this level should affect completeness.
2640 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2641 texDataGreen.data());
2642
2643 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2644 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2645
2646 EXPECT_GL_NO_ERROR();
2647
2648 drawQuad(mProgram, "position", 0.5f);
2649
2650 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2651
2652 // Switch the base level to level 1. The levels within the used range now have inconsistent
2653 // dimensions and the texture should be incomplete.
2654 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2655
2656 EXPECT_GL_NO_ERROR();
2657
2658 drawQuad(mProgram, "position", 0.5f);
2659
2660 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2661}
2662
2663// Test that texture is not complete if base level is greater than max level.
2664// GLES 3.0.4 section 3.8.13 Texture completeness
2665TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2666{
Olli Etuahoa314b612016-03-10 16:43:00 +02002667 glActiveTexture(GL_TEXTURE0);
2668 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2669
2670 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2671 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2672
2673 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2674
2675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2677
2678 EXPECT_GL_NO_ERROR();
2679
2680 drawQuad(mProgram, "position", 0.5f);
2681
2682 // Texture should be incomplete.
2683 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2684}
2685
2686// Test that immutable texture base level and max level are clamped.
2687// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2688TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2689{
Olli Etuahoa314b612016-03-10 16:43:00 +02002690 glActiveTexture(GL_TEXTURE0);
2691 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2692
2693 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2694 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2695
2696 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2697
2698 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2699
2700 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2701 // should be clamped to [base_level, levels - 1].
2702 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2703 // In the case of this test, those rules make the effective base level and max level 0.
2704 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2705 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2706
2707 EXPECT_GL_NO_ERROR();
2708
2709 drawQuad(mProgram, "position", 0.5f);
2710
2711 // Texture should be complete.
2712 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2713}
2714
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002715// Test that changing base level works when it affects the format of the texture.
2716TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2717{
Corentin Wallez7f00d332019-08-28 15:19:16 +02002718 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2719 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2720
Yunchao He8e5ba8b2018-02-05 17:52:27 +08002721 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
Yunchao He9550c602018-02-13 14:47:05 +08002722
2723 // Observed incorrect rendering on AMD OpenGL.
2724 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002725
2726 glActiveTexture(GL_TEXTURE0);
2727 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2728 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2729 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2730
2731 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2732 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2733
2734 // RGBA8 level that's initially unused.
2735 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2736 texDataCyan.data());
2737
2738 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2739 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2740
2741 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2742 // format. It reads green channel data from the green and alpha channels of texDataGreen
2743 // (this is a bit hacky but works).
2744 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2745
2746 EXPECT_GL_NO_ERROR();
2747
2748 drawQuad(mProgram, "position", 0.5f);
2749
2750 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2751
2752 // Switch the texture to use the cyan level 0 with the RGBA format.
2753 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2754 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2755
2756 EXPECT_GL_NO_ERROR();
2757
2758 drawQuad(mProgram, "position", 0.5f);
2759
2760 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2761}
2762
Olli Etuahoa314b612016-03-10 16:43:00 +02002763// Test that setting a texture image works when base level is out of range.
2764TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2765{
2766 glActiveTexture(GL_TEXTURE0);
2767 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2768
2769 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2771
2772 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2773 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2774
2775 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2776
2777 EXPECT_GL_NO_ERROR();
2778
2779 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2780
2781 drawQuad(mProgram, "position", 0.5f);
2782
2783 // Texture should be complete.
2784 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002785}
2786
Jamie Madill50cf2be2018-06-15 09:46:57 -04002787// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
2788// RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
2789// with these formats does not work as expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002790TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002791{
2792 std::vector<GLubyte> pixelData;
2793 for (size_t count = 0; count < 5000; count++)
2794 {
2795 pixelData.push_back(0u);
2796 pixelData.push_back(255u);
2797 pixelData.push_back(0u);
2798 }
2799
2800 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002801 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002802 glUniform1i(mTextureArrayLocation, 0);
2803
2804 // The first draw worked correctly.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002805 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2806 &pixelData[0]);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002807
2808 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2809 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2810 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2811 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002812 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002813 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002814
2815 // The dimension of the respecification must match the original exactly to trigger the bug.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002816 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2817 &pixelData[0]);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002818 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002819 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002820
2821 ASSERT_GL_NO_ERROR();
2822}
2823
Olli Etuaho1a679902016-01-14 12:21:47 +02002824// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2825// This test is needed especially to confirm that sampler registers get assigned correctly on
2826// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2827TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2828{
2829 glActiveTexture(GL_TEXTURE0);
2830 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2831 GLubyte texData[4];
2832 texData[0] = 0;
2833 texData[1] = 60;
2834 texData[2] = 0;
2835 texData[3] = 255;
2836 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2837
2838 glActiveTexture(GL_TEXTURE1);
2839 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2840 GLfloat depthTexData[1];
2841 depthTexData[0] = 0.5f;
2842 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2843 depthTexData);
2844
2845 glUseProgram(mProgram);
2846 glUniform1f(mDepthRefUniformLocation, 0.3f);
2847 glUniform1i(mTexture3DUniformLocation, 0);
2848 glUniform1i(mTextureShadowUniformLocation, 1);
2849
2850 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2851 drawQuad(mProgram, "position", 0.5f);
2852 EXPECT_GL_NO_ERROR();
2853 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2854 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2855
2856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2857 drawQuad(mProgram, "position", 0.5f);
2858 EXPECT_GL_NO_ERROR();
2859 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2860 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2861}
2862
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002863// Test multiple different sampler types in the same shader.
2864// This test makes sure that even if sampler / texture registers get grouped together based on type
2865// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2866// still has the right register index information for each ESSL sampler.
2867// The tested ESSL samplers have the following types in D3D11 HLSL:
2868// sampler2D: Texture2D + SamplerState
2869// samplerCube: TextureCube + SamplerState
2870// sampler2DShadow: Texture2D + SamplerComparisonState
2871// samplerCubeShadow: TextureCube + SamplerComparisonState
2872TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2873{
2874 glActiveTexture(GL_TEXTURE0);
2875 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2876 GLubyte texData[4];
2877 texData[0] = 0;
2878 texData[1] = 0;
2879 texData[2] = 120;
2880 texData[3] = 255;
2881 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2882
2883 glActiveTexture(GL_TEXTURE1);
2884 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2885 texData[0] = 0;
2886 texData[1] = 90;
2887 texData[2] = 0;
2888 texData[3] = 255;
2889 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2890 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2891 texData);
2892
2893 glActiveTexture(GL_TEXTURE2);
2894 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2895 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2896 GLfloat depthTexData[1];
2897 depthTexData[0] = 0.5f;
2898 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2899 depthTexData);
2900
2901 glActiveTexture(GL_TEXTURE3);
2902 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2903 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2904 depthTexData[0] = 0.2f;
2905 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2906 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2907 depthTexData);
2908
Tobin Ehlisbbf0ce22019-10-11 06:55:36 -06002909 // http://anglebug.com/3949: TODO: Add a DS texture case
2910
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002911 EXPECT_GL_NO_ERROR();
2912
2913 glUseProgram(mProgram);
2914 glUniform1f(mDepthRefUniformLocation, 0.3f);
2915 glUniform1i(mTexture2DUniformLocation, 0);
2916 glUniform1i(mTextureCubeUniformLocation, 1);
2917 glUniform1i(mTexture2DShadowUniformLocation, 2);
2918 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2919
2920 drawQuad(mProgram, "position", 0.5f);
2921 EXPECT_GL_NO_ERROR();
2922 // The shader writes:
2923 // <texture 2d color> +
2924 // <cube map color> +
2925 // 0.25 * <comparison result (1.0)> +
2926 // 0.125 * <comparison result (0.0)>
2927 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2928}
2929
Olli Etuahobce743a2016-01-15 17:18:28 +02002930// Test different base levels on textures accessed through the same sampler array.
2931// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2932TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2933{
Yunchao He9550c602018-02-13 14:47:05 +08002934 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
2935
Jamie Madill788fa362020-02-10 14:07:12 -05002936 // http://anglebug.com/4391
2937 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsWindows() && IsD3D11());
2938
Olli Etuahobce743a2016-01-15 17:18:28 +02002939 glActiveTexture(GL_TEXTURE0);
2940 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2941 GLsizei size = 64;
2942 for (GLint level = 0; level < 7; ++level)
2943 {
2944 ASSERT_LT(0, size);
2945 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2946 nullptr);
2947 size = size / 2;
2948 }
2949 ASSERT_EQ(0, size);
2950 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2951
2952 glActiveTexture(GL_TEXTURE1);
2953 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2954 size = 128;
2955 for (GLint level = 0; level < 8; ++level)
2956 {
2957 ASSERT_LT(0, size);
2958 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2959 nullptr);
2960 size = size / 2;
2961 }
2962 ASSERT_EQ(0, size);
2963 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2964 EXPECT_GL_NO_ERROR();
2965
2966 glUseProgram(mProgram);
2967 glUniform1i(mTexture0Location, 0);
2968 glUniform1i(mTexture1Location, 1);
2969
Olli Etuaho5804dc82018-04-13 14:11:46 +03002970 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
Olli Etuahobce743a2016-01-15 17:18:28 +02002971 EXPECT_GL_NO_ERROR();
2972 // Red channel: width of level 1 of texture A: 32.
2973 // Green channel: width of level 3 of texture B: 16.
2974 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2975}
2976
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002977// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2978// ES 3.0.4 table 3.24
2979TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2980{
2981 glActiveTexture(GL_TEXTURE0);
2982 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2983 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2984 EXPECT_GL_NO_ERROR();
2985
2986 drawQuad(mProgram, "position", 0.5f);
2987
2988 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2989}
2990
2991// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2992// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05002993TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002994{
Luc Ferron5164b792018-03-06 09:10:12 -05002995 setUpProgram();
2996
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002997 glActiveTexture(GL_TEXTURE0);
2998 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2999 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
3000 EXPECT_GL_NO_ERROR();
3001
3002 drawQuad(mProgram, "position", 0.5f);
3003
3004 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3005}
3006
Luc Ferron5164b792018-03-06 09:10:12 -05003007// Validate that every component of the pixel will be equal to the luminance value we've set
3008// and that the alpha channel will be 1 (or 255 to be exact).
3009TEST_P(Texture2DTest, TextureLuminanceRGBSame)
3010{
3011 setUpProgram();
3012
3013 glActiveTexture(GL_TEXTURE0);
3014 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3015 uint8_t pixel = 50;
3016 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
3017 EXPECT_GL_NO_ERROR();
3018
3019 drawQuad(mProgram, "position", 0.5f);
3020
3021 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
3022}
3023
3024// Validate that every component of the pixel will be equal to the luminance value we've set
3025// and that the alpha channel will be the second component.
3026TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
3027{
3028 setUpProgram();
3029
3030 glActiveTexture(GL_TEXTURE0);
3031 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3032 uint8_t pixel[] = {50, 25};
3033 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
3034 GL_UNSIGNED_BYTE, pixel);
3035 EXPECT_GL_NO_ERROR();
3036
3037 drawQuad(mProgram, "position", 0.5f);
3038
3039 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
3040}
3041
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003042// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3043// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003044TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003045{
Jamie Madillb8149072019-04-30 16:14:44 -04003046 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003047 ANGLE_SKIP_TEST_IF(IsD3D9());
3048 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferron5164b792018-03-06 09:10:12 -05003049
3050 setUpProgram();
3051
Luc Ferrond8c632c2018-04-10 12:31:44 -04003052 glActiveTexture(GL_TEXTURE0);
3053 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3054 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
3055 EXPECT_GL_NO_ERROR();
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003056
Luc Ferrond8c632c2018-04-10 12:31:44 -04003057 drawQuad(mProgram, "position", 0.5f);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003058
Luc Ferrond8c632c2018-04-10 12:31:44 -04003059 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003060}
3061
3062// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3063// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003064TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003065{
Jamie Madillb8149072019-04-30 16:14:44 -04003066 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003067 ANGLE_SKIP_TEST_IF(IsD3D9());
3068 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferrond8c632c2018-04-10 12:31:44 -04003069 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
3070 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
Luc Ferron5164b792018-03-06 09:10:12 -05003071
Luc Ferrond8c632c2018-04-10 12:31:44 -04003072 setUpProgram();
Luc Ferron5164b792018-03-06 09:10:12 -05003073
Luc Ferrond8c632c2018-04-10 12:31:44 -04003074 glActiveTexture(GL_TEXTURE0);
3075 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3076 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
3077 EXPECT_GL_NO_ERROR();
Yunchao He9550c602018-02-13 14:47:05 +08003078
Luc Ferrond8c632c2018-04-10 12:31:44 -04003079 drawQuad(mProgram, "position", 0.5f);
Yuly Novikovafcec832016-06-21 22:19:51 -04003080
Luc Ferrond8c632c2018-04-10 12:31:44 -04003081 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003082}
3083
3084// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3085// ES 3.0.4 table 3.24
3086TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
3087{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003088 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3089
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003090 glActiveTexture(GL_TEXTURE0);
3091 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3092 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
3093 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3094 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3095 EXPECT_GL_NO_ERROR();
3096
3097 drawQuad(mProgram, "position", 0.5f);
3098
3099 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3100}
3101
3102// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3103// ES 3.0.4 table 3.24
3104TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
3105{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003106 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3107
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003108 glActiveTexture(GL_TEXTURE0);
3109 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3110
3111 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
3112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3114 EXPECT_GL_NO_ERROR();
3115
3116 drawQuad(mProgram, "position", 0.5f);
3117
3118 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3119}
3120
3121// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3122// ES 3.0.4 table 3.24
3123TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
3124{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003125 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3126
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003127 glActiveTexture(GL_TEXTURE0);
3128 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3129 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
3130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3132 EXPECT_GL_NO_ERROR();
3133
3134 drawQuad(mProgram, "position", 0.5f);
3135
3136 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3137}
3138
3139// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3140// ES 3.0.4 table 3.24
3141TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
3142{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003143 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3144
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003145 glActiveTexture(GL_TEXTURE0);
3146 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3147 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
3148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3150 EXPECT_GL_NO_ERROR();
3151
3152 drawQuad(mProgram, "position", 0.5f);
3153
3154 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3155}
3156
3157// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3158// ES 3.0.4 table 3.24
3159TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
3160{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003161 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3162
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003163 glActiveTexture(GL_TEXTURE0);
3164 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3165 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
3166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3168 EXPECT_GL_NO_ERROR();
3169
3170 drawQuad(mProgram, "position", 0.5f);
3171
3172 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3173}
3174
3175// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3176// ES 3.0.4 table 3.24
3177TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
3178{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003179 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3180
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003181 glActiveTexture(GL_TEXTURE0);
3182 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3183 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
3184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3186 EXPECT_GL_NO_ERROR();
3187
3188 drawQuad(mProgram, "position", 0.5f);
3189
3190 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3191}
3192
3193// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3194// ES 3.0.4 table 3.24
3195TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
3196{
3197 glActiveTexture(GL_TEXTURE0);
3198 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3199 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
3200 EXPECT_GL_NO_ERROR();
3201
3202 drawQuad(mProgram, "position", 0.5f);
3203
3204 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3205}
3206
3207// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3208// ES 3.0.4 table 3.24
3209TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
3210{
3211 glActiveTexture(GL_TEXTURE0);
3212 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3213 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
3214 nullptr);
3215 EXPECT_GL_NO_ERROR();
3216
3217 drawQuad(mProgram, "position", 0.5f);
3218
3219 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3220}
3221
3222// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3223// ES 3.0.4 table 3.24
3224TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
3225{
Geoff Lang2a19c592019-08-23 14:10:24 -04003226 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3227 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003228
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003229 glActiveTexture(GL_TEXTURE0);
3230 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3231 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
3232 EXPECT_GL_NO_ERROR();
3233
3234 drawQuad(mProgram, "position", 0.5f);
3235
3236 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3237}
3238
3239// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3240// ES 3.0.4 table 3.24
3241TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
3242{
Geoff Lang2a19c592019-08-23 14:10:24 -04003243 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3244 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003245
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003246 glActiveTexture(GL_TEXTURE0);
3247 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3248 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
3249 EXPECT_GL_NO_ERROR();
3250
3251 drawQuad(mProgram, "position", 0.5f);
3252
3253 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3254}
3255
Olli Etuaho96963162016-03-21 11:54:33 +02003256// Use a sampler in a uniform struct.
3257TEST_P(SamplerInStructTest, SamplerInStruct)
3258{
3259 runSamplerInStructTest();
3260}
3261
3262// Use a sampler in a uniform struct that's passed as a function parameter.
3263TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
3264{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003265 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3266 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Geoff Lang8fcdf6e2016-09-16 10:45:30 -04003267
Olli Etuaho96963162016-03-21 11:54:33 +02003268 runSamplerInStructTest();
3269}
3270
3271// Use a sampler in a uniform struct array with a struct from the array passed as a function
3272// parameter.
3273TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
3274{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003275 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3276 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003277
Olli Etuaho96963162016-03-21 11:54:33 +02003278 runSamplerInStructTest();
3279}
3280
3281// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
3282// parameter.
3283TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
3284{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003285 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3286 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003287
Olli Etuaho96963162016-03-21 11:54:33 +02003288 runSamplerInStructTest();
3289}
3290
3291// Make sure that there isn't a name conflict between sampler extracted from a struct and a
3292// similarly named uniform.
3293TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
3294{
3295 runSamplerInStructTest();
3296}
3297
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003298// GL_EXT_texture_filter_anisotropic
3299class TextureAnisotropyTest : public Texture2DTest
3300{
3301 protected:
3302 void uploadTexture()
3303 {
3304 glActiveTexture(GL_TEXTURE0);
3305 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3306 GLColor texDataRed[1] = {GLColor::red};
3307 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
3308 EXPECT_GL_NO_ERROR();
3309 }
3310};
3311
3312// Tests that setting anisotropic filtering doesn't cause failures at draw time.
3313TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
3314{
Jamie Madillb8149072019-04-30 16:14:44 -04003315 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003316
3317 setUpProgram();
3318
3319 uploadTexture();
3320
3321 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3322 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3323 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
3324 EXPECT_GL_NO_ERROR();
3325
3326 drawQuad(mProgram, "position", 0.5f);
3327
3328 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3329 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3330 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
3331}
3332
Till Rathmannb8543632018-10-02 19:46:14 +02003333// GL_OES_texture_border_clamp
3334class TextureBorderClampTest : public Texture2DTest
3335{
3336 protected:
3337 TextureBorderClampTest() : Texture2DTest() {}
3338
Jamie Madill35cd7332018-12-02 12:03:33 -05003339 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003340 {
3341 return
3342 R"(precision highp float;
3343 attribute vec4 position;
3344 varying vec2 texcoord;
3345
3346 void main()
3347 {
3348 gl_Position = vec4(position.xy, 0.0, 1.0);
3349 // texcoords in [-0.5, 1.5]
3350 texcoord = (position.xy) + 0.5;
3351 })";
3352 }
3353
3354 void uploadTexture()
3355 {
3356 glActiveTexture(GL_TEXTURE0);
3357 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3358 std::vector<GLColor> texDataRed(1, GLColor::red);
3359 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3360 texDataRed.data());
3361 EXPECT_GL_NO_ERROR();
3362 }
3363};
3364
3365// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3366// GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
3367TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
3368{
Jamie Madillb8149072019-04-30 16:14:44 -04003369 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003370
3371 setUpProgram();
3372
3373 uploadTexture();
3374
3375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3378 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3379 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3380 EXPECT_GL_NO_ERROR();
3381
3382 drawQuad(mProgram, "position", 0.5f);
3383
3384 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3385 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3386 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3387}
3388
3389// Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
3390TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
3391{
Jamie Madillb8149072019-04-30 16:14:44 -04003392 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003393
3394 glActiveTexture(GL_TEXTURE0);
3395 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3396
3397 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3398
3399 GLint colorFixedPoint[4] = {0};
3400 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3401 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3402 std::numeric_limits<GLint>::max()};
3403 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3404 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3405 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3406 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3407
3408 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3409 std::numeric_limits<GLint>::max()};
3410 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3411
3412 GLfloat color[4] = {0.0f};
3413 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
3414 EXPECT_EQ(color[0], kFloatBlue.R);
3415 EXPECT_EQ(color[1], kFloatBlue.G);
3416 EXPECT_EQ(color[2], kFloatBlue.B);
3417 EXPECT_EQ(color[3], kFloatBlue.A);
3418}
3419
3420// Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
3421TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
3422{
Jamie Madillb8149072019-04-30 16:14:44 -04003423 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003424
3425 glActiveTexture(GL_TEXTURE0);
3426 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3427
3428 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
3429 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3430
3431 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3432 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3433
3434 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3435 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3436
3437 GLint colorInt[4] = {0};
3438 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
3439 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3440
3441 if (getClientMajorVersion() < 3)
3442 {
3443 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3444 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3445 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3446 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3447
3448 GLuint colorUInt[4] = {0};
3449 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3450 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3451 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3452 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3453
3454 GLSampler sampler;
3455 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3456 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3457 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3458 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3459
3460 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3461 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3462 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3463 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3464 }
3465}
3466
3467class TextureBorderClampTestES3 : public TextureBorderClampTest
3468{
3469 protected:
3470 TextureBorderClampTestES3() : TextureBorderClampTest() {}
3471};
3472
3473// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3474// GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
3475TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
3476{
Jamie Madillb8149072019-04-30 16:14:44 -04003477 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003478
3479 setUpProgram();
3480
3481 uploadTexture();
3482
3483 GLSampler sampler;
3484 glBindSampler(0, sampler);
3485 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3486 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3487 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3488 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3489 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3490 EXPECT_GL_NO_ERROR();
3491
3492 drawQuad(mProgram, "position", 0.5f);
3493
3494 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3495 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3496 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3497}
3498
3499// Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
3500TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
3501{
Jamie Madillb8149072019-04-30 16:14:44 -04003502 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003503
3504 glActiveTexture(GL_TEXTURE0);
3505
3506 GLSampler sampler;
3507 glBindSampler(0, sampler);
3508
3509 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3510
3511 GLint colorFixedPoint[4] = {0};
3512 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3513 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3514 std::numeric_limits<GLint>::max()};
3515 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3516 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3517 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3518 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3519
3520 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3521 std::numeric_limits<GLint>::max()};
3522 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3523
3524 GLfloat color[4] = {0.0f};
3525 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
3526 EXPECT_EQ(color[0], kFloatBlue.R);
3527 EXPECT_EQ(color[1], kFloatBlue.G);
3528 EXPECT_EQ(color[2], kFloatBlue.B);
3529 EXPECT_EQ(color[3], kFloatBlue.A);
3530
3531 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
3532 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
3533 GLint colorInt[4] = {0};
3534 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3535 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
3536 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
3537 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
3538 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
3539
3540 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
3541 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
3542 GLuint colorUInt[4] = {0};
3543 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3544 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
3545 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
3546 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
3547 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
3548
3549 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3550
3551 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
3552 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
3553 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3554 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
3555 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
3556 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
3557 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
3558
3559 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
3560 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
3561 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3562 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
3563 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
3564 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
3565 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
3566}
3567
3568// Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
3569TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
3570{
Jamie Madillb8149072019-04-30 16:14:44 -04003571 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003572
3573 glActiveTexture(GL_TEXTURE0);
3574
3575 GLSampler sampler;
3576 glBindSampler(0, sampler);
3577
3578 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
3579 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3580
3581 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3582 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3583}
3584
3585class TextureBorderClampIntegerTestES3 : public Texture2DTest
3586{
3587 protected:
3588 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
3589
Jamie Madill35cd7332018-12-02 12:03:33 -05003590 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003591 {
3592 return
3593 R"(#version 300 es
3594 out vec2 texcoord;
3595 in vec4 position;
3596
3597 void main()
3598 {
3599 gl_Position = vec4(position.xy, 0.0, 1.0);
3600 // texcoords in [-0.5, 1.5]
3601 texcoord = (position.xy) + 0.5;
3602 })";
3603 }
3604
Jamie Madillba319ba2018-12-29 10:29:33 -05003605 const char *getFragmentShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003606 {
Jamie Madill35cd7332018-12-02 12:03:33 -05003607 if (isUnsignedIntTest)
3608 {
3609 return "#version 300 es\n"
3610 "precision highp float;\n"
3611 "uniform highp usampler2D tex;\n"
3612 "in vec2 texcoord;\n"
3613 "out vec4 fragColor;\n"
Till Rathmannb8543632018-10-02 19:46:14 +02003614
Jamie Madill35cd7332018-12-02 12:03:33 -05003615 "void main()\n"
3616 "{\n"
3617 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3618 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3619 "fragColor = (texture(tex, texcoord).r == 150u)"
3620 " ? green : red;\n"
3621 "}\n";
3622 }
3623 else
3624 {
3625 return "#version 300 es\n"
3626 "precision highp float;\n"
3627 "uniform highp isampler2D tex;\n"
3628 "in vec2 texcoord;\n"
3629 "out vec4 fragColor;\n"
3630
3631 "void main()\n"
3632 "{\n"
3633 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3634 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3635 "fragColor = (texture(tex, texcoord).r == -50)"
3636 " ? green : red;\n"
3637 "}\n";
3638 }
Till Rathmannb8543632018-10-02 19:46:14 +02003639 }
3640
3641 void uploadTexture()
3642 {
3643 glActiveTexture(GL_TEXTURE0);
3644 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3645 if (isUnsignedIntTest)
3646 {
3647 std::vector<GLubyte> texData(4, 100);
3648 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
3649 texData.data());
3650 }
3651 else
3652 {
3653 std::vector<GLbyte> texData(4, 100);
3654 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
3655 texData.data());
3656 }
3657 EXPECT_GL_NO_ERROR();
3658 }
3659
3660 bool isUnsignedIntTest;
3661};
3662
3663// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3664// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3665TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
3666{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003667 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3668 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3669
Jamie Madillb8149072019-04-30 16:14:44 -04003670 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003671
3672 setUpProgram();
3673
3674 uploadTexture();
3675
3676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3677 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3678 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3679 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3680
3681 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3682 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3683
3684 EXPECT_GL_NO_ERROR();
3685
3686 drawQuad(mProgram, "position", 0.5f);
3687
3688 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3689 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3690 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3691}
3692
3693// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3694// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3695TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
3696{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003697 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3698 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3699
Jamie Madillb8149072019-04-30 16:14:44 -04003700 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003701
3702 setUpProgram();
3703
3704 uploadTexture();
3705
3706 GLSampler sampler;
3707 glBindSampler(0, sampler);
3708 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3709 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3710 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3711 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3712
3713 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3714 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3715
3716 EXPECT_GL_NO_ERROR();
3717
3718 drawQuad(mProgram, "position", 0.5f);
3719
3720 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3721 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3722 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3723}
3724
3725// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3726// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
3727TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
3728{
Jamie Madillb8149072019-04-30 16:14:44 -04003729 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003730
3731 isUnsignedIntTest = true;
3732
3733 setUpProgram();
3734
3735 uploadTexture();
3736
3737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3738 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3739 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3740 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3741
3742 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3743 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3744
3745 EXPECT_GL_NO_ERROR();
3746
3747 drawQuad(mProgram, "position", 0.5f);
3748
3749 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3750 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3751 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3752}
3753
3754// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3755// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
3756// glSamplerParameterIuivOES).
3757TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
3758{
Jamie Madillb8149072019-04-30 16:14:44 -04003759 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003760
3761 isUnsignedIntTest = true;
3762
3763 setUpProgram();
3764
3765 uploadTexture();
3766
3767 GLSampler sampler;
3768 glBindSampler(0, sampler);
3769 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3770 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3771 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3772 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3773
3774 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3775 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3776
3777 EXPECT_GL_NO_ERROR();
3778
3779 drawQuad(mProgram, "position", 0.5f);
3780
3781 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3782 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3783 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3784}
3785
3786// ~GL_OES_texture_border_clamp
3787
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003788class TextureLimitsTest : public ANGLETest
3789{
3790 protected:
3791 struct RGBA8
3792 {
3793 uint8_t R, G, B, A;
3794 };
3795
3796 TextureLimitsTest()
3797 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
3798 {
3799 setWindowWidth(128);
3800 setWindowHeight(128);
3801 setConfigRedBits(8);
3802 setConfigGreenBits(8);
3803 setConfigBlueBits(8);
3804 setConfigAlphaBits(8);
3805 }
3806
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003807 void testSetUp() override
Jamie Madill0fdb9562018-09-17 17:18:43 -04003808 {
Jamie Madill0fdb9562018-09-17 17:18:43 -04003809 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
3810 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
3811 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
3812
3813 ASSERT_GL_NO_ERROR();
3814 }
3815
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003816 void testTearDown() override
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003817 {
3818 if (mProgram != 0)
3819 {
3820 glDeleteProgram(mProgram);
3821 mProgram = 0;
3822
3823 if (!mTextures.empty())
3824 {
3825 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
3826 }
3827 }
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003828 }
3829
3830 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
3831 GLint vertexTextureCount,
3832 GLint vertexActiveTextureCount,
3833 const std::string &fragPrefix,
3834 GLint fragmentTextureCount,
3835 GLint fragmentActiveTextureCount)
3836 {
3837 std::stringstream vertexShaderStr;
3838 vertexShaderStr << "attribute vec2 position;\n"
3839 << "varying vec4 color;\n"
3840 << "varying vec2 texCoord;\n";
3841
3842 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
3843 {
3844 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
3845 }
3846
3847 vertexShaderStr << "void main() {\n"
3848 << " gl_Position = vec4(position, 0, 1);\n"
3849 << " texCoord = (position * 0.5) + 0.5;\n"
3850 << " color = vec4(0);\n";
3851
3852 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
3853 {
3854 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
3855 << ", texCoord);\n";
3856 }
3857
3858 vertexShaderStr << "}";
3859
3860 std::stringstream fragmentShaderStr;
3861 fragmentShaderStr << "varying mediump vec4 color;\n"
3862 << "varying mediump vec2 texCoord;\n";
3863
3864 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
3865 {
3866 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
3867 }
3868
3869 fragmentShaderStr << "void main() {\n"
3870 << " gl_FragColor = color;\n";
3871
3872 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
3873 {
3874 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
3875 << ", texCoord);\n";
3876 }
3877
3878 fragmentShaderStr << "}";
3879
3880 const std::string &vertexShaderSource = vertexShaderStr.str();
3881 const std::string &fragmentShaderSource = fragmentShaderStr.str();
3882
Jamie Madill35cd7332018-12-02 12:03:33 -05003883 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003884 }
3885
3886 RGBA8 getPixel(GLint texIndex)
3887 {
3888 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
3889 0, 255u};
3890 return pixel;
3891 }
3892
3893 void initTextures(GLint tex2DCount, GLint texCubeCount)
3894 {
3895 GLint totalCount = tex2DCount + texCubeCount;
3896 mTextures.assign(totalCount, 0);
3897 glGenTextures(totalCount, &mTextures[0]);
3898 ASSERT_GL_NO_ERROR();
3899
3900 std::vector<RGBA8> texData(16 * 16);
3901
3902 GLint texIndex = 0;
3903 for (; texIndex < tex2DCount; ++texIndex)
3904 {
3905 texData.assign(texData.size(), getPixel(texIndex));
3906 glActiveTexture(GL_TEXTURE0 + texIndex);
3907 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
3908 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3909 &texData[0]);
3910 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3911 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3912 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3913 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3914 }
3915
3916 ASSERT_GL_NO_ERROR();
3917
3918 for (; texIndex < texCubeCount; ++texIndex)
3919 {
3920 texData.assign(texData.size(), getPixel(texIndex));
3921 glActiveTexture(GL_TEXTURE0 + texIndex);
3922 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
3923 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3924 GL_UNSIGNED_BYTE, &texData[0]);
3925 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3926 GL_UNSIGNED_BYTE, &texData[0]);
3927 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3928 GL_UNSIGNED_BYTE, &texData[0]);
3929 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3930 GL_UNSIGNED_BYTE, &texData[0]);
3931 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3932 GL_UNSIGNED_BYTE, &texData[0]);
3933 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3934 GL_UNSIGNED_BYTE, &texData[0]);
3935 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3936 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3937 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3938 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3939 }
3940
3941 ASSERT_GL_NO_ERROR();
3942 }
3943
3944 void testWithTextures(GLint vertexTextureCount,
3945 const std::string &vertexTexturePrefix,
3946 GLint fragmentTextureCount,
3947 const std::string &fragmentTexturePrefix)
3948 {
3949 // Generate textures
3950 initTextures(vertexTextureCount + fragmentTextureCount, 0);
3951
3952 glUseProgram(mProgram);
3953 RGBA8 expectedSum = {0};
3954 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
3955 {
3956 std::stringstream uniformNameStr;
3957 uniformNameStr << vertexTexturePrefix << texIndex;
3958 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003959 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003960 ASSERT_NE(-1, location);
3961
3962 glUniform1i(location, texIndex);
3963 RGBA8 contribution = getPixel(texIndex);
3964 expectedSum.R += contribution.R;
3965 expectedSum.G += contribution.G;
3966 }
3967
3968 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
3969 {
3970 std::stringstream uniformNameStr;
3971 uniformNameStr << fragmentTexturePrefix << texIndex;
3972 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003973 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003974 ASSERT_NE(-1, location);
3975
3976 glUniform1i(location, texIndex + vertexTextureCount);
3977 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
3978 expectedSum.R += contribution.R;
3979 expectedSum.G += contribution.G;
3980 }
3981
3982 ASSERT_GE(256u, expectedSum.G);
3983
3984 drawQuad(mProgram, "position", 0.5f);
3985 ASSERT_GL_NO_ERROR();
3986 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
3987 }
3988
3989 GLuint mProgram;
3990 std::vector<GLuint> mTextures;
3991 GLint mMaxVertexTextures;
3992 GLint mMaxFragmentTextures;
3993 GLint mMaxCombinedTextures;
3994};
3995
3996// Test rendering with the maximum vertex texture units.
3997TEST_P(TextureLimitsTest, MaxVertexTextures)
3998{
3999 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
4000 ASSERT_NE(0u, mProgram);
4001 ASSERT_GL_NO_ERROR();
4002
4003 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4004}
4005
4006// Test rendering with the maximum fragment texture units.
4007TEST_P(TextureLimitsTest, MaxFragmentTextures)
4008{
4009 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
4010 ASSERT_NE(0u, mProgram);
4011 ASSERT_GL_NO_ERROR();
4012
4013 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
4014}
4015
4016// Test rendering with maximum combined texture units.
4017TEST_P(TextureLimitsTest, MaxCombinedTextures)
4018{
Tim Van Pattenabaa3572020-02-20 10:23:02 -07004019 // TODO(timvp): http://anglebug.com/3570
4020 // Currently only fails on SwiftShader but we don't have an IsSwiftShader().
4021 // max per-stage sampled image bindings count (32) exceeds device
4022 // maxPerStageDescriptorSampledImages limit (16)
4023 ANGLE_SKIP_TEST_IF(IsVulkan());
4024
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004025 GLint vertexTextures = mMaxVertexTextures;
4026
4027 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
4028 {
4029 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
4030 }
4031
4032 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
4033 mMaxFragmentTextures, mMaxFragmentTextures);
4034 ASSERT_NE(0u, mProgram);
4035 ASSERT_GL_NO_ERROR();
4036
4037 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
4038}
4039
4040// Negative test for exceeding the number of vertex textures
4041TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
4042{
4043 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
4044 0);
4045 ASSERT_EQ(0u, mProgram);
4046}
4047
4048// Negative test for exceeding the number of fragment textures
4049TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
4050{
4051 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
4052 mMaxFragmentTextures + 1);
4053 ASSERT_EQ(0u, mProgram);
4054}
4055
4056// Test active vertex textures under the limit, but excessive textures specified.
4057TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
4058{
4059 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
4060 ASSERT_NE(0u, mProgram);
4061 ASSERT_GL_NO_ERROR();
4062
4063 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4064}
4065
4066// Test active fragment textures under the limit, but excessive textures specified.
4067TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
4068{
4069 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
4070 mMaxFragmentTextures);
4071 ASSERT_NE(0u, mProgram);
4072 ASSERT_GL_NO_ERROR();
4073
4074 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
4075}
4076
4077// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02004078// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004079TEST_P(TextureLimitsTest, TextureTypeConflict)
4080{
Jamie Madill35cd7332018-12-02 12:03:33 -05004081 constexpr char kVS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004082 "attribute vec2 position;\n"
4083 "varying float color;\n"
4084 "uniform sampler2D tex2D;\n"
4085 "uniform samplerCube texCube;\n"
4086 "void main() {\n"
4087 " gl_Position = vec4(position, 0, 1);\n"
4088 " vec2 texCoord = (position * 0.5) + 0.5;\n"
4089 " color = texture2D(tex2D, texCoord).x;\n"
4090 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
4091 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05004092 constexpr char kFS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004093 "varying mediump float color;\n"
4094 "void main() {\n"
4095 " gl_FragColor = vec4(color, 0, 0, 1);\n"
4096 "}";
4097
Jamie Madill35cd7332018-12-02 12:03:33 -05004098 mProgram = CompileProgram(kVS, kFS);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004099 ASSERT_NE(0u, mProgram);
4100
4101 initTextures(1, 0);
4102
4103 glUseProgram(mProgram);
4104 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
4105 ASSERT_NE(-1, tex2DLocation);
4106 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
4107 ASSERT_NE(-1, texCubeLocation);
4108
4109 glUniform1i(tex2DLocation, 0);
4110 glUniform1i(texCubeLocation, 0);
4111 ASSERT_GL_NO_ERROR();
4112
4113 drawQuad(mProgram, "position", 0.5f);
4114 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4115}
4116
Vincent Lang25ab4512016-05-13 18:13:59 +02004117class Texture2DNorm16TestES3 : public Texture2DTestES3
4118{
4119 protected:
4120 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
4121
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004122 void testSetUp() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004123 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004124 Texture2DTestES3::testSetUp();
Vincent Lang25ab4512016-05-13 18:13:59 +02004125
4126 glActiveTexture(GL_TEXTURE0);
4127 glGenTextures(3, mTextures);
4128 glGenFramebuffers(1, &mFBO);
4129 glGenRenderbuffers(1, &mRenderbuffer);
4130
4131 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
4132 {
4133 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
4134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4136 }
4137
4138 glBindTexture(GL_TEXTURE_2D, 0);
4139
4140 ASSERT_GL_NO_ERROR();
4141 }
4142
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004143 void testTearDown() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004144 {
4145 glDeleteTextures(3, mTextures);
4146 glDeleteFramebuffers(1, &mFBO);
4147 glDeleteRenderbuffers(1, &mRenderbuffer);
4148
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004149 Texture2DTestES3::testTearDown();
Vincent Lang25ab4512016-05-13 18:13:59 +02004150 }
4151
4152 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
4153 {
shrekshao81ee4d22019-12-04 17:05:11 -08004154 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4155 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4156 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4157
Geoff Langf607c602016-09-21 11:46:48 -04004158 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
4159 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004160
4161 setUpProgram();
4162
4163 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4164 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
4165 0);
4166
4167 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
4168 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
4169
4170 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Geoff Langf607c602016-09-21 11:46:48 -04004171 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004172
4173 EXPECT_GL_NO_ERROR();
4174
4175 drawQuad(mProgram, "position", 0.5f);
4176
Geoff Langf607c602016-09-21 11:46:48 -04004177 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
Vincent Lang25ab4512016-05-13 18:13:59 +02004178
Jamie Madill50cf2be2018-06-15 09:46:57 -04004179 EXPECT_PIXEL_COLOR_EQ(0, 0,
4180 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
4181 expectedValue, expectedValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004182
4183 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4184
4185 ASSERT_GL_NO_ERROR();
4186 }
4187
shrekshao81ee4d22019-12-04 17:05:11 -08004188 void testReadPixelsRGBAWithRangeAndPixelStoreMode(GLuint x,
4189 GLuint y,
4190 GLuint width,
4191 GLuint height,
4192 GLint packRowLength,
4193 GLint packAlignment,
4194 GLint packSkipPixels,
4195 GLint packSkipRows,
4196 GLenum type,
4197 GLColor16UI color)
Vincent Lang25ab4512016-05-13 18:13:59 +02004198 {
shrekshao81ee4d22019-12-04 17:05:11 -08004199 // PACK modes debugging
4200 GLint s = 2; // single component size in bytes, UNSIGNED_SHORT -> 2 in our case
4201 GLint n = 4; // 4 components per pixel, stands for GL_RGBA
4202
4203 GLuint l = packRowLength == 0 ? width : packRowLength;
4204 const GLint &a = packAlignment;
4205
4206 // According to
4207 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4208 GLint k = (s >= a) ? n * l : a / s * (1 + (s * n * l - 1) / a);
4209 std::size_t componentCount = n * packSkipPixels + k * (packSkipRows + height);
4210 if (static_cast<GLuint>(packRowLength) < width)
4211 {
4212 componentCount += width * n * s - k;
4213 }
4214
4215 // Populate the pixels array with random dirty value
4216 constexpr GLushort kDirtyValue = 0x1234;
4217 std::vector<GLushort> pixels(componentCount, kDirtyValue);
4218 glReadPixels(x, y, width, height, GL_RGBA, type, pixels.data());
4219
4220 EXPECT_GL_NO_ERROR();
4221
4222 GLushort *pixelRowStart = pixels.data();
4223 pixelRowStart += n * packSkipPixels + k * packSkipRows;
4224
4225 std::vector<bool> modifiedPixels(componentCount, false);
4226
4227 char errorInfo[200];
4228
4229 for (GLuint y = 0; y < height; ++y)
4230 {
4231 GLushort *curPixel = pixelRowStart;
4232 for (GLuint x = 0, len = (y == height - 1) ? width : std::min(l, width); x < len; ++x)
4233 {
4234 snprintf(errorInfo, sizeof(errorInfo),
4235 "extent: {%u, %u}, coord: (%u, %u), rowLength: %d, alignment: %d, "
4236 "skipPixels: %d, skipRows: %d\n",
4237 width, height, x, y, packRowLength, packAlignment, packSkipPixels,
4238 packSkipRows);
4239 EXPECT_EQ(color.R, curPixel[0]) << errorInfo;
4240 EXPECT_EQ(color.G, curPixel[1]) << errorInfo;
4241 EXPECT_EQ(color.B, curPixel[2]) << errorInfo;
4242 EXPECT_EQ(color.A, curPixel[3]) << errorInfo;
4243
4244 std::ptrdiff_t diff = curPixel - pixels.data();
4245 modifiedPixels[diff + 0] = true;
4246 modifiedPixels[diff + 1] = true;
4247 modifiedPixels[diff + 2] = true;
4248 modifiedPixels[diff + 3] = true;
4249
4250 curPixel += n;
4251 }
4252 pixelRowStart += k;
4253 }
4254
4255 for (std::size_t i = 0; i < modifiedPixels.size(); ++i)
4256 {
4257 if (!modifiedPixels[i])
4258 {
4259 EXPECT_EQ(pixels[i], kDirtyValue);
4260 }
4261 }
4262 }
4263
4264 void testNorm16RenderAndReadPixels(GLint internalformat, GLenum format, GLenum type)
4265 {
4266 // TODO(http://anglebug.com/4089) Fails on Win Intel OpenGL driver
4267 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4268 // TODO(http://anglebug.com/4245) Fails on Win AMD OpenGL driver
4269 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
4270 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
4271
Jamie Madill50cf2be2018-06-15 09:46:57 -04004272 GLushort pixelValue = 0x6A35;
Geoff Langf607c602016-09-21 11:46:48 -04004273 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
shrekshao81ee4d22019-12-04 17:05:11 -08004274 GLColor16UI color = SliceFormatColor16UI(
4275 format, GLColor16UI(pixelValue, pixelValue, pixelValue, pixelValue));
4276 // Size of drawing viewport
4277 constexpr GLint width = 8, height = 8;
Vincent Lang25ab4512016-05-13 18:13:59 +02004278
4279 setUpProgram();
4280
4281 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
shrekshao81ee4d22019-12-04 17:05:11 -08004282 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, nullptr);
Vincent Lang25ab4512016-05-13 18:13:59 +02004283
4284 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4285 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4286 0);
4287
4288 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
Geoff Langf607c602016-09-21 11:46:48 -04004289 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
shrekshao81ee4d22019-12-04 17:05:11 -08004290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4291 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Vincent Lang25ab4512016-05-13 18:13:59 +02004292
4293 EXPECT_GL_NO_ERROR();
4294
4295 drawQuad(mProgram, "position", 0.5f);
4296
shrekshao81ee4d22019-12-04 17:05:11 -08004297 // ReadPixels against different width, height, pixel pack mode combinations to test
4298 // workaround of pixels rearrangement
4299
4300 // {x, y, width, height}
4301 std::vector<std::array<GLint, 4>> areas = {
4302 {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 2, 1}, {0, 0, 2, 2},
4303 {0, 0, 3, 2}, {0, 0, 3, 3}, {0, 0, 4, 3}, {0, 0, 4, 4},
4304
4305 {1, 3, 3, 2}, {1, 3, 3, 3}, {3, 2, 4, 3}, {3, 2, 4, 4},
4306
4307 {0, 0, 5, 6}, {2, 1, 5, 6}, {0, 0, 6, 1}, {0, 0, 7, 1},
4308 {0, 0, 7, 3}, {0, 0, 7, 8}, {1, 0, 7, 8}, {0, 0, 8, 8},
4309 };
4310
4311 // Put default settings at the last
Tibor Dusnoki4546c5c2020-01-31 15:05:35 +01004312 std::vector<GLint> paramsPackRowLength = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
4313 std::vector<GLint> paramsPackAlignment = {1, 2, 8, 4};
shrekshao81ee4d22019-12-04 17:05:11 -08004314 std::vector<std::array<GLint, 2>> paramsPackSkipPixelsAndRows = {{1, 0}, {0, 1}, {1, 1},
4315 {3, 1}, {20, 20}, {0, 0}};
4316
4317 // Restore pixel pack modes later
4318 GLint restorePackAlignment;
4319 glGetIntegerv(GL_PACK_ALIGNMENT, &restorePackAlignment);
4320 GLint restorePackRowLength;
4321 glGetIntegerv(GL_PACK_ROW_LENGTH, &restorePackRowLength);
4322 GLint restorePackSkipPixels;
4323 glGetIntegerv(GL_PACK_SKIP_PIXELS, &restorePackSkipPixels);
4324 GLint restorePackSkipRows;
4325 glGetIntegerv(GL_PACK_SKIP_ROWS, &restorePackSkipRows);
4326
4327 // Variable symbols are based on:
4328 // https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glPixelStorei.xhtml
4329 for (const auto &skipped : paramsPackSkipPixelsAndRows)
4330 {
4331 glPixelStorei(GL_PACK_SKIP_PIXELS, skipped[0]);
4332 glPixelStorei(GL_PACK_SKIP_ROWS, skipped[1]);
4333 for (GLint a : paramsPackAlignment)
4334 {
4335 glPixelStorei(GL_PACK_ALIGNMENT, a);
4336 for (GLint l : paramsPackRowLength)
4337 {
4338 glPixelStorei(GL_PACK_ROW_LENGTH, l);
4339
4340 for (const auto &area : areas)
4341 {
4342 ASSERT(area[0] + area[2] <= width);
4343 ASSERT(area[1] + area[3] <= height);
4344 testReadPixelsRGBAWithRangeAndPixelStoreMode(area[0], area[1], area[2],
4345 area[3], l, a, skipped[0],
4346 skipped[1], type, color);
4347 }
4348 }
4349 }
4350 }
4351
4352 glPixelStorei(GL_PACK_ALIGNMENT, restorePackAlignment);
4353 glPixelStorei(GL_PACK_ROW_LENGTH, restorePackRowLength);
4354 glPixelStorei(GL_PACK_SKIP_PIXELS, restorePackSkipPixels);
4355 glPixelStorei(GL_PACK_SKIP_ROWS, restorePackSkipRows);
Vincent Lang25ab4512016-05-13 18:13:59 +02004356
4357 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4358 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4359 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4360 mRenderbuffer);
4361 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4362 EXPECT_GL_NO_ERROR();
4363
4364 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4365 glClear(GL_COLOR_BUFFER_BIT);
4366
shrekshaofb1c2fe2019-11-13 11:10:39 -08004367 EXPECT_PIXEL_16UI_COLOR(
4368 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
shrekshaoe33c1582019-11-06 16:55:29 -08004369
4370 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Vincent Lang25ab4512016-05-13 18:13:59 +02004371 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4372
shrekshaoe33c1582019-11-06 16:55:29 -08004373 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4374 0);
shrekshaofb1c2fe2019-11-13 11:10:39 -08004375 EXPECT_PIXEL_16UI_COLOR(
4376 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004377
4378 ASSERT_GL_NO_ERROR();
shrekshaofb1c2fe2019-11-13 11:10:39 -08004379
4380 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Vincent Lang25ab4512016-05-13 18:13:59 +02004381 }
4382
4383 GLuint mTextures[3];
4384 GLuint mFBO;
4385 GLuint mRenderbuffer;
4386};
4387
shrekshao81ee4d22019-12-04 17:05:11 -08004388TEST_P(Texture2DNorm16TestES3, TextureNorm16R16TextureTest)
Vincent Lang25ab4512016-05-13 18:13:59 +02004389{
Vincent Lang25ab4512016-05-13 18:13:59 +02004390 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
shrekshao81ee4d22019-12-04 17:05:11 -08004391}
Vincent Lang25ab4512016-05-13 18:13:59 +02004392
shrekshao81ee4d22019-12-04 17:05:11 -08004393TEST_P(Texture2DNorm16TestES3, TextureNorm16R16SNORMTextureTest)
4394{
4395 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
4396}
4397
4398TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16TextureTest)
4399{
4400 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4401}
4402
4403TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16SNORMTextureTest)
4404{
4405 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
4406}
4407
4408TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16TextureTest)
4409{
4410 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4411 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4412
4413 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
4414}
4415
4416TEST_P(Texture2DNorm16TestES3, TextureNorm16RGB16SNORMTextureTest)
4417{
4418 // (http://anglebug.com/4215) Driver bug on some Qualcomm Adreno gpu
4419 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
4420
4421 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
4422}
4423
4424TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16TextureTest)
4425{
4426 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4427}
4428
4429TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16SNORMTextureTest)
4430{
4431 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
4432}
4433
4434TEST_P(Texture2DNorm16TestES3, TextureNorm16R16RenderTest)
4435{
4436 testNorm16RenderAndReadPixels(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
4437}
4438
4439TEST_P(Texture2DNorm16TestES3, TextureNorm16RG16RenderTest)
4440{
4441 testNorm16RenderAndReadPixels(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4442}
4443
4444TEST_P(Texture2DNorm16TestES3, TextureNorm16RGBA16RenderTest)
4445{
4446 testNorm16RenderAndReadPixels(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
Vincent Lang25ab4512016-05-13 18:13:59 +02004447}
4448
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004449class Texture2DRGTest : public Texture2DTest
4450{
4451 protected:
4452 Texture2DRGTest()
4453 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4454 {}
4455
4456 void testSetUp() override
4457 {
4458 Texture2DTest::testSetUp();
4459
4460 glActiveTexture(GL_TEXTURE0);
4461 glGenTextures(1, &mRenderableTexture);
4462 glGenTextures(1, &mTestTexture);
4463 glGenFramebuffers(1, &mFBO);
4464 glGenRenderbuffers(1, &mRenderbuffer);
4465
4466 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004467 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4468 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004469 glBindTexture(GL_TEXTURE_2D, mTestTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004470 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4471 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004472
4473 glBindTexture(GL_TEXTURE_2D, 0);
4474
4475 setUpProgram();
4476 glUseProgram(mProgram);
4477 glUniform1i(mTexture2DUniformLocation, 0);
4478
4479 ASSERT_GL_NO_ERROR();
4480 }
4481
4482 void testTearDown() override
4483 {
4484 glDeleteTextures(1, &mRenderableTexture);
4485 glDeleteTextures(1, &mTestTexture);
4486 glDeleteFramebuffers(1, &mFBO);
4487 glDeleteRenderbuffers(1, &mRenderbuffer);
4488
4489 Texture2DTest::testTearDown();
4490 }
4491
4492 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
4493 {
4494 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4495 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4496
4497 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4498 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4499 mRenderableTexture, 0);
4500
4501 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4502 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
4503
4504 EXPECT_GL_NO_ERROR();
4505 }
4506
4507 void testRGTexture(GLColor expectedColor)
4508 {
4509 drawQuad(mProgram, "position", 0.5f);
4510
4511 EXPECT_GL_NO_ERROR();
4512 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
4513 }
4514
4515 void testRGRender(GLenum internalformat, GLenum format)
4516 {
4517 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4518 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4519 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4520 mRenderbuffer);
4521 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4522 EXPECT_GL_NO_ERROR();
4523
4524 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4525 glClear(GL_COLOR_BUFFER_BIT);
4526
4527 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4528
4529 ASSERT_GL_NO_ERROR();
4530 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
4531 }
4532
4533 GLuint mRenderableTexture;
4534 GLuint mTestTexture;
4535 GLuint mFBO;
4536 GLuint mRenderbuffer;
4537};
4538
4539// Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
4540TEST_P(Texture2DRGTest, TextureRGUNormTest)
4541{
4542 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4543
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{
Cody Northrop988f7172019-09-30 15:52:37 -06005813 // TODO: Triage this failure on Vulkan: http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005814 ANGLE_SKIP_TEST_IF(IsVulkan());
5815
Jamie Madill35cd7332018-12-02 12:03:33 -05005816 constexpr char kVS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005817 "#version 300 es\n"
5818 "out vec2 texcoord;\n"
5819 "in vec4 position;\n"
5820 "void main()\n"
5821 "{\n"
5822 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
5823 " texcoord = (position.xy * 0.5) + 0.5;\n"
5824 "}\n";
5825
Jamie Madill35cd7332018-12-02 12:03:33 -05005826 constexpr char kFS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005827 "#version 300 es\n"
5828 "precision highp float;\n"
5829 "uniform highp sampler2D tex;\n"
5830 "in vec2 texcoord;\n"
5831 "out vec4 fragColor;\n"
5832 "void main()\n"
5833 "{\n"
5834 " fragColor = texture(tex, texcoord);\n"
5835 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -05005836
5837 ANGLE_GL_PROGRAM(program, kVS, kFS);
Till Rathmannc1551dc2018-08-15 17:04:49 +02005838
5839 GLSampler sampler;
5840 glBindSampler(0, sampler);
5841 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5842 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5843
5844 glActiveTexture(GL_TEXTURE0);
5845 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5846
5847 const GLsizei texWidth = getWindowWidth();
5848 const GLsizei texHeight = getWindowHeight();
5849 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
5850
5851 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5852 whiteData.data());
5853 EXPECT_GL_NO_ERROR();
5854
5855 drawQuad(program, "position", 0.5f);
5856 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
5857}
5858
Anders Leinof6cbe442019-04-18 15:32:07 +03005859// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5860// texture is output.
5861TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
5862{
Yuly Novikovd2683452019-05-23 16:11:19 -04005863 // http://anglebug.com/3478
5864 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5865
Anders Leinof6cbe442019-04-18 15:32:07 +03005866 glActiveTexture(GL_TEXTURE0);
5867 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5868 int width = getWindowWidth();
5869 int height = getWindowHeight();
5870 GLColor color = GLColor::green;
5871 std::vector<GLColor> pixels(width * height, color);
5872 GLint baseLevel = 1;
5873 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5874 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5875 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5876 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5877 GL_UNSIGNED_BYTE, pixels.data());
5878
5879 setUpProgram();
5880 glUseProgram(mProgram);
5881 glUniform1i(mTexture2DUniformLocation, 0);
5882 drawQuad(mProgram, "position", 0.5f);
5883
5884 EXPECT_GL_NO_ERROR();
5885 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5886 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5887}
5888
Anders Leino60cc7512019-05-06 09:25:27 +03005889// Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
5890// the texture is output.
5891TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
5892{
5893 // All output checks returned black, rather than the texture color.
5894 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
5895
5896 glActiveTexture(GL_TEXTURE0);
5897
5898 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5899 GLint baseLevel = 1;
5900 int width = getWindowWidth();
5901 int height = getWindowHeight();
5902 GLColor color = GLColor::green;
5903 std::vector<GLColor> pixels(width * height, color);
5904 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5905 {
5906 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
5907 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5908 EXPECT_GL_NO_ERROR();
5909 }
5910 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
5911 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5912 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5913
5914 glUseProgram(mProgram);
5915 glUniform1i(mTextureCubeUniformLocation, 0);
5916 drawQuad(mProgram, "position", 0.5f);
5917
5918 EXPECT_GL_NO_ERROR();
5919 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5920 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
5921 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
5922 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5923}
5924
Anders Leinoe4452442019-05-09 13:29:49 +03005925// This test sets up a cube map with four distincly colored MIP levels.
5926// The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
5927// the corners of the screen.
5928TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
5929{
5930 glActiveTexture(GL_TEXTURE0);
5931
5932 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5933 int width = getWindowWidth();
5934 int height = getWindowHeight();
5935 ASSERT_EQ(width, height);
5936 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
5937 for (GLint level = 0; level < 4; level++)
5938 {
5939 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5940 {
5941 int levelWidth = (2 * width) >> level;
5942 int levelHeight = (2 * height) >> level;
5943 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
5944 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
5945 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5946 EXPECT_GL_NO_ERROR();
5947 }
5948 }
5949 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5950 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5951 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
5952
5953 glUseProgram(mProgram);
5954 glUniform1i(mTextureCubeUniformLocation, 0);
5955 drawQuad(mProgram, "position", 0.5f);
5956
5957 ASSERT_GL_NO_ERROR();
5958 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
5959 EXPECT_EQ(ReadColor(0, 0).R, 0);
5960 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
5961 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
5962 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
5963}
5964
Anders Leino1b6aded2019-05-20 12:56:34 +03005965// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5966// texture is output.
5967TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
5968{
Jamie Madill29ac2742019-05-28 15:53:00 -04005969 // Fails on AMD: http://crbug.com/967796
Jamie Madill06055b52019-05-29 14:31:42 -04005970 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
Jamie Madill29ac2742019-05-28 15:53:00 -04005971
Anders Leino1b6aded2019-05-20 12:56:34 +03005972 glActiveTexture(GL_TEXTURE0);
5973 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5974 int width = getWindowWidth();
5975 int height = getWindowHeight();
5976 GLColor color = GLColor::green;
5977 std::vector<GLColor> pixels(width * height, color);
5978 GLint baseLevel = 1;
5979 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5980 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5981 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5982 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5983 GL_UNSIGNED_BYTE, pixels.data());
5984
5985 setUpProgram();
5986 glUseProgram(mProgram);
5987 glUniform1i(mTexture2DUniformLocation, 0);
5988 drawQuad(mProgram, "position", 0.5f);
5989
5990 EXPECT_GL_NO_ERROR();
5991 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5992 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5993}
5994
Anders Leino69d04932019-05-20 14:04:13 +03005995// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5996// texture is output.
5997TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
5998{
5999 glActiveTexture(GL_TEXTURE0);
6000 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
6001 int width = getWindowWidth();
6002 int height = getWindowHeight();
6003 int depth = 2;
6004 GLColor color = GLColor::green;
6005 std::vector<GLColor> pixels(width * height * depth, color);
6006 GLint baseLevel = 1;
6007 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
6008 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
6009 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
6010 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6011 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6012
6013 drawQuad(mProgram, "position", 0.5f);
6014
6015 EXPECT_GL_NO_ERROR();
6016 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6017 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6018}
6019
Anders Leino262e2822019-05-20 14:24:40 +03006020// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
6021// texture is output.
6022TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
6023{
6024 glActiveTexture(GL_TEXTURE0);
6025 glBindTexture(GL_TEXTURE_3D, mTexture3D);
6026 int width = getWindowWidth();
6027 int height = getWindowHeight();
6028 int depth = 2;
6029 GLColor color = GLColor::green;
6030 std::vector<GLColor> pixels(width * height * depth, color);
6031 GLint baseLevel = 1;
6032 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
6033 GL_UNSIGNED_BYTE, pixels.data());
6034 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
6035 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6036 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6037
6038 drawQuad(mProgram, "position", 0.5f);
6039
6040 EXPECT_GL_NO_ERROR();
6041 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
6042 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
6043}
6044
Jamie Madillfc3ec572019-11-27 21:43:22 +00006045// Test that uses glCompressedTexSubImage2D combined with a PBO
6046TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
6047{
6048 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6049 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6050 // http://anglebug.com/4115
6051 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
6052 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
6053
6054 if (getClientMajorVersion() < 3)
6055 {
6056 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
6057 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
6058 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
6059 }
6060
6061 const GLuint width = 4u;
6062 const GLuint height = 4u;
6063
6064 setWindowWidth(width);
6065 setWindowHeight(height);
6066
6067 // Setup primary Texture
6068 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6069 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6070 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6071
6072 if (getClientMajorVersion() < 3)
6073 {
6074 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6075 }
6076 else
6077 {
6078 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
6079 }
6080 ASSERT_GL_NO_ERROR();
6081
6082 // Setup PBO and fill it with a red
6083 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
6084 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
6085 ASSERT_GL_NO_ERROR();
6086
6087 // Write PBO to mTexture
6088 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
6089 width * height / 2u, nullptr);
6090 ASSERT_GL_NO_ERROR();
6091
6092 setUpProgram();
6093 // Draw using PBO updated texture
6094 glUseProgram(mProgram);
6095 glUniform1i(mTexture2DUniformLocation, 0);
6096 glBindTexture(GL_TEXTURE_2D, mTexture2D);
6097 drawQuad(mProgram, "position", 0.5f);
6098 ASSERT_GL_NO_ERROR();
6099
6100 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6101 ASSERT_GL_NO_ERROR();
6102}
6103
Cody Northrop74e816b2020-03-26 17:40:25 -06006104// Test using ETC1_RGB8 with subimage updates
6105TEST_P(ETC1CompressedTextureTest, ETC1CompressedSubImage)
6106{
6107 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6108 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6109
6110 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
6111 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
6112 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6113
6114 const GLuint width = 4u;
6115 const GLuint height = 4u;
6116
6117 setWindowWidth(width);
6118 setWindowHeight(height);
6119
6120 // Setup primary Texture
6121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6123
6124 if (getClientMajorVersion() < 3)
6125 {
6126 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6127 }
6128 else
6129 {
6130 glTexStorage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_OES, width, height);
6131 }
6132 ASSERT_GL_NO_ERROR();
6133
6134 // Populate a subimage of the texture
6135 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6136 width * height / 2u, kCompressedImageETC2);
6137 ASSERT_GL_NO_ERROR();
6138
6139 // Render and ensure we get red
6140 glUseProgram(mProgram);
6141 drawQuad(mProgram, "position", 0.5f);
6142 ASSERT_GL_NO_ERROR();
6143
6144 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6145 ASSERT_GL_NO_ERROR();
6146}
6147
Ian Elliotteba008a2020-05-05 10:46:21 -06006148// Fully-define a compressed texture and draw; then decrease MAX_LEVEL and draw; then increase
6149// MAX_LEVEL and draw. This used to cause Vulkan validation errors.
6150TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
6151{
6152 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
6153 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
6154
6155 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
6156 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_compressed_ETC1_RGB8_sub_texture"));
6157
6158 const GLuint width = 4u;
6159 const GLuint height = 4u;
6160
6161 setWindowWidth(width);
6162 setWindowHeight(height);
6163
6164 // Setup primary Texture
6165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6167
6168 if (getClientMajorVersion() < 3)
6169 {
6170 glTexStorage2DEXT(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6171 }
6172 else
6173 {
6174 glTexStorage2D(GL_TEXTURE_2D, 3, GL_ETC1_RGB8_OES, width, height);
6175 }
6176 ASSERT_GL_NO_ERROR();
6177
6178 // Populate a subimage of the texture
6179 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ETC1_RGB8_OES,
6180 width * height / 2u, kCompressedImageETC2);
6181 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, width / 2, height / 2, GL_ETC1_RGB8_OES,
6182 width * height / 2u, kCompressedImageETC2);
6183 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, width / 4, height / 4, GL_ETC1_RGB8_OES,
6184 width * height / 2u, kCompressedImageETC2);
6185 ASSERT_GL_NO_ERROR();
6186
6187 // Set MAX_LEVEL to 2 (the highest level)
6188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6189
6190 // Render and ensure we get red
6191 glUseProgram(mProgram);
6192 drawQuad(mProgram, "position", 0.5f);
6193 ASSERT_GL_NO_ERROR();
6194 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6195 ASSERT_GL_NO_ERROR();
6196
6197 // Decrease MAX_LEVEL to 0, render, and ensure we still get red
6198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
6199 drawQuad(mProgram, "position", 0.5f);
6200 ASSERT_GL_NO_ERROR();
6201 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6202 ASSERT_GL_NO_ERROR();
6203
6204 // Increase MAX_LEVEL back to 2, render, and ensure we still get red
6205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
6206 drawQuad(mProgram, "position", 0.5f);
6207 ASSERT_GL_NO_ERROR();
6208 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
6209 ASSERT_GL_NO_ERROR();
6210}
6211
Jamie Madill50cf2be2018-06-15 09:46:57 -04006212// Use this to select which configurations (e.g. which renderer, which GLES major version) these
6213// tests should be run against.
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07006214ANGLE_INSTANTIATE_TEST_ES2(Texture2DTest);
6215ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
6216ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
6217ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
6218ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
6219ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
6220ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3);
6221ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
6222ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
6223ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
6224ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
6225ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
6226ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
6227ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
6228ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
6229ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
6230ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
6231ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
6232ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
6233ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
6234ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
6235ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
6236ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
6237ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
6238ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
6239ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DRGTest);
6240ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
6241ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
6242ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
6243ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
6244ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
6245ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
6246ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
6247ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
6248ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
6249ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
Jamie Madillfc3ec572019-11-27 21:43:22 +00006250ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
Cody Northrop74e816b2020-03-26 17:40:25 -06006251ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
Jamie Madillfa05f602015-05-07 13:47:11 -04006252
Jamie Madill7ffdda92016-09-08 13:26:51 -04006253} // anonymous namespace