blob: d3f105fd76370ca75a51bcce59a3036a94e6dfb5 [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
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001451TEST_P(Texture2DTest, NegativeAPISubImage)
Jamie Madillf67115c2014-04-22 13:14:05 -04001452{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001453 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Jamie Madillf67115c2014-04-22 13:14:05 -04001454 EXPECT_GL_ERROR(GL_NO_ERROR);
1455
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001456 setUpProgram();
1457
Jamie Madill50cf2be2018-06-15 09:46:57 -04001458 const GLubyte *pixels[20] = {0};
Jamie Madillf67115c2014-04-22 13:14:05 -04001459 glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1460 EXPECT_GL_ERROR(GL_INVALID_VALUE);
Geoff Langc51642b2016-11-14 16:18:26 -05001461
Jamie Madillb8149072019-04-30 16:14:44 -04001462 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
Geoff Langc51642b2016-11-14 16:18:26 -05001463 {
1464 // Create a 1-level immutable texture.
1465 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1466
1467 // Try calling sub image on the second level.
1468 glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1469 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1470 }
Jamie Madillf67115c2014-04-22 13:14:05 -04001471}
Geoff Langc41e42d2014-04-28 10:58:16 -04001472
John Bauman18319182016-09-28 14:22:27 -07001473// Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error.
1474TEST_P(Texture2DTest, QueryBinding)
1475{
1476 glBindTexture(GL_TEXTURE_2D, 0);
1477 EXPECT_GL_ERROR(GL_NO_ERROR);
1478
1479 GLint textureBinding;
1480 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
1481 EXPECT_GL_NO_ERROR();
1482 EXPECT_EQ(0, textureBinding);
1483
1484 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding);
Jamie Madillb8149072019-04-30 16:14:44 -04001485 if (IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
1486 IsGLExtensionEnabled("GL_NV_EGL_stream_consumer_external"))
John Bauman18319182016-09-28 14:22:27 -07001487 {
1488 EXPECT_GL_NO_ERROR();
1489 EXPECT_EQ(0, textureBinding);
1490 }
1491 else
1492 {
1493 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1494 }
1495}
1496
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001497TEST_P(Texture2DTest, ZeroSizedUploads)
Geoff Langc41e42d2014-04-28 10:58:16 -04001498{
Jamie Madilld4cfa572014-07-08 10:00:32 -04001499 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Geoff Langc41e42d2014-04-28 10:58:16 -04001500 EXPECT_GL_ERROR(GL_NO_ERROR);
1501
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001502 setUpProgram();
1503
Geoff Langc41e42d2014-04-28 10:58:16 -04001504 // Use the texture first to make sure it's in video memory
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001505 glUseProgram(mProgram);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001506 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001507 drawQuad(mProgram, "position", 0.5f);
Geoff Langc41e42d2014-04-28 10:58:16 -04001508
Jamie Madill50cf2be2018-06-15 09:46:57 -04001509 const GLubyte *pixel[4] = {0};
Geoff Langc41e42d2014-04-28 10:58:16 -04001510
1511 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1512 EXPECT_GL_NO_ERROR();
1513
1514 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1515 EXPECT_GL_NO_ERROR();
1516
1517 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1518 EXPECT_GL_NO_ERROR();
1519}
Jamie Madilld4cfa572014-07-08 10:00:32 -04001520
1521// Test drawing with two texture types, to trigger an ANGLE bug in validation
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001522TEST_P(TextureCubeTest, CubeMapBug)
Jamie Madilld4cfa572014-07-08 10:00:32 -04001523{
1524 glActiveTexture(GL_TEXTURE0);
1525 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1526 glActiveTexture(GL_TEXTURE1);
1527 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1528 EXPECT_GL_ERROR(GL_NO_ERROR);
1529
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001530 glUseProgram(mProgram);
1531 glUniform1i(mTexture2DUniformLocation, 0);
1532 glUniform1i(mTextureCubeUniformLocation, 1);
1533 drawQuad(mProgram, "position", 0.5f);
Jamie Madilld4cfa572014-07-08 10:00:32 -04001534 EXPECT_GL_NO_ERROR();
1535}
Jamie Madill9aca0592014-10-06 16:26:59 -04001536
Olli Etuaho53a2da12016-01-11 15:43:32 +02001537// Test drawing with two texture types accessed from the same shader and check that the result of
1538// drawing is correct.
1539TEST_P(TextureCubeTest, CubeMapDraw)
1540{
1541 GLubyte texData[4];
1542 texData[0] = 0;
1543 texData[1] = 60;
1544 texData[2] = 0;
1545 texData[3] = 255;
1546
1547 glActiveTexture(GL_TEXTURE0);
1548 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1549 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1550
1551 glActiveTexture(GL_TEXTURE1);
1552 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
1553 texData[1] = 120;
1554 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1555 texData);
1556 EXPECT_GL_ERROR(GL_NO_ERROR);
1557
1558 glUseProgram(mProgram);
1559 glUniform1i(mTexture2DUniformLocation, 0);
1560 glUniform1i(mTextureCubeUniformLocation, 1);
1561 drawQuad(mProgram, "position", 0.5f);
1562 EXPECT_GL_NO_ERROR();
1563
1564 int px = getWindowWidth() - 1;
1565 int py = 0;
1566 EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2);
1567}
1568
Olli Etuaho4644a202016-01-12 15:12:53 +02001569TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter)
1570{
1571 glActiveTexture(GL_TEXTURE0);
1572 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1573 GLubyte texData[4];
1574 texData[0] = 0;
1575 texData[1] = 128;
1576 texData[2] = 0;
1577 texData[3] = 255;
1578 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData);
1579 glUseProgram(mProgram);
1580 glUniform1i(mTexture2DUniformLocation, 0);
1581 drawQuad(mProgram, "position", 0.5f);
1582 EXPECT_GL_NO_ERROR();
1583
1584 EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2);
1585}
1586
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001587// Test drawing with two textures passed to the shader in a sampler array.
1588TEST_P(SamplerArrayTest, SamplerArrayDraw)
1589{
1590 testSamplerArrayDraw();
1591}
1592
1593// Test drawing with two textures passed to the shader in a sampler array which is passed to a
1594// user-defined function in the shader.
1595TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter)
1596{
Shahbaz Youssefi0864a7a2018-11-07 15:50:15 -05001597 // TODO: Diagnose and fix. http://anglebug.com/2955
1598 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1599
Olli Etuaho2173db3d2016-01-12 13:55:14 +02001600 testSamplerArrayDraw();
1601}
1602
Jamie Madill9aca0592014-10-06 16:26:59 -04001603// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001604TEST_P(Texture2DTestWithDrawScale, MipmapsTwice)
Jamie Madill9aca0592014-10-06 16:26:59 -04001605{
1606 int px = getWindowWidth() / 2;
1607 int py = getWindowHeight() / 2;
1608
1609 glActiveTexture(GL_TEXTURE0);
1610 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1611
Olli Etuahoa314b612016-03-10 16:43:00 +02001612 std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001613
Olli Etuahoa314b612016-03-10 16:43:00 +02001614 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1617 glGenerateMipmap(GL_TEXTURE_2D);
1618
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001619 glUseProgram(mProgram);
Jamie Madill9aca0592014-10-06 16:26:59 -04001620 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001621 glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f);
1622 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001623 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001624 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
Jamie Madill9aca0592014-10-06 16:26:59 -04001625
Olli Etuahoa314b612016-03-10 16:43:00 +02001626 std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue);
Jamie Madill9aca0592014-10-06 16:26:59 -04001627
Olli Etuahoa314b612016-03-10 16:43:00 +02001628 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1629 pixelsBlue.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001630 glGenerateMipmap(GL_TEXTURE_2D);
1631
Olli Etuahoa314b612016-03-10 16:43:00 +02001632 std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001633
Olli Etuahoa314b612016-03-10 16:43:00 +02001634 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1635 pixelsGreen.data());
Jamie Madill9aca0592014-10-06 16:26:59 -04001636 glGenerateMipmap(GL_TEXTURE_2D);
1637
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001638 drawQuad(mProgram, "position", 0.5f);
Jamie Madill9aca0592014-10-06 16:26:59 -04001639
1640 EXPECT_GL_NO_ERROR();
Olli Etuahoa314b612016-03-10 16:43:00 +02001641 EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
Jamie Madill9aca0592014-10-06 16:26:59 -04001642}
Jamie Madillf8fccb32014-11-12 15:05:26 -05001643
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001644// Test creating a FBO with a cube map render target, to test an ANGLE bug
1645// https://code.google.com/p/angleproject/issues/detail?id=849
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001646TEST_P(TextureCubeTest, CubeMapFBO)
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001647{
Michael Spangd8506c72019-01-29 15:35:09 -05001648 // http://anglebug.com/3145
1649 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1650
Shahbaz Youssefi0c128e12019-03-25 23:50:14 -04001651 // http://anglebug.com/2822
1652 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1653
Jamie Madill3f3b3582018-09-14 10:38:44 -04001654 GLFramebuffer fbo;
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001655 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1656
1657 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
Jamie Madill50cf2be2018-06-15 09:46:57 -04001658 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1659 mTextureCube, 0);
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001660
Corentin Wallez322653b2015-06-17 18:33:56 +02001661 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001662 EXPECT_GL_NO_ERROR();
Jamie Madill3f3b3582018-09-14 10:38:44 -04001663
1664 // Test clearing the six mip faces individually.
1665 std::array<GLColor, 6> faceColors = {{GLColor::red, GLColor::green, GLColor::blue,
1666 GLColor::yellow, GLColor::cyan, GLColor::magenta}};
1667
1668 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1669 {
1670 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1671 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1672
1673 Vector4 clearColorF = faceColors[faceIndex].toNormalizedVector();
1674 glClearColor(clearColorF.x(), clearColorF.y(), clearColorF.z(), clearColorF.w());
1675 glClear(GL_COLOR_BUFFER_BIT);
1676
1677 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex]);
1678 }
1679
1680 // Iterate the faces again to make sure the colors haven't changed.
1681 for (size_t faceIndex = 0; faceIndex < 6; ++faceIndex)
1682 {
1683 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1684 GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, mTextureCube, 0);
1685 EXPECT_PIXEL_COLOR_EQ(0, 0, faceColors[faceIndex])
1686 << "face color " << faceIndex << " shouldn't change";
1687 }
1688}
1689
1690// Tests clearing a cube map with a scissor enabled.
1691TEST_P(TextureCubeTest, CubeMapFBOScissoredClear)
1692{
1693 // TODO(jie.a.chen): Diagnose and fix. http://anglebug.com/2822
1694 ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
1695
Michael Spangd8506c72019-01-29 15:35:09 -05001696 // http://anglebug.com/3145
1697 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1698
Jamie Madill3f3b3582018-09-14 10:38:44 -04001699 constexpr size_t kSize = 16;
1700
1701 GLFramebuffer fbo;
1702 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1703 glViewport(0, 0, kSize, kSize);
1704
1705 GLTexture texcube;
1706 glBindTexture(GL_TEXTURE_CUBE_MAP, texcube);
1707 for (GLenum face = 0; face < 6; face++)
1708 {
1709 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
1710 GL_UNSIGNED_BYTE, nullptr);
1711 }
1712 ASSERT_GL_NO_ERROR();
1713
1714 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
1715 texcube, 0);
1716
1717 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1718 ASSERT_GL_NO_ERROR();
1719
1720 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1721 glClear(GL_COLOR_BUFFER_BIT);
1722 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1723
1724 glEnable(GL_SCISSOR_TEST);
1725 glScissor(kSize / 2, 0, kSize / 2, kSize);
1726 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1727 glClear(GL_COLOR_BUFFER_BIT);
1728
1729 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1730 EXPECT_PIXEL_COLOR_EQ(kSize / 2 + 1, 0, GLColor::green);
1731
1732 ASSERT_GL_NO_ERROR();
Jamie Madilleb32a2e2014-12-10 14:27:53 -05001733}
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001734
Jamie Madill50cf2be2018-06-15 09:46:57 -04001735// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a
1736// default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001737TEST_P(Texture2DTest, TexStorage)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001738{
Jamie Madillb8149072019-04-30 16:14:44 -04001739 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1740 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -04001741
Jamie Madill50cf2be2018-06-15 09:46:57 -04001742 int width = getWindowWidth();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001743 int height = getWindowHeight();
1744
1745 GLuint tex2D;
1746 glGenTextures(1, &tex2D);
1747 glActiveTexture(GL_TEXTURE0);
1748 glBindTexture(GL_TEXTURE_2D, tex2D);
1749
1750 // Fill with red
1751 std::vector<GLubyte> pixels(3 * 16 * 16);
1752 for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
1753 {
1754 pixels[pixelId * 3 + 0] = 255;
1755 pixels[pixelId * 3 + 1] = 0;
1756 pixels[pixelId * 3 + 2] = 0;
1757 }
1758
1759 // ANGLE internally uses RGBA as the DirectX format for RGB images
Jamie Madill50cf2be2018-06-15 09:46:57 -04001760 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1761 // 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 -04001762 if (getClientMajorVersion() >= 3)
1763 {
1764 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1765 }
1766 else
1767 {
1768 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
1769 }
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001770
1771 // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched.
1772 // glTexSubImage2D should take into account that the image is dirty.
1773 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
1774 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1775 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1776
Olli Etuahoa1c917f2016-04-06 13:50:03 +03001777 setUpProgram();
1778
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001779 glUseProgram(mProgram);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001780 glUniform1i(mTexture2DUniformLocation, 0);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001781 drawQuad(mProgram, "position", 0.5f);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001782 glDeleteTextures(1, &tex2D);
1783 EXPECT_GL_NO_ERROR();
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001784 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
Geoff Langfbfa47c2015-03-31 11:26:00 -04001785
1786 // Validate that the region of the texture without data has an alpha of 1.0
Jamie Madill05b35b22017-10-03 09:01:44 -04001787 angle::GLColor pixel = ReadColor(3 * width / 4, 3 * height / 4);
1788 EXPECT_EQ(255, pixel.A);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001789}
1790
Jamie Madill50cf2be2018-06-15 09:46:57 -04001791// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has
1792// initialized the image with a default color.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001793TEST_P(Texture2DTest, TexStorageWithPBO)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001794{
Jamie Madillfc3ec572019-11-27 21:43:22 +00001795 // http://anglebug.com/4126
1796 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
1797
1798 if (getClientMajorVersion() < 3)
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001799 {
Jamie Madillfc3ec572019-11-27 21:43:22 +00001800 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1801 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001802 }
Jamie Madillfc3ec572019-11-27 21:43:22 +00001803
1804 const int width = getWindowWidth();
1805 const int height = getWindowHeight();
1806 const size_t pixelCount = width * height;
1807 const int componentCount = 3;
1808
1809 GLuint tex2D;
1810 glGenTextures(1, &tex2D);
1811 glActiveTexture(GL_TEXTURE0);
1812 glBindTexture(GL_TEXTURE_2D, tex2D);
1813
1814 // Fill with red
1815 std::vector<GLubyte> pixels(componentCount * pixelCount);
1816 for (size_t pixelId = 0; pixelId < pixelCount; ++pixelId)
1817 {
1818 pixels[pixelId * componentCount + 0] = 255;
1819 pixels[pixelId * componentCount + 1] = 0;
1820 pixels[pixelId * componentCount + 2] = 0;
1821 }
1822
1823 // Read 16x16 region from red backbuffer to PBO
1824 GLuint pbo;
1825 glGenBuffers(1, &pbo);
1826 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1827 glBufferData(GL_PIXEL_UNPACK_BUFFER, componentCount * pixelCount, pixels.data(),
1828 GL_STATIC_DRAW);
1829
1830 // ANGLE internally uses RGBA as the DirectX format for RGB images
1831 // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent
1832 // alpha color. The data is kept in a CPU-side image and the image is marked as dirty.
1833 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
1834
1835 // Initializes the color of the upper-left quadrant of pixels, leaves the other pixels
1836 // untouched. glTexSubImage2D should take into account that the image is dirty.
1837 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RGB, GL_UNSIGNED_BYTE,
1838 nullptr);
1839 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1840 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1841
1842 setUpProgram();
1843
1844 glUseProgram(mProgram);
1845 glUniform1i(mTexture2DUniformLocation, 0);
1846 drawQuad(mProgram, "position", 0.5f);
1847 glDeleteTextures(1, &tex2D);
1848 glDeleteBuffers(1, &pbo);
1849 EXPECT_GL_NO_ERROR();
1850 EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255);
1851 EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255);
1852}
1853
1854// Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO
1855// and drawing with the texture
1856// Pseudo code for the follow test:
1857// 1. Upload PBO to mTexture2D
1858// 2. Delete PBO
1859// 3. Draw with otherTexture (x5)
1860// 4. Draw with mTexture2D
1861// 5. Validate color output
1862TEST_P(Texture2DTest, PBOWithMultipleDraws)
1863{
1864 if (getClientMajorVersion() < 3)
1865 {
1866 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
1867 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
1868 }
1869
1870 const GLuint width = getWindowWidth();
1871 const GLuint height = getWindowHeight();
1872 const GLuint windowPixelCount = width * height;
1873 std::vector<GLColor> pixelsRed(windowPixelCount, GLColor::red);
1874 std::vector<GLColor> pixelsGreen(windowPixelCount, GLColor::green);
1875
1876 // Create secondary draw that does not use mTexture
1877 const char *vertexShaderSource = getVertexShaderSource();
1878 const char *fragmentShaderSource = getFragmentShaderSource();
1879 ANGLE_GL_PROGRAM(otherProgram, vertexShaderSource, fragmentShaderSource);
1880
1881 GLint uniformLoc = glGetUniformLocation(otherProgram, getTextureUniformName());
1882 ASSERT_NE(-1, uniformLoc);
1883 glUseProgram(0);
1884
1885 // Create secondary Texture to draw with
1886 GLTexture otherTexture;
1887 glActiveTexture(GL_TEXTURE0);
1888 glBindTexture(GL_TEXTURE_2D, otherTexture);
1889 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1890 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1891 pixelsRed.data());
1892 ASSERT_GL_NO_ERROR();
1893
1894 // Setup primary Texture
1895 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1896 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1898 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
1899 ASSERT_GL_NO_ERROR();
1900
1901 // Setup PBO
1902 GLuint pbo = 0;
1903 glGenBuffers(1, &pbo);
1904 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
1905 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
1906 GL_STATIC_DRAW);
1907 ASSERT_GL_NO_ERROR();
1908
1909 // Write PBO to mTexture
1910 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1911 ASSERT_GL_NO_ERROR();
1912 // Delete PBO as ANGLE should be properly handling refcount of this buffer
1913 glDeleteBuffers(1, &pbo);
1914 pixelsGreen.clear();
1915
1916 // Do 5 draws not involving primary texture that the PBO updated
1917 glUseProgram(otherProgram);
1918 glUniform1i(uniformLoc, 0);
1919 glBindTexture(GL_TEXTURE_2D, otherTexture);
1920 drawQuad(otherProgram, "position", 0.5f);
1921 glBindTexture(GL_TEXTURE_2D, 0);
1922 glUseProgram(0);
1923
1924 glUseProgram(otherProgram);
1925 glUniform1i(uniformLoc, 0);
1926 glBindTexture(GL_TEXTURE_2D, otherTexture);
1927 drawQuad(otherProgram, "position", 0.5f);
1928 glBindTexture(GL_TEXTURE_2D, 0);
1929 glUseProgram(0);
1930
1931 glUseProgram(otherProgram);
1932 glUniform1i(uniformLoc, 0);
1933 glBindTexture(GL_TEXTURE_2D, otherTexture);
1934 drawQuad(otherProgram, "position", 0.5f);
1935 glBindTexture(GL_TEXTURE_2D, 0);
1936 glUseProgram(0);
1937
1938 glUseProgram(otherProgram);
1939 glUniform1i(uniformLoc, 0);
1940 glBindTexture(GL_TEXTURE_2D, otherTexture);
1941 drawQuad(otherProgram, "position", 0.5f);
1942 glBindTexture(GL_TEXTURE_2D, 0);
1943 glUseProgram(0);
1944 ASSERT_GL_NO_ERROR();
1945
1946 std::vector<GLColor> output(windowPixelCount, GLColor::black);
1947 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1948 output.data());
1949 EXPECT_EQ(pixelsRed, output);
1950
1951 setUpProgram();
1952 // Draw using PBO updated texture
1953 glUseProgram(mProgram);
1954 glUniform1i(mTexture2DUniformLocation, 0);
1955 glBindTexture(GL_TEXTURE_2D, mTexture2D);
1956 drawQuad(mProgram, "position", 0.5f);
1957 ASSERT_GL_NO_ERROR();
1958
1959 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
1960 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1961 actual.data());
1962 // Value should be green as it was updated during PBO transfer to mTexture
1963 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
1964 EXPECT_EQ(expected, actual);
Gregoire Payen de La Garanderie88fe1ad2015-01-19 15:09:26 +00001965}
Jamie Madillbc393df2015-01-29 13:46:07 -05001966
Mohan Maiya6caa2652019-09-11 08:06:13 -07001967// Tests CopySubImage for float formats
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001968TEST_P(Texture2DTest, CopySubImageFloat_R_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001969{
1970 testFloatCopySubImage(1, 1);
1971}
1972
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001973TEST_P(Texture2DTest, CopySubImageFloat_RG_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001974{
1975 testFloatCopySubImage(2, 1);
1976}
1977
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001978TEST_P(Texture2DTest, CopySubImageFloat_RG_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001979{
1980 testFloatCopySubImage(2, 2);
1981}
1982
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001983TEST_P(Texture2DTest, CopySubImageFloat_RGB_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05001984{
1985 testFloatCopySubImage(3, 1);
1986}
1987
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001988TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05001989{
1990 testFloatCopySubImage(3, 2);
1991}
1992
Olli Etuaho4a8329f2016-01-11 17:12:57 +02001993TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05001994{
Yunchao He9550c602018-02-13 14:47:05 +08001995 // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346)
Mohan Maiya6caa2652019-09-11 08:06:13 -07001996 ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
Corentin Wallez9e3c6152016-03-29 21:58:33 -04001997
Yunchao He9550c602018-02-13 14:47:05 +08001998 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
1999 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002000
Jamie Madillbc393df2015-01-29 13:46:07 -05002001 testFloatCopySubImage(3, 3);
2002}
2003
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002004TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R)
Jamie Madillbc393df2015-01-29 13:46:07 -05002005{
2006 testFloatCopySubImage(4, 1);
2007}
2008
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002009TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG)
Jamie Madillbc393df2015-01-29 13:46:07 -05002010{
2011 testFloatCopySubImage(4, 2);
2012}
2013
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002014TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
Jamie Madillbc393df2015-01-29 13:46:07 -05002015{
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(4, 3);
2020}
2021
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002022TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
Jamie Madillbc393df2015-01-29 13:46:07 -05002023{
Yunchao He9550c602018-02-13 14:47:05 +08002024 // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
2025 ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
Austin Kinrossd544cc92016-01-11 15:26:42 -08002026
Jamie Madillbc393df2015-01-29 13:46:07 -05002027 testFloatCopySubImage(4, 4);
2028}
Austin Kinross07285142015-03-26 11:36:16 -07002029
Jamie Madill50cf2be2018-06-15 09:46:57 -04002030// Port of
2031// https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html
2032// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly
2033// handles GL_ALPHA
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002034TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
Austin Kinross07285142015-03-26 11:36:16 -07002035{
2036 const int npotTexSize = 5;
Jamie Madill50cf2be2018-06-15 09:46:57 -04002037 const int potTexSize = 4; // Should be less than npotTexSize
Austin Kinross07285142015-03-26 11:36:16 -07002038 GLuint tex2D;
2039
Jamie Madillb8149072019-04-30 16:14:44 -04002040 if (IsGLExtensionEnabled("GL_OES_texture_npot"))
Austin Kinross07285142015-03-26 11:36:16 -07002041 {
2042 // This test isn't applicable if texture_npot is enabled
2043 return;
2044 }
2045
Olli Etuahoa1c917f2016-04-06 13:50:03 +03002046 setUpProgram();
2047
Austin Kinross07285142015-03-26 11:36:16 -07002048 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2049
Austin Kinross5faa15b2016-01-11 13:32:48 -08002050 // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1.
2051 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2052
Austin Kinross07285142015-03-26 11:36:16 -07002053 glActiveTexture(GL_TEXTURE0);
2054 glGenTextures(1, &tex2D);
2055 glBindTexture(GL_TEXTURE_2D, tex2D);
2056
Till Rathmannc1551dc2018-08-15 17:04:49 +02002057 const std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize, 64);
Austin Kinross07285142015-03-26 11:36:16 -07002058
2059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2061
2062 // Check that an NPOT texture not on level 0 generates INVALID_VALUE
Jamie Madill50cf2be2018-06-15 09:46:57 -04002063 glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2064 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002065 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2066
2067 // Check that an NPOT texture on level 0 succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002068 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA,
2069 GL_UNSIGNED_BYTE, pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002070 EXPECT_GL_NO_ERROR();
2071
2072 // Check that generateMipmap fails on NPOT
2073 glGenerateMipmap(GL_TEXTURE_2D);
2074 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
2075
2076 // Check that nothing is drawn if filtering is not correct for NPOT
2077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2080 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2081 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002082 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002083 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2084
2085 // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
2086 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2087 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2088 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
2089 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002090 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002091 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255);
2092
2093 // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw
2094 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2095 glClear(GL_COLOR_BUFFER_BIT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002096 drawQuad(mProgram, "position", 1.0f);
Austin Kinross07285142015-03-26 11:36:16 -07002097 EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64);
2098
2099 // Check that glTexImage2D for POT texture succeeds
Jamie Madill50cf2be2018-06-15 09:46:57 -04002100 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE,
2101 pixels.data());
Austin Kinross07285142015-03-26 11:36:16 -07002102 EXPECT_GL_NO_ERROR();
2103
2104 // Check that generateMipmap for an POT texture succeeds
2105 glGenerateMipmap(GL_TEXTURE_2D);
2106 EXPECT_GL_NO_ERROR();
2107
2108 // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw
2109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
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 EXPECT_GL_NO_ERROR();
2117}
Jamie Madillfa05f602015-05-07 13:47:11 -04002118
Austin Kinross08528e12015-10-07 16:24:40 -07002119// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions.
2120// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002121TEST_P(Texture2DTest, NPOTSubImageParameters)
Austin Kinross08528e12015-10-07 16:24:40 -07002122{
2123 glActiveTexture(GL_TEXTURE0);
2124 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2125
2126 // Create an 8x8 (i.e. power-of-two) texture.
2127 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2130 glGenerateMipmap(GL_TEXTURE_2D);
2131
2132 // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture.
2133 // This should always work, even if GL_OES_texture_npot isn't active.
Geoff Langfb052642017-10-24 13:42:09 -04002134 std::array<GLColor, 3 * 3> data;
2135 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
Austin Kinross08528e12015-10-07 16:24:40 -07002136
2137 EXPECT_GL_NO_ERROR();
2138}
2139
Geoff Lang3702d8c2019-04-08 13:44:06 -04002140// Regression test for http://crbug.com/949985 to make sure dirty bits are propagated up from
2141// TextureImpl and the texture is synced before being used in a draw call.
2142TEST_P(Texture2DTestES3, TextureImplPropogatesDirtyBits)
2143{
2144 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
Yuly Novikove6b23e42019-04-10 17:19:15 -04002145 // Flaky hangs on Win10 AMD RX 550 GL. http://anglebug.com/3371
2146 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
Yuly Novikovbd4ff472019-07-19 22:08:17 +00002147 // D3D Debug device reports an error. http://anglebug.com/3501
2148 ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D11());
Cody Northrop988f7172019-09-30 15:52:37 -06002149 // TODO(cnorthrop): Needs triage on Vulkan backend. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06002150 ANGLE_SKIP_TEST_IF(IsVulkan());
Geoff Lang3702d8c2019-04-08 13:44:06 -04002151
2152 // The workaround in the GL backend required to trigger this bug generates driver warning
2153 // messages.
2154 ScopedIgnorePlatformMessages ignoreMessages;
2155
2156 setUpProgram();
2157 glUseProgram(mProgram);
2158 glActiveTexture(GL_TEXTURE0 + mTexture2DUniformLocation);
2159
2160 GLTexture dest;
2161 glBindTexture(GL_TEXTURE_2D, dest);
2162
2163 GLTexture source;
2164 glBindTexture(GL_TEXTURE_2D, source);
2165
2166 // Put data in mip 0 and 1
2167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2168 GLColor::red.data());
2169 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2170 GLColor::green.data());
2171
2172 // Disable mipmapping so source is complete
2173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2175
2176 // Force the dirty bits to be synchronized in source
2177 drawQuad(mProgram, "position", 1.0f);
2178
2179 // Copy from mip 1 of the source. In the GL backend this internally sets the base level to mip
2180 // 1 and sets a dirty bit.
2181 glCopyTextureCHROMIUM(source, 1, GL_TEXTURE_2D, dest, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE,
2182 GL_FALSE, GL_FALSE);
2183
2184 // Draw again, assertions are generated if the texture has internal dirty bits at draw time
2185 drawQuad(mProgram, "position", 1.0f);
2186}
2187
Geoff Lang6f691fb2019-04-25 11:01:52 -04002188// This test case changes the base level of a texture that's attached to a framebuffer, clears every
2189// level to green, and then samples the texture when rendering. Test is taken from
2190// https://www.khronos.org/registry/webgl/sdk/tests/conformance2/rendering/framebuffer-texture-changing-base-level.html
2191TEST_P(Texture2DTestES3, FramebufferTextureChangingBaselevel)
2192{
2193 // TODO(geofflang): Investigate on D3D11. http://anglebug.com/2291
2194 ANGLE_SKIP_TEST_IF(IsD3D11());
2195
Cody Northropd192e932019-09-27 10:27:10 -06002196 // TODO(cnorthrop): Failing on Vulkan/Windows/AMD. http://anglebug.com/3996
2197 ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
Cody Northropcb16fb52019-08-29 16:53:55 -06002198
Geoff Lang6f691fb2019-04-25 11:01:52 -04002199 setUpProgram();
2200
2201 constexpr GLint width = 8;
2202 constexpr GLint height = 4;
2203
2204 GLTexture texture;
2205 glBindTexture(GL_TEXTURE_2D, texture);
2206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2208 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2209 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2210
2211 // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
2212 GLint level = 0;
2213 GLint levelW = width;
2214 GLint levelH = height;
2215 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2216 nullptr);
2217 while (levelW > 1 || levelH > 1)
2218 {
2219 ++level;
2220 levelW = static_cast<GLint>(std::max(1.0, std::floor(width / std::pow(2, level))));
2221 levelH = static_cast<GLint>(std::max(1.0, std::floor(height / std::pow(2, level))));
2222 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2223 nullptr);
2224 }
2225
2226 // Clear each level of the texture using an FBO. Change the base level to match the level used
2227 // for the FBO on each iteration.
2228 GLFramebuffer fbo;
2229 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2230 level = 0;
2231 levelW = width;
2232 levelH = height;
2233 while (levelW > 1 || levelH > 1)
2234 {
2235 levelW = static_cast<GLint>(std::floor(width / std::pow(2, level)));
2236 levelH = static_cast<GLint>(std::floor(height / std::pow(2, level)));
2237
2238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
2239 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level);
2240
2241 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2242 EXPECT_GL_NO_ERROR();
2243
2244 glClearColor(0, 1, 0, 1);
2245 glClear(GL_COLOR_BUFFER_BIT);
2246
2247 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2248
2249 ++level;
2250 }
2251
2252 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2253 glViewport(0, 0, 16, 16);
2254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2255
2256 drawQuad(mProgram, "position", 0.5f);
2257
2258 EXPECT_GL_NO_ERROR();
2259 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2260}
2261
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002262// Test to check that texture completeness is determined correctly when the texture base level is
2263// greater than 0, and also that level 0 is not sampled when base level is greater than 0.
2264TEST_P(Texture2DTestES3, DrawWithBaseLevel1)
2265{
2266 glActiveTexture(GL_TEXTURE0);
2267 glBindTexture(GL_TEXTURE_2D, mTexture2D);
Olli Etuahoa314b612016-03-10 16:43:00 +02002268
2269 std::vector<GLColor> texDataRed(4u * 4u, GLColor::red);
2270 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2271 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2272 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2273 texDataGreen.data());
2274 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2275 texDataGreen.data());
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2277 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2278 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2279
2280 EXPECT_GL_NO_ERROR();
2281
2282 drawQuad(mProgram, "position", 0.5f);
2283
Olli Etuahoa314b612016-03-10 16:43:00 +02002284 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2285}
2286
2287// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2288// have images defined.
2289TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined)
2290{
Yunchao He9550c602018-02-13 14:47:05 +08002291 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2292 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2293
Olli Etuahoa314b612016-03-10 16:43:00 +02002294 glActiveTexture(GL_TEXTURE0);
2295 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2296 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2297 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2298 texDataGreen.data());
2299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2303
2304 EXPECT_GL_NO_ERROR();
2305
2306 drawQuad(mProgram, "position", 0.5f);
2307
2308 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2309}
2310
Olli Etuahoe8528d82016-05-16 17:50:52 +03002311// Test that drawing works correctly when level 0 is undefined and base level is 1.
2312TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined)
2313{
Yunchao He9550c602018-02-13 14:47:05 +08002314 // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array.
2315 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
2316
Olli Etuahoe8528d82016-05-16 17:50:52 +03002317 glActiveTexture(GL_TEXTURE0);
2318 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2319 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2320 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2321 texDataGreen.data());
2322 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2323 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2324 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2325 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2326
2327 EXPECT_GL_NO_ERROR();
2328
2329 // Texture is incomplete.
2330 drawQuad(mProgram, "position", 0.5f);
2331 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2332
2333 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2334 texDataGreen.data());
2335
2336 // Texture is now complete.
2337 drawQuad(mProgram, "position", 0.5f);
2338 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2339}
2340
Olli Etuahoa314b612016-03-10 16:43:00 +02002341// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2342// dimensions that don't fit the images inside the range.
2343// GLES 3.0.4 section 3.8.13 Texture completeness
2344TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2345{
Olli Etuahoa314b612016-03-10 16:43:00 +02002346 glActiveTexture(GL_TEXTURE0);
2347 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2348 std::vector<GLColor> texDataRed(8u * 8u, GLColor::red);
2349 std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green);
2350 std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan);
2351
2352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2354
2355 // Two levels that are initially unused.
2356 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data());
2357 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2358 texDataCyan.data());
2359
2360 // One level that is used - only this level should affect completeness.
2361 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2362 texDataGreen.data());
2363
2364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2366
2367 EXPECT_GL_NO_ERROR();
2368
2369 drawQuad(mProgram, "position", 0.5f);
2370
2371 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2372
Yunchao He2f23f352018-02-11 22:11:37 +08002373 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002374
2375 // Switch the level that is being used to the cyan level 2.
2376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2378
2379 EXPECT_GL_NO_ERROR();
2380
2381 drawQuad(mProgram, "position", 0.5f);
2382
2383 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2384}
2385
2386// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2387// have images defined.
2388TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined)
2389{
Olli Etuahoa314b612016-03-10 16:43:00 +02002390 glActiveTexture(GL_TEXTURE0);
2391 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2392 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2393 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2394 texDataGreen.data());
2395 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2396 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2397 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2398 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2399
2400 EXPECT_GL_NO_ERROR();
2401
2402 drawQuad(mProgram, "position", 0.5f);
2403
2404 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2405}
2406
2407// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2408// dimensions that don't fit the images inside the range.
2409// GLES 3.0.4 section 3.8.13 Texture completeness
2410TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2411{
Yuly Novikovc5da7992019-06-27 12:57:13 -04002412 // Crashes on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/2782
2413 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
2414
Olli Etuahoa314b612016-03-10 16:43:00 +02002415 glActiveTexture(GL_TEXTURE0);
2416 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2417 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2418 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2419 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2420
2421 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2422 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2423
2424 // Two levels that are initially unused.
2425 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2426 texDataRed.data());
2427 glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2428 texDataCyan.data());
2429
2430 // One level that is used - only this level should affect completeness.
2431 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2432 texDataGreen.data());
2433
2434 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1);
2435 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2436
2437 EXPECT_GL_NO_ERROR();
2438
2439 drawQuad(mProgram, "position", 0.5f);
2440
2441 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2442
Yunchao He2f23f352018-02-11 22:11:37 +08002443 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Olli Etuahoa314b612016-03-10 16:43:00 +02002444
2445 // Switch the level that is being used to the cyan level 2.
2446 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2);
2447 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2);
2448
2449 EXPECT_GL_NO_ERROR();
2450
2451 drawQuad(mProgram, "position", 0.5f);
2452
2453 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2454}
2455
2456// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not
2457// have images defined.
2458TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined)
2459{
Olli Etuahoa314b612016-03-10 16:43:00 +02002460 glActiveTexture(GL_TEXTURE0);
2461 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
2462 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2463 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2464 texDataGreen.data());
2465 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2466 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2467 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2468 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2469
2470 EXPECT_GL_NO_ERROR();
2471
2472 drawQuad(mProgram, "position", 0.5f);
2473
2474 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2475}
2476
2477// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have
2478// dimensions that don't fit the images inside the range.
2479// GLES 3.0.4 section 3.8.13 Texture completeness
2480TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions)
2481{
Corentin Wallez566c2e32019-08-28 18:37:58 +02002482 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2483 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2484
Olli Etuahoa314b612016-03-10 16:43:00 +02002485 glActiveTexture(GL_TEXTURE0);
2486 glBindTexture(GL_TEXTURE_3D, m2DArrayTexture);
2487 std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red);
2488 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2489 std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan);
2490
2491 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2492 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2493
2494 // Two levels that are initially unused.
2495 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2496 texDataRed.data());
2497 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2498 texDataCyan.data());
2499
2500 // One level that is used - only this level should affect completeness.
2501 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2502 texDataGreen.data());
2503
2504 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
2505 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1);
2506
2507 EXPECT_GL_NO_ERROR();
2508
2509 drawQuad(mProgram, "position", 0.5f);
2510
2511 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2512
Yunchao He2f23f352018-02-11 22:11:37 +08002513 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
2514
Olli Etuahoa314b612016-03-10 16:43:00 +02002515 // Switch the level that is being used to the cyan level 2.
2516 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2);
2517 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
2518
2519 EXPECT_GL_NO_ERROR();
2520
2521 drawQuad(mProgram, "position", 0.5f);
2522
2523 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2524}
2525
2526// Test that texture completeness is updated if texture max level changes.
2527// GLES 3.0.4 section 3.8.13 Texture completeness
2528TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)
2529{
Olli Etuahoa314b612016-03-10 16:43:00 +02002530 glActiveTexture(GL_TEXTURE0);
2531 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2532 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2533
2534 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2535 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2536
2537 // A level that is initially unused.
2538 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2539 texDataGreen.data());
2540
2541 // One level that is initially used - only this level should affect completeness.
2542 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2543 texDataGreen.data());
2544
2545 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2546 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2547
2548 EXPECT_GL_NO_ERROR();
2549
2550 drawQuad(mProgram, "position", 0.5f);
2551
2552 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2553
2554 // Switch the max level to level 1. The levels within the used range now have inconsistent
2555 // dimensions and the texture should be incomplete.
2556 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2557
2558 EXPECT_GL_NO_ERROR();
2559
2560 drawQuad(mProgram, "position", 0.5f);
2561
2562 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2563}
2564
2565// Test that 3D texture completeness is updated if texture max level changes.
2566// GLES 3.0.4 section 3.8.13 Texture completeness
2567TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel)
2568{
Olli Etuahoa314b612016-03-10 16:43:00 +02002569 glActiveTexture(GL_TEXTURE0);
2570 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2571 std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green);
2572
2573 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2574 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2575
2576 // A level that is initially unused.
2577 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2578 texDataGreen.data());
2579
2580 // One level that is initially used - only this level should affect completeness.
2581 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2582 texDataGreen.data());
2583
2584 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
2585 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2586
2587 EXPECT_GL_NO_ERROR();
2588
2589 drawQuad(mProgram, "position", 0.5f);
2590
2591 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2592
2593 // Switch the max level to level 1. The levels within the used range now have inconsistent
2594 // dimensions and the texture should be incomplete.
2595 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
2596
2597 EXPECT_GL_NO_ERROR();
2598
2599 drawQuad(mProgram, "position", 0.5f);
2600
2601 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2602}
2603
2604// Test that texture completeness is updated if texture base level changes.
2605// GLES 3.0.4 section 3.8.13 Texture completeness
2606TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel)
2607{
Olli Etuahoa314b612016-03-10 16:43:00 +02002608 glActiveTexture(GL_TEXTURE0);
2609 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2610 std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green);
2611
2612 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2613 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2614
2615 // Two levels that are initially unused.
2616 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2617 texDataGreen.data());
2618 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2619 texDataGreen.data());
2620
2621 // One level that is initially used - only this level should affect completeness.
2622 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2623 texDataGreen.data());
2624
2625 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
2626 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
2627
2628 EXPECT_GL_NO_ERROR();
2629
2630 drawQuad(mProgram, "position", 0.5f);
2631
2632 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2633
2634 // Switch the base level to level 1. The levels within the used range now have inconsistent
2635 // dimensions and the texture should be incomplete.
2636 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2637
2638 EXPECT_GL_NO_ERROR();
2639
2640 drawQuad(mProgram, "position", 0.5f);
2641
2642 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2643}
2644
2645// Test that texture is not complete if base level is greater than max level.
2646// GLES 3.0.4 section 3.8.13 Texture completeness
2647TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel)
2648{
Olli Etuahoa314b612016-03-10 16:43:00 +02002649 glActiveTexture(GL_TEXTURE0);
2650 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2651
2652 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2653 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2654
2655 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2656
2657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2659
2660 EXPECT_GL_NO_ERROR();
2661
2662 drawQuad(mProgram, "position", 0.5f);
2663
2664 // Texture should be incomplete.
2665 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2666}
2667
2668// Test that immutable texture base level and max level are clamped.
2669// GLES 3.0.4 section 3.8.10 subsection Mipmapping
2670TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
2671{
Olli Etuahoa314b612016-03-10 16:43:00 +02002672 glActiveTexture(GL_TEXTURE0);
2673 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2674
2675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2677
2678 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
2679
2680 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2681
2682 // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level
2683 // should be clamped to [base_level, levels - 1].
2684 // GLES 3.0.4 section 3.8.10 subsection Mipmapping
2685 // In the case of this test, those rules make the effective base level and max level 0.
2686 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2687 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2688
2689 EXPECT_GL_NO_ERROR();
2690
2691 drawQuad(mProgram, "position", 0.5f);
2692
2693 // Texture should be complete.
2694 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2695}
2696
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002697// Test that changing base level works when it affects the format of the texture.
2698TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
2699{
Corentin Wallez7f00d332019-08-28 15:19:16 +02002700 // TODO(crbug.com/998505): Test failing on Android FYI Release (NVIDIA Shield TV)
2701 ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
2702
Yunchao He8e5ba8b2018-02-05 17:52:27 +08002703 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
Yunchao He9550c602018-02-13 14:47:05 +08002704
2705 // Observed incorrect rendering on AMD OpenGL.
2706 ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL());
Olli Etuaho87fc71c2016-05-11 14:25:21 +03002707
2708 glActiveTexture(GL_TEXTURE0);
2709 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2710 std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
2711 std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
2712
2713 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2715
2716 // RGBA8 level that's initially unused.
2717 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2718 texDataCyan.data());
2719
2720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2722
2723 // RG8 level that's initially used, with consistent dimensions with level 0 but a different
2724 // format. It reads green channel data from the green and alpha channels of texDataGreen
2725 // (this is a bit hacky but works).
2726 glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
2727
2728 EXPECT_GL_NO_ERROR();
2729
2730 drawQuad(mProgram, "position", 0.5f);
2731
2732 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2733
2734 // Switch the texture to use the cyan level 0 with the RGBA format.
2735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2737
2738 EXPECT_GL_NO_ERROR();
2739
2740 drawQuad(mProgram, "position", 0.5f);
2741
2742 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2743}
2744
Olli Etuahoa314b612016-03-10 16:43:00 +02002745// Test that setting a texture image works when base level is out of range.
2746TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
2747{
2748 glActiveTexture(GL_TEXTURE0);
2749 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2750
2751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2752 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2753
2754 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000);
2755 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000);
2756
2757 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
2758
2759 EXPECT_GL_NO_ERROR();
2760
2761 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2762
2763 drawQuad(mProgram, "position", 0.5f);
2764
2765 // Texture should be complete.
2766 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Olli Etuahoa7416ff2016-01-18 12:22:55 +02002767}
2768
Jamie Madill50cf2be2018-06-15 09:46:57 -04002769// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG
2770// RBA->RGBA8, with 1.0 in the alpha channel. This test covers a bug where redefining array textures
2771// with these formats does not work as expected.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002772TEST_P(Texture2DArrayTestES3, RedefineInittableArray)
Jamie Madill2453dbc2015-07-14 11:35:42 -04002773{
2774 std::vector<GLubyte> pixelData;
2775 for (size_t count = 0; count < 5000; count++)
2776 {
2777 pixelData.push_back(0u);
2778 pixelData.push_back(255u);
2779 pixelData.push_back(0u);
2780 }
2781
2782 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002783 glUseProgram(mProgram);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002784 glUniform1i(mTextureArrayLocation, 0);
2785
2786 // The first draw worked correctly.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002787 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2788 &pixelData[0]);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002789
2790 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2791 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2792 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
2793 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002794 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002795 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002796
2797 // The dimension of the respecification must match the original exactly to trigger the bug.
Jamie Madill50cf2be2018-06-15 09:46:57 -04002798 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
2799 &pixelData[0]);
Olli Etuaho4a8329f2016-01-11 17:12:57 +02002800 drawQuad(mProgram, "position", 1.0f);
Olli Etuahoa314b612016-03-10 16:43:00 +02002801 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill2453dbc2015-07-14 11:35:42 -04002802
2803 ASSERT_GL_NO_ERROR();
2804}
2805
Olli Etuaho1a679902016-01-14 12:21:47 +02002806// Test shadow sampler and regular non-shadow sampler coexisting in the same shader.
2807// This test is needed especially to confirm that sampler registers get assigned correctly on
2808// the HLSL backend even when there's a mix of different HLSL sampler and texture types.
2809TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw)
2810{
2811 glActiveTexture(GL_TEXTURE0);
2812 glBindTexture(GL_TEXTURE_3D, mTexture3D);
2813 GLubyte texData[4];
2814 texData[0] = 0;
2815 texData[1] = 60;
2816 texData[2] = 0;
2817 texData[3] = 255;
2818 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2819
2820 glActiveTexture(GL_TEXTURE1);
2821 glBindTexture(GL_TEXTURE_2D, mTextureShadow);
2822 GLfloat depthTexData[1];
2823 depthTexData[0] = 0.5f;
2824 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2825 depthTexData);
2826
2827 glUseProgram(mProgram);
2828 glUniform1f(mDepthRefUniformLocation, 0.3f);
2829 glUniform1i(mTexture3DUniformLocation, 0);
2830 glUniform1i(mTextureShadowUniformLocation, 1);
2831
2832 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2833 drawQuad(mProgram, "position", 0.5f);
2834 EXPECT_GL_NO_ERROR();
2835 // The shader writes 0.5 * <comparison result (1.0)> + <texture color>
2836 EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2);
2837
2838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
2839 drawQuad(mProgram, "position", 0.5f);
2840 EXPECT_GL_NO_ERROR();
2841 // The shader writes 0.5 * <comparison result (0.0)> + <texture color>
2842 EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2);
2843}
2844
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002845// Test multiple different sampler types in the same shader.
2846// This test makes sure that even if sampler / texture registers get grouped together based on type
2847// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer
2848// still has the right register index information for each ESSL sampler.
2849// The tested ESSL samplers have the following types in D3D11 HLSL:
2850// sampler2D: Texture2D + SamplerState
2851// samplerCube: TextureCube + SamplerState
2852// sampler2DShadow: Texture2D + SamplerComparisonState
2853// samplerCubeShadow: TextureCube + SamplerComparisonState
2854TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw)
2855{
2856 glActiveTexture(GL_TEXTURE0);
2857 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2858 GLubyte texData[4];
2859 texData[0] = 0;
2860 texData[1] = 0;
2861 texData[2] = 120;
2862 texData[3] = 255;
2863 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
2864
2865 glActiveTexture(GL_TEXTURE1);
2866 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
2867 texData[0] = 0;
2868 texData[1] = 90;
2869 texData[2] = 0;
2870 texData[3] = 255;
2871 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1);
2872 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
2873 texData);
2874
2875 glActiveTexture(GL_TEXTURE2);
2876 glBindTexture(GL_TEXTURE_2D, mTexture2DShadow);
2877 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2878 GLfloat depthTexData[1];
2879 depthTexData[0] = 0.5f;
2880 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
2881 depthTexData);
2882
2883 glActiveTexture(GL_TEXTURE3);
2884 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow);
2885 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2886 depthTexData[0] = 0.2f;
2887 glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1);
2888 glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
2889 depthTexData);
2890
Tobin Ehlisbbf0ce22019-10-11 06:55:36 -06002891 // http://anglebug.com/3949: TODO: Add a DS texture case
2892
Olli Etuahoc8c99a02016-01-14 16:47:22 +02002893 EXPECT_GL_NO_ERROR();
2894
2895 glUseProgram(mProgram);
2896 glUniform1f(mDepthRefUniformLocation, 0.3f);
2897 glUniform1i(mTexture2DUniformLocation, 0);
2898 glUniform1i(mTextureCubeUniformLocation, 1);
2899 glUniform1i(mTexture2DShadowUniformLocation, 2);
2900 glUniform1i(mTextureCubeShadowUniformLocation, 3);
2901
2902 drawQuad(mProgram, "position", 0.5f);
2903 EXPECT_GL_NO_ERROR();
2904 // The shader writes:
2905 // <texture 2d color> +
2906 // <cube map color> +
2907 // 0.25 * <comparison result (1.0)> +
2908 // 0.125 * <comparison result (0.0)>
2909 EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2);
2910}
2911
Olli Etuahobce743a2016-01-15 17:18:28 +02002912// Test different base levels on textures accessed through the same sampler array.
2913// Calling textureSize() on the samplers hits the D3D sampler metadata workaround.
2914TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray)
2915{
Yunchao He9550c602018-02-13 14:47:05 +08002916 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
2917
Olli Etuahobce743a2016-01-15 17:18:28 +02002918 glActiveTexture(GL_TEXTURE0);
2919 glBindTexture(GL_TEXTURE_2D, mTexture2DA);
2920 GLsizei size = 64;
2921 for (GLint level = 0; level < 7; ++level)
2922 {
2923 ASSERT_LT(0, size);
2924 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2925 nullptr);
2926 size = size / 2;
2927 }
2928 ASSERT_EQ(0, size);
2929 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2930
2931 glActiveTexture(GL_TEXTURE1);
2932 glBindTexture(GL_TEXTURE_2D, mTexture2DB);
2933 size = 128;
2934 for (GLint level = 0; level < 8; ++level)
2935 {
2936 ASSERT_LT(0, size);
2937 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2938 nullptr);
2939 size = size / 2;
2940 }
2941 ASSERT_EQ(0, size);
2942 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3);
2943 EXPECT_GL_NO_ERROR();
2944
2945 glUseProgram(mProgram);
2946 glUniform1i(mTexture0Location, 0);
2947 glUniform1i(mTexture1Location, 1);
2948
Olli Etuaho5804dc82018-04-13 14:11:46 +03002949 drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
Olli Etuahobce743a2016-01-15 17:18:28 +02002950 EXPECT_GL_NO_ERROR();
2951 // Red channel: width of level 1 of texture A: 32.
2952 // Green channel: width of level 3 of texture B: 16.
2953 EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2);
2954}
2955
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002956// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2957// ES 3.0.4 table 3.24
2958TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
2959{
2960 glActiveTexture(GL_TEXTURE0);
2961 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2962 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
2963 EXPECT_GL_NO_ERROR();
2964
2965 drawQuad(mProgram, "position", 0.5f);
2966
2967 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2968}
2969
2970// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
2971// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05002972TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002973{
Luc Ferron5164b792018-03-06 09:10:12 -05002974 setUpProgram();
2975
Olli Etuaho6ee394a2016-02-18 13:30:09 +02002976 glActiveTexture(GL_TEXTURE0);
2977 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2978 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
2979 EXPECT_GL_NO_ERROR();
2980
2981 drawQuad(mProgram, "position", 0.5f);
2982
2983 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
2984}
2985
Luc Ferron5164b792018-03-06 09:10:12 -05002986// Validate that every component of the pixel will be equal to the luminance value we've set
2987// and that the alpha channel will be 1 (or 255 to be exact).
2988TEST_P(Texture2DTest, TextureLuminanceRGBSame)
2989{
2990 setUpProgram();
2991
2992 glActiveTexture(GL_TEXTURE0);
2993 glBindTexture(GL_TEXTURE_2D, mTexture2D);
2994 uint8_t pixel = 50;
2995 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
2996 EXPECT_GL_NO_ERROR();
2997
2998 drawQuad(mProgram, "position", 0.5f);
2999
3000 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
3001}
3002
3003// Validate that every component of the pixel will be equal to the luminance value we've set
3004// and that the alpha channel will be the second component.
3005TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
3006{
3007 setUpProgram();
3008
3009 glActiveTexture(GL_TEXTURE0);
3010 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3011 uint8_t pixel[] = {50, 25};
3012 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
3013 GL_UNSIGNED_BYTE, pixel);
3014 EXPECT_GL_NO_ERROR();
3015
3016 drawQuad(mProgram, "position", 0.5f);
3017
3018 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
3019}
3020
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003021// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3022// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003023TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003024{
Jamie Madillb8149072019-04-30 16:14:44 -04003025 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003026 ANGLE_SKIP_TEST_IF(IsD3D9());
3027 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferron5164b792018-03-06 09:10:12 -05003028
3029 setUpProgram();
3030
Luc Ferrond8c632c2018-04-10 12:31:44 -04003031 glActiveTexture(GL_TEXTURE0);
3032 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3033 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr);
3034 EXPECT_GL_NO_ERROR();
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003035
Luc Ferrond8c632c2018-04-10 12:31:44 -04003036 drawQuad(mProgram, "position", 0.5f);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003037
Luc Ferrond8c632c2018-04-10 12:31:44 -04003038 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003039}
3040
3041// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3042// ES 3.0.4 table 3.24
Luc Ferron5164b792018-03-06 09:10:12 -05003043TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003044{
Jamie Madillb8149072019-04-30 16:14:44 -04003045 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
Luc Ferrond8c632c2018-04-10 12:31:44 -04003046 ANGLE_SKIP_TEST_IF(IsD3D9());
3047 ANGLE_SKIP_TEST_IF(IsVulkan());
Luc Ferrond8c632c2018-04-10 12:31:44 -04003048 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
3049 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
Luc Ferron5164b792018-03-06 09:10:12 -05003050
Luc Ferrond8c632c2018-04-10 12:31:44 -04003051 setUpProgram();
Luc Ferron5164b792018-03-06 09:10:12 -05003052
Luc Ferrond8c632c2018-04-10 12:31:44 -04003053 glActiveTexture(GL_TEXTURE0);
3054 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3055 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, nullptr);
3056 EXPECT_GL_NO_ERROR();
Yunchao He9550c602018-02-13 14:47:05 +08003057
Luc Ferrond8c632c2018-04-10 12:31:44 -04003058 drawQuad(mProgram, "position", 0.5f);
Yuly Novikovafcec832016-06-21 22:19:51 -04003059
Luc Ferrond8c632c2018-04-10 12:31:44 -04003060 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003061}
3062
3063// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3064// ES 3.0.4 table 3.24
3065TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1)
3066{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003067 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3068
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003069 glActiveTexture(GL_TEXTURE0);
3070 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3071 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr);
3072 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3073 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3074 EXPECT_GL_NO_ERROR();
3075
3076 drawQuad(mProgram, "position", 0.5f);
3077
3078 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3079}
3080
3081// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3082// ES 3.0.4 table 3.24
3083TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1)
3084{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003085 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3086
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003087 glActiveTexture(GL_TEXTURE0);
3088 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3089
3090 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr);
3091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3092 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3093 EXPECT_GL_NO_ERROR();
3094
3095 drawQuad(mProgram, "position", 0.5f);
3096
3097 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3098}
3099
3100// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3101// ES 3.0.4 table 3.24
3102TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1)
3103{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003104 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3105
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003106 glActiveTexture(GL_TEXTURE0);
3107 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3108 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr);
3109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3111 EXPECT_GL_NO_ERROR();
3112
3113 drawQuad(mProgram, "position", 0.5f);
3114
3115 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3116}
3117
3118// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3119// ES 3.0.4 table 3.24
3120TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1)
3121{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003122 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3123
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003124 glActiveTexture(GL_TEXTURE0);
3125 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr);
3127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3129 EXPECT_GL_NO_ERROR();
3130
3131 drawQuad(mProgram, "position", 0.5f);
3132
3133 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3134}
3135
3136// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3137// ES 3.0.4 table 3.24
3138TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1)
3139{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003140 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3141
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003142 glActiveTexture(GL_TEXTURE0);
3143 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3144 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr);
3145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3147 EXPECT_GL_NO_ERROR();
3148
3149 drawQuad(mProgram, "position", 0.5f);
3150
3151 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3152}
3153
3154// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3155// ES 3.0.4 table 3.24
3156TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1)
3157{
Yunchao He8e5ba8b2018-02-05 17:52:27 +08003158 ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
3159
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003160 glActiveTexture(GL_TEXTURE0);
3161 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3162 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr);
3163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3165 EXPECT_GL_NO_ERROR();
3166
3167 drawQuad(mProgram, "position", 0.5f);
3168
3169 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3170}
3171
3172// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3173// ES 3.0.4 table 3.24
3174TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1)
3175{
3176 glActiveTexture(GL_TEXTURE0);
3177 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3178 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr);
3179 EXPECT_GL_NO_ERROR();
3180
3181 drawQuad(mProgram, "position", 0.5f);
3182
3183 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3184}
3185
3186// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3187// ES 3.0.4 table 3.24
3188TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1)
3189{
3190 glActiveTexture(GL_TEXTURE0);
3191 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3192 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV,
3193 nullptr);
3194 EXPECT_GL_NO_ERROR();
3195
3196 drawQuad(mProgram, "position", 0.5f);
3197
3198 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3199}
3200
3201// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3202// ES 3.0.4 table 3.24
3203TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1)
3204{
Geoff Lang2a19c592019-08-23 14:10:24 -04003205 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3206 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003207
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003208 glActiveTexture(GL_TEXTURE0);
3209 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3210 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr);
3211 EXPECT_GL_NO_ERROR();
3212
3213 drawQuad(mProgram, "position", 0.5f);
3214
3215 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3216}
3217
3218// When sampling a texture without an alpha channel, "1" is returned as the alpha value.
3219// ES 3.0.4 table 3.24
3220TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1)
3221{
Geoff Lang2a19c592019-08-23 14:10:24 -04003222 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
3223 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
Yuly Novikov49886892018-01-23 21:18:27 -05003224
Olli Etuaho6ee394a2016-02-18 13:30:09 +02003225 glActiveTexture(GL_TEXTURE0);
3226 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3227 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr);
3228 EXPECT_GL_NO_ERROR();
3229
3230 drawQuad(mProgram, "position", 0.5f);
3231
3232 EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
3233}
3234
Olli Etuaho96963162016-03-21 11:54:33 +02003235// Use a sampler in a uniform struct.
3236TEST_P(SamplerInStructTest, SamplerInStruct)
3237{
3238 runSamplerInStructTest();
3239}
3240
3241// Use a sampler in a uniform struct that's passed as a function parameter.
3242TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter)
3243{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003244 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3245 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Geoff Lang8fcdf6e2016-09-16 10:45:30 -04003246
Olli Etuaho96963162016-03-21 11:54:33 +02003247 runSamplerInStructTest();
3248}
3249
3250// Use a sampler in a uniform struct array with a struct from the array passed as a function
3251// parameter.
3252TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter)
3253{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003254 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3255 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003256
Olli Etuaho96963162016-03-21 11:54:33 +02003257 runSamplerInStructTest();
3258}
3259
3260// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function
3261// parameter.
3262TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter)
3263{
Yuly Novikovd18c0482019-04-04 19:56:43 -04003264 // Fails on Nexus 5X due to a driver bug. http://anglebug.com/1427
3265 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Yunchao He9550c602018-02-13 14:47:05 +08003266
Olli Etuaho96963162016-03-21 11:54:33 +02003267 runSamplerInStructTest();
3268}
3269
3270// Make sure that there isn't a name conflict between sampler extracted from a struct and a
3271// similarly named uniform.
3272TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable)
3273{
3274 runSamplerInStructTest();
3275}
3276
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003277// GL_EXT_texture_filter_anisotropic
3278class TextureAnisotropyTest : public Texture2DTest
3279{
3280 protected:
3281 void uploadTexture()
3282 {
3283 glActiveTexture(GL_TEXTURE0);
3284 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3285 GLColor texDataRed[1] = {GLColor::red};
3286 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed);
3287 EXPECT_GL_NO_ERROR();
3288 }
3289};
3290
3291// Tests that setting anisotropic filtering doesn't cause failures at draw time.
3292TEST_P(TextureAnisotropyTest, AnisotropyFunctional)
3293{
Jamie Madillb8149072019-04-30 16:14:44 -04003294 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_filter_anisotropic"));
Shahbaz Youssefi962c2222019-02-20 15:43:41 -05003295
3296 setUpProgram();
3297
3298 uploadTexture();
3299
3300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3302 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
3303 EXPECT_GL_NO_ERROR();
3304
3305 drawQuad(mProgram, "position", 0.5f);
3306
3307 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3308 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3309 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
3310}
3311
Till Rathmannb8543632018-10-02 19:46:14 +02003312// GL_OES_texture_border_clamp
3313class TextureBorderClampTest : public Texture2DTest
3314{
3315 protected:
3316 TextureBorderClampTest() : Texture2DTest() {}
3317
Jamie Madill35cd7332018-12-02 12:03:33 -05003318 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003319 {
3320 return
3321 R"(precision highp float;
3322 attribute vec4 position;
3323 varying vec2 texcoord;
3324
3325 void main()
3326 {
3327 gl_Position = vec4(position.xy, 0.0, 1.0);
3328 // texcoords in [-0.5, 1.5]
3329 texcoord = (position.xy) + 0.5;
3330 })";
3331 }
3332
3333 void uploadTexture()
3334 {
3335 glActiveTexture(GL_TEXTURE0);
3336 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3337 std::vector<GLColor> texDataRed(1, GLColor::red);
3338 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3339 texDataRed.data());
3340 EXPECT_GL_NO_ERROR();
3341 }
3342};
3343
3344// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3345// GL_CLAMP_TO_BORDER wrap mode (set with glTexParameter).
3346TEST_P(TextureBorderClampTest, TextureBorderClampFunctional)
3347{
Jamie Madillb8149072019-04-30 16:14:44 -04003348 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003349
3350 setUpProgram();
3351
3352 uploadTexture();
3353
3354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3356 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3358 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3359 EXPECT_GL_NO_ERROR();
3360
3361 drawQuad(mProgram, "position", 0.5f);
3362
3363 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3364 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3365 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3366}
3367
3368// Test reading back GL_TEXTURE_BORDER_COLOR by glGetTexParameter.
3369TEST_P(TextureBorderClampTest, TextureBorderClampFunctional2)
3370{
Jamie Madillb8149072019-04-30 16:14:44 -04003371 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003372
3373 glActiveTexture(GL_TEXTURE0);
3374 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3375
3376 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3377
3378 GLint colorFixedPoint[4] = {0};
3379 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3380 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3381 std::numeric_limits<GLint>::max()};
3382 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3383 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3384 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3385 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3386
3387 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3388 std::numeric_limits<GLint>::max()};
3389 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3390
3391 GLfloat color[4] = {0.0f};
3392 glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
3393 EXPECT_EQ(color[0], kFloatBlue.R);
3394 EXPECT_EQ(color[1], kFloatBlue.G);
3395 EXPECT_EQ(color[2], kFloatBlue.B);
3396 EXPECT_EQ(color[3], kFloatBlue.A);
3397}
3398
3399// Test GL_TEXTURE_BORDER_COLOR parameter validation at glTexParameter.
3400TEST_P(TextureBorderClampTest, TextureBorderClampValidation)
3401{
Jamie Madillb8149072019-04-30 16:14:44 -04003402 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003403
3404 glActiveTexture(GL_TEXTURE0);
3405 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3406
3407 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, 1.0f);
3408 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3409
3410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3411 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3412
3413 glTexParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3414 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3415
3416 GLint colorInt[4] = {0};
3417 glTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BORDER_COLOR, colorInt);
3418 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3419
3420 if (getClientMajorVersion() < 3)
3421 {
3422 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3423 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3424 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3425 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3426
3427 GLuint colorUInt[4] = {0};
3428 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3429 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3430 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3431 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3432
3433 GLSampler sampler;
3434 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3435 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3436 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3437 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3438
3439 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3440 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3441 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3442 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
3443 }
3444}
3445
3446class TextureBorderClampTestES3 : public TextureBorderClampTest
3447{
3448 protected:
3449 TextureBorderClampTestES3() : TextureBorderClampTest() {}
3450};
3451
3452// Test if the color set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the texture in
3453// GL_CLAMP_TO_BORDER wrap mode (set with glSamplerParameter).
3454TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional)
3455{
Jamie Madillb8149072019-04-30 16:14:44 -04003456 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003457
3458 setUpProgram();
3459
3460 uploadTexture();
3461
3462 GLSampler sampler;
3463 glBindSampler(0, sampler);
3464 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3465 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3466 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3467 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3468 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3469 EXPECT_GL_NO_ERROR();
3470
3471 drawQuad(mProgram, "position", 0.5f);
3472
3473 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3474 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3475 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3476}
3477
3478// Test reading back GL_TEXTURE_BORDER_COLOR by glGetSamplerParameter.
3479TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Functional2)
3480{
Jamie Madillb8149072019-04-30 16:14:44 -04003481 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003482
3483 glActiveTexture(GL_TEXTURE0);
3484
3485 GLSampler sampler;
3486 glBindSampler(0, sampler);
3487
3488 glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, &kFloatGreen.R);
3489
3490 GLint colorFixedPoint[4] = {0};
3491 glGetSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorFixedPoint);
3492 constexpr GLint colorGreenFixedPoint[4] = {0, std::numeric_limits<GLint>::max(), 0,
3493 std::numeric_limits<GLint>::max()};
3494 EXPECT_EQ(colorFixedPoint[0], colorGreenFixedPoint[0]);
3495 EXPECT_EQ(colorFixedPoint[1], colorGreenFixedPoint[1]);
3496 EXPECT_EQ(colorFixedPoint[2], colorGreenFixedPoint[2]);
3497 EXPECT_EQ(colorFixedPoint[3], colorGreenFixedPoint[3]);
3498
3499 constexpr GLint colorBlueFixedPoint[4] = {0, 0, std::numeric_limits<GLint>::max(),
3500 std::numeric_limits<GLint>::max()};
3501 glSamplerParameteriv(sampler, GL_TEXTURE_BORDER_COLOR, colorBlueFixedPoint);
3502
3503 GLfloat color[4] = {0.0f};
3504 glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, color);
3505 EXPECT_EQ(color[0], kFloatBlue.R);
3506 EXPECT_EQ(color[1], kFloatBlue.G);
3507 EXPECT_EQ(color[2], kFloatBlue.B);
3508 EXPECT_EQ(color[3], kFloatBlue.A);
3509
3510 constexpr GLint colorSomewhatRedInt[4] = {500000, 0, 0, std::numeric_limits<GLint>::max()};
3511 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedInt);
3512 GLint colorInt[4] = {0};
3513 glGetSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorInt);
3514 EXPECT_EQ(colorInt[0], colorSomewhatRedInt[0]);
3515 EXPECT_EQ(colorInt[1], colorSomewhatRedInt[1]);
3516 EXPECT_EQ(colorInt[2], colorSomewhatRedInt[2]);
3517 EXPECT_EQ(colorInt[3], colorSomewhatRedInt[3]);
3518
3519 constexpr GLuint colorSomewhatRedUInt[4] = {500000, 0, 0, std::numeric_limits<GLuint>::max()};
3520 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorSomewhatRedUInt);
3521 GLuint colorUInt[4] = {0};
3522 glGetSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, colorUInt);
3523 EXPECT_EQ(colorUInt[0], colorSomewhatRedUInt[0]);
3524 EXPECT_EQ(colorUInt[1], colorSomewhatRedUInt[1]);
3525 EXPECT_EQ(colorUInt[2], colorSomewhatRedUInt[2]);
3526 EXPECT_EQ(colorUInt[3], colorSomewhatRedUInt[3]);
3527
3528 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3529
3530 constexpr GLint colorSomewhatGreenInt[4] = {0, 500000, 0, std::numeric_limits<GLint>::max()};
3531 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenInt);
3532 glGetTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorInt);
3533 EXPECT_EQ(colorInt[0], colorSomewhatGreenInt[0]);
3534 EXPECT_EQ(colorInt[1], colorSomewhatGreenInt[1]);
3535 EXPECT_EQ(colorInt[2], colorSomewhatGreenInt[2]);
3536 EXPECT_EQ(colorInt[3], colorSomewhatGreenInt[3]);
3537
3538 constexpr GLuint colorSomewhatGreenUInt[4] = {0, 500000, 0, std::numeric_limits<GLuint>::max()};
3539 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorSomewhatGreenUInt);
3540 glGetTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorUInt);
3541 EXPECT_EQ(colorUInt[0], colorSomewhatGreenUInt[0]);
3542 EXPECT_EQ(colorUInt[1], colorSomewhatGreenUInt[1]);
3543 EXPECT_EQ(colorUInt[2], colorSomewhatGreenUInt[2]);
3544 EXPECT_EQ(colorUInt[3], colorSomewhatGreenUInt[3]);
3545}
3546
3547// Test GL_TEXTURE_BORDER_COLOR parameter validation at glSamplerParameter.
3548TEST_P(TextureBorderClampTestES3, TextureBorderClampES3Validation)
3549{
Jamie Madillb8149072019-04-30 16:14:44 -04003550 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003551
3552 glActiveTexture(GL_TEXTURE0);
3553
3554 GLSampler sampler;
3555 glBindSampler(0, sampler);
3556
3557 glSamplerParameterf(sampler, GL_TEXTURE_BORDER_COLOR, 1.0f);
3558 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3559
3560 glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, std::numeric_limits<GLint>::max());
3561 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3562}
3563
3564class TextureBorderClampIntegerTestES3 : public Texture2DTest
3565{
3566 protected:
3567 TextureBorderClampIntegerTestES3() : Texture2DTest(), isUnsignedIntTest(false) {}
3568
Jamie Madill35cd7332018-12-02 12:03:33 -05003569 const char *getVertexShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003570 {
3571 return
3572 R"(#version 300 es
3573 out vec2 texcoord;
3574 in vec4 position;
3575
3576 void main()
3577 {
3578 gl_Position = vec4(position.xy, 0.0, 1.0);
3579 // texcoords in [-0.5, 1.5]
3580 texcoord = (position.xy) + 0.5;
3581 })";
3582 }
3583
Jamie Madillba319ba2018-12-29 10:29:33 -05003584 const char *getFragmentShaderSource() override
Till Rathmannb8543632018-10-02 19:46:14 +02003585 {
Jamie Madill35cd7332018-12-02 12:03:33 -05003586 if (isUnsignedIntTest)
3587 {
3588 return "#version 300 es\n"
3589 "precision highp float;\n"
3590 "uniform highp usampler2D tex;\n"
3591 "in vec2 texcoord;\n"
3592 "out vec4 fragColor;\n"
Till Rathmannb8543632018-10-02 19:46:14 +02003593
Jamie Madill35cd7332018-12-02 12:03:33 -05003594 "void main()\n"
3595 "{\n"
3596 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3597 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3598 "fragColor = (texture(tex, texcoord).r == 150u)"
3599 " ? green : red;\n"
3600 "}\n";
3601 }
3602 else
3603 {
3604 return "#version 300 es\n"
3605 "precision highp float;\n"
3606 "uniform highp isampler2D tex;\n"
3607 "in vec2 texcoord;\n"
3608 "out vec4 fragColor;\n"
3609
3610 "void main()\n"
3611 "{\n"
3612 "vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
3613 "vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3614 "fragColor = (texture(tex, texcoord).r == -50)"
3615 " ? green : red;\n"
3616 "}\n";
3617 }
Till Rathmannb8543632018-10-02 19:46:14 +02003618 }
3619
3620 void uploadTexture()
3621 {
3622 glActiveTexture(GL_TEXTURE0);
3623 glBindTexture(GL_TEXTURE_2D, mTexture2D);
3624 if (isUnsignedIntTest)
3625 {
3626 std::vector<GLubyte> texData(4, 100);
3627 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
3628 texData.data());
3629 }
3630 else
3631 {
3632 std::vector<GLbyte> texData(4, 100);
3633 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE,
3634 texData.data());
3635 }
3636 EXPECT_GL_NO_ERROR();
3637 }
3638
3639 bool isUnsignedIntTest;
3640};
3641
3642// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3643// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3644TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger)
3645{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003646 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3647 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3648
Jamie Madillb8149072019-04-30 16:14:44 -04003649 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003650
3651 setUpProgram();
3652
3653 uploadTexture();
3654
3655 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3656 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3659
3660 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3661 glTexParameterIivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3662
3663 EXPECT_GL_NO_ERROR();
3664
3665 drawQuad(mProgram, "position", 0.5f);
3666
3667 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3668 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3669 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3670}
3671
3672// Test if the integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside of the
3673// integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIivOES).
3674TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampInteger2)
3675{
Yuly Novikov1dbbc7b2019-07-31 17:49:39 -04003676 // Fails on Win10 FYI x64 Release (AMD RX 550). http://anglebug.com/3760
3677 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
3678
Jamie Madillb8149072019-04-30 16:14:44 -04003679 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003680
3681 setUpProgram();
3682
3683 uploadTexture();
3684
3685 GLSampler sampler;
3686 glBindSampler(0, sampler);
3687 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3688 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3689 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3690 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3691
3692 constexpr GLint borderColor[4] = {-50, -50, -50, -50};
3693 glSamplerParameterIivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3694
3695 EXPECT_GL_NO_ERROR();
3696
3697 drawQuad(mProgram, "position", 0.5f);
3698
3699 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3700 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3701 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3702}
3703
3704// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3705// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with glTexParameterIuivOES).
3706TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned)
3707{
Jamie Madillb8149072019-04-30 16:14:44 -04003708 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003709
3710 isUnsignedIntTest = true;
3711
3712 setUpProgram();
3713
3714 uploadTexture();
3715
3716 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3720
3721 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3722 glTexParameterIuivOES(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
3723
3724 EXPECT_GL_NO_ERROR();
3725
3726 drawQuad(mProgram, "position", 0.5f);
3727
3728 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3729 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3730 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3731}
3732
3733// Test if the unsigned integer values set as GL_TEXTURE_BORDER_COLOR is used when sampling outside
3734// of the unsigned integer texture in GL_CLAMP_TO_BORDER wrap mode (set with
3735// glSamplerParameterIuivOES).
3736TEST_P(TextureBorderClampIntegerTestES3, TextureBorderClampIntegerUnsigned2)
3737{
Jamie Madillb8149072019-04-30 16:14:44 -04003738 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_border_clamp"));
Till Rathmannb8543632018-10-02 19:46:14 +02003739
3740 isUnsignedIntTest = true;
3741
3742 setUpProgram();
3743
3744 uploadTexture();
3745
3746 GLSampler sampler;
3747 glBindSampler(0, sampler);
3748 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
3749 glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
3750 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3751 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3752
3753 constexpr GLuint borderColor[4] = {150, 150, 150, 150};
3754 glSamplerParameterIuivOES(sampler, GL_TEXTURE_BORDER_COLOR, borderColor);
3755
3756 EXPECT_GL_NO_ERROR();
3757
3758 drawQuad(mProgram, "position", 0.5f);
3759
3760 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3761 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3762 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
3763}
3764
3765// ~GL_OES_texture_border_clamp
3766
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003767class TextureLimitsTest : public ANGLETest
3768{
3769 protected:
3770 struct RGBA8
3771 {
3772 uint8_t R, G, B, A;
3773 };
3774
3775 TextureLimitsTest()
3776 : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
3777 {
3778 setWindowWidth(128);
3779 setWindowHeight(128);
3780 setConfigRedBits(8);
3781 setConfigGreenBits(8);
3782 setConfigBlueBits(8);
3783 setConfigAlphaBits(8);
3784 }
3785
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003786 void testSetUp() override
Jamie Madill0fdb9562018-09-17 17:18:43 -04003787 {
Jamie Madill0fdb9562018-09-17 17:18:43 -04003788 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
3789 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
3790 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
3791
3792 ASSERT_GL_NO_ERROR();
3793 }
3794
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04003795 void testTearDown() override
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003796 {
3797 if (mProgram != 0)
3798 {
3799 glDeleteProgram(mProgram);
3800 mProgram = 0;
3801
3802 if (!mTextures.empty())
3803 {
3804 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
3805 }
3806 }
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003807 }
3808
3809 void compileProgramWithTextureCounts(const std::string &vertexPrefix,
3810 GLint vertexTextureCount,
3811 GLint vertexActiveTextureCount,
3812 const std::string &fragPrefix,
3813 GLint fragmentTextureCount,
3814 GLint fragmentActiveTextureCount)
3815 {
3816 std::stringstream vertexShaderStr;
3817 vertexShaderStr << "attribute vec2 position;\n"
3818 << "varying vec4 color;\n"
3819 << "varying vec2 texCoord;\n";
3820
3821 for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
3822 {
3823 vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
3824 }
3825
3826 vertexShaderStr << "void main() {\n"
3827 << " gl_Position = vec4(position, 0, 1);\n"
3828 << " texCoord = (position * 0.5) + 0.5;\n"
3829 << " color = vec4(0);\n";
3830
3831 for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
3832 {
3833 vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
3834 << ", texCoord);\n";
3835 }
3836
3837 vertexShaderStr << "}";
3838
3839 std::stringstream fragmentShaderStr;
3840 fragmentShaderStr << "varying mediump vec4 color;\n"
3841 << "varying mediump vec2 texCoord;\n";
3842
3843 for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
3844 {
3845 fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
3846 }
3847
3848 fragmentShaderStr << "void main() {\n"
3849 << " gl_FragColor = color;\n";
3850
3851 for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
3852 {
3853 fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
3854 << ", texCoord);\n";
3855 }
3856
3857 fragmentShaderStr << "}";
3858
3859 const std::string &vertexShaderSource = vertexShaderStr.str();
3860 const std::string &fragmentShaderSource = fragmentShaderStr.str();
3861
Jamie Madill35cd7332018-12-02 12:03:33 -05003862 mProgram = CompileProgram(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003863 }
3864
3865 RGBA8 getPixel(GLint texIndex)
3866 {
3867 RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
3868 0, 255u};
3869 return pixel;
3870 }
3871
3872 void initTextures(GLint tex2DCount, GLint texCubeCount)
3873 {
3874 GLint totalCount = tex2DCount + texCubeCount;
3875 mTextures.assign(totalCount, 0);
3876 glGenTextures(totalCount, &mTextures[0]);
3877 ASSERT_GL_NO_ERROR();
3878
3879 std::vector<RGBA8> texData(16 * 16);
3880
3881 GLint texIndex = 0;
3882 for (; texIndex < tex2DCount; ++texIndex)
3883 {
3884 texData.assign(texData.size(), getPixel(texIndex));
3885 glActiveTexture(GL_TEXTURE0 + texIndex);
3886 glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
3887 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3888 &texData[0]);
3889 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3890 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3891 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3893 }
3894
3895 ASSERT_GL_NO_ERROR();
3896
3897 for (; texIndex < texCubeCount; ++texIndex)
3898 {
3899 texData.assign(texData.size(), getPixel(texIndex));
3900 glActiveTexture(GL_TEXTURE0 + texIndex);
3901 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
3902 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3903 GL_UNSIGNED_BYTE, &texData[0]);
3904 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3905 GL_UNSIGNED_BYTE, &texData[0]);
3906 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3907 GL_UNSIGNED_BYTE, &texData[0]);
3908 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3909 GL_UNSIGNED_BYTE, &texData[0]);
3910 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3911 GL_UNSIGNED_BYTE, &texData[0]);
3912 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
3913 GL_UNSIGNED_BYTE, &texData[0]);
3914 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3915 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3916 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3917 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3918 }
3919
3920 ASSERT_GL_NO_ERROR();
3921 }
3922
3923 void testWithTextures(GLint vertexTextureCount,
3924 const std::string &vertexTexturePrefix,
3925 GLint fragmentTextureCount,
3926 const std::string &fragmentTexturePrefix)
3927 {
3928 // Generate textures
3929 initTextures(vertexTextureCount + fragmentTextureCount, 0);
3930
3931 glUseProgram(mProgram);
3932 RGBA8 expectedSum = {0};
3933 for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
3934 {
3935 std::stringstream uniformNameStr;
3936 uniformNameStr << vertexTexturePrefix << texIndex;
3937 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003938 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003939 ASSERT_NE(-1, location);
3940
3941 glUniform1i(location, texIndex);
3942 RGBA8 contribution = getPixel(texIndex);
3943 expectedSum.R += contribution.R;
3944 expectedSum.G += contribution.G;
3945 }
3946
3947 for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
3948 {
3949 std::stringstream uniformNameStr;
3950 uniformNameStr << fragmentTexturePrefix << texIndex;
3951 const std::string &uniformName = uniformNameStr.str();
Jamie Madill50cf2be2018-06-15 09:46:57 -04003952 GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
Jamie Madill3d3d2f22015-09-23 16:47:51 -04003953 ASSERT_NE(-1, location);
3954
3955 glUniform1i(location, texIndex + vertexTextureCount);
3956 RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
3957 expectedSum.R += contribution.R;
3958 expectedSum.G += contribution.G;
3959 }
3960
3961 ASSERT_GE(256u, expectedSum.G);
3962
3963 drawQuad(mProgram, "position", 0.5f);
3964 ASSERT_GL_NO_ERROR();
3965 EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
3966 }
3967
3968 GLuint mProgram;
3969 std::vector<GLuint> mTextures;
3970 GLint mMaxVertexTextures;
3971 GLint mMaxFragmentTextures;
3972 GLint mMaxCombinedTextures;
3973};
3974
3975// Test rendering with the maximum vertex texture units.
3976TEST_P(TextureLimitsTest, MaxVertexTextures)
3977{
3978 compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
3979 ASSERT_NE(0u, mProgram);
3980 ASSERT_GL_NO_ERROR();
3981
3982 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
3983}
3984
3985// Test rendering with the maximum fragment texture units.
3986TEST_P(TextureLimitsTest, MaxFragmentTextures)
3987{
3988 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
3989 ASSERT_NE(0u, mProgram);
3990 ASSERT_GL_NO_ERROR();
3991
3992 testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
3993}
3994
3995// Test rendering with maximum combined texture units.
3996TEST_P(TextureLimitsTest, MaxCombinedTextures)
3997{
3998 GLint vertexTextures = mMaxVertexTextures;
3999
4000 if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
4001 {
4002 vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
4003 }
4004
4005 compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
4006 mMaxFragmentTextures, mMaxFragmentTextures);
4007 ASSERT_NE(0u, mProgram);
4008 ASSERT_GL_NO_ERROR();
4009
4010 testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
4011}
4012
4013// Negative test for exceeding the number of vertex textures
4014TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
4015{
4016 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
4017 0);
4018 ASSERT_EQ(0u, mProgram);
4019}
4020
4021// Negative test for exceeding the number of fragment textures
4022TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
4023{
4024 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
4025 mMaxFragmentTextures + 1);
4026 ASSERT_EQ(0u, mProgram);
4027}
4028
4029// Test active vertex textures under the limit, but excessive textures specified.
4030TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
4031{
4032 compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
4033 ASSERT_NE(0u, mProgram);
4034 ASSERT_GL_NO_ERROR();
4035
4036 testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
4037}
4038
4039// Test active fragment textures under the limit, but excessive textures specified.
4040TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
4041{
4042 compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
4043 mMaxFragmentTextures);
4044 ASSERT_NE(0u, mProgram);
4045 ASSERT_GL_NO_ERROR();
4046
4047 testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
4048}
4049
4050// Negative test for pointing two sampler uniforms of different types to the same texture.
Olli Etuaho4a8329f2016-01-11 17:12:57 +02004051// GLES 2.0.25 section 2.10.4 page 39.
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004052TEST_P(TextureLimitsTest, TextureTypeConflict)
4053{
Jamie Madill35cd7332018-12-02 12:03:33 -05004054 constexpr char kVS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004055 "attribute vec2 position;\n"
4056 "varying float color;\n"
4057 "uniform sampler2D tex2D;\n"
4058 "uniform samplerCube texCube;\n"
4059 "void main() {\n"
4060 " gl_Position = vec4(position, 0, 1);\n"
4061 " vec2 texCoord = (position * 0.5) + 0.5;\n"
4062 " color = texture2D(tex2D, texCoord).x;\n"
4063 " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
4064 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05004065 constexpr char kFS[] =
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004066 "varying mediump float color;\n"
4067 "void main() {\n"
4068 " gl_FragColor = vec4(color, 0, 0, 1);\n"
4069 "}";
4070
Jamie Madill35cd7332018-12-02 12:03:33 -05004071 mProgram = CompileProgram(kVS, kFS);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04004072 ASSERT_NE(0u, mProgram);
4073
4074 initTextures(1, 0);
4075
4076 glUseProgram(mProgram);
4077 GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
4078 ASSERT_NE(-1, tex2DLocation);
4079 GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
4080 ASSERT_NE(-1, texCubeLocation);
4081
4082 glUniform1i(tex2DLocation, 0);
4083 glUniform1i(texCubeLocation, 0);
4084 ASSERT_GL_NO_ERROR();
4085
4086 drawQuad(mProgram, "position", 0.5f);
4087 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4088}
4089
Vincent Lang25ab4512016-05-13 18:13:59 +02004090class Texture2DNorm16TestES3 : public Texture2DTestES3
4091{
4092 protected:
4093 Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {}
4094
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004095 void testSetUp() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004096 {
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004097 Texture2DTestES3::testSetUp();
Vincent Lang25ab4512016-05-13 18:13:59 +02004098
4099 glActiveTexture(GL_TEXTURE0);
4100 glGenTextures(3, mTextures);
4101 glGenFramebuffers(1, &mFBO);
4102 glGenRenderbuffers(1, &mRenderbuffer);
4103
4104 for (size_t textureIndex = 0; textureIndex < 3; textureIndex++)
4105 {
4106 glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]);
4107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4109 }
4110
4111 glBindTexture(GL_TEXTURE_2D, 0);
4112
4113 ASSERT_GL_NO_ERROR();
4114 }
4115
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004116 void testTearDown() override
Vincent Lang25ab4512016-05-13 18:13:59 +02004117 {
4118 glDeleteTextures(3, mTextures);
4119 glDeleteFramebuffers(1, &mFBO);
4120 glDeleteRenderbuffers(1, &mRenderbuffer);
4121
Jamie Madill5cbaa3f2019-05-07 15:49:22 -04004122 Texture2DTestES3::testTearDown();
Vincent Lang25ab4512016-05-13 18:13:59 +02004123 }
4124
4125 void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
4126 {
Geoff Langf607c602016-09-21 11:46:48 -04004127 GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
4128 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004129
4130 setUpProgram();
4131
4132 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4133 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
4134 0);
4135
4136 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
4137 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
4138
4139 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Geoff Langf607c602016-09-21 11:46:48 -04004140 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004141
4142 EXPECT_GL_NO_ERROR();
4143
4144 drawQuad(mProgram, "position", 0.5f);
4145
Geoff Langf607c602016-09-21 11:46:48 -04004146 GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
Vincent Lang25ab4512016-05-13 18:13:59 +02004147
Jamie Madill50cf2be2018-06-15 09:46:57 -04004148 EXPECT_PIXEL_COLOR_EQ(0, 0,
4149 SliceFormatColor(format, GLColor(expectedValue, expectedValue,
4150 expectedValue, expectedValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004151
4152 glBindFramebuffer(GL_FRAMEBUFFER, 0);
4153
4154 ASSERT_GL_NO_ERROR();
4155 }
4156
4157 void testNorm16Render(GLint internalformat, GLenum format, GLenum type)
4158 {
Jamie Madill50cf2be2018-06-15 09:46:57 -04004159 GLushort pixelValue = 0x6A35;
Geoff Langf607c602016-09-21 11:46:48 -04004160 GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
Vincent Lang25ab4512016-05-13 18:13:59 +02004161
4162 setUpProgram();
4163
4164 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
4165 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, nullptr);
4166
4167 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4168 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4169 0);
4170
4171 glBindTexture(GL_TEXTURE_2D, mTextures[2]);
Geoff Langf607c602016-09-21 11:46:48 -04004172 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
Vincent Lang25ab4512016-05-13 18:13:59 +02004173
4174 EXPECT_GL_NO_ERROR();
4175
4176 drawQuad(mProgram, "position", 0.5f);
4177
shrekshaofb1c2fe2019-11-13 11:10:39 -08004178 EXPECT_PIXEL_16UI_COLOR(0, 0,
4179 SliceFormatColor16UI(format, GLColor16UI(pixelValue, pixelValue,
4180 pixelValue, pixelValue)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004181
4182 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4183 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4184 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4185 mRenderbuffer);
4186 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4187 EXPECT_GL_NO_ERROR();
4188
4189 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4190 glClear(GL_COLOR_BUFFER_BIT);
4191
shrekshaofb1c2fe2019-11-13 11:10:39 -08004192 EXPECT_PIXEL_16UI_COLOR(
4193 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
shrekshaoe33c1582019-11-06 16:55:29 -08004194
4195 glBindTexture(GL_TEXTURE_2D, mTextures[1]);
Vincent Lang25ab4512016-05-13 18:13:59 +02004196 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4197
shrekshaoe33c1582019-11-06 16:55:29 -08004198 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
4199 0);
shrekshaofb1c2fe2019-11-13 11:10:39 -08004200 EXPECT_PIXEL_16UI_COLOR(
4201 0, 0, SliceFormatColor16UI(format, GLColor16UI(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)));
Vincent Lang25ab4512016-05-13 18:13:59 +02004202
4203 ASSERT_GL_NO_ERROR();
shrekshaofb1c2fe2019-11-13 11:10:39 -08004204
4205 glBindFramebuffer(GL_FRAMEBUFFER, 0);
Vincent Lang25ab4512016-05-13 18:13:59 +02004206 }
4207
4208 GLuint mTextures[3];
4209 GLuint mFBO;
4210 GLuint mRenderbuffer;
4211};
4212
4213// Test texture formats enabled by the GL_EXT_texture_norm16 extension.
4214TEST_P(Texture2DNorm16TestES3, TextureNorm16Test)
4215{
shrekshaoe33c1582019-11-06 16:55:29 -08004216 // TODO(crbug.com/angleproject/4089) Fails on Nexus5X Adreno
shrekshao91075772019-11-18 15:00:29 -08004217 // TODO(crbug.com/1024387) Fails on Nexus6P
4218 ANGLE_SKIP_TEST_IF(IsNexus5X() || IsNexus6P());
shrekshaoe33c1582019-11-06 16:55:29 -08004219 // TODO(crbug.com/angleproject/4089) Fails on Win Intel OpenGL driver
4220 ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
4221
Jamie Madillb8149072019-04-30 16:14:44 -04004222 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
Vincent Lang25ab4512016-05-13 18:13:59 +02004223
4224 testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
4225 testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT);
4226 testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT);
4227 testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4228 testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT);
4229 testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
4230 testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
4231 testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
4232
Vincent Lang25ab4512016-05-13 18:13:59 +02004233 testNorm16Render(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT);
4234}
4235
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004236class Texture2DRGTest : public Texture2DTest
4237{
4238 protected:
4239 Texture2DRGTest()
4240 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4241 {}
4242
4243 void testSetUp() override
4244 {
4245 Texture2DTest::testSetUp();
4246
4247 glActiveTexture(GL_TEXTURE0);
4248 glGenTextures(1, &mRenderableTexture);
4249 glGenTextures(1, &mTestTexture);
4250 glGenFramebuffers(1, &mFBO);
4251 glGenRenderbuffers(1, &mRenderbuffer);
4252
4253 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4255 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004256 glBindTexture(GL_TEXTURE_2D, mTestTexture);
Mohan Maiya6caa2652019-09-11 08:06:13 -07004257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004259
4260 glBindTexture(GL_TEXTURE_2D, 0);
4261
4262 setUpProgram();
4263 glUseProgram(mProgram);
4264 glUniform1i(mTexture2DUniformLocation, 0);
4265
4266 ASSERT_GL_NO_ERROR();
4267 }
4268
4269 void testTearDown() override
4270 {
4271 glDeleteTextures(1, &mRenderableTexture);
4272 glDeleteTextures(1, &mTestTexture);
4273 glDeleteFramebuffers(1, &mFBO);
4274 glDeleteRenderbuffers(1, &mRenderbuffer);
4275
4276 Texture2DTest::testTearDown();
4277 }
4278
4279 void setupFormatTextures(GLenum internalformat, GLenum format, GLenum type, GLvoid *imageData)
4280 {
4281 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4282 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4283
4284 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4285 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4286 mRenderableTexture, 0);
4287
4288 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4289 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
4290
4291 EXPECT_GL_NO_ERROR();
4292 }
4293
4294 void testRGTexture(GLColor expectedColor)
4295 {
4296 drawQuad(mProgram, "position", 0.5f);
4297
4298 EXPECT_GL_NO_ERROR();
4299 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, kPixelTolerance);
4300 }
4301
4302 void testRGRender(GLenum internalformat, GLenum format)
4303 {
4304 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4305 glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
4306 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4307 mRenderbuffer);
4308 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4309 EXPECT_GL_NO_ERROR();
4310
4311 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4312 glClear(GL_COLOR_BUFFER_BIT);
4313
4314 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
4315
4316 ASSERT_GL_NO_ERROR();
4317 EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor(255u, 255u, 255u, 255u)));
4318 }
4319
4320 GLuint mRenderableTexture;
4321 GLuint mTestTexture;
4322 GLuint mFBO;
4323 GLuint mRenderbuffer;
4324};
4325
4326// Test unorm texture formats enabled by the GL_EXT_texture_rg extension.
4327TEST_P(Texture2DRGTest, TextureRGUNormTest)
4328{
4329 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4330
4331 GLubyte pixelValue = 0xab;
4332 GLubyte imageData[] = {pixelValue, pixelValue};
4333
4334 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE, imageData);
4335 testRGTexture(
4336 SliceFormatColor(GL_RED_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4337 testRGRender(GL_R8_EXT, GL_RED_EXT);
4338
4339 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE, imageData);
4340 testRGTexture(
4341 SliceFormatColor(GL_RG_EXT, GLColor(pixelValue, pixelValue, pixelValue, pixelValue)));
4342 testRGRender(GL_RG8_EXT, GL_RG_EXT);
4343}
4344
4345// Test float texture formats enabled by the GL_EXT_texture_rg extension.
4346TEST_P(Texture2DRGTest, TextureRGFloatTest)
4347{
4348 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4349 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4350
4351 GLfloat pixelValue = 0.54321;
4352 GLfloat imageData[] = {pixelValue, pixelValue};
4353
4354 GLubyte expectedValue = static_cast<GLubyte>(pixelValue * 255.0f);
4355 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4356
4357 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_FLOAT, imageData);
4358 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4359
4360 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_FLOAT, imageData);
4361 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4362}
4363
4364// Test half-float texture formats enabled by the GL_EXT_texture_rg extension.
Mohan Maiya6caa2652019-09-11 08:06:13 -07004365TEST_P(Texture2DRGTest, TextureRGHalfFloatTest)
Mohan Maiya8f1169e2019-06-27 15:32:32 -07004366{
4367 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
4368 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4369
4370 GLfloat pixelValueFloat = 0.543f;
4371 GLhalf pixelValue = 0x3858;
4372 GLhalf imageData[] = {pixelValue, pixelValue};
4373
4374 GLubyte expectedValue = static_cast<GLubyte>(pixelValueFloat * 255.0f);
4375 GLColor expectedColor = GLColor(expectedValue, expectedValue, expectedValue, expectedValue);
4376
4377 setupFormatTextures(GL_RED_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES, imageData);
4378 testRGTexture(SliceFormatColor(GL_RED_EXT, expectedColor));
4379
4380 setupFormatTextures(GL_RG_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES, imageData);
4381 testRGTexture(SliceFormatColor(GL_RG_EXT, expectedColor));
4382}
4383
Mohan Maiya6caa2652019-09-11 08:06:13 -07004384class Texture2DFloatTest : public Texture2DTest
4385{
4386 protected:
4387 Texture2DFloatTest()
4388 : Texture2DTest(), mRenderableTexture(0), mTestTexture(0), mFBO(0), mRenderbuffer(0)
4389 {}
4390
4391 void testSetUp() override
4392 {
4393 Texture2DTest::testSetUp();
4394
4395 glActiveTexture(GL_TEXTURE0);
4396 glGenTextures(1, &mRenderableTexture);
4397 glGenTextures(1, &mTestTexture);
4398 glGenFramebuffers(1, &mFBO);
4399 glGenRenderbuffers(1, &mRenderbuffer);
4400
4401 setUpProgram();
4402 glUseProgram(mProgram);
4403 glUniform1i(mTexture2DUniformLocation, 0);
4404
4405 glBindTexture(GL_TEXTURE_2D, mRenderableTexture);
4406 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4407
4408 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4409 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4410 mRenderableTexture, 0);
4411
4412 ASSERT_GL_NO_ERROR();
4413 }
4414
4415 void testTearDown() override
4416 {
4417 glDeleteTextures(1, &mRenderableTexture);
4418 glDeleteTextures(1, &mTestTexture);
4419 glDeleteFramebuffers(1, &mFBO);
4420 glDeleteRenderbuffers(1, &mRenderbuffer);
4421
4422 Texture2DTest::testTearDown();
4423 }
4424
4425 void testFloatTextureSample(GLenum internalFormat, GLenum format, GLenum type)
4426 {
4427 constexpr GLfloat imageDataFloat[] = {
4428 0.2f,
4429 0.3f,
4430 0.4f,
4431 0.5f,
4432 };
4433 constexpr GLhalf imageDataHalf[] = {
4434 0x3266,
4435 0x34CD,
4436 0x3666,
4437 0x3800,
4438 };
4439 GLColor expectedValue;
4440 for (int i = 0; i < 4; i++)
4441 {
4442 expectedValue[i] = static_cast<GLubyte>(imageDataFloat[i] * 255.0f);
4443 }
4444
4445 const GLvoid *imageData;
4446 switch (type)
4447 {
4448 case GL_FLOAT:
4449 imageData = imageDataFloat;
4450 break;
4451 case GL_HALF_FLOAT:
4452 case GL_HALF_FLOAT_OES:
4453 imageData = imageDataHalf;
4454 break;
4455 default:
4456 imageData = nullptr;
4457 }
4458 ASSERT(imageData != nullptr);
4459
4460 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4461 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, imageData);
4462
4463 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4464 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4465
4466 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4467 drawQuad(mProgram, "position", 0.5f);
4468
4469 EXPECT_GL_NO_ERROR();
4470 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, expectedValue), kPixelTolerance);
4471 }
4472
4473 void testFloatTextureLinear(GLenum internalFormat, GLenum format, GLenum type)
4474 {
4475 int numComponents;
4476 switch (format)
4477 {
4478 case GL_RGBA:
4479 numComponents = 4;
4480 break;
4481 case GL_RGB:
4482 numComponents = 3;
4483 break;
4484 case GL_LUMINANCE_ALPHA:
4485 numComponents = 2;
4486 break;
4487 case GL_LUMINANCE:
4488 case GL_ALPHA:
4489 numComponents = 1;
4490 break;
4491 default:
4492 numComponents = 0;
4493 }
4494 ASSERT(numComponents > 0);
4495
4496 constexpr GLfloat pixelIntensitiesFloat[] = {0.0f, 1.0f, 0.0f, 1.0f};
4497 constexpr GLhalf pixelIntensitiesHalf[] = {0x0000, 0x3C00, 0x0000, 0x3C00};
4498
4499 GLfloat imageDataFloat[16];
4500 GLhalf imageDataHalf[16];
4501 for (int i = 0; i < 4; i++)
4502 {
4503 for (int c = 0; c < numComponents; c++)
4504 {
4505 imageDataFloat[i * numComponents + c] = pixelIntensitiesFloat[i];
4506 imageDataHalf[i * numComponents + c] = pixelIntensitiesHalf[i];
4507 }
4508 }
4509
4510 const GLvoid *imageData;
4511 switch (type)
4512 {
4513 case GL_FLOAT:
4514 imageData = imageDataFloat;
4515 break;
4516 case GL_HALF_FLOAT:
4517 case GL_HALF_FLOAT_OES:
4518 imageData = imageDataHalf;
4519 break;
4520 default:
4521 imageData = nullptr;
4522 }
4523 ASSERT(imageData != nullptr);
4524
4525 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4526 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 2, 2, 0, format, type, imageData);
4527
4528 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4529 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4530
4531 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4532 drawQuad(mProgram, "position", 0.5f);
4533
4534 EXPECT_GL_NO_ERROR();
4535 // Source texture contains 2 black pixels and 2 white pixels, we sample in the center so we
4536 // should expect the final value to be gray (halfway in-between)
4537 EXPECT_PIXEL_COLOR_NEAR(0, 0, SliceFormatColor(format, GLColor(127u, 127u, 127u, 127u)),
4538 kPixelTolerance);
4539 }
4540
4541 bool performFloatTextureRender(GLenum internalFormat,
4542 GLenum renderBufferFormat,
4543 GLenum format,
4544 GLenum type)
4545 {
4546 glBindTexture(GL_TEXTURE_2D, mTestTexture);
4547 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
4548 glBindTexture(GL_TEXTURE_2D, 0);
4549
4550 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
4551 glRenderbufferStorage(GL_RENDERBUFFER, renderBufferFormat, 1, 1);
4552 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4553 mRenderbuffer);
4554 glBindRenderbuffer(GL_RENDERBUFFER, 0);
4555 EXPECT_GL_NO_ERROR();
4556
4557 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
4558 {
4559 return false;
4560 }
4561
4562 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
4563
4564 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
4565 glClear(GL_COLOR_BUFFER_BIT);
4566
4567 EXPECT_GL_NO_ERROR();
4568 return true;
4569 }
4570
4571 GLuint mRenderableTexture;
4572 GLuint mTestTexture;
4573 GLuint mFBO;
4574 GLuint mRenderbuffer;
4575};
4576
4577class Texture2DFloatTestES3 : public Texture2DFloatTest
4578{
4579 protected:
4580 void testFloatTextureRender(GLenum internalFormat, GLenum format, GLenum type)
4581 {
4582 bool framebufferComplete =
4583 performFloatTextureRender(internalFormat, internalFormat, format, type);
4584 EXPECT_TRUE(framebufferComplete);
4585 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4586 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4587 kPixelTolerance32F);
4588 }
4589};
4590
4591class Texture2DFloatTestES2 : public Texture2DFloatTest
4592{
4593 protected:
4594 bool checkFloatTextureRender(GLenum renderBufferFormat, GLenum format, GLenum type)
4595 {
4596 bool framebufferComplete =
4597 performFloatTextureRender(format, renderBufferFormat, format, type);
4598
4599 if (!framebufferComplete)
4600 {
4601 return false;
4602 }
4603
4604 EXPECT_PIXEL_COLOR32F_NEAR(0, 0,
4605 SliceFormatColor32F(format, GLColor32F(1.0f, 1.0f, 1.0f, 1.0f)),
4606 kPixelTolerance32F);
4607 return true;
4608 }
4609};
4610
4611// Test texture sampling for ES3 float texture formats
4612TEST_P(Texture2DFloatTestES3, TextureFloatSampleBasicTest)
4613{
4614 testFloatTextureSample(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4615 testFloatTextureSample(GL_RGB32F, GL_RGB, GL_FLOAT);
4616}
4617
4618// Test texture sampling for ES2 float texture formats
4619TEST_P(Texture2DFloatTestES2, TextureFloatSampleBasicTest)
4620{
4621 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4622 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_FLOAT);
4623 testFloatTextureSample(GL_RGB, GL_RGB, GL_FLOAT);
4624}
4625
4626// Test texture sampling for ES3 half float texture formats
4627TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleBasicTest)
4628{
4629 testFloatTextureSample(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4630 testFloatTextureSample(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4631}
4632
4633// Test texture sampling for ES2 half float texture formats
4634TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleBasicTest)
4635{
4636 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4637 testFloatTextureSample(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4638 testFloatTextureSample(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4639}
4640
4641// Test texture sampling for legacy GLES 2.0 float texture formats in ES3
4642TEST_P(Texture2DFloatTestES3, TextureFloatSampleLegacyTest)
4643{
4644 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4645
4646 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4647 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4648 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4649
4650 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4651 {
4652 testFloatTextureSample(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4653 testFloatTextureSample(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4654 testFloatTextureSample(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4655 }
4656}
4657
4658// Test texture sampling for legacy GLES 2.0 float texture formats in ES2
4659TEST_P(Texture2DFloatTestES2, TextureFloatSampleLegacyTest)
4660{
4661 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4662
4663 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4664 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4665 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4666}
4667
4668// Test texture sampling for legacy GLES 2.0 half float texture formats in ES3
4669TEST_P(Texture2DFloatTestES3, TextureHalfFloatSampleLegacyTest)
4670{
4671 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4672
4673 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4674 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4675 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4676
4677 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4678 {
4679 testFloatTextureSample(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4680 testFloatTextureSample(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4681 testFloatTextureSample(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4682 }
4683}
4684// Test texture sampling for legacy GLES 2.0 half float texture formats in ES2
4685TEST_P(Texture2DFloatTestES2, TextureHalfFloatSampleLegacyTest)
4686{
4687 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4688
4689 testFloatTextureSample(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4690 testFloatTextureSample(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4691 testFloatTextureSample(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4692}
4693
4694// Test linear sampling for ES3 32F formats
4695TEST_P(Texture2DFloatTestES3, TextureFloatLinearTest)
4696{
4697 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4698
4699 testFloatTextureLinear(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4700 testFloatTextureLinear(GL_RGB32F, GL_RGB, GL_FLOAT);
4701}
4702// Test linear sampling for ES2 32F formats
4703TEST_P(Texture2DFloatTestES2, TextureFloatLinearTest)
4704{
4705 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4706
4707 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4708
4709 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_FLOAT);
4710}
4711
4712// Test linear sampling for ES3 16F formats
4713TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearTest)
4714{
4715 // Half float formats must be linearly filterable in GLES 3.0 core
4716 testFloatTextureLinear(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4717 testFloatTextureLinear(GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
4718}
4719// Test linear sampling for ES2 16F formats
4720TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearTest)
4721{
4722 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4723 testFloatTextureLinear(GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES);
4724 testFloatTextureLinear(GL_RGB, GL_RGB, GL_HALF_FLOAT_OES);
4725}
4726
4727// Test linear sampling for legacy GLES 2.0 32F formats in ES3
4728TEST_P(Texture2DFloatTestES3, TextureFloatLinearLegacyTest)
4729{
4730 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4731 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4732
4733 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4734 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4735 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4736
4737 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4738 {
4739 testFloatTextureLinear(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT);
4740 testFloatTextureLinear(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT);
4741 testFloatTextureLinear(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT);
4742 }
4743}
4744// Test linear sampling for legacy GLES 2.0 32F formats in ES2
4745TEST_P(Texture2DFloatTestES2, TextureFloatLinearLegacyTest)
4746{
4747 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
4748 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float_linear"));
4749
4750 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT);
4751 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_FLOAT);
4752 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT);
4753}
4754
4755// Test linear sampling for legacy GLES 2.0 16F formats in ES3
4756TEST_P(Texture2DFloatTestES3, TextureHalfFloatLinearLegacyTest)
4757{
4758 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4759 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4760
4761 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4762 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4763 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4764
4765 if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
4766 {
4767 testFloatTextureLinear(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT);
4768 testFloatTextureLinear(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT);
4769 testFloatTextureLinear(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT);
4770 }
4771}
4772// Test linear sampling for legacy GLES 2.0 16F formats in ES2
4773TEST_P(Texture2DFloatTestES2, TextureHalfFloatLinearLegacyTest)
4774{
4775 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
4776 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float_linear"));
4777
4778 testFloatTextureLinear(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES);
4779 testFloatTextureLinear(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES);
4780 testFloatTextureLinear(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES);
4781}
4782
4783// Test color-renderability for ES3 float and half float textures
4784TEST_P(Texture2DFloatTestES3, TextureFloatRenderTest)
4785{
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07004786 // http://anglebug.com/4092
4787 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07004788 // EXT_color_buffer_float covers float, half float, and 11-11-10 float formats
4789 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
4790
4791 testFloatTextureRender(GL_R32F, GL_RED, GL_FLOAT);
4792 testFloatTextureRender(GL_RG32F, GL_RG, GL_FLOAT);
4793 testFloatTextureRender(GL_RGBA32F, GL_RGBA, GL_FLOAT);
4794
4795 testFloatTextureRender(GL_R16F, GL_RED, GL_HALF_FLOAT);
4796 testFloatTextureRender(GL_RG16F, GL_RG, GL_HALF_FLOAT);
4797 testFloatTextureRender(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
4798
4799 testFloatTextureRender(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
4800}
4801
4802// Test color-renderability for ES2 half float textures
4803TEST_P(Texture2DFloatTestES2, TextureFloatRenderTest)
4804{
4805 // EXT_color_buffer_half_float requires at least one format to be renderable, but does not
4806 // require a specific one
4807 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
Zhenyao Mo20bb47d2019-09-16 12:55:30 -07004808 // https://crbug.com/1003971
4809 ANGLE_SKIP_TEST_IF(IsOzone());
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07004810 // http://anglebug.com/4092
4811 ANGLE_SKIP_TEST_IF(IsD3D9());
Mohan Maiya6caa2652019-09-11 08:06:13 -07004812
4813 bool atLeastOneSupported = false;
4814
4815 if (IsGLExtensionEnabled("GL_OES_texture_half_float") ||
4816 IsGLExtensionEnabled("GL_OES_texture_half_float"))
4817 {
4818 atLeastOneSupported |= checkFloatTextureRender(GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
4819 atLeastOneSupported |= checkFloatTextureRender(GL_RG16F_EXT, GL_RG_EXT, GL_HALF_FLOAT_OES);
4820 }
4821 if (IsGLExtensionEnabled("GL_OES_texture_half_float"))
4822 {
4823 atLeastOneSupported |= checkFloatTextureRender(GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
4824
4825 // If OES_texture_half_float is supported, then RGBA half float textures must be renderable
4826 bool rgbaSupported = checkFloatTextureRender(GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
4827 EXPECT_TRUE(rgbaSupported);
4828 atLeastOneSupported |= rgbaSupported;
4829 }
4830
4831 EXPECT_TRUE(atLeastOneSupported);
4832}
4833
Olli Etuaho95faa232016-06-07 14:01:53 -07004834// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads.
4835// GLES 3.0.4 section 3.8.3.
4836TEST_P(Texture2DTestES3, UnpackSkipImages2D)
4837{
Yuly Novikovd18c0482019-04-04 19:56:43 -04004838 // Crashes on Nexus 5X due to a driver bug. http://anglebug.com/1429
4839 ANGLE_SKIP_TEST_IF((IsNexus5X() || IsNexus6P()) && IsOpenGLES());
Olli Etuaho95faa232016-06-07 14:01:53 -07004840
4841 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4842 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4843 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4844 ASSERT_GL_NO_ERROR();
4845
4846 // SKIP_IMAGES should not have an effect on uploading 2D textures
4847 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000);
4848 ASSERT_GL_NO_ERROR();
4849
4850 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
4851
4852 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4853 pixelsGreen.data());
4854 ASSERT_GL_NO_ERROR();
4855
4856 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE,
4857 pixelsGreen.data());
4858 ASSERT_GL_NO_ERROR();
4859
4860 glUseProgram(mProgram);
4861 drawQuad(mProgram, "position", 0.5f);
4862 ASSERT_GL_NO_ERROR();
4863
4864 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4865}
4866
Olli Etuaho989cac32016-06-08 16:18:49 -07004867// Test that skip defined in unpack parameters is taken into account when determining whether
4868// unpacking source extends outside unpack buffer bounds.
4869TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds)
4870{
4871 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4872 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4873 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4874 ASSERT_GL_NO_ERROR();
4875
4876 GLBuffer buf;
4877 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
4878 std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green);
4879 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
4880 GL_DYNAMIC_COPY);
4881 ASSERT_GL_NO_ERROR();
4882
4883 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
4884 ASSERT_GL_NO_ERROR();
4885
4886 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1);
4887 ASSERT_GL_NO_ERROR();
4888
4889 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
4890 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4891
4892 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
4893 glPixelStorei(GL_UNPACK_SKIP_ROWS, 1);
4894 ASSERT_GL_NO_ERROR();
4895
4896 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0);
4897 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
4898}
4899
Olli Etuaho218cf9e2016-05-20 13:55:24 +03004900// Test that unpacking rows that overlap in a pixel unpack buffer works as expected.
4901TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer)
4902{
Yunchao He9550c602018-02-13 14:47:05 +08004903 ANGLE_SKIP_TEST_IF(IsD3D11());
4904
4905 // Incorrect rendering results seen on OSX AMD.
4906 ANGLE_SKIP_TEST_IF(IsOSX() && IsAMD());
Olli Etuaho218cf9e2016-05-20 13:55:24 +03004907
4908 const GLuint width = 8u;
4909 const GLuint height = 8u;
4910 const GLuint unpackRowLength = 5u;
4911 const GLuint unpackSkipPixels = 1u;
4912
4913 setWindowWidth(width);
4914 setWindowHeight(height);
4915
4916 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4917 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4918 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4919 ASSERT_GL_NO_ERROR();
4920
4921 GLBuffer buf;
4922 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get());
4923 std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels,
4924 GLColor::green);
4925
4926 for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel)
4927 {
4928 pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255);
4929 }
4930
4931 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(),
4932 GL_DYNAMIC_COPY);
4933 ASSERT_GL_NO_ERROR();
4934
4935 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
4936 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
4937 ASSERT_GL_NO_ERROR();
4938
4939 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
4940 ASSERT_GL_NO_ERROR();
4941
4942 glUseProgram(mProgram);
4943 drawQuad(mProgram, "position", 0.5f);
4944 ASSERT_GL_NO_ERROR();
4945
4946 GLuint windowPixelCount = getWindowWidth() * getWindowHeight();
4947 std::vector<GLColor> actual(windowPixelCount, GLColor::black);
4948 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
4949 actual.data());
4950 std::vector<GLColor> expected(windowPixelCount, GLColor::green);
4951 EXPECT_EQ(expected, actual);
4952}
4953
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04004954template <typename T>
4955T UNorm(double value)
4956{
4957 return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max()));
4958}
4959
4960// Test rendering a depth texture with mipmaps.
4961TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps)
4962{
Zhenyao Moe520d7c2017-01-13 13:46:49 -08004963 // TODO(cwallez) this is failing on Intel Win7 OpenGL.
4964 // TODO(zmo) this is faling on Win Intel HD 530 Debug.
Jiawei Shaoaf0f31d2018-09-27 15:42:31 +08004965 // http://anglebug.com/1706
4966 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsOpenGL());
Corentin Walleze731d8a2016-09-07 10:56:25 -04004967
Jamie Madill24980272019-04-03 09:03:51 -04004968 // Seems to fail on AMD D3D11. Possibly driver bug. http://anglebug.com/3342
4969 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsD3D11());
4970
Cody Northrop988f7172019-09-30 15:52:37 -06004971 // TODO(cnorthrop): Also failing on Vulkan/Windows/AMD. http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06004972 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
4973
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04004974 const int size = getWindowWidth();
4975
4976 auto dim = [size](int level) { return size >> level; };
Jamie Madill14718762016-09-06 15:56:54 -04004977 int levels = gl::log2(size);
Jamie Madill9e3d7aa2016-09-02 15:19:43 -04004978
4979 glActiveTexture(GL_TEXTURE0);
4980 glBindTexture(GL_TEXTURE_2D, mTexture2D);
4981 glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size);
4982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4984 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4985 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4986 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4987 ASSERT_GL_NO_ERROR();
4988
4989 glUseProgram(mProgram);
4990 glUniform1i(mTexture2DUniformLocation, 0);
4991
4992 std::vector<unsigned char> expected;
4993
4994 for (int level = 0; level < levels; ++level)
4995 {
4996 double value = (static_cast<double>(level) / static_cast<double>(levels - 1));
4997 expected.push_back(UNorm<unsigned char>(value));
4998
4999 int levelDim = dim(level);
5000
5001 ASSERT_GT(levelDim, 0);
5002
5003 std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value));
5004 glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT,
5005 GL_UNSIGNED_INT, initData.data());
5006 }
5007 ASSERT_GL_NO_ERROR();
5008
5009 for (int level = 0; level < levels; ++level)
5010 {
5011 glViewport(0, 0, dim(level), dim(level));
5012 drawQuad(mProgram, "position", 0.5f);
5013 GLColor actual = ReadColor(0, 0);
5014 EXPECT_NEAR(expected[level], actual.R, 10u);
5015 }
5016
5017 ASSERT_GL_NO_ERROR();
5018}
5019
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005020class Texture2DDepthTest : public Texture2DTest
5021{
5022 protected:
5023 Texture2DDepthTest() : Texture2DTest() {}
5024
5025 const char *getVertexShaderSource() override
5026 {
5027 return "attribute vec4 vPosition;\n"
5028 "void main() {\n"
5029 " gl_Position = vPosition;\n"
5030 "}\n";
5031 }
5032
5033 const char *getFragmentShaderSource() override
5034 {
5035 return "precision mediump float;\n"
5036 "uniform sampler2D ShadowMap;"
5037 "void main() {\n"
5038 " vec4 shadow_value = texture2D(ShadowMap, vec2(0.5, 0.5));"
5039 " if (shadow_value.x == shadow_value.z && shadow_value.x != 0.0) {"
5040 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"
5041 " } else {"
5042 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
5043 " }"
5044 "}\n";
5045 }
5046
5047 bool checkTexImageFormatSupport(GLenum format, GLenum internalformat, GLenum type)
5048 {
5049 EXPECT_GL_NO_ERROR();
5050
5051 GLTexture tex;
5052 glBindTexture(GL_TEXTURE_2D, tex);
5053 glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
5054
5055 return (glGetError() == GL_NO_ERROR);
5056 }
5057
5058 void testBehavior(bool useSizedComponent)
5059 {
5060 int w = getWindowWidth();
5061 int h = getWindowHeight();
5062 GLuint format = GL_DEPTH_COMPONENT;
5063 GLuint internalFormat = GL_DEPTH_COMPONENT;
5064
5065 if (useSizedComponent)
5066 {
5067 internalFormat = GL_DEPTH_COMPONENT24;
5068 }
5069
5070 GLFramebuffer fbo;
5071 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5072 ASSERT_GL_NO_ERROR();
5073
5074 GLTexture depthTexture;
5075 glBindTexture(GL_TEXTURE_2D, depthTexture);
5076 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5080
5081 TexCoordDrawTest::setUpProgram();
5082 GLint shadowMapLocation = glGetUniformLocation(mProgram, "ShadowMap");
5083 ASSERT_NE(-1, shadowMapLocation);
5084
5085 GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
5086 ASSERT_NE(-1, positionLocation);
5087
5088 ANGLE_SKIP_TEST_IF(!checkTexImageFormatSupport(format, internalFormat, GL_UNSIGNED_INT));
5089 glBindTexture(GL_TEXTURE_2D, depthTexture);
5090 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, GL_UNSIGNED_INT, nullptr);
5091 ASSERT_GL_NO_ERROR();
5092
5093 // try adding a color buffer.
5094 GLuint colorTex = 0;
5095 glGenTextures(1, &colorTex);
5096 glBindTexture(GL_TEXTURE_2D, colorTex);
5097 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
5098 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
5099 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5101 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5102 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
5103 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
5104 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5105 ASSERT_GL_NO_ERROR();
5106
5107 glViewport(0, 0, w, h);
5108 // Fill depthTexture with 0.75
5109 glClearDepthf(0.75);
5110 glClear(GL_DEPTH_BUFFER_BIT);
5111
5112 // Revert to normal framebuffer to test depth shader
5113 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5114 glViewport(0, 0, w, h);
5115 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5116 glClearDepthf(0.0f);
5117 ASSERT_GL_NO_ERROR();
5118
5119 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
5120 ASSERT_GL_NO_ERROR();
5121
5122 glActiveTexture(GL_TEXTURE0);
5123 glBindTexture(GL_TEXTURE_2D, depthTexture);
5124
5125 glUseProgram(mProgram);
5126 ASSERT_GL_NO_ERROR();
5127
5128 glUniform1i(shadowMapLocation, 0);
5129
5130 const GLfloat gTriangleVertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f};
5131
5132 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
5133 ASSERT_GL_NO_ERROR();
5134 glEnableVertexAttribArray(positionLocation);
5135 ASSERT_GL_NO_ERROR();
5136 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5137 ASSERT_GL_NO_ERROR();
5138
5139 GLuint pixels[1];
5140 glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
5141 ASSERT_GL_NO_ERROR();
5142
5143 // The GLES 3.x spec says that the depth texture sample can be found in the RED component.
5144 // However, the OES_depth_texture indicates that the depth value is treated as luminance and
5145 // is in all the color components. Multiple implementations implement a workaround that
5146 // follows the OES_depth_texture behavior if the internalformat given at glTexImage2D was a
5147 // unsized format (e.g. DEPTH_COMPONENT) and the GLES 3.x behavior if it was a sized
5148 // internalformat such as GL_DEPTH_COMPONENT24. The shader will write out a different color
5149 // depending on if it sees the texture sample in only the RED component.
5150 if (useSizedComponent)
5151 {
5152 ASSERT_NE(pixels[0], 0xff0000ff);
5153 }
5154 else
5155 {
5156 ASSERT_EQ(pixels[0], 0xff0000ff);
5157 }
5158
5159 glBindFramebuffer(GL_FRAMEBUFFER, 0);
5160 glDeleteProgram(mProgram);
5161 }
5162};
5163
5164// Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
5165TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
5166{
5167 ANGLE_SKIP_TEST_IF(IsD3D11());
5168 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
Tobin Ehlis7af26762019-10-23 16:18:57 -06005169 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture") &&
5170 !IsGLExtensionEnabled("GL_OES_depth_texture"));
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005171 // http://anglebug.com/4092
5172 ANGLE_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
Courtney Goeltzenleuchter1f2782e2019-08-29 14:19:23 -06005173
5174 // When the depth texture is specified with unsized internalformat implementations follow
5175 // OES_depth_texture behavior. Otherwise they follow GLES 3.0 behavior.
5176 testBehavior(false);
5177}
5178
5179// Test depth texture compatibility with GLES3 using sized internalformat.
5180TEST_P(Texture2DDepthTest, DepthTextureES3Compatibility)
5181{
5182 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
5183
5184 testBehavior(true);
5185}
5186
Jamie Madill7ffdda92016-09-08 13:26:51 -04005187// Tests unpacking into the unsized GL_ALPHA format.
5188TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer)
5189{
Jamie Madill7ffdda92016-09-08 13:26:51 -04005190 // Initialize the texure.
5191 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5192 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA,
5193 GL_UNSIGNED_BYTE, nullptr);
5194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5196
5197 std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127);
5198
5199 // Pull in the color data from the unpack buffer.
Jamie Madill2e600342016-09-19 13:56:40 -04005200 GLBuffer unpackBuffer;
Jamie Madill7ffdda92016-09-08 13:26:51 -04005201 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5202 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5203 glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(),
5204 GL_STATIC_DRAW);
5205
5206 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA,
5207 GL_UNSIGNED_BYTE, nullptr);
5208
5209 // Clear to a weird color to make sure we're drawing something.
5210 glClearColor(0.5f, 0.8f, 1.0f, 0.2f);
5211 glClear(GL_COLOR_BUFFER_BIT);
5212
5213 // Draw with the alpha texture and verify.
5214 drawQuad(mProgram, "position", 0.5f);
Jamie Madill7ffdda92016-09-08 13:26:51 -04005215
5216 ASSERT_GL_NO_ERROR();
5217 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1);
5218}
5219
Jamie Madill2e600342016-09-19 13:56:40 -04005220// Ensure stale unpack data doesn't propagate in D3D11.
5221TEST_P(Texture2DTestES3, StaleUnpackData)
5222{
5223 // Init unpack buffer.
5224 GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2;
5225 std::vector<GLColor> pixels(pixelCount, GLColor::red);
5226
5227 GLBuffer unpackBuffer;
5228 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5229 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get());
5230 GLsizei bufferSize = pixelCount * sizeof(GLColor);
5231 glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW);
5232
5233 // Create from unpack buffer.
5234 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5235 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0,
5236 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5239
5240 drawQuad(mProgram, "position", 0.5f);
5241
5242 ASSERT_GL_NO_ERROR();
5243 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5244
5245 // Fill unpack with green, recreating buffer.
5246 pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green);
5247 GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor);
5248 glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW);
5249
5250 // Reinit texture with green.
5251 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA,
5252 GL_UNSIGNED_BYTE, nullptr);
5253
5254 drawQuad(mProgram, "position", 0.5f);
5255
5256 ASSERT_GL_NO_ERROR();
5257 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5258}
5259
Geoff Langfb7685f2017-11-13 11:44:11 -05005260// Ensure that texture parameters passed as floats that are converted to ints are rounded before
5261// validating they are less than 0.
5262TEST_P(Texture2DTestES3, TextureBaseMaxLevelRoundingValidation)
5263{
5264 GLTexture texture;
5265 glBindTexture(GL_TEXTURE_2D, texture);
5266
5267 // Use a negative number that will round to zero when converted to an integer
5268 // According to the spec(2.3.1 Data Conversion For State - Setting Commands):
5269 // "Validation of values performed by state-setting commands is performed after conversion,
5270 // unless specified otherwise for a specific command."
5271 GLfloat param = -7.30157126e-07f;
5272 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, param);
5273 EXPECT_GL_NO_ERROR();
5274
5275 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, param);
5276 EXPECT_GL_NO_ERROR();
5277}
5278
Jamie Madillf097e232016-11-05 00:44:15 -04005279// This test covers a D3D format redefinition bug for 3D textures. The base level format was not
5280// being properly checked, and the texture storage of the previous texture format was persisting.
5281// This would result in an ASSERT in debug and incorrect rendering in release.
5282// See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html.
5283TEST_P(Texture3DTestES3, FormatRedefinitionBug)
5284{
5285 GLTexture tex;
5286 glBindTexture(GL_TEXTURE_3D, tex.get());
5287 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5288
5289 GLFramebuffer framebuffer;
5290 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
5291 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0);
5292
5293 glCheckFramebufferStatus(GL_FRAMEBUFFER);
5294
5295 std::vector<uint8_t> pixelData(100, 0);
5296
5297 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr);
5298 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
5299 pixelData.data());
5300
5301 ASSERT_GL_NO_ERROR();
5302}
5303
Corentin Wallezd2627992017-04-28 17:17:03 -04005304// Test basic pixel unpack buffer OOB checks when uploading to a 2D or 3D texture
5305TEST_P(Texture3DTestES3, BasicUnpackBufferOOB)
5306{
5307 // 2D tests
5308 {
5309 GLTexture tex;
5310 glBindTexture(GL_TEXTURE_2D, tex.get());
5311
5312 GLBuffer pbo;
5313 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5314
5315 // Test OOB
5316 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 - 1, nullptr, GL_STATIC_DRAW);
5317 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5318 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5319
5320 // Test OOB
5321 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2, nullptr, GL_STATIC_DRAW);
5322 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5323 ASSERT_GL_NO_ERROR();
5324 }
5325
5326 // 3D tests
5327 {
5328 GLTexture tex;
5329 glBindTexture(GL_TEXTURE_3D, tex.get());
5330
5331 GLBuffer pbo;
5332 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.get());
5333
5334 // Test OOB
5335 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2 - 1, nullptr,
5336 GL_STATIC_DRAW);
5337 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5338 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
5339
5340 // Test OOB
5341 glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLColor) * 2 * 2 * 2, nullptr, GL_STATIC_DRAW);
5342 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5343 ASSERT_GL_NO_ERROR();
5344 }
5345}
5346
Jamie Madill3ed60422017-09-07 11:32:52 -04005347// Tests behaviour with a single texture and multiple sampler objects.
5348TEST_P(Texture2DTestES3, SingleTextureMultipleSamplers)
5349{
5350 GLint maxTextureUnits = 0;
5351 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
5352 ANGLE_SKIP_TEST_IF(maxTextureUnits < 4);
5353
5354 constexpr int kSize = 16;
5355
5356 // Make a single-level texture, fill it with red.
5357 std::vector<GLColor> redColors(kSize * kSize, GLColor::red);
5358 GLTexture tex;
5359 glBindTexture(GL_TEXTURE_2D, tex);
5360 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5361 redColors.data());
5362 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5364
5365 // Simple sanity check.
5366 draw2DTexturedQuad(0.5f, 1.0f, true);
5367 ASSERT_GL_NO_ERROR();
5368 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5369
5370 // Bind texture to unit 1 with a sampler object making it incomplete.
5371 GLSampler sampler;
5372 glBindSampler(0, sampler);
5373 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5374 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5375
5376 // Make a mipmap texture, fill it with blue.
5377 std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
5378 GLTexture mipmapTex;
5379 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5380 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5381 blueColors.data());
5382 glGenerateMipmap(GL_TEXTURE_2D);
5383
5384 // Draw with the sampler, expect blue.
5385 draw2DTexturedQuad(0.5f, 1.0f, true);
5386 ASSERT_GL_NO_ERROR();
5387 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5388
5389 // Simple multitexturing program.
Jamie Madill35cd7332018-12-02 12:03:33 -05005390 constexpr char kVS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005391 "#version 300 es\n"
5392 "in vec2 position;\n"
5393 "out vec2 texCoord;\n"
5394 "void main()\n"
5395 "{\n"
5396 " gl_Position = vec4(position, 0, 1);\n"
5397 " texCoord = position * 0.5 + vec2(0.5);\n"
5398 "}";
Jamie Madill35cd7332018-12-02 12:03:33 -05005399
5400 constexpr char kFS[] =
Jamie Madill3ed60422017-09-07 11:32:52 -04005401 "#version 300 es\n"
5402 "precision mediump float;\n"
5403 "in vec2 texCoord;\n"
5404 "uniform sampler2D tex1;\n"
5405 "uniform sampler2D tex2;\n"
5406 "uniform sampler2D tex3;\n"
5407 "uniform sampler2D tex4;\n"
5408 "out vec4 color;\n"
5409 "void main()\n"
5410 "{\n"
5411 " color = (texture(tex1, texCoord) + texture(tex2, texCoord) \n"
5412 " + texture(tex3, texCoord) + texture(tex4, texCoord)) * 0.25;\n"
5413 "}";
5414
Jamie Madill35cd7332018-12-02 12:03:33 -05005415 ANGLE_GL_PROGRAM(program, kVS, kFS);
Jamie Madill3ed60422017-09-07 11:32:52 -04005416
5417 std::array<GLint, 4> texLocations = {
5418 {glGetUniformLocation(program, "tex1"), glGetUniformLocation(program, "tex2"),
5419 glGetUniformLocation(program, "tex3"), glGetUniformLocation(program, "tex4")}};
5420 for (GLint location : texLocations)
5421 {
5422 ASSERT_NE(-1, location);
5423 }
5424
5425 // Init the uniform data.
5426 glUseProgram(program);
5427 for (GLint location = 0; location < 4; ++location)
5428 {
5429 glUniform1i(texLocations[location], location);
5430 }
5431
5432 // Initialize four samplers
5433 GLSampler samplers[4];
5434
5435 // 0: non-mipped.
5436 glBindSampler(0, samplers[0]);
5437 glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5438 glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5439
5440 // 1: mipped.
5441 glBindSampler(1, samplers[1]);
5442 glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5443 glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5444
5445 // 2: non-mipped.
5446 glBindSampler(2, samplers[2]);
5447 glSamplerParameteri(samplers[2], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5448 glSamplerParameteri(samplers[2], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5449
5450 // 3: mipped.
5451 glBindSampler(3, samplers[3]);
5452 glSamplerParameteri(samplers[3], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5453 glSamplerParameteri(samplers[3], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5454
5455 // Bind two blue mipped textures and two single layer textures, should all draw.
5456 glActiveTexture(GL_TEXTURE0);
5457 glBindTexture(GL_TEXTURE_2D, tex);
5458
5459 glActiveTexture(GL_TEXTURE1);
5460 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5461
5462 glActiveTexture(GL_TEXTURE2);
5463 glBindTexture(GL_TEXTURE_2D, tex);
5464
5465 glActiveTexture(GL_TEXTURE3);
5466 glBindTexture(GL_TEXTURE_2D, mipmapTex);
5467
5468 ASSERT_GL_NO_ERROR();
5469
5470 drawQuad(program, "position", 0.5f);
5471 ASSERT_GL_NO_ERROR();
5472 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 255, 2);
5473
5474 // Bind four single layer textures, two should be incomplete.
5475 glActiveTexture(GL_TEXTURE1);
5476 glBindTexture(GL_TEXTURE_2D, tex);
5477
5478 glActiveTexture(GL_TEXTURE3);
5479 glBindTexture(GL_TEXTURE_2D, tex);
5480
5481 drawQuad(program, "position", 0.5f);
5482 ASSERT_GL_NO_ERROR();
5483 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 2);
5484}
5485
Martin Radev7e2c0d32017-09-15 14:25:42 +03005486// The test is added to cover http://anglebug.com/2153. Cubemap completeness checks used to start
5487// always at level 0 instead of the base level resulting in an incomplete texture if the faces at
5488// level 0 are not created. The test creates a cubemap texture, specifies the images only for mip
5489// level 1 filled with white color, updates the base level to be 1 and renders a quad. The program
5490// samples the cubemap using a direction vector (1,1,1).
5491TEST_P(TextureCubeTestES3, SpecifyAndSampleFromBaseLevel1)
5492{
Yunchao He2f23f352018-02-11 22:11:37 +08005493 // Check http://anglebug.com/2155.
5494 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
5495
Jamie Madill35cd7332018-12-02 12:03:33 -05005496 constexpr char kVS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005497 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005498 precision mediump float;
5499 in vec3 pos;
5500 void main() {
5501 gl_Position = vec4(pos, 1.0);
5502 })";
Martin Radev7e2c0d32017-09-15 14:25:42 +03005503
Jamie Madill35cd7332018-12-02 12:03:33 -05005504 constexpr char kFS[] =
Martin Radev7e2c0d32017-09-15 14:25:42 +03005505 R"(#version 300 es
Olli Etuahoa20af6d2017-09-18 13:32:29 +03005506 precision mediump float;
5507 out vec4 color;
5508 uniform samplerCube uTex;
5509 void main(){
5510 color = texture(uTex, vec3(1.0));
5511 })";
Jamie Madill35cd7332018-12-02 12:03:33 -05005512
5513 ANGLE_GL_PROGRAM(program, kVS, kFS);
Martin Radev7e2c0d32017-09-15 14:25:42 +03005514 glUseProgram(program);
5515
5516 glUniform1i(glGetUniformLocation(program, "uTex"), 0);
5517 glActiveTexture(GL_TEXTURE0);
5518
5519 GLTexture cubeTex;
5520 glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
5521
5522 const int kFaceWidth = 1;
5523 const int kFaceHeight = 1;
5524 std::vector<uint32_t> texData(kFaceWidth * kFaceHeight, 0xFFFFFFFF);
5525 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5526 GL_UNSIGNED_BYTE, texData.data());
5527 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5528 GL_UNSIGNED_BYTE, texData.data());
5529 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5530 GL_UNSIGNED_BYTE, texData.data());
5531 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5532 GL_UNSIGNED_BYTE, texData.data());
5533 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5534 GL_UNSIGNED_BYTE, texData.data());
5535 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1, GL_RGBA8, kFaceWidth, kFaceHeight, 0, GL_RGBA,
5536 GL_UNSIGNED_BYTE, texData.data());
5537 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5538 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5539 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
5540 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
5541 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
5542 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1);
5543
5544 drawQuad(program, "pos", 0.5f, 1.0f, true);
5545 ASSERT_GL_NO_ERROR();
5546
5547 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5548}
5549
Jiawei Shao3c43b4d2018-02-23 11:08:28 +08005550// Verify that using negative texture base level and max level generates GL_INVALID_VALUE.
5551TEST_P(Texture2DTestES3, NegativeTextureBaseLevelAndMaxLevel)
5552{
5553 GLuint texture = create2DTexture();
5554
5555 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, -1);
5556 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5557
5558 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, -1);
5559 EXPECT_GL_ERROR(GL_INVALID_VALUE);
5560
5561 glDeleteTextures(1, &texture);
5562 EXPECT_GL_NO_ERROR();
5563}
5564
Olli Etuaho023371b2018-04-24 17:43:32 +03005565// Test setting base level after calling generateMipmap on a LUMA texture.
5566// Covers http://anglebug.com/2498
5567TEST_P(Texture2DTestES3, GenerateMipmapAndBaseLevelLUMA)
5568{
5569 glActiveTexture(GL_TEXTURE0);
5570 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5571
5572 constexpr const GLsizei kWidth = 8;
5573 constexpr const GLsizei kHeight = 8;
5574 std::array<GLubyte, kWidth * kHeight * 2> whiteData;
5575 whiteData.fill(255u);
5576
5577 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, kWidth, kHeight, 0, GL_LUMINANCE_ALPHA,
5578 GL_UNSIGNED_BYTE, whiteData.data());
5579 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
5580 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5581 glGenerateMipmap(GL_TEXTURE_2D);
5582 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5583 EXPECT_GL_NO_ERROR();
5584
5585 drawQuad(mProgram, "position", 0.5f);
5586 EXPECT_PIXEL_COLOR_EQ(0, 0, angle::GLColor::white);
5587}
5588
Till Rathmannc1551dc2018-08-15 17:04:49 +02005589// Covers a bug in the D3D11 backend: http://anglebug.com/2772
5590// When using a sampler the texture was created as if it has mipmaps,
5591// regardless what you specified in GL_TEXTURE_MIN_FILTER via
5592// glSamplerParameteri() -- mistakenly the default value
5593// GL_NEAREST_MIPMAP_LINEAR or the value set via glTexParameteri() was
5594// evaluated.
5595// If you didn't provide mipmaps and didn't let the driver generate them
5596// this led to not sampling your texture data when minification occurred.
5597TEST_P(Texture2DTestES3, MinificationWithSamplerNoMipmapping)
5598{
Cody Northrop988f7172019-09-30 15:52:37 -06005599 // TODO: Triage this failure on Vulkan: http://anglebug.com/3950
Cody Northropcb16fb52019-08-29 16:53:55 -06005600 ANGLE_SKIP_TEST_IF(IsVulkan());
5601
Jamie Madill35cd7332018-12-02 12:03:33 -05005602 constexpr char kVS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005603 "#version 300 es\n"
5604 "out vec2 texcoord;\n"
5605 "in vec4 position;\n"
5606 "void main()\n"
5607 "{\n"
5608 " gl_Position = vec4(position.xy * 0.1, 0.0, 1.0);\n"
5609 " texcoord = (position.xy * 0.5) + 0.5;\n"
5610 "}\n";
5611
Jamie Madill35cd7332018-12-02 12:03:33 -05005612 constexpr char kFS[] =
Till Rathmannc1551dc2018-08-15 17:04:49 +02005613 "#version 300 es\n"
5614 "precision highp float;\n"
5615 "uniform highp sampler2D tex;\n"
5616 "in vec2 texcoord;\n"
5617 "out vec4 fragColor;\n"
5618 "void main()\n"
5619 "{\n"
5620 " fragColor = texture(tex, texcoord);\n"
5621 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -05005622
5623 ANGLE_GL_PROGRAM(program, kVS, kFS);
Till Rathmannc1551dc2018-08-15 17:04:49 +02005624
5625 GLSampler sampler;
5626 glBindSampler(0, sampler);
5627 glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5628 glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5629
5630 glActiveTexture(GL_TEXTURE0);
5631 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5632
5633 const GLsizei texWidth = getWindowWidth();
5634 const GLsizei texHeight = getWindowHeight();
5635 const std::vector<GLColor> whiteData(texWidth * texHeight, GLColor::white);
5636
5637 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5638 whiteData.data());
5639 EXPECT_GL_NO_ERROR();
5640
5641 drawQuad(program, "position", 0.5f);
5642 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, angle::GLColor::white);
5643}
5644
Anders Leinof6cbe442019-04-18 15:32:07 +03005645// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5646// texture is output.
5647TEST_P(Texture2DIntegerTestES3, IntegerTextureNonZeroBaseLevel)
5648{
Yuly Novikovd2683452019-05-23 16:11:19 -04005649 // http://anglebug.com/3478
5650 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
5651
Anders Leinof6cbe442019-04-18 15:32:07 +03005652 glActiveTexture(GL_TEXTURE0);
5653 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5654 int width = getWindowWidth();
5655 int height = getWindowHeight();
5656 GLColor color = GLColor::green;
5657 std::vector<GLColor> pixels(width * height, color);
5658 GLint baseLevel = 1;
5659 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5660 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5661 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5662 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5663 GL_UNSIGNED_BYTE, pixels.data());
5664
5665 setUpProgram();
5666 glUseProgram(mProgram);
5667 glUniform1i(mTexture2DUniformLocation, 0);
5668 drawQuad(mProgram, "position", 0.5f);
5669
5670 EXPECT_GL_NO_ERROR();
5671 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5672 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5673}
5674
Anders Leino60cc7512019-05-06 09:25:27 +03005675// Draw a quad with an integer cube texture with a non-zero base level, and test that the color of
5676// the texture is output.
5677TEST_P(TextureCubeIntegerTestES3, IntegerCubeTextureNonZeroBaseLevel)
5678{
5679 // All output checks returned black, rather than the texture color.
5680 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
5681
5682 glActiveTexture(GL_TEXTURE0);
5683
5684 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5685 GLint baseLevel = 1;
5686 int width = getWindowWidth();
5687 int height = getWindowHeight();
5688 GLColor color = GLColor::green;
5689 std::vector<GLColor> pixels(width * height, color);
5690 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5691 {
5692 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, baseLevel, GL_RGBA8UI, width,
5693 height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5694 EXPECT_GL_NO_ERROR();
5695 }
5696 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, baseLevel);
5697 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5698 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5699
5700 glUseProgram(mProgram);
5701 glUniform1i(mTextureCubeUniformLocation, 0);
5702 drawQuad(mProgram, "position", 0.5f);
5703
5704 EXPECT_GL_NO_ERROR();
5705 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5706 EXPECT_PIXEL_COLOR_EQ(width - 1, 0, color);
5707 EXPECT_PIXEL_COLOR_EQ(0, height - 1, color);
5708 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5709}
5710
Anders Leinoe4452442019-05-09 13:29:49 +03005711// This test sets up a cube map with four distincly colored MIP levels.
5712// The size of the texture and the geometry is chosen such that levels 1 or 2 should be chosen at
5713// the corners of the screen.
5714TEST_P(TextureCubeIntegerEdgeTestES3, IntegerCubeTextureCorner)
5715{
5716 glActiveTexture(GL_TEXTURE0);
5717
5718 glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
5719 int width = getWindowWidth();
5720 int height = getWindowHeight();
5721 ASSERT_EQ(width, height);
5722 GLColor color[4] = {GLColor::white, GLColor::green, GLColor::blue, GLColor::red};
5723 for (GLint level = 0; level < 4; level++)
5724 {
5725 for (GLenum faceIndex = 0; faceIndex < 6; faceIndex++)
5726 {
5727 int levelWidth = (2 * width) >> level;
5728 int levelHeight = (2 * height) >> level;
5729 std::vector<GLColor> pixels(levelWidth * levelHeight, color[level]);
5730 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, GL_RGBA8UI, levelWidth,
5731 levelHeight, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5732 EXPECT_GL_NO_ERROR();
5733 }
5734 }
5735 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
5736 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5737 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 3);
5738
5739 glUseProgram(mProgram);
5740 glUniform1i(mTextureCubeUniformLocation, 0);
5741 drawQuad(mProgram, "position", 0.5f);
5742
5743 ASSERT_GL_NO_ERROR();
5744 // Check that we do not read from levels 0 or 3. Levels 1 and 2 are both acceptable.
5745 EXPECT_EQ(ReadColor(0, 0).R, 0);
5746 EXPECT_EQ(ReadColor(width - 1, 0).R, 0);
5747 EXPECT_EQ(ReadColor(0, height - 1).R, 0);
5748 EXPECT_EQ(ReadColor(width - 1, height - 1).R, 0);
5749}
5750
Anders Leino1b6aded2019-05-20 12:56:34 +03005751// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5752// texture is output.
5753TEST_P(Texture2DIntegerProjectiveOffsetTestES3, NonZeroBaseLevel)
5754{
Jamie Madill29ac2742019-05-28 15:53:00 -04005755 // Fails on AMD: http://crbug.com/967796
Jamie Madill06055b52019-05-29 14:31:42 -04005756 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
Jamie Madill29ac2742019-05-28 15:53:00 -04005757
Anders Leino1b6aded2019-05-20 12:56:34 +03005758 glActiveTexture(GL_TEXTURE0);
5759 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5760 int width = getWindowWidth();
5761 int height = getWindowHeight();
5762 GLColor color = GLColor::green;
5763 std::vector<GLColor> pixels(width * height, color);
5764 GLint baseLevel = 1;
5765 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5766 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5767 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5768 glTexImage2D(GL_TEXTURE_2D, baseLevel, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER,
5769 GL_UNSIGNED_BYTE, pixels.data());
5770
5771 setUpProgram();
5772 glUseProgram(mProgram);
5773 glUniform1i(mTexture2DUniformLocation, 0);
5774 drawQuad(mProgram, "position", 0.5f);
5775
5776 EXPECT_GL_NO_ERROR();
5777 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5778 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5779}
5780
Anders Leino69d04932019-05-20 14:04:13 +03005781// Draw a quad with an integer texture with a non-zero base level, and test that the color of the
5782// texture is output.
5783TEST_P(Texture2DArrayIntegerTestES3, NonZeroBaseLevel)
5784{
5785 glActiveTexture(GL_TEXTURE0);
5786 glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
5787 int width = getWindowWidth();
5788 int height = getWindowHeight();
5789 int depth = 2;
5790 GLColor color = GLColor::green;
5791 std::vector<GLColor> pixels(width * height * depth, color);
5792 GLint baseLevel = 1;
5793 glTexImage3D(GL_TEXTURE_2D_ARRAY, baseLevel, GL_RGBA8UI, width, height, depth, 0,
5794 GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixels.data());
5795 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, baseLevel);
5796 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5797 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5798
5799 drawQuad(mProgram, "position", 0.5f);
5800
5801 EXPECT_GL_NO_ERROR();
5802 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5803 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5804}
5805
Anders Leino262e2822019-05-20 14:24:40 +03005806// Draw a quad with an integer 3D texture with a non-zero base level, and test that the color of the
5807// texture is output.
5808TEST_P(Texture3DIntegerTestES3, NonZeroBaseLevel)
5809{
5810 glActiveTexture(GL_TEXTURE0);
5811 glBindTexture(GL_TEXTURE_3D, mTexture3D);
5812 int width = getWindowWidth();
5813 int height = getWindowHeight();
5814 int depth = 2;
5815 GLColor color = GLColor::green;
5816 std::vector<GLColor> pixels(width * height * depth, color);
5817 GLint baseLevel = 1;
5818 glTexImage3D(GL_TEXTURE_3D, baseLevel, GL_RGBA8UI, width, height, depth, 0, GL_RGBA_INTEGER,
5819 GL_UNSIGNED_BYTE, pixels.data());
5820 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, baseLevel);
5821 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5822 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5823
5824 drawQuad(mProgram, "position", 0.5f);
5825
5826 EXPECT_GL_NO_ERROR();
5827 EXPECT_PIXEL_COLOR_EQ(0, 0, color);
5828 EXPECT_PIXEL_COLOR_EQ(width - 1, height - 1, color);
5829}
5830
Jamie Madillfc3ec572019-11-27 21:43:22 +00005831// Test that uses glCompressedTexSubImage2D combined with a PBO
5832TEST_P(PBOCompressedTextureTest, PBOCompressedSubImage)
5833{
5834 // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
5835 ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
5836 // http://anglebug.com/4115
5837 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsDesktopOpenGL());
5838 ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsDesktopOpenGL());
5839
5840 if (getClientMajorVersion() < 3)
5841 {
5842 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
5843 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
5844 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC2_RGB8_texture"));
5845 }
5846
5847 const GLuint width = 4u;
5848 const GLuint height = 4u;
5849
5850 setWindowWidth(width);
5851 setWindowHeight(height);
5852
5853 // Setup primary Texture
5854 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5855 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5857
5858 if (getClientMajorVersion() < 3)
5859 {
5860 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
5861 }
5862 else
5863 {
5864 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, width, height);
5865 }
5866 ASSERT_GL_NO_ERROR();
5867
5868 // Setup PBO and fill it with a red
5869 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
5870 glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height / 2u, kCompressedImageETC2, GL_STATIC_DRAW);
5871 ASSERT_GL_NO_ERROR();
5872
5873 // Write PBO to mTexture
5874 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_COMPRESSED_RGB8_ETC2,
5875 width * height / 2u, nullptr);
5876 ASSERT_GL_NO_ERROR();
5877
5878 setUpProgram();
5879 // Draw using PBO updated texture
5880 glUseProgram(mProgram);
5881 glUniform1i(mTexture2DUniformLocation, 0);
5882 glBindTexture(GL_TEXTURE_2D, mTexture2D);
5883 drawQuad(mProgram, "position", 0.5f);
5884 ASSERT_GL_NO_ERROR();
5885
5886 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
5887 ASSERT_GL_NO_ERROR();
5888}
5889
Jamie Madill50cf2be2018-06-15 09:46:57 -04005890// Use this to select which configurations (e.g. which renderer, which GLES major version) these
5891// tests should be run against.
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07005892ANGLE_INSTANTIATE_TEST_ES2(Texture2DTest);
5893ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
5894ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
5895ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
5896ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
5897ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayAsFunctionParameterTest);
5898ANGLE_INSTANTIATE_TEST_ES3(Texture2DTestES3);
5899ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
5900ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
5901ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
5902ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
5903ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
5904ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
5905ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
5906ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructTest);
5907ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAsFunctionParameterTest);
5908ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructArrayAsFunctionParameterTest);
5909ANGLE_INSTANTIATE_TEST_ES2(SamplerInNestedStructAsFunctionParameterTest);
5910ANGLE_INSTANTIATE_TEST_ES2(SamplerInStructAndOtherVariableTest);
5911ANGLE_INSTANTIATE_TEST_ES2(TextureAnisotropyTest);
5912ANGLE_INSTANTIATE_TEST_ES2(TextureBorderClampTest);
5913ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
5914ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
5915ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
5916ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
5917ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DRGTest);
5918ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
5919ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
5920ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
5921ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3);
5922ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3);
5923ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3);
5924ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3);
5925ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
5926ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
5927ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
Jamie Madillfc3ec572019-11-27 21:43:22 +00005928ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
Jamie Madillfa05f602015-05-07 13:47:11 -04005929
Jamie Madill7ffdda92016-09-08 13:26:51 -04005930} // anonymous namespace