blob: 342f789c54a34fe9815679d14e3be518fc3bd653 [file] [log] [blame]
Geoff Langa8406172015-07-21 16:53:39 -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// ImageTest:
7// Tests the correctness of eglImage.
8//
9
10#include "test_utils/ANGLETest.h"
11
12namespace angle
13{
Jamie Madill0be37b42018-07-19 10:03:52 -040014namespace
15{
16constexpr char kOESExt[] = "GL_OES_EGL_image";
17constexpr char kExternalExt[] = "GL_OES_EGL_image_external";
18constexpr char kExternalESSL3Ext[] = "GL_OES_EGL_image_external_essl3";
19constexpr char kBaseExt[] = "EGL_KHR_image_base";
20constexpr char k2DTextureExt[] = "EGL_KHR_gl_texture_2D_image";
21constexpr char k3DTextureExt[] = "EGL_KHR_gl_texture_3D_image";
22constexpr char kPixmapExt[] = "EGL_KHR_image_pixmap";
23constexpr char kRenderbufferExt[] = "EGL_KHR_gl_renderbuffer_image";
24constexpr char kCubemapExt[] = "EGL_KHR_gl_texture_cubemap_image";
25} // anonymous namespace
26
Geoff Langa8406172015-07-21 16:53:39 -040027class ImageTest : public ANGLETest
28{
29 protected:
30 ImageTest()
31 {
32 setWindowWidth(128);
33 setWindowHeight(128);
34 setConfigRedBits(8);
35 setConfigGreenBits(8);
36 setConfigBlueBits(8);
37 setConfigAlphaBits(8);
38 setConfigDepthBits(24);
39 }
40
41 void SetUp() override
42 {
43 ANGLETest::SetUp();
44
Jamie Madill35cd7332018-12-02 12:03:33 -050045 constexpr char kVS[] =
Geoff Langa8406172015-07-21 16:53:39 -040046 "precision highp float;\n"
47 "attribute vec4 position;\n"
48 "varying vec2 texcoord;\n"
49 "\n"
50 "void main()\n"
51 "{\n"
52 " gl_Position = position;\n"
53 " texcoord = (position.xy * 0.5) + 0.5;\n"
54 " texcoord.y = 1.0 - texcoord.y;\n"
55 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -050056 constexpr char kVSESSL3[] =
Geoff Langb66a9092016-05-16 15:59:14 -040057 "#version 300 es\n"
58 "precision highp float;\n"
59 "in vec4 position;\n"
60 "out vec2 texcoord;\n"
61 "\n"
62 "void main()\n"
63 "{\n"
64 " gl_Position = position;\n"
65 " texcoord = (position.xy * 0.5) + 0.5;\n"
66 " texcoord.y = 1.0 - texcoord.y;\n"
67 "}\n";
Geoff Langa8406172015-07-21 16:53:39 -040068
Jamie Madill35cd7332018-12-02 12:03:33 -050069 constexpr char kTextureFS[] =
Geoff Langa8406172015-07-21 16:53:39 -040070 "precision highp float;\n"
71 "uniform sampler2D tex;\n"
72 "varying vec2 texcoord;\n"
73 "\n"
74 "void main()\n"
75 "{\n"
76 " gl_FragColor = texture2D(tex, texcoord);\n"
77 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -050078 constexpr char kTextureExternalFS[] =
Geoff Langb66a9092016-05-16 15:59:14 -040079 "#extension GL_OES_EGL_image_external : require\n"
80 "precision highp float;\n"
81 "uniform samplerExternalOES tex;\n"
82 "varying vec2 texcoord;\n"
83 "\n"
84 "void main()\n"
85 "{\n"
86 " gl_FragColor = texture2D(tex, texcoord);\n"
87 "}\n";
Jamie Madill35cd7332018-12-02 12:03:33 -050088 constexpr char kTextureExternalESSL3FS[] =
Geoff Langb66a9092016-05-16 15:59:14 -040089 "#version 300 es\n"
90 "#extension GL_OES_EGL_image_external_essl3 : require\n"
91 "precision highp float;\n"
92 "uniform samplerExternalOES tex;\n"
93 "in vec2 texcoord;\n"
94 "out vec4 color;"
95 "\n"
96 "void main()\n"
97 "{\n"
98 " color = texture(tex, texcoord);\n"
99 "}\n";
Geoff Langa8406172015-07-21 16:53:39 -0400100
Jamie Madill35cd7332018-12-02 12:03:33 -0500101 mTextureProgram = CompileProgram(kVS, kTextureFS);
Geoff Langa8406172015-07-21 16:53:39 -0400102 if (mTextureProgram == 0)
103 {
104 FAIL() << "shader compilation failed.";
105 }
106
107 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
108
Geoff Langb66a9092016-05-16 15:59:14 -0400109 if (extensionEnabled("GL_OES_EGL_image_external"))
110 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500111 mTextureExternalProgram = CompileProgram(kVS, kTextureExternalFS);
Geoff Langb66a9092016-05-16 15:59:14 -0400112 ASSERT_NE(0u, mTextureExternalProgram) << "shader compilation failed.";
113
114 mTextureExternalUniformLocation = glGetUniformLocation(mTextureExternalProgram, "tex");
115 }
116
117 if (extensionEnabled("GL_OES_EGL_image_external_essl3"))
118 {
Jamie Madill35cd7332018-12-02 12:03:33 -0500119 mTextureExternalESSL3Program = CompileProgram(kVSESSL3, kTextureExternalESSL3FS);
Geoff Langb66a9092016-05-16 15:59:14 -0400120 ASSERT_NE(0u, mTextureExternalESSL3Program) << "shader compilation failed.";
121
122 mTextureExternalESSL3UniformLocation =
123 glGetUniformLocation(mTextureExternalESSL3Program, "tex");
124 }
125
Geoff Langa8406172015-07-21 16:53:39 -0400126 eglCreateImageKHR =
127 reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
128 eglDestroyImageKHR =
129 reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
130
131 ASSERT_GL_NO_ERROR();
132 }
133
134 void TearDown() override
135 {
Geoff Langa8406172015-07-21 16:53:39 -0400136 glDeleteProgram(mTextureProgram);
Geoff Langb66a9092016-05-16 15:59:14 -0400137 glDeleteProgram(mTextureExternalProgram);
138 glDeleteProgram(mTextureExternalESSL3Program);
139
140 ANGLETest::TearDown();
Geoff Langa8406172015-07-21 16:53:39 -0400141 }
142
143 void createEGLImage2DTextureSource(size_t width,
144 size_t height,
145 GLenum format,
146 GLenum type,
147 void *data,
148 GLuint *outSourceTexture,
149 EGLImageKHR *outSourceImage)
150 {
151 // Create a source 2D texture
152 GLuint source;
153 glGenTextures(1, &source);
154 glBindTexture(GL_TEXTURE_2D, source);
155
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700156 glTexImage2D(GL_TEXTURE_2D, 0, format, static_cast<GLsizei>(width),
157 static_cast<GLsizei>(height), 0, format, type, data);
Geoff Langa8406172015-07-21 16:53:39 -0400158
159 // Disable mipmapping
160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
161 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
162
163 ASSERT_GL_NO_ERROR();
164
165 // Create an image from the source texture
166 EGLWindow *window = getEGLWindow();
Geoff Langc0b61502018-07-27 15:59:32 -0400167
168 EGLint attribs[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500169 EGL_IMAGE_PRESERVED,
170 EGL_TRUE,
171 EGL_NONE,
Geoff Langc0b61502018-07-27 15:59:32 -0400172 };
173
Geoff Langa8406172015-07-21 16:53:39 -0400174 EGLImageKHR image =
175 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
Geoff Langc0b61502018-07-27 15:59:32 -0400176 reinterpretHelper<EGLClientBuffer>(source), attribs);
Geoff Langa8406172015-07-21 16:53:39 -0400177
178 ASSERT_EGL_SUCCESS();
179
180 *outSourceTexture = source;
181 *outSourceImage = image;
182 }
183
184 void createEGLImageCubemapTextureSource(size_t width,
185 size_t height,
186 GLenum format,
187 GLenum type,
188 uint8_t *data,
189 size_t dataStride,
190 EGLenum imageTarget,
191 GLuint *outSourceTexture,
192 EGLImageKHR *outSourceImage)
193 {
194 // Create a source cube map texture
195 GLuint source;
196 glGenTextures(1, &source);
197 glBindTexture(GL_TEXTURE_CUBE_MAP, source);
198
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700199 for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++)
Geoff Langa8406172015-07-21 16:53:39 -0400200 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700201 glTexImage2D(faceIdx + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format,
202 static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0, format, type,
203 data + (faceIdx * dataStride));
Geoff Langa8406172015-07-21 16:53:39 -0400204 }
205
206 // Disable mipmapping
207 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
208 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
209
210 ASSERT_GL_NO_ERROR();
211
212 // Create an image from the source texture
213 EGLWindow *window = getEGLWindow();
Geoff Langc0b61502018-07-27 15:59:32 -0400214
215 EGLint attribs[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500216 EGL_IMAGE_PRESERVED,
217 EGL_TRUE,
218 EGL_NONE,
Geoff Langc0b61502018-07-27 15:59:32 -0400219 };
220
Geoff Langa8406172015-07-21 16:53:39 -0400221 EGLImageKHR image =
222 eglCreateImageKHR(window->getDisplay(), window->getContext(), imageTarget,
Geoff Langc0b61502018-07-27 15:59:32 -0400223 reinterpretHelper<EGLClientBuffer>(source), attribs);
Geoff Langa8406172015-07-21 16:53:39 -0400224
225 ASSERT_EGL_SUCCESS();
226
227 *outSourceTexture = source;
228 *outSourceImage = image;
229 }
230
231 void createEGLImage3DTextureSource(size_t width,
232 size_t height,
233 size_t depth,
234 GLenum format,
235 GLenum type,
236 void *data,
237 size_t imageLayer,
238 GLuint *outSourceTexture,
239 EGLImageKHR *outSourceImage)
240 {
241 // Create a source 3D texture
242 GLuint source;
243 glGenTextures(1, &source);
244 glBindTexture(GL_TEXTURE_3D, source);
245
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700246 glTexImage3D(GL_TEXTURE_3D, 0, format, static_cast<GLsizei>(width),
247 static_cast<GLsizei>(height), static_cast<GLsizei>(depth), 0, format, type,
248 data);
Geoff Langa8406172015-07-21 16:53:39 -0400249
250 // Disable mipmapping
251 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
252 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
253
254 ASSERT_GL_NO_ERROR();
255
256 // Create an image from the source texture
257 EGLWindow *window = getEGLWindow();
258
259 EGLint attribs[] = {
Geoff Langc0b61502018-07-27 15:59:32 -0400260 EGL_GL_TEXTURE_ZOFFSET_KHR,
261 static_cast<EGLint>(imageLayer),
262 EGL_IMAGE_PRESERVED,
263 EGL_TRUE,
264 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400265 };
266 EGLImageKHR image =
267 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700268 reinterpretHelper<EGLClientBuffer>(source), attribs);
Geoff Langa8406172015-07-21 16:53:39 -0400269
270 ASSERT_EGL_SUCCESS();
271
272 *outSourceTexture = source;
273 *outSourceImage = image;
274 }
275
276 void createEGLImageRenderbufferSource(size_t width,
277 size_t height,
278 GLenum internalFormat,
279 GLubyte data[4],
280 GLuint *outSourceRenderbuffer,
281 EGLImageKHR *outSourceImage)
282 {
283 // Create a source renderbuffer
284 GLuint source;
285 glGenRenderbuffers(1, &source);
286 glBindRenderbuffer(GL_RENDERBUFFER, source);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700287 glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, static_cast<GLsizei>(width),
288 static_cast<GLsizei>(height));
Geoff Langa8406172015-07-21 16:53:39 -0400289
290 // Create a framebuffer and clear it to set the data
291 GLuint framebuffer;
292 glGenFramebuffers(1, &framebuffer);
293 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
294 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, source);
295
296 glClearColor(data[0] / 255.0f, data[1] / 255.0f, data[2] / 255.0f, data[3] / 255.0f);
297 glClear(GL_COLOR_BUFFER_BIT);
298
299 glDeleteFramebuffers(1, &framebuffer);
300
301 ASSERT_GL_NO_ERROR();
302
303 // Create an image from the source renderbuffer
304 EGLWindow *window = getEGLWindow();
Geoff Langc0b61502018-07-27 15:59:32 -0400305
306 EGLint attribs[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500307 EGL_IMAGE_PRESERVED,
308 EGL_TRUE,
309 EGL_NONE,
Geoff Langc0b61502018-07-27 15:59:32 -0400310 };
311
Geoff Langa8406172015-07-21 16:53:39 -0400312 EGLImageKHR image =
313 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_RENDERBUFFER_KHR,
Geoff Langc0b61502018-07-27 15:59:32 -0400314 reinterpretHelper<EGLClientBuffer>(source), attribs);
Geoff Langa8406172015-07-21 16:53:39 -0400315
316 ASSERT_EGL_SUCCESS();
317
318 *outSourceRenderbuffer = source;
319 *outSourceImage = image;
320 }
321
322 void createEGLImageTargetTexture2D(EGLImageKHR image, GLuint *outTargetTexture)
323 {
324 // Create a target texture from the image
325 GLuint target;
326 glGenTextures(1, &target);
327 glBindTexture(GL_TEXTURE_2D, target);
328 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
329
330 // Disable mipmapping
331 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
332 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
333
334 ASSERT_GL_NO_ERROR();
335
336 *outTargetTexture = target;
337 }
338
Geoff Langb66a9092016-05-16 15:59:14 -0400339 void createEGLImageTargetTextureExternal(EGLImageKHR image, GLuint *outTargetTexture)
340 {
341 // Create a target texture from the image
342 GLuint target;
343 glGenTextures(1, &target);
344 glBindTexture(GL_TEXTURE_EXTERNAL_OES, target);
345 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
346
347 // Disable mipmapping
348 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350
351 ASSERT_GL_NO_ERROR();
352
353 *outTargetTexture = target;
354 }
355
Geoff Langa8406172015-07-21 16:53:39 -0400356 void createEGLImageTargetRenderbuffer(EGLImageKHR image, GLuint *outTargetRenderbuffer)
357 {
358 // Create a target texture from the image
359 GLuint target;
360 glGenRenderbuffers(1, &target);
361 glBindRenderbuffer(GL_RENDERBUFFER, target);
362 glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
363
364 ASSERT_GL_NO_ERROR();
365
366 *outTargetRenderbuffer = target;
367 }
368
Geoff Langb66a9092016-05-16 15:59:14 -0400369 void verifyResultsTexture(GLuint texture,
370 GLubyte data[4],
371 GLenum textureTarget,
372 GLuint program,
373 GLuint textureUniform)
Geoff Langa8406172015-07-21 16:53:39 -0400374 {
375 // Draw a quad with the target texture
Geoff Langb66a9092016-05-16 15:59:14 -0400376 glUseProgram(program);
377 glBindTexture(textureTarget, texture);
378 glUniform1i(textureUniform, 0);
Geoff Langa8406172015-07-21 16:53:39 -0400379
Geoff Langb66a9092016-05-16 15:59:14 -0400380 drawQuad(program, "position", 0.5f);
Geoff Langa8406172015-07-21 16:53:39 -0400381
382 // Expect that the rendered quad has the same color as the source texture
383 EXPECT_PIXEL_EQ(0, 0, data[0], data[1], data[2], data[3]);
384 }
385
Geoff Langb66a9092016-05-16 15:59:14 -0400386 void verifyResults2D(GLuint texture, GLubyte data[4])
387 {
388 verifyResultsTexture(texture, data, GL_TEXTURE_2D, mTextureProgram,
389 mTextureUniformLocation);
390 }
391
392 void verifyResultsExternal(GLuint texture, GLubyte data[4])
393 {
394 verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalProgram,
395 mTextureExternalUniformLocation);
396 }
397
398 void verifyResultsExternalESSL3(GLuint texture, GLubyte data[4])
399 {
400 verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalESSL3Program,
401 mTextureExternalESSL3UniformLocation);
402 }
403
Geoff Langa8406172015-07-21 16:53:39 -0400404 void verifyResultsRenderbuffer(GLuint renderbuffer, GLubyte data[4])
405 {
406 // Bind the renderbuffer to a framebuffer
407 GLuint framebuffer;
408 glGenFramebuffers(1, &framebuffer);
409 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
410 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
411 renderbuffer);
412
413 // Expect that the rendered quad has the same color as the source texture
414 EXPECT_PIXEL_EQ(0, 0, data[0], data[1], data[2], data[3]);
415
416 glDeleteFramebuffers(1, &framebuffer);
417 }
418
Austin Kinrossa8187762015-08-12 10:54:37 -0700419 template <typename destType, typename sourcetype>
420 destType reinterpretHelper(sourcetype source)
421 {
422 static_assert(sizeof(destType) == sizeof(size_t),
423 "destType should be the same size as a size_t");
424 size_t sourceSizeT = static_cast<size_t>(source);
425 return reinterpret_cast<destType>(sourceSizeT);
426 }
427
Jamie Madill0be37b42018-07-19 10:03:52 -0400428 bool hasOESExt() const { return extensionEnabled(kOESExt); }
429
430 bool hasExternalExt() const { return extensionEnabled(kExternalExt); }
431
432 bool hasExternalESSL3Ext() const { return extensionEnabled(kExternalESSL3Ext); }
433
434 bool hasBaseExt() const
435 {
436 return eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kBaseExt);
437 }
438
439 bool has2DTextureExt() const
440 {
441 return eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), k2DTextureExt);
442 }
443
444 bool has3DTextureExt() const
445 {
446 return eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), k3DTextureExt);
447 }
448
449 bool hasPixmapExt() const
450 {
451 return eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kPixmapExt);
452 }
453
454 bool hasRenderbufferExt() const
455 {
456 return eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kRenderbufferExt);
457 }
458
459 bool hasCubemapExt() const
460 {
461 return eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kCubemapExt);
462 }
463
Geoff Langa8406172015-07-21 16:53:39 -0400464 GLuint mTextureProgram;
465 GLint mTextureUniformLocation;
466
Geoff Langb66a9092016-05-16 15:59:14 -0400467 GLuint mTextureExternalProgram = 0;
468 GLint mTextureExternalUniformLocation = -1;
469
470 GLuint mTextureExternalESSL3Program = 0;
471 GLint mTextureExternalESSL3UniformLocation = -1;
472
Geoff Langa8406172015-07-21 16:53:39 -0400473 PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
474 PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
475};
476
Geoff Langb66a9092016-05-16 15:59:14 -0400477class ImageTestES3 : public ImageTest
Jamie Madillb980c562018-11-27 11:34:27 -0500478{};
Geoff Langb66a9092016-05-16 15:59:14 -0400479
Jamie Madill0be37b42018-07-19 10:03:52 -0400480// Tests that the extension is exposed on the platforms we think it should be. Please modify this as
481// you change extension availability.
482TEST_P(ImageTest, ANGLEExtensionAvailability)
483{
Geoff Langc0b61502018-07-27 15:59:32 -0400484 // EGL support is based on driver extension availability.
Geoff Langdbd16122018-07-19 11:30:21 -0400485 ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsAndroid());
Geoff Langc0b61502018-07-27 15:59:32 -0400486 ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsOzone());
Geoff Langdbd16122018-07-19 11:30:21 -0400487
Jamie Madill0be37b42018-07-19 10:03:52 -0400488 if (IsD3D11() || IsD3D9())
489 {
490 EXPECT_TRUE(hasOESExt());
491 EXPECT_TRUE(hasExternalExt());
492 EXPECT_TRUE(hasBaseExt());
493 EXPECT_TRUE(has2DTextureExt());
494 EXPECT_TRUE(hasRenderbufferExt());
495
496 if (IsD3D11())
497 {
498 EXPECT_TRUE(hasCubemapExt());
499
500 if (getClientMajorVersion() >= 3)
501 {
502 EXPECT_TRUE(hasExternalESSL3Ext());
503 }
504 else
505 {
506 EXPECT_FALSE(hasExternalESSL3Ext());
507 }
508 }
509 else
510 {
511 EXPECT_FALSE(hasCubemapExt());
512 EXPECT_FALSE(hasExternalESSL3Ext());
513 }
514 }
515 else
516 {
517 EXPECT_FALSE(hasOESExt());
518 EXPECT_FALSE(hasExternalExt());
519 EXPECT_FALSE(hasExternalESSL3Ext());
520 EXPECT_FALSE(hasBaseExt());
521 EXPECT_FALSE(has2DTextureExt());
522 EXPECT_FALSE(has3DTextureExt());
523 EXPECT_FALSE(hasRenderbufferExt());
524 }
525
526 // These extensions are not yet available on any platform.
527 EXPECT_FALSE(hasPixmapExt());
528 EXPECT_FALSE(has3DTextureExt());
529}
530
Geoff Langa8406172015-07-21 16:53:39 -0400531// Check validation from the EGL_KHR_image_base extension
532TEST_P(ImageTest, ValidationImageBase)
533{
534 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -0400535 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -0400536
537 GLuint glTexture2D;
538 glGenTextures(1, &glTexture2D);
539 glBindTexture(GL_TEXTURE_2D, glTexture2D);
540 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
541
542 EGLDisplay display = window->getDisplay();
543 EGLContext context = window->getContext();
544 EGLConfig config = window->getConfig();
545 EGLImageKHR image = EGL_NO_IMAGE_KHR;
Austin Kinrossa8187762015-08-12 10:54:37 -0700546 EGLClientBuffer texture2D = reinterpretHelper<EGLClientBuffer>(glTexture2D);
Geoff Langa8406172015-07-21 16:53:39 -0400547
548 // Test validation of eglCreateImageKHR
549
550 // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is
551 // generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700552 image = eglCreateImageKHR(reinterpretHelper<EGLDisplay>(0xBAADF00D), context,
Geoff Langa8406172015-07-21 16:53:39 -0400553 EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
554 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
555 EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
556
557 // If <ctx> is neither the handle of a valid EGLContext object on <dpy> nor EGL_NO_CONTEXT, the
558 // error EGL_BAD_CONTEXT is generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700559 image = eglCreateImageKHR(display, reinterpretHelper<EGLContext>(0xBAADF00D),
Geoff Langa8406172015-07-21 16:53:39 -0400560 EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
561 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
562 EXPECT_EGL_ERROR(EGL_BAD_CONTEXT);
563
564 // Test EGL_NO_CONTEXT with a 2D texture target which does require a context.
565 image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
566 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
567 EXPECT_EGL_ERROR(EGL_BAD_CONTEXT);
568
569 // If an attribute specified in <attrib_list> is not one of the attributes listed in Table bbb,
570 // the error EGL_BAD_PARAMETER is generated.
571 EGLint badAttributes[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500572 static_cast<EGLint>(0xDEADBEEF),
573 0,
574 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400575 };
576
577 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, badAttributes);
578 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
579 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
580
581 // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> has an off -
582 // screen buffer bound to it(e.g., by a
583 // previous call to eglBindTexImage), the error EGL_BAD_ACCESS is generated.
584 EGLint surfaceType = 0;
585 eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType);
586
587 EGLint bindToTextureRGBA = 0;
588 eglGetConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBA);
589 if ((surfaceType & EGL_PBUFFER_BIT) != 0 && bindToTextureRGBA == EGL_TRUE)
590 {
591 EGLint pbufferAttributes[] = {
592 EGL_WIDTH, 1,
593 EGL_HEIGHT, 1,
594 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
595 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
596 EGL_NONE, EGL_NONE,
597 };
598 EGLSurface pbuffer = eglCreatePbufferSurface(display, config, pbufferAttributes);
599 ASSERT_NE(pbuffer, EGL_NO_SURFACE);
600 EXPECT_EGL_SUCCESS();
601
602 eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
603 EXPECT_EGL_SUCCESS();
604
605 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
606 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
607 EXPECT_EGL_ERROR(EGL_BAD_ACCESS);
608
609 eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER);
610 eglDestroySurface(display, pbuffer);
611 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
612 EXPECT_EGL_SUCCESS();
613 EXPECT_GL_NO_ERROR();
614 }
615
616 // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and
617 // <attrib_list> is itself an EGLImage sibling, the error EGL_BAD_ACCESS is generated.
618 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
619 EXPECT_NE(image, EGL_NO_IMAGE_KHR);
620 EXPECT_EGL_SUCCESS();
621
622 /* TODO(geofflang): Enable this validation when it passes.
623 EGLImageKHR image2 = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
624 reinterpret_cast<EGLClientBuffer>(texture2D), nullptr);
625 EXPECT_EQ(image2, EGL_NO_IMAGE_KHR);
626 EXPECT_EGL_ERROR(EGL_BAD_ACCESS);
627 */
628
629 // Test validation of eglDestroyImageKHR
630 // Note: image is now a valid EGL image
631 EGLBoolean result = EGL_FALSE;
632
633 // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is
634 // generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700635 result = eglDestroyImageKHR(reinterpretHelper<EGLDisplay>(0xBAADF00D), image);
Geoff Langa8406172015-07-21 16:53:39 -0400636 EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE));
637 EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
638
639 // If <image> is not a valid EGLImageKHR object created with respect to <dpy>, the error
640 // EGL_BAD_PARAMETER is generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700641 result = eglDestroyImageKHR(display, reinterpretHelper<EGLImageKHR>(0xBAADF00D));
Geoff Langa8406172015-07-21 16:53:39 -0400642 EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE));
643 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
644
645 // Clean up and validate image is destroyed
646 result = eglDestroyImageKHR(display, image);
647 EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_TRUE));
648 EXPECT_EGL_SUCCESS();
649
650 glDeleteTextures(1, &glTexture2D);
651 EXPECT_GL_NO_ERROR();
652}
653
Geoff Langa8406172015-07-21 16:53:39 -0400654// Check validation from the EGL_KHR_gl_texture_2D_image, EGL_KHR_gl_texture_cubemap_image,
655// EGL_KHR_gl_texture_3D_image and EGL_KHR_gl_renderbuffer_image extensions
656TEST_P(ImageTest, ValidationGLImage)
657{
658 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -0400659 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());
Geoff Langa8406172015-07-21 16:53:39 -0400660
661 EGLDisplay display = window->getDisplay();
662 EGLContext context = window->getContext();
663 EGLImageKHR image = EGL_NO_IMAGE_KHR;
664
Jamie Madill0be37b42018-07-19 10:03:52 -0400665 if (has2DTextureExt())
Geoff Langa8406172015-07-21 16:53:39 -0400666 {
667 // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR or
668 // EGL_GL_TEXTURE_3D_KHR and <buffer> is not the name of a texture object of type <target>,
669 // the error EGL_BAD_PARAMETER is generated.
670 GLuint textureCube;
671 glGenTextures(1, &textureCube);
672 glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
673 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
674 face++)
675 {
676 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
677 }
678
679 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700680 reinterpretHelper<EGLClientBuffer>(textureCube), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400681 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
682 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
683
684 // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR,
685 // EGL_GL_TEXTURE_CUBE_MAP_*_KHR or EGL_GL_TEXTURE_3D_KHR, <buffer> is the name of an
686 // incomplete GL texture object, and any mipmap levels other than mipmap level 0 are
687 // specified, the error EGL_BAD_PARAMETER is generated.
688 GLuint incompleteTexture;
689 glGenTextures(1, &incompleteTexture);
690 glBindTexture(GL_TEXTURE_2D, incompleteTexture);
691 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
692 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
693
694 EGLint level0Attribute[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500695 EGL_GL_TEXTURE_LEVEL_KHR,
696 0,
697 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400698 };
699 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700700 reinterpretHelper<EGLClientBuffer>(incompleteTexture),
Geoff Langa8406172015-07-21 16:53:39 -0400701 level0Attribute);
702 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
703 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
704
705 // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR or
706 // EGL_GL_TEXTURE_3D_KHR, <buffer> is not the name of a complete GL texture object, and
707 // mipmap level 0 is not specified, the error EGL_BAD_PARAMETER is generated.
708 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
709 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700710 reinterpretHelper<EGLClientBuffer>(incompleteTexture), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400711 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
712 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
713
714 // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR,
715 // EGL_GL_RENDERBUFFER_KHR or EGL_GL_TEXTURE_3D_KHR and <buffer> refers to the default GL
716 // texture object(0) for the corresponding GL target, the error EGL_BAD_PARAMETER is
717 // generated.
718 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, 0, nullptr);
719 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
720 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
721
722 // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR, or
723 // EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for
724 // EGL_GL_TEXTURE_LEVEL_KHR is not a valid mipmap level for the specified GL texture object
725 // <buffer>, the error EGL_BAD_MATCH is generated.
726 EGLint level2Attribute[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500727 EGL_GL_TEXTURE_LEVEL_KHR,
728 2,
729 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400730 };
731 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700732 reinterpretHelper<EGLClientBuffer>(incompleteTexture),
Geoff Langa8406172015-07-21 16:53:39 -0400733 level2Attribute);
734 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
735 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
736 }
737 else
738 {
739 GLuint texture2D;
740 glGenTextures(1, &texture2D);
741 glBindTexture(GL_TEXTURE_2D, texture2D);
742 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
743
744 // From EGL_KHR_image_base:
745 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
746 // generated.
747 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700748 reinterpretHelper<EGLClientBuffer>(texture2D), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400749 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
750 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
751 }
752
Jamie Madill0be37b42018-07-19 10:03:52 -0400753 if (hasCubemapExt())
Geoff Langa8406172015-07-21 16:53:39 -0400754 {
755 // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_CUBE_MAP_*_KHR, <buffer> is
756 // not the name of a complete GL texture object, and one or more faces do not have mipmap
757 // level 0 specified, the error EGL_BAD_PARAMETER is generated.
758 GLuint incompleteTextureCube;
759 glGenTextures(1, &incompleteTextureCube);
760 glBindTexture(GL_TEXTURE_CUBE_MAP, incompleteTextureCube);
761 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
762 nullptr);
763 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
764 nullptr);
765 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
766 nullptr);
767 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
768 nullptr);
769 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
770 nullptr);
771
772 EGLint level0Attribute[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500773 EGL_GL_TEXTURE_LEVEL_KHR,
774 0,
775 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400776 };
777 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700778 reinterpretHelper<EGLClientBuffer>(incompleteTextureCube),
Geoff Langa8406172015-07-21 16:53:39 -0400779 level0Attribute);
780 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
781 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
782 }
783 else
784 {
785 GLuint textureCube;
786 glGenTextures(1, &textureCube);
787 glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
788 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
789 face++)
790 {
791 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
792 }
793
794 // From EGL_KHR_image_base:
795 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
796 // generated.
797 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700798 reinterpretHelper<EGLClientBuffer>(textureCube), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400799 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
800 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
801 }
802
Jamie Madill0be37b42018-07-19 10:03:52 -0400803 if (has3DTextureExt() && getClientMajorVersion() >= 3)
Geoff Langa8406172015-07-21 16:53:39 -0400804 {
805 // If <target> is EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for
806 // EGL_GL_TEXTURE_ZOFFSET_KHR exceeds the depth of the specified mipmap level - of - detail
807 // in <buffer>, the error EGL_BAD_PARAMETER is generated.
808 GLuint texture3D;
809 glGenTextures(1, &texture3D);
810 glBindTexture(GL_TEXTURE_3D, texture3D);
811 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
812
813 EGLint zOffset3Parameter[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500814 EGL_GL_TEXTURE_ZOFFSET_KHR,
815 3,
816 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400817 };
818 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700819 reinterpretHelper<EGLClientBuffer>(texture3D), zOffset3Parameter);
Geoff Langa8406172015-07-21 16:53:39 -0400820 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
821 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
822
823 EGLint zOffsetNegative1Parameter[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500824 EGL_GL_TEXTURE_ZOFFSET_KHR,
825 -1,
826 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400827 };
828 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700829 reinterpretHelper<EGLClientBuffer>(texture3D),
Geoff Langa8406172015-07-21 16:53:39 -0400830 zOffsetNegative1Parameter);
831 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
832 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
833 }
834 else
835 {
Jamie Madill0be37b42018-07-19 10:03:52 -0400836 if (has2DTextureExt())
Geoff Langa8406172015-07-21 16:53:39 -0400837 {
838 GLuint texture2D;
839 glGenTextures(1, &texture2D);
840 glBindTexture(GL_TEXTURE_2D, texture2D);
841 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
842
843 // Verify EGL_GL_TEXTURE_ZOFFSET_KHR is not a valid parameter
844 EGLint zOffset0Parameter[] = {
Jamie Madillb980c562018-11-27 11:34:27 -0500845 EGL_GL_TEXTURE_ZOFFSET_KHR,
846 0,
847 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -0400848 };
849
850 image =
851 eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700852 reinterpretHelper<EGLClientBuffer>(texture2D), zOffset0Parameter);
Geoff Langa8406172015-07-21 16:53:39 -0400853 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
854 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
855 }
856
Martin Radev1be913c2016-07-11 17:59:16 +0300857 if (getClientMajorVersion() >= 3)
Geoff Langa8406172015-07-21 16:53:39 -0400858 {
859 GLuint texture3D;
860 glGenTextures(1, &texture3D);
861 glBindTexture(GL_TEXTURE_3D, texture3D);
862 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
863
864 // From EGL_KHR_image_base:
865 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
866 // generated.
867 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700868 reinterpretHelper<EGLClientBuffer>(texture3D), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400869 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
870 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
871 }
872 }
873
Jamie Madill0be37b42018-07-19 10:03:52 -0400874 if (hasRenderbufferExt())
Geoff Langa8406172015-07-21 16:53:39 -0400875 {
876 // If <target> is EGL_GL_RENDERBUFFER_KHR and <buffer> is not the name of a renderbuffer
877 // object, or if <buffer> is the name of a multisampled renderbuffer object, the error
878 // EGL_BAD_PARAMETER is generated.
879 image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
880 reinterpret_cast<EGLClientBuffer>(0), nullptr);
881 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
882 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
883
884 if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
885 {
886 GLuint renderbuffer;
887 glGenRenderbuffers(1, &renderbuffer);
888 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
889 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
890 EXPECT_GL_NO_ERROR();
891
892 image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
893 reinterpret_cast<EGLClientBuffer>(0), nullptr);
894 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
895 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
896 }
897 }
898 else
899 {
900 GLuint renderbuffer;
901 glGenRenderbuffers(1, &renderbuffer);
902 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
903 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 1, 1);
904
905 // From EGL_KHR_image_base:
906 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
907 // generated.
908 image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700909 reinterpretHelper<EGLClientBuffer>(renderbuffer), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400910 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
911 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
912 }
913}
914
915// Check validation from the GL_OES_EGL_image extension
916TEST_P(ImageTest, ValidationGLEGLImage)
917{
Jamie Madill0be37b42018-07-19 10:03:52 -0400918 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -0400919
920 GLubyte data[4] = {255, 0, 255, 255};
921
922 // Create the Image
923 GLuint source;
924 EGLImageKHR image;
925 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
926
927 // If <target> is not TEXTURE_2D, the error INVALID_ENUM is generated.
928 glEGLImageTargetTexture2DOES(GL_TEXTURE_CUBE_MAP_POSITIVE_X, image);
929 EXPECT_GL_ERROR(GL_INVALID_ENUM);
930
931 // If <image> does not refer to a valid eglImageOES object, the error INVALID_VALUE is
932 // generated.
933 GLuint texture;
934 glGenTextures(1, &texture);
935 glBindTexture(GL_TEXTURE_2D, texture);
Austin Kinrossa8187762015-08-12 10:54:37 -0700936 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, reinterpretHelper<GLeglImageOES>(0xBAADF00D));
Geoff Langa8406172015-07-21 16:53:39 -0400937 EXPECT_GL_ERROR(GL_INVALID_VALUE);
938
939 // <target> must be RENDERBUFFER_OES, and <image> must be the handle of a valid EGLImage
940 // resource, cast into the type
941 // eglImageOES.
942 glEGLImageTargetRenderbufferStorageOES(GL_TEXTURE_2D, image);
943 EXPECT_GL_ERROR(GL_INVALID_ENUM);
944
945 // If the GL is unable to create a renderbuffer using the specified eglImageOES, the error
946 // INVALID_OPERATION is generated.If <image>
947 // does not refer to a valid eglImageOES object, the error INVALID_VALUE is generated.
948 GLuint renderbuffer;
949 glGenRenderbuffers(1, &renderbuffer);
950 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
951 glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
Austin Kinrossa8187762015-08-12 10:54:37 -0700952 reinterpretHelper<GLeglImageOES>(0xBAADF00D));
Geoff Langa8406172015-07-21 16:53:39 -0400953 EXPECT_GL_ERROR(GL_INVALID_VALUE);
954
955 // Clean up
956 glDeleteTextures(1, &source);
Jamie Madill0be37b42018-07-19 10:03:52 -0400957 eglDestroyImageKHR(getEGLWindow()->getDisplay(), image);
Geoff Langa8406172015-07-21 16:53:39 -0400958 glDeleteTextures(1, &texture);
959 glDeleteRenderbuffers(1, &renderbuffer);
960}
961
962// Check validation from the GL_OES_EGL_image_external extension
963TEST_P(ImageTest, ValidationGLEGLImageExternal)
964{
Jamie Madill0be37b42018-07-19 10:03:52 -0400965 ANGLE_SKIP_TEST_IF(!hasExternalExt());
Geoff Langb66a9092016-05-16 15:59:14 -0400966
967 GLuint texture;
968 glGenTextures(1, &texture);
969 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
970
971 // In the initial state of a TEXTURE_EXTERNAL_OES texture object, the value assigned to
972 // TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER is LINEAR, and the s and t wrap modes are both set
973 // to CLAMP_TO_EDGE
Jamie Madillb980c562018-11-27 11:34:27 -0500974 auto getTexParam = [](GLenum target, GLenum pname) {
Geoff Langb66a9092016-05-16 15:59:14 -0400975 GLint value = 0;
976 glGetTexParameteriv(target, pname, &value);
977 EXPECT_GL_NO_ERROR();
978 return value;
979 };
980 EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER));
981 EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER));
982 EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S));
983 EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T));
984
985 // "When <target> is TEXTURE_EXTERNAL_OES only NEAREST and LINEAR are accepted as
986 // TEXTURE_MIN_FILTER, only CLAMP_TO_EDGE is accepted as TEXTURE_WRAP_S and TEXTURE_WRAP_T, and
987 // only FALSE is accepted as GENERATE_MIPMAP. Attempting to set other values for
988 // TEXTURE_MIN_FILTER, TEXTURE_WRAP_S, TEXTURE_WRAP_T, or GENERATE_MIPMAP will result in an
989 // INVALID_ENUM error.
990 GLenum validMinFilters[]{
Jamie Madillb980c562018-11-27 11:34:27 -0500991 GL_NEAREST,
992 GL_LINEAR,
Geoff Langb66a9092016-05-16 15:59:14 -0400993 };
994 for (auto minFilter : validMinFilters)
995 {
996 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
997 EXPECT_GL_NO_ERROR();
998 }
999
1000 GLenum invalidMinFilters[]{
Jamie Madillb980c562018-11-27 11:34:27 -05001001 GL_NEAREST_MIPMAP_LINEAR,
1002 GL_NEAREST_MIPMAP_NEAREST,
1003 GL_LINEAR_MIPMAP_LINEAR,
Geoff Langb66a9092016-05-16 15:59:14 -04001004 GL_LINEAR_MIPMAP_NEAREST,
1005 };
1006 for (auto minFilter : invalidMinFilters)
1007 {
1008 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
1009 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1010 }
1011
1012 GLenum validWrapModes[]{
1013 GL_CLAMP_TO_EDGE,
1014 };
1015 for (auto minFilter : validWrapModes)
1016 {
1017 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, minFilter);
1018 EXPECT_GL_NO_ERROR();
1019 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, minFilter);
1020 EXPECT_GL_NO_ERROR();
1021 }
1022
1023 GLenum invalidWrapModes[]{
Jamie Madillb980c562018-11-27 11:34:27 -05001024 GL_REPEAT,
1025 GL_MIRRORED_REPEAT,
Geoff Langb66a9092016-05-16 15:59:14 -04001026 };
1027 for (auto minFilter : invalidWrapModes)
1028 {
1029 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, minFilter);
1030 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1031 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, minFilter);
1032 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1033 }
1034
1035 // When <target> is set to TEXTURE_EXTERNAL_OES, GenerateMipmap always fails and generates an
1036 // INVALID_ENUM error.
1037 glGenerateMipmap(GL_TEXTURE_EXTERNAL_OES);
1038 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1039
1040 glDeleteTextures(1, &texture);
Geoff Langa8406172015-07-21 16:53:39 -04001041}
1042
1043// Check validation from the GL_OES_EGL_image_external_essl3 extension
1044TEST_P(ImageTest, ValidationGLEGLImageExternalESSL3)
1045{
Jamie Madill0be37b42018-07-19 10:03:52 -04001046 ANGLE_SKIP_TEST_IF(!hasExternalESSL3Ext());
Geoff Langb66a9092016-05-16 15:59:14 -04001047
1048 // Make sure this extension is not exposed without ES3.
Martin Radev1be913c2016-07-11 17:59:16 +03001049 ASSERT_GE(getClientMajorVersion(), 3);
Geoff Langb66a9092016-05-16 15:59:14 -04001050
1051 GLuint texture;
1052 glGenTextures(1, &texture);
1053 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
1054
1055 // It is an INVALID_OPERATION error to set the TEXTURE_BASE_LEVEL to a value other than zero.
1056 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 1);
1057 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1058
1059 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 10);
1060 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1061
1062 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 0);
1063 EXPECT_GL_NO_ERROR();
1064
1065 glDeleteTextures(1, &texture);
Geoff Langa8406172015-07-21 16:53:39 -04001066}
1067
1068TEST_P(ImageTest, Source2DTarget2D)
1069{
1070 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001071 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001072
1073 GLubyte data[4] = {255, 0, 255, 255};
1074
1075 // Create the Image
1076 GLuint source;
1077 EGLImageKHR image;
1078 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
1079
1080 // Create the target
1081 GLuint target;
1082 createEGLImageTargetTexture2D(image, &target);
1083
1084 // Expect that the target texture has the same color as the source texture
1085 verifyResults2D(target, data);
1086
1087 // Clean up
1088 glDeleteTextures(1, &source);
1089 eglDestroyImageKHR(window->getDisplay(), image);
1090 glDeleteTextures(1, &target);
1091}
1092
1093TEST_P(ImageTest, Source2DTargetRenderbuffer)
1094{
1095 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001096 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001097
1098 GLubyte data[4] = {255, 0, 255, 255};
1099
1100 // Create the Image
1101 GLuint source;
1102 EGLImageKHR image;
1103 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
1104
1105 // Create the target
1106 GLuint target;
1107 createEGLImageTargetRenderbuffer(image, &target);
1108
1109 // Expect that the target renderbuffer has the same color as the source texture
1110 verifyResultsRenderbuffer(target, data);
1111
1112 // Clean up
1113 glDeleteTextures(1, &source);
1114 eglDestroyImageKHR(window->getDisplay(), image);
1115 glDeleteRenderbuffers(1, &target);
1116}
1117
Geoff Langb66a9092016-05-16 15:59:14 -04001118TEST_P(ImageTest, Source2DTargetExternal)
1119{
1120 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001121 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasExternalExt());
Geoff Langb66a9092016-05-16 15:59:14 -04001122
1123 GLubyte data[4] = {255, 0, 255, 255};
1124
1125 // Create the Image
1126 GLuint source;
1127 EGLImageKHR image;
1128 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
1129
1130 // Create the target
1131 GLuint target;
1132 createEGLImageTargetTextureExternal(image, &target);
1133
1134 // Expect that the target renderbuffer has the same color as the source texture
1135 verifyResultsExternal(target, data);
1136
1137 // Clean up
1138 glDeleteTextures(1, &source);
1139 eglDestroyImageKHR(window->getDisplay(), image);
1140 glDeleteRenderbuffers(1, &target);
1141}
1142
1143TEST_P(ImageTestES3, Source2DTargetExternalESSL3)
1144{
1145 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001146 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
1147 !hasExternalESSL3Ext());
Geoff Langb66a9092016-05-16 15:59:14 -04001148
1149 GLubyte data[4] = {255, 0, 255, 255};
1150
1151 // Create the Image
1152 GLuint source;
1153 EGLImageKHR image;
1154 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
1155
1156 // Create the target
1157 GLuint target;
1158 createEGLImageTargetTextureExternal(image, &target);
1159
1160 // Expect that the target renderbuffer has the same color as the source texture
1161 verifyResultsExternalESSL3(target, data);
1162
1163 // Clean up
1164 glDeleteTextures(1, &source);
1165 eglDestroyImageKHR(window->getDisplay(), image);
1166 glDeleteRenderbuffers(1, &target);
1167}
1168
Geoff Langa8406172015-07-21 16:53:39 -04001169TEST_P(ImageTest, SourceCubeTarget2D)
1170{
1171 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001172 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasCubemapExt());
Geoff Langa8406172015-07-21 16:53:39 -04001173
1174 GLubyte data[24] = {
1175 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1176 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1177 };
1178
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001179 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
Geoff Langa8406172015-07-21 16:53:39 -04001180 {
1181 // Create the Image
1182 GLuint source;
1183 EGLImageKHR image;
1184 createEGLImageCubemapTextureSource(
1185 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1186 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image);
1187
1188 // Create the target
1189 GLuint target;
1190 createEGLImageTargetTexture2D(image, &target);
1191
1192 // Expect that the target texture has the same color as the source texture
1193 verifyResults2D(target, &data[faceIdx * 4]);
1194
1195 // Clean up
1196 glDeleteTextures(1, &source);
1197 eglDestroyImageKHR(window->getDisplay(), image);
1198 glDeleteTextures(1, &target);
1199 }
1200}
1201
1202TEST_P(ImageTest, SourceCubeTargetRenderbuffer)
1203{
1204 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001205 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasCubemapExt());
Geoff Langa8406172015-07-21 16:53:39 -04001206
1207 GLubyte data[24] = {
1208 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1209 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1210 };
1211
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001212 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
Geoff Langa8406172015-07-21 16:53:39 -04001213 {
1214 // Create the Image
1215 GLuint source;
1216 EGLImageKHR image;
1217 createEGLImageCubemapTextureSource(
1218 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1219 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image);
1220
1221 // Create the target
1222 GLuint target;
1223 createEGLImageTargetRenderbuffer(image, &target);
1224
1225 // Expect that the target texture has the same color as the source texture
1226 verifyResultsRenderbuffer(target, &data[faceIdx * 4]);
1227
1228 // Clean up
1229 glDeleteTextures(1, &source);
1230 eglDestroyImageKHR(window->getDisplay(), image);
1231 glDeleteRenderbuffers(1, &target);
1232 }
1233}
1234
Geoff Langb66a9092016-05-16 15:59:14 -04001235// Test cubemap -> external texture EGL images.
1236TEST_P(ImageTest, SourceCubeTargetExternal)
1237{
1238 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001239 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasCubemapExt() || !hasExternalExt());
Geoff Langb66a9092016-05-16 15:59:14 -04001240
1241 GLubyte data[24] = {
1242 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1243 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1244 };
1245
1246 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
1247 {
1248 // Create the Image
1249 GLuint source;
1250 EGLImageKHR image;
1251 createEGLImageCubemapTextureSource(
1252 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1253 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image);
1254
1255 // Create the target
1256 GLuint target;
1257 createEGLImageTargetTextureExternal(image, &target);
1258
1259 // Expect that the target texture has the same color as the source texture
1260 verifyResultsExternal(target, &data[faceIdx * 4]);
1261
1262 // Clean up
1263 glDeleteTextures(1, &source);
1264 eglDestroyImageKHR(window->getDisplay(), image);
1265 glDeleteRenderbuffers(1, &target);
1266 }
1267}
1268
1269// Test cubemap -> external texture EGL images using ESSL3 shaders.
1270TEST_P(ImageTestES3, SourceCubeTargetExternalESSL3)
1271{
1272 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001273 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalESSL3Ext() || !hasBaseExt() || !hasCubemapExt());
Geoff Langb66a9092016-05-16 15:59:14 -04001274
1275 GLubyte data[24] = {
1276 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1277 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1278 };
1279
1280 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
1281 {
1282 // Create the Image
1283 GLuint source;
1284 EGLImageKHR image;
1285 createEGLImageCubemapTextureSource(
1286 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1287 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image);
1288
1289 // Create the target
1290 GLuint target;
1291 createEGLImageTargetTextureExternal(image, &target);
1292
1293 // Expect that the target texture has the same color as the source texture
1294 verifyResultsExternalESSL3(target, &data[faceIdx * 4]);
1295
1296 // Clean up
1297 glDeleteTextures(1, &source);
1298 eglDestroyImageKHR(window->getDisplay(), image);
1299 glDeleteRenderbuffers(1, &target);
1300 }
1301}
1302
Geoff Langa8406172015-07-21 16:53:39 -04001303TEST_P(ImageTest, Source3DTargetTexture)
1304{
1305 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001306 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has3DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001307
Yunchao He9550c602018-02-13 14:47:05 +08001308 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langa8406172015-07-21 16:53:39 -04001309
1310 const size_t depth = 2;
1311 GLubyte data[4 * depth] = {
1312 255, 0, 255, 255, 255, 255, 0, 255,
1313 };
1314
1315 for (size_t layer = 0; layer < depth; layer++)
1316 {
1317 // Create the Image
1318 GLuint source;
1319 EGLImageKHR image;
1320 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1321 &image);
1322
1323 // Create the target
1324 GLuint target;
1325 createEGLImageTargetTexture2D(image, &target);
1326
1327 // Expect that the target renderbuffer has the same color as the source texture
1328 verifyResults2D(target, &data[layer * 4]);
1329
1330 // Clean up
1331 glDeleteTextures(1, &source);
1332 eglDestroyImageKHR(window->getDisplay(), image);
1333 glDeleteTextures(1, &target);
1334 }
1335}
1336
1337TEST_P(ImageTest, Source3DTargetRenderbuffer)
1338{
Geoff Langdbd16122018-07-19 11:30:21 -04001339 // Qualcom drivers appear to always bind the 0 layer of the source 3D texture when the target is
1340 // a renderbuffer. They work correctly when the target is a 2D texture. http://anglebug.com/2745
1341 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1342
Geoff Langa8406172015-07-21 16:53:39 -04001343 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001344 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has3DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001345
Yunchao He9550c602018-02-13 14:47:05 +08001346 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langa8406172015-07-21 16:53:39 -04001347
1348 const size_t depth = 2;
1349 GLubyte data[4 * depth] = {
1350 255, 0, 255, 255, 255, 255, 0, 255,
1351 };
1352
1353 for (size_t layer = 0; layer < depth; layer++)
1354 {
1355 // Create the Image
1356 GLuint source;
1357 EGLImageKHR image;
1358 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1359 &image);
1360
1361 // Create the target
1362 GLuint target;
1363 createEGLImageTargetRenderbuffer(image, &target);
1364
1365 // Expect that the target renderbuffer has the same color as the source texture
1366 verifyResultsRenderbuffer(target, &data[layer * 4]);
1367
1368 // Clean up
1369 glDeleteTextures(1, &source);
1370 eglDestroyImageKHR(window->getDisplay(), image);
1371 glDeleteTextures(1, &target);
1372 }
1373}
1374
Geoff Langb66a9092016-05-16 15:59:14 -04001375// Test 3D -> external texture EGL images.
1376TEST_P(ImageTest, Source3DTargetExternal)
1377{
1378 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001379 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalExt() || !hasBaseExt() || !has3DTextureExt());
Geoff Langb66a9092016-05-16 15:59:14 -04001380
Yunchao He9550c602018-02-13 14:47:05 +08001381 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langb66a9092016-05-16 15:59:14 -04001382
1383 const size_t depth = 2;
1384 GLubyte data[4 * depth] = {
1385 255, 0, 255, 255, 255, 255, 0, 255,
1386 };
1387
1388 for (size_t layer = 0; layer < depth; layer++)
1389 {
1390 // Create the Image
1391 GLuint source;
1392 EGLImageKHR image;
1393 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1394 &image);
1395
1396 // Create the target
1397 GLuint target;
1398 createEGLImageTargetTextureExternal(image, &target);
1399
1400 // Expect that the target renderbuffer has the same color as the source texture
1401 verifyResultsExternal(target, &data[layer * 4]);
1402
1403 // Clean up
1404 glDeleteTextures(1, &source);
1405 eglDestroyImageKHR(window->getDisplay(), image);
1406 glDeleteTextures(1, &target);
1407 }
1408}
1409
1410// Test 3D -> external texture EGL images using ESSL3 shaders.
1411TEST_P(ImageTestES3, Source3DTargetExternalESSL3)
1412{
1413 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001414 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalESSL3Ext() || !hasBaseExt() ||
1415 !has3DTextureExt());
Geoff Langb66a9092016-05-16 15:59:14 -04001416
Yunchao He9550c602018-02-13 14:47:05 +08001417 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langb66a9092016-05-16 15:59:14 -04001418
1419 const size_t depth = 2;
1420 GLubyte data[4 * depth] = {
1421 255, 0, 255, 255, 255, 255, 0, 255,
1422 };
1423
1424 for (size_t layer = 0; layer < depth; layer++)
1425 {
1426 // Create the Image
1427 GLuint source;
1428 EGLImageKHR image;
1429 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1430 &image);
1431
1432 // Create the target
1433 GLuint target;
1434 createEGLImageTargetTextureExternal(image, &target);
1435
1436 // Expect that the target renderbuffer has the same color as the source texture
1437 verifyResultsExternalESSL3(target, &data[layer * 4]);
1438
1439 // Clean up
1440 glDeleteTextures(1, &source);
1441 eglDestroyImageKHR(window->getDisplay(), image);
1442 glDeleteTextures(1, &target);
1443 }
1444}
1445
Geoff Langa8406172015-07-21 16:53:39 -04001446TEST_P(ImageTest, SourceRenderbufferTargetTexture)
1447{
1448 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001449 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());
Geoff Langa8406172015-07-21 16:53:39 -04001450
1451 GLubyte data[4] = {255, 0, 255, 255};
1452
1453 // Create the Image
1454 GLuint source;
1455 EGLImageKHR image;
1456 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1457
1458 // Create the target
1459 GLuint target;
1460 createEGLImageTargetTexture2D(image, &target);
1461
1462 // Expect that the target texture has the same color as the source texture
1463 verifyResults2D(target, data);
1464
1465 // Clean up
1466 glDeleteRenderbuffers(1, &source);
1467 eglDestroyImageKHR(window->getDisplay(), image);
1468 glDeleteTextures(1, &target);
1469}
1470
Geoff Langb66a9092016-05-16 15:59:14 -04001471// Test renderbuffer -> external texture EGL images.
1472TEST_P(ImageTest, SourceRenderbufferTargetTextureExternal)
1473{
1474 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001475 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalExt() || !hasBaseExt() || !hasRenderbufferExt());
Geoff Langb66a9092016-05-16 15:59:14 -04001476
1477 GLubyte data[4] = {255, 0, 255, 255};
1478
1479 // Create the Image
1480 GLuint source;
1481 EGLImageKHR image;
1482 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1483
1484 // Create the target
1485 GLuint target;
1486 createEGLImageTargetTextureExternal(image, &target);
1487
1488 // Expect that the target texture has the same color as the source texture
1489 verifyResultsExternal(target, data);
1490
1491 // Clean up
1492 glDeleteRenderbuffers(1, &source);
1493 eglDestroyImageKHR(window->getDisplay(), image);
1494 glDeleteTextures(1, &target);
1495}
1496
1497// Test renderbuffer -> external texture EGL images using ESSL3 shaders.
1498TEST_P(ImageTestES3, SourceRenderbufferTargetTextureExternalESSL3)
1499{
1500 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001501 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalESSL3Ext() || !hasBaseExt() ||
1502 !hasRenderbufferExt());
Geoff Langb66a9092016-05-16 15:59:14 -04001503
1504 GLubyte data[4] = {255, 0, 255, 255};
1505
1506 // Create the Image
1507 GLuint source;
1508 EGLImageKHR image;
1509 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1510
1511 // Create the target
1512 GLuint target;
1513 createEGLImageTargetTextureExternal(image, &target);
1514
1515 // Expect that the target texture has the same color as the source texture
1516 verifyResultsExternalESSL3(target, data);
1517
1518 // Clean up
1519 glDeleteRenderbuffers(1, &source);
1520 eglDestroyImageKHR(window->getDisplay(), image);
1521 glDeleteTextures(1, &target);
1522}
1523
Geoff Langa8406172015-07-21 16:53:39 -04001524TEST_P(ImageTest, SourceRenderbufferTargetRenderbuffer)
1525{
1526 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001527 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());
Geoff Langa8406172015-07-21 16:53:39 -04001528
1529 GLubyte data[4] = {255, 0, 255, 255};
1530
1531 // Create the Image
1532 GLuint source;
1533 EGLImageKHR image;
1534 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1535
1536 // Create the target
1537 GLuint target;
1538 createEGLImageTargetRenderbuffer(image, &target);
1539
1540 // Expect that the target renderbuffer has the same color as the source texture
1541 verifyResultsRenderbuffer(target, data);
1542
1543 // Clean up
1544 glDeleteRenderbuffers(1, &source);
1545 eglDestroyImageKHR(window->getDisplay(), image);
1546 glDeleteRenderbuffers(1, &target);
1547}
1548
1549// Delete the source texture and EGL image. The image targets should still have the same data
1550// because
1551// they hold refs to the image.
1552TEST_P(ImageTest, Deletion)
1553{
1554 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001555 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001556
1557 GLubyte originalData[4] = {255, 0, 255, 255};
1558 GLubyte updateData[4] = {0, 255, 0, 255};
1559
1560 // Create the Image
1561 GLuint source;
1562 EGLImageKHR image;
1563 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1564
1565 // Create multiple targets
1566 GLuint targetTexture;
1567 createEGLImageTargetTexture2D(image, &targetTexture);
1568
1569 GLuint targetRenderbuffer;
1570 createEGLImageTargetRenderbuffer(image, &targetRenderbuffer);
1571
1572 // Delete the source texture
1573 glDeleteTextures(1, &source);
1574 source = 0;
1575
1576 // Expect that both the targets have the original data
1577 verifyResults2D(targetTexture, originalData);
1578 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1579
1580 // Update the data of the target
1581 glBindTexture(GL_TEXTURE_2D, targetTexture);
1582 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1583
1584 // Expect that both targets have the updated data
1585 verifyResults2D(targetTexture, updateData);
1586 verifyResultsRenderbuffer(targetRenderbuffer, updateData);
1587
1588 // Delete the EGL image
1589 eglDestroyImageKHR(window->getDisplay(), image);
1590 image = EGL_NO_IMAGE_KHR;
1591
1592 // Update the data of the target back to the original data
1593 glBindTexture(GL_TEXTURE_2D, targetTexture);
1594 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData);
1595
1596 // Expect that both targets have the original data again
1597 verifyResults2D(targetTexture, originalData);
1598 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1599
1600 // Clean up
1601 glDeleteTextures(1, &targetTexture);
1602 glDeleteRenderbuffers(1, &targetRenderbuffer);
1603}
1604
1605TEST_P(ImageTest, MipLevels)
1606{
Geoff Langc0b61502018-07-27 15:59:32 -04001607 // Driver returns OOM in read pixels, some internal error.
1608 ANGLE_SKIP_TEST_IF(IsOzone() && IsOpenGLES());
Zhenyao Mo5b3b5cc2018-07-27 16:49:57 -07001609 // Also fails on NVIDIA Shield TV bot.
1610 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
Geoff Langc0b61502018-07-27 15:59:32 -04001611
Geoff Langa8406172015-07-21 16:53:39 -04001612 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001613 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001614
1615 const size_t mipLevels = 3;
1616 const size_t textureSize = 4;
1617 std::vector<GLuint> mip0Data(textureSize * textureSize, 0xFFFF0000);
1618 std::vector<GLuint> mip1Data(mip0Data.size() << 1, 0xFF00FF00);
1619 std::vector<GLuint> mip2Data(mip0Data.size() << 2, 0xFF0000FF);
1620 GLubyte *data[mipLevels] = {
Jamie Madillb980c562018-11-27 11:34:27 -05001621 reinterpret_cast<GLubyte *>(&mip0Data[0]),
1622 reinterpret_cast<GLubyte *>(&mip1Data[0]),
Geoff Langa8406172015-07-21 16:53:39 -04001623 reinterpret_cast<GLubyte *>(&mip2Data[0]),
1624 };
1625
1626 GLuint source;
1627 glGenTextures(1, &source);
1628 glBindTexture(GL_TEXTURE_2D, source);
1629
1630 for (size_t level = 0; level < mipLevels; level++)
1631 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001632 glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(level), GL_RGBA, textureSize >> level,
1633 textureSize >> level, 0, GL_RGBA, GL_UNSIGNED_BYTE, data[level]);
Geoff Langa8406172015-07-21 16:53:39 -04001634 }
1635
1636 ASSERT_GL_NO_ERROR();
1637
1638 for (size_t level = 0; level < mipLevels; level++)
1639 {
1640 // Create the Image
1641 EGLint attribs[] = {
Jamie Madillb980c562018-11-27 11:34:27 -05001642 EGL_GL_TEXTURE_LEVEL_KHR,
1643 static_cast<EGLint>(level),
1644 EGL_NONE,
Geoff Langa8406172015-07-21 16:53:39 -04001645 };
1646 EGLImageKHR image =
1647 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -07001648 reinterpretHelper<EGLClientBuffer>(source), attribs);
Geoff Langa8406172015-07-21 16:53:39 -04001649 ASSERT_EGL_SUCCESS();
1650
1651 // Create a texture and renderbuffer target
1652 GLuint textureTarget;
1653 createEGLImageTargetTexture2D(image, &textureTarget);
1654
1655 // Disable mipmapping
1656 glBindTexture(GL_TEXTURE_2D, textureTarget);
1657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1658 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1659
1660 GLuint renderbufferTarget;
1661 createEGLImageTargetRenderbuffer(image, &renderbufferTarget);
1662
1663 // Expect that the targets have the same color as the source texture
1664 verifyResults2D(textureTarget, data[level]);
1665 verifyResultsRenderbuffer(renderbufferTarget, data[level]);
1666
1667 // Clean up
1668 eglDestroyImageKHR(window->getDisplay(), image);
1669 glDeleteTextures(1, &textureTarget);
1670 glDeleteRenderbuffers(1, &renderbufferTarget);
1671 }
1672
1673 // Clean up
1674 glDeleteTextures(1, &source);
1675}
1676
1677// Respecify the source texture, orphaning it. The target texture should not have updated data.
1678TEST_P(ImageTest, Respecification)
1679{
Geoff Langdbd16122018-07-19 11:30:21 -04001680 // Respecification of textures that does not change the size of the level attached to the EGL
1681 // image does not cause orphaning on Qualcomm devices. http://anglebug.com/2744
1682 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
Geoff Langc0b61502018-07-27 15:59:32 -04001683 ANGLE_SKIP_TEST_IF(IsOzone() && IsOpenGLES());
Geoff Langdbd16122018-07-19 11:30:21 -04001684
Geoff Langa8406172015-07-21 16:53:39 -04001685 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001686 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001687
1688 GLubyte originalData[4] = {255, 0, 255, 255};
1689 GLubyte updateData[4] = {0, 255, 0, 255};
1690
1691 // Create the Image
1692 GLuint source;
1693 EGLImageKHR image;
1694 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1695
1696 // Create the target
1697 GLuint target;
1698 createEGLImageTargetTexture2D(image, &target);
1699
1700 // Respecify source
1701 glBindTexture(GL_TEXTURE_2D, source);
1702 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1703
1704 // Expect that the target texture has the original data
1705 verifyResults2D(target, originalData);
1706
1707 // Expect that the source texture has the updated data
1708 verifyResults2D(source, updateData);
1709
1710 // Clean up
1711 glDeleteTextures(1, &source);
1712 eglDestroyImageKHR(window->getDisplay(), image);
1713 glDeleteTextures(1, &target);
1714}
1715
Geoff Langdbd16122018-07-19 11:30:21 -04001716// Respecify the source texture with a different size, orphaning it. The target texture should not
1717// have updated data.
1718TEST_P(ImageTest, RespecificationDifferentSize)
1719{
1720 EGLWindow *window = getEGLWindow();
1721 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
1722
1723 GLubyte originalData[4] = {255, 0, 255, 255};
1724 GLubyte updateData[16] = {0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
1725
1726 // Create the Image
1727 GLuint source;
1728 EGLImageKHR image;
1729 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1730
1731 // Create the target
1732 GLuint target;
1733 createEGLImageTargetTexture2D(image, &target);
1734
1735 // Respecify source
1736 glBindTexture(GL_TEXTURE_2D, source);
1737 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1738
1739 // Expect that the target texture has the original data
1740 verifyResults2D(target, originalData);
1741
1742 // Expect that the source texture has the updated data
1743 verifyResults2D(source, updateData);
1744
1745 // Clean up
1746 glDeleteTextures(1, &source);
1747 eglDestroyImageKHR(window->getDisplay(), image);
1748 glDeleteTextures(1, &target);
1749}
1750
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001751// First render to a target texture, then respecify the source texture, orphaning it.
1752// The target texture's FBO should be notified of the target texture's orphaning.
1753TEST_P(ImageTest, RespecificationWithFBO)
1754{
1755 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001756 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001757
Olli Etuaho5804dc82018-04-13 14:11:46 +03001758 GLuint program = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001759 ASSERT_NE(0u, program);
1760
1761 GLubyte originalData[4] = {255, 0, 255, 255};
1762 GLubyte updateData[4] = {0, 255, 0, 255};
1763
1764 // Create the Image
1765 GLuint source;
1766 EGLImageKHR image;
1767 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1768
1769 // Create the target
1770 GLuint target;
1771 createEGLImageTargetTexture2D(image, &target);
1772
1773 // Render to the target texture
1774 GLuint fbo;
1775 glGenFramebuffers(1, &fbo);
1776 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1777 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
Olli Etuaho5804dc82018-04-13 14:11:46 +03001778 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1779 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001780
1781 // Respecify source with same parameters. This should not change the texture storage in D3D11.
1782 glBindTexture(GL_TEXTURE_2D, source);
1783 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1784
1785 // Expect that the source texture has the updated data
1786 verifyResults2D(source, updateData);
1787
1788 // Render to the target texture again and verify it gets the rendered pixels.
Olli Etuaho5804dc82018-04-13 14:11:46 +03001789 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1790 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001791
1792 // Clean up
1793 glDeleteTextures(1, &source);
1794 eglDestroyImageKHR(window->getDisplay(), image);
1795 glDeleteTextures(1, &target);
1796 glDeleteProgram(program);
1797 glDeleteFramebuffers(1, &fbo);
1798}
1799
Geoff Langa8406172015-07-21 16:53:39 -04001800// Test that respecifying a level of the target texture orphans it and keeps a copy of the EGLimage
1801// data
1802TEST_P(ImageTest, RespecificationOfOtherLevel)
1803{
Geoff Langdbd16122018-07-19 11:30:21 -04001804 // Respecification of textures that does not change the size of the level attached to the EGL
1805 // image does not cause orphaning on Qualcomm devices. http://anglebug.com/2744
1806 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1807
Geoff Langa8406172015-07-21 16:53:39 -04001808 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001809 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001810
1811 GLubyte originalData[2 * 2 * 4] = {
1812 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
1813 };
1814
1815 GLubyte updateData[2 * 2 * 4] = {
1816 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
1817 };
1818
1819 // Create the Image
1820 GLuint source;
1821 EGLImageKHR image;
1822 createEGLImage2DTextureSource(2, 2, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1823
1824 // Create the target
1825 GLuint target;
1826 createEGLImageTargetTexture2D(image, &target);
1827
1828 // Expect that the target and source textures have the original data
1829 verifyResults2D(source, originalData);
1830 verifyResults2D(target, originalData);
1831
1832 // Add a new mipLevel to the target, orphaning it
1833 glBindTexture(GL_TEXTURE_2D, target);
1834 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, originalData);
1835 EXPECT_GL_NO_ERROR();
1836
1837 // Expect that the target and source textures still have the original data
1838 verifyResults2D(source, originalData);
1839 verifyResults2D(target, originalData);
1840
1841 // Update the source's data
1842 glBindTexture(GL_TEXTURE_2D, source);
1843 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1844
1845 // Expect that the target still has the original data and source has the updated data
1846 verifyResults2D(source, updateData);
1847 verifyResults2D(target, originalData);
1848
1849 // Clean up
1850 glDeleteTextures(1, &source);
1851 eglDestroyImageKHR(window->getDisplay(), image);
1852 glDeleteTextures(1, &target);
1853}
1854
1855// Update the data of the source and target textures. All image siblings should have the new data.
1856TEST_P(ImageTest, UpdatedData)
1857{
1858 EGLWindow *window = getEGLWindow();
Jamie Madill0be37b42018-07-19 10:03:52 -04001859 ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
Geoff Langa8406172015-07-21 16:53:39 -04001860
1861 GLubyte originalData[4] = {255, 0, 255, 255};
1862 GLubyte updateData[4] = {0, 255, 0, 255};
1863
1864 // Create the Image
1865 GLuint source;
1866 EGLImageKHR image;
1867 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1868
1869 // Create multiple targets
1870 GLuint targetTexture;
1871 createEGLImageTargetTexture2D(image, &targetTexture);
1872
1873 GLuint targetRenderbuffer;
1874 createEGLImageTargetRenderbuffer(image, &targetRenderbuffer);
1875
1876 // Expect that both the source and targets have the original data
1877 verifyResults2D(source, originalData);
1878 verifyResults2D(targetTexture, originalData);
1879 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1880
1881 // Update the data of the source
1882 glBindTexture(GL_TEXTURE_2D, source);
1883 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1884
1885 // Expect that both the source and targets have the updated data
1886 verifyResults2D(source, updateData);
1887 verifyResults2D(targetTexture, updateData);
1888 verifyResultsRenderbuffer(targetRenderbuffer, updateData);
1889
1890 // Update the data of the target back to the original data
1891 glBindTexture(GL_TEXTURE_2D, targetTexture);
1892 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData);
1893
1894 // Expect that both the source and targets have the original data again
1895 verifyResults2D(source, originalData);
1896 verifyResults2D(targetTexture, originalData);
1897 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1898
1899 // Clean up
1900 glDeleteTextures(1, &source);
1901 eglDestroyImageKHR(window->getDisplay(), image);
1902 glDeleteTextures(1, &targetTexture);
1903 glDeleteRenderbuffers(1, &targetRenderbuffer);
1904}
1905
1906// Use this to select which configurations (e.g. which renderer, which GLES major version) these
1907// tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -05001908ANGLE_INSTANTIATE_TEST(ImageTest,
1909 ES2_D3D9(),
1910 ES2_D3D11(),
1911 ES3_D3D11(),
1912 ES2_OPENGL(),
1913 ES3_OPENGL(),
1914 ES2_OPENGLES(),
Luc Ferronaf883622018-06-08 15:57:31 -04001915 ES3_OPENGLES(),
1916 ES2_VULKAN());
Geoff Langb66a9092016-05-16 15:59:14 -04001917ANGLE_INSTANTIATE_TEST(ImageTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Jamie Madillb980c562018-11-27 11:34:27 -05001918} // namespace angle