blob: 7a36e4d0c2e7ad0d8223e384474bba7e5e5630e9 [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{
14class ImageTest : public ANGLETest
15{
16 protected:
17 ImageTest()
18 {
19 setWindowWidth(128);
20 setWindowHeight(128);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 setConfigDepthBits(24);
26 }
27
28 void SetUp() override
29 {
30 ANGLETest::SetUp();
31
32 const std::string vsSource =
33 "precision highp float;\n"
34 "attribute vec4 position;\n"
35 "varying vec2 texcoord;\n"
36 "\n"
37 "void main()\n"
38 "{\n"
39 " gl_Position = position;\n"
40 " texcoord = (position.xy * 0.5) + 0.5;\n"
41 " texcoord.y = 1.0 - texcoord.y;\n"
42 "}\n";
Geoff Langb66a9092016-05-16 15:59:14 -040043 const std::string vsESSL3Source =
44 "#version 300 es\n"
45 "precision highp float;\n"
46 "in vec4 position;\n"
47 "out vec2 texcoord;\n"
48 "\n"
49 "void main()\n"
50 "{\n"
51 " gl_Position = position;\n"
52 " texcoord = (position.xy * 0.5) + 0.5;\n"
53 " texcoord.y = 1.0 - texcoord.y;\n"
54 "}\n";
Geoff Langa8406172015-07-21 16:53:39 -040055
56 const std::string textureFSSource =
57 "precision highp float;\n"
58 "uniform sampler2D tex;\n"
59 "varying vec2 texcoord;\n"
60 "\n"
61 "void main()\n"
62 "{\n"
63 " gl_FragColor = texture2D(tex, texcoord);\n"
64 "}\n";
Geoff Langb66a9092016-05-16 15:59:14 -040065 const std::string textureExternalFSSource =
66 "#extension GL_OES_EGL_image_external : require\n"
67 "precision highp float;\n"
68 "uniform samplerExternalOES tex;\n"
69 "varying vec2 texcoord;\n"
70 "\n"
71 "void main()\n"
72 "{\n"
73 " gl_FragColor = texture2D(tex, texcoord);\n"
74 "}\n";
75 const std::string textureExternalESSL3FSSource =
76 "#version 300 es\n"
77 "#extension GL_OES_EGL_image_external_essl3 : require\n"
78 "precision highp float;\n"
79 "uniform samplerExternalOES tex;\n"
80 "in vec2 texcoord;\n"
81 "out vec4 color;"
82 "\n"
83 "void main()\n"
84 "{\n"
85 " color = texture(tex, texcoord);\n"
86 "}\n";
Geoff Langa8406172015-07-21 16:53:39 -040087
88 mTextureProgram = CompileProgram(vsSource, textureFSSource);
89 if (mTextureProgram == 0)
90 {
91 FAIL() << "shader compilation failed.";
92 }
93
94 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
95
Geoff Langb66a9092016-05-16 15:59:14 -040096 if (extensionEnabled("GL_OES_EGL_image_external"))
97 {
98 mTextureExternalProgram = CompileProgram(vsSource, textureExternalFSSource);
99 ASSERT_NE(0u, mTextureExternalProgram) << "shader compilation failed.";
100
101 mTextureExternalUniformLocation = glGetUniformLocation(mTextureExternalProgram, "tex");
102 }
103
104 if (extensionEnabled("GL_OES_EGL_image_external_essl3"))
105 {
106 mTextureExternalESSL3Program =
107 CompileProgram(vsESSL3Source, textureExternalESSL3FSSource);
108 ASSERT_NE(0u, mTextureExternalESSL3Program) << "shader compilation failed.";
109
110 mTextureExternalESSL3UniformLocation =
111 glGetUniformLocation(mTextureExternalESSL3Program, "tex");
112 }
113
Geoff Langa8406172015-07-21 16:53:39 -0400114 eglCreateImageKHR =
115 reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
116 eglDestroyImageKHR =
117 reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
118
119 ASSERT_GL_NO_ERROR();
120 }
121
122 void TearDown() override
123 {
Geoff Langa8406172015-07-21 16:53:39 -0400124 glDeleteProgram(mTextureProgram);
Geoff Langb66a9092016-05-16 15:59:14 -0400125 glDeleteProgram(mTextureExternalProgram);
126 glDeleteProgram(mTextureExternalESSL3Program);
127
128 ANGLETest::TearDown();
Geoff Langa8406172015-07-21 16:53:39 -0400129 }
130
131 void createEGLImage2DTextureSource(size_t width,
132 size_t height,
133 GLenum format,
134 GLenum type,
135 void *data,
136 GLuint *outSourceTexture,
137 EGLImageKHR *outSourceImage)
138 {
139 // Create a source 2D texture
140 GLuint source;
141 glGenTextures(1, &source);
142 glBindTexture(GL_TEXTURE_2D, source);
143
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700144 glTexImage2D(GL_TEXTURE_2D, 0, format, static_cast<GLsizei>(width),
145 static_cast<GLsizei>(height), 0, format, type, data);
Geoff Langa8406172015-07-21 16:53:39 -0400146
147 // Disable mipmapping
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
150
151 ASSERT_GL_NO_ERROR();
152
153 // Create an image from the source texture
154 EGLWindow *window = getEGLWindow();
155 EGLImageKHR image =
156 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700157 reinterpretHelper<EGLClientBuffer>(source), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400158
159 ASSERT_EGL_SUCCESS();
160
161 *outSourceTexture = source;
162 *outSourceImage = image;
163 }
164
165 void createEGLImageCubemapTextureSource(size_t width,
166 size_t height,
167 GLenum format,
168 GLenum type,
169 uint8_t *data,
170 size_t dataStride,
171 EGLenum imageTarget,
172 GLuint *outSourceTexture,
173 EGLImageKHR *outSourceImage)
174 {
175 // Create a source cube map texture
176 GLuint source;
177 glGenTextures(1, &source);
178 glBindTexture(GL_TEXTURE_CUBE_MAP, source);
179
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700180 for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++)
Geoff Langa8406172015-07-21 16:53:39 -0400181 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700182 glTexImage2D(faceIdx + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format,
183 static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0, format, type,
184 data + (faceIdx * dataStride));
Geoff Langa8406172015-07-21 16:53:39 -0400185 }
186
187 // Disable mipmapping
188 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
189 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
190
191 ASSERT_GL_NO_ERROR();
192
193 // Create an image from the source texture
194 EGLWindow *window = getEGLWindow();
195 EGLImageKHR image =
196 eglCreateImageKHR(window->getDisplay(), window->getContext(), imageTarget,
Austin Kinrossa8187762015-08-12 10:54:37 -0700197 reinterpretHelper<EGLClientBuffer>(source), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400198
199 ASSERT_EGL_SUCCESS();
200
201 *outSourceTexture = source;
202 *outSourceImage = image;
203 }
204
205 void createEGLImage3DTextureSource(size_t width,
206 size_t height,
207 size_t depth,
208 GLenum format,
209 GLenum type,
210 void *data,
211 size_t imageLayer,
212 GLuint *outSourceTexture,
213 EGLImageKHR *outSourceImage)
214 {
215 // Create a source 3D texture
216 GLuint source;
217 glGenTextures(1, &source);
218 glBindTexture(GL_TEXTURE_3D, source);
219
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700220 glTexImage3D(GL_TEXTURE_3D, 0, format, static_cast<GLsizei>(width),
221 static_cast<GLsizei>(height), static_cast<GLsizei>(depth), 0, format, type,
222 data);
Geoff Langa8406172015-07-21 16:53:39 -0400223
224 // Disable mipmapping
225 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
226 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
227
228 ASSERT_GL_NO_ERROR();
229
230 // Create an image from the source texture
231 EGLWindow *window = getEGLWindow();
232
233 EGLint attribs[] = {
234 EGL_GL_TEXTURE_ZOFFSET_KHR, static_cast<EGLint>(imageLayer), EGL_NONE,
235 };
236 EGLImageKHR image =
237 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700238 reinterpretHelper<EGLClientBuffer>(source), attribs);
Geoff Langa8406172015-07-21 16:53:39 -0400239
240 ASSERT_EGL_SUCCESS();
241
242 *outSourceTexture = source;
243 *outSourceImage = image;
244 }
245
246 void createEGLImageRenderbufferSource(size_t width,
247 size_t height,
248 GLenum internalFormat,
249 GLubyte data[4],
250 GLuint *outSourceRenderbuffer,
251 EGLImageKHR *outSourceImage)
252 {
253 // Create a source renderbuffer
254 GLuint source;
255 glGenRenderbuffers(1, &source);
256 glBindRenderbuffer(GL_RENDERBUFFER, source);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700257 glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, static_cast<GLsizei>(width),
258 static_cast<GLsizei>(height));
Geoff Langa8406172015-07-21 16:53:39 -0400259
260 // Create a framebuffer and clear it to set the data
261 GLuint framebuffer;
262 glGenFramebuffers(1, &framebuffer);
263 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
264 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, source);
265
266 glClearColor(data[0] / 255.0f, data[1] / 255.0f, data[2] / 255.0f, data[3] / 255.0f);
267 glClear(GL_COLOR_BUFFER_BIT);
268
269 glDeleteFramebuffers(1, &framebuffer);
270
271 ASSERT_GL_NO_ERROR();
272
273 // Create an image from the source renderbuffer
274 EGLWindow *window = getEGLWindow();
275 EGLImageKHR image =
276 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_RENDERBUFFER_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700277 reinterpretHelper<EGLClientBuffer>(source), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400278
279 ASSERT_EGL_SUCCESS();
280
281 *outSourceRenderbuffer = source;
282 *outSourceImage = image;
283 }
284
285 void createEGLImageTargetTexture2D(EGLImageKHR image, GLuint *outTargetTexture)
286 {
287 // Create a target texture from the image
288 GLuint target;
289 glGenTextures(1, &target);
290 glBindTexture(GL_TEXTURE_2D, target);
291 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
292
293 // Disable mipmapping
294 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
295 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
296
297 ASSERT_GL_NO_ERROR();
298
299 *outTargetTexture = target;
300 }
301
Geoff Langb66a9092016-05-16 15:59:14 -0400302 void createEGLImageTargetTextureExternal(EGLImageKHR image, GLuint *outTargetTexture)
303 {
304 // Create a target texture from the image
305 GLuint target;
306 glGenTextures(1, &target);
307 glBindTexture(GL_TEXTURE_EXTERNAL_OES, target);
308 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
309
310 // Disable mipmapping
311 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
312 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
313
314 ASSERT_GL_NO_ERROR();
315
316 *outTargetTexture = target;
317 }
318
Geoff Langa8406172015-07-21 16:53:39 -0400319 void createEGLImageTargetRenderbuffer(EGLImageKHR image, GLuint *outTargetRenderbuffer)
320 {
321 // Create a target texture from the image
322 GLuint target;
323 glGenRenderbuffers(1, &target);
324 glBindRenderbuffer(GL_RENDERBUFFER, target);
325 glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
326
327 ASSERT_GL_NO_ERROR();
328
329 *outTargetRenderbuffer = target;
330 }
331
Geoff Langb66a9092016-05-16 15:59:14 -0400332 void verifyResultsTexture(GLuint texture,
333 GLubyte data[4],
334 GLenum textureTarget,
335 GLuint program,
336 GLuint textureUniform)
Geoff Langa8406172015-07-21 16:53:39 -0400337 {
338 // Draw a quad with the target texture
Geoff Langb66a9092016-05-16 15:59:14 -0400339 glUseProgram(program);
340 glBindTexture(textureTarget, texture);
341 glUniform1i(textureUniform, 0);
Geoff Langa8406172015-07-21 16:53:39 -0400342
Geoff Langb66a9092016-05-16 15:59:14 -0400343 drawQuad(program, "position", 0.5f);
Geoff Langa8406172015-07-21 16:53:39 -0400344
345 // Expect that the rendered quad has the same color as the source texture
346 EXPECT_PIXEL_EQ(0, 0, data[0], data[1], data[2], data[3]);
347 }
348
Geoff Langb66a9092016-05-16 15:59:14 -0400349 void verifyResults2D(GLuint texture, GLubyte data[4])
350 {
351 verifyResultsTexture(texture, data, GL_TEXTURE_2D, mTextureProgram,
352 mTextureUniformLocation);
353 }
354
355 void verifyResultsExternal(GLuint texture, GLubyte data[4])
356 {
357 verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalProgram,
358 mTextureExternalUniformLocation);
359 }
360
361 void verifyResultsExternalESSL3(GLuint texture, GLubyte data[4])
362 {
363 verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalESSL3Program,
364 mTextureExternalESSL3UniformLocation);
365 }
366
Geoff Langa8406172015-07-21 16:53:39 -0400367 void verifyResultsRenderbuffer(GLuint renderbuffer, GLubyte data[4])
368 {
369 // Bind the renderbuffer to a framebuffer
370 GLuint framebuffer;
371 glGenFramebuffers(1, &framebuffer);
372 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
373 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
374 renderbuffer);
375
376 // Expect that the rendered quad has the same color as the source texture
377 EXPECT_PIXEL_EQ(0, 0, data[0], data[1], data[2], data[3]);
378
379 glDeleteFramebuffers(1, &framebuffer);
380 }
381
Austin Kinrossa8187762015-08-12 10:54:37 -0700382 template <typename destType, typename sourcetype>
383 destType reinterpretHelper(sourcetype source)
384 {
385 static_assert(sizeof(destType) == sizeof(size_t),
386 "destType should be the same size as a size_t");
387 size_t sourceSizeT = static_cast<size_t>(source);
388 return reinterpret_cast<destType>(sourceSizeT);
389 }
390
Geoff Langa8406172015-07-21 16:53:39 -0400391 GLuint mTextureProgram;
392 GLint mTextureUniformLocation;
393
Geoff Langb66a9092016-05-16 15:59:14 -0400394 GLuint mTextureExternalProgram = 0;
395 GLint mTextureExternalUniformLocation = -1;
396
397 GLuint mTextureExternalESSL3Program = 0;
398 GLint mTextureExternalESSL3UniformLocation = -1;
399
Geoff Langa8406172015-07-21 16:53:39 -0400400 PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
401 PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
402};
403
Geoff Langb66a9092016-05-16 15:59:14 -0400404class ImageTestES3 : public ImageTest
405{
406};
407
Geoff Langa8406172015-07-21 16:53:39 -0400408// Check validation from the EGL_KHR_image_base extension
409TEST_P(ImageTest, ValidationImageBase)
410{
411 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +0800412 ANGLE_SKIP_TEST_IF(
413 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -0400414 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +0800415 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -0400416
417 GLuint glTexture2D;
418 glGenTextures(1, &glTexture2D);
419 glBindTexture(GL_TEXTURE_2D, glTexture2D);
420 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
421
422 EGLDisplay display = window->getDisplay();
423 EGLContext context = window->getContext();
424 EGLConfig config = window->getConfig();
425 EGLImageKHR image = EGL_NO_IMAGE_KHR;
Austin Kinrossa8187762015-08-12 10:54:37 -0700426 EGLClientBuffer texture2D = reinterpretHelper<EGLClientBuffer>(glTexture2D);
Geoff Langa8406172015-07-21 16:53:39 -0400427
428 // Test validation of eglCreateImageKHR
429
430 // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is
431 // generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700432 image = eglCreateImageKHR(reinterpretHelper<EGLDisplay>(0xBAADF00D), context,
Geoff Langa8406172015-07-21 16:53:39 -0400433 EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
434 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
435 EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
436
437 // If <ctx> is neither the handle of a valid EGLContext object on <dpy> nor EGL_NO_CONTEXT, the
438 // error EGL_BAD_CONTEXT is generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700439 image = eglCreateImageKHR(display, reinterpretHelper<EGLContext>(0xBAADF00D),
Geoff Langa8406172015-07-21 16:53:39 -0400440 EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
441 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
442 EXPECT_EGL_ERROR(EGL_BAD_CONTEXT);
443
444 // Test EGL_NO_CONTEXT with a 2D texture target which does require a context.
445 image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
446 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
447 EXPECT_EGL_ERROR(EGL_BAD_CONTEXT);
448
449 // If an attribute specified in <attrib_list> is not one of the attributes listed in Table bbb,
450 // the error EGL_BAD_PARAMETER is generated.
451 EGLint badAttributes[] = {
452 static_cast<EGLint>(0xDEADBEEF), 0, EGL_NONE,
453 };
454
455 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, badAttributes);
456 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
457 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
458
459 // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> has an off -
460 // screen buffer bound to it(e.g., by a
461 // previous call to eglBindTexImage), the error EGL_BAD_ACCESS is generated.
462 EGLint surfaceType = 0;
463 eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType);
464
465 EGLint bindToTextureRGBA = 0;
466 eglGetConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBA);
467 if ((surfaceType & EGL_PBUFFER_BIT) != 0 && bindToTextureRGBA == EGL_TRUE)
468 {
469 EGLint pbufferAttributes[] = {
470 EGL_WIDTH, 1,
471 EGL_HEIGHT, 1,
472 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
473 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
474 EGL_NONE, EGL_NONE,
475 };
476 EGLSurface pbuffer = eglCreatePbufferSurface(display, config, pbufferAttributes);
477 ASSERT_NE(pbuffer, EGL_NO_SURFACE);
478 EXPECT_EGL_SUCCESS();
479
480 eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
481 EXPECT_EGL_SUCCESS();
482
483 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
484 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
485 EXPECT_EGL_ERROR(EGL_BAD_ACCESS);
486
487 eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER);
488 eglDestroySurface(display, pbuffer);
489 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
490 EXPECT_EGL_SUCCESS();
491 EXPECT_GL_NO_ERROR();
492 }
493
494 // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and
495 // <attrib_list> is itself an EGLImage sibling, the error EGL_BAD_ACCESS is generated.
496 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
497 EXPECT_NE(image, EGL_NO_IMAGE_KHR);
498 EXPECT_EGL_SUCCESS();
499
500 /* TODO(geofflang): Enable this validation when it passes.
501 EGLImageKHR image2 = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
502 reinterpret_cast<EGLClientBuffer>(texture2D), nullptr);
503 EXPECT_EQ(image2, EGL_NO_IMAGE_KHR);
504 EXPECT_EGL_ERROR(EGL_BAD_ACCESS);
505 */
506
507 // Test validation of eglDestroyImageKHR
508 // Note: image is now a valid EGL image
509 EGLBoolean result = EGL_FALSE;
510
511 // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is
512 // generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700513 result = eglDestroyImageKHR(reinterpretHelper<EGLDisplay>(0xBAADF00D), image);
Geoff Langa8406172015-07-21 16:53:39 -0400514 EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE));
515 EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
516
517 // If <image> is not a valid EGLImageKHR object created with respect to <dpy>, the error
518 // EGL_BAD_PARAMETER is generated.
Austin Kinrossa8187762015-08-12 10:54:37 -0700519 result = eglDestroyImageKHR(display, reinterpretHelper<EGLImageKHR>(0xBAADF00D));
Geoff Langa8406172015-07-21 16:53:39 -0400520 EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE));
521 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
522
523 // Clean up and validate image is destroyed
524 result = eglDestroyImageKHR(display, image);
525 EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_TRUE));
526 EXPECT_EGL_SUCCESS();
527
528 glDeleteTextures(1, &glTexture2D);
529 EXPECT_GL_NO_ERROR();
530}
531
532// Check validation from the EGL_KHR_gl_texture_2D_image extension
533TEST_P(ImageTest, ValidationImagePixmap)
534{
535 // This extension is not implemented anywhere yet. This makes sure that it is tested once it is
536 // added.
537 EGLWindow *window = getEGLWindow();
538 EXPECT_FALSE(eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_pixmap"));
539}
540
541// Check validation from the EGL_KHR_gl_texture_2D_image, EGL_KHR_gl_texture_cubemap_image,
542// EGL_KHR_gl_texture_3D_image and EGL_KHR_gl_renderbuffer_image extensions
543TEST_P(ImageTest, ValidationGLImage)
544{
545 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +0800546 ANGLE_SKIP_TEST_IF(!extensionEnabled("OES_EGL_image") ||
547 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base"));
Geoff Langa8406172015-07-21 16:53:39 -0400548
549 EGLDisplay display = window->getDisplay();
550 EGLContext context = window->getContext();
551 EGLImageKHR image = EGL_NO_IMAGE_KHR;
552
553 if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"))
554 {
555 // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR or
556 // EGL_GL_TEXTURE_3D_KHR and <buffer> is not the name of a texture object of type <target>,
557 // the error EGL_BAD_PARAMETER is generated.
558 GLuint textureCube;
559 glGenTextures(1, &textureCube);
560 glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
561 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
562 face++)
563 {
564 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
565 }
566
567 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700568 reinterpretHelper<EGLClientBuffer>(textureCube), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400569 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
570 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
571
572 // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR,
573 // EGL_GL_TEXTURE_CUBE_MAP_*_KHR or EGL_GL_TEXTURE_3D_KHR, <buffer> is the name of an
574 // incomplete GL texture object, and any mipmap levels other than mipmap level 0 are
575 // specified, the error EGL_BAD_PARAMETER is generated.
576 GLuint incompleteTexture;
577 glGenTextures(1, &incompleteTexture);
578 glBindTexture(GL_TEXTURE_2D, incompleteTexture);
579 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
580 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
581
582 EGLint level0Attribute[] = {
583 EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE,
584 };
585 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700586 reinterpretHelper<EGLClientBuffer>(incompleteTexture),
Geoff Langa8406172015-07-21 16:53:39 -0400587 level0Attribute);
588 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
589 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
590
591 // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR or
592 // EGL_GL_TEXTURE_3D_KHR, <buffer> is not the name of a complete GL texture object, and
593 // mipmap level 0 is not specified, the error EGL_BAD_PARAMETER is generated.
594 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
595 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700596 reinterpretHelper<EGLClientBuffer>(incompleteTexture), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400597 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
598 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
599
600 // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR,
601 // EGL_GL_RENDERBUFFER_KHR or EGL_GL_TEXTURE_3D_KHR and <buffer> refers to the default GL
602 // texture object(0) for the corresponding GL target, the error EGL_BAD_PARAMETER is
603 // generated.
604 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, 0, nullptr);
605 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
606 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
607
608 // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR, or
609 // EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for
610 // EGL_GL_TEXTURE_LEVEL_KHR is not a valid mipmap level for the specified GL texture object
611 // <buffer>, the error EGL_BAD_MATCH is generated.
612 EGLint level2Attribute[] = {
613 EGL_GL_TEXTURE_LEVEL_KHR, 2, EGL_NONE,
614 };
615 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700616 reinterpretHelper<EGLClientBuffer>(incompleteTexture),
Geoff Langa8406172015-07-21 16:53:39 -0400617 level2Attribute);
618 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
619 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
620 }
621 else
622 {
623 GLuint texture2D;
624 glGenTextures(1, &texture2D);
625 glBindTexture(GL_TEXTURE_2D, texture2D);
626 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
627
628 // From EGL_KHR_image_base:
629 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
630 // generated.
631 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700632 reinterpretHelper<EGLClientBuffer>(texture2D), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400633 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
634 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
635 }
636
637 if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image"))
638 {
639 // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_CUBE_MAP_*_KHR, <buffer> is
640 // not the name of a complete GL texture object, and one or more faces do not have mipmap
641 // level 0 specified, the error EGL_BAD_PARAMETER is generated.
642 GLuint incompleteTextureCube;
643 glGenTextures(1, &incompleteTextureCube);
644 glBindTexture(GL_TEXTURE_CUBE_MAP, incompleteTextureCube);
645 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
646 nullptr);
647 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
648 nullptr);
649 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
650 nullptr);
651 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
652 nullptr);
653 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
654 nullptr);
655
656 EGLint level0Attribute[] = {
657 EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE,
658 };
659 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700660 reinterpretHelper<EGLClientBuffer>(incompleteTextureCube),
Geoff Langa8406172015-07-21 16:53:39 -0400661 level0Attribute);
662 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
663 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
664 }
665 else
666 {
667 GLuint textureCube;
668 glGenTextures(1, &textureCube);
669 glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
670 for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
671 face++)
672 {
673 glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
674 }
675
676 // From EGL_KHR_image_base:
677 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
678 // generated.
679 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_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
685 if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image") &&
Martin Radev1be913c2016-07-11 17:59:16 +0300686 getClientMajorVersion() >= 3)
Geoff Langa8406172015-07-21 16:53:39 -0400687 {
688 // If <target> is EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for
689 // EGL_GL_TEXTURE_ZOFFSET_KHR exceeds the depth of the specified mipmap level - of - detail
690 // in <buffer>, the error EGL_BAD_PARAMETER is generated.
691 GLuint texture3D;
692 glGenTextures(1, &texture3D);
693 glBindTexture(GL_TEXTURE_3D, texture3D);
694 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
695
696 EGLint zOffset3Parameter[] = {
697 EGL_GL_TEXTURE_ZOFFSET_KHR, 3, EGL_NONE,
698 };
699 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700700 reinterpretHelper<EGLClientBuffer>(texture3D), zOffset3Parameter);
Geoff Langa8406172015-07-21 16:53:39 -0400701 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
702 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
703
704 EGLint zOffsetNegative1Parameter[] = {
705 EGL_GL_TEXTURE_ZOFFSET_KHR, -1, EGL_NONE,
706 };
707 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700708 reinterpretHelper<EGLClientBuffer>(texture3D),
Geoff Langa8406172015-07-21 16:53:39 -0400709 zOffsetNegative1Parameter);
710 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
711 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
712 }
713 else
714 {
715 if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"))
716 {
717 GLuint texture2D;
718 glGenTextures(1, &texture2D);
719 glBindTexture(GL_TEXTURE_2D, texture2D);
720 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
721
722 // Verify EGL_GL_TEXTURE_ZOFFSET_KHR is not a valid parameter
723 EGLint zOffset0Parameter[] = {
724 EGL_GL_TEXTURE_ZOFFSET_KHR, 0, EGL_NONE,
725 };
726
727 image =
728 eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700729 reinterpretHelper<EGLClientBuffer>(texture2D), zOffset0Parameter);
Geoff Langa8406172015-07-21 16:53:39 -0400730 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
731 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
732 }
733
Martin Radev1be913c2016-07-11 17:59:16 +0300734 if (getClientMajorVersion() >= 3)
Geoff Langa8406172015-07-21 16:53:39 -0400735 {
736 GLuint texture3D;
737 glGenTextures(1, &texture3D);
738 glBindTexture(GL_TEXTURE_3D, texture3D);
739 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
740
741 // From EGL_KHR_image_base:
742 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
743 // generated.
744 image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700745 reinterpretHelper<EGLClientBuffer>(texture3D), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400746 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
747 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
748 }
749 }
750
751 if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image"))
752 {
753 // If <target> is EGL_GL_RENDERBUFFER_KHR and <buffer> is not the name of a renderbuffer
754 // object, or if <buffer> is the name of a multisampled renderbuffer object, the error
755 // EGL_BAD_PARAMETER is generated.
756 image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
757 reinterpret_cast<EGLClientBuffer>(0), nullptr);
758 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
759 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
760
761 if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
762 {
763 GLuint renderbuffer;
764 glGenRenderbuffers(1, &renderbuffer);
765 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
766 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
767 EXPECT_GL_NO_ERROR();
768
769 image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
770 reinterpret_cast<EGLClientBuffer>(0), nullptr);
771 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
772 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
773 }
774 }
775 else
776 {
777 GLuint renderbuffer;
778 glGenRenderbuffers(1, &renderbuffer);
779 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
780 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 1, 1);
781
782 // From EGL_KHR_image_base:
783 // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
784 // generated.
785 image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -0700786 reinterpretHelper<EGLClientBuffer>(renderbuffer), nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400787 EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
788 EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
789 }
790}
791
792// Check validation from the GL_OES_EGL_image extension
793TEST_P(ImageTest, ValidationGLEGLImage)
794{
795 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +0800796 ANGLE_SKIP_TEST_IF(
797 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -0400798 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +0800799 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -0400800
801 GLubyte data[4] = {255, 0, 255, 255};
802
803 // Create the Image
804 GLuint source;
805 EGLImageKHR image;
806 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
807
808 // If <target> is not TEXTURE_2D, the error INVALID_ENUM is generated.
809 glEGLImageTargetTexture2DOES(GL_TEXTURE_CUBE_MAP_POSITIVE_X, image);
810 EXPECT_GL_ERROR(GL_INVALID_ENUM);
811
812 // If <image> does not refer to a valid eglImageOES object, the error INVALID_VALUE is
813 // generated.
814 GLuint texture;
815 glGenTextures(1, &texture);
816 glBindTexture(GL_TEXTURE_2D, texture);
Austin Kinrossa8187762015-08-12 10:54:37 -0700817 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, reinterpretHelper<GLeglImageOES>(0xBAADF00D));
Geoff Langa8406172015-07-21 16:53:39 -0400818 EXPECT_GL_ERROR(GL_INVALID_VALUE);
819
820 // <target> must be RENDERBUFFER_OES, and <image> must be the handle of a valid EGLImage
821 // resource, cast into the type
822 // eglImageOES.
823 glEGLImageTargetRenderbufferStorageOES(GL_TEXTURE_2D, image);
824 EXPECT_GL_ERROR(GL_INVALID_ENUM);
825
826 // If the GL is unable to create a renderbuffer using the specified eglImageOES, the error
827 // INVALID_OPERATION is generated.If <image>
828 // does not refer to a valid eglImageOES object, the error INVALID_VALUE is generated.
829 GLuint renderbuffer;
830 glGenRenderbuffers(1, &renderbuffer);
831 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
832 glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
Austin Kinrossa8187762015-08-12 10:54:37 -0700833 reinterpretHelper<GLeglImageOES>(0xBAADF00D));
Geoff Langa8406172015-07-21 16:53:39 -0400834 EXPECT_GL_ERROR(GL_INVALID_VALUE);
835
836 // Clean up
837 glDeleteTextures(1, &source);
838 eglDestroyImageKHR(window->getDisplay(), image);
839 glDeleteTextures(1, &texture);
840 glDeleteRenderbuffers(1, &renderbuffer);
841}
842
843// Check validation from the GL_OES_EGL_image_external extension
844TEST_P(ImageTest, ValidationGLEGLImageExternal)
845{
Yunchao He9550c602018-02-13 14:47:05 +0800846 ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_OES_EGL_image_external"));
Geoff Langb66a9092016-05-16 15:59:14 -0400847
848 GLuint texture;
849 glGenTextures(1, &texture);
850 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
851
852 // In the initial state of a TEXTURE_EXTERNAL_OES texture object, the value assigned to
853 // TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER is LINEAR, and the s and t wrap modes are both set
854 // to CLAMP_TO_EDGE
855 auto getTexParam = [](GLenum target, GLenum pname)
856 {
857 GLint value = 0;
858 glGetTexParameteriv(target, pname, &value);
859 EXPECT_GL_NO_ERROR();
860 return value;
861 };
862 EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER));
863 EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER));
864 EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S));
865 EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T));
866
867 // "When <target> is TEXTURE_EXTERNAL_OES only NEAREST and LINEAR are accepted as
868 // TEXTURE_MIN_FILTER, only CLAMP_TO_EDGE is accepted as TEXTURE_WRAP_S and TEXTURE_WRAP_T, and
869 // only FALSE is accepted as GENERATE_MIPMAP. Attempting to set other values for
870 // TEXTURE_MIN_FILTER, TEXTURE_WRAP_S, TEXTURE_WRAP_T, or GENERATE_MIPMAP will result in an
871 // INVALID_ENUM error.
872 GLenum validMinFilters[]{
873 GL_NEAREST, GL_LINEAR,
874 };
875 for (auto minFilter : validMinFilters)
876 {
877 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
878 EXPECT_GL_NO_ERROR();
879 }
880
881 GLenum invalidMinFilters[]{
882 GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR,
883 GL_LINEAR_MIPMAP_NEAREST,
884 };
885 for (auto minFilter : invalidMinFilters)
886 {
887 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
888 EXPECT_GL_ERROR(GL_INVALID_ENUM);
889 }
890
891 GLenum validWrapModes[]{
892 GL_CLAMP_TO_EDGE,
893 };
894 for (auto minFilter : validWrapModes)
895 {
896 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, minFilter);
897 EXPECT_GL_NO_ERROR();
898 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, minFilter);
899 EXPECT_GL_NO_ERROR();
900 }
901
902 GLenum invalidWrapModes[]{
903 GL_REPEAT, GL_MIRRORED_REPEAT,
904 };
905 for (auto minFilter : invalidWrapModes)
906 {
907 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, minFilter);
908 EXPECT_GL_ERROR(GL_INVALID_ENUM);
909 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, minFilter);
910 EXPECT_GL_ERROR(GL_INVALID_ENUM);
911 }
912
913 // When <target> is set to TEXTURE_EXTERNAL_OES, GenerateMipmap always fails and generates an
914 // INVALID_ENUM error.
915 glGenerateMipmap(GL_TEXTURE_EXTERNAL_OES);
916 EXPECT_GL_ERROR(GL_INVALID_ENUM);
917
918 glDeleteTextures(1, &texture);
Geoff Langa8406172015-07-21 16:53:39 -0400919}
920
921// Check validation from the GL_OES_EGL_image_external_essl3 extension
922TEST_P(ImageTest, ValidationGLEGLImageExternalESSL3)
923{
Yunchao He9550c602018-02-13 14:47:05 +0800924 ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_OES_EGL_image_external_essl3"));
Geoff Langb66a9092016-05-16 15:59:14 -0400925
926 // Make sure this extension is not exposed without ES3.
Martin Radev1be913c2016-07-11 17:59:16 +0300927 ASSERT_GE(getClientMajorVersion(), 3);
Geoff Langb66a9092016-05-16 15:59:14 -0400928
929 GLuint texture;
930 glGenTextures(1, &texture);
931 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
932
933 // It is an INVALID_OPERATION error to set the TEXTURE_BASE_LEVEL to a value other than zero.
934 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 1);
935 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
936
937 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 10);
938 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
939
940 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 0);
941 EXPECT_GL_NO_ERROR();
942
943 glDeleteTextures(1, &texture);
Geoff Langa8406172015-07-21 16:53:39 -0400944}
945
946TEST_P(ImageTest, Source2DTarget2D)
947{
948 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +0800949 ANGLE_SKIP_TEST_IF(
950 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -0400951 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +0800952 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -0400953
954 GLubyte data[4] = {255, 0, 255, 255};
955
956 // Create the Image
957 GLuint source;
958 EGLImageKHR image;
959 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
960
961 // Create the target
962 GLuint target;
963 createEGLImageTargetTexture2D(image, &target);
964
965 // Expect that the target texture has the same color as the source texture
966 verifyResults2D(target, data);
967
968 // Clean up
969 glDeleteTextures(1, &source);
970 eglDestroyImageKHR(window->getDisplay(), image);
971 glDeleteTextures(1, &target);
972}
973
974TEST_P(ImageTest, Source2DTargetRenderbuffer)
975{
976 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +0800977 ANGLE_SKIP_TEST_IF(
978 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -0400979 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +0800980 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -0400981
982 GLubyte data[4] = {255, 0, 255, 255};
983
984 // Create the Image
985 GLuint source;
986 EGLImageKHR image;
987 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
988
989 // Create the target
990 GLuint target;
991 createEGLImageTargetRenderbuffer(image, &target);
992
993 // Expect that the target renderbuffer has the same color as the source texture
994 verifyResultsRenderbuffer(target, data);
995
996 // Clean up
997 glDeleteTextures(1, &source);
998 eglDestroyImageKHR(window->getDisplay(), image);
999 glDeleteRenderbuffers(1, &target);
1000}
1001
Geoff Langb66a9092016-05-16 15:59:14 -04001002TEST_P(ImageTest, Source2DTargetExternal)
1003{
1004 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001005 ANGLE_SKIP_TEST_IF(
1006 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001007 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001008 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001009
1010 GLubyte data[4] = {255, 0, 255, 255};
1011
1012 // Create the Image
1013 GLuint source;
1014 EGLImageKHR image;
1015 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
1016
1017 // Create the target
1018 GLuint target;
1019 createEGLImageTargetTextureExternal(image, &target);
1020
1021 // Expect that the target renderbuffer has the same color as the source texture
1022 verifyResultsExternal(target, data);
1023
1024 // Clean up
1025 glDeleteTextures(1, &source);
1026 eglDestroyImageKHR(window->getDisplay(), image);
1027 glDeleteRenderbuffers(1, &target);
1028}
1029
1030TEST_P(ImageTestES3, Source2DTargetExternalESSL3)
1031{
1032 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001033 ANGLE_SKIP_TEST_IF(
1034 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001035 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001036 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001037
1038 GLubyte data[4] = {255, 0, 255, 255};
1039
1040 // Create the Image
1041 GLuint source;
1042 EGLImageKHR image;
1043 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image);
1044
1045 // Create the target
1046 GLuint target;
1047 createEGLImageTargetTextureExternal(image, &target);
1048
1049 // Expect that the target renderbuffer has the same color as the source texture
1050 verifyResultsExternalESSL3(target, data);
1051
1052 // Clean up
1053 glDeleteTextures(1, &source);
1054 eglDestroyImageKHR(window->getDisplay(), image);
1055 glDeleteRenderbuffers(1, &target);
1056}
1057
Geoff Langa8406172015-07-21 16:53:39 -04001058TEST_P(ImageTest, SourceCubeTarget2D)
1059{
1060 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001061 ANGLE_SKIP_TEST_IF(
1062 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001063 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001064 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001065
1066 GLubyte data[24] = {
1067 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1068 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1069 };
1070
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001071 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
Geoff Langa8406172015-07-21 16:53:39 -04001072 {
1073 // Create the Image
1074 GLuint source;
1075 EGLImageKHR image;
1076 createEGLImageCubemapTextureSource(
1077 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1078 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &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[faceIdx * 4]);
1086
1087 // Clean up
1088 glDeleteTextures(1, &source);
1089 eglDestroyImageKHR(window->getDisplay(), image);
1090 glDeleteTextures(1, &target);
1091 }
1092}
1093
1094TEST_P(ImageTest, SourceCubeTargetRenderbuffer)
1095{
1096 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001097 ANGLE_SKIP_TEST_IF(
1098 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001099 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001100 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001101
1102 GLubyte data[24] = {
1103 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1104 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1105 };
1106
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001107 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
Geoff Langa8406172015-07-21 16:53:39 -04001108 {
1109 // Create the Image
1110 GLuint source;
1111 EGLImageKHR image;
1112 createEGLImageCubemapTextureSource(
1113 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1114 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image);
1115
1116 // Create the target
1117 GLuint target;
1118 createEGLImageTargetRenderbuffer(image, &target);
1119
1120 // Expect that the target texture has the same color as the source texture
1121 verifyResultsRenderbuffer(target, &data[faceIdx * 4]);
1122
1123 // Clean up
1124 glDeleteTextures(1, &source);
1125 eglDestroyImageKHR(window->getDisplay(), image);
1126 glDeleteRenderbuffers(1, &target);
1127 }
1128}
1129
Geoff Langb66a9092016-05-16 15:59:14 -04001130// Test cubemap -> external texture EGL images.
1131TEST_P(ImageTest, SourceCubeTargetExternal)
1132{
1133 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001134 ANGLE_SKIP_TEST_IF(
1135 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001136 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001137 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001138
1139 GLubyte data[24] = {
1140 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1141 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1142 };
1143
1144 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
1145 {
1146 // Create the Image
1147 GLuint source;
1148 EGLImageKHR image;
1149 createEGLImageCubemapTextureSource(
1150 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1151 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image);
1152
1153 // Create the target
1154 GLuint target;
1155 createEGLImageTargetTextureExternal(image, &target);
1156
1157 // Expect that the target texture has the same color as the source texture
1158 verifyResultsExternal(target, &data[faceIdx * 4]);
1159
1160 // Clean up
1161 glDeleteTextures(1, &source);
1162 eglDestroyImageKHR(window->getDisplay(), image);
1163 glDeleteRenderbuffers(1, &target);
1164 }
1165}
1166
1167// Test cubemap -> external texture EGL images using ESSL3 shaders.
1168TEST_P(ImageTestES3, SourceCubeTargetExternalESSL3)
1169{
1170 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001171 ANGLE_SKIP_TEST_IF(
1172 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001173 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001174 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001175
1176 GLubyte data[24] = {
1177 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255,
1178 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255,
1179 };
1180
1181 for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
1182 {
1183 // Create the Image
1184 GLuint source;
1185 EGLImageKHR image;
1186 createEGLImageCubemapTextureSource(
1187 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4,
1188 EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image);
1189
1190 // Create the target
1191 GLuint target;
1192 createEGLImageTargetTextureExternal(image, &target);
1193
1194 // Expect that the target texture has the same color as the source texture
1195 verifyResultsExternalESSL3(target, &data[faceIdx * 4]);
1196
1197 // Clean up
1198 glDeleteTextures(1, &source);
1199 eglDestroyImageKHR(window->getDisplay(), image);
1200 glDeleteRenderbuffers(1, &target);
1201 }
1202}
1203
Geoff Langa8406172015-07-21 16:53:39 -04001204TEST_P(ImageTest, Source3DTargetTexture)
1205{
1206 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001207 ANGLE_SKIP_TEST_IF(
1208 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001209 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001210 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001211
Yunchao He9550c602018-02-13 14:47:05 +08001212 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langa8406172015-07-21 16:53:39 -04001213
1214 const size_t depth = 2;
1215 GLubyte data[4 * depth] = {
1216 255, 0, 255, 255, 255, 255, 0, 255,
1217 };
1218
1219 for (size_t layer = 0; layer < depth; layer++)
1220 {
1221 // Create the Image
1222 GLuint source;
1223 EGLImageKHR image;
1224 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1225 &image);
1226
1227 // Create the target
1228 GLuint target;
1229 createEGLImageTargetTexture2D(image, &target);
1230
1231 // Expect that the target renderbuffer has the same color as the source texture
1232 verifyResults2D(target, &data[layer * 4]);
1233
1234 // Clean up
1235 glDeleteTextures(1, &source);
1236 eglDestroyImageKHR(window->getDisplay(), image);
1237 glDeleteTextures(1, &target);
1238 }
1239}
1240
1241TEST_P(ImageTest, Source3DTargetRenderbuffer)
1242{
1243 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001244 ANGLE_SKIP_TEST_IF(
1245 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001246 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001247 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001248
Yunchao He9550c602018-02-13 14:47:05 +08001249 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langa8406172015-07-21 16:53:39 -04001250
1251 const size_t depth = 2;
1252 GLubyte data[4 * depth] = {
1253 255, 0, 255, 255, 255, 255, 0, 255,
1254 };
1255
1256 for (size_t layer = 0; layer < depth; layer++)
1257 {
1258 // Create the Image
1259 GLuint source;
1260 EGLImageKHR image;
1261 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1262 &image);
1263
1264 // Create the target
1265 GLuint target;
1266 createEGLImageTargetRenderbuffer(image, &target);
1267
1268 // Expect that the target renderbuffer has the same color as the source texture
1269 verifyResultsRenderbuffer(target, &data[layer * 4]);
1270
1271 // Clean up
1272 glDeleteTextures(1, &source);
1273 eglDestroyImageKHR(window->getDisplay(), image);
1274 glDeleteTextures(1, &target);
1275 }
1276}
1277
Geoff Langb66a9092016-05-16 15:59:14 -04001278// Test 3D -> external texture EGL images.
1279TEST_P(ImageTest, Source3DTargetExternal)
1280{
1281 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001282 ANGLE_SKIP_TEST_IF(
1283 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001284 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001285 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001286
Yunchao He9550c602018-02-13 14:47:05 +08001287 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langb66a9092016-05-16 15:59:14 -04001288
1289 const size_t depth = 2;
1290 GLubyte data[4 * depth] = {
1291 255, 0, 255, 255, 255, 255, 0, 255,
1292 };
1293
1294 for (size_t layer = 0; layer < depth; layer++)
1295 {
1296 // Create the Image
1297 GLuint source;
1298 EGLImageKHR image;
1299 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1300 &image);
1301
1302 // Create the target
1303 GLuint target;
1304 createEGLImageTargetTextureExternal(image, &target);
1305
1306 // Expect that the target renderbuffer has the same color as the source texture
1307 verifyResultsExternal(target, &data[layer * 4]);
1308
1309 // Clean up
1310 glDeleteTextures(1, &source);
1311 eglDestroyImageKHR(window->getDisplay(), image);
1312 glDeleteTextures(1, &target);
1313 }
1314}
1315
1316// Test 3D -> external texture EGL images using ESSL3 shaders.
1317TEST_P(ImageTestES3, Source3DTargetExternalESSL3)
1318{
1319 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001320 ANGLE_SKIP_TEST_IF(
1321 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001322 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001323 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001324
Yunchao He9550c602018-02-13 14:47:05 +08001325 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D"));
Geoff Langb66a9092016-05-16 15:59:14 -04001326
1327 const size_t depth = 2;
1328 GLubyte data[4 * depth] = {
1329 255, 0, 255, 255, 255, 255, 0, 255,
1330 };
1331
1332 for (size_t layer = 0; layer < depth; layer++)
1333 {
1334 // Create the Image
1335 GLuint source;
1336 EGLImageKHR image;
1337 createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source,
1338 &image);
1339
1340 // Create the target
1341 GLuint target;
1342 createEGLImageTargetTextureExternal(image, &target);
1343
1344 // Expect that the target renderbuffer has the same color as the source texture
1345 verifyResultsExternalESSL3(target, &data[layer * 4]);
1346
1347 // Clean up
1348 glDeleteTextures(1, &source);
1349 eglDestroyImageKHR(window->getDisplay(), image);
1350 glDeleteTextures(1, &target);
1351 }
1352}
1353
Geoff Langa8406172015-07-21 16:53:39 -04001354TEST_P(ImageTest, SourceRenderbufferTargetTexture)
1355{
1356 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001357 ANGLE_SKIP_TEST_IF(
1358 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001359 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001360 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001361
1362 GLubyte data[4] = {255, 0, 255, 255};
1363
1364 // Create the Image
1365 GLuint source;
1366 EGLImageKHR image;
1367 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1368
1369 // Create the target
1370 GLuint target;
1371 createEGLImageTargetTexture2D(image, &target);
1372
1373 // Expect that the target texture has the same color as the source texture
1374 verifyResults2D(target, data);
1375
1376 // Clean up
1377 glDeleteRenderbuffers(1, &source);
1378 eglDestroyImageKHR(window->getDisplay(), image);
1379 glDeleteTextures(1, &target);
1380}
1381
Geoff Langb66a9092016-05-16 15:59:14 -04001382// Test renderbuffer -> external texture EGL images.
1383TEST_P(ImageTest, SourceRenderbufferTargetTextureExternal)
1384{
1385 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001386 ANGLE_SKIP_TEST_IF(
1387 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001388 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001389 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001390
1391 GLubyte data[4] = {255, 0, 255, 255};
1392
1393 // Create the Image
1394 GLuint source;
1395 EGLImageKHR image;
1396 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1397
1398 // Create the target
1399 GLuint target;
1400 createEGLImageTargetTextureExternal(image, &target);
1401
1402 // Expect that the target texture has the same color as the source texture
1403 verifyResultsExternal(target, data);
1404
1405 // Clean up
1406 glDeleteRenderbuffers(1, &source);
1407 eglDestroyImageKHR(window->getDisplay(), image);
1408 glDeleteTextures(1, &target);
1409}
1410
1411// Test renderbuffer -> external texture EGL images using ESSL3 shaders.
1412TEST_P(ImageTestES3, SourceRenderbufferTargetTextureExternalESSL3)
1413{
1414 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001415 ANGLE_SKIP_TEST_IF(
1416 !extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") ||
Geoff Langb66a9092016-05-16 15:59:14 -04001417 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001418 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image"));
Geoff Langb66a9092016-05-16 15:59:14 -04001419
1420 GLubyte data[4] = {255, 0, 255, 255};
1421
1422 // Create the Image
1423 GLuint source;
1424 EGLImageKHR image;
1425 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1426
1427 // Create the target
1428 GLuint target;
1429 createEGLImageTargetTextureExternal(image, &target);
1430
1431 // Expect that the target texture has the same color as the source texture
1432 verifyResultsExternalESSL3(target, data);
1433
1434 // Clean up
1435 glDeleteRenderbuffers(1, &source);
1436 eglDestroyImageKHR(window->getDisplay(), image);
1437 glDeleteTextures(1, &target);
1438}
1439
Geoff Langa8406172015-07-21 16:53:39 -04001440TEST_P(ImageTest, SourceRenderbufferTargetRenderbuffer)
1441{
1442 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001443 ANGLE_SKIP_TEST_IF(
1444 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001445 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001446 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001447
1448 GLubyte data[4] = {255, 0, 255, 255};
1449
1450 // Create the Image
1451 GLuint source;
1452 EGLImageKHR image;
1453 createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image);
1454
1455 // Create the target
1456 GLuint target;
1457 createEGLImageTargetRenderbuffer(image, &target);
1458
1459 // Expect that the target renderbuffer has the same color as the source texture
1460 verifyResultsRenderbuffer(target, data);
1461
1462 // Clean up
1463 glDeleteRenderbuffers(1, &source);
1464 eglDestroyImageKHR(window->getDisplay(), image);
1465 glDeleteRenderbuffers(1, &target);
1466}
1467
1468// Delete the source texture and EGL image. The image targets should still have the same data
1469// because
1470// they hold refs to the image.
1471TEST_P(ImageTest, Deletion)
1472{
1473 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001474 ANGLE_SKIP_TEST_IF(
1475 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001476 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001477 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001478
1479 GLubyte originalData[4] = {255, 0, 255, 255};
1480 GLubyte updateData[4] = {0, 255, 0, 255};
1481
1482 // Create the Image
1483 GLuint source;
1484 EGLImageKHR image;
1485 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1486
1487 // Create multiple targets
1488 GLuint targetTexture;
1489 createEGLImageTargetTexture2D(image, &targetTexture);
1490
1491 GLuint targetRenderbuffer;
1492 createEGLImageTargetRenderbuffer(image, &targetRenderbuffer);
1493
1494 // Delete the source texture
1495 glDeleteTextures(1, &source);
1496 source = 0;
1497
1498 // Expect that both the targets have the original data
1499 verifyResults2D(targetTexture, originalData);
1500 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1501
1502 // Update the data of the target
1503 glBindTexture(GL_TEXTURE_2D, targetTexture);
1504 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1505
1506 // Expect that both targets have the updated data
1507 verifyResults2D(targetTexture, updateData);
1508 verifyResultsRenderbuffer(targetRenderbuffer, updateData);
1509
1510 // Delete the EGL image
1511 eglDestroyImageKHR(window->getDisplay(), image);
1512 image = EGL_NO_IMAGE_KHR;
1513
1514 // Update the data of the target back to the original data
1515 glBindTexture(GL_TEXTURE_2D, targetTexture);
1516 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData);
1517
1518 // Expect that both targets have the original data again
1519 verifyResults2D(targetTexture, originalData);
1520 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1521
1522 // Clean up
1523 glDeleteTextures(1, &targetTexture);
1524 glDeleteRenderbuffers(1, &targetRenderbuffer);
1525}
1526
1527TEST_P(ImageTest, MipLevels)
1528{
1529 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001530 ANGLE_SKIP_TEST_IF(
1531 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001532 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001533 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001534
1535 const size_t mipLevels = 3;
1536 const size_t textureSize = 4;
1537 std::vector<GLuint> mip0Data(textureSize * textureSize, 0xFFFF0000);
1538 std::vector<GLuint> mip1Data(mip0Data.size() << 1, 0xFF00FF00);
1539 std::vector<GLuint> mip2Data(mip0Data.size() << 2, 0xFF0000FF);
1540 GLubyte *data[mipLevels] = {
1541 reinterpret_cast<GLubyte *>(&mip0Data[0]), reinterpret_cast<GLubyte *>(&mip1Data[0]),
1542 reinterpret_cast<GLubyte *>(&mip2Data[0]),
1543 };
1544
1545 GLuint source;
1546 glGenTextures(1, &source);
1547 glBindTexture(GL_TEXTURE_2D, source);
1548
1549 for (size_t level = 0; level < mipLevels; level++)
1550 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001551 glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(level), GL_RGBA, textureSize >> level,
1552 textureSize >> level, 0, GL_RGBA, GL_UNSIGNED_BYTE, data[level]);
Geoff Langa8406172015-07-21 16:53:39 -04001553 }
1554
1555 ASSERT_GL_NO_ERROR();
1556
1557 for (size_t level = 0; level < mipLevels; level++)
1558 {
1559 // Create the Image
1560 EGLint attribs[] = {
1561 EGL_GL_TEXTURE_LEVEL_KHR, static_cast<EGLint>(level), EGL_NONE,
1562 };
1563 EGLImageKHR image =
1564 eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
Austin Kinrossa8187762015-08-12 10:54:37 -07001565 reinterpretHelper<EGLClientBuffer>(source), attribs);
Geoff Langa8406172015-07-21 16:53:39 -04001566 ASSERT_EGL_SUCCESS();
1567
1568 // Create a texture and renderbuffer target
1569 GLuint textureTarget;
1570 createEGLImageTargetTexture2D(image, &textureTarget);
1571
1572 // Disable mipmapping
1573 glBindTexture(GL_TEXTURE_2D, textureTarget);
1574 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1575 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1576
1577 GLuint renderbufferTarget;
1578 createEGLImageTargetRenderbuffer(image, &renderbufferTarget);
1579
1580 // Expect that the targets have the same color as the source texture
1581 verifyResults2D(textureTarget, data[level]);
1582 verifyResultsRenderbuffer(renderbufferTarget, data[level]);
1583
1584 // Clean up
1585 eglDestroyImageKHR(window->getDisplay(), image);
1586 glDeleteTextures(1, &textureTarget);
1587 glDeleteRenderbuffers(1, &renderbufferTarget);
1588 }
1589
1590 // Clean up
1591 glDeleteTextures(1, &source);
1592}
1593
1594// Respecify the source texture, orphaning it. The target texture should not have updated data.
1595TEST_P(ImageTest, Respecification)
1596{
1597 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001598 ANGLE_SKIP_TEST_IF(
1599 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001600 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001601 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001602
1603 GLubyte originalData[4] = {255, 0, 255, 255};
1604 GLubyte updateData[4] = {0, 255, 0, 255};
1605
1606 // Create the Image
1607 GLuint source;
1608 EGLImageKHR image;
1609 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1610
1611 // Create the target
1612 GLuint target;
1613 createEGLImageTargetTexture2D(image, &target);
1614
1615 // Respecify source
1616 glBindTexture(GL_TEXTURE_2D, source);
1617 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1618
1619 // Expect that the target texture has the original data
1620 verifyResults2D(target, originalData);
1621
1622 // Expect that the source texture has the updated data
1623 verifyResults2D(source, updateData);
1624
1625 // Clean up
1626 glDeleteTextures(1, &source);
1627 eglDestroyImageKHR(window->getDisplay(), image);
1628 glDeleteTextures(1, &target);
1629}
1630
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001631// First render to a target texture, then respecify the source texture, orphaning it.
1632// The target texture's FBO should be notified of the target texture's orphaning.
1633TEST_P(ImageTest, RespecificationWithFBO)
1634{
1635 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001636 ANGLE_SKIP_TEST_IF(
1637 !extensionEnabled("OES_EGL_image") ||
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001638 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001639 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001640
Olli Etuaho5804dc82018-04-13 14:11:46 +03001641 GLuint program = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001642 ASSERT_NE(0u, program);
1643
1644 GLubyte originalData[4] = {255, 0, 255, 255};
1645 GLubyte updateData[4] = {0, 255, 0, 255};
1646
1647 // Create the Image
1648 GLuint source;
1649 EGLImageKHR image;
1650 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1651
1652 // Create the target
1653 GLuint target;
1654 createEGLImageTargetTexture2D(image, &target);
1655
1656 // Render to the target texture
1657 GLuint fbo;
1658 glGenFramebuffers(1, &fbo);
1659 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1660 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
Olli Etuaho5804dc82018-04-13 14:11:46 +03001661 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1662 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001663
1664 // Respecify source with same parameters. This should not change the texture storage in D3D11.
1665 glBindTexture(GL_TEXTURE_2D, source);
1666 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1667
1668 // Expect that the source texture has the updated data
1669 verifyResults2D(source, updateData);
1670
1671 // Render to the target texture again and verify it gets the rendered pixels.
Olli Etuaho5804dc82018-04-13 14:11:46 +03001672 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1673 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
Jamie Madill1fbc59f2016-02-24 15:25:51 -05001674
1675 // Clean up
1676 glDeleteTextures(1, &source);
1677 eglDestroyImageKHR(window->getDisplay(), image);
1678 glDeleteTextures(1, &target);
1679 glDeleteProgram(program);
1680 glDeleteFramebuffers(1, &fbo);
1681}
1682
Geoff Langa8406172015-07-21 16:53:39 -04001683// Test that respecifying a level of the target texture orphans it and keeps a copy of the EGLimage
1684// data
1685TEST_P(ImageTest, RespecificationOfOtherLevel)
1686{
1687 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001688 ANGLE_SKIP_TEST_IF(
1689 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001690 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001691 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001692
1693 GLubyte originalData[2 * 2 * 4] = {
1694 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
1695 };
1696
1697 GLubyte updateData[2 * 2 * 4] = {
1698 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
1699 };
1700
1701 // Create the Image
1702 GLuint source;
1703 EGLImageKHR image;
1704 createEGLImage2DTextureSource(2, 2, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1705
1706 // Create the target
1707 GLuint target;
1708 createEGLImageTargetTexture2D(image, &target);
1709
1710 // Expect that the target and source textures have the original data
1711 verifyResults2D(source, originalData);
1712 verifyResults2D(target, originalData);
1713
1714 // Add a new mipLevel to the target, orphaning it
1715 glBindTexture(GL_TEXTURE_2D, target);
1716 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, originalData);
1717 EXPECT_GL_NO_ERROR();
1718
1719 // Expect that the target and source textures still have the original data
1720 verifyResults2D(source, originalData);
1721 verifyResults2D(target, originalData);
1722
1723 // Update the source's data
1724 glBindTexture(GL_TEXTURE_2D, source);
1725 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1726
1727 // Expect that the target still has the original data and source has the updated data
1728 verifyResults2D(source, updateData);
1729 verifyResults2D(target, originalData);
1730
1731 // Clean up
1732 glDeleteTextures(1, &source);
1733 eglDestroyImageKHR(window->getDisplay(), image);
1734 glDeleteTextures(1, &target);
1735}
1736
1737// Update the data of the source and target textures. All image siblings should have the new data.
1738TEST_P(ImageTest, UpdatedData)
1739{
1740 EGLWindow *window = getEGLWindow();
Yunchao He9550c602018-02-13 14:47:05 +08001741 ANGLE_SKIP_TEST_IF(
1742 !extensionEnabled("OES_EGL_image") ||
Geoff Langa8406172015-07-21 16:53:39 -04001743 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") ||
Yunchao He9550c602018-02-13 14:47:05 +08001744 !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
Geoff Langa8406172015-07-21 16:53:39 -04001745
1746 GLubyte originalData[4] = {255, 0, 255, 255};
1747 GLubyte updateData[4] = {0, 255, 0, 255};
1748
1749 // Create the Image
1750 GLuint source;
1751 EGLImageKHR image;
1752 createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
1753
1754 // Create multiple targets
1755 GLuint targetTexture;
1756 createEGLImageTargetTexture2D(image, &targetTexture);
1757
1758 GLuint targetRenderbuffer;
1759 createEGLImageTargetRenderbuffer(image, &targetRenderbuffer);
1760
1761 // Expect that both the source and targets have the original data
1762 verifyResults2D(source, originalData);
1763 verifyResults2D(targetTexture, originalData);
1764 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1765
1766 // Update the data of the source
1767 glBindTexture(GL_TEXTURE_2D, source);
1768 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
1769
1770 // Expect that both the source and targets have the updated data
1771 verifyResults2D(source, updateData);
1772 verifyResults2D(targetTexture, updateData);
1773 verifyResultsRenderbuffer(targetRenderbuffer, updateData);
1774
1775 // Update the data of the target back to the original data
1776 glBindTexture(GL_TEXTURE_2D, targetTexture);
1777 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData);
1778
1779 // Expect that both the source and targets have the original data again
1780 verifyResults2D(source, originalData);
1781 verifyResults2D(targetTexture, originalData);
1782 verifyResultsRenderbuffer(targetRenderbuffer, originalData);
1783
1784 // Clean up
1785 glDeleteTextures(1, &source);
1786 eglDestroyImageKHR(window->getDisplay(), image);
1787 glDeleteTextures(1, &targetTexture);
1788 glDeleteRenderbuffers(1, &targetRenderbuffer);
1789}
1790
1791// Use this to select which configurations (e.g. which renderer, which GLES major version) these
1792// tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -05001793ANGLE_INSTANTIATE_TEST(ImageTest,
1794 ES2_D3D9(),
1795 ES2_D3D11(),
1796 ES3_D3D11(),
1797 ES2_OPENGL(),
1798 ES3_OPENGL(),
1799 ES2_OPENGLES(),
Luc Ferronaf883622018-06-08 15:57:31 -04001800 ES3_OPENGLES(),
1801 ES2_VULKAN());
Geoff Langb66a9092016-05-16 15:59:14 -04001802ANGLE_INSTANTIATE_TEST(ImageTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Geoff Langa8406172015-07-21 16:53:39 -04001803}